protected function _getLine(
        Horde_Imap_Client_Interaction_Pipeline $pipeline
    )
    {
        $server = Horde_Imap_Client_Interaction_Server::create(
            $this->_connection->read()
        );

        switch (get_class($server)) {
        case 'Horde_Imap_Client_Interaction_Server_Continuation':
            $this->_responseCode($pipeline, $server);
            break;

        case 'Horde_Imap_Client_Interaction_Server_Tagged':
            $cmd = $pipeline->complete($server);
            if (is_null($cmd)) {
                /* This indicates a "dangling" tagged response - it was either
                 * generated by an aborted previous pipeline object or is the
                 * result of spurious output by the server. Ignore. */
                return $this->_getLine($pipeline);
            }

            if ($timer = $cmd->getTimer()) {
                $this->_debug->info(sprintf(
                    'Command %s took %s seconds.',
                    $cmd->tag,
                    $timer
                ));
            }
            $this->_responseCode($pipeline, $server);

            if (is_callable($cmd->on_success)) {
                call_user_func($cmd->on_success);
            }
            break;

        case 'Horde_Imap_Client_Interaction_Server_Untagged':
            if (is_null($server->status)) {
                $this->_serverResponse($pipeline, $server);
            } else {
                $this->_responseCode($pipeline, $server);
            }
            break;
        }

        switch ($server->status) {
        case $server::BAD:
        case $server::NO:
            /* A tagged BAD response indicates that the tagged command caused
             * the error. This information is unknown if untagged (RFC 3501
             * [7.1.3]) - ignore these untagged responses.
             * An untagged NO response indicates a warning; ignore and assume
             * that it also included response text code that is handled
             * elsewhere. Throw exception if tagged; command handlers can
             * catch this if able to workaround this issue (RFC 3501
             * [7.1.2]). */
            if ($server instanceof Horde_Imap_Client_Interaction_Server_Tagged) {
                /* Check for a on_error callback. If function returns true,
                 * ignore the error. */
                if (($cmd = $pipeline->getCmd($server->tag)) &&
                    is_callable($cmd->on_error) &&
                    call_user_func($cmd->on_error)) {
                    break;
                }

                throw new Horde_Imap_Client_Exception_ServerResponse(
                    Horde_Imap_Client_Translation::r("IMAP error reported by server."),
                    0,
                    $server,
                    $pipeline
                );
            }
            break;

        case $server::BYE:
            /* A BYE response received as part of a logout command should be
             * be treated like a regular command: a client MUST process the
             * entire command until logging out (RFC 3501 [3.4; 7.1.5]). */
            if (empty($this->_temp['logout'])) {
                $e = new Horde_Imap_Client_Exception(
                    Horde_Imap_Client_Translation::r("IMAP Server closed the connection."),
                    Horde_Imap_Client_Exception::DISCONNECT
                );
                $e->details = strval($server);
                throw $e;
            }
            break;

        case $server::PREAUTH:
            /* The user was pre-authenticated. (RFC 3501 [7.1.4]) */
            $this->_temp['preauth'] = true;
            break;
        }

        return $server;
    }