private void transmitMessage(MsgHeaderRequest_PI msgHeaderPI,
            IRodsPI bodyPart,
            RError_PI errorPart, BitstreamCallback bitstreamData,
            ResultCallback callback) throws IOException
    {
        byte[] headerSize;
        byte[] header;
        OutputStream output;


        if ( isClosed() )
        {
            throw new IOException("Attempt to send command to closed connection");
        }

        header = msgHeaderPI.getBytes();
        headerSize = RodsUtil.renderInt(header.length);
        output = connection.getOutputStream();


        //1. Send Header Size
        if ( debug )
        {
            LOG.debug("Sending Header Size: " + header.length);
        }
        output.write(headerSize);

        //2. Send Header
        if ( debug )
        {
            LOG.debug("Sending Header: " + msgHeaderPI);
        }
        output.write(header);

        //3. Send Body
        if ( msgHeaderPI.getMsgLen() > 0 )
        {
            if ( debug )
            {
                LOG.debug("Sending Body: " + bodyPart);
            }
            output.write(bodyPart.getBytes());
        }

        // 4. Send Error
        if ( msgHeaderPI.getErrorLen() > 0 )
        {
            if ( debug )
            {
                LOG.debug("Sending Error: " + errorPart);
            }
            output.write(errorPart.getBytes());
        }


        if ( msgHeaderPI.getBsLen() > 0 )
        {
            //TODO: Wrap outputstream to limit number of bits sent
            if ( debug )
            {
                LOG.debug("Sending bitstream, size: " +
                        msgHeaderPI.getBsLen());
            }
//            RodsOutputStream ros = new RodsOutputStream(output);
            activeOutput = new RodsOutputStream(output, callback);
            bitstreamData.writeBitstream(activeOutput);
            activeOutput = null;
//            ros.close();
        }

        LOG.debug("Flushing");
        output.flush();

    }