/// <summary>
        /// Binds the specified listen URL.
        /// </summary>
        /// <param name="listenUrl">The listen URL.</param>
        /// <param name="sendUrl">The send URL.</param>
        /// <param name="page">Page object</param>
        /// <param name="classDefs">Class definition handler</param>
        /// <param name="clientId">The client id</param>
        /// <param name="cometEnabled">if set to <c>true</c> [comet enabled].</param>
        /// <returns></returns>
        public static bool Bind(string listenUrl, string sendUrl, System.Web.UI.Page page, DefineClassObjects classDefs, out string clientId, bool cometEnabled)
        {
            clientId = NewClientId;

            lock (_clients)
            {
                _clients.Add(clientId, new CometMessage());
            }

            Dictionary <string, object> classList = new Dictionary <string, object>();

            classDefs(clientId, ref classList);

            bool anyAdd = false;

            lock (DynamicCode.Definitions)
            {
                foreach (KeyValuePair <string, object> en in classList)
                {
                    object ba = en.Value;
                    DynamicCode.Definitions.Add(en.Key, ref ba, clientId);
                    anyAdd = true;
                }
                object brO = new BrowserEvents(clientId);
                DynamicCode.Definitions.Add("BrowserEvents", ref brO, clientId);
                System.Reflection.FieldInfo fi = page.GetType().GetField("PokeInSafe");
                if (fi != null)
                {
                    object br1 = page;
                    DynamicCode.Definitions.Add("MainPage", ref br1, clientId);
                }
            }

            if (!anyAdd)
            {
                page.Response.Write("<script>alert('There is no server side class!');</script>");
                return(false);
            }

            JWriter.WriteClientScript(ref page, clientId, listenUrl, sendUrl, cometEnabled);

            CometWorker worker = new CometWorker(clientId);

            lock (ClientStatus)
            {
                ClientStatus.Add(clientId, new ClientCodeStatus(worker));

                //Oguz Bastemur
                //to-do::smart threads through the core units
                if (cometEnabled)
                {
                    System.Threading.ThreadStart ts = new System.Threading.ThreadStart(ClientStatus[clientId].Worker.ClientThread);
                    ClientStatus[clientId].Worker._thread = new System.Threading.Thread(ts);
                    ClientStatus[clientId].Worker._thread.SetApartmentState(System.Threading.ApartmentState.MTA);
                    ClientStatus[clientId].Worker._thread.Start();
                }
            }

            return(true);
        }
        /// <summary>
        /// Listens through the specified page object.
        /// </summary>
        /// <param name="page">Page object</param>
        public static void Listen(System.Web.UI.Page page)
        {
            if (!page.Request.Params.HasKeys())
            {
                return;
            }

            string clientId = page.Request.Params["c"];

            if (clientId == null)
            {
                return;
            }

            DateTime pageStart = DateTime.Now.AddMilliseconds(CometSettings.ListenerTimeout);

            bool isSecure = true;

            if (page.Request.Params["sc"] != null)
            {
                bool.TryParse(page.Request.Params["sc"], out isSecure);
            }

            bool ijStatus = false;

            if (page.Request.Params["ij"] != null)
            {
                ijStatus = page.Request.Params["ij"].ToString() == "1";
            }

            UpdateUserTime(clientId, pageStart, false);

            string message;
            int    clientTester = 0;

            page.Response.Buffer = false;

            while (true)
            {
                string messages;
                if (GrabClientMessages(clientId, out messages))
                {
                    if (messages.Length > 0)
                    {
                        message = messages + "PokeIn.Listen();";
                        message = JWriter.CreateText(clientId, message, false, isSecure);

                        if (ijStatus)
                        {
                            message = "PokeIn.CreateText('" + message.Replace("'", "\\'").Replace("\n", "\\n").Replace("\r", "\\r") + "',true);";
                        }
                        else
                        {
                            message = message.Replace("\\\'", "\'");
                        }

                        page.Response.Write(message);
                        break;
                    }
                }

                if (clientTester % 25 == 0)
                {
                    page.Response.Write(" ");
                }
                clientTester++;

                if (messages == null || !page.Response.IsClientConnected)
                {
                    RemoveClient(clientId);
                    message = JWriter.CreateText(clientId, "PokeIn.ClientObjectsDoesntExist();PokeIn.Closed();", false, isSecure);
                    if (ijStatus)
                    {
                        message = "PokeIn.CreateText('" + message + "',true);";
                    }
                    page.Response.Write(message);
                    break;
                }

                if (pageStart < DateTime.Now)
                {
                    message = JWriter.CreateText(clientId, "PokeIn.Listen();", false, isSecure);
                    if (ijStatus)
                    {
                        message = "PokeIn.CreateText('" + message + "',true);";
                    }
                    page.Response.Write(message);
                    break;
                }
                System.Threading.Thread.Sleep(50);
            }

            UpdateUserTime(clientId, DateTime.Now, false);
        }
        /// <summary>
        /// Sends through the specified page object.
        /// </summary>
        /// <param name="page">Page object</param>
        public static void Send(System.Web.UI.Page page)
        {
            if (!page.Request.Params.HasKeys())
            {
                return;
            }

            string clientId = page.Request.Params["c"];

            if (clientId == null)
            {
                return;
            }

            string message = page.Request.Params["ms"];

            if (message == null)
            {
                return;
            }

            if (message.Trim().Length == 0)
            {
                return;
            }

            bool isSecure = true;

            if (page.Request.Params["sc"] != null)
            {
                bool.TryParse(page.Request.Params["sc"], out isSecure);
            }

            bool cometEnabled = true;

            if (page.Request.Params["ce"] != null)
            {
                bool.TryParse(page.Request.Params["ce"], out cometEnabled);
            }

            bool ijStatus = false;

            if (page.Request.Params["ij"] != null)
            {
                ijStatus = page.Request.Params["ij"].ToString() == "1";
            }

            message = JWriter.CreateText(clientId, message, true, isSecure);

            if (CometSettings.LogClientScripts)
            {
                lock (_clientScriptsLog)
                {
                    if (!_clientScriptsLog.ContainsKey(clientId))
                    {
                        _clientScriptsLog.Add(clientId, new List <string>());
                    }
                }
                lock (_clientScriptsLog[clientId])
                {
                    _clientScriptsLog[clientId].Add(message);
                }
            }

            if (UpdateUserTime(clientId, DateTime.Now, true))
            {
                if (message.Trim().StartsWith(clientId + ".CometBase.Close();"))
                {
                    RemoveClient(clientId);
                    message = JWriter.CreateText(clientId, "PokeIn.Closed();", false, isSecure);
                    if (ijStatus)
                    {
                        message = "PokeIn.CreateText('" + message + "',true);";
                    }
                    page.Response.Write(message);
                }
                else
                {
                    lock (ClientStatus[clientId])
                    {
                        if (ClientStatus[clientId].Worker == null)
                        {
                            RemoveClient(clientId);
                            message = JWriter.CreateText(clientId, "PokeIn.Closed();", false, isSecure);
                            page.Response.Write(message);
                            return;
                        }

                        ClientStatus[clientId].Worker._codesToRun.Add(message);
                        if (!cometEnabled)
                        {
                            ClientStatus[clientId].Worker.ExecuteJobs(clientId);
                        }
                    }

                    string messages;
                    if (GrabClientMessages(clientId, out messages))
                    {
                        if (messages.Length > 0)
                        {
                            message = JWriter.CreateText(clientId, messages, false, isSecure);
                            if (ijStatus)
                            {
                                message = "PokeIn.CreateText('" + message.Replace("'", "\\'").Replace("\n", "\\n").Replace("\r", "\\r") + "',true);";
                            }
                            else
                            {
                                message = message.Replace("\\\'", "\'");
                            }
                            page.Response.Write(message);
                        }
                    }
                    else if (messages == null)
                    {
                        RemoveClient(clientId);
                        message = JWriter.CreateText(clientId, "PokeIn.ClientObjectsDoesntExist();PokeIn.Closed();", false, isSecure);
                        if (ijStatus)
                        {
                            message = "PokeIn.CreateText('" + message + "',true);";
                        }
                        page.Response.Write(message);
                    }

                    page.Response.Write(" ");
                    page.Response.Flush();

                    if (!page.Response.IsClientConnected)
                    {
                        RemoveClient(clientId);
                    }
                }
            }
            else
            {
                RemoveClient(clientId);
                message = JWriter.CreateText(clientId, "PokeIn.ClientObjectsDoesntExist();PokeIn.Closed();", false, isSecure);
                if (ijStatus)
                {
                    message = "PokeIn.CreateText('" + message + "',true);";
                }
                page.Response.Write(message);
            }
        }