static bool ReadConfig()
{
    string iniPath;
    if (!UIGetIniPath(iniPath))
        return false;

    if (!ReadStringsFromFile(iniPath, gStrings, true))
        return false;

    // See if we have a string override file, if so process it
    char* overrideEnv = getenv("MOZ_CRASHREPORTER_STRINGS_OVERRIDE");
    if (overrideEnv && *overrideEnv && UIFileExists(overrideEnv))
        ReadStringsFromFile(overrideEnv, gStrings, true);

    return true;
}
void ProcessWebInterfaceModels() {
	string Filename(GetParameter("web interface model directory"));
	Filename.append("ModelList.txt");
	vector<string> Lines = ReadStringsFromFile(Filename,false);

	//this database will hold a combination of all of the model compounds and reactions
	Data* CompleteDatabase = new Data(0);

	//the following structures will hold the data for the various models as they are read in
	vector<Data*> Models;
	vector< map<string, Identity*, std::less<string> > > ModelGenes;
	map<string, vector<string>, std::less<string> > ReactionGenes;
	map<string, vector<string>, std::less<string> > ReactionModels;
	map<string, vector<string>, std::less<string> > CompoundModels;
	//Reading in the models and storing the data in the above structures
	for (int i=1; i < int(Lines.size()); i++) {
		cout << i << endl;
		//Parsing the model list line
		vector<string>* Strings = StringToStrings(Lines[i], "\t");
		
		if (Strings->size() >= 4) {
			Filename.assign(GetParameter("web interface model directory"));
			Filename.append((*Strings)[3]);
		}

		//Loading each model from the combined model file
		if (FileExists(Filename)) {
			map<string, Identity*, std::less<string> > CurrentGeneData;
			ModelGenes.push_back(CurrentGeneData);
			Data* NewData = new Data(0);
			Models.push_back(NewData);
			NewData->AddData("NAME",(*Strings)[0].data(),STRING);
			NewData->AddData("AUTHORS",(*Strings)[1].data(),STRING);
			NewData->AddData("ORGANISMS NAME",(*Strings)[2].data(),STRING);
			NewData->AddData("FILENAME",(*Strings)[3].data(),STRING);
			NewData->LoadSystem(Filename);
			//Loading additional data on compounds and reactions from the centralized database
			int TotalTransported = 0;
			for (int j=0; j < NewData->FNumSpecies(); j++) {
				if (NewData->GetSpecies(j)->FExtracellular()) {
					TotalTransported++;
				}
				NewData->GetSpecies(j)->LoadSpecies(NewData->GetSpecies(j)->GetData("DATABASE",STRING));
				CompoundModels[NewData->GetSpecies(j)->Query("CGI_ID")].push_back((*Strings)[0]);
				if (CompleteDatabase->FindSpecies("DATABASE;CGI_ID",NewData->GetSpecies(j)->Query("CGI_ID").data()) == NULL && CompleteDatabase->FindSpecies("DATABASE;CGI_ID",NewData->GetSpecies(j)->GetData("DATABASE",STRING).data()) == NULL) {
					CompleteDatabase->AddSpecies(NewData->GetSpecies(j));
				}
			}
			//Note that the reaction equation that was read in was cleared in favor of the database equation... this could lead to problems
			int TotalReactionsWithGenes = 0;
			for (int j=0; j < NewData->FNumReactions(); j++) {
				NewData->GetReaction(j)->LoadReaction(NewData->GetReaction(j)->GetData("DATABASE",STRING));
				ReactionModels[NewData->GetReaction(j)->Query("CGI_ID")].push_back((*Strings)[0]);
				//Capturing the gene data for entry into the gene hash
				vector<string> GeneData = NewData->GetReaction(j)->GetAllData("ASSOCIATED PEG",DATABASE_LINK);
				if (GeneData.size() > 0) {
					TotalReactionsWithGenes++;
				}
				for (int k=0; k < int(GeneData.size()); k++) {
					//Adding the gene to the reaction gene hash
					string GeneName((*Strings)[2]);
					GeneName.append(":");
					GeneName.append(GeneData[k]);
					ReactionGenes[NewData->GetReaction(j)->Query("CGI_ID")].push_back(GeneName);
					//Finding the gene and creating a new gene if the gene does not currently exist
					Identity* CurrentGene = ModelGenes[ModelGenes.size()-1][GeneData[k]];
					if (CurrentGene == NULL) {
						CurrentGene = new Identity;
						ModelGenes[ModelGenes.size()-1][GeneData[k]] = CurrentGene;
					}
					//Adding the reaction data to the gene data
					CurrentGene->AddData("REACTIONS",NewData->GetReaction(j)->Query("CGI_ID").data(),STRING);
					vector<string> EnzymeData = NewData->GetReaction(j)->GetAllData("ENZYME",DATABASE_LINK);
					for (int l=0; l < int(EnzymeData.size()); l++) {
						CurrentGene->AddData("ENZYME",EnzymeData[l].data(),STRING);
					}
					EnzymeData = NewData->GetReaction(j)->GetAllData("PATHWAYS",STRING);
					for (int l=0; l < int(EnzymeData.size()); l++) {
						CurrentGene->AddData("PATHWAY",EnzymeData[l].data(),STRING);
					}

				}
				//Adding all unique reactions to the complete database
				if (CompleteDatabase->FindReaction("DATABASE;CGI_ID",NewData->GetReaction(j)->Query("CGI_ID").data()) == NULL && CompleteDatabase->FindReaction("DATABASE;CGI_ID",NewData->GetReaction(j)->GetData("DATABASE",STRING).data()) == NULL) {
					CompleteDatabase->AddReaction(NewData->GetReaction(j));
				}
			}
			//Searching the model for dead compounds and reactions
			NewData->FindDeadEnds();
			NewData->AddData("TRANSPORTED COMPOUNDS",double(TotalTransported));
			NewData->AddData("REACTION WITH GENES",double(TotalReactionsWithGenes));
		}

		delete Strings;
	}

	//Printing the combined compounds table
	Filename.assign(GetParameter("web interface model directory"));
	Filename.append("AllCompoundsTable.txt");
	ofstream CompleteOutput;
	if (!OpenOutput(CompleteOutput,Filename)) {
		return;
	}
	CompleteOutput << "ID	SHORTNAME	NAMES	STATUS IN MODEL	MODELS	FORMULA	MASS	CHARGE(pH7)	DELTA G(kcal/mol)	PATHWAY	DATABASE LINKS	REACTIONS" << endl;
	for (int i=0; i < CompleteDatabase->FNumSpecies(); i++) {
		CompleteOutput << CompleteDatabase->GetSpecies(i)->Query("CGI_ID") << "\t";
		CompleteOutput << CompleteDatabase->GetSpecies(i)->Query("SHORTNAME") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetSpecies(i)->GetAllDataString("NAME",STRING).data(),"\t",", ") << "\t";
		CompleteOutput << "Not in model" << "\t";
		vector<string> ModelList = CompoundModels[CompleteDatabase->GetSpecies(i)->Query("CGI_ID")];
		for (int j=0; j < int(ModelList.size()-1); j++) {
			CompleteOutput << ModelList[j] << ", ";
		}
		CompleteOutput << ModelList[ModelList.size()-1] << "\t";		CompleteOutput << CompleteDatabase->GetSpecies(i)->FFormula() << "\t";
		CompleteOutput << CompleteDatabase->GetSpecies(i)->FMW() << "\t";
		CompleteOutput << CompleteDatabase->GetSpecies(i)->FCharge() << "\t";
		CompleteOutput << CompleteDatabase->GetSpecies(i)->FEstDeltaG() << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetSpecies(i)->GetAllDataString("PATHWAYS",STRING).data(),"\t",", ") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetSpecies(i)->GetCombinedData(DATABASE_LINK).data(),"\t",", ") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetSpecies(i)->Query("REACTIONS").data(),"\t",", ") << endl;
	}
	CompleteOutput.close();

	//Printing the combined reactions table
	Filename.assign(GetParameter("web interface model directory"));
	Filename.append("AllReactionsTable.txt");
	if (!OpenOutput(CompleteOutput,Filename)) {
		return;
	}
	CompleteOutput << "ID	SHORTNAME	NAMES	STATUS IN MODEL	MODELS	DEFINITION	EQUATION	EC NUMBER	ASSIGNED FUNCTIONS	ASSIGNED GENES	DELTA G(kcal/mol)	PATHWAY	PREVIOUS REACTIONS	NEXT REACTIONS" << endl;
	for (int i=0; i < CompleteDatabase->FNumReactions(); i++) {
		CompleteOutput << CompleteDatabase->GetReaction(i)->Query("CGI_ID") << "\t";
		CompleteOutput << CompleteDatabase->GetReaction(i)->Query("SHORTNAME") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetReaction(i)->GetAllDataString("NAME",STRING).data(),"\t",", ") << "\t";
		CompleteOutput << "Not in model" << "\t";
		vector<string> ModelList = ReactionModels[CompleteDatabase->GetReaction(i)->Query("CGI_ID")];
		for (int j=0; j < int(ModelList.size()-1); j++) {
			CompleteOutput << ModelList[j] << ", ";
		}
		CompleteOutput << ModelList[ModelList.size()-1] << "\t";
		CompleteOutput << CompleteDatabase->GetReaction(i)->Query("DEFINITION") << "\t";
		CompleteOutput << CompleteDatabase->GetReaction(i)->CreateReactionEquation("CGI_ID") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetReaction(i)->GetAllDataString("ENZYME",DATABASE_LINK).data(),"\t",", ") << "\t";
		CompleteOutput << "No data" << "\t";
		vector<string> AssignedGenes = ReactionGenes[CompleteDatabase->GetReaction(i)->Query("CGI_ID")];
		if (AssignedGenes.size() >= 1) {
			for (int j=0; j < int(AssignedGenes.size()-1); j++) {
				CompleteOutput << AssignedGenes[j] << ", ";
			}
			CompleteOutput << AssignedGenes[AssignedGenes.size()-1] << "\t";
		} else {
			CompleteOutput << "None" << "\t";
		}
		CompleteOutput << CompleteDatabase->GetReaction(i)->FEstDeltaG() << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetReaction(i)->Query("PATHWAYS").data(),"\t",", ") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetReaction(i)->Query("PREVIOUS").data(),"\t",", ") << "\t";
		CompleteOutput << StringReplace(CompleteDatabase->GetReaction(i)->Query("NEXT").data(),"\t",", ") << endl;
	}
	CompleteOutput.close();

	//Printing the compounds, reactions, and genes tables for each model and the model table
	Filename.assign(GetParameter("web interface model directory"));
	Filename.append("ModelTable.txt");
	if (!OpenOutput(CompleteOutput,Filename)) {
		return;
	}
	CompleteOutput << "ID	MODEL AUTHORS	ORGANISMS NAME	TOTAL COMPOUNDS	TRANSPORTED COMPOUNDS	DEAD COMPOUNDS	TOTAL REACTIONS	REACTIONS WITH GENES	DEAD REACTIONS	NUMBER OF GENES" << endl;
	for (int j=0; j < int(Models.size()); j++) {
		//Printing the model data into the model table
		CompleteOutput << Models[j]->GetData("NAME",STRING) << "\t";
		CompleteOutput << Models[j]->GetData("AUTHORS",STRING) << "\t";
		CompleteOutput << Models[j]->GetData("ORGANISMS NAME",STRING) << "\t";
		CompleteOutput << Models[j]->FNumSpecies() << "\t";
		CompleteOutput << Models[j]->GetDoubleData("TRANSPORTED COMPOUNDS") << "\t";
		CompleteOutput << Models[j]->GetDoubleData("DEAD COMPOUNDS") << "\t";
		CompleteOutput << Models[j]->FNumReactions() << "\t";
		CompleteOutput << Models[j]->GetDoubleData("REACTION WITH GENES") << "\t";
		CompleteOutput << Models[j]->GetDoubleData("DEAD REACTIONS") << "\t";
		CompleteOutput << ModelGenes[j].size() << endl;
		
		ofstream ModelOutput;
		Filename.assign(GetParameter("web interface model directory"));
		Filename.append(Models[j]->GetData("NAME",STRING));
		Filename.append("CompoundsTable.txt");
		if (!OpenOutput(ModelOutput,Filename)) {
			return;
		}
		ModelOutput << "ID	SHORTNAME	NAMES	STATUS IN MODEL	MODELS	FORMULA	MASS	CHARGE(pH7)	DELTA G(kcal/mol)	PATHWAY	DATABASE LINKS	REACTIONS" << endl;
		for (int i=0; i < Models[j]->FNumSpecies(); i++) {
			ModelOutput << Models[j]->GetSpecies(i)->Query("CGI_ID") << "\t";
			ModelOutput << Models[j]->GetSpecies(i)->Query("SHORTNAME") << "\t";
			ModelOutput << StringReplace(Models[j]->GetSpecies(i)->GetAllDataString("NAME",STRING).data(),"\t",", ") << "\t";
			ModelOutput << Models[j]->GetSpecies(i)->GetData("CLASS",STRING) << "\t";
			vector<string> ModelList = ReactionModels[Models[j]->GetSpecies(i)->Query("CGI_ID")];
			if (ModelList.size() > 0) {
				for (int k=0; k < int(ModelList.size()-1); k++) {
					ModelOutput << ModelList[k] << ", ";
				}
				ModelOutput << ModelList[ModelList.size()-1] << "\t";
			} else {
				ModelOutput << "No data" << "\t";
			}
			ModelOutput << Models[j]->GetSpecies(i)->FFormula() << "\t";
			ModelOutput << Models[j]->GetSpecies(i)->FMW() << "\t";
			ModelOutput << Models[j]->GetSpecies(i)->FCharge() << "\t";
			ModelOutput << Models[j]->GetSpecies(i)->FEstDeltaG() << "\t";
			ModelOutput << StringReplace(Models[j]->GetSpecies(i)->GetAllDataString("PATHWAYS",STRING).data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(Models[j]->GetSpecies(i)->GetCombinedData(DATABASE_LINK).data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(Models[j]->GetSpecies(i)->Query("REACTIONS").data(),"\t",", ") << endl;
		}
		ModelOutput.close();

		Filename.assign(GetParameter("web interface model directory"));
		Filename.append(Models[j]->GetData("NAME",STRING));
		Filename.append("ReactionsTable.txt");
		if (!OpenOutput(ModelOutput,Filename)) {
			return;
		}
		ModelOutput << "ID	SHORTNAME	NAMES	STATUS IN MODEL	MODELS	DEFINITION	EQUATION	EC NUMBER	ASSIGNED FUNCTIONS	ASSIGNED GENES	DELTA G(kcal/mol)	PATHWAY	PREVIOUS REACTIONS	NEXT REACTIONS" << endl;
		for (int i=0; i < Models[j]->FNumReactions(); i++) {
			ModelOutput << Models[j]->GetReaction(i)->Query("CGI_ID") << "\t";
			ModelOutput << Models[j]->GetReaction(i)->Query("SHORTNAME") << "\t";
			ModelOutput << StringReplace(Models[j]->GetReaction(i)->GetAllDataString("NAME",STRING).data(),"\t",", ") << "\t";
			ModelOutput << Models[j]->GetReaction(i)->GetData("CLASS",STRING) << "\t";
			vector<string> ModelList = ReactionModels[Models[j]->GetReaction(i)->Query("CGI_ID")];
			if (ModelList.size() > 0) {
				for (int k=0; k < int(ModelList.size()-1); k++) {
					ModelOutput << ModelList[k] << ", ";
				}
				ModelOutput << ModelList[ModelList.size()-1] << "\t";
			}else {
				ModelOutput << "No data" << "\t";
			}
			ModelOutput << Models[j]->GetReaction(i)->Query("DEFINITION") << "\t";
			ModelOutput << Models[j]->GetReaction(i)->CreateReactionEquation("CGI_ID") << "\t";
			ModelOutput << StringReplace(Models[j]->GetReaction(i)->GetAllDataString("ENZYME",DATABASE_LINK).data(),"\t",", ") << "\t";
			ModelOutput << "No data" << "\t";
			vector<string> AssignedGenes = ReactionGenes[Models[j]->GetReaction(i)->Query("CGI_ID")];
			if (AssignedGenes.size() >= 1) {
				bool First = true;
				for (int k=0; k < int(AssignedGenes.size()); k++) {
					if (AssignedGenes[k].length() > Models[j]->GetData("ORGANISMS NAME",STRING).length() && AssignedGenes[k].substr(0,Models[j]->GetData("ORGANISMS NAME",STRING).length()).compare(Models[j]->GetData("ORGANISMS NAME",STRING)) == 0) {
						if (!First) {
							ModelOutput << ", ";
						}
						First = false;
						ModelOutput << AssignedGenes[k].substr(Models[j]->GetData("ORGANISMS NAME",STRING).length()+1,AssignedGenes[k].length()-Models[j]->GetData("ORGANISMS NAME",STRING).length()-1);
					}
				}
				ModelOutput << "\t";
			} else {
				ModelOutput << "None" << "\t";
			}
			ModelOutput << Models[j]->GetReaction(i)->FEstDeltaG() << "\t";
			ModelOutput << StringReplace(Models[j]->GetReaction(i)->Query("PATHWAYS").data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(Models[j]->GetReaction(i)->Query("PREVIOUS").data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(Models[j]->GetReaction(i)->Query("NEXT").data(),"\t",", ") << endl;
		}
		ModelOutput.close();

		Filename.assign(GetParameter("web interface model directory"));
		Filename.append(Models[j]->GetData("NAME",STRING));
		Filename.append("GenesTable.txt");
		if (!OpenOutput(ModelOutput,Filename)) {
			return;
		}
		ModelOutput << "ID	SHORTNAME	NAMES	ASSIGNED FUNCTIONS	STATUS IN ORGANISM	PARALOGS	COORDINATES	DIRECTIONALITY	EC NUMBER	PATHWAY	REACTIONS" << endl;
		for (map<string, Identity*, std::less<string> >::iterator MapIT = ModelGenes[j].begin(); MapIT != ModelGenes[j].end(); MapIT++) {
			ModelOutput << MapIT->first << "\t";
			ModelOutput << MapIT->first << "\t";
			ModelOutput << MapIT->first << "\t";
			ModelOutput << "No data" << "\t";
			ModelOutput << "No data" << "\t";
			ModelOutput << "No data" << "\t";
			ModelOutput << "No data" << "\t";
			ModelOutput << "No data" << "\t";
			ModelOutput << StringReplace(MapIT->second->GetAllDataString("ENZYME",STRING).data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(MapIT->second->GetAllDataString("PATHWAY",STRING).data(),"\t",", ") << "\t";
			ModelOutput << StringReplace(MapIT->second->GetAllDataString("REACTIONS",STRING).data(),"\t",", ") << endl;
		}
		ModelOutput.close();
	}
	CompleteOutput.close();
}