bool Pipeline::runSimulation(XMLNode tms)
{
	m_pMevicLogger->logMessage("[Pipeline::runSimulation]");

	XMLNode chain,       // Current Chain of the current Simulation
	        mod,         // Current Module in the current Chain of the current Simulation
	        param;       // Current Parameter in the current Module of the current Chain of the current Simulation

	string chainName,     // Respective chain of modules name
	       modFormalName, // Module formal name (type)
	       modActualName, // Module actual name (label); indicated by keyword "module" or "name"
	       paramName,     // Parameter name
	       paramValue;    // Parameter value

	// For every Simulation
	for(int simulation = 0; simulation < m_numberOfSimulations; simulation++)
	{
		//! Create new MevicLogger for this simulation
		MevicLogger * pMevicLogger = new MevicLogger(m_pMevicLogger->getDirName(), "simulation_" + boost::lexical_cast<string>(simulation), false); // Log in the same directory, no console feedback
		pMevicLogger->logMessage("Simulation: " + boost::lexical_cast<string>(simulation));

		InOutManagement *    pInOutManagement    = new InOutManagement();    // (Pointer to) Temporary input/output manager
		ContainerExchanger * pContainerExchanger = new ContainerExchanger(); // (Pointer to) Container exchanger

		boost::posix_time::ptime         startTime,          // Simulation start time stamp
										 endTime;            // Simulation end time stamp
		boost::posix_time::time_duration simulationDuration; // Simulation duration

		startTime = boost::posix_time::microsec_clock::local_time();

		// For every Chain of the current Simulation
		for(int i = 0; i < tms.nChildNode(); i++)
		{
			chain = tms.getChildNode(i);
			chainName = wcToMb(chain.getName());
			pMevicLogger->logMessage("\tChain: " + chainName);

			UtilitiesExchanger * pUtilitiesExchanger = new UtilitiesExchanger(); // (Pointer to) Utilities exchanger

			vector<DSContainer *> containers; // List of (pointers to) DSContainers

			//! If the vector of DSContainer objects is empty, add a dummy test object
			if(containers.empty())
			{
				DSContainer * pContainer = new DSContainer();
				containers.push_back(pContainer);
				pContainer = 0;
			}

			// For every Module in the current Chain of the current Simulation
			for(int j = 0; j < chain.nChildNode(); j++)
			{
				mod = chain.getChildNode(j);
				modFormalName = wcToMb(mod.getName());
				modActualName = getName(mod);
				pMevicLogger->logMessage("\t\tModule: " + modActualName);

				try
				{
					// Generate new Module
					FactoryModule * pFactoryModule = new FactoryModule();                                // Pointer to Module generator object
					Module * pModule = pFactoryModule->construct(modFormalName.c_str(), pMevicLogger); // Pointer to new Module
					delete pFactoryModule;
					pFactoryModule = 0;

					//! For every Parameter in the current Module of the current Chain of the current Simulation
					for(int k = 0; k < mod.nChildNode(); k++)
					{
						param = mod.getChildNode(k);
						paramName  = wcToMb(param.getName());
						paramValue = wcToMb(param.getAttribute(_T("value")));

						//! Get respective local parameter if any
						if(0 == paramValue.compare("$"))
						{
							paramValue = m_localParameters[chainName][modActualName][paramName]->GetCurrentPositionAndIterate();
						}
						//! Get respective global parameter if any
						else if(   2 <= paramValue.size()
								&& 0 == paramValue.compare(0, 1, "$"))
						{
							paramValue = m_globalParameters[paramValue.substr(1)]->GetCurrentPosition();
						}
						//! Provide in-out management if any
						else if(InOutManagement::check(paramValue))
						{
							paramValue = pInOutManagement->manage(paramValue);
						}
						//! Replace command-line arguments if any 
						paramValue = getParamValue(paramValue);
						//! Replace backslashes by forward-slashes if any
						while(paramValue.find_last_of('\\') != std::string::npos)
						{
							paramValue = paramValue.replace(paramValue.find_last_of('\\'), 1, "/");
						}

						pMevicLogger->logMessage("\t\t\tParameter: " + paramName + " = " + paramValue);

						//! Set the Module's Parameter
						pModule->SetParameter(paramName, paramValue);
					}

					//! Set the Module's container exchanger
					pModule->SetContainerExchanger(pContainerExchanger);

					//! Set the Module's utilities exchanger
					pModule->SetUtilitiesExchanger(pUtilitiesExchanger);

					//! Simulate Module
					pModule->Simulate(containers);

					delete pModule;
					pModule = 0;
				}
#ifdef USE_OPENCL
				catch(cl::Error& e)
				{
					m_pMevicLogger->logError(string("Exception caught: Module initialization/simulation failed ")
						+modFormalName+string("; ")+e.what()+string("(): ")+openclStrError(e.err()));
				}
#endif
				catch(exception& e)
				{
					m_pMevicLogger->logError(string("Exception caught: Module initialization/simulation failed ")
						+modFormalName+string("; ")+e.what());
				}
			}

			//! Clean-up non-used (not present in the ContainerExchanger) DSContainer objects in the vector
			for (unsigned int i = 0; i < containers.size(); i++)
			{
				DSContainer * pContainer = containers[i];
				// Check if the Container is not present in the ContainerExchanger
				if ((pContainerExchanger->lookUpContainer(pContainer)).empty())
				{
					delete pContainer;
				}
			}
			containers.clear();

			delete pUtilitiesExchanger;
			pUtilitiesExchanger = 0;
		}

		delete pContainerExchanger;
		pContainerExchanger = 0;
		delete pInOutManagement;
		pInOutManagement = 0;

		endTime = boost::posix_time::microsec_clock::local_time();
		simulationDuration = endTime - startTime;
		pMevicLogger->logMessage("Duration: " + boost::posix_time::to_simple_string(simulationDuration));
		delete pMevicLogger;
	}

	//! Return
	return true;
}