def prepare(self, params=None):

        if isinstance(params, tuple) or isinstance(params, list):
            try:
                self.set_command_type(params[0])

                self._query = params[1]
                self._limit = params[2]
                self._fetch_plan = params[3]

                # callback function use to operate
                # over the async fetched records
                self.set_callback(params[4])

            except IndexError:
                # Use default for non existent indexes
                pass

        if self._command_type == QUERY_CMD \
                or self._command_type == QUERY_SYNC \
                or self._command_type == QUERY_SCRIPT \
                or self._command_type == QUERY_GREMLIN:
            self._mod_byte = 's'
        else:
            if self._callback is None:
                raise PyOrientBadMethodCallException("No callback was provided.", [])
            self._mod_byte = 'a'

        _payload_definition = [
            (FIELD_STRING, self._command_type),
            (FIELD_STRING, self._query)
        ]

        if self._command_type == QUERY_ASYNC \
                or self._command_type == QUERY_SYNC \
                or self._command_type == QUERY_GREMLIN:

            # a limit specified in a sql string should always override a
            # limit parameter pass to prepare()
            if ' LIMIT ' not in self._query.upper() or self._command_type == QUERY_GREMLIN:
                _payload_definition.append((FIELD_INT, self._limit))
            else:
                _payload_definition.append((FIELD_INT, -1))

            _payload_definition.append((FIELD_STRING, self._fetch_plan))

        if self._command_type == QUERY_SCRIPT:
            _payload_definition.insert(1, (FIELD_STRING, 'sql'))

        _payload_definition.append((FIELD_INT, 0))

        payload = b''.join(
            self._encode_field(x) for x in _payload_definition
        )

        self._append((FIELD_BYTE, self._mod_byte))
        self._append((FIELD_STRING, payload))

        return super(CommandMessage, self).prepare()