@Override
    protected void process_pipe_term ()
    {
        //  This is the simple case of peer-induced termination. If there are no
        //  more pending messages to read, or if the pipe was configured to drop
        //  pending messages, we can move directly to the terminating state.
        //  Otherwise we'll hang up in pending state till all the pending messages
        //  are sent.
        if (state == State.active) {
            if (!delay) {
                state = State.terminating;
                outpipe = null;
                send_pipe_term_ack (peer);
            }
            else
                state = State.pending;
            return;
        }

        //  Delimiter happened to arrive before the term command. Now we have the
        //  term command as well, so we can move straight to terminating state.
        if (state == State.delimited) {
            state = State.terminating;
            outpipe = null;
            send_pipe_term_ack (peer);
            return;
        }

        //  This is the case where both ends of the pipe are closed in parallel.
        //  We simply reply to the request by ack and continue waiting for our
        //  own ack.
        if (state == State.terminated) {
            state = State.double_terminated;
            outpipe = null;
            send_pipe_term_ack (peer);
            return;
        }

        //  pipe_term is invalid in other states.
        assert (false);
    }