//-----------------------------------------------------------------------------------------------
// Called by Ipopt when finished
//-----------------------------------------------------------------------------------------------
void BonminInterfaceGradients::finalize_solution(TMINLP::SolverReturn status,
                               Index n, const Number* x, Number obj_value)
{


    cout << "IPOPT returned a status indicating ";

    if ( status == Ipopt::SUCCESS ) cout << "SUCCESS";
    else if ( status == Ipopt::MAXITER_EXCEEDED ) cout << "MAXITER_EXCEEDED";
    else if ( status == Ipopt::CPUTIME_EXCEEDED ) cout << "CPUTIME_EXCEEDED";
    else if ( status == Ipopt::STOP_AT_TINY_STEP ) cout << "STOP_AT_TINY_STEP";
    else if ( status == Ipopt::STOP_AT_ACCEPTABLE_POINT ) cout << "STOP_AT_ACCEPTABLE_POINT";
    else if ( status == Ipopt::LOCAL_INFEASIBILITY ) cout << "LOCAL_INFEASIBILITY";
    else if ( status == Ipopt::USER_REQUESTED_STOP ) cout << "USER_REQUESTED_STOP";
    else if ( status == Ipopt::FEASIBLE_POINT_FOUND ) cout << "FEASIBLE_POINT_FOUND";
    else if ( status == Ipopt::DIVERGING_ITERATES ) cout << "DIVERGING_ITERATES";
    else if ( status == Ipopt::RESTORATION_FAILURE ) cout << "RESTORATION_FAILURE";
    else if ( status == Ipopt::ERROR_IN_STEP_COMPUTATION ) cout << "ERROR_IN_STEP_COMPUTATION";
    else if ( status == Ipopt::INVALID_NUMBER_DETECTED ) cout << "INVALID_NUMBER_DETECTED";
    else if ( status == Ipopt::TOO_FEW_DEGREES_OF_FREEDOM ) cout << "TOO_FEW_DEGREES_OF_FREEDOM";
    else if ( status == Ipopt::INVALID_OPTION ) cout << "INVALID_OPTION";
    else if ( status == Ipopt::OUT_OF_MEMORY ) cout << "OUT_OF_MEMORY";
    else if ( status == Ipopt::INTERNAL_ERROR ) cout << "INTERNAL_ERROR";
    else cout << "UNKNOWN_ERROR";

    cout << endl;

    cout << "Writing the final solution to the summary file..." << endl;
    Case *c = generateCase(n,x);
    c->setObjectiveValue(-obj_value);

    p_optimizer->sendBestCaseToRunner(c);

}
//-----------------------------------------------------------------------------------------------
// Starts the optimization
//-----------------------------------------------------------------------------------------------
void NomadIpoptOptimizer::start()
{
    cout << "Starting the NOMAD optimizer..." << endl;

    if(p_disp == 0) initialize();

    try
    {

        // NOMAD initializations:
        NOMAD::begin(0, 0); // hope this works, was: begin(argc, argv)



        // parameters creation:
        generateParameters();

        // custom evaluator creation:
        p_evaluator = new NomadIpoptEvaluator(*p_param, this);


        // algorithm creation and execution:
        NOMAD::Mads mads ( *p_param , p_evaluator );
        mads.run();

        // getting the best feasible solution, sending it to the runner if exists
        const NOMAD::Eval_Point *best_feas = mads.get_best_feasible();
        if(best_feas != NULL)
        {
            const NOMAD::Point outputs = best_feas->get_bb_outputs();

            // setting the variable values
            Case *c = p_evaluator->generateCase(*best_feas);

            // trying to find a result case in the evaluator
            Case *res = p_evaluator->findResult(c);

            if(res != 0) sendBestCaseToRunner(res);
            else
            {
                // the objective
                c->setObjectiveValue(-outputs[0].value());

                // sending it to the runner
                sendBestCaseToRunner(c);
            }



            delete c;
        }

    }
    catch(exception &e)
    {
        cerr << "\nNOMAD has been interrupted (" << e.what() << ")\n\n";
    }

    NOMAD::Slave::stop_slaves (*p_disp);
    NOMAD::end();

    emit finished();


}