finally { if (acquired) { lock.readLock().release(); } }
   public Set handle(DeliveryObserver observer, Routable routable, Transaction tx)   {      Set deliveries = new HashSet();      // TODO synchronizing this is going to produce a bottleneck, do we really need to?      synchronized(receivers)      {         for(Iterator i = receivers.iterator(); i.hasNext(); )         {            Receiver receiver = (Receiver)i.next();            try            {               Delivery d = receiver.handle(observer, routable, tx);               if (trace) { log.trace("receiver " + receiver + " handled " + routable + " and returned " + d); }               if (d != null && !d.isCancelled())               {                  deliveries.add(d);               }            }            catch(Throwable t)            {               // broken receiver - log the exception and ignore it               log.error("The receiver " + receiver + " is broken", t);            }         }      }      return deliveries;   }