private void startReduceProcessing(Task task)
        {
            task.deleteDividerFiles();

            List <WorkConfig> reduceWorkConfigs = createReduceConfigs(task);

            if (reduceWorkConfigs.Count == 0)
            {
                abortTask(task, "No files to reduce");
                return;
            }

            NextCoordinatorInBulkGetter coordinatorGetter = null;

            try{
                coordinatorGetter = new NextCoordinatorInBulkGetter(validReduceCoordinator);
            }
            catch (Exception e) {
                abortTask(task, "No coordinator");
                return;
            }

            foreach (var workConfig in reduceWorkConfigs)
            {
                startNewReduceWork(task, workConfig, coordinatorGetter.next());
            }
        }
        public void handleReduceCoordinatorTermination(Terminated message, Coordinator reduceCoordinator)
        {
            Console.WriteLine("Reduce coordinator terminated");

            IActorRef coordinatorActor = message.ActorRef;
            NextCoordinatorInBulkGetter coordinatorGetter = null;

            validReduceCoordinator.Remove(reduceCoordinator);

            try{
                coordinatorGetter = new NextCoordinatorInBulkGetter(validReduceCoordinator);
            }
            catch (Exception e) {}

            foreach (int taskId in tasks.Keys.ToList())
            {
                Task task = tasks [taskId];
                if (coordinatorGetter == null)
                {
                    abortTask(task, "No coordinators");

                    continue;
                }

                if (task.ReduceCoordinators.ContainsKey(coordinatorActor))
                {
                    task.ReduceCoordinators.Remove(coordinatorActor);
                }
            }

            if (coordinatorGetter == null)
            {
                return;
            }

            foreach (Work work in reduceCoordinator.Works.Values)
            {
                startNewReduceWork(tasks[work.WorkConfig.TaskId], work.WorkConfig, coordinatorGetter.next());
            }

            foreach (WorkConfig workConfig in reduceCoordinator.OrderedWorks.Values)
            {
                startNewReduceWork(tasks[workConfig.TaskId], workConfig, coordinatorGetter.next());
            }
        }
        public void Handle(DivideResponseMessage message)
        {
            Task task = null;

            if (tasks.TryGetValue(message.TaskId, out task))
            {
                if (message.Files.Count == 0)
                {
                    abortTask(task, "No files to map");
                    return;
                }

                task.addDivideFiles(message.Files);

                NextCoordinatorInBulkGetter coordinatorGetter = null;
                try {
                    coordinatorGetter = new NextCoordinatorInBulkGetter(validMapCoordinator);
                } catch (Exception e) {
                    abortTask(task, "No coordinators");
                    return;
                }
                foreach (Dictionary <string, S3ObjectMetadata> files in message.Files)
                {
                    Dictionary <string, List <S3ObjectMetadata> > workConfigFiles = new Dictionary <string, List <S3ObjectMetadata> > ();

                    foreach (KeyValuePair <string, S3ObjectMetadata> pair in files)
                    {
                        workConfigFiles.Add(pair.Key, new List <S3ObjectMetadata> ()
                        {
                            pair.Value
                        });
                    }

                    WorkConfig workConfig = new WorkConfig(
                        task.Id,
                        task.Username,
                        workConfigFiles,
                        task.AssemblyMetadata
                        );

                    startNewMapWork(task, workConfig, coordinatorGetter.next());
                }
            }
            else
            {
                foreach (Dictionary <string, S3ObjectMetadata> dict in message.Files)
                {
                    foreach (S3ObjectMetadata file in dict.Values)
                    {
                        file.remove();
                    }
                }
            }
        }