public void plug (IOThread io_thread_,
            SessionBase session_)
    {
        assert (!plugged);
        plugged = true;
        
        //  Connect to session object.
        assert (session == null);
        assert (session_ != null);
        session = session_;
        socket = session.get_soket ();

        io_object = new IOObject(null);
        io_object.set_handler(this);
        //  Connect to I/O threads poller object.
        io_object.plug (io_thread_);
        io_object.add_fd (handle);
        io_enabled = true;
        
        //  Send the 'length' and 'flags' fields of the identity message.
        //  The 'length' field is encoded in the long format.
        greeting_output_buffer.put ((byte) 0xff);
        greeting_output_buffer.putLong (options.identity_size + 1);
        greeting_output_buffer.put ((byte) 0x7f);

        io_object.set_pollin (handle);
        //  When there's a raw custom encoder, we don't send 10 bytes frame
        boolean custom = false;
        try {
            custom = options.encoder != null && options.encoder.getDeclaredField ("RAW_ENCODER") != null;
        } catch (SecurityException e) {
        } catch (NoSuchFieldException e) {
        }
        
        if (!custom) {
            outsize = greeting_output_buffer.position ();
            outbuf = new Transfer.ByteBufferTransfer ((ByteBuffer) greeting_output_buffer.flip ());
            io_object.set_pollout (handle);
        }        
        
        //  Flush all the data that may have been already received downstream.
        in_event ();
    }