/*!
 *  \brief Compile a shared library for evaluating the fitness of each individual in deme specified.
 *  \param ioDeme Reference to the deme for which to compile a shared library.
 *  \param ioContext Evolutionary context of the operation.
 *
 */
void SharedLibCompileOp::operate(Beagle::Deme& ioDeme, Beagle::Context& ioContext)
{  
    Beagle_StackTraceBeginM();

	std::string lPathLib;

    /* The abstract class Operator is defined in the namespace Beagle.
    * Thus, the Context passed in is from Beagle as well.
    * However, Beagle::GP::Individual::deparse requires a Beagle::GP::Context.
    * Cast the Beagle::Context passed in to a Beagle::GP::Context.
    */
    Beagle::GP::Context lContext= Beagle::castObjectT<Beagle::GP::Context&>(ioContext);

	// Create a SharedLibCompiler.
    int lNrColumns= castHandleT<Int>(ioContext.getSystem().getRegister()["icu.dataset.columns"])->getWrappedValue();
    std::string lTmpDirectory= castHandleT<String>(ioContext.getSystem().getRegister()["icu.compiler.tmp-directory"])->getWrappedValue();
    SharedLibCompiler lSharedLibCompiler(lNrColumns, lTmpDirectory);
    
    // Add individuals, compile.
    for(Beagle::Deme::const_iterator lIndividual=ioDeme.begin(); lIndividual!=ioDeme.end(); ++lIndividual)
    {
        Beagle::GP::Individual::Handle lGPIndividual= castHandleT<Beagle::GP::Individual>(*lIndividual);
		lSharedLibCompiler.addIndividual(*lGPIndividual, lContext.getGeneration(), lContext.getDemeIndex(), lIndividual- ioDeme.begin());
	}
	std::ostringstream lLibName;
	lLibName << "g" << lContext.getGeneration() << "_d" << lContext.getDemeIndex();
	lPathLib= lSharedLibCompiler.compile(lLibName.str());

    // Update register with the path of the newly compiled library.
    lContext.getSystem().getRegister().modifyEntry("icu.compiler.lib-path", new String(lPathLib));

    Beagle_StackTraceEndM("void SharedLibCompileOp::operate(Deme& ioDeme, Context& ioContext)");
}