@Override
    public Object run() throws Exception {
        if (getModel() == null) {
            throw new ComponentException("missing 'model'.");
        }
        if (calib_start == null) {
            throw new ComponentException("missing 'calibration_start'");
        }
        if (steps.isEmpty()) {
            throw new ComponentException("missing 'step' definition(s)");
        }

        ModelExecution exec = new ModelExecution();
        Object start = exec.getParameter().get("startTime");
        Object end = exec.getParameter().get("endTime");
        Date startTime = Conversions.convert(start, Date.class);
        Date endTime = Conversions.convert(end, Date.class);     
        
        
       
        
        if (calib_start.after(endTime)) {
            throw new ComponentException("illegal calibration_start: " + calib_start);
        }
        for (Step step : steps) {
            step.init(exec, startMonthOfYear, calib_start, endTime, rounds);            
        }
         
        // Send info to summary writer
        String outFolder = steps.get(0).outFolder.getAbsolutePath();       
        List<Params> params = getModel().getParams();
        SW.setModelInfo(rounds, steps.size(), getModel().getClassname(), params, calib_start, startTime, endTime, outFolder);
        for (int s = 0; s < steps.size(); s++) {
                Step step = steps.get(s);
                Data stepData = step.round()[0];
                SCE initSce = new SCE(exec, step, stepData);
                double origOF = initSce.getInitialOF();
                SW.writeInitialStep(s, step, stepData, origOF);
        }
       
        // Call SCE for each step of each round.               
        for (int r = 0; r < rounds; r++) {
            for (int s = 0; s < steps.size(); s++) {
                Step step = steps.get(s);
                Data stepData = step.round()[r];

                System.out.println("\n\n>>>>>>>>>>>>>>  Round [" + (r + 1) + "]  Step [" + step.getName() + "] <<<<<<<<<<<<<<");              
                SCE sce = new SCE(exec, step, stepData);
                double finalOF = sce.run();
                
               // Step step0 = steps.get(0);
                SW.writeStep(r, s, step, stepData, finalOF );
                exec.writeParameterCopy(step, r);
                step.post(r, stepData);
                Runtime.getRuntime().gc();
            }
        }
        Compound.shutdown();
        SW.close();
        return null;
    }