docs: function(self, commands, result, callback) {
    // Base case when there are no more commands to serialize
    if (commands.length === 0) return callback(null, result);
  
    // Pop off the zeroth command and serialize it
    var thisCommand = commands.shift();
    var originalCommandBuffer = thisCommand.toBin();
  
    // Check whether we and the server have agreed to use a compressor
    if (self.options.agreedCompressor && !hasUncompressibleCommands(thisCommand)) {
      // Transform originalCommandBuffer into OP_COMPRESSED
      var concatenatedOriginalCommandBuffer = Buffer.concat(originalCommandBuffer);
      var messageToBeCompressed = concatenatedOriginalCommandBuffer.slice(MESSAGE_HEADER_SIZE);
  
      // Extract information needed for OP_COMPRESSED from the uncompressed message
      var originalCommandOpCode = concatenatedOriginalCommandBuffer.readInt32LE(12);
  
      // Compress the message body
      compress(self, messageToBeCompressed, function(err, compressedMessage) {
        if (err) return callback(err, null);
  
        // Create the msgHeader of OP_COMPRESSED
        var msgHeader = Buffer.alloc(MESSAGE_HEADER_SIZE);
        msgHeader.writeInt32LE(MESSAGE_HEADER_SIZE + 9 + compressedMessage.length, 0); // messageLength
        msgHeader.writeInt32LE(thisCommand.requestId, 4); // requestID
        msgHeader.writeInt32LE(0, 8); // responseTo (zero)
        msgHeader.writeInt32LE(opcodes.OP_COMPRESSED, 12); // opCode
  
        // Create the compression details of OP_COMPRESSED
        var compressionDetails = Buffer.alloc(9);
        compressionDetails.writeInt32LE(originalCommandOpCode, 0); // originalOpcode
        compressionDetails.writeInt32LE(messageToBeCompressed.length, 4); // Size of the uncompressed compressedMessage, excluding the MsgHeader
        compressionDetails.writeUInt8(compressorIDs[self.options.agreedCompressor], 8); // compressorID
  
        // Push the concatenation of the OP_COMPRESSED message onto results
        result.push(Buffer.concat([msgHeader, compressionDetails, compressedMessage]));
  
        // Continue recursing through the commands array
        serializeCommands(self, commands, result, callback);
      });
    } else {
      // Push the serialization of the command onto results
      result.push(originalCommandBuffer);
  
      // Continue recursing through the commands array
      serializeCommands(self, commands, result, callback);
    }
  }