// Path: src/main/java/tonius/neiintegration/Utils.java
// public class Utils {
//     
//     public static String translate(String unlocalized, boolean prefix) {
//         return StatCollector.translateToLocal((prefix ? "neiintegration." : "") + unlocalized);
//     }
//     
//     public static String translate(String unlocalized) {
//         return translate(unlocalized, true);
//     }
//     
//     public static boolean areStacksSameTypeCraftingSafe(ItemStack stack1, ItemStack stack2) {
//         if (stack1 != null && stack2 != null) {
//             return NEIServerUtils.areStacksSameTypeCrafting(stack1, stack2);
//         }
//         return false;
//     }
//     
//     public static List<ItemStack> getItemVariations(ItemStack base) {
//         List<ItemStack> variations = new ArrayList<ItemStack>();
//         base.getItem().getSubItems(base.getItem(), null, variations);
//         Iterator<ItemStack> itr = variations.iterator();
//         ItemStack stack;
//         while (itr.hasNext()) {
//             stack = itr.next();
//             if (!base.isItemEqual(stack) || !stack.hasTagCompound()) {
//                 itr.remove();
//             }
//         }
//         if (variations.isEmpty()) {
//             return Collections.singletonList(base);
//         }
//         return variations;
//     }
//     
//     public static FluidStack getFluidStack(ItemStack stack) {
//         if (stack != null) {
//             FluidStack fluidStack = null;
//             Block block = Block.getBlockFromItem(stack.getItem());
//             
//             if (stack.getItem() instanceof IFluidContainerItem) {
//                 fluidStack = ((IFluidContainerItem) stack.getItem()).getFluid(stack);
//             }
//             if (fluidStack == null) {
//                 fluidStack = FluidContainerRegistry.getFluidForFilledItem(stack);
//             }
//             if (fluidStack == null && block instanceof IFluidBlock) {
//                 Fluid fluid = ((IFluidBlock) block).getFluid();
//                 if (fluid != null) {
//                     fluidStack = new FluidStack(fluid, 1000);
//                 }
//             }
//             if (fluidStack == null && (block == Blocks.water || block == Blocks.flowing_water)) {
//                 fluidStack = new FluidStack(FluidRegistry.WATER, 1000);
//             }
//             if (fluidStack == null && (block == Blocks.lava || block == Blocks.flowing_lava)) {
//                 fluidStack = new FluidStack(FluidRegistry.LAVA, 1000);
//             }
//             
//             return fluidStack;
//         }
//         return null;
//     }
//     
//     public static boolean areFluidsSameType(FluidStack fluidStack1, FluidStack fluidStack2) {
//         if (fluidStack1 == null || fluidStack2 == null) {
//             return false;
//         }
//         return fluidStack1.getFluid() == fluidStack2.getFluid();
//     }
//     
//     public static boolean isFluidBlock(ItemStack stack) {
//         if (stack == null || stack.getItem() == null) {
//             return false;
//         }
//         
//         Block block = Block.getBlockFromItem(stack.getItem());
//         if (block == null) {
//             return false;
//         }
//         
//         return block instanceof IFluidBlock || block == Blocks.water || block == Blocks.flowing_water || block == Blocks.lava || block == Blocks.flowing_lava;
//     }
//     
//     public static boolean isShiftKeyDown() {
//         return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
//     }
//     
//     public static Class getClass(String name) {
//         try {
//             Class clazz = Class.forName(name);
//             return clazz;
//         } catch (Exception e) {
//             NEIIntegration.log.error("Failed to find class " + name);
//         }
//         return null;
//     }
//     
//     public static boolean isModLoaded(String modid) {
//         return Loader.isModLoaded(modid);
//     }
//     
//     public static boolean isModLoaded(String modid, String versionRangeString) {
//         if (!isModLoaded(modid)) {
//             return false;
//         }
//         
//         ModContainer mod = Loader.instance().getIndexedModList().get(modid);
//         VersionRange versionRange = VersionParser.parseRange(versionRangeString);
//         DefaultArtifactVersion required = new DefaultArtifactVersion(modid, versionRange);
//         
//         return required.containsVersion(mod.getProcessedVersion());
//     }
//     
// }


