protected virtual void OnListMode(int numeric, string channel, string setBy, DateTime setOn, string mask)
        {
            Channel c = GetChannel(channel);
            //ListModeType type = ListModeType.BAN;
            char type = '\0';

            switch (numeric)
            {
            case 346:               // +I
            {
                type = 'I';
            } break;

            case 348:               // +e
            {
                type = 'e';
            } break;

            default:
            case 367:               // +b
            {
                type = 'b';
            } break;
            }

            if (c.ListModes.Find(x => x.Mask.EqualsIgnoreCase(mask)) != null)
            {
                return;                 // Already set, why are we adding it again? o.O
            }

            ListMode l = new ListMode(setOn, mask, setBy, type);

            c.ListModes.Add(l);
        }
        /*
         * protected virtual void OnNoticeReceived(string input)
         * {
         *  string[] toks = input.Split(' ');
         *  Match m, n;
         *  string sender = "", message = "";
         *  if ((m = Patterns.rUserHost.Match(toks[0])).Success)
         *  {
         *      Channel target;
         *      message = input.Substring(input.IndexOf(':', 2) + 1);
         *      sender = m.Groups[1].Value;
         *      // priv. notice
         *      if ((n = Patterns.rChannelRegex.Match(toks[2])).Success)
         *      {
         *          // channel
         *          target = GetChannel(n.Groups[1].Value);
         *          ChannelNoticeReceivedEvent.Raise(this, new ChannelMessageReceivedEventArgs(target, message, sender, true));
         *      }
         *      else
         *      {
         *          // private notice
         *          PrivateNoticeReceivedEvent.Raise(this, new PrivateMessageReceivedEventArgs(sender, message, true));
         *      }
         *  }
         *  else
         *  {
         *      // Server Notice
         *      Console.WriteLine("(S)NOTICE: {0}", input.Substring(input.IndexOf(toks[2])));
         *  }
         * }
         */

        /// <summary>
        /// Internally handles one specific mode change on a channel
        /// </summary>
        /// <param name="chan">The Channel on which the change happened.</param>
        /// <param name="mode">The mode the change happened with.</param>
        /// <param name="parameter">The parameter for this mode (or null)</param>
        /// <param name="type">The type of mode this is.</param>
        /// <param name="isSet">If this mode was set. (False if it was unset)</param>
        protected virtual void HandleChannelMode(Channel chan, char mode, string parameter, ChanmodeType type, bool isSet)
        {
#if DEBUG
            System.Diagnostics.Debug.WriteLine("Mode '{0}' is being {1} with parameter: {2} (Type: {3})", mode, isSet ? "set" : "unset", parameter, type);
#endif

            if (type == ChanmodeType.ACCESS)
            {
                PrefixList list = null;
                foreach (var kvp in chan.Users)
                {
                    if (kvp.Key.EqualsIgnoreCase(parameter))
                    {
                        list = kvp.Value;
                    }
                }
                if (list == null)
                {
#if DEBUG
//                    throw new Exception("HandleChannelMode Access mode was set on a user who was not in the channel's list (chan.Users).");
#endif
                    list = new PrefixList(this);
                    chan.Users.Add(parameter, list);
                }

                if (isSet)
                {
                    list.AddPrefix(list.ModeToPrefix(mode));
                }
                else
                {
                    list.RemovePrefix(list.ModeToPrefix(mode));
                }

                if (StrictNames)
                {
                    Send("NAMES {0}", chan.Name);
                }
            }
            else if (type != ChanmodeType.LIST)
            {
                if (isSet)
                {
                    chan.Modes.Remove(mode);  // If it is already there, it needs to be updated most likely. Or the IRCD is broken and this is irrelevent.
                    chan.Modes.Add(mode, parameter);
                }
                else
                {
                    chan.Modes.Remove(mode);
                }
            }
            else // if type is LIST
            {
                List <ListMode> list = chan.ListModes;

                ListMode lMode;

                if ((lMode = list.Find(x => x.Mask.EqualsIgnoreCase(parameter))) == null)
                {
                    if (!isSet)
                    {
                        return;
                    }

                    lMode = new ListMode(DateTime.Now, parameter, "", mode);
                    list.Add(lMode);
                }

                if (StrictModes)
                {
                    Send("MODE {0} +{1}", chan.Name, mode);
                }

                /*List<string> list;
                 * if (!chan.ListModes.TryGetValue(mode, out list))
                 * {
                 *  if (!isSet) // If we are unsetting a value but had no list...then clearly we had no value already stored :)
                 *      return;
                 *  list = new List<string>();
                 *  chan.ListModes.Add(mode, list);
                 * }
                 * // If we are here, we should have the list of this mode
                 * list.RemoveAll(x => x.EqualsIgnoreCase(parameter));
                 * if (isSet)
                 * {
                 *  list.Add(parameter);
                 * }*/
            }
        }