/**
  * Detects if a Player can use a protectable Block or not
  *
  * @param player the Player involved
  * @param b the Block to be used
  * @return true if the Player can use the Block, false otherwise
  */
 public boolean canUse(final Player player, final Block b) {
   if (Perms.hasProtectionSignBypass(player)) {
     return true;
   }
   final Material blockType = b.getType();
   final String userId = PlayerIdsUtil.getId(player.getName());
   final List<Sign> signLines;
   if (blockType == Material.CHEST || blockType == Material.TRAPPED_CHEST) {
     signLines = SignUtil.getSignsForChest(b);
   } else if (getProtectedMaterials().contains(blockType)) {
     signLines = SignUtil.getSignsForBlock(b);
   } else {
     return true;
   }
   boolean protectedBySign = false;
   boolean explicitlyAllowed = false;
   for (final Sign sign : signLines) {
     if (sign.getLine(0).equals(PROTECTION)) {
       protectedBySign = true;
       if (ColorUtil.stripColorCodes(sign.getLine(1)).equals(userId)
           || ColorUtil.stripColorCodes(sign.getLine(2)).equals(userId)
           || ColorUtil.stripColorCodes(sign.getLine(3)).equals(userId)) {
         explicitlyAllowed = true;
         break;
       }
     }
   }
   return !protectedBySign || explicitlyAllowed;
 }
 /**
  * Detect if a Block can be broken by a Player or by something else (Explosion...)
  *
  * @param b the Block to be broken
  * @param player the Player that want to break the Block, if there is one, null otherwise
  * @return true if the block can be broken [by the Player], false otherwise
  */
 public boolean canBreak(final Block b, final Player player) {
   final Material blockType = b.getType();
   final String userId = player != null ? PlayerIdsUtil.getId(player.getName()) : null;
   if (blockType == Material.SIGN_POST || blockType == Material.WALL_SIGN) {
     final Sign sign = (Sign) b.getState();
     return !sign.getLine(0).equals(PROTECTION)
         || player != null && ColorUtil.stripColorCodes(sign.getLine(3)).equals(userId)
         || player != null && Perms.hasProtectionSignBreak(player);
   } else {
     final List<Sign> signLines;
     if (blockType == Material.CHEST || blockType == Material.TRAPPED_CHEST) {
       signLines = SignUtil.getSignsForChest(b);
     } else if (getProtectedMaterials().contains(blockType)) {
       signLines = SignUtil.getSignsForBlock(b);
     } else {
       return true;
     }
     for (final Sign sign : signLines) {
       if (sign.getLine(0).equals(PROTECTION)) {
         return false;
       }
     }
     return true;
   }
 }
  /**
   * This method checks if a Player with the provided playerName can place a Special Sign at the
   * given Location.
   *
   * <p>This will check every Block that would be affected by this Sign and see if at least one of
   * them is protected, or not.
   *
   * @param loc the Location of the future Sign
   * @param playerName the name of the Player that is placing the Sign
   * @return true if none of the considered Blocks is protected, false otherwise
   */
  public boolean canPlaceSign(final String playerName, final Location loc) {
    final World w = loc.getWorld();
    final int x = loc.getBlockX();
    final int y = loc.getBlockY();
    final int z = loc.getBlockZ();

    final String userId = PlayerIdsUtil.getId(playerName);
    String protecterId;

    protecterId = this.isProtected(w.getBlockAt(x - 1, y, z));
    if (protecterId != null && !protecterId.equals(userId)) {
      return false;
    }

    protecterId = this.isProtected(w.getBlockAt(x + 1, y, z));
    if (protecterId != null && !protecterId.equals(userId)) {
      return false;
    }

    protecterId = this.isProtected(w.getBlockAt(x, y - 1, z));
    if (protecterId != null && !protecterId.equals(userId)) {
      return false;
    }

    protecterId = this.isProtected(w.getBlockAt(x, y + 1, z));
    if (protecterId != null && !protecterId.equals(userId)) {
      return false;
    }

    protecterId = this.isProtected(w.getBlockAt(x, y, z - 1));
    if (protecterId != null && !protecterId.equals(userId)) {
      return false;
    }

    protecterId = this.isProtected(w.getBlockAt(x, y, z + 1));
    return !(protecterId != null && !protecterId.equals(userId));
  }