import java.util.ArrayList;
import java.util.List;
import mods.railcraft.api.crafting.RailcraftCraftingManager;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraftforge.oredict.ShapedOreRecipe;
import tonius.neiintegration.Utils;
import codechicken.core.ReflectionManager;
import codechicken.nei.PositionedStack;
                    
                    Object item = items[index];
                    
                    if (item == null) {
                        continue;
                    } else if (item instanceof ItemStack[] && ((ItemStack[]) item).length == 0) {
                        continue;
                    } else if (item instanceof List && ((List) item).size() == 0) {
                        continue;
                    }
                    
                    PositionedStack stack = new PositionedStack(item, 25 + x * 18, 8 + y * 18, false);
                    stack.setMaxSize(1);
                    this.inputs.add(stack);
                }
            }
        }
        
        @Override
        public List<PositionedStack> getIngredients() {
            return this.getCycledIngredients(RecipeHandlerRollingMachineShaped.this.cycleticks / 20, this.inputs);
        }
        
        @Override
        public PositionedStack getResult() {
            return this.output;
        }
        
        public void generatePermutations() {
            for (PositionedStack p : this.inputs) {
// Path: src/main/java/tonius/neiintegration/Utils.java
// public class Utils {
//     
//     public static String translate(String unlocalized, boolean prefix) {
//         return StatCollector.translateToLocal((prefix ? "neiintegration." : "") + unlocalized);
//     }
//     
//     public static String translate(String unlocalized) {
//         return translate(unlocalized, true);
//     }
//     
//     public static boolean areStacksSameTypeCraftingSafe(ItemStack stack1, ItemStack stack2) {
//         if (stack1 != null && stack2 != null) {
//             return NEIServerUtils.areStacksSameTypeCrafting(stack1, stack2);
//         }
//         return false;
//     }
//     
//     public static List<ItemStack> getItemVariations(ItemStack base) {
//         List<ItemStack> variations = new ArrayList<ItemStack>();
//         base.getItem().getSubItems(base.getItem(), null, variations);
//         Iterator<ItemStack> itr = variations.iterator();
//         ItemStack stack;
//         while (itr.hasNext()) {
//             stack = itr.next();
//             if (!base.isItemEqual(stack) || !stack.hasTagCompound()) {
//                 itr.remove();
//             }
//         }
//         if (variations.isEmpty()) {
//             return Collections.singletonList(base);
//         }
//         return variations;
//     }
//     
//     public static FluidStack getFluidStack(ItemStack stack) {
//         if (stack != null) {
//             FluidStack fluidStack = null;
//             Block block = Block.getBlockFromItem(stack.getItem());
//             
//             if (stack.getItem() instanceof IFluidContainerItem) {
//                 fluidStack = ((IFluidContainerItem) stack.getItem()).getFluid(stack);
//             }
//             if (fluidStack == null) {
//                 fluidStack = FluidContainerRegistry.getFluidForFilledItem(stack);
//             }
//             if (fluidStack == null && block instanceof IFluidBlock) {
//                 Fluid fluid = ((IFluidBlock) block).getFluid();
//                 if (fluid != null) {
//                     fluidStack = new FluidStack(fluid, 1000);
//                 }
//             }
//             if (fluidStack == null && (block == Blocks.water || block == Blocks.flowing_water)) {
//                 fluidStack = new FluidStack(FluidRegistry.WATER, 1000);
//             }
//             if (fluidStack == null && (block == Blocks.lava || block == Blocks.flowing_lava)) {
//                 fluidStack = new FluidStack(FluidRegistry.LAVA, 1000);
//             }
//             
//             return fluidStack;
//         }
//         return null;
//     }
//     
//     public static boolean areFluidsSameType(FluidStack fluidStack1, FluidStack fluidStack2) {
//         if (fluidStack1 == null || fluidStack2 == null) {
//             return false;
//         }
//         return fluidStack1.getFluid() == fluidStack2.getFluid();
//     }
//     
//     public static boolean isFluidBlock(ItemStack stack) {
//         if (stack == null || stack.getItem() == null) {
//             return false;
//         }
//         
//         Block block = Block.getBlockFromItem(stack.getItem());
//         if (block == null) {
//             return false;
//         }
//         
//         return block instanceof IFluidBlock || block == Blocks.water || block == Blocks.flowing_water || block == Blocks.lava || block == Blocks.flowing_lava;
//     }
//     
//     public static boolean isShiftKeyDown() {
//         return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
//     }
//     
//     public static Class getClass(String name) {
//         try {
//             Class clazz = Class.forName(name);
//             return clazz;
//         } catch (Exception e) {
//             NEIIntegration.log.error("Failed to find class " + name);
//         }
//         return null;
//     }
//     
//     public static boolean isModLoaded(String modid) {
//         return Loader.isModLoaded(modid);
//     }
//     
//     public static boolean isModLoaded(String modid, String versionRangeString) {
//         if (!isModLoaded(modid)) {
//             return false;
//         }
//         
//         ModContainer mod = Loader.instance().getIndexedModList().get(modid);
//         VersionRange versionRange = VersionParser.parseRange(versionRangeString);
//         DefaultArtifactVersion required = new DefaultArtifactVersion(modid, versionRange);
//         
//         return required.containsVersion(mod.getProcessedVersion());
//     }
//     
// }


// Path: src/main/java/tonius/neiintegration/mods/railcraft/RecipeHandlerRollingMachineShaped.java
import java.util.ArrayList;
import java.util.List;
import mods.railcraft.api.crafting.RailcraftCraftingManager;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraftforge.oredict.ShapedOreRecipe;
import tonius.neiintegration.Utils;
import codechicken.core.ReflectionManager;
import codechicken.nei.PositionedStack;

                    
                    Object item = items[index];
                    
                    if (item == null) {
                        continue;
                    } else if (item instanceof ItemStack[] && ((ItemStack[]) item).length == 0) {
                        continue;
                    } else if (item instanceof List && ((List) item).size() == 0) {
                        continue;
                    }
                    
                    PositionedStack stack = new PositionedStack(item, 25 + x * 18, 8 + y * 18, false);
                    stack.setMaxSize(1);
                    this.inputs.add(stack);
                }
            }
        }
        
        @Override
        public List<PositionedStack> getIngredients() {
            return this.getCycledIngredients(RecipeHandlerRollingMachineShaped.this.cycleticks / 20, this.inputs);
        }
        
        @Override
        public PositionedStack getResult() {
            return this.output;
        }
        
        public void generatePermutations() {
            for (PositionedStack p : this.inputs) {
                p.generatePermutations();