@Override
  public void deleteDocument(String docId, String prevRevId) throws ConflictException {
    Preconditions.checkState(this.isOpen(), "Database is closed");
    Preconditions.checkArgument(
        !Strings.isNullOrEmpty(docId), "Input document id can not be empty");
    Preconditions.checkArgument(
        !Strings.isNullOrEmpty(prevRevId), "Input previous revision id can not be empty");

    CouchUtils.validateRevisionId(prevRevId);

    DocumentDeleted documentDeleted = null;
    this.sqlDb.beginTransaction();
    try {
      BasicDocumentRevision preRevision = this.getDocument(docId, prevRevId);
      if (preRevision == null) {
        throw new IllegalArgumentException("The document trying to update does not exist.");
      }

      DocumentRevisionTree revisionTree = this.getAllRevisionsOfDocument(docId);
      if (revisionTree == null) {
        throw new IllegalArgumentException("Document does not exist for id: " + docId);
      } else if (!revisionTree.leafRevisionIds().contains(prevRevId)) {
        throw new ConflictException("Revision to be deleted is not a leaf node:" + prevRevId);
      }

      if (!preRevision.isDeleted()) {
        this.checkOffPreviousWinnerRevisionStatus(preRevision);
        String newRevisionId = CouchUtils.generateNextRevisionId(preRevision.getRevision());
        // Previous revision to be deleted could be winner revision ("current" == true),
        // or a non-winner leaf revision ("current" == false), the new inserted
        // revision must have the same flag as it previous revision.
        // Deletion of non-winner leaf revision is mainly used when resolving
        // conflicts.
        this.insertRevision(
            preRevision.getInternalNumericId(),
            newRevisionId,
            preRevision.getSequence(),
            true,
            preRevision.isCurrent(),
            JSONUtils.EMPTY_JSON,
            false);
        BasicDocumentRevision newRevision = this.getDocument(preRevision.getId(), newRevisionId);
        documentDeleted = new DocumentDeleted(preRevision, newRevision);
      }

      // Very tricky! Must call setTransactionSuccessful() even no change
      // to the db within this method. This is to allow this method to be
      // nested to other outer transaction, otherwise, the outer transaction
      // will rollback.
      this.sqlDb.setTransactionSuccessful();
    } finally {
      this.sqlDb.endTransaction();
      if (documentDeleted != null) {
        eventBus.post(documentDeleted);
      }
    }
  }
 private String insertNewWinnerRevision(DocumentBody newWinner, DocumentRevision oldWinner) {
   String newRevisionId = CouchUtils.generateNextRevisionId(oldWinner.getRevision());
   this.insertRevision(
       oldWinner.getInternalNumericId(),
       newRevisionId,
       oldWinner.getSequence(),
       false,
       true,
       newWinner.asBytes(),
       true);
   return newRevisionId;
 }