private void registerChannelOnThisThread(
			RegisterableChannelImpl channel, int validOps, Object listener) 
												throws ClosedChannelException {
		if(channel == null)
			throw new IllegalArgumentException("cannot register a null channel");
		else if(!Thread.currentThread().equals(selector.getThread()))
			throw new IllegalArgumentException("This function can only be invoked on PollingThread");
		else if(channel.isClosed())
			return; //do nothing if the channel is closed
		else if(!selector.isRunning())
			return; //do nothing if the selector is not running
		
		WrapperAndListener struct;
		SelectableChannel s = channel.getRealChannel();
		
		int previousOps = 0;
		if (log.isLoggable(Level.FINEST))
			log.log(Level.FINEST, channel+"registering2="+s+" ops="+Helper.opType(validOps));
        
		SelectionKey previous = channel.keyFor(selector);
		if(previous == null) {
			struct = new WrapperAndListener(channel);
		}else if(previous.attachment() == null) {
			struct = new WrapperAndListener(channel);
			previousOps = previous.interestOps();
		} else {
			struct = (WrapperAndListener)previous.attachment();
			previousOps = previous.interestOps();
		}
		struct.addListener(id, listener, validOps);
		int allOps = previousOps | validOps;
		SelectionKey key = channel.register(selector, allOps, struct);
		channel.setKey(key);
		if (log.isLoggable(Level.FINER))
			log.log(Level.FINER, channel+"registered2="+s+" allOps="+Helper.opType(allOps));		
	}