@SuppressWarnings("unchecked")
    private void multiPutOperation(DataStoreOperation op) {
      Set<Future<Pair<String, Boolean>>> set = new HashSet<Future<Pair<String, Boolean>>>();
      Map<String, Boolean> mapResults = new HashMap<String, Boolean>();
      String tablename = ((MultiPutOperation) op).getTableName();

      if (tablename.equals("friendsTimeLine")) {
        Map<String, Pair<String, String>> map = ((MultiPutOperation) op).getMapKeyToDataAndTags();
        Set<String> keys = map.keySet();
        Iterator<String> iter = keys.iterator();
        String follower;
        while (iter.hasNext()) {
          follower = iter.next();

          Pair<String, String> pair = map.get(follower);
          String date = pair.getFirst();
          String tweetId = pair.getSecond();

          Callable<Pair<String, Boolean>> callable =
              new TMultiPutMySqlFriendsTimeline(this.borrowClient(), follower, date, tweetId);
          Future<Pair<String, Boolean>> future = this.pool.submit(callable);
          set.add(future);
        }
        for (Future<Pair<String, Boolean>> future : set) {
          try {
            Pair<String, Boolean> aux = future.get();
            mapResults.put(aux.getFirst(), aux.getSecond());
          } catch (InterruptedException e) {
            e.printStackTrace();
          } catch (ExecutionException e) {
            e.printStackTrace();
          }
        }
        ((MultiPutOperation) op).setMapResults(mapResults);
        op.notifyListeners();

      } else {
        if (tablename.equals("users")) {
          Map<String, Pair<Map<String, String>, List<String>>> map =
              ((MultiPutOperation) op).getMapKeyToDataAndTags();
          Set<String> keys = map.keySet();
          Iterator<String> iter = keys.iterator();
          String userid;
          while (iter.hasNext()) {
            userid = iter.next();
            Pair<Map<String, String>, List<String>> hash = map.get(userid);
            Map<String, String> userFields = hash.getFirst();
            Callable<Pair<String, Boolean>> callable =
                new TMultiPutMySqlUsers(this.borrowClient(), userid, userFields);
            Future<Pair<String, Boolean>> future = this.pool.submit(callable);
            set.add(future);
          }
          for (Future<Pair<String, Boolean>> future : set) {
            try {
              Pair<String, Boolean> aux = future.get();
              mapResults.put(aux.getFirst(), aux.getSecond());
            } catch (InterruptedException e) {
              e.printStackTrace();
            } catch (ExecutionException e) {
              e.printStackTrace();
            }
          }
          ((MultiPutOperation) op).setMapResults(mapResults);
          op.notifyListeners();
        }
      }
    }
    @SuppressWarnings("unchecked")
    private void putOperation(DataStoreOperation op)
        throws UnsupportedEncodingException, SQLException {
      // long timestamp;
      boolean res = false;
      java.sql.Connection conn = null;
      Comparable key = ((PutOperation) op).getKey();
      String tablename = ((PutOperation) op).getTableName();

      if (tablename.equals("friendsTimeLine")) { // SERA QUASE UM MULTIPUT DE TIMELINE
        conn = this.borrowClient();
        String query =
            "insert into "
                + tablename
                + " (tweetID,userID,date) values (?,?,?)"; // on duplicate key udpdate userID =
        // values(userID), date = values(date)";
        PreparedStatement stmt = conn.prepareStatement(query);
        List<Pair<String, String>> value =
            (List<Pair<String, String>>) ((PutOperation) op).getData();
        for (Pair<String, String> pair : value) {
          String date = pair.getFirst();
          String tweetID = pair.getSecond();
          stmt.setString(1, tweetID /*+":"+date*/);
          stmt.setString(2, (String) key);
          stmt.setString(3, date);
          stmt.executeUpdate();
        }
        stmt.close();
        this.releaseClient(conn);
        res = true;
        ((PutOperation) op).setResult(res);
        op.notifyListeners();
      } else {
        if (tablename.equals("users")) {
          Map<String, String> value = (Map<String, String>) ((PutOperation) op).getData();
          String query;
          int i;
          // String query = "insert into "+tablename+"
          // (userID,name,password,following,followers,username,lasttweet,created) values
          // (?,?,?,?,?,?,?,?)";
          if (value.size() < 7) {
            i = 0;
            query = "update " + tablename + " set ";
          } else {
            i = 1;
            query =
                "insert into "
                    + tablename
                    + " "; // (userID,name,password,following,followers,username,lasttweet,created)
            // values (?,?,?,?,?,?,?,?)";
          }
          Set<String> keys = value.keySet();
          Iterator<String> iter = keys.iterator();
          ArrayList<String> columnNames = new ArrayList<String>();
          ArrayList<String> columnValues = new ArrayList<String>();

          while (iter.hasNext()) { // FUNCIONA PARA O INSERT e UPDATE
            String columnName = iter.next();
            columnNames.add(columnName);
            columnValues.add(value.get(columnName));
          }
          conn = this.borrowClient();
          Statement stmt = conn.createStatement();
          try {
            if (i == 0)
              query += this.buildUpdateQuery("userID", (String) key, columnNames, columnValues);
            else
              query +=
                  this.buildInsertNamesQuery("userID", columnNames)
                      + " values "
                      + this.buildInsertValuesQuery((String) key, columnValues)
                      + " on duplicate key update "
                      + this.buildDuplicateNamesQuery(columnNames);
            // System.out.println("QUERY:" +query);
            stmt.executeUpdate(query);
          } finally {
            try {
              stmt.close();
            } catch (Exception e) {
            }
            this.releaseClient(conn);
          }
          res = true;
          // System.out.println("PUTOP SETRESULT");
          ((PutOperation) op).setResult(res);
          op.notifyListeners();
        } else {
          Map<String, String> value = (Map<String, String>) ((PutOperation) op).getData();
          // conn = this.borrowClient(op);
          // String query = "insert into "+tablename+" (tweetID,id,text,date,user) values
          // (?,?,?,?,?,?,?,?)";
          String query = "insert into " + tablename + " "; // tweets

          ArrayList<String> columnNames = new ArrayList<String>();
          ArrayList<String> columnValues = new ArrayList<String>();
          Set<String> keys = value.keySet();
          Iterator<String> iter = keys.iterator();
          while (iter.hasNext()) {
            String columnName = iter.next();
            columnNames.add(columnName);
            columnValues.add(value.get(columnName));
          }
          conn = this.borrowClient();
          Statement stmt = conn.createStatement();
          try {
            query +=
                this.buildInsertNamesQuery("tweetID", columnNames)
                    + " values "
                    + this.buildInsertValuesQuery((String) key, columnValues)
                    + " on duplicate key update "
                    + this.buildDuplicateNamesQuery(columnNames);
            stmt.executeUpdate(query);
            // System.out.println(stmt.executeUpdate(query));
          } finally {
            try {
              stmt.close();
            } catch (Exception e) {
            }
            // this.releaseClient(conn);
          }

          //// INSERT IN TWEET TAGS
          Set<String> tags = ((PutOperation) op).getTags();
          query = "insert into tweetsTags "; // topic,user) values (?,?,?) on duplicate key update
          // topic=values(topic),user=values(user)";
          PreparedStatement st = conn.prepareStatement(query);

          columnNames = new ArrayList<String>(3);
          columnValues = new ArrayList<String>(2);
          // columnNames.add("tweetID");
          // columnValues.add((String) key); ///TWEETID
          columnNames.add("topic");
          columnNames.add("user");

          if (!tags.isEmpty()) {
            Iterator<String> it = tags.iterator();
            while (it.hasNext()) {
              String tag = it.next();
              if (tag.startsWith("topico")) {
                columnValues.add(tag); // TOPIC
              } else if (tag.startsWith("user")) {
                columnValues.add(tag); // USER
              }
            }
          }
          query +=
              this.buildInsertNamesQuery("tweetID", columnNames)
                  + " values "
                  + this.buildInsertValuesQueryForTweetsTags((String) key, columnValues)
                  + " on duplicate key update "
                  + this.buildDuplicateNamesQuery(columnNames);
          // System.out.println("TAGS PUTOP QUERY:"+query);
          try {
            // System.out.println(st.toString());
            st.executeUpdate(query);
          } finally {
            try {
              st.close();
            } catch (Exception e) {
            }
            this.releaseClient(conn);
          }
          ///// FINISH TAGS
          res = true;

          ((PutOperation) op).setResult(res);
          op.notifyListeners();
        }
      }
    }