private async Task Raid()
        {
            if (Command.Count() < 4)
            {
                await Handler.MakeCommandMessage(Message.Channel, Parser.Language.Strings["commandInvalidNumberOfParameters"]);
                return;
            }

            var post = Parser.ParsePost(Message);

            if (post.PokemonId == default(int))
            {
                await Handler.MakeCommandMessage(Message.Channel, string.Format(Parser.Language.Formats["commandRaidPokemonInvalid"], Command[1]));
                return;
            }

            if (post.HasEndDate == false)
            {
                await Handler.MakeCommandMessage(Message.Channel, string.Format(Parser.Language.Formats["commandRaidTimespanInvalid"], Command[2]));
                return;
            }

            var d = Message.Channel.EnterTypingState();
            try
            {

                post.Location = Parser.ToTitleCase(string.Join(" ", Command.Skip(3)));
                post.FullLocation = Parser.GetFullLocation(post.Location, GuildConfig, Message.Channel.Id);

                if (GuildConfig.Places.ContainsKey(post.Location.ToLower()))
                {
                    post.LatLong = GuildConfig.Places[post.Location];
                }
                else
                    post.LatLong = await Parser.GetLocationLatLong(post.FullLocation, Message.Channel, Config);

                if (string.IsNullOrWhiteSpace(post.Location))
                {
                    await Handler.MakeCommandMessage(Message.Channel, Parser.Language.Strings["commandRaidLocationInvalid"]);
                    return;
                }
                post.IsValid = true;

                var outputchannel = !GuildConfig.OutputChannelId.HasValue || GuildConfig.OutputChannelId == 0 ? null : Message.Server.Channels.FirstOrDefault(x => x.Id == GuildConfig.OutputChannelId.Value);

                await Handler.DoPost(post, Message, Parser, outputchannel, true);
            }
            catch (Exception e)
            {
                Handler.DoError(e, "Executor");
            }
            finally
            {
                d.Dispose();
            }
        }
        /// <summary>
        /// Performs the raid post behavior
        /// </summary>
        /// <param name="message"></param>
        /// <param name="parser"></param>
        /// <param name="outputchannel"></param>
        /// <param name="pin"></param>
        /// <returns></returns>
        public async Task DoPost(PokemonRaidPost post, IChatMessage message, MessageParser parser, IChatChannel outputchannel = null, bool force = false)
        {
            //var post = await parser.ParsePost(message, Config);//await DoResponse(message, parser);//returns null if

            if (post != null)
            {
                post.OutputChannelId = outputchannel?.Id ?? 0;
                post = AddPost(post, parser, message, true, force);

                if (post.IsValid)
                {
                    IDisposable d = null;

                    if (!post.IsExisting)//it's going to post something and google geocode can take a few secs so we can do the "typing" behavior
                    {
                        d = message.Channel.EnterTypingState();
                    }
                    try
                    {
                        if ((post.LatLong == null || !post.LatLong.HasValue) && !string.IsNullOrWhiteSpace(post.Location))
                        {
                            var guildConfig = Config.GetServerConfig(message.Channel.Server.Id, ChatTypes.Discord);

                            if (guildConfig.Places.ContainsKey(post.Location.ToLower()))
                            {
                                post.LatLong = guildConfig.Places[post.Location.ToLower()];
                            }
                            else
                            {
                                post.LatLong = await parser.GetLocationLatLong(post.FullLocation, message.Channel, Config);
                            }
                        }

                        await MakePost(post, parser);

                        Config.Save();
                    }
                    catch (Exception e)
                    {
                        DoError(e);
                    }
                    finally
                    {
                        if (d != null)
                        {
                            d.Dispose();
                        }
                    }
                }
                //else TODO maybe DM user to see if it's valid? Tricky because hard to hold on to post ID reference...
            }

            Config.Save();
        }