function singleEventPubSub(eventType, newListener, removeListener){

   /** we are optimised for emitting events over firing them.
    *  As well as the tuple list which stores event ids and
    *  listeners there is a list with just the listeners which 
    *  can be iterated more quickly when we are emitting
    */
   var listenerTupleList,
       listenerList;

   function hasId(id){
      return function(tuple) {
         return tuple.id == id;      
      };  
   }
              
   return {

      /**
       * @param {Function} listener
       * @param {*} listenerId 
       *    an id that this listener can later by removed by. 
       *    Can be of any type, to be compared to other ids using ==
       */
      on:function( listener, listenerId ) {
         
         var tuple = {
            listener: listener
         ,  id:       listenerId || listener // when no id is given use the
                                             // listener function as the id
         };

         if( newListener ) {
            newListener.emit(eventType, listener, tuple.id);
         }
         
         listenerTupleList = cons( tuple,    listenerTupleList );
         listenerList      = cons( listener, listenerList      );

         return this; // chaining
      },
     
      emit:function () {                                                                                           
         applyEach( listenerList, arguments );
      },
      
      un: function( listenerId ) {
             
         var removed;             
              
         listenerTupleList = without(
            listenerTupleList,
            hasId(listenerId),
            function(tuple){
               removed = tuple;
            }
         );    
         
         if( removed ) {
            listenerList = without( listenerList, function(listener){
               return listener == removed.listener;
            });
         
            if( removeListener ) {
               removeListener.emit(eventType, removed.listener, removed.id);
            }
         }
      },
      
      listeners: function(){
         // differs from Node EventEmitter: returns list, not array
         return listenerList;
      },
      
      hasListener: function(listenerId){
         var test = listenerId? hasId(listenerId) : always;
      
         return defined(first( test, listenerTupleList));
      }
   };
}
A pub/sub which is responsible for a single event type. A 
multi-event type event bus is created by pubSub by collecting
several of these.

@param {String} eventType                   
   the name of the events managed by this singleEventPubSub
@param {singleEventPubSub} [newListener]    
   place to notify of new listeners
@param {singleEventPubSub} [removeListener] 
   place to notify of when listeners are removed