@Override public void produceData(final IOSession iosession, final ServerState sessionState) throws IOException, SMTPProtocolException { Args.notNull(iosession, "IO session"); Args.notNull(sessionState, "Session state"); SessionOutputBuffer buf = this.iobuffers.getOutbuf(); synchronized (sessionState) { if (this.actionFuture != null) { SMTPReply reply = getReply(this.actionFuture); this.actionFuture = null; this.writer.write(reply, buf); } if (this.actionFuture == null) { while (!this.pendingActions.isEmpty()) { Action<ServerState> action = this.pendingActions.remove(); Future<SMTPReply> future = action.execute(sessionState, new OutputTrigger<SMTPReply>(sessionState, iosession)); if (future.isDone()) { SMTPReply reply = getReply(future); this.writer.write(reply, buf); } else { this.actionFuture = future; break; } } } if (buf.hasData()) { buf.flush(iosession.channel()); } if (!buf.hasData()) { if (sessionState.getDataType() != null) { this.completed = true; } if (sessionState.isTerminated()) { iosession.close(); } else { iosession.clearEvent(SelectionKey.OP_WRITE); } } } }