// the number of claim blocks a player has available for claiming land
  public int getRemainingClaimBlocks() {
    int remainingBlocks =
        this.optionInitialClaimBlocks + this.getAccruedClaimBlocks() + this.getBonusClaimBlocks();
    for (Claim claim : this.claimList) {
      if (!claim.isAdminClaim() && !claim.isSubdivision()) {
        remainingBlocks -= claim.getArea();
      }
    }

    return remainingBlocks;
  }
  @Override
  public CommandResult execute(CommandSource src, CommandContext ctx) {
    Player player;
    try {
      player = GriefPrevention.checkPlayer(src);
    } catch (CommandException e) {
      src.sendMessage(e.getText());
      return CommandResult.success();
    }
    // which claim is being abandoned?
    PlayerData playerData =
        GriefPrevention.instance.dataStore.getOrCreatePlayerData(
            player.getWorld(), player.getUniqueId());
    Claim claim =
        GriefPrevention.instance.dataStore.getClaimAtPlayer(playerData, player.getLocation(), true);
    UUID ownerId = claim.ownerID;
    if (claim.parent != null) {
      ownerId = claim.parent.ownerID;
    }
    if (claim.isWildernessClaim()) {
      GriefPrevention.sendMessage(player, TextMode.Instr, Messages.AbandonClaimMissing);
      return CommandResult.success();
    } else if (claim.allowEdit(player) != null
        || (!claim.isAdminClaim() && !player.getUniqueId().equals(ownerId))) {
      // verify ownership
      GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotYourClaim);
      return CommandResult.success();
    }

    // warn if has children and we're not explicitly deleting a top level claim
    else if (claim.children.size() > 0 && !deleteTopLevelClaim) {
      GriefPrevention.sendMessage(player, TextMode.Instr, Messages.DeleteTopLevelClaim);
      return CommandResult.empty();
    } else {
      // delete it
      claim.removeSurfaceFluids(null);
      // remove all context permissions
      player.getSubjectData().clearPermissions(ImmutableSet.of(claim.getContext()));
      GriefPrevention.GLOBAL_SUBJECT
          .getSubjectData()
          .clearPermissions(ImmutableSet.of(claim.getContext()));
      GriefPrevention.instance.dataStore.deleteClaim(claim, true);

      // if in a creative mode world, restore the claim area
      if (GriefPrevention.instance.claimModeIsActive(
          claim.getLesserBoundaryCorner().getExtent().getProperties(), ClaimsMode.Creative)) {
        GriefPrevention.addLogEntry(
            player.getName()
                + " abandoned a claim @ "
                + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
        GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning);
        GriefPrevention.instance.restoreClaim(claim, 20L * 60 * 2);
      }

      // this prevents blocks being gained without spending adjust claim blocks when abandoning a
      // top level claim
      if (!claim.isSubdivision() && !claim.isAdminClaim()) {
        int newAccruedClaimCount =
            playerData.getAccruedClaimBlocks()
                - ((int) Math.ceil(claim.getArea() * (1 - playerData.optionAbandonReturnRatio)));
        playerData.setAccruedClaimBlocks(newAccruedClaimCount);
      }

      // tell the player how many claim blocks he has left
      int remainingBlocks = playerData.getRemainingClaimBlocks();
      GriefPrevention.sendMessage(
          player, TextMode.Success, Messages.AbandonSuccess, String.valueOf(remainingBlocks));
      // revert any current visualization
      playerData.revertActiveVisual(player);
      playerData.warnedAboutMajorDeletion = false;
    }

    return CommandResult.success();
  }