class OperationConductor implements OnOperationCompleteListener {

    public void run()
    {
        final int ORIGINAL_OP_COUNT = pendingOperations.size();

        try
        {
            logger.debug("Loading Prior Progress (if available)");
            loadPriorProgress();

            logger.debug("Getting executor service");
            if(executorService == null)
            {
                executorService = Executors.newFixedThreadPool(
                    Integer.parseInt(executorContext.getLaunchDataWrapper().getPropertyRetriever().getField(THREAD_POOL_SIZE_SETTING, Integer.toString(DEFAULT_THREAD_POOL_SIZE))),
                    new OperationRunnerThreadFactory("OpRunner-"));
            }

            logger.debug("Adding progress");
            executorContext.getAgendaProgressReporter().addProgress(ProcessingState.EXECUTING, ExecutorMessages.OPERATIONS_RUNNING.getMessage());

            logger.debug("Before drain/launch operations.");
            while (pendingOperations.size() > 0 || runningOperations.size() > 0)
            {
                drainPostProcessOperations();
                launchReadyPendingOperations();
                waitOnPostProcessOperations();
            }
        }
        catch(Throwable t)
        {
            diagnosticEvents.add(new DiagnosticEvent(ExecutorMessages.OPERATIONS_ERROR.getMessage(), t));
            logger.error(ExecutorMessages.OPERATIONS_ERROR.getMessage(), t);
        }
        finally
        {
            // TODO: log an error or something if these don't match
            logger.info("Original OpCount: {} Completed OpCount: {}", ORIGINAL_OP_COUNT, completedOperations.size());
            operationRunnerFactory.shutdown();
            List<Runnable> remainingTasks = executorService.shutdownNow();
            logger.info("ExecutorService shutdownNow called. {} Runnables were waiting.", remainingTasks.size());
        }
    }

    public  OperationConductor(Collection<Operation> operations, ExecutorContext executorContext,
        List<OperationConductorModifier> completedOperationModifiers);
    public  OperationConductor(Collection<Operation> operations, ExecutorContext executorContext);

}