protected Tuple <DateTime, ScheduleMessageState> ExecuteScript(string scriptName, IComponentContext context)
        {
            var script = Scripts[scriptName];

            if (script == null)
            {
                throw new Exception("Script not found");
            }
            RunningScriptName = scriptName;

            var flow = new ScriptFlow(this);

            flow.OnNewMessage +=
                (m) =>
            {
                if (m.Type == ScheduleMessageState.Error)
                {
                    log.Error(String.Format("{0}: {1}", m.Type, m.Message));
                }
                else
                {
                    log.Info(String.Format("{0}: {1}", m.Type, m.Message));
                }
                Progress.SetProgress(m.Message);
            };
            scriptUtility.Flow = flow;

            flow.AddMessage(String.Format("Starting {1} for {0}", TaskName, scriptName));
            OnScriptStarted(script);
            //init
            try
            {
                flow.AddMessage(String.Format("Initializing {0}", scriptName), ScheduleMessageState.Debug);
                var dependency = ResolveScriptDependency(script, context);
                ValidateDependencies(dependency);
                script.Init(dependency, Settings, flow, scriptUtility);
            }
            catch (Exception ex)
            {
                flow.AddMessage("Script init failed", ScheduleMessageState.Error);
                flow.Dump(ex);
            }
            //execution
            if (flow.MessagesState < ScheduleMessageState.Error)
            {
                try
                {
                    script.Execute();
                }
                catch (FlowException ex)
                {
                    if (ex.ExceptionType == FlowExceptionType.Fail)
                    {
                        flow.AddMessage(ex.Message, ScheduleMessageState.Error);
                    }
                    else if (!String.IsNullOrEmpty(ex.Message))
                    {
                        flow.AddMessage(ex.Message);
                    }
                }
                catch (Exception ex)
                {
                    flow.AddMessage("Script failed with exception", ScheduleMessageState.Error);
                    flow.Dump(ex);
                }
            }
            //execution done - changing and saving settings
            Settings.Set(SETTING_LAST_STATE, flow.MessagesState);

            var currentTime = DateTime.Now;

            if (flow.MessagesState < ScheduleMessageState.Error)
            {
                //update schedules
                ScheduledScripts = ScheduledScripts.Skip(1).ToList();
                flow.ScheduledScripts.ForEach(x =>
                {
                    if (Scripts.Any(s => s.Key == x.Key))
                    {
                        ScheduledScripts.Add(new BrowsingGoalScriptSchedule()
                        {
                            ScriptName = x.Key, Date = currentTime.AddSeconds(x.Value)
                        });
                    }
                    else
                    {
                        flow.AddMessage(String.Format("Script {0} not found for schedule.", x.Key), ScheduleMessageState.Error);
                    }
                });
                ScheduledScripts = ScheduledScripts.OrderBy(x => x.Date).ToList();
                flow.AddMessage(String.Format("{0} scripts in queue", ScheduledScripts.Count), ScheduleMessageState.Debug);
            }
            flow.AddMessage(String.Format("Script {0}.{1} finished", TaskName, RunningScriptName), flow.MessagesState);
            Settings.Set(SETTING_PREFIX_MESSAGES + scriptName, flow.Messages);

            Progress.SetProgressRemaining(RunningScriptName + " complete",
                                          (int)((0.0 + ProgressStatus.PROGRESS_MAX) * (Math.Min(ScheduledScripts.Count, Scripts.Count) / (0.0 + Scripts.Count))));

            OnScriptFinished(script);
            if (ScheduledScripts.Count == 0 || flow.MessagesState >= ScheduleMessageState.Error)
            {
                flow.AddMessage(String.Format("Task '{0}' finished", TaskName));
                OnTaskFinished();
            }
            RunningScriptName = null;
            return(new Tuple <DateTime, ScheduleMessageState>(
                       (ScheduledScripts.Count == 0) ? DateTime.MaxValue :
                       ScheduledScripts.First().Date, flow.MessagesState));
        }