@Override
		public void processed(DataChunkImpl chunk) {
			try {
				mgr.registerSelectableChannel(channel, SelectionKey.OP_READ, in, false);
			} catch (IOException e) {
				throw new RuntimeException(e);
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}
    }
    
	private static void write(Object id, SelectionKey key) throws IOException, InterruptedException {
		if(log.isLoggable(Level.FINEST))
			log.finest(key.attachment()+"writing data");
		
		WrapperAndListener struct = (WrapperAndListener)key.attachment();
		BasChannelImpl channel = (BasChannelImpl)struct.getChannel();		
		
		if(log.isLoggable(Level.FINER))
			log.finer(channel+"notifying channel of write");

        channel.writeAll();  
	}
	
	static void unregisterSelectableChannel(RegisterableChannelImpl channel, int ops) {
		SelectorManager2 mgr = channel.getSelectorManager();		
		if(!Thread.currentThread().equals(mgr.getThread()))
			throw new RuntimeException(channel+"Bug, changing selector keys can only be done " +
					"on registration thread because there is not synchronization");

		//this could be dangerous and result in deadlock....may want
		//to move this to the selector thread from jdk bugs!!!
		//but alas, follow KISS, move on...
        Select select = channel.getSelectorManager().getSelector();
        SelectionKey key = channel.keyFor(select);
        if(key == null || !key.isValid()) //no need to unregister, key is cancelled
            return;

		int previous = key.interestOps();
		int opsNow = previous & ~ops; //subtract out the operation
		
		key.interestOps(opsNow);
		
		//make sure we remove the appropriate listener and clean up
		if(key.attachment() != null) {
			WrapperAndListener struct = (WrapperAndListener)key.attachment();
			struct.removeListener(ops);
		}