protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
		{
			if (context.IsBotAddressed
					|| message.Type != MessageType.Default
					|| context.RandomProvider.Next(2) == 0
					|| !Matcher.IsMatch(message.Text))
			{
				return NotHandled();
			}

			var text = Matcher.Replace(
					message.Text,
					m =>
					{
						var capture = m.Captures[0].Value;
						if (capture[0] == 'e')
						{
							return "s" + capture;
						}

						if (capture[1] == 'X')
						{
							return "SE" + capture.Substring(1);
						}

						return "Se" + capture.Substring(1);
					});

			return Handled(Message(text));
		}
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            var match = Matcher.Match(message.Text);
            if (!match.Success)
            {
                return NotHandled();
            }
            
            var index = context.RandomProvider.Next(0, 2);
            string answerText;

            if (index == 0)
            {
                // Negative
                var answerIndex = context.RandomProvider.Next(0, NegativeResponses.Length);
                answerText = NegativeResponses[answerIndex];
            }
            else
            {
                // Positive
                var answerIndex = context.RandomProvider.Next(0, PositiveResponses.Length);
                answerText = PositiveResponses[answerIndex];
            }

            return Handled(Message("@{0}: {1}!", context.User.Name, answerText));
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            var match = Matcher.Match(message.Text);
            if (!match.Success)
            {
                return NotHandled();
            }

            var values = new List<string>();
            values.Add(match.Groups[1].Value.Trim());
            values.AddRange(match.Groups[2].Captures.OfType<Capture>().Select(x => x.Value.Trim()));

            var options = (from v in values
                           where v.Length > 0 && !v.Equals("or", StringComparison.InvariantCultureIgnoreCase)
                           select v).ToList();

            if (options.Count == 0)
            {
                return Handled(Message("{0}: confuse BawBag, receive kicking...", context.User.Name), Kick());
            }
            
            var index = context.RandomProvider.Next(0, options.Count);

            return Handled(Message("@{0}: {1}", context.User.Name, options[index]));
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            var getKaramMatch = GetKarmaExpression.Match(message.Text);
            if (getKaramMatch.Success)
            {
                return GetKarma(getKaramMatch.Groups["nick"].Value, context);
            }

            return NotHandled();
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            if (message.Type != MessageType.Action)
            {
                return MessageHandlerResult.NotHandled;
            }

            var match = Matcher.Match(message.Text);
            if (!match.Success)
            {
                return NotHandled();
            }

            var countText = match.Groups["count"].Value;
            var sidesText = match.Groups["sides"].Value;

            if (countText == string.Empty)
            {
                countText = "1";
            }

            var count = int.Parse(countText);
            var sides = int.Parse(sidesText);

            if (count > 10)
            {
                return Handled(Message(string.Format("@{0}: that's too many dice for my tiny bothands!", context.User.Name)));
            }

            if (sides > 20)
            {
                return Handled(Message(string.Format("@{0}: the numbers are too tiny to read!", context.User.Name)));
            }

            if (count == 1)
            {
                var result = context.RandomProvider.Next(1, sides + 1);
                var singleResponse = string.Format("@{0}: you got {1}.", context.User.Name, result);

                return Handled(Message(singleResponse));
            }

            var results = new List<int>();
            for (var index = 0; index < count; ++index)
            {
                var result = context.RandomProvider.Next(1, sides + 1);
                results.Add(result);
            }

            var response = string.Format("@{0}: you got {1} for a total of {2}.", context.User.Name, string.Join(", ", results), results.Sum());

            return Handled(Message(response));
        }
        public MessageHandlerResult Execute(Message message, IPluginContext context)
        {
            Guard.NullParameter(message, () => message);
            Guard.NullParameter(context, () => context);

            if (MustBeAddressed && !context.IsBotAddressed)
            {
                return MessageHandlerResult.NotHandled;
            }

            return ExecuteCore(message, context);
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            var assignMatches = AssignKarmaExpression.Matches(message.Text);
            foreach (var match in assignMatches.Cast<Match>())
            {
                var nick = match.Groups["nick"].Value;
                var amount = match.Groups["quantity"].Length - 1;

                if (string.Equals(nick, context.User.Name, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var karma = new Karma
                    {
                        CreatedBy = context.User.Name,
                        CreatedOn = context.DateTimeProvider.GetUtcNow(),
                        Name = nick,
                        Quantity = amount
                    };

                context.RavenSession.Store(karma);
            }

            var retractMatches = RetractKarmaExpression.Matches(message.Text);
            foreach (var match in retractMatches.Cast<Match>())
            {
                var nick = match.Groups["nick"].Value;
                var amount = -1 * (match.Groups["quantity"].Length - 1);

                if (string.Equals(nick, context.User.Name, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var karma = new Karma
                {
                    CreatedBy = context.User.Name,
                    CreatedOn = context.DateTimeProvider.GetUtcNow(),
                    Name = nick,
                    Quantity = amount
                };

                context.RavenSession.Store(karma);
            }

            return NotHandled();
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            if (context.IsBotAddressed || message.Type != MessageType.Default)
            {
                return NotHandled();
            }

            if (!Matcher.IsMatch(message.Text) || context.RandomProvider.Next(2) == 0)
            {
                return NotHandled();
            }

            var text = Matcher.Replace(message.Text, "$2 $1");

            return Handled(Message(text));
        }
		protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
		{
			if (message.Type != MessageType.Default)
			{
				return NotHandled();
			}

			var match = ImageMeExpression.Match(message.Text);
			if (match.Success)
			{
				var query = match.Groups["query"].Value;
				return GetImage(query, context);
			}

			return NotHandled();
		}
		protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
		{
			var responseTrigger = context.TextProcessor.SimplifyText(message.Text);
			var factoidTrigger = responseTrigger.ToUpperInvariant();

			var factoid = context.RavenSession.Query<Factoid>().SingleOrDefault(x => x.Trigger == factoidTrigger);
			if (factoid == null)
			{
				return NotHandled();
			}

			var matchingResponses = factoid.Responses.Where(x => !x.IsCaseSensitive || x.Trigger == responseTrigger).ToList();
			var index = context.RandomProvider.Next(matchingResponses.Count);

			var factoidResponse = matchingResponses[index];
			var responseText = context.TextProcessor.FormatPluginResponse(factoidResponse.Response, context);

			MessageResponse response;

			switch (factoidResponse.ResponseType)
			{
				case FactoidResponseType.Is:
					response = Message("{0} is {1}", message.Text, responseText);
					break;

				case FactoidResponseType.Action:
					response = Action(responseText);
					break;

				case FactoidResponseType.Reply:
					response = Message(responseText);
					break;

				default:
					throw new Exception("Unknown response type.");
			}

			return Handled(response);
		}
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            if (message.Type != MessageType.Default)
            {
                return NotHandled();
            }

            var addMatch = AddQuoteExpression.Match(message.Text);
            if (addMatch.Success)
            {
                return AddQuote(addMatch.Groups["nick"].Value, addMatch.Groups["text"].Value, context);
            }

            var getMatch = GetQuoteExpression.Match(message.Text);
            if (getMatch.Success)
            {
                var nickMatch = getMatch.Groups["nick"];
                return GetQuote(nickMatch.Success ? nickMatch.Value : null, context);
            }

            return NotHandled();
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {         
            var addMatch = AddFactoidExpression.Match(message.Text);
            if (addMatch.Success)
            {
                return AddFactiod(addMatch, context);
            }

            var showtMatch = ShowFactoidExpression.Match(message.Text);
            if (showtMatch.Success)
            {
                return ShowFactiod(showtMatch, context);
            }

            var removeMatch = RemoveFactoidExpression.Match(message.Text);
            if (removeMatch.Success)
            {
                return RemoveFactoid(removeMatch, context);
            }

            return NotHandled();
        }
        protected override MessageHandlerResult ExecuteCore(Message message, IPluginContext context)
        {
            Match match = null;
            if (message.Type == MessageType.Action)
            {
                match = GetFirstMatch(
                    message.Text,
                    new Regex(@"^\s*puts\s+(?<item>.+?)\s+in\s+@?" + context.BotName + @"\b?.*$", RegexOptions.IgnoreCase),
                    new Regex(@"^\s*gives\s+@?" + context.BotName + @"\s+(?<item>.+?)\.?\s*$", RegexOptions.IgnoreCase),
                    new Regex(@"^\s*gives\s+(?<item>.+?)\s+to\s+@?" + context.BotName + @"\b?.*$", RegexOptions.IgnoreCase));
            }

            if (match == null)
            {
                return NotHandled();
            }

            var item = new InventoryItem
                {
                    Value = match.Groups["item"].Value,
                    CreatedBy = context.User.Name,
                    CreatedOn = DateTime.Now
                };

            InventoryItem droppedItem;
            var isDuplicate = context.InventoryManager.AddItem(context.Room, item, out droppedItem, context.TextProcessor);
            if (isDuplicate)
            {
                return Handled(Message("No thanks, @{0}, I've already got one.", context.User.Name));
            }

            if (droppedItem == null)
            {
                return Handled(Action("now contains {0}.", item.Value));
            }

            return Handled(Action("drops {0} and takes {1}.", droppedItem.Value, item.Value));
        }
 protected abstract MessageHandlerResult ExecuteCore(Message message, IPluginContext context);
    private void MessageReceivedCore(MessageType type, string content, User user, Room room)
    {
      var text = WebUtility.HtmlDecode(content);
      var isBotAddressed = false;

      var addressMatch = _botAddressedMatcher.Match(text);
      if (addressMatch.Success)
      {
        isBotAddressed = true;
        text = addressMatch.Groups[1].Value.Trim();
      }

      using (var session = _store.OpenSession())
      {
        var message = new Message
            {
              Text = text,
              Type = type,
            };

        var context = new PluginContext
            {
              IsBotAddressed = isBotAddressed,
              BotName = _configuration.JabbrNick,
              Room = room,
              User = user,
              RavenSession = session,
              RandomProvider = _randomProvider,
              InventoryManager = _inventoryManager,
              TextProcessor = _textProcessor,
              DateTimeProvider = _dateTimeProvider
            };

        _pluginManager.ProcessMessage(message, context, _client);

        session.SaveChanges();
      }
    }