@Override
  public T execute(final InternalConnection connection) {
    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug(
          format(
              "Sending command {%s : %s} to database %s on connection [%s] to server %s",
              getCommandName(),
              command.values().iterator().next(),
              namespace.getDatabaseName(),
              connection.getDescription().getConnectionId(),
              connection.getDescription().getServerAddress()));
    }
    long startTimeNanos = System.nanoTime();
    CommandMessage commandMessage =
        new CommandMessage(
            namespace.getFullName(),
            command,
            slaveOk,
            fieldNameValidator,
            ProtocolHelper.getMessageSettings(connection.getDescription()));
    ResponseBuffers responseBuffers = null;
    try {
      sendMessage(commandMessage, connection);
      responseBuffers = connection.receiveMessage(commandMessage.getId());
      if (!ProtocolHelper.isCommandOk(
          new BsonBinaryReader(new ByteBufferBsonInput(responseBuffers.getBodyByteBuffer())))) {
        throw getCommandFailureException(
            getResponseDocument(responseBuffers, commandMessage, new BsonDocumentCodec()),
            connection.getDescription().getServerAddress());
      }

      T retval = getResponseDocument(responseBuffers, commandMessage, commandResultDecoder);

      if (commandListener != null) {
        sendSucceededEvent(
            connection.getDescription(),
            startTimeNanos,
            commandMessage,
            getResponseDocument(responseBuffers, commandMessage, new RawBsonDocumentCodec()));
      }
      LOGGER.debug("Command execution completed");
      return retval;
    } catch (RuntimeException e) {
      sendFailedEvent(connection.getDescription(), startTimeNanos, commandMessage, e);
      throw e;
    } finally {
      if (responseBuffers != null) {
        responseBuffers.close();
      }
    }
  }
 @Override
 public void executeAsync(
     final InternalConnection connection, final SingleResultCallback<T> callback) {
   long startTimeNanos = System.nanoTime();
   CommandMessage message =
       new CommandMessage(
           namespace.getFullName(),
           command,
           slaveOk,
           fieldNameValidator,
           ProtocolHelper.getMessageSettings(connection.getDescription()));
   boolean sentStartedEvent = false;
   try {
     if (LOGGER.isDebugEnabled()) {
       LOGGER.debug(
           format(
               "Asynchronously sending command {%s : %s} to database %s on connection [%s] to server %s",
               getCommandName(),
               command.values().iterator().next(),
               namespace.getDatabaseName(),
               connection.getDescription().getConnectionId(),
               connection.getDescription().getServerAddress()));
     }
     ByteBufferBsonOutput bsonOutput = new ByteBufferBsonOutput(connection);
     int documentPosition =
         ProtocolHelper.encodeMessageWithMetadata(message, bsonOutput).getFirstDocumentPosition();
     sendStartedEvent(connection, bsonOutput, message, documentPosition);
     sentStartedEvent = true;
     SingleResultCallback<ResponseBuffers> receiveCallback =
         new CommandResultCallback(callback, message, connection.getDescription(), startTimeNanos);
     connection.sendMessageAsync(
         bsonOutput.getByteBuffers(),
         message.getId(),
         new SendMessageCallback<T>(
             connection,
             bsonOutput,
             message,
             getCommandName(),
             startTimeNanos,
             commandListener,
             callback,
             receiveCallback));
   } catch (Throwable t) {
     if (sentStartedEvent) {
       sendFailedEvent(connection.getDescription(), startTimeNanos, message, t);
     }
     callback.onResult(null, t);
   }
 }
 private BsonDocument getCommand(final ConnectionDescription description) {
   BsonDocument outputDocument =
       new BsonDocument(getAction(), new BsonString(getCollectionName()));
   outputDocument.append("sharded", BsonBoolean.valueOf(isSharded()));
   outputDocument.append("nonAtomic", BsonBoolean.valueOf(isNonAtomic()));
   if (getDatabaseName() != null) {
     outputDocument.put("db", new BsonString(getDatabaseName()));
   }
   BsonDocument commandDocument =
       new BsonDocument("mapreduce", new BsonString(namespace.getCollectionName()))
           .append("map", getMapFunction())
           .append("reduce", getReduceFunction())
           .append("out", outputDocument)
           .append("query", asValueOrNull(getFilter()))
           .append("sort", asValueOrNull(getSort()))
           .append("finalize", asValueOrNull(getFinalizeFunction()))
           .append("scope", asValueOrNull(getScope()))
           .append("verbose", BsonBoolean.valueOf(isVerbose()));
   putIfNotZero(commandDocument, "limit", getLimit());
   putIfNotZero(commandDocument, "maxTimeMS", getMaxTime(MILLISECONDS));
   putIfTrue(commandDocument, "jsMode", isJsMode());
   if (bypassDocumentValidation != null
       && description != null
       && serverIsAtLeastVersionThreeDotTwo(description)) {
     commandDocument.put(
         "bypassDocumentValidation", BsonBoolean.valueOf(bypassDocumentValidation));
   }
   if (description != null) {
     appendWriteConcernToCommand(writeConcern, commandDocument, description);
   }
   if (collation != null) {
     commandDocument.put("collation", collation.asDocument());
   }
   return commandDocument;
 }
 private CommandReadOperation<BsonDocument> createExplainableOperation(
     final ExplainVerbosity explainVerbosity) {
   return new CommandReadOperation<BsonDocument>(
       namespace.getDatabaseName(),
       ExplainHelper.asExplainCommand(getCommand(null), explainVerbosity),
       new BsonDocumentCodec());
 }
 private void sendStartedEvent(
     final InternalConnection connection,
     final ByteBufferBsonOutput bsonOutput,
     final CommandMessage message,
     final int documentPosition) {
   if (commandListener != null) {
     ByteBufBsonDocument byteBufBsonDocument = createOne(bsonOutput, documentPosition);
     BsonDocument commandDocument;
     if (byteBufBsonDocument.containsKey("$query")) {
       commandDocument = byteBufBsonDocument.getDocument("$query");
       commandName = commandDocument.keySet().iterator().next();
     } else {
       commandDocument = byteBufBsonDocument;
       commandName = byteBufBsonDocument.getFirstKey();
     }
     BsonDocument commandDocumentForEvent =
         (SECURITY_SENSITIVE_COMMANDS.contains(commandName))
             ? new BsonDocument()
             : commandDocument;
     sendCommandStartedEvent(
         message,
         namespace.getDatabaseName(),
         commandName,
         commandDocumentForEvent,
         connection.getDescription(),
         commandListener);
   }
 }