int QGTConsole::exec() const {

	if (!this->m_arguments || (this->m_argumentsCount < 2)) {
		_GT_SYSTEM_ERR("Insufficient arguments");
		return (-1);
	}

	// Selects algorithm filter and deserializes provider schema.
	QString filter = QString(this->m_arguments[1]);
	Interpreter interpreter;
	Factory::Item item = Factory::instance().create(filter, NULL);
	if (!item.isValid()) {
		_GT_SYSTEM_ERR(boost::format("Algorithm filter <%1%> not found.") % filter.toStdString());
		return (-1);
	} else {
		interpreter.interpret(item.provider());
		Factory::instance().dispose(item);
	}

	// Prepares generic options and algorithm specified options.
	util::OptionsManager optionsManager(std::string("Generic Options"),
			(boost::format("Program Options for <%1%>") % filter.toStdString()).str());
	optionsManager.genericOptionsDescription().add_options()
			("help,h",															"Displays help test.")
			("input,i",			boost::program_options::value<std::string>(),	"Specifies filename of input mesh.")
			("output,o",		boost::program_options::value<std::string>(),	"Specifies filename of output result.");

	foreach (const Interpreter::Param &param, interpreter.computing()) {
		std::string command = param.getCommand().toStdString();
		std::string description = param.description().toStdString();
		if (param.type() == QString("Integer")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Integer::DataType>(), description.data());
		}
		if (param.type() == QString("Real")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Real::DataType>(), description.data());
		}
		if (param.type() == QString("Switch")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Switch::DataType>(), description.data());
		}
		if (param.type() == QString("Option")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Option::DataType>(), description.data());
		}
		if (param.type() == QString("Vertices")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Vertices::DataType>(), description.data());
		}
		if (param.type() == QString("Edges")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Edges::DataType>(), description.data());
		}
		if (param.type() == QString("Faces")) {
				optionsManager.programOptionsDescription().add_options()(command.data(),
						boost::program_options::value<Parameter::Faces::DataType>(), description.data());
		}
	}

	// Parses command line.
	try {
		optionsManager.parseGenericOptions(this->m_argumentsCount, this->m_arguments);
		optionsManager.parseProgramOptions(this->m_argumentsCount, this->m_arguments);
	} catch (const std::exception &e) {
		_GT_SYSTEM_ERR(boost::format("Error occurred on parsing command line: %1%.") % e.what());
		return (-1);
	}

	// Fetches arguments from program options.
	const util::Options genericOptions(optionsManager.genericOptions());
	const util::Options programOptions(optionsManager.programOptions());
	if (genericOptions.exists("help")) {
		optionsManager.print(std::cout);
		return (0);
	}
	std::string inputFilename;
	std::string outputFilename;
	if (genericOptions.exists("input")) {
		inputFilename = genericOptions.getPath("input");
	}
	if (genericOptions.exists("output")) {
		outputFilename = genericOptions.getPath("output");
	} else {
		outputFilename = inputFilename + interpreter.format().getExtension().toStdString();
	}

	QFileInfo fileInfo = QFileInfo(QString::fromStdString(inputFilename));
	if (!fileInfo.exists()) {
		_GT_SYSTEM_ERR(boost::format("Input file <%1%> not found.") % inputFilename);
		return (-1);
	}

	// Creates provider for the specified algorithm and fills the arguments.
	QGTManager manager;
	manager.addItem(QGTManager::nextSerial(), fileInfo);
	Provider *provider = manager.provider(1, filter);
	foreach (const Interpreter::Param &param, interpreter.computing()) {
		std::string option = param.getOption().toStdString();
		if (!programOptions.exists(option)) continue;
		if (param.type() == QString("Integer")) {
			provider->set(param.name().toStdString(), Parameter::Integer(programOptions.value<Parameter::Integer::DataType>(option)));
		}
		if (param.type() == QString("Real")) {
			provider->set(param.name().toStdString(), Parameter::Real(programOptions.value<Parameter::Real::DataType>(option)));
		}
		if (param.type() == QString("Switch")) {
			provider->set(param.name().toStdString(), Parameter::Switch(programOptions.value<Parameter::Switch::DataType>(option)));
		}
		if (param.type() == QString("Option")) {
			provider->set(param.name().toStdString(), Parameter::Option(programOptions.value<Parameter::Option::DataType>(option)));
		}
		if (param.type() == QString("Vertices")) {
			provider->set(param.name().toStdString(), Parameter::Vertices(programOptions.value<Parameter::Vertices::DataType>(option)));
		}
		if (param.type() == QString("Edges")) {
			provider->set(param.name().toStdString(), Parameter::Edges(programOptions.value<Parameter::Edges::DataType>(option)));
		}
		if (param.type() == QString("Faces")) {
			provider->set(param.name().toStdString(), Parameter::Faces(programOptions.value<Parameter::Faces::DataType>(option)));
		}
	}

	// Starts initialization and computing.
	if (!provider->initialize()) return (-1);
	if (!provider->compute()) return (-1);
	
	// Writes result to output file.
	provider->writeFile(outputFilename);

	return (0);
}