Boolean ProcessHandshake ()
		{
			log.Info("Processing handshake");

			JObject o = new JObject (
				new JProperty ("channel", "/meta/handshake"),
				new JProperty ("version", "1.0"),
				new JProperty ("supportedConnectionTypes", new JArray ("long-polling"))); 

			String response = SendMessage (o);

			List<HandshakeResponse> hResponses = JsonConvert.DeserializeObject<List<HandshakeResponse>> (response);
			log.Debug("Acquired CIENT-ID: " + hResponses[0].clientId);

			ClientId = hResponses [0].clientId;

			if (hResponses [0].advice != null && hResponses [0].advice.reconnect == "retry") {
				this.ServerAdvice = hResponses [0].advice;
			}

			ResubscribeToChannels();

			return true;
		}
		void ProcessServerResponse (ServerResponse response)
		{
			if (response.data != null) {
				log.Debug("Received data");
				OnDataReceived(response.data, response.channel);
			} else {
				if (response.channel == "/meta/subscribe")
				{
					if (response.successful)
					{
						log.Info ("Subscription successfull to " + response.subscription);
						ChannelSubscriptions.Add(response.subscription);
					}
					else
					{
						log.Error("Subscription failed to " + response.subscription);
					}
					//TODO: Add an event here for failed or successful channel subscription

					lock(PendingChannelSubscriptions)
					{
						PendingChannelSubscriptions.Remove(response.subscription);
					}
				}
				else if (response.channel == "/meta/unsubscribe")
				{
					if (response.successful)
					{
						log.Info( "Unsubscription successfull from " + response.subscription);
						ChannelSubscriptions.Remove(response.subscription);
						lock(PendingChannelUnsubscriptions)
						{
							PendingChannelUnsubscriptions.Remove(response.subscription);
						}
						OnChannelUnsubscribed();
					}
					else
					{
						log.Error("Subscription failed to " + response.subscription);
					}
				}
				else if (response.channel == "/meta/connect")
				{
					if (!response.successful && response.error != null && 
					    response.advice != null && response.advice.reconnect == "handshake")
					{
						log.Info ("Received request to rehandshake");

						lock(this)
						{
							ClientState = ClientStateEnum.Handshaking;
						}
					}
				}

				if (response.advice != null && response.advice.reconnect == "retry")
				{
					log.Debug("Server advice received " + response.advice.ToString());
					this.ServerAdvice = response.advice;
				}
			}
		}
		public BayeuxClient (Uri serverUri)
		{
			this.ServerUri = serverUri;

			//Setup default server advice
			ServerAdvice = new Advice();
			ServerAdvice.interval = 0;
			ServerAdvice.reconnect = "retry";
			ServerAdvice.timeout = 30000;

			//Setup background worker
			BayeuxWorker = new BackgroundWorker();
			BayeuxWorker.WorkerSupportsCancellation = true;
			BayeuxWorker.DoWork += ProcessRequests;

			ClientState = ClientStateEnum.Disconnected;
			log = LogManager.GetLogger(serverUri.Host);	
		}