void client_Said(object sender, TasSayEventArgs e)
		{
		    User user;
		    if (!client.ExistingUsers.TryGetValue(e.UserName, out user)) return;
			if (e.Place == SayPlace.Channel && e.Channel != "main")
			{
				Task.Factory.StartNew(() =>
					{
						try
						{
							using (var db = new ZkDataContext())
							{
							    Channel channel;
							    if (!client.JoinedChannels.TryGetValue(e.Channel, out channel)) return;
								foreach (var s in db.LobbyChannelSubscriptions.Where(x => x.Channel == e.Channel).Select(x=>x.Account))
								{
									if (!channel.Users.ContainsKey(s.Name)) {
									    var fac = db.Factions.FirstOrDefault(x => x.Shortcut == e.Channel);
                                        // if faction channel check if allowed
                                        if (fac == null || (fac.FactionID == s.AccountID && s.Level >= GlobalConst.FactionChannelMinLevel)) {

                                            var message = new LobbyMessage()
                                                          {
                                                              SourceLobbyID = user.AccountID,
                                                              SourceName = e.UserName,
                                                              Created = DateTime.UtcNow,
                                                              Message = e.Text,
                                                              TargetName = s.Name,
                                                              Channel = e.Channel
                                                          };
                                            db.LobbyMessages.InsertOnSubmit(message);
                                        }
									}
								}
								db.SubmitChanges();
							}
						}
						catch (Exception ex)
						{
							Trace.TraceError("Error storing message: {0}", ex);
						}
					});
			}
			else if (e.Place == SayPlace.User)
			{
				Task.Factory.StartNew(() =>
					{
						try
						{
							if (e.Place == SayPlace.User)
							{
								if (e.Text.StartsWith("!pm"))
								{
									var regex = Regex.Match(e.Text, "!pm ([^ ]+) (.+)");
									if (regex.Success)
									{
										var name = regex.Groups[1].Value;
										var text = regex.Groups[2].Value;

										var message = new LobbyMessage()
										              { SourceLobbyID = user.AccountID, SourceName = e.UserName, Created = DateTime.UtcNow, Message = text, TargetName = name };
										using (var db = new ZkDataContext())
										{
											db.LobbyMessages.InsertOnSubmit(message);
											db.SubmitChanges();
										}
									}
								}
								else if (e.Text.StartsWith("!subscribe"))
								{
									var regex = Regex.Match(e.Text, "!subscribe #([^ ]+)");
									if (regex.Success)
									{
										var chan = regex.Groups[1].Value;
										if (chan != "main")
										{
											using (var db = new ZkDataContext()) {
												Faction channelFaction = db.Factions.FirstOrDefault(x=> chan == x.Name);
												//Clan channelClan = db.Clans.FirstOrDefault(x=> x.GetClanChannel() == chan);
												Account account = Account.AccountByName(db, e.UserName);
												if (!(account.IsZeroKAdmin) &&
													((chan == AuthService.ModeratorChannel)	
                                                    || (channelFaction != null && account.Faction != channelFaction)
													//|| (channelClan != null && account.Clan != channelClan)
                                                    ))
                                                {
                                                    client.Say(SayPlace.User, user.Name, "Not authorized to subscribe to this channel", false);
                                                }
                                                else
                                                {
                                                    var accountID = account.AccountID;
                                                    var subs = db.LobbyChannelSubscriptions.FirstOrDefault(x => x.AccountID == accountID && x.Channel == chan);
                                                    if (subs == null)
                                                    {
                                                        subs = new LobbyChannelSubscription() { AccountID = accountID, Channel = chan };
                                                        db.LobbyChannelSubscriptions.InsertOnSubmit(subs);
                                                        db.SubmitChanges();
                                                        client.JoinChannel(chan);
                                                    }
                                                    client.Say(SayPlace.User, user.Name, "Subscribed", false);
                                                }
											}
										}
									}
								}
								else if (e.Text.StartsWith("!unsubscribe"))
								{
									var regex = Regex.Match(e.Text, "!unsubscribe #([^ ]+)");
									if (regex.Success)
									{
										var chan = regex.Groups[1].Value;

										using (var db = new ZkDataContext()) {
										    var accountID = Account.AccountByName(db, e.UserName).AccountID;
											var subs = db.LobbyChannelSubscriptions.FirstOrDefault(x => x.AccountID == accountID && x.Channel == chan);
											if (subs != null)
											{
												db.LobbyChannelSubscriptions.DeleteOnSubmit(subs);
												db.SubmitChanges();
											}
											client.Say(SayPlace.User, user.Name, "Unsubscribed", false);
										}
									}
								}
                                else if (e.Text.Equals("!listsubscriptions"))
                                {
                                    using (var db = new ZkDataContext())
                                    {
                                        var accountID = Account.AccountByName(db, e.UserName).AccountID;
                                        var subscriptionList = "No channels subscribed.";
                                        var subs = db.LobbyChannelSubscriptions.Where(x => x.AccountID == accountID).OrderBy(x => x.Channel).Select(x => x.Channel );
                                        if (subs != null)
                                        {
                                            subscriptionList = "Subscribed to: " + String.Join(", ", subs);
                                        }
                                        client.Say(SayPlace.User, user.Name, subscriptionList, false);
                                    }
                                }

							}
						}
						catch (Exception ex)
						{
							Trace.TraceError("Error sending stored message: {0}", ex);
						}
					});
			}
		}
 partial void UpdateLobbyChannelSubscription(LobbyChannelSubscription instance);
 partial void DeleteLobbyChannelSubscription(LobbyChannelSubscription instance);
 partial void InsertLobbyChannelSubscription(LobbyChannelSubscription instance);