protected Operation transform(DeleteOperation delA, InsertOperation insB) {

    int posA = delA.getPosition();
    int lenA = delA.getTextLength();
    int posB = insB.getPosition();
    int lenB = insB.getTextLength();

    if (posB >= (posA + lenA)) {
      /*
       * Operation B is completely after operation A.
       */
      return delA;
    } else if (posB <= posA) {
      /*
       * Operation B starts before or at the same position like operation
       * A
       */
      return new DeleteOperation(posA + lenB, delA.getText());
    } else {
      /*
       * Operation B (insert) is in the range of operation A (delete).
       * Operation A' must be split up into two delete operations. (A):
       * "123456" (A'): "1" "23456"
       */
      DeleteOperation del1 = new DeleteOperation(posA, delA.getText().substring(0, posB - posA));
      DeleteOperation del2 =
          new DeleteOperation(posA + lenB, delA.getText().substring(posB - posA, lenA));
      return new SplitOperation(del1, del2);
    }
  }
  protected Operation transform(InsertOperation insA, DeleteOperation delB) {

    int posA = insA.getPosition();
    int posB = delB.getPosition();
    int lenB = delB.getTextLength();

    if (posA <= posB) {
      /*
       * Operation A starts before or at the same position like operation
       */
      return insA;
    } else if (posA > (posB + lenB)) {
      /*
       * Operation A starts after operation B. Index of operation A' must
       * be reduced by the length of the text of operation B.
       */
      return new InsertOperation(posA - lenB, insA.getText(), insA.getOrigin());
    } else {
      /*
       * Operation A starts in operation B. Index of A' must be the index
       * of operation B.
       */
      return new InsertOperation(posB, insA.getText(), insA.getOrigin());
    }
  }
  protected Operation transform(DeleteOperation delA, DeleteOperation delB) {

    int posA = delA.getPosition();
    int lenA = delA.getTextLength();
    int posB = delB.getPosition();
    int lenB = delB.getTextLength();

    if (posB >= (posA + lenA)) {
      /*
       * Operation A is completely before operation B.
       */
      return delA;
    } else if (posA >= (posB + lenB)) {
      /*
       * Operation A starts at the end or after operation B. Index of
       * operation A' must be reduced by the length of the text of
       * operation B.
       */
      return new DeleteOperation(posA - lenB, delA.getText());
    } else {
      /*
       * Operation A and operation B are overlapping.
       */
      if ((posB <= posA) && ((posA + lenA) <= (posB + lenB))) {
        /*
         * Operation B starts before or at the same position like
         * operation A and ends after or at the same position like
         * operation A.
         */
        return new NoOperation();
      } else if ((posB <= posA) && ((posA + lenA) > (posB + lenB))) {
        /*
         * Operation B starts before or at the same position like
         * operation A and ends before operation A.
         */
        return new DeleteOperation(posB, delA.getText().substring(posB + lenB - posA, lenA));
      } else if ((posB > posA) && ((posB + lenB) >= (posA + lenA))) {
        /*
         * Operation B starts after operation A and ends after or at the
         * same position like operation A.
         */
        return new DeleteOperation(posA, delA.getText().substring(0, posB - posA));
      } else {
        /*
         * Operation B is fully in operation A.
         */
        return new DeleteOperation(
            posA,
            delA.getText().substring(0, posB - posA)
                + delA.getText().substring(posB + lenB - posA, lenA));
      }
    }
  }
    @SuppressWarnings("unchecked")
    private void deleteOperation(DataStoreOperation op) throws SQLException {
      Comparable key = ((DeleteOperation) op).getKey();
      String tablename = ((DeleteOperation) op).getTableName();
      java.sql.Connection conn = null;

      // System.out.println("OP:"+op.toString());

      if (tablename.equals("friendsTimeLine")) {
        List<String> pos = ((DeleteOperation) op).getColumns();
        conn = this.borrowClient();
        String query =
            "delete from " + tablename + " where userID = '" + (String) key + "' and date = ?";
        PreparedStatement stmt = null;

        try {
          stmt = conn.prepareStatement(query);
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          // e.printStackTrace();
          System.out.println("prepare");
        }

        // System.out.println(query);
        // System.out.println(pos.toString());
        for (String str : pos) {
          // System.out.println("delete 2");
          try {
            stmt.setString(1, str);
          } catch (SQLException e) {
            System.out.println("setString" + query + "=" + str);
          }
          // System.out.println(query+"="+str);
          // System.out.println(stmt.toString());
          try {
            stmt.executeUpdate();
          } catch (SQLException e) {

            // e.printStackTrace();
            System.out.println("EXCEP" + query + "=" + str);
            System.out.println("EXCEP" + stmt.toString());
          }
        }

        try {
          stmt.close();
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } finally {
          this.releaseClient(conn);
        }
      }

      ((DeleteOperation) op).setResult(true);
      op.notifyListeners();
    }
  @Override
  public JsonObject visit(DeleteOperation operation) throws Throwable {
    MobileServiceJsonTable table = this.getRemoteTable(operation.getTableName());
    ListenableFuture<Void> future = table.delete(this.mItem);

    try {
      future.get();

      return null;
    } catch (ExecutionException ex) {

      if (!ExceptionIs404NotFound(ex)) {
        throw ex.getCause();
      }

      return null;
    }
  }