public function execute($command, $arguments = array(), $options = 0, $filter = null)
    {
        $tag      = $this->nextTag();
        $query    = $tag . ' ' . $command;
        $noresp   = ($options & self::COMMAND_NORESPONSE);
        $response = $noresp ? null : '';

        if (!empty($arguments)) {
            foreach ($arguments as $arg) {
                $query .= ' ' . self::r_implode($arg);
            }
        }

        // Send command
        if (!$this->putLineC($query, true, ($options & self::COMMAND_ANONYMIZED))) {
            preg_match('/^[A-Z0-9]+ ((UID )?[A-Z]+)/', $query, $matches);
            $cmd = $matches[1] ?: 'UNKNOWN';
            $this->setError(self::ERROR_COMMAND, "Failed to send $cmd command");

            return $noresp ? self::ERROR_COMMAND : array(self::ERROR_COMMAND, '');
        }

        // Parse response
        do {
            $line = $this->readLine(4096);

            if ($response !== null) {
                // TODO: Better string literals handling with filter
                if (!$filter || preg_match($filter, $line)) {
                    $response .= $line;
                }
            }

            // parse untagged response for [COPYUID 1204196876 3456:3457 123:124] (RFC6851)
            if ($line && $command == 'UID MOVE') {
                if (preg_match("/^\* OK \[COPYUID [0-9]+ ([0-9,:]+) ([0-9,:]+)\]/i", $line, $m)) {
                    $this->data['COPYUID'] = array($m[1], $m[2]);
                }
            }
        }
        while (!$this->startsWith($line, $tag . ' ', true, true));

        $code = $this->parseResult($line, $command . ': ');

        // Remove last line from response
        if ($response) {
            if (!$filter) {
                $line_len = min(strlen($response), strlen($line));
                $response = substr($response, 0, -$line_len);
            }

            $response = rtrim($response, "\r\n");
        }

        // optional CAPABILITY response
        if (($options & self::COMMAND_CAPABILITY) && $code == self::ERROR_OK
            && preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)
        ) {
            $this->parseCapability($matches[1], true);
        }

        // return last line only (without command tag, result and response code)
        if ($line && ($options & self::COMMAND_LASTLINE)) {
            $response = preg_replace("/^$tag (OK|NO|BAD|BYE|PREAUTH)?\s*(\[[a-z-]+\])?\s*/i", '', trim($line));
        }

        return $noresp ? $code : array($code, $response);
    }