--- a/net/minecraft/world/item/crafting/Recipe.java
+++ b/net/minecraft/world/item/crafting/Recipe.java
@@ -15,9 +15,9 @@
 import net.minecraft.world.level.block.Blocks;
 
 public interface Recipe<C extends Container> {
+
     Codec<Recipe<?>> CODEC = BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec);
-    StreamCodec<RegistryFriendlyByteBuf, Recipe<?>> STREAM_CODEC = ByteBufCodecs.registry(Registries.RECIPE_SERIALIZER)
-        .dispatch(Recipe::getSerializer, RecipeSerializer::streamCodec);
+    StreamCodec<RegistryFriendlyByteBuf, Recipe<?>> STREAM_CODEC = ByteBufCodecs.registry(Registries.RECIPE_SERIALIZER).dispatch(Recipe::getSerializer, RecipeSerializer::streamCodec);
 
     boolean matches(C inventory, Level world);
 
@@ -28,16 +28,17 @@
     ItemStack getResultItem(HolderLookup.Provider registriesLookup);
 
     default NonNullList<ItemStack> getRemainingItems(C inventory) {
-        NonNullList<ItemStack> nonNullList = NonNullList.withSize(inventory.getContainerSize(), ItemStack.EMPTY);
+        NonNullList<ItemStack> nonnulllist = NonNullList.withSize(inventory.getContainerSize(), ItemStack.EMPTY);
 
-        for (int i = 0; i < nonNullList.size(); i++) {
+        for (int i = 0; i < nonnulllist.size(); ++i) {
             Item item = inventory.getItem(i).getItem();
+
             if (item.hasCraftingRemainingItem()) {
-                nonNullList.set(i, new ItemStack(item.getCraftingRemainingItem()));
+                nonnulllist.set(i, new ItemStack(item.getCraftingRemainingItem()));
             }
         }
 
-        return nonNullList;
+        return nonnulllist;
     }
 
     default NonNullList<Ingredient> getIngredients() {
@@ -65,7 +66,18 @@
     RecipeType<?> getType();
 
     default boolean isIncomplete() {
-        NonNullList<Ingredient> nonNullList = this.getIngredients();
-        return nonNullList.isEmpty() || nonNullList.stream().anyMatch(ingredient -> ingredient.getItems().length == 0);
+        NonNullList<Ingredient> nonnulllist = this.getIngredients();
+
+        return nonnulllist.isEmpty() || nonnulllist.stream().anyMatch((recipeitemstack) -> {
+            return recipeitemstack.getItems().length == 0;
+        });
+    }
+
+    org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id); // CraftBukkit
+
+    // Paper start - improved exact choice recipes
+    default boolean hasExactIngredients() {
+        return false;
     }
+    // Paper end
 }
