code: @Override
  	public void queueEnvelope(Envelope envelope) {
  		// The sequence number of the envelope to be queued
  		final int sequenceNumber = envelope.getSequenceNumber();
  
  		synchronized (this.queuedEnvelopes) {
  
  			if (this.destroyCalled) {
  				final Buffer buffer = envelope.getBuffer();
  				if (buffer != null) {
  					buffer.recycleBuffer();
  				}
  				return;
  			}
  
  			final int expectedSequenceNumber = this.lastReceivedEnvelope + 1;
  			if (sequenceNumber != expectedSequenceNumber) {
  				// This is a problem, now we are actually missing some data
  				reportIOException(new IOException("Expected data packet " + expectedSequenceNumber + " but received " + sequenceNumber));
  
  				// notify that something (an exception) is available
  				notifyGateThatInputIsAvailable();
  
  				if (LOG.isDebugEnabled()) {
  					LOG.debug("Input channel " + this.toString() + " expected envelope " + expectedSequenceNumber
  							+ " but received " + sequenceNumber);
  				}
  
  				// rescue the buffer
  				final Buffer buffer = envelope.getBuffer();
  				if (buffer != null) {
  					buffer.recycleBuffer();
  				}
  			} else {
  
  				this.queuedEnvelopes.add(envelope);
  				this.lastReceivedEnvelope = sequenceNumber;
  				this.lastSourceID = envelope.getSource();
  
  				// Notify the channel about the new data. notify as much as there is (buffer plus once per event)
  				if (envelope.getBuffer() != null) {
  					notifyGateThatInputIsAvailable();
  				}
  
  				List<? extends AbstractEvent> events = envelope.deserializeEvents();
  
  				if (events != null) {
  					for (int i = 0; i < events.size(); i++) {
  						notifyGateThatInputIsAvailable();
  					}
  				}
  			}
  		}
  	}
docs: InputChannelContext