protected ContainerMEMonitorable(
      final InventoryPlayer ip, final ITerminalHost monitorable, final boolean bindInventory) {
    super(
        ip,
        monitorable instanceof TileEntity ? (TileEntity) monitorable : null,
        monitorable instanceof IPart ? (IPart) monitorable : null);

    this.host = monitorable;
    this.clientCM = new ConfigManager(this);

    this.clientCM.registerSetting(Settings.SORT_BY, SortOrder.NAME);
    this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
    this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);

    if (Platform.isServer()) {
      this.serverCM = monitorable.getConfigManager();

      this.monitor = monitorable.getItemInventory();
      if (this.monitor != null) {
        this.monitor.addListener(this, null);

        this.cellInv = this.monitor;

        if (monitorable instanceof IPortableCell) {
          this.powerSrc = (IEnergySource) monitorable;
        } else if (monitorable instanceof IMEChest) {
          this.powerSrc = (IEnergySource) monitorable;
        } else if (monitorable instanceof IGridHost) {
          final IGridNode node = ((IGridHost) monitorable).getGridNode(ForgeDirection.UNKNOWN);
          if (node != null) {
            this.networkNode = node;
            final IGrid g = node.getGrid();
            if (g != null) {
              this.powerSrc =
                  new ChannelPowerSrc(
                      this.networkNode, (IEnergySource) g.getCache(IEnergyGrid.class));
            }
          }
        }
      } else {
        this.isContainerValid = false;
      }
    } else {
      this.monitor = null;
    }

    this.canAccessViewCells = false;
    if (monitorable instanceof IViewCellStorage) {
      for (int y = 0; y < 5; y++) {
        this.cellView[y] =
            new SlotRestrictedInput(
                SlotRestrictedInput.PlacableItemType.VIEW_CELL,
                ((IViewCellStorage) monitorable).getViewCellStorage(),
                y,
                206,
                y * 18 + 8,
                this.invPlayer);
        this.cellView[y].allowEdit = this.canAccessViewCells;
        this.addSlotToContainer(this.cellView[y]);
      }
    }

    if (bindInventory) {
      this.bindPlayerInventory(ip, 0, 0);
    }
  }
  @Override
  public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) {
    EntityPlayerMP pmp = (EntityPlayerMP) player;
    Container con = pmp.openContainer;

    if (con instanceof IContainerCraftingPacket) {
      IContainerCraftingPacket cct = (IContainerCraftingPacket) con;
      IGridNode node = cct.getNetworkNode();
      if (node != null) {
        IGrid grid = node.getGrid();
        if (grid == null) {
          return;
        }

        IStorageGrid inv = grid.getCache(IStorageGrid.class);
        IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
        ISecurityGrid security = grid.getCache(ISecurityGrid.class);
        IInventory craftMatrix = cct.getInventoryByName("crafting");
        IInventory playerInventory = cct.getInventoryByName("player");

        Actionable realForFake = cct.useRealItems() ? Actionable.MODULATE : Actionable.SIMULATE;

        if (inv != null && this.recipe != null && security != null) {
          InventoryCrafting testInv = new InventoryCrafting(new ContainerNull(), 3, 3);
          for (int x = 0; x < 9; x++) {
            if (this.recipe[x] != null && this.recipe[x].length > 0) {
              testInv.setInventorySlotContents(x, this.recipe[x][0]);
            }
          }

          IRecipe r = Platform.findMatchingRecipe(testInv, pmp.worldObj);

          if (r != null && security.hasPermission(player, SecurityPermissions.EXTRACT)) {
            ItemStack is = r.getCraftingResult(testInv);

            if (is != null) {
              IMEMonitor<IAEItemStack> storage = inv.getItemInventory();
              IItemList all = storage.getStorageList();
              IPartitionList<IAEItemStack> filter = ItemViewCell.createFilter(cct.getViewCells());

              for (int x = 0; x < craftMatrix.getSizeInventory(); x++) {
                ItemStack patternItem = testInv.getStackInSlot(x);

                ItemStack currentItem = craftMatrix.getStackInSlot(x);
                if (currentItem != null) {
                  testInv.setInventorySlotContents(x, currentItem);
                  ItemStack newItemStack =
                      r.matches(testInv, pmp.worldObj) ? r.getCraftingResult(testInv) : null;
                  testInv.setInventorySlotContents(x, patternItem);

                  if (newItemStack == null || !Platform.isSameItemPrecise(newItemStack, is)) {
                    IAEItemStack in = AEItemStack.create(currentItem);
                    if (in != null) {
                      IAEItemStack out =
                          realForFake == Actionable.SIMULATE
                              ? null
                              : Platform.poweredInsert(energy, storage, in, cct.getSource());
                      if (out != null) {
                        craftMatrix.setInventorySlotContents(x, out.getItemStack());
                      } else {
                        craftMatrix.setInventorySlotContents(x, null);
                      }

                      currentItem = craftMatrix.getStackInSlot(x);
                    }
                  }
                }

                // True if we need to fetch an item for the recipe
                if (patternItem != null && currentItem == null) {
                  // Grab from network by recipe
                  ItemStack whichItem =
                      Platform.extractItemsByRecipe(
                          energy,
                          cct.getSource(),
                          storage,
                          player.worldObj,
                          r,
                          is,
                          testInv,
                          patternItem,
                          x,
                          all,
                          realForFake,
                          filter);

                  // If that doesn't get it, grab exact items from network (?)
                  // TODO see if this code is necessary
                  if (whichItem == null) {
                    for (int y = 0; y < this.recipe[x].length; y++) {
                      IAEItemStack request = AEItemStack.create(this.recipe[x][y]);
                      if (request != null) {
                        if (filter == null || filter.isListed(request)) {
                          request.setStackSize(1);
                          IAEItemStack out =
                              Platform.poweredExtraction(energy, storage, request, cct.getSource());
                          if (out != null) {
                            whichItem = out.getItemStack();
                            break;
                          }
                        }
                      }
                    }
                  }

                  // If that doesn't work, grab from the player's inventory
                  if (whichItem == null && playerInventory != null) {
                    whichItem = extractItemFromPlayerInventory(player, realForFake, patternItem);
                  }

                  craftMatrix.setInventorySlotContents(x, whichItem);
                }
              }
              con.onCraftMatrixChanged(craftMatrix);
            }
          }
        }
      }
    }
  }