if (binding.getNodeId().equals(this.nodeId))
Filter filter = binding.getFilter();  if (filter != null && filter.accept(ref))
   public boolean route(MessageReference ref, String condition, Transaction tx) throws Exception   {      if (ref == null)      {         throw new IllegalArgumentException("Message reference is null");      }            if (condition == null)      {         throw new IllegalArgumentException("Condition is null");      }            boolean routed = false;            lock.readLock().acquire();            try      {               ConditionBindings cb = (ConditionBindings)conditionMap.get(condition);                  boolean startInternalTx = false;                  if (cb != null)         {            if (tx == null && ref.isReliable())            {               if (!(cb.getDurableCount() == 1 && cb.getLocalDurableCount() == 1))               {                  // When routing a persistent message without a transaction then we may need to start an                   // internal transaction in order to route it.                  // This is so we can guarantee the message is delivered to all or none of the subscriptions.                  // We need to do this if there is any other than a single local durable subscription                  startInternalTx = true;               }            }                        if (startInternalTx)            {               tx = tr.createTransaction();            }                        //There may be no transaction in the following cases            //1) No transaction specified in params and reference is unreliable            //2) No transaction specified in params and reference is reliable and there is only one            //   or less local durable subscription                     Collection bindingLists = cb.getBindingsByName();            Iterator iter = bindingLists.iterator();                        int numberRemote = 0;                        Map queueNameNodeIdMap = null;                                    while (iter.hasNext())            {               //Each list is the list of bindings which have the same queue name               List bindings = (List)iter.next();                              //We may have more than one binding with the same queue name on different nodes in the               //following situations:               //1) When a point to point queue has been deployed across the cluster               //2) When a durable subscription has been created on multiple nodes to implement               // shared durable subscriptions.               //In both of these cases we only want one of the queues to receive the message, we choose which                //one by asking the routing policy               Binding binding;                              if (bindings.size() == 1)               {                  binding = (Binding)bindings.get(0);               }               else if (bindings.size() > 1)               {                  binding = routingPolicy.choose(bindings);                                     if (queueNameNodeIdMap == null)                  {                     queueNameNodeIdMap = new HashMap();                  }                                    if (!binding.getNodeId().equals(this.nodeId))                  {                     //Chose a remote node                     //We add the node id to the map against the name                     //This is used on receipt to work out if a particular queue should                     //accept the message, when multicasted                     queueNameNodeIdMap.put(binding.getQueueName(), binding.getNodeId());                  }               }               else               {                  throw new IllegalStateException("No bindings in list!");               }                              if (binding.getNodeId().equals(this.nodeId))               {                  //It's a local binding so we pass the message on to the queue                  Queue queue = binding.getQueue();                                 Delivery del = queue.handle(null, ref, tx);                                        if (del != null && del.isSelectorAccepted())                  {                     routed = true;                  }                 }               else               {                  //It's a binding on a different office instance on the cluster                  numberRemote++;                                                         if (ref.isReliable() && binding.isDurable())                  {                     //Insert the reference into the database                                          //TODO perhaps we should do this via a stub queue class                     pm.addReference(binding.getChannelId(), ref, tx);                  }                                    routed = true;               }                                                            }                                                //Now we've sent the message to any local queues, we might also need            //to send the message to the other office instances on the cluster if there are            //queues on those nodes that need to receive the message                        if (numberRemote > 0)            {               //TODO - If numberRemote == 1, we could do unicast rather than multicast               //This would avoid putting strain on nodes that don't need to receive the reference               //This would be the case for load balancing queues where the routing policy               //sometimes allows a remote queue to get the reference                              if (tx == null)               {                  //We just throw the message on the network - no need to wait for any reply                         asyncSendRequest(new MessageRequest(condition, ref.getMessage(), queueNameNodeIdMap));                              }               else               {                  CastMessagesCallback callback = (CastMessagesCallback)tx.getCallback(this);                                    if (callback == null)                  {                     callback = new CastMessagesCallback(nodeId, tx.getId(), ClusteredPostOfficeImpl.this);                                          //This callback must be executed first                     tx.addFirstCallback(callback, this);                  }                                        callback.addMessage(condition, ref.getMessage(), queueNameNodeIdMap);                   }            }                        if (startInternalTx)            {                              // TODO - do we need to rollback if an exception is thrown??                              tx.commit();            }         }      }      finally      {                           lock.readLock().release();      }               return routed;    }