public void callRedstoneEvent(BlockRedstoneEvent event) {
    boolean on = event.getNewCurrent() > event.getOldCurrent();

    for (BlockFace direction :
        Arrays.asList(
            BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.UP)) {
      Block block = event.getBlock().getRelative(direction);
      if (SignUtil.isSign(block)) {
        Sign sign = SignUtil.getSign(block);
        List<SignMechanic> list =
            redstoneSignMechanicMap.get(SignUtil.getMechanicsIdentifier(sign));
        if (list == null) {
          list = new ArrayList<SignMechanic>();
        }
        if (redstoneSignMechanicMap.containsKey(null)) {
          list.addAll(redstoneSignMechanicMap.get(null));
        }
        for (SignMechanic mechanic : list) {
          try {
            BlockBagHandler bag = null;
            BlockMap map = null;
            if (mechanic.hasBlockMapper()) {
              map = mechanic.mapBlocks(sign);
            }
            if (mechanic.hasBlockBag()) {
              bag = BlockBagHandler.locate(sign);
            }
            SignMechanicEventData data = new SignMechanicEventData(map, bag);
            if (on) {
              mechanic.onSignPowerOn(data);
            } else {
              mechanic.onSignPowerOff(data);
            }
          } catch (BlockMapException e) {
            BetterMechanics.log(e.getMessage());
          } catch (BlockBagException e) {
            BetterMechanics.log(e.getMessage());
          }
        }
      } else {
        List<BlockMechanic> list = redstoneBlockMechanicMap.get(block.getType());
        if (list == null) {
          list = new ArrayList<BlockMechanic>();
        }
        if (blockMechanicMap.containsKey(null)) {
          list.addAll(blockMechanicMap.get(null));
        }
        for (BlockMechanic mechanic : list) {
          if (on) {
            mechanic.onBlockPowerOn(event.getBlock());
          } else {
            mechanic.onBlockPowerOff(event.getBlock());
          }
        }
      }
    }
  }
  /**
   * Called when redstone changes From: the source of the redstone change To: The redstone dust that
   * changed
   *
   * @param event Relevant event details
   */
  @Override
  public void onBlockRedstoneChange(BlockRedstoneEvent event) {

    Block blockTo = event.getBlock();
    World world = blockTo.getWorld();

    ConfigurationManager cfg = plugin.getGlobalConfiguration();
    WorldConfiguration wcfg = cfg.get(world);

    if (wcfg.simulateSponge && wcfg.redstoneSponges) {
      int ox = blockTo.getX();
      int oy = blockTo.getY();
      int oz = blockTo.getZ();

      for (int cx = -1; cx <= 1; cx++) {
        for (int cy = -1; cy <= 1; cy++) {
          for (int cz = -1; cz <= 1; cz++) {
            Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
            if (sponge.getTypeId() == 19 && sponge.isBlockIndirectlyPowered()) {
              clearSpongeWater(world, ox + cx, oy + cy, oz + cz);
            } else if (sponge.getTypeId() == 19 && !sponge.isBlockIndirectlyPowered()) {
              addSpongeWater(world, ox + cx, oy + cy, oz + cz);
            }
          }
        }
      }

      return;
    }
  }
 @EventHandler(priority = EventPriority.NORMAL)
 public void onBlockRedstoneChange(BlockRedstoneEvent event) {
   if (event.getNewCurrent() == event.getOldCurrent()
       || event.getNewCurrent() > 0 && event.getOldCurrent() > 0) return;
   RedstoneEvent redstoneEvent =
       new RedstoneEvent(
           (event.getNewCurrent() > 0) ? RedstoneEvent.State.ON : RedstoneEvent.State.OFF, event);
   for (BlockFace blockFace : blockFaces) {
     Block block = event.getBlock().getRelative(blockFace);
     redstoneEvent.setData(
         SignUtil.isSign(event.getBlock().getRelative(blockFace))
             ? Event.Type.SIGN
             : Event.Type.BLOCK,
         event.getBlock(),
         blockFace.getOppositeFace());
     mechanicsHandler.callRedstoneEvent(redstoneEvent);
   }
 }