code: @Override
  	public void dispatchFromOutputChannel(Envelope envelope) throws IOException, InterruptedException {
  		EnvelopeReceiverList receiverList = getReceiverListForEnvelope(envelope, true);
  
  		Buffer srcBuffer = envelope.getBuffer();
  		Buffer destBuffer = null;
  		
  		boolean success = false;
  		
  		try {
  			if (receiverList.hasLocalReceiver()) {
  				ChannelID receiver = receiverList.getLocalReceiver();
  				Channel channel = this.channels.get(receiver);
  
  				if (channel == null) {
  					throw new LocalReceiverCancelledException(receiver);
  				}
  
  				if (!channel.isInputChannel()) {
  					throw new IOException("Local receiver " + receiver + " is not an input channel.");
  				}
  
  				InputChannel<?> inputChannel = (InputChannel<?>) channel;
  				
  				// copy the buffer into the memory space of the receiver 
  				if (srcBuffer != null) {
  					try {
  						destBuffer = inputChannel.requestBufferBlocking(srcBuffer.size());
  					} catch (InterruptedException e) {
  						throw new IOException(e.getMessage());
  					}
  
  					srcBuffer.copyToBuffer(destBuffer);
  					envelope.setBuffer(destBuffer);
  					srcBuffer.recycleBuffer();
  				}
  				
  				inputChannel.queueEnvelope(envelope);
  				success = true;
  			}
  			else if (receiverList.hasRemoteReceiver()) {
  				RemoteReceiver remoteReceiver = receiverList.getRemoteReceiver();
  
  				// Generate sender hint before sending the first envelope over the network
  				if (envelope.getSequenceNumber() == 0) {
  					generateSenderHint(envelope, remoteReceiver);
  				}
  
  				this.nettyConnectionManager.enqueue(envelope, remoteReceiver);
  				success = true;
  			}
  		} finally {
  			if (!success) {
  				if (srcBuffer != null) {
  					srcBuffer.recycleBuffer();
  				}
  				if (destBuffer != null) {
  					destBuffer.recycleBuffer();
  				}
  			}
  		}
  	}
docs: -----------------------------------------------------------------------------------------------------------------