public synchronized InventoryActionResponse attemptToHandBackToSeller(Player player, int itemId) {
    ItemForSale ifs = this.getItemForSale(itemId);

    if (ifs == null) {
      return new InventoryActionResponse(
          null, false, "Invalid item id! (The item may have already been sold)");
    }

    // double check the player is this player
    PlayerInventoryAccount sellerAccount = this.getSellerAccount(ifs);

    if (sellerAccount == null) {
      return new InventoryActionResponse(null, false, "Invalid seller account... Awhaaa?");
    }

    if (!sellerAccount.getUUID().equals(player.getUniqueId())) {
      return new InventoryActionResponse(
          null, false, "It seems like you aren't the seller of this item.");
    }

    try {
      PreparedStatement markAsSold =
          this.con.prepareStatement(
              "UPDATE "
                  + this.TBL_ITEMS
                  + " SET sold=1,buyer_id=?,sold_at=? WHERE id = ? LIMIT 1;");
      markAsSold.setInt(1, sellerAccount.getdbId());
      markAsSold.setTimestamp(2, new java.sql.Timestamp(new java.util.Date().getTime()));
      markAsSold.setInt(3, itemId);

      markAsSold.executeUpdate();

      this.logger.log(
          Level.INFO,
          "set item id:{0} is:{1} given back to seller {3} {4}",
          new Object[] {
            itemId, ifs.getItemStack(), sellerAccount.getUsername(), sellerAccount.getUUID()
          });
    } catch (Exception ex) {
      this.logger.log(Level.SEVERE, null, ex);

      return new InventoryActionResponse(null, false, "Unable to remove the for sale item");
    }

    return new InventoryActionResponse(
        ifs.getItemStack(),
        true,
        "You retrieved your " + ifs.getItemStack().getType().name() + " from your shop!");
  }
  public synchronized PlayerInventoryAccount getSellerAccount(ItemForSale ifs) {
    try {
      PreparedStatement getSellerAccount =
          this.con.prepareStatement(
              "SELECT id,uuid,username FROM "
                  + this.TBL_ACCOUNTS
                  + " WHERE id=(SELECT seller_id FROM "
                  + this.TBL_ITEMS
                  + " WHERE id=? LIMIT 1) LIMIT 1;");
      getSellerAccount.setInt(1, ifs.getDbID());

      ResultSet result = getSellerAccount.executeQuery();

      if (result.next()) {
        String username = result.getString("username");
        int dbID = result.getInt("id");
        UUID uuid = UUID.fromString(result.getString("uuid"));

        return new PlayerInventoryAccount(dbID, uuid, username);
      }
    } catch (SQLException ex) {
      Logger.getLogger(InventoryManager.class.getName()).log(Level.SEVERE, null, ex);
    }

    return null;
  }
  public synchronized InventoryActionResponse attemptToBuy(Player player, int itemId) {
    PlayerInventoryAccount buyerInventoryAccount = this.getPlayerAccount(player);

    if (buyerInventoryAccount == null) {
      return new InventoryActionResponse(null, false, "Unable to query database for your info!");
    }

    ItemForSale ifs = this.getItemForSale(itemId);

    if (ifs == null) {
      return new InventoryActionResponse(
          null, false, "Invalid item id! (The item may have already been sold)");
    }

    double price = ifs.getPrice();

    if (!plugin.economy.has(player.getName(), price)) {
      return new InventoryActionResponse(
          null, false, "You don't have " + plugin.economy.format(price));
    }

    PlayerInventoryAccount sellerInventoryAccount = this.getSellerAccount(ifs);

    if (sellerInventoryAccount == null) {
      return new InventoryActionResponse(null, false, "Unable to query database for seller info!");
    }

    EconomyResponse buyerWithdrawlResponse = plugin.economy.withdrawPlayer(player.getName(), price);

    if (buyerWithdrawlResponse.type.equals(ResponseType.SUCCESS)) {
      try {
        PreparedStatement markAsSold =
            this.con.prepareStatement(
                "UPDATE "
                    + this.TBL_ITEMS
                    + " SET sold=1,buyer_id=?,sold_at=? WHERE id = ? LIMIT 1;");
        markAsSold.setInt(1, buyerInventoryAccount.getdbId());
        markAsSold.setTimestamp(2, new java.sql.Timestamp(new java.util.Date().getTime()));
        markAsSold.setInt(3, itemId);

        markAsSold.executeUpdate();

        this.logger.log(
            Level.INFO,
            "set item id:{0} is:{1} sold to {2}({3}) for {4}",
            new Object[] {
              itemId,
              ifs.getItemStack(),
              buyerInventoryAccount.getUsername(),
              buyerInventoryAccount.getUUID(),
              price
            });

        EconomyResponse sellerDepositResponse =
            plugin.economy.depositPlayer(sellerInventoryAccount.getUsername(), price);

        if (sellerDepositResponse.type.equals(ResponseType.SUCCESS)) {
          Player seller = Bukkit.getPlayer(sellerInventoryAccount.getUUID());
          ItemStack itemSold = ifs.getItemStack();

          // message if online, mail otherwise
          if (seller != null) {
            seller.sendMessage(
                "LonelyShop: You sold "
                    + itemSold.getAmount()
                    + " "
                    + itemSold.getType()
                    + " for "
                    + plugin.economy.format(price));
          } else {
            Bukkit.getServer()
                .dispatchCommand(
                    Bukkit.getServer().getConsoleSender(),
                    "mail "
                        + sellerInventoryAccount.getUsername()
                        + " You sold "
                        + ifs.getItemStack().getType()
                        + " for "
                        + plugin.economy.format(price));
          }
        }
        // really shouldn't ever happen... Even with LonelyEconomy the money was just given to the
        // server to hand to the player
        else {
          Bukkit.getServer()
              .dispatchCommand(
                  Bukkit.getServer().getConsoleSender(),
                  "mail ne0nx3r0 that scary error happened at "
                      + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date())
                      + " with "
                      + ifs.getItemStack().getType()
                      + " for "
                      + plugin.economy.format(price));
          Bukkit.getServer()
              .dispatchCommand(
                  Bukkit.getServer().getConsoleSender(),
                  "mail "
                      + sellerInventoryAccount.getUsername()
                      + " an error occurred selling "
                      + ifs.getItemStack().getType()
                      + " for "
                      + plugin.economy.format(price)
                      + ", sorry but you did not receive the money for it. Ne0nx3r0 should have been notified.");
        }
      } catch (SQLException ex) {
        this.logger.log(Level.SEVERE, null, ex);

        player.sendMessage(
            ChatColor.RED + "Something bad happened and you really should mention it.");
      }

      return new InventoryActionResponse(
          ifs.getItemStack(),
          true,
          "You bought "
              + ifs.getItemStack().getType().name()
              + " for "
              + plugin.economy.format(price)
              + "!");
    }

    return new InventoryActionResponse(null, false, buyerWithdrawlResponse.errorMessage);
  }