private boolean placeBlock(
      Minecraft minecraft,
      World world,
      EntityPlayer player,
      int x,
      int y,
      int z,
      int itemId,
      int itemDamage) {
    if (!isValidOrientation(player, x, y, z, itemId, itemDamage)) {
      return false;
    }

    if (SchematicWorld.isFluidContainer(itemId) || itemId == Item.sign.itemID) {
      return false;
    }

    int side = 0;
    float offsetY = 0.0f;
    ForgeDirection direction = ForgeDirection.DOWN;
    boolean[] blocks =
        new boolean[] {
          world.getBlockId(x, y + 1, z) > 0,
          world.getBlockId(x, y - 1, z) > 0,
          world.getBlockId(x, y, z + 1) > 0,
          world.getBlockId(x, y, z - 1) > 0,
          world.getBlockId(x + 1, y, z) > 0,
          world.getBlockId(x - 1, y, z) > 0
        };

    for (int i = 0; i < 6; i++) {
      if (blocks[i]) {
        direction = ForgeDirection.getOrientation(i).getOpposite();
        break;
      }
    }

    if (SchematicWorld.isMetadataSensitive(itemId)) {
      int itemDamageInHand = 0xF;
      if (SchematicWorld.isTorch(itemId)) {
        switch (itemDamage) {
          case 1:
            direction = ForgeDirection.WEST;
            break;
          case 2:
            direction = ForgeDirection.EAST;
            break;
          case 3:
            direction = ForgeDirection.NORTH;
            break;
          case 4:
            direction = ForgeDirection.SOUTH;
            break;
          case 5:
            direction = ForgeDirection.DOWN;
            break;
        }

        if (direction == ForgeDirection.DOWN) {
          if (world.doesBlockHaveSolidTopSurface(x, y - 1, z)) {
            itemDamageInHand = 0;
          }
        } else {
          if (world.isBlockSolidOnSide(
              x + direction.offsetX,
              y + direction.offsetY,
              z + direction.offsetZ,
              direction,
              false)) {
            itemDamageInHand = 0;
          }
        }
      } else if (SchematicWorld.isBlock(itemId)) {
        itemDamageInHand = itemDamage;
      } else if (SchematicWorld.isSlab(itemId)) {
        if ((itemDamage & 0x8) != 0 && direction == ForgeDirection.DOWN) {
          direction = ForgeDirection.UP;
        } else if ((itemDamage & 0x8) == 0 && direction == ForgeDirection.UP) {
          direction = ForgeDirection.DOWN;
        }
        offsetY = (itemDamage & 0x8) == 0x0 ? 0.0f : 1.0f;
        itemDamageInHand = itemDamage & 0x7;
      } else if (SchematicWorld.isPistonBase(itemId)) {
        itemDamageInHand = 0;
      } else if (SchematicWorld.isDoubleSlab(itemId)) {
        itemDamageInHand = itemDamage;
      } else if (SchematicWorld.isContainer(itemId)) {
        itemDamageInHand = 0;
      } else if (SchematicWorld.isButton(itemId)) {
        switch (itemDamage & 0x7) {
          case 0x1:
            direction = ForgeDirection.WEST;
            break;
          case 0x2:
            direction = ForgeDirection.EAST;
            break;
          case 0x3:
            direction = ForgeDirection.NORTH;
            break;
          case 0x4:
            direction = ForgeDirection.SOUTH;
            break;
          default:
            return false;
        }

        if (world.isBlockSolidOnSide(
            x + direction.offsetX,
            y + direction.offsetY,
            z + direction.offsetZ,
            direction,
            false)) {
          itemDamageInHand = 0;
        } else {
          return false;
        }
      } else if (SchematicWorld.isPumpkin(itemId)) {
        if (world.doesBlockHaveSolidTopSurface(x, y - 1, z)) {
          itemDamageInHand = 0;
        } else {
          return false;
        }
      } else if (itemId == Item.redstoneRepeater.itemID) {
        itemDamageInHand = 0;
      } else if (itemId == Block.anvil.blockID) {
        switch (itemDamage & 0xC) {
          case 0x0:
            itemDamageInHand = 0;
            break;
          case 0x4:
            itemDamageInHand = 1;
            break;
          case 0x8:
            itemDamageInHand = 2;
            break;
          default:
            return false;
        }
      } else if (itemId == Block.fenceGate.blockID) {
        itemDamageInHand = 0;
      } else if (itemId == Block.trapdoor.blockID) {
        switch (itemDamage & 0x3) {
          case 0x0:
            direction = ForgeDirection.SOUTH;
            break;
          case 0x1:
            direction = ForgeDirection.NORTH;
            break;
          case 0x2:
            direction = ForgeDirection.EAST;
            break;
          case 0x3:
            direction = ForgeDirection.WEST;
            break;
          default:
            return false;
        }

        if ((itemDamage & 0x8) != 0) {
          offsetY = 0.75f;
        }

        if (world.isBlockSolidOnSide(
            x + direction.offsetX,
            y + direction.offsetY,
            z + direction.offsetZ,
            direction,
            false)) {
          itemDamageInHand = 0;
        } else {
          return false;
        }
      } else {
        return false;
      }

      if (!swapToItem(player.inventory, itemId, itemDamageInHand)) {
        return false;
      }
    } else {
      if (!swapToItem(player.inventory, itemId)) {
        return false;
      }

      if (SchematicWorld.isStair(itemId)) {
        direction = (itemDamage & 0x4) == 0x0 ? ForgeDirection.DOWN : ForgeDirection.UP;
      } else if (Block.wood.blockID == itemId) {
        if ((itemDamage & 0xC) == 0x00) {
          direction = ForgeDirection.DOWN;
        } else if ((itemDamage & 0xC) == 0x04) {
          direction = ForgeDirection.EAST;
        } else if ((itemDamage & 0xC) == 0x08) {
          direction = ForgeDirection.NORTH;
        }
      }
    }

    side = getSide(direction);
    if (side != 255 && blocks[side] || !this.settings.placeAdjacent) {
      return placeBlock(minecraft, world, player, x, y, z, direction, 0.0f, offsetY, 0.0f);
    }

    return false;
  }
  private boolean isValidOrientation(
      EntityPlayer player, int x, int y, int z, int itemId, int itemDamage) {
    int orientation = this.settings.orientation;

    if (SchematicWorld.isStair(itemId)) {
      switch (itemDamage & 0x3) {
        case 0:
          return orientation == 4;
        case 1:
          return orientation == 5;
        case 2:
          return orientation == 2;
        case 3:
          return orientation == 3;
      }
    } else if (SchematicWorld.isPistonBase(itemId)) {
      return BlockPistonBase.determineOrientation(null, x, y, z, player)
          == BlockPistonBase.getOrientation(itemDamage);
    } else if (SchematicWorld.isContainer(itemId)) {
      switch (itemDamage) {
        case 2:
          return orientation == 2;
        case 3:
          return orientation == 3;
        case 4:
          return orientation == 4;
        case 5:
          return orientation == 5;
        default:
          return false;
      }
    } else if (SchematicWorld.isPumpkin(itemId)) {
      switch (itemDamage) {
        case 0x0:
          return orientation == 3;
        case 0x1:
          return orientation == 4;
        case 0x2:
          return orientation == 2;
        case 0x3:
          return orientation == 5;
        default:
          return false;
      }
    } else if (itemId == Item.redstoneRepeater.itemID) {
      switch (itemDamage & 0x3) {
        case 0:
          return orientation == 3;
        case 1:
          return orientation == 4;
        case 2:
          return orientation == 2;
        case 3:
          return orientation == 5;
      }
    } else if (itemId == Block.anvil.blockID) {
      switch (itemDamage & 0x3) {
        case 0:
          return orientation == 5;
        case 1:
          return orientation == 3;
        case 2:
          return orientation == 4;
        case 3:
          return orientation == 2;
      }
    } else if (itemId == Block.fenceGate.blockID) {
      switch (itemDamage & 0x3) {
        case 0:
          return orientation == 2;
        case 1:
          return orientation == 5;
        case 2:
          return orientation == 3;
        case 3:
          return orientation == 4;
      }
    }

    return true;
  }