public static List<BlockFace> calculateConnections(GlowBlock block) {
    List<BlockFace> value = new ArrayList<>();
    List<BlockFace> connections = new ArrayList<>();
    value.add(BlockFace.DOWN);
    for (BlockFace face : SIDES) {
      GlowBlock target = block.getRelative(face);
      switch (target.getType()) {
        case DIODE_BLOCK_ON:
        case DIODE_BLOCK_OFF:
          Diode diode = (Diode) target.getState().getData();
          if (face == diode.getFacing() || face == diode.getFacing().getOppositeFace()) {
            connections.add(face);
          }
          break;
        case REDSTONE_BLOCK:
        case REDSTONE_TORCH_ON:
        case REDSTONE_TORCH_OFF:
        case REDSTONE_WIRE:
        case WOOD_BUTTON:
        case STONE_BUTTON:
        case LEVER:
          connections.add(face);
          break;
        default:
          if (target.getType().isSolid()
              && !block.getRelative(BlockFace.UP).getType().isSolid()
              && target.getRelative(BlockFace.UP).getType() == Material.REDSTONE_WIRE) {
            connections.add(face);
          } else if (!target.getType().isSolid()
              && target.getRelative(BlockFace.DOWN).getType() == Material.REDSTONE_WIRE) {
            connections.add(face);
          }
          break;
      }
    }

    if (connections.isEmpty()) {
      value.addAll(Arrays.asList(SIDES));
    } else {
      value.addAll(connections);
      if (connections.size() == 1) {
        value.add(connections.get(0).getOppositeFace());
      }
    }

    return value;
  }
  @Override
  public void updatePhysics(GlowBlock me) {
    super.updatePhysics(me);

    for (BlockFace face : ADJACENT) {
      GlowBlock target = me.getRelative(face);

      switch (target.getType()) {
        case LEVER:
          Lever lever = (Lever) target.getState().getData();
          if (lever.isPowered()) {
            if (me.getData() != 15) {
              me.setData((byte) 15);
              extraUpdate(me);
            }
            return;
          }
          break;
        case STONE_BUTTON:
        case WOOD_BUTTON:
          Button button = (Button) target.getState().getData();
          if (button.isPowered()) {
            if (me.getData() != 15) {
              me.setData((byte) 15);
              extraUpdate(me);
            }
            return;
          }
          break;
        case DIODE_BLOCK_ON:
          Diode diode = (Diode) target.getState().getData();
          if (face == diode.getFacing().getOppositeFace()) {
            if (me.getData() != 15) {
              me.setData((byte) 15);
              extraUpdate(me);
            }
            return;
          }
          break;
        case REDSTONE_BLOCK:
        case REDSTONE_TORCH_ON:
          if (me.getData() != 15) {
            me.setData((byte) 15);
            extraUpdate(me);
          }
          return;
        default:
          if (target.getType().isSolid()
              && target.getRelative(BlockFace.DOWN).getType() == Material.REDSTONE_TORCH_ON) {
            if (me.getData() != 15) {
              me.setData((byte) 15);
              extraUpdate(me);
            }
            return;
          }
          if (target.getType().isSolid()) {
            for (BlockFace face2 : ADJACENT) {
              GlowBlock target2 = target.getRelative(face2);
              if (target2.getType() == Material.DIODE_BLOCK_ON
                  && ((Diode) target2.getState().getData()).getFacing()
                      == target2.getFace(target)) {
                if (me.getData() != 15) {
                  me.setData((byte) 15);
                  extraUpdate(me);
                }
                return;
              } else if (target2.getType() == Material.STONE_BUTTON
                  || target2.getType() == Material.WOOD_BUTTON) {
                Button button2 = (Button) target2.getState().getData();
                if (button2.isPowered() && button2.getAttachedFace() == target2.getFace(target)) {
                  if (me.getData() != 15) {
                    me.setData((byte) 15);
                    extraUpdate(me);
                  }
                  return;
                }
              } else if (target2.getType() == Material.LEVER) {
                Lever lever2 = (Lever) target2.getState().getData();
                if (lever2.isPowered() && lever2.getAttachedFace() == target2.getFace(target)) {
                  if (me.getData() != 15) {
                    me.setData((byte) 15);
                    extraUpdate(me);
                  }
                  return;
                }
              }
            }
          }
      }
    }

    byte power = 0;

    for (BlockFace face : calculateConnections(me)) {

      if (face == BlockFace.DOWN) {
        continue;
      }

      GlowBlock target = me.getRelative(face);
      if (target.getType() != Material.REDSTONE_WIRE) {
        if (!target.getType().isSolid()) {
          target = target.getRelative(BlockFace.DOWN);
        } else if (!me.getRelative(BlockFace.UP).getType().isSolid()) {
          target = target.getRelative(BlockFace.UP);
        }

        if (target.getType() != Material.REDSTONE_WIRE) {
          // There is no redstone wire here..
          continue;
        }
      }

      if (target.getData() > power) {
        power = (byte) (target.getData() - 1);
      }
    }

    if (power != me.getData()) {
      me.setData(power);
      extraUpdate(me);
      me.getWorld().requestPulse(me, 1, true);
    }
  }