public final void addConnection(AbstractSelectableChannelConnection conn, Set<String> allowedEvents) throws ConnectionException {
        
        if (conn.isClosed()) {
            return;
        }

        final SelectableChannel channel = conn.getChannel();
        try {
            synchronized (guard) {
                sel.wakeup();
                
                int interestsOps = 0;
                for (String eventName : allowedEvents) {
                    if (Event.EVENT_READ.equals(eventName)) {
                        interestsOps |= SelectionKey.OP_READ;
                    } else
                    if (Event.EVENT_WRITE.equals(eventName)) {
                        interestsOps |= SelectionKey.OP_WRITE;
                    } else {
                        LOGGER.error("unknown event name '" + eventName + "'");
                        throw new ConnectionException("Unknown event name '" + eventName + "'");
                    }
                }
                
                if (!channel.isRegistered()) {
                    channel.register(sel, interestsOps, conn);
                } else {
                    try {
                        final SelectionKey key = channel.keyFor(sel);
                        if (key != null) {
                            key.interestOps(interestsOps);
                        } else {
                            sel.selectNow();
                            channel.register(sel, interestsOps, conn);
                        }
                    } catch (CancelledKeyException e) {
                        sel.selectNow();
                        channel.register(sel, interestsOps, conn);
                    }
                }
            }

        } catch (Exception e) {
            throw new ConnectionException("cannot add asynchronous context to dispatcher", e);
        }
    }