private bool TryGetExecutor(ICommandContext context, out Func <Task> call)
        {
            call = null;
            if (context.Command == null)
            {
                return(false);
            }

            var command = context.Command.Value;

            var instance = DependencyFactory.WithInstance(context).Construct(command.CommandType) as Command;

            if (instance == null)
            {
                throw new InvalidOperationException($"Unable to create an instance of the {command.CommandType} command");
            }
            ArgumentCheckResponse response = default(ArgumentCheckResponse);
            var calls = PermissionManager.CheckContext(context, command.Calls.ToArray());

            if (calls.Count() == 0)
            {
                ReplyAsync(context, COMMANDEXECUTOR_DISALLOWED_CHANNEL, ReplyType.Error);
                return(false);
            }
            var subCalls = CheckSubcommands(context, calls);

            if (subCalls.Count() == 0)
            {
                ReplyAsync(context, COMMANDEXECUTOR_SUBCALL_UNKNOWN, ReplyType.Error, context.Prefix, context.CommandText);
                return(false);
            }
            foreach (var subCall in subCalls)
            {
                response = MatchArguments(context, subCall.CallInfo, subCall.CallName).Result;
                if (response.SuccessStatus == ArgumentCheckResult.Successful)
                {
                    var permCheck = PermissionManager.CheckAllowed(context, new CallInfo[] { subCall.CallInfo });
                    if (!permCheck.IsSuccess)
                    {
                        if (permCheck.ErrorMessage != null)
                        {
                            ReplyAsync(context, permCheck.ErrorMessage, ReplyType.Error, context.Prefix, context.CommandText);
                        }
                    }
                    else
                    {
                        call = () =>
                        {
                            instance.Install(context, DependencyFactory);
                            foreach (var buildEvent in Owner.GetBuildEvents(instance.GetType()))
                            {
                                buildEvent.Invoke(instance);
                            }
                            LogCommand(context, subCall.CallInfo);
                            if (subCall.CallInfo.ShowTyping)
                            {
                                context.Channel.TriggerTypingAsync().Wait();
                            }

                            return((Task)subCall.CallInfo.Method.Invoke(instance, response.CallArguments));
                        };
                        return(true);
                    }
                    return(false);
                }
            }
            ReplyAsync(context, response.ErrorMessage.message, ReplyType.Error, new object[] { context.Prefix, context.CommandText }
                       .Concat(response.ErrorMessage.values.Select(v => v(context.TextResource)))
                       .ToArray());
            return(false);
        }