/// <summary>
 /// Create a client registration for a certain event type.
 /// </summary>
 /// <param name="clientUri"></param>
 /// <param name="eventType"></param>
 /// <param name="userName"></param>
 /// <param name="prox"></param>
 public void RegisterClient(Uri clientUri, NotificationTypes eventType, string userName, IClientNotification prox)
 {           
     var reg = new Registration() { RegistrationUri = clientUri, EventType = eventType.ToString(), UserName = userName, clientProxy=prox  };
     var key = reg.CreateKey();
     if (!Registrations.ContainsKey(key))
         Registrations.Add(key, new List<Registration> { reg });
     else if (Registrations[key].Find(rg => (rg.RegistrationUri.AbsolutePath == reg.RegistrationUri.AbsolutePath)) == null)
            Registrations[key].Add(reg);            
 }
        /// <summary>
        /// Send notifications to registered clients.
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <param name="address">The client's address </param>
        public static void SendNotifications(TicketingMessage message, Registration[] address)
        {
            //Notifications are sent on another thread.
            foreach (var add in address)
            {
                Action<TicketingMessage, Registration> del = SendMessage;
                del.BeginInvoke(message, add, null, null);
            }

        }
 /// <summary>
 /// Create a client registration for a certain event type.
 /// </summary>
 /// <param name="clientUri"></param>
 /// <param name="eventType"></param>
 public void UnRegisterClient(Uri clientUri, NotificationTypes eventType)
 {
     var reg = new Registration() { RegistrationUri = clientUri, EventType = eventType.ToString() };
      var key = reg.CreateKey();
      if (Registrations.ContainsKey(key))
          Registrations.Remove(key);
 }
        /// <summary>
        /// Send a message back to the client. 
        /// First try a duplex callcack channel, then try a one-way channel back to the client.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="clientRegistration"></param>
        private static void SendMessage(TicketingMessage message,Registration clientRegistration)
        {
            IClientNotification prox = null;
            try
            {
                // Create a proxy for duplex channel
                if ((clientRegistration.clientProxy != null) &&
                    ((clientRegistration.clientProxy as IClientChannel).State == CommunicationState.Opened))
                    prox = clientRegistration.clientProxy;
                else
                {
                    //Create a proxy for oneway channel
                    if (chf == null)
                        chf = new ChannelFactory<IClientNotification>(new BasicHttpBinding());

                    prox = chf.CreateChannel(new EndpointAddress(clientRegistration.RegistrationUri));
                }

                //send the message to the client
                prox.MessageArrived(message);                
            }
            catch (Exception ex)
            {
                 LoggingManager.Logger.Log(LoggingCategory.Error, string.Format(StringsResource.FailedToContactClient,ex.Message));                
            }
            finally
            {
               var channel = prox as ICommunicationObject;
               if ((channel != null) && (channel.State == CommunicationState.Opened))
                    channel.Close();
             }
           }