void submitTask(AdvancedAdaptiveLevinSearchProblem problem)
        {
            Observable levinSearchObservable = new Observable();

            levinSearchObservable.register(new AdvancedAdaptiveLevinSearchLogObserver(log));
            levinSearchObservable.register(this); // register ourself to know when the task failed or succeeded

            LevinSearchTask levinSearchTask = new LevinSearchTask(levinSearchObservable, database, problem);


            if (problem.humanReadableIndirectlyCallableProgramNames.Count > 0)
            {
                // query the problem for the hint
                Debug.Assert(problem.humanReadableIndirectlyCallableProgramNames.Count == 1, "Implemented for just one subproblem");
                var q = database.getQuery().whereHumanReadableProgramName(problem.humanReadableIndirectlyCallableProgramNames[0]);

                foreach (var iq in q.enumerable)
                {
                    Debug.Assert(iq.program != null, "Problem must have been already solved to be added as an indrectly callable program!");

                    levinSearchTask.problem.indirectCallablePrograms.Add(iq);
                }
            }


            scheduler.addTaskSync(levinSearchTask);

            levinSearchTask.levinSearchContext = new LevinSearchContext(problem);
            levinSearchTask.levinSearchContext.localInterpreterState.maxNumberOfRetiredInstructions = problem.maxNumberOfRetiredInstructions;
            fillUsedInstructionSet(levinSearchTask.levinSearchContext);
            levinSearchTask.levinSearchContext.initiateSearch(sparseArrayProgramDistribution, problem.enumerationMaxProgramLength);
        }
        public void notify(params object[] arguments)
        {
            string          messageType = (string)arguments[0];
            LevinSearchTask task        = (LevinSearchTask)arguments[1];
            string          taskName    = (string)arguments[2];

            string message = "";

            if (messageType == "success")
            {
                ulong iteration = task.levinSearchContext.searchIterations;

                message = string.Format("< Task:{0} (no meta)> success, {0} required< #iterations={1}, cputime=?, realtime=?>", taskName, iteration);
            }
            else if (messageType == "increaseProgramsize")
            {
                message = string.Format("<Task:{0} (no meta)> increaseProgramsize, {1}", taskName, task.levinSearchContext.numberOfInstructions);
            }
            else if (messageType == "failed")
            {
                message = string.Format("<Task:{0} (no meta)> failed, {1}", taskName, "?");
            }

            Logged logged = new Logged();

            logged.message       = message;
            logged.notifyConsole = Logged.EnumNotifyConsole.YES;
            logged.origin        = new string[] { "search", "ALS" };
            logged.serverity     = Logged.EnumServerity.INFO;
            log.write(logged);
        }
        // implementation of IObserver
        public void notify(params object[] arguments)
        {
            string          messageType = (string)arguments[0];
            LevinSearchTask task        = (LevinSearchTask)arguments[1];
            string          taskName    = (string)arguments[2];

            if (messageType == "success")
            {
                // a search was successful

                // TODO< retrive all tasks which solved the same problem with different parameters and stop them >

                tryToDequeueTaskAndSubmit();
            }
            else if (messageType == "failed")
            {
                // a search failed

                // we just suply the next task
                tryToDequeueTaskAndSubmit();
            }
        }