protected HubMessage ParseMessage(string raw)
 {
     raw = raw.Replace(this.Seperator, "");
     HubMessage msg = new HubMessage(hub, raw);
     if (!string.IsNullOrEmpty(raw))
     {
         switch (raw[0])
         {
             case '$':
                 int pos;
                 string cmd = null;
                 if ((pos = raw.IndexOf(' ')) != -1)
                     cmd = raw.Substring(0, pos).ToLower();
                 else
                 {
                     if (raw.Length >= 10)
                         break;
                     cmd = raw.ToLower();
                 }
                 if (cmd == null || cmd.Equals(string.Empty))
                     break;
                 switch (cmd)
                 {
                     case "$lock":
                         msg = new Lock(hub, raw); break;
                     case "$supports":
                         msg = new Supports(hub, raw); break;
                     case "$hubname":
                         msg = new HubNmdc.HubName(hub, raw); break;
                     case "$hello":
                         msg = new Hello(hub, raw); break;
                     case "$myinfo":
                         msg = new MyINFO(hub, raw); break;
                     case "$nicklist":
                         msg = new NickList(hub, raw); break;
                     case "$oplist":
                         msg = new OpList(hub, raw); break;
                     case "$to:":
                         msg = new To(hub, raw); break;
                     case "$quit":
                         msg = new Quit(hub, raw); break;
                     case "$getpass":
                         msg = new GetPass(hub, raw); break;
                     case "$logedin":
                         msg = new LogedIn(hub, raw); break;
                     case "$validatedenide":
                         msg = new ValidateDenide(hub, raw); break;
                     case "$forcemove":
                         msg = new ForceMove(hub, raw); break;
                     case "$connecttome":
                         msg = new ConnectToMe(hub, raw); break;
                     case "$revconnecttome":
                         msg = new RevConnectToMe(hub, raw); break;
                     case "$search":
                         msg = new Search(hub, raw); break;
                     case "$sr":
                         msg = new SR(hub, raw); break;
                 }
                 break;
             default:
                 // No command. Assume MainChat.
                 msg = new MainChat(hub, raw);
                 break;
         }
     }
     return msg;
 }
        public void ActOnInMessage(IConMessage comMsg)
        {
            HubMessage message = (HubMessage)comMsg;
            if (message is MainChat)
            {
                MainChat main = (MainChat)message;
                MainMessage msg = new MainMessage(main.From, main.Content);
                Update(hub, new FmdcEventArgs(Actions.MainMessage, msg));
            }
            else if (message is To)
            {
                To to = (To)message;
                PrivateMessage pm = new PrivateMessage(to.To, to.From, to.Content);
                Update(hub, new FmdcEventArgs(Actions.PrivateMessage, pm));
            }
            else if (message is SR)
            {
                SR searchResult = (SR)message;
                SearchResultInfo srinfo = new SearchResultInfo(searchResult.Info, searchResult.From);
                Update(hub, new FmdcEventArgs(Actions.SearchResult, srinfo));
            }
            else if (message is Search)
            {
                Search search = (Search)message;
                if (hub.Share == null)
                    return;
                int maxReturns = 5;
                bool active = false;
                if (search.Address != null)
                {
                    maxReturns = 10;
                    active = true;
                }
                System.Collections.Generic.List<ContentInfo> ret = new System.Collections.Generic.List<ContentInfo>(maxReturns);
                // TODO : This lookup can be done nicer
                lock (hub.Share)
                {

                    foreach (System.Collections.Generic.KeyValuePair<string, Containers.ContentInfo> var in hub.Share)
                    {
                        if (var.Value == null)
                            continue;
                        bool foundEnough = false;
                        string ext = search.Info.Get(SearchInfo.EXTENTION);
                        string sch = search.Info.Get(SearchInfo.SEARCH);
                        if (ext != null && sch != null)
                        {
                            ContentInfo contentInfo = new ContentInfo();
                            if (search.Info.ContainsKey(SearchInfo.TYPE))
                            {
                                switch (search.Info.Get(SearchInfo.TYPE))
                                {
                                    case "2":

                                        contentInfo.Set(ContentInfo.TTH, search.Info.Get(SearchInfo.SEARCH));
                                        if (hub.Share.ContainsContent(ref contentInfo))
                                        {
                                            ret.Add(contentInfo);
                                        }
                                        // We are looking through whole share here.
                                        // If no TTH matching. Ignore.
                                        foundEnough = true;
                                        break;
                                    case "1":
                                    default:
                                        if (var.Value.ContainsKey(ContentInfo.VIRTUAL) && (System.IO.Path.GetDirectoryName(var.Value.Get(ContentInfo.VIRTUAL)).IndexOf(sch, System.StringComparison.OrdinalIgnoreCase) != -1))
                                            ret.Add(var.Value);
                                        break;
                                }
                            }

                            if (!foundEnough)
                            {
                                string infoExt = System.IO.Path.GetExtension(var.Value.Get(ContentInfo.VIRTUAL)).TrimStart('.');
                                if (
                                        var.Value.ContainsKey(ContentInfo.VIRTUAL)
                                        && (var.Value.Get(ContentInfo.VIRTUAL).IndexOf(sch, System.StringComparison.OrdinalIgnoreCase) != -1)
                                        && (ext.Length == 0 || ext.Contains(infoExt))
                                    )
                                    ret.Add(var.Value);
                            }
                        }
                        if (foundEnough || ret.Count >= maxReturns)
                            break;
                    }
                }
                // Test against size restrictions
                for (int i = 0; i < ret.Count; i++)
                {
                    bool send = true;
                    long size = -1;
                    try
                    {
                        size = int.Parse(search.Info.Get(SearchInfo.SIZE));
                    }
                    catch { }
                    if (search.Info.ContainsKey(SearchInfo.SIZETYPE) && size != -1)
                    {
                        switch (search.Info.Get(SearchInfo.SIZETYPE))
                        {
                            case "1":       // Min Size
                                send = (size <= ret[i].Size);
                                break;
                            case "2":       // Max Size
                                send = (size >= ret[i].Size);
                                break;
                            case "3":       // Equal Size
                                send = (size == ret[i].Size);
                                break;
                        }
                    }
                    // Should this be sent?
                    if (send)
                    {
                        SR sr = new SR(hub, ret[i], (search.Info.ContainsKey(SearchInfo.EXTENTION) ? search.Info.Get(SearchInfo.EXTENTION).Equals("$0") : false), search.From);
                        if (active)
                        {
                            // Send with UDP
                            UdpConnection.Send(sr, search.Address);
                        }
                        else
                        {
                            // Send through hub
                            hub.Send(sr);
                        }
                    }
                }
            }
            else if (message is Lock)
            {
                hub.Send(new Supports(hub));
                hub.Send(new Key(hub, ((Lock)message).Key));
                hub.Send(new ValidateNick(hub));
            }
            else if (message is HubZpoc.HubName)
            {
                HubZpoc.HubName hubname = (HubZpoc.HubName)message;
                Containers.HubName name = null;
                if (hubname.Topic != null)
                    name = new Containers.HubName(hubname.Name, hubname.Topic);
                else
                    name = new Containers.HubName(hubname.Content);
                Update(hub, new FmdcEventArgs(Actions.Name, name));
            }
            else if (message is NickList)
            {
                NickList nicks = (NickList)message;
                foreach (string userid in nicks.List)
                {
                    UserInfo userInfo = new UserInfo();
                    userInfo.DisplayName = userid;
                    userInfo.Set(UserInfo.STOREID, hub.HubSetting.Address + hub.HubSetting.Port.ToString() + userid);
                    if (hub.GetUserById(userid) == null)
                        Update(hub, new FmdcEventArgs(Actions.UserOnline, userInfo));
                }
            }
            else if (message is OpList)
            {
                OpList ops = (OpList)message;
                foreach (string userid in ops.List)
                {
                    UserInfo userInfo = new UserInfo();
                    userInfo.DisplayName = userid;
                    userInfo.Set(UserInfo.STOREID, hub.HubSetting.Address + hub.HubSetting.Port.ToString() + userid);
                    userInfo.IsOperator = true;
                    User usr = null;
                    if ((usr = hub.GetUserById(userid)) == null)
                        Update(hub, new FmdcEventArgs(Actions.UserOnline, userInfo));
                    else
                    {
                        usr.UserInfo = userInfo;
                        Update(hub, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo));
                    }
                }
            }
            else if (message is Quit)
            {
                Quit quit = (Quit)message;
                User usr = null;
                if ((usr = hub.GetUserById(quit.From)) != null)
                    Update(hub, new FmdcEventArgs(Actions.UserOffline, usr.UserInfo));
            }
            else if (message is LogedIn)
                hub.RegMode = 2;
            else if (message is ValidateDenide)
                Update(hub, new FmdcEventArgs(Actions.StatusChange, new HubStatus(HubStatus.Codes.Disconnected)));
            else if (message is GetPass)
            {
                hub.RegMode = 1;
                if (hub.HubSetting.Password.Length == 0)
                    Update(hub, new FmdcEventArgs(Actions.Password, null));
                else
                    hub.Send(new MyPass(hub));
            }
            else if (message is MyINFO)
            {
                MyINFO myinfo = (MyINFO)message;
                User usr = null;
                if ((usr = hub.GetUserById(message.From)) == null)
                    Update(hub, new FmdcEventArgs(Actions.UserOnline, myinfo.UserInfo));
                else
                {
                    bool op = usr.IsOperator;
                    usr.UserInfo = myinfo.UserInfo;
                    usr.UserInfo.IsOperator = op;
                    Update(hub, new FmdcEventArgs(Actions.UserInfoChange, usr.UserInfo));
                }
            }
            else if (message is Hello)
            {
                if (hub.HubSetting.DisplayName.Equals(message.From))
                {
                    hub.Send(new Version(hub));
                    hub.Send(new GetNickList(hub));
                    if (hub.RegMode < 0)
                        hub.RegMode = 0;
                    UpdateMyInfo();
                }
            }
            else if (message is ConnectToMe)
            {
                ConnectToMe conToMe = (ConnectToMe)message;
                Transfer trans = new Transfer(conToMe.Address, conToMe.Port);
                trans.Share = this.hub.Share;
                trans.Me = hub.Me;
                trans.Source = new Source(hub.RemoteAddress.ToString(), null);
                // Protocol has to be set last.
                trans.Protocol = new TransferNmdcProtocol(trans);
            #if !COMPACT_FRAMEWORK
                if (conToMe.TLS && hub.Me.ContainsKey(UserInfo.SECURE))
                    trans.SecureProtocol = SecureProtocols.TLS;
            #endif
                Update(hub, new FmdcEventArgs(Actions.TransferStarted, trans));
            }
            else if (message is RevConnectToMe)
            {
                RevConnectToMe revConToMe = (RevConnectToMe)message;
                User usr = null;
                usr = hub.GetUserById(revConToMe.From);
                if (hub.Me.Mode == FlowLib.Enums.ConnectionTypes.Passive)
                {
                    if (usr != null)
                    {
                        // If user are not set as passive. Set it as it and respond with a revconnect.
                        if (usr.UserInfo.Mode != FlowLib.Enums.ConnectionTypes.Passive)
                        {
                            usr.UserInfo.Mode = FlowLib.Enums.ConnectionTypes.Passive;
                            hub.Send(new RevConnectToMe(revConToMe.From, hub));
                        }
                    }
                }
                else
                {
                    if (usr != null)
                    {
                        Update(hub, new FmdcEventArgs(Actions.TransferRequest, new TransferRequest(usr.ID, hub, usr.UserInfo)));
            #if !COMPACT_FRAMEWORK
                        // Security, Windows Mobile doesnt support SSLStream so we disable this feature for it.
                        if (
                            usr.UserInfo.ContainsKey(UserInfo.SECURE) &&
                            hub.Me.ContainsKey(UserInfo.SECURE) &&
                            !string.IsNullOrEmpty(hub.Me.Get(UserInfo.SECURE))
                            )
                            hub.Send(new ConnectToMe(usr.ID, hub.Share.Port, hub, SecureProtocols.TLS));
                        else
            #endif
                            hub.Send(new ConnectToMe(usr.ID, hub.Share.Port, hub));
                    }
                }
            }
            else if (message is ForceMove)
            {
                ForceMove forceMove = (ForceMove)message;
                hub.Disconnect();
                Update(hub, new FmdcEventArgs(Actions.Redirect, new RedirectInfo(forceMove.Address)));
            }
        }