diff --git a/Analysis.cpp b/Analysis.cpp
index 20030eed6f11cb6aed7e6af487ae9ee018708524..06345af459f8410b48846367f95169aeb75706ab 100644
--- a/Analysis.cpp
+++ b/Analysis.cpp
@@ -2,15 +2,14 @@
 
 #include "Analysis.h"
 #include "geometry/Room.h"
-#include "general/xmlParser.h"
-
-//#include "VoronoiDiagramGenerator.h"
-//#include "VoronoiPolygons.h"
+#include "tinyxml/tinyxml.h"
 
 #include "VoronoiDiagram.h"
 
 #include <iostream>
 #include <fstream>
+#include <direct.h>
+
 using namespace std;
 
 /************************************************
@@ -19,66 +18,65 @@ using namespace std;
 
 Analysis::Analysis() {
 
-  _building = NULL;
-  _iod = new IODispatcher();
-  _numFrames = 10;
-
-  _tIn = NULL;
-  _tOut = NULL;
-  _lengthMeasurementarea = 200;  // the length of the measurement area
-  _maxNumofPed =0;  //the maximum index of the pedestrian in the trajectory data
-  _deltaF=5;											// half of the time interval that used to calculate instantaneous velocity of ped i.
-  // here v_i = (X(t+deltaF) - X(t+deltaF))/(2*deltaF).   X is location.
-  _xCor = NULL;
-  _yCor = NULL;
-  _firstFrame = NULL;   // Record the first frame of each pedestrian
-  _lastFrame = NULL;	// Record the last frame of each pedestrian
-  _deltaT =160;   // the time interval to calculate the classic flow
-  _lineStartX = 0;  			//the coordinate of the line used to calculate the flow and velocity
-  _lineStartY =10;
-  _lineEndX = 0;
-  _lineEndY =100;
-  _flowVelocity = false; 						// Method A (Zhang2011a)
-  _fundamentalTinTout = false; 			// Method B (Zhang2011a)
-  _classicMethod = false; 					// Method C //calculate and save results of classic in separate file
-  _voronoiMethod = false;  					// Method D--Voronoi method
-  _cutByCircle = false;  //Adjust whether cut each original voronoi cell by a circle
-  _getProfile = false;   // Whether make field analysis or not
-  _outputGraph = false;   // Whether output the data for plot the fundamental diagram each frame
-  _calcIndividualFD = false; //Adjust whether analyze the individual density and velocity of each pedestrian in stationary state (ALWAYS VORONOI-BASED)
-  _vComponent = 'B'; // to mark whether x, y or x and y coordinate are used when calculating the velocity
-  //AccumPedsPassLine = NULL; // the accumulative pedestrians pass a line with time
-  //AccumVPassLine = NULL;  // the accumulative instantaneous velocity of the pedestrians pass a line
-  _fps = 16;												// Frame rate of data
-  _fClassicRhoV = NULL;
-  _fVoronoiRhoV = NULL;
-  _individualFD = NULL;
-  _fN_t = NULL;
-
-  _scaleX = 10;   // the size of the grid
-  _scaleY = 10;
-  _lowVertexX = 0;// LOWest vertex of the geometry (x coordinate)
-  _lowVertexY = 0; //  LOWest vertex of the geometry (y coordinate)
-  _highVertexX = 10; // Highest vertex of the geometry
-  _highVertexY = 10;
-
+	_building = NULL;
+	_iod = new IODispatcher();
+	_numFrames = 10;
+
+	_tIn = NULL;
+	_tOut = NULL;
+	_lengthMeasurementarea = 200;  // the length of the measurement area
+	_maxNumofPed =0;  //the maximum index of the pedestrian in the trajectory data
+	_deltaF=5;											// half of the time interval that used to calculate instantaneous velocity of ped i.
+	// here v_i = (X(t+deltaF) - X(t+deltaF))/(2*deltaF).   X is location.
+	_xCor = NULL;
+	_yCor = NULL;
+	_firstFrame = NULL;   // Record the first frame of each pedestrian
+	_lastFrame = NULL;	// Record the last frame of each pedestrian
+	_deltaT =160;   // the time interval to calculate the classic flow
+	_lineStartX = 0;  			//the coordinate of the line used to calculate the flow and velocity
+	_lineStartY =10;
+	_lineEndX = 0;
+	_lineEndY =100;
+	_flowVelocity = false; 						// Method A (Zhang2011a)
+	_fundamentalTinTout = false; 			// Method B (Zhang2011a)
+	_classicMethod = false; 					// Method C //calculate and save results of classic in separate file
+	_voronoiMethod = false;  					// Method D--Voronoi method
+	_cutByCircle = false;  //Adjust whether cut each original voronoi cell by a circle
+	_getProfile = false;   // Whether make field analysis or not
+	_outputGraph = false;   // Whether output the data for plot the fundamental diagram each frame
+	_calcIndividualFD = false; //Adjust whether analyze the individual density and velocity of each pedestrian in stationary state (ALWAYS VORONOI-BASED)
+	_vComponent = 'B'; // to mark whether x, y or x and y coordinate are used when calculating the velocity
+	//AccumPedsPassLine = NULL; // the accumulative pedestrians pass a line with time
+	//AccumVPassLine = NULL;  // the accumulative instantaneous velocity of the pedestrians pass a line
+	_fps = 16;												// Frame rate of data
+	_fClassicRhoV = NULL;
+	_fVoronoiRhoV = NULL;
+	_individualFD = NULL;
+	_fN_t = NULL;
+
+	_scaleX = 10;   // the size of the grid
+	_scaleY = 10;
+	_lowVertexX = 0;// LOWest vertex of the geometry (x coordinate)
+	_lowVertexY = 0; //  LOWest vertex of the geometry (y coordinate)
+	_highVertexX = 10; // Highest vertex of the geometry
+	_highVertexY = 10;
 }
 
 Analysis::~Analysis() {
-  delete _building;
-  delete _iod;
-  delete  _firstFrame;
-  delete  _lastFrame;
-  delete  _tIn;
-  delete  _tOut;
-
-  for (int i=0; i<_maxNumofPed; i++)
-    {
-      delete _xCor[i];
-      delete _yCor[i];
-    }
-  delete []_xCor;
-  delete []_yCor;
+	delete _building;
+	delete _iod;
+	delete  _firstFrame;
+	delete  _lastFrame;
+	delete  _tIn;
+	delete  _tOut;
+
+	for (int i=0; i<_maxNumofPed; i++)
+	{
+		delete _xCor[i];
+		delete _yCor[i];
+	}
+	delete []_xCor;
+	delete []_yCor;
 }
 
 /************************************************
@@ -87,7 +85,7 @@ Analysis::~Analysis() {
 
 
 Building * Analysis::GetBuilding() const {
-  return _building;
+	return _building;
 }
 
 /************************************************
@@ -98,470 +96,500 @@ Building * Analysis::GetBuilding() const {
  * und setzt die entsprechenden Parameter in der Simulation
  * */
 void Analysis::InitArgs(ArgumentParser* args) {
-  char tmp[CLENGTH];
-  string s = "Parameter:\n";
-
-  switch (args->GetLog()) {
-  case 0:
-    // no log file
-    //Log = new OutputHandler();
-    break;
-  case 1:
-    if(Log) delete Log;
-    Log = new STDIOHandler();
-    break;
-  case 2:
-    {
-      char name[CLENGTH]="";
-      sprintf(name,"%s.P0.dat",args->GetErrorLogFile().c_str());
-      if(Log) delete Log;
-      Log = new FileHandler(name);
-    }
-    break;
-  default:
-    printf("Wrong option for Logfile!\n\n");
-    exit(0);
-  }
+	char tmp[CLENGTH];
+	string s = "Parameter:\n";
+
+	switch (args->GetLog()) {
+	case 0:
+		// no log file
+		//Log = new OutputHandler();
+		break;
+	case 1:
+		if(Log) delete Log;
+		Log = new STDIOHandler();
+		break;
+	case 2:
+	{
+		char name[CLENGTH]="";
+		sprintf(name,"%s.P0.dat",args->GetErrorLogFile().c_str());
+		if(Log) delete Log;
+		Log = new FileHandler(name);
+	}
+	break;
+	default:
+		printf("Wrong option for Logfile!\n\n");
+		exit(0);
+	}
 
-  Log->Write("INFO: \tOptionen an Simulation geben\n");
+	Log->Write("INFO: \tOptionen an Simulation geben\n");
 
-  _measureZone = args->GetMeasureArea();
+	_measureZone = args->GetMeasureArea();
 
 
-  _flowVelocity = args->GetIsMethodA();
-  _fundamentalTinTout = args->GetIsMethodB();
-  _classicMethod = args ->GetIsMethodC();
-  if(_fundamentalTinTout)
-    {
-      _classicMethod = true;
-    }
-  _voronoiMethod = args ->GetIsMethodD();
-  _lengthMeasurementarea = args->GetLengthMeasurementArea();
-  _deltaF = args->GetDelatT_Vins();
-  _deltaT = args->GetTimeIntervalA();
-  _lineStartX = args->GetLineStartX();
-  _lineStartY = args->GetLineStartY();
-  _lineEndX = args->GetLineEndX();
-  _lineEndY = args->GetLineEndY();
-  _cutByCircle = args->GetIsCutByCircle();
-  _getProfile = args->GetIsGetProfile();
-  _outputGraph = args->GetIsOutputGraph();
-  _calcIndividualFD = args->GetIsIndividualFD();
-  _vComponent = args->GetVComponent();
-  _scaleX = args->GetScaleX();
-  _scaleY = args->GetScaleY();
-
-  // IMPORTANT: do not change the order in the following..
-  sprintf(tmp, "\tGeometrie: [%s]\n", args->GetGeometryFilename().c_str());
-  s.append(tmp);
-  Log->Write("INFO: \t" + s);
-  _geoPoly = ReadGeometry(args->GetGeometryFilename());
-  //pBuilding->WriteToErrorLog();
-
-  _trajectoryName = args->GetTrajectoryName();
-  _trajectoryFile = args->GetTrajectoriesFile();
-  std::cout<<_trajectoryFile.c_str();
-  Log->Write(string("INFO: \t") + _trajectoryFile);
-  ReadTrajetories(_trajectoryFile);
-
-  if(_classicMethod)
-    {
-#ifdef WIN32
-      string results_C=  "Output\\Fundamental_Diagram\\Classical_Voronoi\\rho_v_Classic_"+_trajectoryName+".dat";
-#else
-      string results_C=  "Output/Fundamental_Diagram/Classical_Voronoi/rho_v_Classic_"+_trajectoryName+".dat";
-#endif
-                         
-      if((_fClassicRhoV=fopen(results_C.c_str(),"w"))==NULL)
+	_flowVelocity = args->GetIsMethodA();
+	_fundamentalTinTout = args->GetIsMethodB();
+	_classicMethod = args ->GetIsMethodC();
+	if(_fundamentalTinTout)
 	{
-	  Log->Write("cannot open file %s to write classical density and velocity\n", results_C.c_str());
-	  exit(0);
+		_classicMethod = true;
 	}
-      fprintf(_fClassicRhoV,"#Frame \tclassical density(m^(-2))\t	classical velocity(m/s)\n");
-    }
-  if(_voronoiMethod)
-    {
-#ifdef WIN32
-      string results_V=  "Output\\Fundamental_Diagram\\Classical_Voronoi\\rho_v_Voronoi_"+_trajectoryName+".dat";
-      //string results_V=  "rho_v_Voronoi_"+_trajectoryName+".dat";
-#else
-      string results_V=  "Output/Fundamental_Diagram/Classical_Voronoi/rho_v_Voronoi_"+_trajectoryName+".dat";
-#endif
-      if((_fVoronoiRhoV=fopen(results_V.c_str(),"w"))==NULL)
+	_voronoiMethod = args ->GetIsMethodD();
+	_lengthMeasurementarea = args->GetLengthMeasurementArea();
+	_deltaF = args->GetDelatT_Vins();
+	_deltaT = args->GetTimeIntervalA();
+	_lineStartX = args->GetLineStartX();
+	_lineStartY = args->GetLineStartY();
+	_lineEndX = args->GetLineEndX();
+	_lineEndY = args->GetLineEndY();
+	_cutByCircle = args->GetIsCutByCircle();
+	_getProfile = args->GetIsGetProfile();
+	_outputGraph = args->GetIsOutputGraph();
+	_calcIndividualFD = args->GetIsIndividualFD();
+	_vComponent = args->GetVComponent();
+	_scaleX = args->GetScaleX();
+	_scaleY = args->GetScaleY();
+
+	sprintf(tmp, "\tGeometrie: [%s]\n", args->GetGeometryFilename().c_str());
+	s.append(tmp);
+	Log->Write("INFO: \t" + s);
+	_geoPoly = ReadGeometry(args->GetGeometryFilename());
+	//pBuilding->WriteToErrorLog();
+
+	_trajectoryName = args->GetTrajectoriesFilename();
+	_trajectoriesLocation= args->GetTrajectoriesLocation();
+
+
+	ReadTrajetories(_trajectoriesLocation+"/"+_trajectoryName);
+
+	if(_classicMethod)
 	{
-	  Log->Write("cannot open the file to write Voronoi density and velocity\n");
-	  exit(0);
+		string results_C= "Output/Fundamental_Diagram/Classical_Voronoi/rho_v_Classic_"+_trajectoryName+".dat";
+		if((_fClassicRhoV=CreateFile(results_C))==NULL)
+		{
+			Log->Write("cannot open file %s to write classical density and velocity\n", results_C.c_str());
+			exit(EXIT_FAILURE);
+		}
+		fprintf(_fClassicRhoV,"#Frame \tclassical density(m^(-2))\t	classical velocity(m/s)\n");
 	}
-      fprintf(_fVoronoiRhoV,"#Frame \t Voronoi density(m^(-2))\t	Voronoi velocity(m/s)\n");
-    }
-  if(_calcIndividualFD)
-    {
-#ifdef WIN32
-      string Individualfundment="Output\\Fundamental_Diagram\\Individual_FD\\IndividualFD"+_trajectoryName+".dat";
-#else
-      string Individualfundment="Output/Fundamental_Diagram/Individual_FD/IndividualFD"+_trajectoryName+".dat";
-#endif
-      if((_individualFD=fopen(Individualfundment.c_str(),"w"))==NULL)
+	if(_voronoiMethod)
 	{
-	  Log->Write("cannot open the file individual\n");
-	  exit(0);
+		string results_V=  "Output/Fundamental_Diagram/Classical_Voronoi/rho_v_Voronoi_"+_trajectoryName+".dat";
+		if((_fVoronoiRhoV=CreateFile(results_V))==NULL)
+		{
+			Log->Write("cannot open the file to write Voronoi density and velocity\n");
+			exit(EXIT_FAILURE);
+		}
+		fprintf(_fVoronoiRhoV,"#Frame \t Voronoi density(m^(-2))\t	Voronoi velocity(m/s)\n");
 	}
-      fprintf(_individualFD,"#Individual density(m^(-2))\t	Individual velocity(m/s)\n");
-    }
-  if(_flowVelocity)
-    {
 
-#ifdef WIN32
-      string N_t= "Output\\Fundamental_Diagram\\FlowVelocity\\Flow_NT_"+_trajectoryName+"_Out.dat";
-#else
-      string N_t= "Output/Fundamental_Diagram/FlowVelocity/Flow_NT_"+_trajectoryName+"_Out.dat";
-#endif
-      if((_fN_t=fopen(N_t.c_str(),"w"))==NULL)
+	if(_calcIndividualFD)
 	{
-	  Log->Write("cannot open the file %s  t\n", N_t.c_str() );
-	  exit(0);
+		string Individualfundment="Output/Fundamental_Diagram/Individual_FD/IndividualFD"+_trajectoryName+".dat";
+		if((_individualFD=CreateFile(Individualfundment))==NULL)
+		{
+			Log->Write("cannot open the file individual\n");
+			exit(EXIT_FAILURE);
+		}
+		fprintf(_individualFD,"#Individual density(m^(-2))\t	Individual velocity(m/s)\n");
+	}
+
+	if(_flowVelocity)
+	{
+
+		string N_t= "Output/Fundamental_Diagram/FlowVelocity/Flow_NT_"+_trajectoryName+"_Out.dat";
+		if((_fN_t=CreateFile(N_t))==NULL)
+		{
+			Log->Write("cannot open the file %s  t\n", N_t.c_str() );
+			exit(EXIT_FAILURE);
+		}
+		else
+			cout << "can open \n";
+
+		fprintf(_fN_t,"#Frame\t	Cumulative pedestrians\n");
 	}
-      else 
-	cout << "can open \n";
-	
-      fprintf(_fN_t,"#Frame\t	Cumulative pedestrians\n");
-    }
 }
 
 polygon_2d Analysis::ReadGeometry(const string& geometryFile){
 
-  _building = new Building();
-  _building->LoadBuilding(geometryFile);
-  double geo_minX  = FLT_MAX;
-  double geo_minY  = FLT_MAX;
-  double geo_maxX  = -FLT_MAX;
-  double geo_maxY  = -FLT_MAX;
-  polygon_2d geoPoly;
-  // create the polygons
-  _building->InitGeometry();
-  vector<Obstacle*> GeoObst;
-  for(int i=0;i<_building->GetNumberOfRooms();i++){
-    Room* room=_building->GetRoom(i);
-
-    for( int j=0;j<room->GetNumberOfSubRooms();j++){
-      SubRoom* subroom = room->GetSubRoom(i);
-      const vector<Point>& temp_GeoPoly = subroom->GetPolygon();
-      for (unsigned int j = 0; j< temp_GeoPoly.size(); j++){
-	append(geoPoly, make<point_2d>(temp_GeoPoly[j]._x, temp_GeoPoly[j]._y));
-	geo_minX = (temp_GeoPoly[j]._x<=geo_minX) ? temp_GeoPoly[j]._x : geo_minX;
-	geo_minY = (temp_GeoPoly[j]._y<=geo_minY) ? temp_GeoPoly[j]._y : geo_minY;
-	geo_maxX = (temp_GeoPoly[j]._x>=geo_maxX) ? temp_GeoPoly[j]._x : geo_maxX;
-	geo_maxY = (temp_GeoPoly[j]._y>=geo_maxY) ? temp_GeoPoly[j]._y : geo_maxY;
-
-      }
-      correct(geoPoly);
-      //std::cout << "poly without hole: " << boost::geometry::dsv(geoPoly) << std::endl;
-      GeoObst = subroom->GetAllObstacles();
-    }
-    for (unsigned int k = 0; k < GeoObst.size(); k++) {
-      //std::cout<< GeoObst.size()<<std::endl;
-      //std::cout<< pBuilding->GetAnzRooms() <<'\t'<<room->GetAnzSubRooms()<<std::endl;
-      const vector<Point>& temp_obst = GeoObst[k]->GetPolygon();
-
-      geoPoly.inners().resize(k+1);
-      geoPoly.inners().back();
-      model::ring<point_2d>& inner = geoPoly.inners().back();
-      for (unsigned int j = 0; j< temp_obst.size();j++){
-	append(inner, make<point_2d>(temp_obst[j]._x, temp_obst[j]._y));
-      }
-      correct(geoPoly);
-    }
-  }
+	_building = new Building();
+	_building->LoadBuilding(geometryFile);
+	double geo_minX  = FLT_MAX;
+	double geo_minY  = FLT_MAX;
+	double geo_maxX  = -FLT_MAX;
+	double geo_maxY  = -FLT_MAX;
+	polygon_2d geoPoly;
+	// create the polygons
+	_building->InitGeometry();
+	vector<Obstacle*> GeoObst;
+	for(int i=0;i<_building->GetNumberOfRooms();i++){
+		Room* room=_building->GetRoom(i);
+
+		for( int j=0;j<room->GetNumberOfSubRooms();j++){
+			SubRoom* subroom = room->GetSubRoom(i);
+			const vector<Point>& temp_GeoPoly = subroom->GetPolygon();
+			for (unsigned int j = 0; j< temp_GeoPoly.size(); j++){
+				append(geoPoly, make<point_2d>(temp_GeoPoly[j]._x, temp_GeoPoly[j]._y));
+				geo_minX = (temp_GeoPoly[j]._x<=geo_minX) ? temp_GeoPoly[j]._x : geo_minX;
+				geo_minY = (temp_GeoPoly[j]._y<=geo_minY) ? temp_GeoPoly[j]._y : geo_minY;
+				geo_maxX = (temp_GeoPoly[j]._x>=geo_maxX) ? temp_GeoPoly[j]._x : geo_maxX;
+				geo_maxY = (temp_GeoPoly[j]._y>=geo_maxY) ? temp_GeoPoly[j]._y : geo_maxY;
 
-  _highVertexX = geo_maxX;
-  _highVertexY = geo_maxY;
-  _lowVertexX = geo_minX;
-  _lowVertexY = geo_minY;
-  cout <<"_highVertexX: \t"<<_highVertexX<< endl;
-  cout <<"_highVertexY: \t"<<_highVertexY<< endl;
-  cout <<"_lowVertexX: \t"<<_lowVertexX<< endl;
-  cout <<"_lowVertexY: \t"<<_lowVertexY<< endl;
+			}
+			correct(geoPoly);
+			//std::cout << "poly without hole: " << boost::geometry::dsv(geoPoly) << std::endl;
+			GeoObst = subroom->GetAllObstacles();
+		}
+		for (unsigned int k = 0; k < GeoObst.size(); k++) {
+			//std::cout<< GeoObst.size()<<std::endl;
+			//std::cout<< pBuilding->GetAnzRooms() <<'\t'<<room->GetAnzSubRooms()<<std::endl;
+			const vector<Point>& temp_obst = GeoObst[k]->GetPolygon();
+
+			geoPoly.inners().resize(k+1);
+			geoPoly.inners().back();
+			model::ring<point_2d>& inner = geoPoly.inners().back();
+			for (unsigned int j = 0; j< temp_obst.size();j++){
+				append(inner, make<point_2d>(temp_obst[j]._x, temp_obst[j]._y));
+			}
+			correct(geoPoly);
+		}
+	}
+
+	_highVertexX = geo_maxX;
+	_highVertexY = geo_maxY;
+	_lowVertexX = geo_minX;
+	_lowVertexY = geo_minY;
 
-  return geoPoly;
+	return geoPoly;
 }
 
 void Analysis::ReadTrajetories(const string& trajectoriesFile){
-  //---------read the trajectory data from file-----------
-  ////////////////////////////--------------Parse the xmlFile---------------///////////////////////////////////////////////////////
+	//---------read the trajectory data from file-----------
+
+	Log->Write("INFO:\t input file <%s>\n",trajectoriesFile.c_str());
+	TiXmlDocument docGeo(trajectoriesFile);
+	if (!docGeo.LoadFile()){
+		Log->Write("ERROR: \t%s", docGeo.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the trajectories file");
+		exit(EXIT_FAILURE);
+	}
 
-  Log->Write(">>> input file <%s>\n",trajectoriesFile.c_str());
 
-  XMLNode xMainNode = XMLNode::openFileHelper(trajectoriesFile.c_str(),"trajectoriesDataset");
-  XMLNode xHeader = xMainNode.getChildNode("header"); // header
-  XMLNode xFrame = xMainNode.getChildNode("frame"); // frame
-  _numFrames = xMainNode.nChildNode("frame"); // how much frames
+	TiXmlElement* xRootNode = docGeo.RootElement();
+	if( ! xRootNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
 
-  Log->Write("numFrames = %d\n",_numFrames);
-  if(!xHeader.getChildNode("agents").isEmpty()){
-    const char* N = xHeader.getChildNode("agents").getText();
-    _maxNumofPed = atoi(N);
-    Log->Write("N=%d\n", _maxNumofPed);
-  }
-  if(!xHeader.getChildNode("frameRate").isEmpty()){
-    const char* NF = xHeader.getChildNode("frameRate").getText();
-    _fps = atoi(NF);
-    Log->Write("fps=%d\n", _fps);
-  }
-  _xCor = new double* [_maxNumofPed];
-  _yCor = new double* [_maxNumofPed];
-  for (int i=0; i<_maxNumofPed; i++)
-    {
-      _xCor[i] = new double [_numFrames];
-      _yCor[i] = new double [_numFrames];
-    }
-  _firstFrame = new int[_maxNumofPed];  // Record the first frame of each pedestrian
-  _lastFrame = new int[_maxNumofPed];  // Record the last frame of each pedestrian
-  _tIn = new int[_maxNumofPed];				// Record the time of each pedestrian entering measurement area
-  _tOut = new int[_maxNumofPed];				// Record the time of each pedestrian exiting measurement area
-  bool IsinMeasurezone[_maxNumofPed];  // Record whether pedestrian i is in measurement area or not
-
-  for(int i = 0; i <_maxNumofPed; i++)
-    {
-      for (int j = 0; j < _numFrames; j++)
-	{
-	  _xCor[i][j] = 0;
-	  _yCor[i][j] = 0;
+	if( xRootNode->ValueStr () != "trajectoriesDataset" ) {
+		Log->Write("ERROR:\tRoot element value is not 'geometry'.");
+		exit(EXIT_FAILURE);
 	}
-      _firstFrame[i] = INT_MAX;
-      _lastFrame[i] = INT_MIN;
-      _tIn[i] = 0;
-      _tOut[i] = 0;
-      IsinMeasurezone[i] = false;
-    }
+
+	//fixme in JPSGCFM
+	double version = xmltof(xRootNode->Attribute("version"), -1);
+	if (version != JPS_MAJOR_VERSION) {
+		Log->Write("ERROR: \tOnly version [%f] > 0.4 supported",version);
+		Log->Write("ERROR: \tparsing trajectories file failed!");
+		//exit(EXIT_FAILURE);
+	}
+
+
+	//counting the number of frames
+	_numFrames=0;
+	for(TiXmlElement* xFrame = xRootNode->FirstChildElement("frame"); xFrame;
+			xFrame = xFrame->NextSiblingElement("frame")) {
+		_numFrames++;
+	}
+	Log->Write("numFrames = %d\n",_numFrames);
 
 
-  if(!xFrame.isEmpty())
-    {
-      for (int f=0; f<_numFrames; f++) //read the data frame by frame
+	TiXmlNode*  xHeader = xRootNode->FirstChild("header"); // header
+	//Number of agents
+	if(xHeader->FirstChild("agents")){
+		_maxNumofPed=atoi(xHeader->FirstChild("agents")->FirstChild()->Value());
+		Log->Write("N=%d\n", _maxNumofPed);
+	}
+
+	//framerate
+	if(xHeader->FirstChild("frameRate")){
+		_fps=atoi(xHeader->FirstChild("frameRate")->FirstChild()->Value());
+		Log->Write("fps=%d\n", _fps);
+	}
+
+	_xCor = new double* [_maxNumofPed];
+	_yCor = new double* [_maxNumofPed];
+	for (int i=0; i<_maxNumofPed; i++)
 	{
-	  xFrame = xMainNode.getChildNode("frame", f); // frame j
-	  int numPedsInFrame = xFrame.nChildNode("agent"); // how much agents in this frame
-	  //printf("This frame has %d peds\n",numPedsInFrame);
-	  for (int i=0; i<numPedsInFrame; i++) //read pedestrians in frame j
-	    {
-	      if(!xFrame.getChildNode("agent", i).isEmpty())
+		_xCor[i] = new double [_numFrames];
+		_yCor[i] = new double [_numFrames];
+	}
+	_firstFrame = new int[_maxNumofPed];  // Record the first frame of each pedestrian
+	_lastFrame = new int[_maxNumofPed];  // Record the last frame of each pedestrian
+	_tIn = new int[_maxNumofPed];				// Record the time of each pedestrian entering measurement area
+	_tOut = new int[_maxNumofPed];				// Record the time of each pedestrian exiting measurement area
+	bool IsinMeasurezone[_maxNumofPed];  // Record whether pedestrian i is in measurement area or not
+
+	for(int i = 0; i <_maxNumofPed; i++)
+	{
+		for (int j = 0; j < _numFrames; j++)
 		{
-		  //get agent id, x, y
-		  const char* x = xFrame.getChildNode("agent", i).getAttribute("xPos");
-		  const char* y = xFrame.getChildNode("agent", i).getAttribute("yPos");
-		  const char* id = xFrame.getChildNode("agent", i).getAttribute("ID");
-		  int ID = atoi(id)-1;
-		  _xCor[ID][f] = atof(x);
-		  _yCor[ID][f] = atof(y);
-		  if(f < _firstFrame[ID])
-		    {
-		      _firstFrame[ID] = f;
-		    }
-		  if(f > _lastFrame[ID])
-		    {
-		      _lastFrame[ID] = f;
-		    }
-		  if(_fundamentalTinTout==true)
-		    {
-		      if(within(make<point_2d>(atof(x),atof(y)), _measureZone)&&!(IsinMeasurezone[ID]))
+			_xCor[i][j] = 0;
+			_yCor[i][j] = 0;
+		}
+		_firstFrame[i] = INT_MAX;
+		_lastFrame[i] = INT_MIN;
+		_tIn[i] = 0;
+		_tOut[i] = 0;
+		IsinMeasurezone[i] = false;
+	}
+
+
+	//processing the frames node
+	TiXmlNode*  xFramesNode = xRootNode->FirstChild("frame");
+	if (!xFramesNode){
+		Log->Write("ERROR: \tThe geometry should have at least one frame");
+		exit(EXIT_FAILURE);
+	}
+
+	int frameNr=0;
+	for(TiXmlElement* xFrame = xRootNode->FirstChildElement("frame"); xFrame;
+			xFrame = xFrame->NextSiblingElement("frame")) {
+
+		for(TiXmlElement* xAgent = xFrame->FirstChildElement("agent"); xAgent;
+				xAgent = xAgent->NextSiblingElement("agent")) {
+
+			//get agent id, x, y
+			double x= atof(xAgent->Attribute("xPos"));
+			double y= atof(xAgent->Attribute("yPos"));
+			int ID= atoi(xAgent->Attribute("ID"))-1;
+
+			_xCor[ID][frameNr] =  x;
+			_yCor[ID][frameNr] =  y;
+			if(frameNr < _firstFrame[ID])
 			{
-			  _tIn[ID]=f;
-			  IsinMeasurezone[ID] = true;
+				_firstFrame[ID] = frameNr;
 			}
-		      if((!within(make<point_2d>(atof(x),atof(y)), _measureZone))&&IsinMeasurezone[ID])
+			if(frameNr > _lastFrame[ID])
 			{
-			  _tOut[ID]=f;
-			  IsinMeasurezone[ID] = false;
+				_lastFrame[ID] = frameNr;
+			}
+			if(_fundamentalTinTout==true)
+			{
+				if(within(make<point_2d>( (x), (y)), _measureZone)&&!(IsinMeasurezone[ID]))
+				{
+					_tIn[ID]=frameNr;
+					IsinMeasurezone[ID] = true;
+				}
+				if((!within(make<point_2d>( (x), (y)), _measureZone))&&IsinMeasurezone[ID])
+				{
+					_tOut[ID]=frameNr;
+					IsinMeasurezone[ID] = false;
+				}
 			}
-		    }
 		}
-	    } //for i
-	}// getFrame number j
-    }
-  Log->Write("finished test of xmlParser.\n");
+		frameNr++;
+	}
 
+	Log->Write("INFO:\tDone reading the trajectories");
 }
 
 int Analysis::RunAnalysis()
 {
-  XMLNode xMainNode = XMLNode::openFileHelper(_trajectoryFile.c_str(),"trajectoriesDataset");
-  XMLNode xFrame = xMainNode.getChildNode("frame"); // frame
-  int ClassicFlow=0; // the number of pedestrians pass a line in a certain time
-  double V_deltaT=0;   // define this is to measure cumulative velocity each pedestrian pass a measure line each time step to calculate the <v>delat T=sum<vi>/N
-  double *DensityPerFrame;
-  DensityPerFrame = new double[_numFrames];
-  for(int i=0;i<_numFrames;i++)
-    {
-      DensityPerFrame[i]=0;
-    }
-  bool *PassLine = new bool[_maxNumofPed];
-  for(int i=0; i<_maxNumofPed; i++)
-    {
-      PassLine[i] = false;
-    }
 
-  string N_t="Flow_NT_"+_trajectoryName+"_Out.dat";
-  ofstream flowNTs(N_t.c_str());
+	string fullTrajectoriesPathName= _trajectoriesLocation+"/"+_trajectoryName;
+
+	TiXmlDocument docGeo(fullTrajectoriesPathName);
+	if (!docGeo.LoadFile()){
+		Log->Write("ERROR: \t%s", docGeo.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the trajectories file <%s>",fullTrajectoriesPathName.c_str());
+		exit(EXIT_FAILURE);
+	}
 
-  if(!xFrame.isEmpty())
-    {
-      for (int f=0; f<_numFrames; f++) //read the data frame by frame
+	TiXmlElement* xRootNode = docGeo.RootElement();
+	if( ! xRootNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
+
+	if( xRootNode->ValueStr () != "trajectoriesDataset" ) {
+		Log->Write("ERROR:\tRoot element value is not 'geometry'.");
+		exit(EXIT_FAILURE);
+	}
+
+	int ClassicFlow=0; // the number of pedestrians pass a line in a certain time
+	double V_deltaT=0;   // define this is to measure cumulative velocity each pedestrian pass a measure line each time step to calculate the <v>delat T=sum<vi>/N
+	double *DensityPerFrame;
+	DensityPerFrame = new double[_numFrames];
+	for(int i=0;i<_numFrames;i++)
 	{
-	  xFrame = xMainNode.getChildNode("frame", f); // frame j
-	  const char* frid = xFrame.getAttribute("ID");
+		DensityPerFrame[i]=0;
+	}
+	bool *PassLine = new bool[_maxNumofPed];
+	for(int i=0; i<_maxNumofPed; i++)
+	{
+		PassLine[i] = false;
+	}
+
+	string N_t="Flow_NT_"+_trajectoryName+"_Out.dat";
+	ofstream flowNTs(N_t.c_str());
+
+	int frameNr=0;
+	for(TiXmlElement* xFrame = xRootNode->FirstChildElement("frame"); xFrame;
+			xFrame = xFrame->NextSiblingElement("frame")) {
+
+		int frid = atoi(xFrame->Attribute("ID"));
+		frameNr++;
+
+		//counting the agents in the frame
+		int numPedsInFrame=0;
+		for(TiXmlElement* xAgent = xFrame->FirstChildElement("agent"); xAgent;
+				xAgent = xAgent->NextSiblingElement("agent")) numPedsInFrame++;
+
+
+		Log->Write("frame ID = %d\n",(frid));
+
+		//printf("This frame has %d peds\n",numPedsInFrame);
+		double *XInFrame = new double[numPedsInFrame]; 				// save the X coordinates of pedestrian in the geometry in this frame
+		double *YInFrame = new double[numPedsInFrame];				// save the Y coordinates of pedestrian in the geometry in this frame
+		double *VInFrame = new double[numPedsInFrame]; 				// save the instantaneous velocity of pedestrians in the geometry in this frame
+
+		int agentCnt=0;
+		for(TiXmlElement* xAgent = xFrame->FirstChildElement("agent"); xAgent;
+				xAgent = xAgent->NextSiblingElement("agent")) {
+
+			//get agent id, x, y
+			double x= atof(xAgent->Attribute("xPos"));
+			double y= atof(xAgent->Attribute("yPos"));
+			int ID= atoi(xAgent->Attribute("ID"))-1;
 
-	  Log->Write("frame ID = %d\n",atoi(frid));
 
-	  int numPedsInFrame = xFrame.nChildNode("agent"); 		// how many agents in this frame
-	  //printf("This frame has %d peds\n",numPedsInFrame);
-	  double *XInFrame = new double[numPedsInFrame]; 				// save the X coordinates of pedestrian in the geometry in this frame
-	  double *YInFrame = new double[numPedsInFrame];				// save the Y coordinates of pedestrian in the geometry in this frame
-	  double *VInFrame = new double[numPedsInFrame]; 				// save the instantaneous velocity of pedestrians in the geometry in this frame
+			XInFrame[agentCnt] =  (x);
+			YInFrame[agentCnt] =  (y);
+			int Tpast = frameNr - _deltaF;
+			int Tfuture = frameNr + _deltaF;
+			VInFrame[agentCnt] = GetVinFrame(frameNr, Tpast, Tfuture, ID, _firstFrame, _lastFrame, _xCor, _yCor, _vComponent);
+			bool IspassLine=false;
+			if(frameNr >_firstFrame[ID]&&!PassLine[ID])
+			{
+				IspassLine = IsPassLine(_lineStartX,_lineStartY, _lineEndX, _lineEndY,_xCor[ID][frameNr-1],_yCor[ID][frameNr-1],_xCor[ID][frameNr],_yCor[ID][frameNr]);
+			}
+			if(IspassLine==true)
+			{
+				PassLine[ID] = true;
+				ClassicFlow++;
+				V_deltaT+=VInFrame[agentCnt];
+				//cout<<_xCor[ID][f-1]<< "\t"<<_yCor[ID][f-1]<< "\t"<<_xCor[ID][f]<< "\t"<<_yCor[ID][f]<< endl;
+			}
+		}
+		agentCnt++;
+		//for agentCnt
 
-	  for (int i=0; i<numPedsInFrame; i++) //read pedestrians in frame j
-	    {
-	      if(!xFrame.getChildNode("agent", i).isEmpty())
+		if(_flowVelocity)
 		{
-		  //get agent id, x, y
-		  const char* x = xFrame.getChildNode("agent", i).getAttribute("xPos");
-		  const char* y = xFrame.getChildNode("agent", i).getAttribute("yPos");
-		  const char* id = xFrame.getChildNode("agent", i).getAttribute("ID");
-		  int ID = atoi(id)-1;
-		  XInFrame[i] = atof(x);
-		  YInFrame[i] = atof(y);
-		  int Tpast = f - _deltaF;
-		  int Tfuture = f + _deltaF;
-		  VInFrame[i] = GetVinFrame(f, Tpast, Tfuture, ID, _firstFrame, _lastFrame, _xCor, _yCor, _vComponent);
-		  bool IspassLine=false;
-		  if(f >_firstFrame[ID]&&!PassLine[ID])
-		    {
-		      IspassLine = IsPassLine(_lineStartX,_lineStartY, _lineEndX, _lineEndY,_xCor[ID][f-1],_yCor[ID][f-1],_xCor[ID][f],_yCor[ID][f]);
-		    }
-		  if(IspassLine==true)
-		    {
-		      PassLine[ID] = true;
-		      ClassicFlow++;
-		      V_deltaT+=VInFrame[i];
-		      //cout<<_xCor[ID][f-1]<< "\t"<<_yCor[ID][f-1]<< "\t"<<_xCor[ID][f]<< "\t"<<_yCor[ID][f]<< endl;
-		    }
+			_accumPedsPassLine.push_back(ClassicFlow);
+			_accumVPassLine.push_back(V_deltaT);
+			fprintf(_fN_t,"%d\t%d\n",frid, ClassicFlow);
 		}
-	    } //for i
-
-	  if(_flowVelocity)
-	    {
-	      _accumPedsPassLine.push_back(ClassicFlow);
-	      _accumVPassLine.push_back(V_deltaT);
-	      fprintf(_fN_t,"%d\t%d\n",atoi(frid), ClassicFlow);
-	    }
-
-	  if(_classicMethod)
-	    {
-	      double ClassicDensity = GetClassicalDensity(XInFrame, YInFrame, numPedsInFrame, _measureZone);
-	      double ClassicVelocity = GetClassicalVelocity(XInFrame, YInFrame, VInFrame, numPedsInFrame, _measureZone);
-	      DensityPerFrame[f]=ClassicDensity;
-	      fprintf(_fClassicRhoV,"%d\t%.3f\t%.3f\n",atoi(frid), ClassicDensity,ClassicVelocity);
-	    }
-
-	  //------------------Voronoi Method---------------------------------
-	  if(_voronoiMethod)
-	    {
-
-	      vector<polygon_2d> polygons;
-	      VoronoiDiagram vd;
-	      if(numPedsInFrame>2)
+
+		if(_classicMethod)
+		{
+			double ClassicDensity = GetClassicalDensity(XInFrame, YInFrame, numPedsInFrame, _measureZone);
+			double ClassicVelocity = GetClassicalVelocity(XInFrame, YInFrame, VInFrame, numPedsInFrame, _measureZone);
+			DensityPerFrame[frameNr]=ClassicDensity;
+			fprintf(_fClassicRhoV,"%d\t%.3f\t%.3f\n", frid, ClassicDensity,ClassicVelocity);
+		}
+
+		//------------------Voronoi Method---------------------------------
+		if(_voronoiMethod)
 		{
-		  polygons = vd.getVoronoiPolygons(XInFrame, YInFrame, VInFrame, numPedsInFrame);
-		  if(_cutByCircle)
-		    {
-		      //polygons = cutPolygonsWithCircle(polygons, XInFrame, YInFrame, 50);
-		    }
-		  polygons = vd.cutPolygonsWithGeometry(polygons, _geoPoly, XInFrame, YInFrame);
-		  double VoronoiVelocity;
-		  if(numPedsInFrame>0)
-		    {
-		      VoronoiVelocity=GetVoronoiVelocity(polygons,VInFrame,_measureZone);
-		    }
-		  else
-		    {
-		      VoronoiVelocity=0;
-		    }
-		  double VoronoiDensity=GetVoronoiDensity(polygons, _measureZone);
-		  fprintf(_fVoronoiRhoV,"%d\t%.3f\t%.3f\n",atoi(frid),VoronoiDensity, VoronoiVelocity);
-
-		  if(_calcIndividualFD)
-		    {
-		      if(numPedsInFrame>0)
+			vector<polygon_2d> polygons;
+			VoronoiDiagram vd;
+			if(numPedsInFrame>2)
 			{
-			  // if(i>beginstationary&&i<endstationary)
-			  {
-			    GetIndividualFD(polygons,VInFrame,_measureZone);
-			  }
+				polygons = vd.getVoronoiPolygons(XInFrame, YInFrame, VInFrame, numPedsInFrame);
+				if(_cutByCircle)
+				{
+					//polygons = cutPolygonsWithCircle(polygons, XInFrame, YInFrame, 50);
+				}
+				polygons = vd.cutPolygonsWithGeometry(polygons, _geoPoly, XInFrame, YInFrame);
+				double VoronoiVelocity;
+				if(numPedsInFrame>0)
+				{
+					VoronoiVelocity=GetVoronoiVelocity(polygons,VInFrame,_measureZone);
+				}
+				else
+				{
+					VoronoiVelocity=0;
+				}
+				double VoronoiDensity=GetVoronoiDensity(polygons, _measureZone);
+				fprintf(_fVoronoiRhoV,"%d\t%.3f\t%.3f\n",frid,VoronoiDensity, VoronoiVelocity);
+
+				if(_calcIndividualFD)
+				{
+					if(numPedsInFrame>0)
+					{
+						// if(i>beginstationary&&i<endstationary)
+						{
+							GetIndividualFD(polygons,VInFrame,_measureZone);
+						}
+					}
+				}
+				//------------------field analysis----------------------------------------------------------
+				if(_getProfile)
+				{
+					if(numPedsInFrame>0)
+					{
+						GetProfiles(boost::lexical_cast<string>(frid), polygons, VInFrame);
+						//						GetProfiles(lexical_cast<string>(frid)string(frid_str), polygons, VInFrame);
+					}
+				}
+				//------------the following codes is written to output the Voronoi polygons of a frame-----------
+				if(_outputGraph)
+				{
+					cout<<"output polygons"<<endl;
+					OutputVoroGraph(boost::lexical_cast<string>(frid), polygons, numPedsInFrame,XInFrame, YInFrame,VInFrame);
+				}
 			}
-		    }
-		  //------------------field analysis----------------------------------------------------------
-		  if(_getProfile)
-		    {
-		      if(numPedsInFrame>0)
+			else
 			{
-			  GetProfiles(string(frid), polygons, VInFrame);
+				cout<<" the number of the pedestrians is less than 2 !!"<< endl;
 			}
-		    }
-		  //------------the following codes is written to output the Voronoi polygons of a frame-----------
-		  if(_outputGraph)
-		    {
-		      cout<<"output polygons"<<endl;
-		      OutputVoroGraph(string(frid), polygons, numPedsInFrame,XInFrame, YInFrame,VInFrame);
-		    }
 		}
-	      else
-		{
-		  cout<<" the number of the pedestrians is less than 2 !!"<< endl;
-		}
-	    }
-	
-	  delete []XInFrame;
-	
-	  delete []YInFrame;
-	
-	  delete []VInFrame;
-	
+
+		delete []XInFrame;
+
+		delete []YInFrame;
+
+		delete []VInFrame;
+
 	}// getFrame number j
-    }
-	
-  if(_classicMethod)
-    fclose(_fClassicRhoV);
-	
-  if(_voronoiMethod)
-    fclose(_fVoronoiRhoV);
-	
-  if(_flowVelocity)
-    fclose(_fN_t);//
-	
-  delete []PassLine;
-	
-  //--------------------Fundamental diagram based on Tin and Tout----------------------------------------------------------------------
-  if(_fundamentalTinTout)
-    {
-#ifdef WIN32
-      string FD_TinTout=  "Output\\Fundamental_Diagram\\TinTout\\FDTinTout_"+_trajectoryName+".dat";
-#else
-      string FD_TinTout=  "Output/Fundamental_Diagram/TinTout/FDTinTout_"+_trajectoryName+".dat";
-#endif
-      Log->Write("Fundamental diagram based on Tin and Tout will be calculated!");
-      GetFundamentalTinTout(_tIn,_tOut,DensityPerFrame, _fps, _lengthMeasurementarea,_maxNumofPed, FD_TinTout); //MC. 15.8.12. replaced "datafile" by results
-    }
-  //-----------------------------------------------------------------------------------------------------------------------------------
-  if(_flowVelocity)
-    {
-#ifdef WIN32
-      string FD_FlowVelocity=  "Output\\Fundamental_Diagram\\FlowVelocity\\FDFlowVelocity_"+_trajectoryName+".dat";
-#else
-      string FD_FlowVelocity=  "Output/Fundamental_Diagram/FlowVelocity/FDFlowVelocity_"+_trajectoryName+".dat";
-#endif
-      FlowRate_Velocity(_deltaT,_fps, _accumPedsPassLine,_accumVPassLine,FD_FlowVelocity);
-    }
-  delete []DensityPerFrame;
-  return 0;
+
+	if(_classicMethod)
+		fclose(_fClassicRhoV);
+
+	if(_voronoiMethod)
+		fclose(_fVoronoiRhoV);
+
+	if(_flowVelocity)
+		fclose(_fN_t);//
+
+	delete []PassLine;
+
+	//--------------------Fundamental diagram based on Tin and Tout----------------------------------------------------------------------
+	if(_fundamentalTinTout)
+	{
+		string FD_TinTout=  "Output/Fundamental_Diagram/TinTout/FDTinTout_"+_trajectoryName+".dat";
+		Log->Write("Fundamental diagram based on Tin and Tout will be calculated!");
+		GetFundamentalTinTout(_tIn,_tOut,DensityPerFrame, _fps, _lengthMeasurementarea,_maxNumofPed, FD_TinTout); //MC. 15.8.12. replaced "datafile" by results
+	}
+	//-----------------------------------------------------------------------------------------------------------------------------------
+	if(_flowVelocity)
+	{
+		string FD_FlowVelocity=  "Output/Fundamental_Diagram/FlowVelocity/FDFlowVelocity_"+_trajectoryName+".dat";
+		FlowRate_Velocity(_deltaT,_fps, _accumPedsPassLine,_accumVPassLine,FD_FlowVelocity);
+	}
+	delete []DensityPerFrame;
+	return 0;
 }
 
 /*
@@ -570,53 +598,53 @@ int Analysis::RunAnalysis()
  */
 bool Analysis::IsPassLine(double Line_startX,double Line_startY, double Line_endX, double Line_endY,double pt1_X, double pt1_Y,double pt2_X, double pt2_Y)
 {
-  double x1=Line_startX;
-  double y1=Line_startY;
-  double x2=Line_endX;
-  double y2=Line_endY;
-  double x3=pt1_X;
-  double y3=pt1_Y;
-  double x4=pt2_X;
-  double y4=pt2_Y;
-
-  double d=(y2-y1)*(x4-x3)-(y4-y3)*(x2-x1);
-  if(d==0)
-    {
-      return false;
-    }
-  else
-    {
-      double x0=((x2-x1)*(x4-x3)*(y3-y1)+(y2-y1)*(x4-x3)*x1-(y4-y3)*(x2-x1)*x3)/d;
-      double y0=((y2-y1)*(y4-y3)*(x3-x1)+(x2-x1)*(y4-y3)*y1-(x4-x3)*(y2-y1)*y3)/(-1.0*d);
-      double temp1=(x0-x1)*(x0-x2);
-      double temp2=(x0-x3)*(x0-x4);
-      double temp3=(y0-y1)*(y0-y2);
-      double temp4=(y0-y3)*(y0-y4);
-      if(temp1<10.0E-16)
+	double x1=Line_startX;
+	double y1=Line_startY;
+	double x2=Line_endX;
+	double y2=Line_endY;
+	double x3=pt1_X;
+	double y3=pt1_Y;
+	double x4=pt2_X;
+	double y4=pt2_Y;
+
+	double d=(y2-y1)*(x4-x3)-(y4-y3)*(x2-x1);
+	if(d==0)
 	{
-	  temp1=0.0;
+		return false;
 	}
-      if(temp2<10.0E-16)
+	else
 	{
-	  temp2=0.0;
-	}
-      if(temp3<10.0E-16)
-	{
-	  temp3=0.0;
-	}
-      if(temp4<10.0E-16)
-	{
-	  temp4=0.0;
-	}
-      if(temp1<=0.0&&temp2<=0.0&&temp3<=0.0&&temp4<=0.0)
-	{
-	  return true;
-	}
-      else
-	{
-	  return false;
+		double x0=((x2-x1)*(x4-x3)*(y3-y1)+(y2-y1)*(x4-x3)*x1-(y4-y3)*(x2-x1)*x3)/d;
+		double y0=((y2-y1)*(y4-y3)*(x3-x1)+(x2-x1)*(y4-y3)*y1-(x4-x3)*(y2-y1)*y3)/(-1.0*d);
+		double temp1=(x0-x1)*(x0-x2);
+		double temp2=(x0-x3)*(x0-x4);
+		double temp3=(y0-y1)*(y0-y2);
+		double temp4=(y0-y3)*(y0-y4);
+		if(temp1<10.0E-16)
+		{
+			temp1=0.0;
+		}
+		if(temp2<10.0E-16)
+		{
+			temp2=0.0;
+		}
+		if(temp3<10.0E-16)
+		{
+			temp3=0.0;
+		}
+		if(temp4<10.0E-16)
+		{
+			temp4=0.0;
+		}
+		if(temp1<=0.0&&temp2<=0.0&&temp3<=0.0&&temp4<=0.0)
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
 	}
-    }
 }
 
 //-----------------------------------------------------------------------------------------------------------------------------
@@ -627,26 +655,26 @@ bool Analysis::IsPassLine(double Line_startX,double Line_startY, double Line_end
  */
 void Analysis::GetFundamentalTinTout(int *Tin, int *Tout, double *DensityPerFrame, int fps, double LengthMeasurementarea,int Nped, string ofile)
 {
-  FILE *fFD_TinTout;
-  string fdTinTout=ofile;
-  if((fFD_TinTout=fopen(fdTinTout.c_str(),"w"))==NULL)
-    {
-      Log->Write("cannot open the file to write the TinTout data\n");
-      exit(0);
-    }
-  fprintf(fFD_TinTout,"#person Index\t	density_i(m^(-2))\t	velocity_i(m/s)\n");
-  for(int i=0;i<Nped;i++)
-    {
-      double velocity_temp=fps*CMtoM*LengthMeasurementarea/(Tout[i]-Tin[i]);
-      double density_temp=0;
-      for(int j=Tin[i];j<Tout[i];j++)
+	FILE *fFD_TinTout;
+	string fdTinTout=ofile;
+	if((fFD_TinTout=CreateFile(fdTinTout))==NULL)
 	{
-	  density_temp+=DensityPerFrame[j];
+		Log->Write("cannot open the file to write the TinTout data\n");
+		exit(0);
 	}
-      density_temp/=(Tout[i]-Tin[i]);
-      fprintf(fFD_TinTout,"%d\t%f\t%f\n",i+1,density_temp,velocity_temp);
-    }
-  fclose(fFD_TinTout);
+	fprintf(fFD_TinTout,"#person Index\t	density_i(m^(-2))\t	velocity_i(m/s)\n");
+	for(int i=0;i<Nped;i++)
+	{
+		double velocity_temp=fps*CMtoM*LengthMeasurementarea/(Tout[i]-Tin[i]);
+		double density_temp=0;
+		for(int j=Tin[i];j<Tout[i];j++)
+		{
+			density_temp+=DensityPerFrame[j];
+		}
+		density_temp/=(Tout[i]-Tin[i]);
+		fprintf(fFD_TinTout,"%d\t%f\t%f\n",i+1,density_temp,velocity_temp);
+	}
+	fclose(fFD_TinTout);
 }
 
 //----------------------------------------------------------------------------------------------------------------------------
@@ -660,43 +688,43 @@ void Analysis::GetFundamentalTinTout(int *Tin, int *Tout, double *DensityPerFram
 void Analysis::FlowRate_Velocity(int DeltaT, int fps, vector<int> AccumPeds, vector<double> AccumVelocity, string ofile)
 {
 
-  FILE *fFD_FlowVelocity;
-  string fdFlowVelocity = ofile;  //"Fundamental Diagram\\FlowVelocity\\FundamentalFlowVelocity"+datafile+".dat";
-  if((fFD_FlowVelocity=fopen(fdFlowVelocity.c_str(),"w"))==NULL)
-    {
-      Log->Write("cannot open the file to write the Flow-Velocity data\n");
-      exit(0);
-    }
-  fprintf(fFD_FlowVelocity,"#Flow rate(1/s)	Mean velocity(m/s)\n");
-  int TotalTime=AccumPeds.size();  // the total Frame of in the data file
-  int TotalPeds=AccumPeds[TotalTime-1];  //the total pedestrians in the data file
-  int firstPassT=-1;  // the first time that there are pedestrians pass the line
-  int *pedspassT=new int[TotalPeds+1]; // the time for certain pedestrian passing the line
-  for(int i=0; i<=TotalPeds; i++)
-    {
-      pedspassT[i]=-1;
-    }
-
-  for(int ix=0; ix<TotalTime; ix++)
-    {
-      if(AccumPeds[ix]>0 && firstPassT<0)
+	FILE *fFD_FlowVelocity;
+	string fdFlowVelocity = ofile;  //"Fundamental Diagram\\FlowVelocity\\FundamentalFlowVelocity"+datafile+".dat";
+	if((fFD_FlowVelocity=CreateFile(fdFlowVelocity))==NULL)
 	{
-	  firstPassT=ix;
+		Log->Write("cannot open the file to write the Flow-Velocity data\n");
+		exit(0);
 	}
-      if(pedspassT[AccumPeds[ix]]<0)
+	fprintf(fFD_FlowVelocity,"#Flow rate(1/s)	Mean velocity(m/s)\n");
+	int TotalTime=AccumPeds.size();  // the total Frame of in the data file
+	int TotalPeds=AccumPeds[TotalTime-1];  //the total pedestrians in the data file
+	int firstPassT=-1;  // the first time that there are pedestrians pass the line
+	int *pedspassT=new int[TotalPeds+1]; // the time for certain pedestrian passing the line
+	for(int i=0; i<=TotalPeds; i++)
 	{
-	  pedspassT[AccumPeds[ix]]=ix;
+		pedspassT[i]=-1;
 	}
-    }
-  for(int i=firstPassT+DeltaT; i<TotalTime; i+=DeltaT)
-    {
-      double flow_rate=fps*(AccumPeds[i]-AccumPeds[i-DeltaT])*1.00/(pedspassT[AccumPeds[i]]-pedspassT[AccumPeds[i-DeltaT]]);
-      double MeanV=(AccumVelocity[i]-AccumVelocity[i-DeltaT])/(AccumPeds[i]-AccumPeds[i-DeltaT]);
-      fprintf(fFD_FlowVelocity,"%.3f\t%.3f\n",flow_rate,MeanV);
 
-    }
-  fclose(fFD_FlowVelocity);
-  delete []pedspassT;
+	for(int ix=0; ix<TotalTime; ix++)
+	{
+		if(AccumPeds[ix]>0 && firstPassT<0)
+		{
+			firstPassT=ix;
+		}
+		if(pedspassT[AccumPeds[ix]]<0)
+		{
+			pedspassT[AccumPeds[ix]]=ix;
+		}
+	}
+	for(int i=firstPassT+DeltaT; i<TotalTime; i+=DeltaT)
+	{
+		double flow_rate=fps*(AccumPeds[i]-AccumPeds[i-DeltaT])*1.00/(pedspassT[AccumPeds[i]]-pedspassT[AccumPeds[i-DeltaT]]);
+		double MeanV=(AccumVelocity[i]-AccumVelocity[i-DeltaT])/(AccumPeds[i]-AccumPeds[i-DeltaT]);
+		fprintf(fFD_FlowVelocity,"%.3f\t%.3f\n",flow_rate,MeanV);
+
+	}
+	fclose(fFD_FlowVelocity);
+	delete []pedspassT;
 }
 
 //-----------------------------------------------------------------------------------------------------------------
@@ -708,29 +736,29 @@ void Analysis::FlowRate_Velocity(int DeltaT, int fps, vector<int> AccumPeds, vec
 void Analysis::GetIndividualFD(vector<polygon_2d> polygon, double* Velocity, polygon_2d measureArea)
 {
 
-  vector<polygon_2d>::iterator polygon_iterator;
-  double uniquedensity=0;
-  double uniquevelocity=0;
-  int temp=0;
-  for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
-    {
-      typedef std::vector<polygon_2d> polygon_list;
-      polygon_list v;
-      intersection(measureArea, *polygon_iterator, v);
-      if(!v.empty())
+	vector<polygon_2d>::iterator polygon_iterator;
+	double uniquedensity=0;
+	double uniquevelocity=0;
+	int temp=0;
+	for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
 	{
-	  uniquedensity=1/(area(*polygon_iterator)*CMtoM*CMtoM);
-	  uniquevelocity=Velocity[temp];
-	  fprintf(_individualFD,"%.3f\t%.3f\n",uniquedensity,uniquevelocity);
+		typedef std::vector<polygon_2d> polygon_list;
+		polygon_list v;
+		intersection(measureArea, *polygon_iterator, v);
+		if(!v.empty())
+		{
+			uniquedensity=1/(area(*polygon_iterator)*CMtoM*CMtoM);
+			uniquevelocity=Velocity[temp];
+			fprintf(_individualFD,"%.3f\t%.3f\n",uniquedensity,uniquevelocity);
+		}
+		temp++;
 	}
-      temp++;
-    }
 }
 
 double Analysis::Distance(double x1, double y1, double x2, double y2)
 {
-  double distance=sqrt(pow((x1-x2),2)+pow((y1-y2),2));
-  return distance;
+	double distance=sqrt(pow((x1-x2),2)+pow((y1-y2),2));
+	return distance;
 }
 ///---------------------------------------------------------------------------------------------------------------------
 /*this function is to obtain the frequency distribution of the pedestrian movement through a line from (Line_startX,Line_startY)
@@ -740,41 +768,41 @@ double Analysis::Distance(double x1, double y1, double x2, double y2)
  */
 void Analysis::DistributionOnLine(int *frequency,int fraction, double Line_startX,double Line_startY, double Line_endX, double Line_endY,double pt1_X, double pt1_Y,double pt2_X, double pt2_Y)
 {
-  /* in this function, we firstly calculate the intersection point between the trajectory (the line from point (pt1_X,pt1_Y)
-   *  to (pt2_X,pt2_Y)) of a pedestrian and the Line. then, we determine which part of the line he or she belongs to
-   */
-  double sumdistance=Distance(Line_startX,Line_startY,Line_endX, Line_endY);
-  double A=Line_endY-Line_startY;
-  double B=Line_startX-Line_endX;
-  double C=Line_endX*Line_startY-Line_startX*Line_endY;
-  double d1=A*pt1_X+B*pt1_Y+C;
-  double d2=A*pt2_X+B*pt2_Y+C;
-  if(d1*d2<0)
-    {
-      double x1=Line_startX;
-      double y1=Line_startY;
-      double x2=Line_endX;
-      double y2=Line_endY;
-      double x3=pt1_X;
-      double y3=pt1_Y;
-      double x4=pt2_X;
-      double y4=pt2_Y;
-      double x =((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
-	/((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
-
-      double y =((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
-	/((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
-      int index=(int)floor(Distance(x,y,x1,y1)*fraction/sumdistance);
-      frequency[index]++;
-    }
-  else if(d1*d2==0)
-    {
-      if(d1==0)
+	/* in this function, we firstly calculate the intersection point between the trajectory (the line from point (pt1_X,pt1_Y)
+	 *  to (pt2_X,pt2_Y)) of a pedestrian and the Line. then, we determine which part of the line he or she belongs to
+	 */
+	double sumdistance=Distance(Line_startX,Line_startY,Line_endX, Line_endY);
+	double A=Line_endY-Line_startY;
+	double B=Line_startX-Line_endX;
+	double C=Line_endX*Line_startY-Line_startX*Line_endY;
+	double d1=A*pt1_X+B*pt1_Y+C;
+	double d2=A*pt2_X+B*pt2_Y+C;
+	if(d1*d2<0)
 	{
-	  int index=(int)floor(Distance(Line_startX,Line_startY,pt1_X,pt1_Y)*fraction/sumdistance);
-	  frequency[index]++;
+		double x1=Line_startX;
+		double y1=Line_startY;
+		double x2=Line_endX;
+		double y2=Line_endY;
+		double x3=pt1_X;
+		double y3=pt1_Y;
+		double x4=pt2_X;
+		double y4=pt2_Y;
+		double x =((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
+							/((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
+
+		double y =((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
+							/((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
+		int index=(int)floor(Distance(x,y,x1,y1)*fraction/sumdistance);
+		frequency[index]++;
+	}
+	else if(d1*d2==0)
+	{
+		if(d1==0)
+		{
+			int index=(int)floor(Distance(Line_startX,Line_startY,pt1_X,pt1_Y)*fraction/sumdistance);
+			frequency[index]++;
+		}
 	}
-    }
 
 }
 
@@ -786,24 +814,24 @@ void Analysis::DistributionOnLine(int *frequency,int fraction, double Line_start
  */
 double Analysis::GetVoronoiDensity(vector<polygon_2d> polygon, polygon_2d measureArea)
 {
-  vector<polygon_2d>::iterator polygon_iterator;
-  double density=0;
-  for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
-    {
-      typedef std::vector<polygon_2d > polygon_list;
-      polygon_list v;
-      intersection(measureArea, *polygon_iterator, v);
-      if(!v.empty())
+	vector<polygon_2d>::iterator polygon_iterator;
+	double density=0;
+	for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
 	{
-	  density+=area(v[0])/area(*polygon_iterator);
-	  if((area(v[0])/area(*polygon_iterator))>1.00001)
-	    {
-	      std::cout<<"this is a wrong result "<<area(v[0])<<'\t'<<area(*polygon_iterator)<<"\n";
-	    }
+		typedef std::vector<polygon_2d > polygon_list;
+		polygon_list v;
+		intersection(measureArea, *polygon_iterator, v);
+		if(!v.empty())
+		{
+			density+=area(v[0])/area(*polygon_iterator);
+			if((area(v[0])/area(*polygon_iterator))>1.00001)
+			{
+				std::cout<<"this is a wrong result "<<area(v[0])<<'\t'<<area(*polygon_iterator)<<"\n";
+			}
+		}
 	}
-    }
-  density=density/(area(measureArea)*CMtoM*CMtoM);
-  return density;
+	density=density/(area(measureArea)*CMtoM*CMtoM);
+	return density;
 }
 
 //---------------------------------------------------------------------------------------------
@@ -818,40 +846,40 @@ double Analysis::GetVoronoiDensity(vector<polygon_2d> polygon, polygon_2d measur
  */
 double Analysis::GetClassicalDensity(double *xs, double *ys, int pednum, polygon_2d measureArea)
 {
-  int pedsinMeasureArea=0;
-  for(int i=0;i<pednum;i++)
-    {
-      if(within(make<point_2d>(xs[i], ys[i]), measureArea))
+	int pedsinMeasureArea=0;
+	for(int i=0;i<pednum;i++)
 	{
-	  pedsinMeasureArea++;
+		if(within(make<point_2d>(xs[i], ys[i]), measureArea))
+		{
+			pedsinMeasureArea++;
+		}
 	}
-    }
 
-  double density=pedsinMeasureArea/(area(measureArea)*CMtoM*CMtoM);
-  return density;
+	double density=pedsinMeasureArea/(area(measureArea)*CMtoM*CMtoM);
+	return density;
 }
 
 double Analysis::GetClassicalVelocity(double *xs, double *ys, double *VInFrame, int pednum, polygon_2d measureArea){
 
-  int pedsinMeasureArea=0;
-  double velocity = 0;
-  for(int i=0;i<pednum;i++)
-    {
-      if(within(make<point_2d>(xs[i], ys[i]), measureArea))
+	int pedsinMeasureArea=0;
+	double velocity = 0;
+	for(int i=0;i<pednum;i++)
 	{
-	  velocity+=VInFrame[i];
-	  pedsinMeasureArea++;
+		if(within(make<point_2d>(xs[i], ys[i]), measureArea))
+		{
+			velocity+=VInFrame[i];
+			pedsinMeasureArea++;
+		}
 	}
-    }
-  if(pedsinMeasureArea!=0)
-    {
-      velocity /= (1.0*pedsinMeasureArea);
-    }
-  else
-    {
-      velocity = 0;
-    }
-  return velocity;
+	if(pedsinMeasureArea!=0)
+	{
+		velocity /= (1.0*pedsinMeasureArea);
+	}
+	else
+	{
+		velocity = 0;
+	}
+	return velocity;
 
 }
 //---------------------------------------------------------------------------------------------
@@ -863,30 +891,30 @@ double Analysis::GetClassicalVelocity(double *xs, double *ys, double *VInFrame,
  */
 double Analysis::GetVoronoiVelocity(vector<polygon_2d> polygon, double* Velocity, polygon_2d measureArea)
 {
-  vector<polygon_2d>::iterator polygon_iterator;
-  double meanV=0;
-  int temp=0;
-
-  for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
-    {
-      typedef std::vector<polygon_2d > polygon_list;
-
-      polygon_list v;
-      //intersection_inserter<polygon_2d>(measureArea, *polygon_iterator, std::back_inserter(v));
-      intersection(measureArea, *polygon_iterator, v);
-      if(!v.empty())
+	vector<polygon_2d>::iterator polygon_iterator;
+	double meanV=0;
+	int temp=0;
+
+	for(polygon_iterator = polygon.begin(); polygon_iterator!=polygon.end();polygon_iterator++)
 	{
-	  meanV+=(Velocity[temp]*area(v[0])/area(measureArea));
-	  //std::cout<<"the velocity and areas:"<<Velocity[temp]<<'\t'<<area(v[0])<<'\t'<<meanV<<'\t'<<temp<<'\n';
-	  if((area(v[0])/area(*polygon_iterator))>1.00001)
-	    {
-	      std::cout<<"this is a wrong result"<<area(v[0])<<'\t'<<area(*polygon_iterator);
-	    }
+		typedef std::vector<polygon_2d > polygon_list;
+
+		polygon_list v;
+		//intersection_inserter<polygon_2d>(measureArea, *polygon_iterator, std::back_inserter(v));
+		intersection(measureArea, *polygon_iterator, v);
+		if(!v.empty())
+		{
+			meanV+=(Velocity[temp]*area(v[0])/area(measureArea));
+			//std::cout<<"the velocity and areas:"<<Velocity[temp]<<'\t'<<area(v[0])<<'\t'<<meanV<<'\t'<<temp<<'\n';
+			if((area(v[0])/area(*polygon_iterator))>1.00001)
+			{
+				std::cout<<"this is a wrong result"<<area(v[0])<<'\t'<<area(*polygon_iterator);
+			}
+		}
+		temp++;
 	}
-      temp++;
-    }
 
-  return meanV;
+	return meanV;
 }
 
 /*
@@ -896,138 +924,163 @@ double Analysis::GetVoronoiVelocity(vector<polygon_2d> polygon, double* Velocity
 //double Analysis::GetVinFrame(int Tnow,int Tpast, int Tfuture, int Tfirst, int Tlast, double Xcor_past, double Xcor_now, double Xcor_future,double Ycor_past, double Ycor_now, double Ycor_future, char VComponent){
 double Analysis::GetVinFrame(int Tnow,int Tpast, int Tfuture, int ID, int *Tfirst, int *Tlast, double **Xcor, double **Ycor, char VComponent){
 
-  double v=0;
-  //VInFrame[i] = GetVinFrame(f, Tpast, Tfuture, _firstFrame[ID], _lastFrame[ID], _xCor[ID][Tpast], _xCor[ID][f], _xCor[ID][Tfuture], _yCor[ID][Tpast], _yCor[ID][f], _yCor[ID][Tfuture], _vComponent);
+	double v=0;
+	//VInFrame[i] = GetVinFrame(f, Tpast, Tfuture, _firstFrame[ID], _lastFrame[ID], _xCor[ID][Tpast], _xCor[ID][f], _xCor[ID][Tfuture], _yCor[ID][Tpast], _yCor[ID][f], _yCor[ID][Tfuture], _vComponent);
 
-  if(VComponent == 'X')
-    {
-      if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+	if(VComponent == 'X')
 	{
-	  v = _fps*CMtoM*(Xcor[ID][Tfuture] - Xcor[ID][Tpast])/(2.0 * _deltaF);  //one dimensional velocity
-	}
-      else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
-	{
-	  v = _fps*CMtoM*(Xcor[ID][Tfuture] - Xcor[ID][Tnow])/(_deltaF);  //one dimensional velocity
+		if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Xcor[ID][Tfuture] - Xcor[ID][Tpast])/(2.0 * _deltaF);  //one dimensional velocity
+		}
+		else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Xcor[ID][Tfuture] - Xcor[ID][Tnow])/(_deltaF);  //one dimensional velocity
+		}
+		else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Xcor[ID][Tnow] - Xcor[ID][Tpast])/( _deltaF);  //one dimensional velocity
+		}
 	}
-      else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+	if(VComponent == 'Y')
 	{
-	  v = _fps*CMtoM*(Xcor[ID][Tnow] - Xcor[ID][Tpast])/( _deltaF);  //one dimensional velocity
+		if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Ycor[ID][Tfuture] - Ycor[ID][Tpast])/(2.0 * _deltaF);  //one dimensional velocity
+		}
+		else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Ycor[ID][Tfuture] - Ycor[ID][Tnow])/(_deltaF);  //one dimensional velocity
+		}
+		else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+		{
+			v = _fps*CMtoM*(Ycor[ID][Tnow] - Ycor[ID][Tpast])/( _deltaF);  //one dimensional velocity
+		}
 	}
-    }
-  if(VComponent == 'Y')
-    {
-      if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+	if(VComponent == 'B')
 	{
-	  v = _fps*CMtoM*(Ycor[ID][Tfuture] - Ycor[ID][Tpast])/(2.0 * _deltaF);  //one dimensional velocity
+		if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tfuture] - Xcor[ID][Tpast]),2)+pow((Ycor[ID][Tfuture] - Ycor[ID][Tpast]),2))/(2.0 * _deltaF);  //two dimensional velocity
+		}
+		else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+		{
+			v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tfuture] - Xcor[ID][Tnow]),2)+pow((Ycor[ID][Tfuture] - Ycor[ID][Tnow]),2))/(_deltaF);
+		}
+		else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+		{
+			v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tnow] - Xcor[ID][Tpast]),2)+pow((Ycor[ID][Tnow] - Ycor[ID][Tpast]),2))/(_deltaF);  //two dimensional velocity
+		}
 	}
-      else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+
+	v = fabs(v);
+	return v;
+}
+
+void Analysis::GetProfiles(string frameId, vector<polygon_2d> polygons, double * velocity)
+{
+	string Prfvelocity="Fundamental_Diagram/Classical_Voronoi/field/velocity/Prf_v_"+_trajectoryName+"_"+frameId+".dat";
+	string Prfdensity="Fundamental_Diagram/Classical_Voronoi/field/density/Prf_d_"+_trajectoryName+"_"+frameId+".dat";
+
+	FILE *Prf_velocity;
+	if((Prf_velocity=CreateFile(Prfvelocity))==NULL)
 	{
-	  v = _fps*CMtoM*(Ycor[ID][Tfuture] - Ycor[ID][Tnow])/(_deltaF);  //one dimensional velocity
+		Log->Write("cannot open the file <%s> to write the field data\n",Prfvelocity.c_str());
+		exit(0);
 	}
-      else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+	FILE *Prf_density;
+	if((Prf_density=CreateFile(Prfdensity))==NULL)
 	{
-	  v = _fps*CMtoM*(Ycor[ID][Tnow] - Ycor[ID][Tpast])/( _deltaF);  //one dimensional velocity
+		Log->Write("cannot open the file to write the field density\n");
+		exit(0);
 	}
-    }
-  if(VComponent == 'B')
-    {
-      if((Tpast >=Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+
+	int NRow = (int)ceil((_highVertexY-_lowVertexY)/_scaleY); // the number of rows that the geometry will be discretized for field analysis
+	int NColumn = (int)ceil((_highVertexX-_lowVertexX)/_scaleX); //the number of columns that the geometry will be discretized for field analysis
+	for(int row_i=0;row_i<NRow;row_i++) //
 	{
-	  v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tfuture] - Xcor[ID][Tpast]),2)+pow((Ycor[ID][Tfuture] - Ycor[ID][Tpast]),2))/(2.0 * _deltaF);  //two dimensional velocity
+		for(int colum_j=0;colum_j<NColumn;colum_j++)
+		{
+			polygon_2d measurezoneXY;
+			{
+				const double coor[][2] = {
+						{_lowVertexX+colum_j*_scaleX,_lowVertexY+row_i*_scaleY}, {_lowVertexX+colum_j*_scaleX+_scaleX,_lowVertexY+row_i*_scaleY}, {_lowVertexX+colum_j*_scaleX+_scaleX, _lowVertexY+row_i*_scaleY+_scaleY},
+						{_lowVertexX+colum_j*_scaleX, _lowVertexY+row_i*_scaleY+_scaleY},
+						{_lowVertexX+colum_j*_scaleX,_lowVertexY+row_i*_scaleY} // closing point is opening point
+				};
+				assign_points(measurezoneXY, coor);
+			}
+			correct(measurezoneXY);     // Polygons should be closed, and directed clockwise. If you're not sure if that is the case, call this function
+			double densityXY=GetVoronoiDensity(polygons,measurezoneXY);
+			fprintf(Prf_density,"%.3f\t",densityXY);
+			double velocityXY = GetVoronoiVelocity(polygons,velocity,measurezoneXY);
+			fprintf(Prf_velocity,"%.3f\t",velocityXY);
+		}
+		fprintf(Prf_density,"\n");
+		fprintf(Prf_velocity,"\n");
 	}
-      else if((Tpast <Tfirst[ID])&&(Tfuture <= Tlast[ID]))
+	fclose(Prf_velocity);
+	fclose(Prf_density);
+}
+
+void Analysis::OutputVoroGraph(string frameId, vector<polygon_2d> polygons, int numPedsInFrame, double* XInFrame, double* YInFrame,double* VInFrame)
+{
+	string point="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/points"+_trajectoryName+"_"+frameId+".dat";
+	string polygon="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/polygon"+_trajectoryName+"_"+frameId+".dat";
+	string v_individual="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/speed"+_trajectoryName+"_"+frameId+".dat";
+
+	ofstream points (point.c_str());
+	ofstream polys (polygon.c_str());
+	ofstream velo (v_individual.c_str());
+
+	for(vector<polygon_2d>::iterator polygon_iterator=polygons.begin(); polygon_iterator!=polygons.end();polygon_iterator++)
 	{
-	  v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tfuture] - Xcor[ID][Tnow]),2)+pow((Ycor[ID][Tfuture] - Ycor[ID][Tnow]),2))/(_deltaF);
+		polys << dsv(*polygon_iterator) << endl;
 	}
-      else if((Tpast >=Tfirst[ID])&&(Tfuture > Tlast[ID]))
+	for(int pts=0;pts<numPedsInFrame;pts++)
 	{
-	  v = _fps*CMtoM*sqrt(pow((Xcor[ID][Tnow] - Xcor[ID][Tpast]),2)+pow((Ycor[ID][Tnow] - Ycor[ID][Tpast]),2))/(_deltaF);  //two dimensional velocity
+		points << XInFrame[pts] << "\t" << YInFrame[pts] << endl;
+		velo << fabs(VInFrame[pts]) << endl;
 	}
-    }
-
-  v = fabs(v);
-  return v;
+	points.close();
+	polys.close();
+	velo.close();
 }
 
-void Analysis::GetProfiles(string frameId, vector<polygon_2d> polygons, double * velocity)
-{
-  //std::string buffer(frameId);
-#ifdef WIN32
-  string Prfvelocity="Fundamental_Diagram\\Classical_Voronoi\\Profile\\velocity\\Prf_v_"+_trajectoryName+"_"+frameId+".dat";
-  string Prfdensity= "Fundamental_Diagram\\Classical_Voronoi\\Profile\\density\\Prf_d_"+_trajectoryName+"_"+frameId+".dat";
-#else
-  string Prfvelocity="Fundamental_Diagram/Classical_Voronoi/field/velocity/Prf_v_"+_trajectoryName+"_"+frameId+".dat";
-  string Prfdensity="Fundamental_Diagram/Classical_Voronoi/field/density/Prf_d_"+_trajectoryName+"_"+frameId+".dat";
-#endif
-  FILE *Prf_velocity;
-  if((Prf_velocity=fopen(Prfvelocity.c_str(),"w"))==NULL)
-    {
-      Log->Write("cannot open the file <%s> to write the field data\n",Prfvelocity.c_str());
-      exit(0);
-    }
-  FILE *Prf_density;
-  if((Prf_density=fopen(Prfdensity.c_str(),"w"))==NULL)
-    {
-      Log->Write("cannot open the file to write the field density\n");
-      exit(0);
-    }
+FILE* Analysis::CreateFile(const string& filename){
+	//first try to create the file
+	FILE* fHandle= fopen(filename.c_str(),"w");
+	if(fHandle) return fHandle;
 
-  int NRow = (int)ceil((_highVertexY-_lowVertexY)/_scaleY); // the number of rows that the geometry will be discretized for field analysis
-  int NColumn = (int)ceil((_highVertexX-_lowVertexX)/_scaleX); //the number of columns that the geometry will be discretized for field analysis
-  for(int row_i=0;row_i<NRow;row_i++) //
-    {
-      for(int colum_j=0;colum_j<NColumn;colum_j++)
-	{
-	  polygon_2d measurezoneXY;
-	  {
-	    const double coor[][2] = {
-	      {_lowVertexX+colum_j*_scaleX,_lowVertexY+row_i*_scaleY}, {_lowVertexX+colum_j*_scaleX+_scaleX,_lowVertexY+row_i*_scaleY}, {_lowVertexX+colum_j*_scaleX+_scaleX, _lowVertexY+row_i*_scaleY+_scaleY},
-	      {_lowVertexX+colum_j*_scaleX, _lowVertexY+row_i*_scaleY+_scaleY},
-	      {_lowVertexX+colum_j*_scaleX,_lowVertexY+row_i*_scaleY} // closing point is opening point
-	    };
-	    assign_points(measurezoneXY, coor);
-	  }
-	  correct(measurezoneXY);     // Polygons should be closed, and directed clockwise. If you're not sure if that is the case, call this function
-	  double densityXY=GetVoronoiDensity(polygons,measurezoneXY);
-	  fprintf(Prf_density,"%.3f\t",densityXY);
-	  double velocityXY = GetVoronoiVelocity(polygons,velocity,measurezoneXY);
-	  fprintf(Prf_velocity,"%.3f\t",velocityXY);
+	unsigned int found=filename.find_last_of("/\\");
+	string dir = filename.substr(0,found)+"/";
+	string file= filename.substr(found+1);
+
+	// the directories are probably missing, create it
+	if (mkpath(dir.c_str())==-1) {
+		Log->Write("ERROR:\tcannot create the directory <%s>",dir.c_str());
+		return NULL;
 	}
-      fprintf(Prf_density,"\n");
-      fprintf(Prf_velocity,"\n");
-    }
-  fclose(Prf_velocity);
-  fclose(Prf_density);
+	//second and last attempt
+	return fopen(filename.c_str(),"w");
 }
 
-void Analysis::OutputVoroGraph(string frameId, vector<polygon_2d> polygons, int numPedsInFrame, double* XInFrame, double* YInFrame,double* VInFrame)
-{
-#ifdef WIN32
-  string point="Output\\Fundamental_Diagram\\Classical_Voronoi\\VoronoiCell\\points"+_trajectoryName+"_"+frameId+".dat";
-  string polygon="Output\\Fundamental_Diagram\\Classical_Voronoi\\VoronoiCell\\polygon"+_trajectoryName+"_"+frameId+".dat";
-  //string point="points"+_trajectoryName+"_"+frameId+".dat";
-  //string polygon="polygon"+_trajectoryName+"_"+frameId+".dat";
-  string v_individual="Output\\Fundamental_Diagram\\Classical_Voronoi\\VoronoiCell\\speed"+_trajectoryName+"_"+frameId+".dat";
+
+int Analysis::mkpath(const char* file_path, mode_t mode) {
+  assert(file_path && *file_path);
+  char* p;
+  for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) {
+    *p='\0';
+
+#ifdef __linux__
+    if (_mkdir(file_path, mode)==-1) {
 #else
-  string point="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/points"+_trajectoryName+"_"+frameId+".dat";
-  string polygon="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/polygon"+_trajectoryName+"_"+frameId+".dat";
-  string v_individual="Fundamental_Diagram/Classical_Voronoi/VoronoiCell/speed"+_trajectoryName+"_"+frameId+".dat";
+    if (_mkdir(file_path)==-1) {
 #endif
 
-  ofstream points (point.c_str());
-  ofstream polys (polygon.c_str());
-  ofstream velo (v_individual.c_str());
-
-  for(vector<polygon_2d>::iterator polygon_iterator=polygons.begin(); polygon_iterator!=polygons.end();polygon_iterator++)
-    {
-      polys << dsv(*polygon_iterator) << endl;
-    }
-  for(int pts=0;pts<numPedsInFrame;pts++)
-    {
-      points << XInFrame[pts] << "\t" << YInFrame[pts] << endl;
-      velo << fabs(VInFrame[pts]) << endl;
+      if (errno!=EEXIST) { *p='/'; return -1; }
     }
-  points.close();
-  polys.close();
-  velo.close();
+    *p='/';
+  }
+  return 0;
 }
diff --git a/Analysis.h b/Analysis.h
index 21643b5ecdc2ccbee95fcff6facac600238d797a..319c1f4ea76e2e01a7116df9f3a62ad0bee4c3e7 100644
--- a/Analysis.h
+++ b/Analysis.h
@@ -1,24 +1,3 @@
-/*Simulation.h:
-  The Simulation class represents a simulation of pedestrians
-  based on a certain model in a specific scenario. A simulation is defined by
-  various parameters and functions.
-  Copyright (C) <2009-2010>  <Jonas Mehlich and Mohcine Chraibi>
-
-  This file is part of OpenPedSim.
-
-  OpenPedSim is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  any later version.
-
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  OpenPedSim is distributed in the hope that it will be useful,
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with Foobar. If not, see <http://www.gnu.org/licenses/>.
- */
 
 #ifndef ANALYSIS_H_
 #define ANALYSIS_H_
@@ -55,7 +34,7 @@ private:
 	polygon_2d _geoPoly;
 	polygon_2d _measureZone;
 	string _trajectoryName;
-	string _trajectoryFile;
+	string _trajectoriesLocation;
 
 	int _numFrames; // how much frames
 	int *_tIn;   //the time for each pedestrian enter the measurement area
@@ -106,6 +85,11 @@ private:
 	void GetProfiles(string frameId, vector<polygon_2d> polygons, double * velocity);
 	void OutputVoroGraph(string frameId, vector<polygon_2d> polygons, int numPedsInFrame, double* XInFrame, double* YInFrame,double* VInFrame);
 	void DistributionOnLine(int *frequency,int fraction, double Line_startX,double Line_startY, double Line_endX, double Line_endY,double pt1_X, double pt1_Y,double pt2_X, double pt2_Y);
+
+	//create a file and the directory structure if needed.
+	FILE* CreateFile(const string& filename);
+	int mkpath(const char* file_path, mode_t mode=0755);
+
 public:
 
 	Analysis();
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 062685c7e910fa27579bf68c70d112a4144582e0..929668982a10b0b559b67f3cc956db8f49ef4d88 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,18 +15,18 @@ INCLUDE_DIRECTORIES("./")
 file(
 	GLOB_RECURSE
 	source_files
-        Analysis.cpp  
-        main.cpp  
-        VoronoiDiagram.cpp  
-        VoronoiDiagramGenerator.cpp   
-        VoronoiPolygons.cpp
-
+	Analysis.cpp
+	main.cpp
+	VoronoiDiagram.cpp
+	VoronoiDiagramGenerator.cpp
+	VoronoiPolygons.cpp
 	IO/IODispatcher.cpp
 	IO/OutputHandler.cpp
-
 	general/ArgumentParser.cpp
-	general/xmlParser.cpp
-		
+	tinyxml/tinystr.cpp
+	tinyxml/tinyxml.cpp
+	tinyxml/tinyxmlerror.cpp
+	tinyxml/tinyxmlparser.cpp
 	geometry/Building.cpp  
 	geometry/Line.cpp      
 	geometry/Point.cpp    
@@ -39,21 +39,17 @@ file(
 	geometry/Obstacle.cpp  
 	geometry/SubRoom.cpp
 
-
-
 	header_files:
-        Analysis.h  
-        VoronoiDiagramGenerator.h  
-        VoronoiDiagram.h  
-        VoronoiPolygons.h
-
+	Analysis.h  
+	VoronoiDiagramGenerator.h  
+	VoronoiDiagram.h  
+	VoronoiPolygons.h
 	IO/IODispatcher.h
 	IO/OutputHandler.h
-
 	general/ArgumentParser.h
-	general/xmlParser.h	
+	tinyxml/tinyxml.h
+	tinyxml/tinystr.h
 	general/Macros.h
-
 	geometry/Building.h  
 	geometry/Line.h      
 	geometry/Point.h    
diff --git a/general/ArgumentParser.cpp b/general/ArgumentParser.cpp
index a9fc4067d06e402aa0ed34014a3ecbe5f988bfac..cbaf4c71316242597bef1dfc6f34ffe01af08b4d 100644
--- a/general/ArgumentParser.cpp
+++ b/general/ArgumentParser.cpp
@@ -11,7 +11,7 @@
 #include <omp.h>
 #endif
 
-#include "../general/xmlParser.h"
+#include "../tinyxml/tinyxml.h"
 #include "../IO/OutputHandler.h"
 #include "ArgumentParser.h"
 
@@ -21,7 +21,7 @@ void ArgumentParser::Usage() {
 
 	Log->Write("Usage: \n");
 	Log->Write("\tJPSreport.exe --inifile=input.xml\n");
-/*
+	/*
 	fprintf(stderr,
 			"Usage: program options\n\n"
 			"With the following options (default values in parenthesis):\n\n"
@@ -114,7 +114,7 @@ void ArgumentParser::Usage() {
 			"\n");
 
 
-*/
+	 */
 	exit(EXIT_SUCCESS);
 }
 
@@ -146,6 +146,8 @@ ArgumentParser::ArgumentParser() {
 	_errorLogFile="./Logfile.dat";
 	_log=1; //no output wanted
 	pFormat=FORMAT_XML_PLAIN;
+	_trajectoriesLocation="";
+	_trajectoriesFilename="";
 }
 
 
@@ -169,25 +171,25 @@ void ArgumentParser::ParseArgs(int argc, char **argv) {
 
 		switch (c) {
 
-			case 'q':
-			{
-				string inifile="input.xml";
-				if (optarg)
-					inifile=optarg;
-				Log->Write("INFO: \t Loading initialization file <"+inifile+">");
-				ParseIniFile(inifile);
-			}
-			break;
+		case 'q':
+		{
+			string inifile="input.xml";
+			if (optarg)
+				inifile=optarg;
+			Log->Write("INFO: \t Loading initialization file <"+inifile+">");
+			ParseIniFile(inifile);
+		}
+		break;
 
-			case 'h':
-				Usage();
-				break;
-			default:
-			{
-				Log->Write("ERROR: \tin ArgumentParser::ParseArgs() "
-						"wrong program options!!!\n");
-				Usage();
-			}
+		case 'h':
+			Usage();
+			break;
+		default:
+		{
+			Log->Write("ERROR: \tin ArgumentParser::ParseArgs() "
+					"wrong program options!!!\n");
+			Usage();
+		}
 		}
 	}
 }
@@ -195,119 +197,130 @@ void ArgumentParser::ParseArgs(int argc, char **argv) {
 
 void ArgumentParser::ParseIniFile(string inifile){
 
-	XMLNode xMainNode=XMLNode::openFileHelper(inifile.c_str(),"JPSreport");
-
 	Log->Write("INFO: \tParsing the ini file");
 	//I just assume all parameters are present
 
+	TiXmlDocument doc(inifile);
+	if (!doc.LoadFile()){
+		Log->Write("ERROR: \t%s", doc.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the ini file");
+		exit(EXIT_FAILURE);
+	}
+
+	// everything is fine. proceed with parsing
+
+	TiXmlElement* xMainNode = doc.RootElement();
+	if( ! xMainNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
+
+	if( xMainNode->ValueStr () != "JPSreport" ) {
+		Log->Write("ERROR:\tRoot element value is not 'JPSreport'.");
+		exit(EXIT_FAILURE);
+	}
+
 	//geometry
-	XMLNode xGeometry = xMainNode.getChildNode("Geometry");
-	if(!xGeometry.isEmpty()){
-		string geometry = xmltoa(xGeometry.getAttribute("file"));
-		_geometryFileName =geometry.c_str();
-		Log->Write("INFO: \tgeometry  <"+geometry+">");
+	if(xMainNode->FirstChild("geometry")){
+		_geometryFileName=xMainNode->FirstChildElement("geometry")->Attribute("file");
+		Log->Write("INFO: \tgeometry <"+_geometryFileName+">");
 	}
 
 	//trajectories
-	XMLNode xTrajectories=xMainNode.getChildNode("Trajectories");
-	if(!xTrajectories.isEmpty()){
+	TiXmlNode* xTrajectories=xMainNode->FirstChild("trajectories");
+	if(xTrajectories){
+		//a file descriptor was given
+		if(xTrajectories->FirstChild("file")){
+			if(xTrajectories->FirstChildElement("file"))
+				_trajectoriesFilename = xTrajectories->FirstChildElement("file")->Attribute("name");
 
-/*		pfps = xmltof(xTrajectories.getAttribute("fps"),pfps);
-		string format=xmltoa(xTrajectories.getAttribute("format"),"xml-plain");
-		if(format=="xml-plain") pFormat=FORMAT_XML_PLAIN;
-		if(format=="xml-bin") pFormat=FORMAT_XML_BIN;
-		if(format=="plain") pFormat=FORMAT_PLAIN;
-		if(format=="vtk") pFormat=FORMAT_VTK;*/
+			if(xTrajectories->FirstChildElement("path"))
+				_trajectoriesLocation = xTrajectories->FirstChildElement("path")->Attribute("location");
 
-		//a file descriptor was given
-			_trajectoryName =
-					xmltoa(
-						xTrajectories.getChildNode(
-								"file").getAttribute("name"), _trajectoryName.c_str());
-			string trajectoriesfile =
-					xmltoa(
-						xTrajectories.getChildNode(
-								"path").getAttribute("location"))+ string(_trajectoryName)+".xml";
-			_trajectoryFile = trajectoriesfile.c_str();
-
-		Log->Write("INFO: \ttrajectory file  <" + _trajectoryFile+">");
+			Log->Write("INFO: \tinput file  <"+ (_trajectoriesFilename)+">");
+			Log->Write("INFO: \tinput dir  <"+ (_trajectoriesLocation)+">");
+		}
 	}
 
 	//measurement area
-	XMLNode xMeasurementArea=xMainNode.getChildNode("MeasurementAreas");
-	if(!xMeasurementArea.isEmpty()){
-		if(!xMeasurementArea.getChildNode("Area_B").isEmpty())
+	if(xMainNode->FirstChild("measurementAreas")){
+
+		string unit = xMainNode->FirstChildElement("measurementAreas")->Attribute("unit");
+
+		if(unit!="cm"){
+			Log->Write("WARNING: \tonly <cm> unit is supported. Convert your units.");
+			exit(EXIT_FAILURE);
+		}
+
+		TiXmlNode* xMeasurementArea_B=xMainNode->FirstChild("measurementAreas")->FirstChild("area_B");
+		if(xMeasurementArea_B)
 		{
-			_measureAreaId =
-							xmltoa(
-									xMeasurementArea.getChildNode(
-											"Area_B").getAttribute("id"));
-			string pMeasureAreaType =
-							xmltoa(
-									xMeasurementArea.getChildNode(
-											"Area_B").getAttribute("type"));
-			XMLNode xBox = xMeasurementArea.getChildNode("Area_B");
-			const char* box_p1x = xmltoa(xBox.getChildNode("p1").getAttribute("x"));
-			const char* box_p1y = xmltoa(xBox.getChildNode("p1").getAttribute("y"));
-			const char* box_p2x = xmltoa(xBox.getChildNode("p2").getAttribute("x"));
-			const char* box_p2y = xmltoa(xBox.getChildNode("p2").getAttribute("y"));
-			const char* box_p3x = xmltoa(xBox.getChildNode("p3").getAttribute("x"));
-			const char* box_p3y = xmltoa(xBox.getChildNode("p3").getAttribute("y"));
-			const char* box_p4x = xmltoa(xBox.getChildNode("p4").getAttribute("x"));
-			const char* box_p4y = xmltoa(xBox.getChildNode("p4").getAttribute("y"));
-			//-------------the following codes define measurement area-------------------------------------
-		    polygon_2d poly;
-		    {
-		        const double coor[][2] = {
-		            {atof(box_p1x),atof(box_p1y)}, {atof(box_p2x),atof(box_p2y)}, {atof(box_p3x),atof(box_p3y)}, {atof(box_p4x),atof(box_p4y)},
-		            {atof(box_p1x),atof(box_p1y)} // closing point is opening point
-		            };
-		        assign_points(poly, coor);
-		        correct(poly);     // Polygons should be closed, and directed clockwise. If you're not sure if that is the case, call this function
-		    }
-		    _measureArea = poly;
-
-
-			string MovingDire_start = xmltoa(xBox.getChildNode("MovingDirection").getAttribute("start"));
-			string MovingDire_end = xmltoa(xBox.getChildNode("MovingDirection").getAttribute("end"));
-			double start_x = atof(xmltoa(xBox.getChildNode(MovingDire_start.c_str()).getAttribute("x")));
-			double start_y = atof(xmltoa(xBox.getChildNode(MovingDire_start.c_str()).getAttribute("y")));
-			double end_x = atof(xmltoa(xBox.getChildNode(MovingDire_end.c_str()).getAttribute("x")));
-			double end_y = atof(xmltoa(xBox.getChildNode(MovingDire_end.c_str()).getAttribute("y")));
+			_measureAreaId =xMeasurementArea_B->ToElement()->Attribute("id");
+			//FIXME: you never used this variable
+			string pMeasureAreaType = xMeasurementArea_B->ToElement()->Attribute("type");
+
+			double box_p1x = xmltof(xMeasurementArea_B->FirstChildElement("p1")->Attribute("x"));
+			double box_p1y = xmltof(xMeasurementArea_B->FirstChildElement("p1")->Attribute("y"));
+			double box_p2x = xmltof(xMeasurementArea_B->FirstChildElement("p2")->Attribute("x"));
+			double box_p2y = xmltof(xMeasurementArea_B->FirstChildElement("p2")->Attribute("y"));
+			double box_p3x = xmltof(xMeasurementArea_B->FirstChildElement("p3")->Attribute("x"));
+			double box_p3y = xmltof(xMeasurementArea_B->FirstChildElement("p3")->Attribute("y"));
+			double box_p4x = xmltof(xMeasurementArea_B->FirstChildElement("p4")->Attribute("x"));
+			double box_p4y = xmltof(xMeasurementArea_B->FirstChildElement("p4")->Attribute("y"));
+
+			//-------------the following codes define measurement area---------------------------
+			// Polygons should be closed, and directed clockwise.
+			// If you're not sure if that is the case, call the function correct
+			polygon_2d poly;
+			const double coor[][2] = {
+					{box_p1x,box_p1y}, {box_p2x,box_p2y}, {box_p3x,box_p3y}, {box_p4x,box_p4y},
+					{box_p1x,box_p1y} // closing point is opening point
+			};
+
+			assign_points(poly, coor);
+			correct(poly); // in the case the Polygone is not closed
+
+			_measureArea = poly;
+
+			string MovingDire_start = xMeasurementArea_B->FirstChildElement("movingDirection")->Attribute("start");
+			string MovingDire_end   = xMeasurementArea_B->FirstChildElement("movingDirection")->Attribute("end");
+			double start_x = xmltof(xMeasurementArea_B->FirstChildElement(MovingDire_start.c_str())->Attribute("x"));
+			double start_y = xmltof(xMeasurementArea_B->FirstChildElement(MovingDire_start.c_str())->Attribute("y"));
+			double end_x   = xmltof(xMeasurementArea_B->FirstChildElement(MovingDire_end.c_str())->Attribute("x"));
+			double end_y   = xmltof(xMeasurementArea_B->FirstChildElement(MovingDire_end.c_str())->Attribute("y"));
 
 			_lengthMeasureArea = sqrt(pow((start_x-end_x),2)+pow((start_y-end_y),2));
 
 			Log->Write("INFO: \tmeasure area id  <"+_measureAreaId+">");
 			Log->Write("INFO: \tmeasure area type  <"+pMeasureAreaType+">");
-			Log->Write("INFO: \tp1 of Box  <"+string(box_p1x)+','+string(box_p1y)+">");
-			cout<<"INFO: \tlength of measurement area is:  <" << _lengthMeasureArea<<">"<<endl;
+			Log->Write("INFO: \tp1 of Box  < %f, %f>",box_p1x,box_p1y);
+			Log->Write("INFO: \tlength of measurement area is:  < %f>", _lengthMeasureArea);
 		}
-		if(!xMeasurementArea.getChildNode("Area_L").isEmpty())
+
+		TiXmlNode* xMeasurementArea_L=xMainNode->FirstChild("measurementAreas")->FirstChild("area_L");
+		if(xMeasurementArea_L)
 		{
-			_measureAreaId = xmltoa(xMeasurementArea.getChildNode("Area_L").getAttribute("id"));
-			string pMeasureAreaType = xmltoa(xMeasurementArea.getChildNode("Area_L").getAttribute("type"));
-			XMLNode xLine = xMeasurementArea.getChildNode("Area_L");
-			string line_startx = xmltoa(xLine.getChildNode("Start").getAttribute("x"));
-			string line_starty = xmltoa(xLine.getChildNode("Start").getAttribute("y"));
-			string line_endx = xmltoa(xLine.getChildNode("End").getAttribute("x"));
-			string line_endy = xmltoa(xLine.getChildNode("End").getAttribute("y"));
-
-			_lineStartX = atof(line_startx.c_str());
-			_lineStartY = atof(line_starty.c_str());
-			_lineEndX = atof(line_endx.c_str());
-			_lineEndY = atof(line_endy.c_str());
+			//fixme: this value overwrite the previous one vom area_B
+			_measureAreaId =xMeasurementArea_L->ToElement()->Attribute("id");
+			string pMeasureAreaType = xMeasurementArea_L->ToElement()->Attribute("type");
+
+			_lineStartX = xmltof(xMeasurementArea_L->FirstChildElement("start")->Attribute("x"));
+			_lineStartY =xmltof(xMeasurementArea_L->FirstChildElement("start")->Attribute("y"));
+			_lineEndX = xmltof(xMeasurementArea_L->FirstChildElement("end")->Attribute("x"));
+			_lineEndY =xmltof(xMeasurementArea_L->FirstChildElement("end")->Attribute("y"));
 
 			Log->Write("INFO: \tmeasure area id  <"+_measureAreaId+">" + "\t<"+pMeasureAreaType+">");
-			Log->Write("INFO: \treference line starts from  <"+line_startx+","+line_starty+">" +" to  <"+line_endx+","+line_endy+">" );
+			Log->Write("INFO: \treference line starts from  <%f, %f> to <%f, %f>",_lineStartX,_lineStartY,_lineEndX,_lineEndY);
 		}
 	}
 
 	//instantaneous velocity
-	XMLNode xVelocity=xMainNode.getChildNode("Velocity");
-	if(!xVelocity.isEmpty()){
-		string UseXComponent = string(xVelocity.getChildNode("UseXComponent").getText());
-		string UseYComponent = string(xVelocity.getChildNode("UseYComponent").getText());
-		string HalfFrameNumberToUse = string(xVelocity.getChildNode("HalfFrameNumberToUse").getText());
+	TiXmlNode* xVelocity=xMainNode->FirstChild("velocity");
+	if(xVelocity){
+		string UseXComponent = xVelocity->FirstChildElement("useXComponent")->GetText();
+		string UseYComponent = xVelocity->FirstChildElement("useYComponent")->GetText();
+		string HalfFrameNumberToUse = xVelocity->FirstChildElement("halfFrameNumberToUse")->GetText();
+
 		_delatTVInst = atof(HalfFrameNumberToUse.c_str());
 		if(UseXComponent == "true"&&UseYComponent == "false"){
 			_vComponent = 'X';
@@ -323,73 +336,72 @@ void ArgumentParser::ParseIniFile(string inifile){
 		}
 		else{
 			Log->Write("INFO: \ttype of velocity is not selected, please check it !!! " );
-			exit(0) ;
+			exit(EXIT_FAILURE) ;
 		}
 	}
 
 	// method A
-	XMLNode xMethod_A=xMainNode.getChildNode("Method_A");
-	if(string(xMethod_A.getAttribute("enabled"))=="true"){
-		const char* TimeInterval_A = xMethod_A.getChildNode("TimeInterval").getText();
-		_measureAreaId = xmltoa(xMeasurementArea.getChildNode("MeasurementArea").getAttribute("id"));
-		_isMethodA = true;
-		_timeIntervalA = atoi(TimeInterval_A);
-		Log->Write("INFO: \tMethod A is selected" );
-		Log->Write("INFO: \ttime interval used in Method A is <"+string(TimeInterval_A)+" frames>" );
+	TiXmlElement* xMethod_A=xMainNode->FirstChildElement("method_A");
+	if(xMethod_A){
+		if(string(xMethod_A->Attribute("enabled"))=="true"){
+			_timeIntervalA = xmltoi(xMethod_A->FirstChildElement("timeInterval")->GetText());
+			_measureAreaId = xMethod_A->FirstChildElement("measurementArea")->Attribute("id");
+			_isMethodA = true;
+			Log->Write("INFO: \tMethod A is selected" );
+			Log->Write("INFO: \ttime interval used in Method A is < %d>",_timeIntervalA);
+		}
 	}
 
 	// method B
-	XMLNode xMethod_B=xMainNode.getChildNode("Method_B");
-	if(string(xMethod_B.getAttribute("enabled"))=="true"){
+	TiXmlElement* xMethod_B=xMainNode->FirstChildElement("method_B");
+	if(string(xMethod_B->Attribute("enabled"))=="true"){
 		_isMethodB = true;
-		_measureAreaId = xmltoa(xMeasurementArea.getChildNode("MeasurementArea").getAttribute("id"));
+		//FIXME> this value is overwritten
+		_measureAreaId = xMethod_A->FirstChildElement("measurementArea")->Attribute("id");
 		Log->Write("INFO: \tMethod B is selected" );
 	}
 
 	// method C
-	XMLNode xMethod_C=xMainNode.getChildNode("Method_C");
-	if(string(xMethod_C.getAttribute("enabled"))=="true"){
+	TiXmlElement* xMethod_C=xMainNode->FirstChildElement("method_C");
+	if(string(xMethod_C->Attribute("enabled"))=="true"){
 		_isMethodC = true;
-		_measureAreaId = xmltoa(xMeasurementArea.getChildNode("MeasurementArea").getAttribute("id"));
+		_measureAreaId = xMethod_C->FirstChildElement("measurementArea")->Attribute("id");
 		Log->Write("INFO: \tMethod C is selected" );
 	}
 
-
 	// method D
-	XMLNode xMethod_D=xMainNode.getChildNode("Method_D");
-	if(string(xMethod_D.getAttribute("enabled"))=="true"){
+	TiXmlElement* xMethod_D=xMainNode->FirstChildElement("method_D");
+	if(string(xMethod_D->Attribute("enabled"))=="true"){
 		_isMethodD = true;
-		string xIsCutByCircle = string(xMethod_D.getAttribute("cutbycircle")) ;
-		_isCutByCircle = (xIsCutByCircle == "true") ? true: false;
-		string xIsOutputGraph = string(xMethod_D.getAttribute("IsOutputGraph"));
-		_isOutputGraph =  (xIsOutputGraph == "true") ? true: false;
+		_isCutByCircle = (string(xMethod_D->Attribute("cutByCircle")) == "true");
+		_isOutputGraph =  (string(xMethod_D->Attribute("outputGraph")) == "true");
 		if(_isOutputGraph)
 		{
 			Log->Write("INFO: \tVoronoi graph is asked to output!" );
 		}
-		string xIsIndividualFD = string(xMethod_D.getAttribute("IndividualFDdata"));
-		_isIndividualFD = (xIsIndividualFD== "true") ? true: false;
-		_measureAreaId = xmltoa(xMeasurementArea.getChildNode("MeasurementArea").getAttribute("id"));
-
-		if(!xMethod_D.getChildNode("SteadyState").isEmpty()){
-			const char* steady_start = xMethod_D.getChildNode("SteadyState").getAttribute("start");
-			const char* steady_end = xMethod_D.getChildNode("SteadyState").getAttribute("end");
-			_steadyStart = atof(steady_start);
-			_steadyEnd = atof(steady_end);
-			Log->Write("INFO: \tthe steady state is from  <" + string(steady_start) + "> to <"+string(steady_end) +"> frame"  );
+		_isIndividualFD = (string(xMethod_D->Attribute("individualFDdata")) == "true");
+		_measureAreaId = xMethod_D->FirstChildElement("measurementArea")->Attribute("id");
+
+		if ( xMethod_D->FirstChildElement("steadyState"))
+		{
+			_steadyStart =xmltof(xMethod_D->FirstChildElement("steadyState")->Attribute("start"));
+			_steadyEnd =xmltof(xMethod_D->FirstChildElement("steadyState")->Attribute("end"));
+			Log->Write("INFO: \tthe steady state is from  <%f> to <%f> frames", _steadyStart, _steadyEnd);
 		}
 
-		if(string(xMethod_D.getChildNode("GetProfile").getAttribute("enabled")) == "true"){
+		if(xMethod_D->FirstChildElement("getProfile"))
+		if ( string(xMethod_D->FirstChildElement("getProfile")->Attribute("enabled"))=="true")
+		{
 			_isGetProfile = true;
-			const char* scale_x = xMethod_D.getChildNode("GetProfile").getAttribute("scale_x");
-			_scaleX = atoi(scale_x);
-			const char* scale_y = xMethod_D.getChildNode("GetProfile").getAttribute("scale_y");
-			_scaleY = atoi(scale_y);
+			_scaleX =xmltoi(xMethod_D->FirstChildElement("getProfile")->Attribute("scale_x"));
+			_scaleY =xmltoi(xMethod_D->FirstChildElement("getProfile")->Attribute("scale_y"));
 			Log->Write("INFO: \tprofiles will be calculated" );
-			Log->Write("INFO: \tthe scale of the discretized cell in x, y direction are: <" + string(scale_x) + "> and <"+string(scale_y) +">"  );
+			Log->Write("INFO: \tthe scale of the discretized cell in x, y direction are: < %d > and < %d >",_scaleX, _scaleY);
 		}
+
 		Log->Write("INFO: \tMethod D is selected" );
 	}
+
 	Log->Write("INFO: \tdone parsing ini");
 }
 
@@ -411,16 +423,12 @@ const string& ArgumentParser::GetGeometryFilename() const {
 	return _geometryFileName;
 }
 
-const string& ArgumentParser::GetTrajectoriesFile() const {
-	return _trajectoryFile;
-}
-
-const string& ArgumentParser::GetTrajectoryName() const {
-	return _trajectoryName;
+const string& ArgumentParser::GetTrajectoriesLocation() const {
+	return _trajectoriesLocation;
 }
 
-void ArgumentParser::SetTrajectoriesFile(const string& trajectoriesFile) {
-	_trajectoryFile = trajectoriesFile;
+const string& ArgumentParser::GetTrajectoriesFilename() const {
+	return _trajectoriesFilename;
 }
 
 const string& ArgumentParser::GetMeasureAreaId() const {
diff --git a/general/ArgumentParser.h b/general/ArgumentParser.h
index fbfe6905fdfa804fc3e725bacd2c4d8bb7453642..caca45f60a0448832c925e0746e2e9843b1cc27d 100644
--- a/general/ArgumentParser.h
+++ b/general/ArgumentParser.h
@@ -56,8 +56,8 @@ private:
 	FileFormat pFormat;
 	string _geometryFileName;
 	string _errorLogFile;
-	string _trajectoryFile;
-	string _trajectoryName;
+	string _trajectoriesLocation;
+	string _trajectoriesFilename;
 	string _measureAreaId;
 	double _lengthMeasureArea;
 	polygon_2d _measureArea;
@@ -91,8 +91,8 @@ public:
 	ArgumentParser(); // gibt die Programmoptionen aus
 
 	// Getter-Funktionen
-	const string& GetTrajectoriesFile() const;
-	const string& GetTrajectoryName() const;
+	const string& GetTrajectoriesFilename() const;
+	const string& GetTrajectoriesLocation() const;
 	const string& GetMeasureAreaId() const;
 	const FileFormat& GetFileFormat() const;
 	const string& GetGeometryFilename() const;
@@ -121,8 +121,6 @@ public:
 	int GetLog() const;
 	void SetHostname(const string& hostname);
 	void SetPort(int port);
-	void SetTrajectoriesFile(const string& trajectoriesFile);
-	void SetTrajectoriesPath(const string& trajectoriesPath);
 	void ParseArgs(int argc, char **argv);
 
 	/**
diff --git a/general/Macros.h b/general/Macros.h
index f050a36e9fc800bc2984f90ebb2c1fd07d949618..292811a34a5f047ee2f0f489bb23aab6758fb58e 100644
--- a/general/Macros.h
+++ b/general/Macros.h
@@ -25,11 +25,16 @@
  */
 
 #ifndef _MACROS_H
-#define	_MACROS_H
+#define _MACROS_H
 
+#include <cstdlib>
+#include <vector>
+#include <string.h>
 
 //#define _SIMULATOR 1
 
+//#undef _OPENMP
+
 // Genauigkeit
 #define J_EPS 0.001
 #define J_EPS_DIST 0.05// [m]
@@ -41,13 +46,14 @@
 // zur Versionskontrolle beim Geometrieformat
 #define VERSION 0.40
 #define JPS_VERSION "0.4"
+#define JPS_MAJOR_VERSION 0
+#define JPS_MINOR_VERSION 4
 
 // Länge von char vectoren zur Ausgabe
 #define CLENGTH 1000
 
 
 // Faktor für TraVisTo (cm <-> m)
-//#define FAKTOR 100
 #define FAKTOR 100
 
 
@@ -85,5 +91,16 @@ enum RoutingStrategy {
 	ROUTING_UNDEFINED =-1
 };
 
+
+//global functions for convenience
+// convenience functions
+
+inline char    xmltob(const char * t,char    v=0){ if (t&&(*t)) return (char)atoi(t); return v; }
+inline int     xmltoi(const char * t,int     v=0){ if (t&&(*t)) return atoi(t); return v; }
+inline long    xmltol(const char * t,long    v=0){ if (t&&(*t)) return atol(t); return v; }
+inline double  xmltof(const char * t,double  v=0.0){ if (t&&(*t)) return atof(t); return v; }
+inline const char * xmltoa(const char * t,      const char * v=""){ if (t)       return  t; return v; }
+inline char xmltoc(const char * t,const char v='\0'){ if (t&&(*t)) return *t; return v; }
+
 #endif	/* _MACROS_H */
 
diff --git a/general/xmlParser.cpp b/general/xmlParser.cpp
deleted file mode 100644
index 82046476a5ed93516a475e2b4c0324af288b2a86..0000000000000000000000000000000000000000
--- a/general/xmlParser.cpp
+++ /dev/null
@@ -1,2887 +0,0 @@
-/**
- ****************************************************************************
- * <P> XML.c - implementation file for basic XML parser written in ANSI C++
- * for portability. It works by using recursion and a node tree for breaking
- * down the elements of an XML document.  </P>
- *
- * @version     V2.41
- * @author      Frank Vanden Berghen
- *
- * NOTE:
- *
- *   If you add "#define STRICT_PARSING", on the first line of this file
- *   the parser will see the following XML-stream:
- *      <a><b>some text</b><b>other text    </a>
- *   as an error. Otherwise, this tring will be equivalent to:
- *      <a><b>some text</b><b>other text</b></a>
- *
- * NOTE:
- *
- *   If you add "#define APPROXIMATE_PARSING" on the first line of this file
- *   the parser will see the following XML-stream:
- *     <data name="n1">
- *     <data name="n2">
- *     <data name="n3" />
- *   as equivalent to the following XML-stream:
- *     <data name="n1" />
- *     <data name="n2" />
- *     <data name="n3" />
- *   This can be useful for badly-formed XML-streams but prevent the use
- *   of the following XML-stream (problem is: tags at contiguous levels
- *   have the same names):
- *     <data name="n1">
- *        <data name="n2">
- *            <data name="n3" />
- *        </data>
- *     </data>
- *
- * NOTE:
- *
- *   If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file
- *   the "openFileHelper" function will always display error messages inside the
- *   console instead of inside a message-box-window. Message-box-windows are
- *   available on windows 9x/NT/2000/XP/Vista only.
- *
- * Copyright (c) 2002, Business-Insight
- * <a href="http://www.Business-Insight.com">Business-Insight</a>
- * All rights reserved.
- * See the file "AFPL-license.txt" about the licensing terms
- *
- ****************************************************************************
- */
-#ifndef _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_DEPRECATE
-#endif
-#include "xmlParser.h"
-#ifdef _XMLWINDOWS
-//#ifdef _DEBUG
-//#define _CRTDBG_MAP_ALLOC
-//#include <crtdbg.h>
-//#endif
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h> // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files
-                     // to have "MessageBoxA" to display error messages for openFilHelper
-#endif
-
-#include <memory.h>
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-XMLCSTR XMLNode::getVersion() { return _CXML("v2.41"); }
-void freeXMLString(XMLSTR t){if(t)free(t);}
-
-static XMLNode::XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8;
-static char guessWideCharChars=1, dropWhiteSpace=1, removeCommentsInMiddleOfText=1;
-
-inline int mmin( const int t1, const int t2 ) { return t1 < t2 ? t1 : t2; }
-
-// You can modify the initialization of the variable "XMLClearTags" below
-// to change the clearTags that are currently recognized by the library.
-// The number on the second columns is the length of the string inside the
-// first column. The "<!DOCTYPE" declaration must be the second in the list.
-// The "<!--" declaration must be the third in the list.
-typedef struct { XMLCSTR lpszOpen; int openTagLen; XMLCSTR lpszClose;} ALLXMLClearTag;
-static ALLXMLClearTag XMLClearTags[] =
-{
-    {    _CXML("<![CDATA["),9,  _CXML("]]>")      },
-    {    _CXML("<!DOCTYPE"),9,  _CXML(">")        },
-    {    _CXML("<!--")     ,4,  _CXML("-->")      },
-    {    _CXML("<PRE>")    ,5,  _CXML("</PRE>")   },
-//  {    _CXML("<Script>") ,8,  _CXML("</Script>")},
-    {    NULL              ,0,  NULL           }
-};
-
-// You can modify the initialization of the variable "XMLEntities" below
-// to change the character entities that are currently recognized by the library.
-// The number on the second columns is the length of the string inside the
-// first column. Additionally, the syntaxes "&#xA0;" and "&#160;" are recognized.
-typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity;
-static XMLCharacterEntity XMLEntities[] =
-{
-    { _CXML("&amp;" ), 5, _CXML('&' )},
-    { _CXML("&lt;"  ), 4, _CXML('<' )},
-    { _CXML("&gt;"  ), 4, _CXML('>' )},
-    { _CXML("&quot;"), 6, _CXML('\"')},
-    { _CXML("&apos;"), 6, _CXML('\'')},
-    { NULL           , 0, '\0'    }
-};
-
-// When rendering the XMLNode to a string (using the "createXMLString" function),
-// you can ask for a beautiful formatting. This formatting is using the
-// following indentation character:
-#define INDENTCHAR _CXML('\t')
-
-// The following function parses the XML errors into a user friendly string.
-// You can edit this to change the output language of the library to something else.
-XMLCSTR XMLNode::getError(XMLError xerror)
-{
-    switch (xerror)
-    {
-    case eXMLErrorNone:                  return _CXML("No error");
-    case eXMLErrorMissingEndTag:         return _CXML("Warning: Unmatched end tag");
-    case eXMLErrorNoXMLTagFound:         return _CXML("Warning: No XML tag found");
-    case eXMLErrorEmpty:                 return _CXML("Error: No XML data");
-    case eXMLErrorMissingTagName:        return _CXML("Error: Missing start tag name");
-    case eXMLErrorMissingEndTagName:     return _CXML("Error: Missing end tag name");
-    case eXMLErrorUnmatchedEndTag:       return _CXML("Error: Unmatched end tag");
-    case eXMLErrorUnmatchedEndClearTag:  return _CXML("Error: Unmatched clear tag end");
-    case eXMLErrorUnexpectedToken:       return _CXML("Error: Unexpected token found");
-    case eXMLErrorNoElements:            return _CXML("Error: No elements found");
-    case eXMLErrorFileNotFound:          return _CXML("Error: File not found");
-    case eXMLErrorFirstTagNotFound:      return _CXML("Error: First Tag not found");
-    case eXMLErrorUnknownCharacterEntity:return _CXML("Error: Unknown character entity");
-    case eXMLErrorCharacterCodeAbove255: return _CXML("Error: Character code above 255 is forbidden in MultiByte char mode.");
-    case eXMLErrorCharConversionError:   return _CXML("Error: unable to convert between WideChar and MultiByte chars");
-    case eXMLErrorCannotOpenWriteFile:   return _CXML("Error: unable to open file for writing");
-    case eXMLErrorCannotWriteFile:       return _CXML("Error: cannot write into file");
-
-    case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _CXML("Warning: Base64-string length is not a multiple of 4");
-    case eXMLErrorBase64DecodeTruncatedData:      return _CXML("Warning: Base64-string is truncated");
-    case eXMLErrorBase64DecodeIllegalCharacter:   return _CXML("Error: Base64-string contains an illegal character");
-    case eXMLErrorBase64DecodeBufferTooSmall:     return _CXML("Error: Base64 decode output buffer is too small");
-    };
-    return _CXML("Unknown");
-}
-
-/////////////////////////////////////////////////////////////////////////
-//      Here start the abstraction layer to be OS-independent          //
-/////////////////////////////////////////////////////////////////////////
-
-// Here is an abstraction layer to access some common string manipulation functions.
-// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0,
-// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++.
-// If you plan to "port" the library to a new system/compiler, all you have to do is
-// to edit the following lines.
-#ifdef XML_NO_WIDE_CHAR
-char myIsTextWideChar(const void *b, int len) { return FALSE; }
-#else
-    #if defined (UNDER_CE) || !defined(_XMLWINDOWS)
-    char myIsTextWideChar(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode
-    {
-#ifdef sun
-        // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer.
-        if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE;
-#endif
-        const wchar_t *s=(const wchar_t*)b;
-
-        // buffer too small:
-        if (len<(int)sizeof(wchar_t)) return FALSE;
-
-        // odd length test
-        if (len&1) return FALSE;
-
-        /* only checks the first 256 characters */
-        len=mmin(256,len/sizeof(wchar_t));
-
-        // Check for the special byte order:
-        if (*((unsigned short*)s) == 0xFFFE) return TRUE;     // IS_TEXT_UNICODE_REVERSE_SIGNATURE;
-        if (*((unsigned short*)s) == 0xFEFF) return TRUE;      // IS_TEXT_UNICODE_SIGNATURE
-
-        // checks for ASCII characters in the UNICODE stream
-        int i,stats=0;
-        for (i=0; i<len; i++) if (s[i]<=(unsigned short)255) stats++;
-        if (stats>len/2) return TRUE;
-
-        // Check for UNICODE NULL chars
-        for (i=0; i<len; i++) if (!s[i]) return TRUE;
-
-        return FALSE;
-    }
-    #else
-    char myIsTextWideChar(const void *b,int l) { return (char)IsTextUnicode((CONST LPVOID)b,l,NULL); };
-    #endif
-#endif
-
-#ifdef _XMLWINDOWS
-// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0
-    #ifdef _XMLWIDECHAR
-        wchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce)
-        {
-            int i;
-            if (ce==XMLNode::char_encoding_UTF8) i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,-1,NULL,0);
-            else                            i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,-1,NULL,0);
-            if (i<0) return NULL;
-            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(XMLCHAR));
-            if (ce==XMLNode::char_encoding_UTF8) i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,-1,d,i);
-            else                            i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,-1,d,i);
-            d[i]=0;
-            return d;
-        }
-        static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) { return _wfopen(filename,mode); }
-        static inline int xstrlen(XMLCSTR c)   { return (int)wcslen(c); }
-        static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return _wcsnicmp(c1,c2,l);}
-        static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncmp(c1,c2,l);}
-        static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return _wcsicmp(c1,c2); }
-        static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); }
-        static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); }
-    #else
-        char *myWideCharToMultiByte(const wchar_t *s)
-        {
-            UINT codePage=CP_ACP; if (characterEncoding==XMLNode::char_encoding_UTF8) codePage=CP_UTF8;
-            int i=(int)WideCharToMultiByte(codePage,  // code page
-                0,                       // performance and mapping flags
-                s,                       // wide-character string
-                -1,                       // number of chars in string
-                NULL,                       // buffer for new string
-                0,                       // size of buffer
-                NULL,                    // default for unmappable chars
-                NULL                     // set when default char used
-                );
-            if (i<0) return NULL;
-            char *d=(char*)malloc(i+1);
-            WideCharToMultiByte(codePage,  // code page
-                0,                       // performance and mapping flags
-                s,                       // wide-character string
-                -1,                       // number of chars in string
-                d,                       // buffer for new string
-                i,                       // size of buffer
-                NULL,                    // default for unmappable chars
-                NULL                     // set when default char used
-                );
-            d[i]=0;
-            return d;
-        }
-        static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); }
-        static inline int xstrlen(XMLCSTR c)   { return (int)strlen(c); }
-        #ifdef __BORLANDC__
-            static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strnicmp(c1,c2,l);}
-            static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return stricmp(c1,c2); }
-        #else
-            static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return _strnicmp(c1,c2,l);}
-            static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return _stricmp(c1,c2); }
-        #endif
-        static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncmp(c1,c2,l);}
-        static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); }
-        static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); }
-    #endif
-#else
-// for gcc and CC
-    #ifdef XML_NO_WIDE_CHAR
-        char *myWideCharToMultiByte(const wchar_t *s) { return NULL; }
-    #else
-        char *myWideCharToMultiByte(const wchar_t *s)
-        {
-            const wchar_t *ss=s;
-            int i=(int)wcsrtombs(NULL,&ss,0,NULL);
-            if (i<0) return NULL;
-            char *d=(char *)malloc(i+1);
-            wcsrtombs(d,&s,i,NULL);
-            d[i]=0;
-            return d;
-        }
-    #endif
-    #ifdef _XMLWIDECHAR
-        wchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce)
-        {
-            const char *ss=s;
-            int i=(int)mbsrtowcs(NULL,&ss,0,NULL);
-            if (i<0) return NULL;
-            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(wchar_t));
-            mbsrtowcs(d,&s,i,NULL);
-            d[i]=0;
-            return d;
-        }
-        int xstrlen(XMLCSTR c)   { return wcslen(c); }
-        #ifdef sun
-        // for CC
-           #include <widec.h>
-           static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1,c2,l);}
-           static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncmp(c1,c2,l);}
-           static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1,c2); }
-        #else
-        static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncmp(c1,c2,l);}
-            #ifdef __linux__
-            // for gcc/linux
-            static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1,c2,l);}
-            static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1,c2); }
-            #else
-            #include <wctype.h>
-            // for gcc/non-linux (MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 4.3.2, HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin, mingw)
-            static inline int xstricmp(XMLCSTR c1, XMLCSTR c2)
-            {
-                wchar_t left,right;
-                do
-                {
-                    left=towlower(*c1++); right=towlower(*c2++);
-                } while (left&&(left==right));
-                return (int)left-(int)right;
-            }
-            static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l)
-            {
-                wchar_t left,right;
-                while(l--)
-                {
-                    left=towlower(*c1++); right=towlower(*c2++);
-                    if ((!left)||(left!=right)) return (int)left-(int)right;
-                }
-                return 0;
-            }
-            #endif
-        #endif
-        static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); }
-        static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); }
-        static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode)
-        {
-            char *filenameAscii=myWideCharToMultiByte(filename);
-            FILE *f;
-            if (mode[0]==_CXML('r')) f=fopen(filenameAscii,"rb");
-            else                     f=fopen(filenameAscii,"wb");
-            free(filenameAscii);
-            return f;
-        }
-    #else
-        static inline FILE *xfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); }
-        static inline int xstrlen(XMLCSTR c)   { return strlen(c); }
-        static inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1,c2,l);}
-        static inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncmp(c1,c2,l);}
-        static inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1,c2); }
-        static inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); }
-        static inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); }
-    #endif
-    static inline int _strnicmp(const char *c1,const char *c2, int l) { return strncasecmp(c1,c2,l);}
-#endif
-
-
-///////////////////////////////////////////////////////////////////////////////
-//            the "xmltoc,xmltob,xmltoi,xmltol,xmltof,xmltoa" functions      //
-///////////////////////////////////////////////////////////////////////////////
-// These 6 functions are not used inside the XMLparser.
-// There are only here as "convenience" functions for the user.
-// If you don't need them, you can delete them without any trouble.
-#ifdef _XMLWIDECHAR
-    #ifdef _XMLWINDOWS
-    // for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0
-        char    xmltob(XMLCSTR t,int     v){ if (t&&(*t)) return (char)_wtoi(t); return v; }
-        int     xmltoi(XMLCSTR t,int     v){ if (t&&(*t)) return _wtoi(t); return v; }
-        long    xmltol(XMLCSTR t,long    v){ if (t&&(*t)) return _wtol(t); return v; }
-        double  xmltof(XMLCSTR t,double  v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; }
-    #else
-        #ifdef sun
-        // for CC
-           #include <widec.h>
-           char    xmltob(XMLCSTR t,int     v){ if (t) return (char)wstol(t,NULL,10); return v; }
-           int     xmltoi(XMLCSTR t,int     v){ if (t) return (int)wstol(t,NULL,10); return v; }
-           long    xmltol(XMLCSTR t,long    v){ if (t) return wstol(t,NULL,10); return v; }
-        #else
-        // for gcc
-           char    xmltob(XMLCSTR t,int     v){ if (t) return (char)wcstol(t,NULL,10); return v; }
-           int     xmltoi(XMLCSTR t,int     v){ if (t) return (int)wcstol(t,NULL,10); return v; }
-           long    xmltol(XMLCSTR t,long    v){ if (t) return wcstol(t,NULL,10); return v; }
-        #endif
-		double  xmltof(XMLCSTR t,double  v){ if (t&&(*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ return v; }
-    #endif
-#else
-    char    xmltob(XMLCSTR t,char    v){ if (t&&(*t)) return (char)atoi(t); return v; }
-    int     xmltoi(XMLCSTR t,int     v){ if (t&&(*t)) return atoi(t); return v; }
-    long    xmltol(XMLCSTR t,long    v){ if (t&&(*t)) return atol(t); return v; }
-    double  xmltof(XMLCSTR t,double  v){ if (t&&(*t)) return atof(t); return v; }
-#endif
-XMLCSTR xmltoa(XMLCSTR t,      XMLCSTR v){ if (t)       return  t; return v; }
-XMLCHAR xmltoc(XMLCSTR t,const XMLCHAR v){ if (t&&(*t)) return *t; return v; }
-
-/////////////////////////////////////////////////////////////////////////
-//                    the "openFileHelper" function                    //
-/////////////////////////////////////////////////////////////////////////
-
-// Since each application has its own way to report and deal with errors, you should modify & rewrite
-// the following "openFileHelper" function to get an "error reporting mechanism" tailored to your needs.
-XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag)
-{
-    // guess the value of the global parameter "characterEncoding"
-    // (the guess is based on the first 200 bytes of the file).
-    FILE *f=xfopen(filename,_CXML("rb"));
-    if (f)
-    {
-        char bb[205];
-        int l=(int)fread(bb,1,200,f);
-        setGlobalOptions(guessCharEncoding(bb,l),guessWideCharChars,dropWhiteSpace,removeCommentsInMiddleOfText);
-        fclose(f);
-    }
-
-    // parse the file
-    XMLResults pResults;
-    XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults);
-
-    // display error message (if any)
-    if (pResults.error != eXMLErrorNone)
-    {
-        // create message
-        char message[2000],*s1=(char*)"",*s3=(char*)""; XMLCSTR s2=_CXML("");
-        if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(char*)"First Tag should be '"; s2=tag; s3=(char*)"'.\n"; }
-        sprintf(message,
-#ifdef _XMLWIDECHAR
-            "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s"
-#else
-            "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s"
-#endif
-            ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3);
-
-        // display message
-#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_)
-        MessageBoxA(NULL,message,"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST);
-#else
-        printf("%s",message);
-#endif
-        exit(255);
-    }
-    return xnode;
-}
-
-/////////////////////////////////////////////////////////////////////////
-//      Here start the core implementation of the XMLParser library    //
-/////////////////////////////////////////////////////////////////////////
-
-// You should normally not change anything below this point.
-
-#ifndef _XMLWIDECHAR
-// If "characterEncoding=ascii" then we assume that all characters have the same length of 1 byte.
-// If "characterEncoding=UTF8" then the characters have different lengths (from 1 byte to 4 bytes).
-// If "characterEncoding=ShiftJIS" then the characters have different lengths (from 1 byte to 2 bytes).
-// This table is used as lookup-table to know the length of a character (in byte) based on the
-// content of the first byte of the character.
-// (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ).
-static const char XML_utf8ByteTable[256] =
-{
-    //  0 1 2 3 4 5 6 7 8 9 a b c d e f
-    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70 End of ASCII range
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 0x80 to 0xc1 invalid
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0
-    1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 0xc2 to 0xdf 2 byte
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0
-    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,// 0xe0 0xe0 to 0xef 3 byte
-    4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
-};
-static const char XML_legacyByteTable[256] =
-{
-    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
-};
-static const char XML_sjisByteTable[256] =
-{
-    //  0 1 2 3 4 5 6 7 8 9 a b c d e f
-    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70
-    1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0x9F 2 bytes
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xc0
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xd0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0 0xe0 to 0xef 2 bytes
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 // 0xf0
-};
-static const char XML_gb2312ByteTable[256] =
-{
-//  0 1 2 3 4 5 6 7 8 9 a b c d e f
-    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90
-    1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0 0xa1 to 0xf7 2 bytes
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0
-    2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 // 0xf0
-};
-static const char XML_gbk_big5_ByteTable[256] =
-{
-    //  0 1 2 3 4 5 6 7 8 9 a b c d e f
-    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70
-    1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x80 0x81 to 0xfe 2 bytes
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0x90
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xa0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xb0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xe0
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1 // 0xf0
-};
-static const char *XML_ByteTable=(const char *)XML_utf8ByteTable; // the default is "characterEncoding=XMLNode::encoding_UTF8"
-#endif
-
-
-XMLNode XMLNode::emptyXMLNode;
-XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL};
-XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL};
-
-// Enumeration used to decipher what type a token is
-typedef enum XMLTokenTypeTag
-{
-    eTokenText = 0,
-    eTokenQuotedText,
-    eTokenTagStart,         /* "<"            */
-    eTokenTagEnd,           /* "</"           */
-    eTokenCloseTag,         /* ">"            */
-    eTokenEquals,           /* "="            */
-    eTokenDeclaration,      /* "<?"           */
-    eTokenShortHandClose,   /* "/>"           */
-    eTokenClear,
-    eTokenError
-} XMLTokenType;
-
-// Main structure used for parsing XML
-typedef struct XML
-{
-    XMLCSTR                lpXML;
-    XMLCSTR                lpszText;
-    int                    nIndex,nIndexMissigEndTag;
-    enum XMLError          error;
-    XMLCSTR                lpEndTag;
-    int                    cbEndTag;
-    XMLCSTR                lpNewElement;
-    int                    cbNewElement;
-    int                    nFirst;
-} XML;
-
-typedef struct
-{
-    ALLXMLClearTag *pClr;
-    XMLCSTR     pStr;
-} NextToken;
-
-// Enumeration used when parsing attributes
-typedef enum Attrib
-{
-    eAttribName = 0,
-    eAttribEquals,
-    eAttribValue
-} Attrib;
-
-// Enumeration used when parsing elements to dictate whether we are currently
-// inside a tag
-typedef enum Status
-{
-    eInsideTag = 0,
-    eOutsideTag
-} Status;
-
-XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const
-{
-    if (!d) return eXMLErrorNone;
-    FILE *f=xfopen(filename,_CXML("wb"));
-    if (!f) return eXMLErrorCannotOpenWriteFile;
-#ifdef _XMLWIDECHAR
-    unsigned char h[2]={ 0xFF, 0xFE };
-    if (!fwrite(h,2,1,f)) return eXMLErrorCannotWriteFile;
-    if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration())))
-    {
-        if (!fwrite(L"<?xml version=\"1.0\" encoding=\"utf-16\"?>\n",sizeof(wchar_t)*40,1,f))
-            return eXMLErrorCannotWriteFile;
-    }
-#else
-    if ((!isDeclaration())&&((d->lpszName)||(!getChildNode().isDeclaration())))
-    {
-        if (characterEncoding==char_encoding_UTF8)
-        {
-            // header so that windows recognize the file as UTF-8:
-            unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
-            encoding="utf-8";
-        } else if (characterEncoding==char_encoding_ShiftJIS) encoding="SHIFT-JIS";
-
-        if (!encoding) encoding="ISO-8859-1";
-        if (fprintf(f,"<?xml version=\"1.0\" encoding=\"%s\"?>\n",encoding)<0) return eXMLErrorCannotWriteFile;
-    } else
-    {
-        if (characterEncoding==char_encoding_UTF8)
-        {
-            unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
-        }
-    }
-#endif
-    int i;
-    XMLSTR t=createXMLString(nFormat,&i);
-    if (!fwrite(t,sizeof(XMLCHAR)*i,1,f)) return eXMLErrorCannotWriteFile;
-    if (fclose(f)!=0) return eXMLErrorCannotWriteFile;
-    free(t);
-    return eXMLErrorNone;
-}
-
-// Duplicate a given string.
-XMLSTR stringDup(XMLCSTR lpszData, int cbData)
-{
-    if (lpszData==NULL) return NULL;
-
-    XMLSTR lpszNew;
-    if (cbData==-1) cbData=(int)xstrlen(lpszData);
-    lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR));
-    if (lpszNew)
-    {
-        memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR));
-        lpszNew[cbData] = (XMLCHAR)NULL;
-    }
-    return lpszNew;
-}
-
-XMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest,XMLCSTR source)
-{
-    XMLSTR dd=dest;
-    XMLCHAR ch;
-    XMLCharacterEntity *entity;
-    while ((ch=*source))
-    {
-        entity=XMLEntities;
-        do
-        {
-            if (ch==entity->c) {xstrcpy(dest,entity->s); dest+=entity->l; source++; goto out_of_loop1; }
-            entity++;
-        } while(entity->s);
-#ifdef _XMLWIDECHAR
-        *(dest++)=*(source++);
-#else
-        switch(XML_ByteTable[(unsigned char)ch])
-        {
-        case 4: *(dest++)=*(source++);
-        case 3: *(dest++)=*(source++);
-        case 2: *(dest++)=*(source++);
-        case 1: *(dest++)=*(source++);
-        }
-#endif
-out_of_loop1:
-        ;
-    }
-    *dest=0;
-    return dd;
-}
-
-// private (used while rendering):
-int ToXMLStringTool::lengthXMLString(XMLCSTR source)
-{
-    int r=0;
-    XMLCharacterEntity *entity;
-    XMLCHAR ch;
-    while ((ch=*source))
-    {
-        entity=XMLEntities;
-        do
-        {
-            if (ch==entity->c) { r+=entity->l; source++; goto out_of_loop1; }
-            entity++;
-        } while(entity->s);
-#ifdef _XMLWIDECHAR
-        r++; source++;
-#else
-        ch=XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch;
-#endif
-out_of_loop1:
-        ;
-    }
-    return r;
-}
-
-ToXMLStringTool::~ToXMLStringTool(){ freeBuffer(); }
-void ToXMLStringTool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; }
-XMLSTR ToXMLStringTool::toXML(XMLCSTR source)
-{
-  if (!source) return _CXML((XMLSTR)"");
-    int l=lengthXMLString(source)+1;
-    if (l>buflen) { buflen=l; buf=(XMLSTR)realloc(buf,l*sizeof(XMLCHAR)); }
-    return toXMLUnSafe(buf,source);
-}
-
-// private:
-XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML)
-{
-    // This function is the opposite of the function "toXMLString". It decodes the escape
-    // sequences &amp;, &quot;, &apos;, &lt;, &gt; and replace them by the characters
-    // &,",',<,>. This function is used internally by the XML Parser. All the calls to
-    // the XML library will always gives you back "decoded" strings.
-    //
-    // in: string (s) and length (lo) of string
-    // out:  new allocated string converted from xml
-    if (!s) return NULL;
-
-    int ll=0,j;
-    XMLSTR d;
-    XMLCSTR ss=s;
-    XMLCharacterEntity *entity;
-    while ((lo>0)&&(*s))
-    {
-        if (*s==_CXML('&'))
-        {
-            if ((lo>2)&&(s[1]==_CXML('#')))
-            {
-                s+=2; lo-=2;
-                if ((*s==_CXML('X'))||(*s==_CXML('x'))) { s++; lo--; }
-                while ((*s)&&(*s!=_CXML(';'))&&((lo--)>0)) s++;
-                if (*s!=_CXML(';'))
-                {
-                    pXML->error=eXMLErrorUnknownCharacterEntity;
-                    return NULL;
-                }
-                s++; lo--;
-            } else
-            {
-                entity=XMLEntities;
-                do
-                {
-                    if ((lo>=entity->l)&&(xstrnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l; break; }
-                    entity++;
-                } while(entity->s);
-                if (!entity->s)
-                {
-                    pXML->error=eXMLErrorUnknownCharacterEntity;
-                    return NULL;
-                }
-            }
-        } else
-        {
-#ifdef _XMLWIDECHAR
-            s++; lo--;
-#else
-            j=XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1;
-#endif
-        }
-        ll++;
-    }
-
-    d=(XMLSTR)malloc((ll+1)*sizeof(XMLCHAR));
-    s=d;
-    while (ll-->0)
-    {
-        if (*ss==_CXML('&'))
-        {
-            if (ss[1]==_CXML('#'))
-            {
-                ss+=2; j=0;
-                if ((*ss==_CXML('X'))||(*ss==_CXML('x')))
-                {
-                    ss++;
-                    while (*ss!=_CXML(';'))
-                    {
-                        if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j<<4)+*ss-_CXML('0');
-                        else if ((*ss>=_CXML('A'))&&(*ss<=_CXML('F'))) j=(j<<4)+*ss-_CXML('A')+10;
-                        else if ((*ss>=_CXML('a'))&&(*ss<=_CXML('f'))) j=(j<<4)+*ss-_CXML('a')+10;
-                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
-                        ss++;
-                    }
-                } else
-                {
-                    while (*ss!=_CXML(';'))
-                    {
-                        if ((*ss>=_CXML('0'))&&(*ss<=_CXML('9'))) j=(j*10)+*ss-_CXML('0');
-                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
-                        ss++;
-                    }
-                }
-#ifndef _XMLWIDECHAR
-                if (j>255) { free((void*)s); pXML->error=eXMLErrorCharacterCodeAbove255;return NULL;}
-#endif
-                (*d++)=(XMLCHAR)j; ss++;
-            } else
-            {
-                entity=XMLEntities;
-                do
-                {
-                    if (xstrnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; }
-                    entity++;
-                } while(entity->s);
-            }
-        } else
-        {
-#ifdef _XMLWIDECHAR
-            *(d++)=*(ss++);
-#else
-            switch(XML_ByteTable[(unsigned char)*ss])
-            {
-            case 4: *(d++)=*(ss++); ll--;
-            case 3: *(d++)=*(ss++); ll--;
-            case 2: *(d++)=*(ss++); ll--;
-            case 1: *(d++)=*(ss++);
-            }
-#endif
-        }
-    }
-    *d=0;
-    return (XMLSTR)s;
-}
-
-#define XML_isSPACECHAR(ch) ((ch==_CXML('\n'))||(ch==_CXML(' '))||(ch== _CXML('\t'))||(ch==_CXML('\r')))
-
-// private:
-char myTagCompare(XMLCSTR cclose, XMLCSTR copen)
-// !!!! WARNING strange convention&:
-// return 0 if equals
-// return 1 if different
-{
-    if (!cclose) return 1;
-    int l=(int)xstrlen(cclose);
-    if (xstrnicmp(cclose, copen, l)!=0) return 1;
-    const XMLCHAR c=copen[l];
-    if (XML_isSPACECHAR(c)||
-        (c==_CXML('/' ))||
-        (c==_CXML('<' ))||
-        (c==_CXML('>' ))||
-        (c==_CXML('=' ))) return 0;
-    return 1;
-}
-
-// Obtain the next character from the string.
-static inline XMLCHAR getNextChar(XML *pXML)
-{
-    XMLCHAR ch = pXML->lpXML[pXML->nIndex];
-#ifdef _XMLWIDECHAR
-    if (ch!=0) pXML->nIndex++;
-#else
-    pXML->nIndex+=XML_ByteTable[(unsigned char)ch];
-#endif
-    return ch;
-}
-
-// Find the next token in a string.
-// pcbToken contains the number of characters that have been read.
-static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType)
-{
-    NextToken        result;
-    XMLCHAR            ch;
-    XMLCHAR            chTemp;
-    int              indexStart,nFoundMatch,nIsText=FALSE;
-    result.pClr=NULL; // prevent warning
-
-    // Find next non-white space character
-    do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch);
-
-    if (ch)
-    {
-        // Cache the current string pointer
-        result.pStr = &pXML->lpXML[indexStart];
-
-        // First check whether the token is in the clear tag list (meaning it
-        // does not need formatting).
-        ALLXMLClearTag *ctag=XMLClearTags;
-        do
-        {
-            if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0)
-            {
-                result.pClr=ctag;
-                pXML->nIndex+=ctag->openTagLen-1;
-                *pType=eTokenClear;
-                return result;
-            }
-            ctag++;
-        } while(ctag->lpszOpen);
-
-        // If we didn't find a clear tag then check for standard tokens
-        switch(ch)
-        {
-        // Check for quotes
-        case _CXML('\''):
-        case _CXML('\"'):
-            // Type of token
-            *pType = eTokenQuotedText;
-            chTemp = ch;
-
-            // Set the size
-            nFoundMatch = FALSE;
-
-            // Search through the string to find a matching quote
-            while((ch = getNextChar(pXML)))
-            {
-                if (ch==chTemp) { nFoundMatch = TRUE; break; }
-                if (ch==_CXML('<')) break;
-            }
-
-            // If we failed to find a matching quote
-            if (nFoundMatch == FALSE)
-            {
-                pXML->nIndex=indexStart+1;
-                nIsText=TRUE;
-                break;
-            }
-
-//  4.02.2002
-//            if (FindNonWhiteSpace(pXML)) pXML->nIndex--;
-
-            break;
-
-        // Equals (used with attribute values)
-        case _CXML('='):
-            *pType = eTokenEquals;
-            break;
-
-        // Close tag
-        case _CXML('>'):
-            *pType = eTokenCloseTag;
-            break;
-
-        // Check for tag start and tag end
-        case _CXML('<'):
-
-            // Peek at the next character to see if we have an end tag '</',
-            // or an xml declaration '<?'
-            chTemp = pXML->lpXML[pXML->nIndex];
-
-            // If we have a tag end...
-            if (chTemp == _CXML('/'))
-            {
-                // Set the type and ensure we point at the next character
-                getNextChar(pXML);
-                *pType = eTokenTagEnd;
-            }
-
-            // If we have an XML declaration tag
-            else if (chTemp == _CXML('?'))
-            {
-
-                // Set the type and ensure we point at the next character
-                getNextChar(pXML);
-                *pType = eTokenDeclaration;
-            }
-
-            // Otherwise we must have a start tag
-            else
-            {
-                *pType = eTokenTagStart;
-            }
-            break;
-
-        // Check to see if we have a short hand type end tag ('/>').
-        case _CXML('/'):
-
-            // Peek at the next character to see if we have a short end tag '/>'
-            chTemp = pXML->lpXML[pXML->nIndex];
-
-            // If we have a short hand end tag...
-            if (chTemp == _CXML('>'))
-            {
-                // Set the type and ensure we point at the next character
-                getNextChar(pXML);
-                *pType = eTokenShortHandClose;
-                break;
-            }
-
-            // If we haven't found a short hand closing tag then drop into the
-            // text process
-
-        // Other characters
-        default:
-            nIsText = TRUE;
-        }
-
-        // If this is a TEXT node
-        if (nIsText)
-        {
-            // Indicate we are dealing with text
-            *pType = eTokenText;
-            while((ch = getNextChar(pXML)))
-            {
-                if XML_isSPACECHAR(ch)
-                {
-                    indexStart++; break;
-
-                } else if (ch==_CXML('/'))
-                {
-                    // If we find a slash then this maybe text or a short hand end tag
-                    // Peek at the next character to see it we have short hand end tag
-                    ch=pXML->lpXML[pXML->nIndex];
-                    // If we found a short hand end tag then we need to exit the loop
-                    if (ch==_CXML('>')) { pXML->nIndex--; break; }
-
-                } else if ((ch==_CXML('<'))||(ch==_CXML('>'))||(ch==_CXML('=')))
-                {
-                    pXML->nIndex--; break;
-                }
-            }
-        }
-        *pcbToken = pXML->nIndex-indexStart;
-    } else
-    {
-        // If we failed to obtain a valid character
-        *pcbToken = 0;
-        *pType = eTokenError;
-        result.pStr=NULL;
-    }
-
-    return result;
-}
-
-XMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName)
-{
-    if (!d) { free(lpszName); return NULL; }
-    if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName);
-    d->lpszName=lpszName;
-    return lpszName;
-}
-
-// private:
-XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; }
-XMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration)
-{
-    d=(XMLNodeData*)malloc(sizeof(XMLNodeData));
-    d->ref_count=1;
-
-    d->lpszName=NULL;
-    d->nChild= 0;
-    d->nText = 0;
-    d->nClear = 0;
-    d->nAttribute = 0;
-
-    d->isDeclaration = isDeclaration;
-
-    d->pParent = pParent;
-    d->pChild= NULL;
-    d->pText= NULL;
-    d->pClear= NULL;
-    d->pAttribute= NULL;
-    d->pOrder= NULL;
-
-    updateName_WOSD(lpszName);
-}
-
-XMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); }
-XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); }
-
-#define MEMORYINCREASE 50
-
-static inline void myFree(void *p) { if (p) free(p); }
-static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem)
-{
-    if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); }
-    if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem);
-//    if (!p)
-//    {
-//        printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220);
-//    }
-    return p;
-}
-
-// private:
-XMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xxtype)
-{
-    if (index<0) return -1;
-    int i=0,j=(int)((index<<2)+xxtype),*o=d->pOrder; while (o[i]!=j) i++; return i;
-}
-
-// private:
-// update "order" information when deleting a content of a XMLNode
-int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index)
-{
-    int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t);
-    memmove(o+i, o+i+1, (n-i)*sizeof(int));
-    for (;i<n;i++)
-        if ((o[i]&3)==(int)t) o[i]-=4;
-    // We should normally do:
-    // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int));
-    // but we skip reallocation because it's too time consuming.
-    // Anyway, at the end, it will be free'd completely at once.
-    return i;
-}
-
-void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype)
-{
-    //  in: *_pos is the position inside d->pOrder ("-1" means "EndOf")
-    // out: *_pos is the index inside p
-    p=myRealloc(p,(nc+1),memoryIncrease,size);
-    int n=d->nChild+d->nText+d->nClear;
-    d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int));
-    int pos=*_pos,*o=d->pOrder;
-
-    if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
-
-    int i=pos;
-    memmove(o+i+1, o+i, (n-i)*sizeof(int));
-
-    while ((pos<n)&&((o[pos]&3)!=(int)xtype)) pos++;
-    if (pos==n) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
-
-    o[i]=o[pos];
-    for (i=pos+1;i<=n;i++) if ((o[i]&3)==(int)xtype) o[i]+=4;
-
-    *_pos=pos=o[pos]>>2;
-    memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size);
-
-    return p;
-}
-
-// Add a child node to the given element.
-XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, char isDeclaration, int pos)
-{
-    if (!lpszName) return emptyXMLNode;
-    d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
-    d->pChild[pos].d=NULL;
-    d->pChild[pos]=XMLNode(d,lpszName,isDeclaration);
-    d->nChild++;
-    return d->pChild[pos];
-}
-
-// Add an attribute to an element.
-XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease,XMLSTR lpszName, XMLSTR lpszValuev)
-{
-    if (!lpszName) return &emptyXMLAttribute;
-    if (!d) { myFree(lpszName); myFree(lpszValuev); return &emptyXMLAttribute; }
-    int nc=d->nAttribute;
-    d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,sizeof(XMLAttribute));
-    XMLAttribute *pAttr=d->pAttribute+nc;
-    pAttr->lpszName = lpszName;
-    pAttr->lpszValue = lpszValuev;
-    d->nAttribute++;
-    return pAttr;
-}
-
-// Add text to the element.
-XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos)
-{
-    if (!lpszValue) return NULL;
-    if (!d) { myFree(lpszValue); return NULL; }
-    d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,sizeof(XMLSTR),eNodeText);
-    d->pText[pos]=lpszValue;
-    d->nText++;
-    return lpszValue;
-}
-
-// Add clear (unformatted) text to the element.
-XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
-{
-    if (!lpszValue) return &emptyXMLClear;
-    if (!d) { myFree(lpszValue); return &emptyXMLClear; }
-    d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,sizeof(XMLClear),eNodeClear);
-    XMLClear *pNewClear=d->pClear+pos;
-    pNewClear->lpszValue = lpszValue;
-    if (!lpszOpen) lpszOpen=XMLClearTags->lpszOpen;
-    if (!lpszClose) lpszClose=XMLClearTags->lpszClose;
-    pNewClear->lpszOpenTag = lpszOpen;
-    pNewClear->lpszCloseTag = lpszClose;
-    d->nClear++;
-    return pNewClear;
-}
-
-// private:
-// Parse a clear (unformatted) type node.
-char XMLNode::parseClearTag(void *px, void *_pClear)
-{
-    XML *pXML=(XML *)px;
-    ALLXMLClearTag pClear=*((ALLXMLClearTag*)_pClear);
-    int cbTemp=0;
-    XMLCSTR lpszTemp=NULL;
-    XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex];
-    static XMLCSTR docTypeEnd=_CXML("]>");
-
-    // Find the closing tag
-    // Seems the <!DOCTYPE need a better treatment so lets handle it
-    if (pClear.lpszOpen==XMLClearTags[1].lpszOpen)
-    {
-        XMLCSTR pCh=lpXML;
-        while (*pCh)
-        {
-            if (*pCh==_CXML('<')) { pClear.lpszClose=docTypeEnd; lpszTemp=xstrstr(lpXML,docTypeEnd); break; }
-            else if (*pCh==_CXML('>')) { lpszTemp=pCh; break; }
-#ifdef _XMLWIDECHAR
-            pCh++;
-#else
-            pCh+=XML_ByteTable[(unsigned char)(*pCh)];
-#endif
-        }
-    } else lpszTemp=xstrstr(lpXML, pClear.lpszClose);
-
-    if (lpszTemp)
-    {
-        // Cache the size and increment the index
-        cbTemp = (int)(lpszTemp - lpXML);
-
-        pXML->nIndex += cbTemp+(int)xstrlen(pClear.lpszClose);
-
-        // Add the clear node to the current element
-        addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear.lpszOpen, pClear.lpszClose,-1);
-        return 0;
-    }
-
-    // If we failed to find the end tag
-    pXML->error = eXMLErrorUnmatchedEndClearTag;
-    return 1;
-}
-
-void XMLNode::exactMemory(XMLNodeData *d)
-{
-    if (d->pOrder)     d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*sizeof(int));
-    if (d->pChild)     d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode));
-    if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute));
-    if (d->pText)      d->pText=(XMLCSTR*)realloc(d->pText,d->nText*sizeof(XMLSTR));
-    if (d->pClear)     d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear));
-}
-
-char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr)
-{
-    XML *pXML=(XML *)pa;
-    XMLCSTR lpszText=pXML->lpszText;
-    if (!lpszText) return 0;
-    if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++;
-    int cbText = (int)(tokenPStr - lpszText);
-    if (!cbText) { pXML->lpszText=NULL; return 0; }
-    if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; }
-    if (!cbText) { pXML->lpszText=NULL; return 0; }
-    XMLSTR lpt=fromXMLString(lpszText,cbText,pXML);
-    if (!lpt) return 1;
-    pXML->lpszText=NULL;
-    if (removeCommentsInMiddleOfText && d->nText && d->nClear)
-    {
-        // if the previous insertion was a comment (<!-- -->) AND
-        // if the previous previous insertion was a text then, delete the comment and append the text
-        int n=d->nChild+d->nText+d->nClear-1,*o=d->pOrder;
-        if (((o[n]&3)==eNodeClear)&&((o[n-1]&3)==eNodeText))
-        {
-            int i=o[n]>>2;
-            if (d->pClear[i].lpszOpenTag==XMLClearTags[2].lpszOpen)
-            {
-                deleteClear(i);
-                i=o[n-1]>>2;
-                n=xstrlen(d->pText[i]);
-                int n2=xstrlen(lpt)+1;
-                d->pText[i]=(XMLSTR)realloc((void*)d->pText[i],(n+n2)*sizeof(XMLCHAR));
-                if (!d->pText[i]) return 1;
-                memcpy((void*)(d->pText[i]+n),lpt,n2*sizeof(XMLCHAR));
-                free(lpt);
-                return 0;
-            }
-        }
-    }
-    addText_priv(MEMORYINCREASE,lpt,-1);
-    return 0;
-}
-// private:
-// Recursively parse an XML element.
-int XMLNode::ParseXMLElement(void *pa)
-{
-    XML *pXML=(XML *)pa;
-    int cbToken;
-    enum XMLTokenTypeTag xtype;
-    NextToken token;
-    XMLCSTR lpszTemp=NULL;
-    int cbTemp=0;
-    char nDeclaration;
-    XMLNode pNew;
-    enum Status status; // inside or outside a tag
-    enum Attrib attrib = eAttribName;
-
-    assert(pXML);
-
-    // If this is the first call to the function
-    if (pXML->nFirst)
-    {
-        // Assume we are outside of a tag definition
-        pXML->nFirst = FALSE;
-        status = eOutsideTag;
-    } else
-    {
-        // If this is not the first call then we should only be called when inside a tag.
-        status = eInsideTag;
-    }
-
-    // Iterate through the tokens in the document
-    for(;;)
-    {
-        // Obtain the next token
-        token = GetNextToken(pXML, &cbToken, &xtype);
-
-        if (xtype != eTokenError)
-        {
-            // Check the current status
-            switch(status)
-            {
-
-            // If we are outside of a tag definition
-            case eOutsideTag:
-
-                // Check what type of token we obtained
-                switch(xtype)
-                {
-                // If we have found text or quoted text
-                case eTokenText:
-                case eTokenCloseTag:          /* '>'         */
-                case eTokenShortHandClose:    /* '/>'        */
-                case eTokenQuotedText:
-                case eTokenEquals:
-                    break;
-
-                // If we found a start tag '<' and declarations '<?'
-                case eTokenTagStart:
-                case eTokenDeclaration:
-
-                    // Cache whether this new element is a declaration or not
-                    nDeclaration = (xtype == eTokenDeclaration);
-
-                    // If we have node text then add this to the element
-                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
-
-                    // Find the name of the tag
-                    token = GetNextToken(pXML, &cbToken, &xtype);
-
-                    // Return an error if we couldn't obtain the next token or
-                    // it wasnt text
-                    if (xtype != eTokenText)
-                    {
-                        pXML->error = eXMLErrorMissingTagName;
-                        return FALSE;
-                    }
-
-                    // If we found a new element which is the same as this
-                    // element then we need to pass this back to the caller..
-
-#ifdef APPROXIMATE_PARSING
-                    if (d->lpszName &&
-                        myTagCompare(d->lpszName, token.pStr) == 0)
-                    {
-                        // Indicate to the caller that it needs to create a
-                        // new element.
-                        pXML->lpNewElement = token.pStr;
-                        pXML->cbNewElement = cbToken;
-                        return TRUE;
-                    } else
-#endif
-                    {
-                        // If the name of the new element differs from the name of
-                        // the current element we need to add the new element to
-                        // the current one and recurse
-                        pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1);
-
-                        while (!pNew.isEmpty())
-                        {
-                            // Callself to process the new node.  If we return
-                            // FALSE this means we dont have any more
-                            // processing to do...
-
-                            if (!pNew.ParseXMLElement(pXML)) return FALSE;
-                            else
-                            {
-                                // If the call to recurse this function
-                                // evented in a end tag specified in XML then
-                                // we need to unwind the calls to this
-                                // function until we find the appropriate node
-                                // (the element name and end tag name must
-                                // match)
-                                if (pXML->cbEndTag)
-                                {
-                                    // If we are back at the root node then we
-                                    // have an unmatched end tag
-                                    if (!d->lpszName)
-                                    {
-                                        pXML->error=eXMLErrorUnmatchedEndTag;
-                                        return FALSE;
-                                    }
-
-                                    // If the end tag matches the name of this
-                                    // element then we only need to unwind
-                                    // once more...
-
-                                    if (myTagCompare(d->lpszName, pXML->lpEndTag)==0)
-                                    {
-                                        pXML->cbEndTag = 0;
-                                    }
-
-                                    return TRUE;
-                                } else
-                                    if (pXML->cbNewElement)
-                                    {
-                                        // If the call indicated a new element is to
-                                        // be created on THIS element.
-
-                                        // If the name of this element matches the
-                                        // name of the element we need to create
-                                        // then we need to return to the caller
-                                        // and let it process the element.
-
-                                        if (myTagCompare(d->lpszName, pXML->lpNewElement)==0)
-                                        {
-                                            return TRUE;
-                                        }
-
-                                        // Add the new element and recurse
-                                        pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1);
-                                        pXML->cbNewElement = 0;
-                                    }
-                                    else
-                                    {
-                                        // If we didn't have a new element to create
-                                        pNew = emptyXMLNode;
-
-                                    }
-                            }
-                        }
-                    }
-                    break;
-
-                // If we found an end tag
-                case eTokenTagEnd:
-
-                    // If we have node text then add this to the element
-                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
-
-                    // Find the name of the end tag
-                    token = GetNextToken(pXML, &cbTemp, &xtype);
-
-                    // The end tag should be text
-                    if (xtype != eTokenText)
-                    {
-                        pXML->error = eXMLErrorMissingEndTagName;
-                        return FALSE;
-                    }
-                    lpszTemp = token.pStr;
-
-                    // After the end tag we should find a closing tag
-                    token = GetNextToken(pXML, &cbToken, &xtype);
-                    if (xtype != eTokenCloseTag)
-                    {
-                        pXML->error = eXMLErrorMissingEndTagName;
-                        return FALSE;
-                    }
-                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
-
-                    // We need to return to the previous caller.  If the name
-                    // of the tag cannot be found we need to keep returning to
-                    // caller until we find a match
-                    if (myTagCompare(d->lpszName, lpszTemp) != 0)
-#ifdef STRICT_PARSING
-                    {
-                        pXML->error=eXMLErrorUnmatchedEndTag;
-                        pXML->nIndexMissigEndTag=pXML->nIndex;
-                        return FALSE;
-                    }
-#else
-                    {
-                        pXML->error=eXMLErrorMissingEndTag;
-                        pXML->nIndexMissigEndTag=pXML->nIndex;
-                        pXML->lpEndTag = lpszTemp;
-                        pXML->cbEndTag = cbTemp;
-                    }
-#endif
-
-                    // Return to the caller
-                    exactMemory(d);
-                    return TRUE;
-
-                // If we found a clear (unformatted) token
-                case eTokenClear:
-                    // If we have node text then add this to the element
-                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
-                    if (parseClearTag(pXML, token.pClr)) return FALSE;
-                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
-                    break;
-
-                default:
-                    break;
-                }
-                break;
-
-            // If we are inside a tag definition we need to search for attributes
-            case eInsideTag:
-
-                // Check what part of the attribute (name, equals, value) we
-                // are looking for.
-                switch(attrib)
-                {
-                // If we are looking for a new attribute
-                case eAttribName:
-
-                    // Check what the current token type is
-                    switch(xtype)
-                    {
-                    // If the current type is text...
-                    // Eg.  'attribute'
-                    case eTokenText:
-                        // Cache the token then indicate that we are next to
-                        // look for the equals
-                        lpszTemp = token.pStr;
-                        cbTemp = cbToken;
-                        attrib = eAttribEquals;
-                        break;
-
-                    // If we found a closing tag...
-                    // Eg.  '>'
-                    case eTokenCloseTag:
-                        // We are now outside the tag
-                        status = eOutsideTag;
-                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
-                        break;
-
-                    // If we found a short hand '/>' closing tag then we can
-                    // return to the caller
-                    case eTokenShortHandClose:
-                        exactMemory(d);
-                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
-                        return TRUE;
-
-                    // Errors...
-                    case eTokenQuotedText:    /* '"SomeText"'   */
-                    case eTokenTagStart:      /* '<'            */
-                    case eTokenTagEnd:        /* '</'           */
-                    case eTokenEquals:        /* '='            */
-                    case eTokenDeclaration:   /* '<?'           */
-                    case eTokenClear:
-                        pXML->error = eXMLErrorUnexpectedToken;
-                        return FALSE;
-                    default: break;
-                    }
-                    break;
-
-                // If we are looking for an equals
-                case eAttribEquals:
-                    // Check what the current token type is
-                    switch(xtype)
-                    {
-                    // If the current type is text...
-                    // Eg.  'Attribute AnotherAttribute'
-                    case eTokenText:
-                        // Add the unvalued attribute to the list
-                        addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
-                        // Cache the token then indicate.  We are next to
-                        // look for the equals attribute
-                        lpszTemp = token.pStr;
-                        cbTemp = cbToken;
-                        break;
-
-                    // If we found a closing tag 'Attribute >' or a short hand
-                    // closing tag 'Attribute />'
-                    case eTokenShortHandClose:
-                    case eTokenCloseTag:
-                        // If we are a declaration element '<?' then we need
-                        // to remove extra closing '?' if it exists
-                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
-
-                        if (d->isDeclaration &&
-                            (lpszTemp[cbTemp-1]) == _CXML('?'))
-                        {
-                            cbTemp--;
-                            if (d->pParent && d->pParent->pParent) xtype = eTokenShortHandClose;
-                        }
-
-                        if (cbTemp)
-                        {
-                            // Add the unvalued attribute to the list
-                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
-                        }
-
-                        // If this is the end of the tag then return to the caller
-                        if (xtype == eTokenShortHandClose)
-                        {
-                            exactMemory(d);
-                            return TRUE;
-                        }
-
-                        // We are now outside the tag
-                        status = eOutsideTag;
-                        break;
-
-                    // If we found the equals token...
-                    // Eg.  'Attribute ='
-                    case eTokenEquals:
-                        // Indicate that we next need to search for the value
-                        // for the attribute
-                        attrib = eAttribValue;
-                        break;
-
-                    // Errors...
-                    case eTokenQuotedText:    /* 'Attribute "InvalidAttr"'*/
-                    case eTokenTagStart:      /* 'Attribute <'            */
-                    case eTokenTagEnd:        /* 'Attribute </'           */
-                    case eTokenDeclaration:   /* 'Attribute <?'           */
-                    case eTokenClear:
-                        pXML->error = eXMLErrorUnexpectedToken;
-                        return FALSE;
-                    default: break;
-                    }
-                    break;
-
-                // If we are looking for an attribute value
-                case eAttribValue:
-                    // Check what the current token type is
-                    switch(xtype)
-                    {
-                    // If the current type is text or quoted text...
-                    // Eg.  'Attribute = "Value"' or 'Attribute = Value' or
-                    // 'Attribute = 'Value''.
-                    case eTokenText:
-                    case eTokenQuotedText:
-                        // If we are a declaration element '<?' then we need
-                        // to remove extra closing '?' if it exists
-                        if (d->isDeclaration &&
-                            (token.pStr[cbToken-1]) == _CXML('?'))
-                        {
-                            cbToken--;
-                        }
-
-                        if (cbTemp)
-                        {
-                            // Add the valued attribute to the list
-                            if (xtype==eTokenQuotedText) { token.pStr++; cbToken-=2; }
-                            XMLSTR attrVal=(XMLSTR)token.pStr;
-                            if (attrVal)
-                            {
-                                attrVal=fromXMLString(attrVal,cbToken,pXML);
-                                if (!attrVal) return FALSE;
-                            }
-                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal);
-                        }
-
-                        // Indicate we are searching for a new attribute
-                        attrib = eAttribName;
-                        break;
-
-                    // Errors...
-                    case eTokenTagStart:        /* 'Attr = <'          */
-                    case eTokenTagEnd:          /* 'Attr = </'         */
-                    case eTokenCloseTag:        /* 'Attr = >'          */
-                    case eTokenShortHandClose:  /* "Attr = />"         */
-                    case eTokenEquals:          /* 'Attr = ='          */
-                    case eTokenDeclaration:     /* 'Attr = <?'         */
-                    case eTokenClear:
-                        pXML->error = eXMLErrorUnexpectedToken;
-                        return FALSE;
-                        break;
-                    default: break;
-                    }
-                }
-            }
-        }
-        // If we failed to obtain the next token
-        else
-        {
-            if ((!d->isDeclaration)&&(d->pParent))
-            {
-#ifdef STRICT_PARSING
-                pXML->error=eXMLErrorUnmatchedEndTag;
-#else
-                pXML->error=eXMLErrorMissingEndTag;
-#endif
-                pXML->nIndexMissigEndTag=pXML->nIndex;
-            }
-            maybeAddTxT(pXML,pXML->lpXML+pXML->nIndex);
-            return FALSE;
-        }
-    }
-}
-
-// Count the number of lines and columns in an XML string.
-static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults)
-{
-    XMLCHAR ch;
-    assert(lpXML);
-    assert(pResults);
-
-    struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
-
-    pResults->nLine = 1;
-    pResults->nColumn = 1;
-    while (xml.nIndex<nUpto)
-    {
-        ch = getNextChar(&xml);
-        if (ch != _CXML('\n')) pResults->nColumn++;
-        else
-        {
-            pResults->nLine++;
-            pResults->nColumn=1;
-        }
-    }
-}
-
-// Parse XML and return the root element.
-XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults)
-{
-    if (!lpszXML)
-    {
-        if (pResults)
-        {
-            pResults->error=eXMLErrorNoElements;
-            pResults->nLine=0;
-            pResults->nColumn=0;
-        }
-        return emptyXMLNode;
-    }
-
-    XMLNode xnode(NULL,NULL,FALSE);
-    struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
-
-    // Create header element
-    xnode.ParseXMLElement(&xml);
-    enum XMLError error = xml.error;
-    if (!xnode.nChildNode()) error=eXMLErrorNoXMLTagFound;
-    if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node
-
-    // If no error occurred
-    if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag)||(error==eXMLErrorNoXMLTagFound))
-    {
-        XMLCSTR name=xnode.getName();
-        if (tag&&(*tag)&&((!name)||(xstricmp(name,tag))))
-        {
-            xnode=xnode.getChildNode(tag);
-            if (xnode.isEmpty())
-            {
-                if (pResults)
-                {
-                    pResults->error=eXMLErrorFirstTagNotFound;
-                    pResults->nLine=0;
-                    pResults->nColumn=0;
-                }
-                return emptyXMLNode;
-            }
-        }
-    } else
-    {
-        // Cleanup: this will destroy all the nodes
-        xnode = emptyXMLNode;
-    }
-
-
-    // If we have been given somewhere to place results
-    if (pResults)
-    {
-        pResults->error = error;
-
-        // If we have an error
-        if (error!=eXMLErrorNone)
-        {
-            if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag;
-            // Find which line and column it starts on.
-            CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);
-        }
-    }
-    return xnode;
-}
-
-XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults)
-{
-    if (pResults) { pResults->nLine=0; pResults->nColumn=0; }
-    FILE *f=xfopen(filename,_CXML("rb"));
-    if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; }
-    fseek(f,0,SEEK_END);
-    int l=(int)ftell(f),headerSz=0;
-    if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; fclose(f); return emptyXMLNode; }
-    fseek(f,0,SEEK_SET);
-    unsigned char *buf=(unsigned char*)malloc(l+4);
-    l=(int)fread(buf,1,l,f);
-    fclose(f);
-    buf[l]=0;buf[l+1]=0;buf[l+2]=0;buf[l+3]=0;
-#ifdef _XMLWIDECHAR
-    if (guessWideCharChars)
-    {
-        if (!myIsTextWideChar(buf,l))
-        {
-            XMLNode::XMLCharEncoding ce=XMLNode::char_encoding_legacy;
-            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) { headerSz=3; ce=XMLNode::char_encoding_UTF8; }
-            XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz),ce);
-            free(buf); buf=(unsigned char*)b2; headerSz=0;
-        } else
-        {
-            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
-            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
-        }
-    }
-#else
-    if (guessWideCharChars)
-    {
-        if (myIsTextWideChar(buf,l))
-        {
-            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
-            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
-            char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz));
-            free(buf); buf=(unsigned char*)b2; headerSz=0;
-        } else
-        {
-            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
-        }
-    }
-#endif
-
-    if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; }
-    XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults);
-    free(buf);
-    return x;
-}
-
-static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; }
-// private:
-// Creates an user friendly XML string from a given element with
-// appropriate white space and carriage returns.
-//
-// This recurses through all subnodes then adds contents of the nodes to the
-// string.
-int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat)
-{
-    int nResult = 0;
-    int cb=nFormat<0?0:nFormat;
-    int cbElement;
-    int nChildFormat=-1;
-    int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear;
-    int i,j;
-    if ((nFormat>=0)&&(nElementI==1)&&(pEntry->nText==1)&&(!pEntry->isDeclaration)) nFormat=-2;
-
-    assert(pEntry);
-
-#define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0)
-
-    // If the element has no name then assume this is the head node.
-    cbElement = (int)LENSTR(pEntry->lpszName);
-
-    if (cbElement)
-    {
-        // "<elementname "
-        if (lpszMarker)
-        {
-            if (cb) charmemset(lpszMarker, INDENTCHAR, cb);
-            nResult = cb;
-            lpszMarker[nResult++]=_CXML('<');
-            if (pEntry->isDeclaration) lpszMarker[nResult++]=_CXML('?');
-            xstrcpy(&lpszMarker[nResult], pEntry->lpszName);
-            nResult+=cbElement;
-            lpszMarker[nResult++]=_CXML(' ');
-
-        } else
-        {
-            nResult+=cbElement+2+cb;
-            if (pEntry->isDeclaration) nResult++;
-        }
-
-        // Enumerate attributes and add them to the string
-        XMLAttribute *pAttr=pEntry->pAttribute;
-        for (i=0; i<pEntry->nAttribute; i++)
-        {
-            // "Attrib
-            cb = (int)LENSTR(pAttr->lpszName);
-            if (cb)
-            {
-                if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName);
-                nResult += cb;
-                // "Attrib=Value "
-                if (pAttr->lpszValue)
-                {
-                    cb=(int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue);
-                    if (lpszMarker)
-                    {
-                        lpszMarker[nResult]=_CXML('=');
-                        lpszMarker[nResult+1]=_CXML('"');
-                        if (cb) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+2],pAttr->lpszValue);
-                        lpszMarker[nResult+cb+2]=_CXML('"');
-                    }
-                    nResult+=cb+3;
-                }
-                if (lpszMarker) lpszMarker[nResult] = _CXML(' ');
-                nResult++;
-            }
-            pAttr++;
-        }
-
-        if (pEntry->isDeclaration)
-        {
-            if (lpszMarker)
-            {
-                lpszMarker[nResult-1]=_CXML('?');
-                lpszMarker[nResult]=_CXML('>');
-            }
-            nResult++;
-            if (nFormat!=-1)
-            {
-                if (lpszMarker) lpszMarker[nResult]=_CXML('\n');
-                nResult++;
-            }
-        } else
-            // If there are child nodes we need to terminate the start tag
-            if (nElementI)
-            {
-                if (lpszMarker) lpszMarker[nResult-1]=_CXML('>');
-                if (nFormat>=0)
-                {
-                    if (lpszMarker) lpszMarker[nResult]=_CXML('\n');
-                    nResult++;
-                }
-            } else nResult--;
-    }
-
-    // Calculate the child format for when we recurse.  This is used to
-    // determine the number of spaces used for prefixes.
-    if (nFormat!=-1)
-    {
-        if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1;
-        else nChildFormat=nFormat;
-    }
-
-    // Enumerate through remaining children
-    for (i=0; i<nElementI; i++)
-    {
-        j=pEntry->pOrder[i];
-        switch((XMLElementType)(j&3))
-        {
-        // Text nodes
-        case eNodeText:
-            {
-                // "Text"
-                XMLCSTR pChild=pEntry->pText[j>>2];
-                cb = (int)ToXMLStringTool::lengthXMLString(pChild);
-                if (cb)
-                {
-                    if (nFormat>=0)
-                    {
-                        if (lpszMarker)
-                        {
-                            charmemset(&lpszMarker[nResult],INDENTCHAR,nFormat+1);
-                            ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+nFormat+1],pChild);
-                            lpszMarker[nResult+nFormat+1+cb]=_CXML('\n');
-                        }
-                        nResult+=cb+nFormat+2;
-                    } else
-                    {
-                        if (lpszMarker) ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], pChild);
-                        nResult += cb;
-                    }
-                }
-                break;
-            }
-
-        // Clear type nodes
-        case eNodeClear:
-            {
-                XMLClear *pChild=pEntry->pClear+(j>>2);
-                // "OpenTag"
-                cb = (int)LENSTR(pChild->lpszOpenTag);
-                if (cb)
-                {
-                    if (nFormat!=-1)
-                    {
-                        if (lpszMarker)
-                        {
-                            charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat+1);
-                            xstrcpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag);
-                        }
-                        nResult+=cb+nFormat+1;
-                    }
-                    else
-                    {
-                        if (lpszMarker)xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag);
-                        nResult += cb;
-                    }
-                }
-
-                // "OpenTag Value"
-                cb = (int)LENSTR(pChild->lpszValue);
-                if (cb)
-                {
-                    if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszValue);
-                    nResult += cb;
-                }
-
-                // "OpenTag Value CloseTag"
-                cb = (int)LENSTR(pChild->lpszCloseTag);
-                if (cb)
-                {
-                    if (lpszMarker) xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag);
-                    nResult += cb;
-                }
-
-                if (nFormat!=-1)
-                {
-                    if (lpszMarker) lpszMarker[nResult] = _CXML('\n');
-                    nResult++;
-                }
-                break;
-            }
-
-        // Element nodes
-        case eNodeChild:
-            {
-                // Recursively add child nodes
-                nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat);
-                break;
-            }
-        default: break;
-        }
-    }
-
-    if ((cbElement)&&(!pEntry->isDeclaration))
-    {
-        // If we have child entries we need to use long XML notation for
-        // closing the element - "<elementname>blah blah blah</elementname>"
-        if (nElementI)
-        {
-            // "</elementname>\0"
-            if (lpszMarker)
-            {
-                if (nFormat >=0)
-                {
-                    charmemset(&lpszMarker[nResult], INDENTCHAR,nFormat);
-                    nResult+=nFormat;
-                }
-
-                lpszMarker[nResult]=_CXML('<'); lpszMarker[nResult+1]=_CXML('/');
-                nResult += 2;
-                xstrcpy(&lpszMarker[nResult], pEntry->lpszName);
-                nResult += cbElement;
-
-                lpszMarker[nResult]=_CXML('>');
-                if (nFormat == -1) nResult++;
-                else
-                {
-                    lpszMarker[nResult+1]=_CXML('\n');
-                    nResult+=2;
-                }
-            } else
-            {
-                if (nFormat>=0) nResult+=cbElement+4+nFormat;
-                else if (nFormat==-1) nResult+=cbElement+3;
-                else nResult+=cbElement+4;
-            }
-        } else
-        {
-            // If there are no children we can use shorthand XML notation -
-            // "<elementname/>"
-            // "/>\0"
-            if (lpszMarker)
-            {
-                lpszMarker[nResult]=_CXML('/'); lpszMarker[nResult+1]=_CXML('>');
-                if (nFormat != -1) lpszMarker[nResult+2]=_CXML('\n');
-            }
-            nResult += nFormat == -1 ? 2 : 3;
-        }
-    }
-
-    return nResult;
-}
-
-#undef LENSTR
-
-// Create an XML string
-// @param       int nFormat             - 0 if no formatting is required
-//                                        otherwise nonzero for formatted text
-//                                        with carriage returns and indentation.
-// @param       int *pnSize             - [out] pointer to the size of the
-//                                        returned string not including the
-//                                        NULL terminator.
-// @return      XMLSTR                  - Allocated XML string, you must free
-//                                        this with free().
-XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const
-{
-    if (!d) { if (pnSize) *pnSize=0; return NULL; }
-
-    XMLSTR lpszResult = NULL;
-    int cbStr;
-
-    // Recursively Calculate the size of the XML string
-    if (!dropWhiteSpace) nFormat=0;
-    nFormat = nFormat ? 0 : -1;
-    cbStr = CreateXMLStringR(d, 0, nFormat);
-    // Alllocate memory for the XML string + the NULL terminator and
-    // create the recursively XML string.
-    lpszResult=(XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR));
-    CreateXMLStringR(d, lpszResult, nFormat);
-    lpszResult[cbStr]=_CXML('\0');
-    if (pnSize) *pnSize = cbStr;
-    return lpszResult;
-}
-
-int XMLNode::detachFromParent(XMLNodeData *d)
-{
-    XMLNode *pa=d->pParent->pChild;
-    int i=0;
-    while (((void*)(pa[i].d))!=((void*)d)) i++;
-    d->pParent->nChild--;
-    if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*sizeof(XMLNode));
-    else { free(pa); d->pParent->pChild=NULL; }
-    return removeOrderElement(d->pParent,eNodeChild,i);
-}
-
-XMLNode::~XMLNode()
-{
-    if (!d) return;
-    d->ref_count--;
-    emptyTheNode(0);
-}
-void XMLNode::deleteNodeContent()
-{
-    if (!d) return;
-    if (d->pParent) { detachFromParent(d); d->pParent=NULL; d->ref_count--; }
-    emptyTheNode(1);
-}
-void XMLNode::emptyTheNode(char force)
-{
-    XMLNodeData *dd=d; // warning: must stay this way!
-    if ((dd->ref_count==0)||force)
-    {
-        if (d->pParent) detachFromParent(d);
-        int i;
-        XMLNode *pc;
-        for(i=0; i<dd->nChild; i++)
-        {
-            pc=dd->pChild+i;
-            pc->d->pParent=NULL;
-            pc->d->ref_count--;
-            pc->emptyTheNode(force);
-        }
-        myFree(dd->pChild);
-        for(i=0; i<dd->nText; i++) free((void*)dd->pText[i]);
-        myFree(dd->pText);
-        for(i=0; i<dd->nClear; i++) free((void*)dd->pClear[i].lpszValue);
-        myFree(dd->pClear);
-        for(i=0; i<dd->nAttribute; i++)
-        {
-            free((void*)dd->pAttribute[i].lpszName);
-            if (dd->pAttribute[i].lpszValue) free((void*)dd->pAttribute[i].lpszValue);
-        }
-        myFree(dd->pAttribute);
-        myFree(dd->pOrder);
-        myFree((void*)dd->lpszName);
-        dd->nChild=0;    dd->nText=0;    dd->nClear=0;    dd->nAttribute=0;
-        dd->pChild=NULL; dd->pText=NULL; dd->pClear=NULL; dd->pAttribute=NULL;
-        dd->pOrder=NULL; dd->lpszName=NULL; dd->pParent=NULL;
-    }
-    if (dd->ref_count==0)
-    {
-        free(dd);
-        d=NULL;
-    }
-}
-
-XMLNode& XMLNode::operator=( const XMLNode& A )
-{
-    // shallow copy
-    if (this != &A)
-    {
-        if (d) { d->ref_count--; emptyTheNode(0); }
-        d=A.d;
-        if (d) (d->ref_count) ++ ;
-    }
-    return *this;
-}
-
-XMLNode::XMLNode(const XMLNode &A)
-{
-    // shallow copy
-    d=A.d;
-    if (d) (d->ref_count)++ ;
-}
-
-XMLNode XMLNode::deepCopy() const
-{
-    if (!d) return XMLNode::emptyXMLNode;
-    XMLNode x(NULL,stringDup(d->lpszName),d->isDeclaration);
-    XMLNodeData *p=x.d;
-    int n=d->nAttribute;
-    if (n)
-    {
-        p->nAttribute=n; p->pAttribute=(XMLAttribute*)malloc(n*sizeof(XMLAttribute));
-        while (n--)
-        {
-            p->pAttribute[n].lpszName=stringDup(d->pAttribute[n].lpszName);
-            p->pAttribute[n].lpszValue=stringDup(d->pAttribute[n].lpszValue);
-        }
-    }
-    if (d->pOrder)
-    {
-        n=(d->nChild+d->nText+d->nClear)*sizeof(int); p->pOrder=(int*)malloc(n); memcpy(p->pOrder,d->pOrder,n);
-    }
-    n=d->nText;
-    if (n)
-    {
-        p->nText=n; p->pText=(XMLCSTR*)malloc(n*sizeof(XMLCSTR));
-        while(n--) p->pText[n]=stringDup(d->pText[n]);
-    }
-    n=d->nClear;
-    if (n)
-    {
-        p->nClear=n; p->pClear=(XMLClear*)malloc(n*sizeof(XMLClear));
-        while (n--)
-        {
-            p->pClear[n].lpszCloseTag=d->pClear[n].lpszCloseTag;
-            p->pClear[n].lpszOpenTag=d->pClear[n].lpszOpenTag;
-            p->pClear[n].lpszValue=stringDup(d->pClear[n].lpszValue);
-        }
-    }
-    n=d->nChild;
-    if (n)
-    {
-        p->nChild=n; p->pChild=(XMLNode*)malloc(n*sizeof(XMLNode));
-        while (n--)
-        {
-            p->pChild[n].d=NULL;
-            p->pChild[n]=d->pChild[n].deepCopy();
-            p->pChild[n].d->pParent=p;
-        }
-    }
-    return x;
-}
-
-XMLNode XMLNode::addChild(XMLNode childNode, int pos)
-{
-    XMLNodeData *dc=childNode.d;
-    if ((!dc)||(!d)) return childNode;
-    if (!dc->lpszName)
-    {
-        // this is a root node: todo: correct fix
-        int j=pos;
-        while (dc->nChild)
-        {
-            addChild(dc->pChild[0],j);
-            if (pos>=0) j++;
-        }
-        return childNode;
-    }
-    if (dc->pParent) { if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; } else dc->ref_count++;
-    dc->pParent=d;
-//     int nc=d->nChild;
-//     d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode));
-    d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
-    d->pChild[pos].d=dc;
-    d->nChild++;
-    return childNode;
-}
-
-void XMLNode::deleteAttribute(int i)
-{
-    if ((!d)||(i<0)||(i>=d->nAttribute)) return;
-    d->nAttribute--;
-    XMLAttribute *p=d->pAttribute+i;
-    free((void*)p->lpszName);
-    if (p->lpszValue) free((void*)p->lpszValue);
-    if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute=NULL; }
-}
-
-void XMLNode::deleteAttribute(XMLAttribute *a){ if (a) deleteAttribute(a->lpszName); }
-void XMLNode::deleteAttribute(XMLCSTR lpszName)
-{
-    int j=0;
-    getAttribute(lpszName,&j);
-    if (j) deleteAttribute(j-1);
-}
-
-XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,int i)
-{
-    if (!d) { if (lpszNewValue) free(lpszNewValue); if (lpszNewName) free(lpszNewName); return NULL; }
-    if (i>=d->nAttribute)
-    {
-        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
-        return NULL;
-    }
-    XMLAttribute *p=d->pAttribute+i;
-    if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((void*)p->lpszValue);
-    p->lpszValue=lpszNewValue;
-    if (lpszNewName&&p->lpszName!=lpszNewName) { free((void*)p->lpszName); p->lpszName=lpszNewName; };
-    return p;
-}
-
-XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
-{
-    if (oldAttribute) return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue,(XMLSTR)newAttribute->lpszName,oldAttribute->lpszName);
-    return addAttribute_WOSD((XMLSTR)newAttribute->lpszName,(XMLSTR)newAttribute->lpszValue);
-}
-
-XMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName)
-{
-    int j=0;
-    getAttribute(lpszOldName,&j);
-    if (j) return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1);
-    else
-    {
-        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
-        else             return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue);
-    }
-}
-
-int XMLNode::indexText(XMLCSTR lpszValue) const
-{
-    if (!d) return -1;
-    int i,l=d->nText;
-    if (!lpszValue) { if (l) return 0; return -1; }
-    XMLCSTR *p=d->pText;
-    for (i=0; i<l; i++) if (lpszValue==p[i]) return i;
-    return -1;
-}
-
-void XMLNode::deleteText(int i)
-{
-    if ((!d)||(i<0)||(i>=d->nText)) return;
-    d->nText--;
-    XMLCSTR *p=d->pText+i;
-    free((void*)*p);
-    if (d->nText) memmove(p,p+1,(d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText=NULL; }
-    removeOrderElement(d,eNodeText,i);
-}
-
-void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); }
-
-XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i)
-{
-    if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; }
-    if (i>=d->nText) return addText_WOSD(lpszNewValue);
-    XMLCSTR *p=d->pText+i;
-    if (*p!=lpszNewValue) { free((void*)*p); *p=lpszNewValue; }
-    return lpszNewValue;
-}
-
-XMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue)
-{
-    if (!d) { if (lpszNewValue) free(lpszNewValue); return NULL; }
-    int i=indexText(lpszOldValue);
-    if (i>=0) return updateText_WOSD(lpszNewValue,i);
-    return addText_WOSD(lpszNewValue);
-}
-
-void XMLNode::deleteClear(int i)
-{
-    if ((!d)||(i<0)||(i>=d->nClear)) return;
-    d->nClear--;
-    XMLClear *p=d->pClear+i;
-    free((void*)p->lpszValue);
-    if (d->nClear) memmove(p,p+1,(d->nClear-i)*sizeof(XMLClear)); else { free(p); d->pClear=NULL; }
-    removeOrderElement(d,eNodeClear,i);
-}
-
-int XMLNode::indexClear(XMLCSTR lpszValue) const
-{
-    if (!d) return -1;
-    int i,l=d->nClear;
-    if (!lpszValue) { if (l) return 0; return -1; }
-    XMLClear *p=d->pClear;
-    for (i=0; i<l; i++) if (lpszValue==p[i].lpszValue) return i;
-    return -1;
-}
-
-void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); }
-void XMLNode::deleteClear(XMLClear *a) { if (a) deleteClear(a->lpszValue); }
-
-XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i)
-{
-    if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; }
-    if (i>=d->nClear) return addClear_WOSD(lpszNewContent);
-    XMLClear *p=d->pClear+i;
-    if (lpszNewContent!=p->lpszValue) { free((void*)p->lpszValue); p->lpszValue=lpszNewContent; }
-    return p;
-}
-
-XMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, XMLCSTR lpszOldValue)
-{
-    if (!d) { if (lpszNewContent) free(lpszNewContent); return NULL; }
-    int i=indexClear(lpszOldValue);
-    if (i>=0) return updateClear_WOSD(lpszNewContent,i);
-    return addClear_WOSD(lpszNewContent);
-}
-
-XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP)
-{
-    if (oldP) return updateClear_WOSD((XMLSTR)newP->lpszValue,(XMLSTR)oldP->lpszValue);
-    return NULL;
-}
-
-int XMLNode::nChildNode(XMLCSTR name) const
-{
-    if (!d) return 0;
-    int i,j=0,n=d->nChild;
-    XMLNode *pc=d->pChild;
-    for (i=0; i<n; i++)
-    {
-        if (xstricmp(pc->d->lpszName, name)==0) j++;
-        pc++;
-    }
-    return j;
-}
-
-XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const
-{
-    if (!d) return emptyXMLNode;
-    int i=0,n=d->nChild;
-    if (j) i=*j;
-    XMLNode *pc=d->pChild+i;
-    for (; i<n; i++)
-    {
-        if (!xstricmp(pc->d->lpszName, name))
-        {
-            if (j) *j=i+1;
-            return *pc;
-        }
-        pc++;
-    }
-    return emptyXMLNode;
-}
-
-XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const
-{
-    if (!d) return emptyXMLNode;
-    if (j>=0)
-    {
-        int i=0;
-        while (j-->0) getChildNode(name,&i);
-        return getChildNode(name,&i);
-    }
-    int i=d->nChild;
-    while (i--) if (!xstricmp(name,d->pChild[i].d->lpszName)) break;
-    if (i<0) return emptyXMLNode;
-    return getChildNode(i);
-}
-
-XMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, XMLCHAR sep)
-{
-    XMLSTR path=stringDup(_path);
-    XMLNode x=getChildNodeByPathNonConst(path,createMissing,sep);
-    if (path) free(path);
-    return x;
-}
-
-XMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, char createIfMissing, XMLCHAR sep)
-{
-    if ((!path)||(!(*path))) return *this;
-    XMLNode xn,xbase=*this;
-    XMLCHAR *tend1,sepString[2]; sepString[0]=sep; sepString[1]=0;
-    tend1=xstrstr(path,sepString);
-    while(tend1)
-    {
-        *tend1=0;
-        xn=xbase.getChildNode(path);
-        if (xn.isEmpty())
-        {
-            if (createIfMissing) xn=xbase.addChild(path);
-            else { *tend1=sep; return XMLNode::emptyXMLNode; }
-        }
-        *tend1=sep;
-        xbase=xn;
-        path=tend1+1;
-        tend1=xstrstr(path,sepString);
-    }
-    xn=xbase.getChildNode(path);
-    if (xn.isEmpty()&&createIfMissing) xn=xbase.addChild(path);
-    return xn;
-}
-
-XMLElementPosition XMLNode::positionOfText     (int i) const { if (i>=d->nText ) i=d->nText-1;  return findPosition(d,i,eNodeText ); }
-XMLElementPosition XMLNode::positionOfClear    (int i) const { if (i>=d->nClear) i=d->nClear-1; return findPosition(d,i,eNodeClear); }
-XMLElementPosition XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i=d->nChild-1; return findPosition(d,i,eNodeChild); }
-XMLElementPosition XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); }
-XMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); }
-XMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); }
-XMLElementPosition XMLNode::positionOfChildNode(XMLNode x)  const
-{
-    if ((!d)||(!x.d)) return -1;
-    XMLNodeData *dd=x.d;
-    XMLNode *pc=d->pChild;
-    int i=d->nChild;
-    while (i--) if (pc[i].d==dd) return findPosition(d,i,eNodeChild);
-    return -1;
-}
-XMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const
-{
-    if (!name) return positionOfChildNode(count);
-    int j=0;
-    do { getChildNode(name,&j); if (j<0) return -1; } while (count--);
-    return findPosition(d,j-1,eNodeChild);
-}
-
-XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue, int *k) const
-{
-     int i=0,j;
-     if (k) i=*k;
-     XMLNode x;
-     XMLCSTR t;
-     do
-     {
-         x=getChildNode(name,&i);
-         if (!x.isEmpty())
-         {
-             if (attributeValue)
-             {
-                 j=0;
-                 do
-                 {
-                     t=x.getAttribute(attributeName,&j);
-                     if (t&&(xstricmp(attributeValue,t)==0)) { if (k) *k=i; return x; }
-                 } while (t);
-             } else
-             {
-                 if (x.isAttributeSet(attributeName)) { if (k) *k=i; return x; }
-             }
-         }
-     } while (!x.isEmpty());
-     return emptyXMLNode;
-}
-
-// Find an attribute on an node.
-XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const
-{
-    if (!d) return NULL;
-    int i=0,n=d->nAttribute;
-    if (j) i=*j;
-    XMLAttribute *pAttr=d->pAttribute+i;
-    for (; i<n; i++)
-    {
-        if (xstricmp(pAttr->lpszName, lpszAttrib)==0)
-        {
-            if (j) *j=i+1;
-            return pAttr->lpszValue;
-        }
-        pAttr++;
-    }
-    return NULL;
-}
-
-char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const
-{
-    if (!d) return FALSE;
-    int i,n=d->nAttribute;
-    XMLAttribute *pAttr=d->pAttribute;
-    for (i=0; i<n; i++)
-    {
-        if (xstricmp(pAttr->lpszName, lpszAttrib)==0)
-        {
-            return TRUE;
-        }
-        pAttr++;
-    }
-    return FALSE;
-}
-
-XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const
-{
-    if (!d) return NULL;
-    int i=0;
-    while (j-->0) getAttribute(name,&i);
-    return getAttribute(name,&i);
-}
-
-XMLNodeContents XMLNode::enumContents(int i) const
-{
-    XMLNodeContents c;
-    if (!d) { c.etype=eNodeNULL; return c; }
-    if (i<d->nAttribute)
-    {
-        c.etype=eNodeAttribute;
-        c.attrib=d->pAttribute[i];
-        return c;
-    }
-    i-=d->nAttribute;
-    c.etype=(XMLElementType)(d->pOrder[i]&3);
-    i=(d->pOrder[i])>>2;
-    switch (c.etype)
-    {
-    case eNodeChild:     c.child = d->pChild[i];      break;
-    case eNodeText:      c.text  = d->pText[i];       break;
-    case eNodeClear:     c.clear = d->pClear[i];      break;
-    default: break;
-    }
-    return c;
-}
-
-XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName;   }
-int XMLNode::nText()       const { if (!d) return 0;    return d->nText;      }
-int XMLNode::nChildNode()  const { if (!d) return 0;    return d->nChild;     }
-int XMLNode::nAttribute()  const { if (!d) return 0;    return d->nAttribute; }
-int XMLNode::nClear()      const { if (!d) return 0;    return d->nClear;     }
-int XMLNode::nElement()    const { if (!d) return 0;    return d->nAttribute+d->nChild+d->nText+d->nClear; }
-XMLClear     XMLNode::getClear         (int i) const { if ((!d)||(i>=d->nClear    )) return emptyXMLClear;     return d->pClear[i];     }
-XMLAttribute XMLNode::getAttribute     (int i) const { if ((!d)||(i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; }
-XMLCSTR      XMLNode::getAttributeName (int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszName;  }
-XMLCSTR      XMLNode::getAttributeValue(int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszValue; }
-XMLCSTR      XMLNode::getText          (int i) const { if ((!d)||(i>=d->nText     )) return NULL;              return d->pText[i];      }
-XMLNode      XMLNode::getChildNode     (int i) const { if ((!d)||(i>=d->nChild    )) return emptyXMLNode;      return d->pChild[i];     }
-XMLNode      XMLNode::getParentNode    (     ) const { if ((!d)||(!d->pParent     )) return emptyXMLNode;      return XMLNode(d->pParent); }
-char         XMLNode::isDeclaration    (     ) const { if (!d) return 0;             return d->isDeclaration; }
-char         XMLNode::isEmpty          (     ) const { return (d==NULL); }
-XMLNode       XMLNode::emptyNode       (     )       { return XMLNode::emptyXMLNode; }
-
-XMLNode       XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, XMLElementPosition pos)
-              { return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); }
-XMLNode       XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, XMLElementPosition pos)
-              { return addChild_priv(0,lpszName,isDeclaration,pos); }
-XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue)
-              { return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); }
-XMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev)
-              { return addAttribute_priv(0,lpszName,lpszValuev); }
-XMLCSTR       XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos)
-              { return addText_priv(0,stringDup(lpszValue),pos); }
-XMLCSTR       XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos)
-              { return addText_priv(0,lpszValue,pos); }
-XMLClear     *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos)
-              { return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); }
-XMLClear     *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, XMLElementPosition pos)
-              { return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); }
-XMLCSTR       XMLNode::updateName(XMLCSTR lpszName)
-              { return updateName_WOSD(stringDup(lpszName)); }
-XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
-              { return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); }
-XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i)
-              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); }
-XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
-              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); }
-XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, int i)
-              { return updateText_WOSD(stringDup(lpszNewValue),i); }
-XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
-              { return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); }
-XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewContent, int i)
-              { return updateClear_WOSD(stringDup(lpszNewContent),i); }
-XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
-              { return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); }
-XMLClear     *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP)
-              { return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); }
-
-char XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, char _guessWideCharChars,
-                               char _dropWhiteSpace, char _removeCommentsInMiddleOfText)
-{
-    guessWideCharChars=_guessWideCharChars; dropWhiteSpace=_dropWhiteSpace; removeCommentsInMiddleOfText=_removeCommentsInMiddleOfText;
-#ifdef _XMLWIDECHAR
-    if (_characterEncoding) characterEncoding=_characterEncoding;
-#else
-    switch(_characterEncoding)
-    {
-    case char_encoding_UTF8:     characterEncoding=_characterEncoding; XML_ByteTable=XML_utf8ByteTable; break;
-    case char_encoding_legacy:   characterEncoding=_characterEncoding; XML_ByteTable=XML_legacyByteTable; break;
-    case char_encoding_ShiftJIS: characterEncoding=_characterEncoding; XML_ByteTable=XML_sjisByteTable; break;
-    case char_encoding_GB2312:   characterEncoding=_characterEncoding; XML_ByteTable=XML_gb2312ByteTable; break;
-    case char_encoding_Big5:
-    case char_encoding_GBK:      characterEncoding=_characterEncoding; XML_ByteTable=XML_gbk_big5_ByteTable; break;
-    default: return 1;
-    }
-#endif
-    return 0;
-}
-
-XMLNode::XMLCharEncoding XMLNode::guessCharEncoding(void *buf,int l, char useXMLEncodingAttribute)
-{
-#ifdef _XMLWIDECHAR
-    return (XMLCharEncoding)0;
-#else
-    if (l<25) return (XMLCharEncoding)0;
-    if (guessWideCharChars&&(myIsTextWideChar(buf,l))) return (XMLCharEncoding)0;
-    unsigned char *b=(unsigned char*)buf;
-    if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf)) return char_encoding_UTF8;
-
-    // Match utf-8 model ?
-    XMLCharEncoding bestGuess=char_encoding_UTF8;
-    int i=0;
-    while (i<l)
-        switch (XML_utf8ByteTable[b[i]])
-        {
-        case 4: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=char_encoding_legacy; i=l; } // 10bbbbbb ?
-        case 3: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=char_encoding_legacy; i=l; } // 10bbbbbb ?
-        case 2: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) { bestGuess=char_encoding_legacy; i=l; } // 10bbbbbb ?
-        case 1: i++; break;
-        case 0: i=l;
-        }
-    if (!useXMLEncodingAttribute) return bestGuess;
-    // if encoding is specified and different from utf-8 than it's non-utf8
-    // otherwise it's utf-8
-    char bb[201];
-    l=mmin(l,200);
-    memcpy(bb,buf,l); // copy buf into bb to be able to do "bb[l]=0"
-    bb[l]=0;
-    b=(unsigned char*)strstr(bb,"encoding");
-    if (!b) return bestGuess;
-    b+=8; while XML_isSPACECHAR(*b) b++; if (*b!='=') return bestGuess;
-    b++;  while XML_isSPACECHAR(*b) b++; if ((*b!='\'')&&(*b!='"')) return bestGuess;
-    b++;  while XML_isSPACECHAR(*b) b++;
-
-    if ((xstrnicmp((char*)b,"utf-8",5)==0)||
-        (xstrnicmp((char*)b,"utf8",4)==0))
-    {
-        if (bestGuess==char_encoding_legacy) return char_encoding_error;
-        return char_encoding_UTF8;
-    }
-
-    if ((xstrnicmp((char*)b,"shiftjis",8)==0)||
-        (xstrnicmp((char*)b,"shift-jis",9)==0)||
-        (xstrnicmp((char*)b,"sjis",4)==0)) return char_encoding_ShiftJIS;
-
-    if (xstrnicmp((char*)b,"GB2312",6)==0) return char_encoding_GB2312;
-    if (xstrnicmp((char*)b,"Big5",4)==0) return char_encoding_Big5;
-    if (xstrnicmp((char*)b,"GBK",3)==0) return char_encoding_GBK;
-
-    return char_encoding_legacy;
-#endif
-}
-#undef XML_isSPACECHAR
-
-//////////////////////////////////////////////////////////
-//      Here starts the base64 conversion functions.    //
-//////////////////////////////////////////////////////////
-
-static const char base64Fillchar = _CXML('='); // used to mark partial words at the end
-
-// this lookup table defines the base64 encoding
-XMLCSTR base64EncodeTable=_CXML("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
-
-// Decode Table gives the index of any valid base64 character in the Base64 table]
-// 96: '='  -   97: space char   -   98: illegal char   -   99: end of string
-const unsigned char base64DecodeTable[] = {
-    99,98,98,98,98,98,98,98,98,97,  97,98,98,97,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //00 -29
-    98,98,97,98,98,98,98,98,98,98,  98,98,98,62,98,98,98,63,52,53,  54,55,56,57,58,59,60,61,98,98,  //30 -59
-    98,96,98,98,98, 0, 1, 2, 3, 4,   5, 6, 7, 8, 9,10,11,12,13,14,  15,16,17,18,19,20,21,22,23,24,  //60 -89
-    25,98,98,98,98,98,98,26,27,28,  29,30,31,32,33,34,35,36,37,38,  39,40,41,42,43,44,45,46,47,48,  //90 -119
-    49,50,51,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //120 -149
-    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //150 -179
-    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //180 -209
-    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //210 -239
-    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98                                               //240 -255
-};
-
-XMLParserBase64Tool::~XMLParserBase64Tool(){ freeBuffer(); }
-
-void XMLParserBase64Tool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; }
-
-int XMLParserBase64Tool::encodeLength(int inlen, char formatted)
-{
-    unsigned int i=((inlen-1)/3*4+4+1);
-    if (formatted) i+=inlen/54;
-    return i;
-}
-
-XMLSTR XMLParserBase64Tool::encode(unsigned char *inbuf, unsigned int inlen, char formatted)
-{
-    int i=encodeLength(inlen,formatted),k=17,eLen=inlen/3,j;
-    alloc(i*sizeof(XMLCHAR));
-    XMLSTR curr=(XMLSTR)buf;
-    for(i=0;i<eLen;i++)
-    {
-        // Copy next three bytes into lower 24 bits of int, paying attention to sign.
-        j=(inbuf[0]<<16)|(inbuf[1]<<8)|inbuf[2]; inbuf+=3;
-        // Encode the int into four chars
-        *(curr++)=base64EncodeTable[ j>>18      ];
-        *(curr++)=base64EncodeTable[(j>>12)&0x3f];
-        *(curr++)=base64EncodeTable[(j>> 6)&0x3f];
-        *(curr++)=base64EncodeTable[(j    )&0x3f];
-        if (formatted) { if (!k) { *(curr++)=_CXML('\n'); k=18; } k--; }
-    }
-    eLen=inlen-eLen*3; // 0 - 2.
-    if (eLen==1)
-    {
-        *(curr++)=base64EncodeTable[ inbuf[0]>>2      ];
-        *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F];
-        *(curr++)=base64Fillchar;
-        *(curr++)=base64Fillchar;
-    } else if (eLen==2)
-    {
-        j=(inbuf[0]<<8)|inbuf[1];
-        *(curr++)=base64EncodeTable[ j>>10      ];
-        *(curr++)=base64EncodeTable[(j>> 4)&0x3f];
-        *(curr++)=base64EncodeTable[(j<< 2)&0x3f];
-        *(curr++)=base64Fillchar;
-    }
-    *(curr++)=0;
-    return (XMLSTR)buf;
-}
-
-unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe)
-{
-    if (!data) return 0;
-    if (xe) *xe=eXMLErrorNone;
-    int size=0;
-    unsigned char c;
-    //skip any extra characters (e.g. newlines or spaces)
-    while (*data)
-    {
-#ifdef _XMLWIDECHAR
-        if (*data>255) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
-#endif
-        c=base64DecodeTable[(unsigned char)(*data)];
-        if (c<97) size++;
-        else if (c==98) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
-        data++;
-    }
-    if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4;
-    if (size==0) return 0;
-    do { data--; size--; } while(*data==base64Fillchar); size++;
-    return (unsigned int)((size*3)/4);
-}
-
-unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe)
-{
-    if (!data) return 0;
-    if (xe) *xe=eXMLErrorNone;
-    int i=0,p=0;
-    unsigned char d,c;
-    for(;;)
-    {
-
-#ifdef _XMLWIDECHAR
-#define BASE64DECODE_READ_NEXT_CHAR(c)                                              \
-        do {                                                                        \
-            if (data[i]>255){ c=98; break; }                                        \
-            c=base64DecodeTable[(unsigned char)data[i++]];                       \
-        }while (c==97);                                                             \
-        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
-#else
-#define BASE64DECODE_READ_NEXT_CHAR(c)                                           \
-        do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97);   \
-        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
-#endif
-
-        BASE64DECODE_READ_NEXT_CHAR(c)
-        if (c==99) { return 2; }
-        if (c==96)
-        {
-            if (p==(int)len) return 2;
-            if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
-            return 1;
-        }
-
-        BASE64DECODE_READ_NEXT_CHAR(d)
-        if ((d==99)||(d==96)) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
-        if (p==(int)len) {      if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; return 0; }
-        buf[p++]=(unsigned char)((c<<2)|((d>>4)&0x3));
-
-        BASE64DECODE_READ_NEXT_CHAR(c)
-        if (c==99) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
-        if (p==(int)len)
-        {
-            if (c==96) return 2;
-            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
-            return 0;
-        }
-        if (c==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
-        buf[p++]=(unsigned char)(((d<<4)&0xf0)|((c>>2)&0xf));
-
-        BASE64DECODE_READ_NEXT_CHAR(d)
-        if (d==99 ) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
-        if (p==(int)len)
-        {
-            if (d==96) return 2;
-            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
-            return 0;
-        }
-        if (d==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
-        buf[p++]=(unsigned char)(((c<<6)&0xc0)|d);
-    }
-}
-#undef BASE64DECODE_READ_NEXT_CHAR
-
-void XMLParserBase64Tool::alloc(int newsize)
-{
-    if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize; return; }
-    if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; }
-}
-
-unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe)
-{
-    if (xe) *xe=eXMLErrorNone;
-    if (!data) { *outlen=0; return (unsigned char*)""; }
-    unsigned int len=decodeSize(data,xe);
-    if (outlen) *outlen=len;
-    if (!len) return NULL;
-    alloc(len+1);
-    if(!decode(data,(unsigned char*)buf,len,xe)){ return NULL; }
-    return (unsigned char*)buf;
-}
-
diff --git a/general/xmlParser.h b/general/xmlParser.h
deleted file mode 100644
index 80c54756ee7e76c66f5ca6bb79b11245764c0a3b..0000000000000000000000000000000000000000
--- a/general/xmlParser.h
+++ /dev/null
@@ -1,733 +0,0 @@
-/****************************************************************************/
-/** mainpage mainpage XMLParser library
- * \section intro_sec Introduction
- *
- * This is a basic XML parser written in ANSI C++ for portability.
- * It works by using recursion and a node tree for breaking
- * down the elements of an XML document.
- *
- * @version     V2.41
- * @author      Frank Vanden Berghen
- *
- * Copyright (c) 2002, Business-Insight
- * <a href="http://www.Business-Insight.com">Business-Insight</a>
- * All rights reserved.
- * See the file <a href="../../AFPL-license.txt">AFPL-license.txt</a> about the licensing terms
- *
- * \section tutorial First Tutorial
- * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
- *
- * \section usage General usage: How to include the XMLParser library inside your project.
- *
- * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
- * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
- * using the library inside your own projects.
- *
- * All the functions of the library are documented inside the comments of the file
- * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
- * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
- *
- * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
- * version of the library, you need to define the "_UNICODE" preprocessor definition variable
- * (this is usually done inside your project definition file) (This is done automatically for you
- * when using Visual Studio).
- *
- * \section example Advanced Tutorial and Many Examples of usage.
- *
- * Some very small introductory examples are described inside the Tutorial file
- * <a href="../../xmlParser.html">xmlParser.html</a>
- *
- * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
- * (for the "char*" version of the library) and inside the file
- * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
- * version of the library). If you have a question, please review these additionnal examples
- * before sending an e-mail to the author.
- *
- * To build the examples:
- * - linux/unix: type "make"
- * - solaris: type "make -f makefile.solaris"
- * - windows: Visual Studio: double-click on xmlParser.dsw
- *   (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
- *
- * In order to build the examples you need some additional files:
- * - linux/unix: makefile
- * - solaris: makefile.solaris
- * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
- *
- * \section debugging Debugging with the XMLParser library
- *
- * \subsection debugwin Debugging under WINDOWS
- *
- * 	Inside Visual C++, the "debug versions" of the memory allocation functions are
- * 	very slow: Do not forget to compile in "release mode" to get maximum speed.
- * 	When I had to debug a software that was using the XMLParser Library, it was usually
- * 	a nightmare because the library was sooOOOoooo slow in debug mode (because of the
- *  slow memory allocations in Debug mode). To solve this
- * 	problem, during all the debugging session, I am now using a very fast DLL version of the
- * 	XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
- * 	the XMLParser Library allows me to have lightening XML parsing speed even in debug!
- * 	Other than that, the DLL version is useless: In the release version of my tool,
- * 	I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
- * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
- * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
- *
- * 	The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
- * "tweaks" that improve substancially the display of the content of the XMLNode objects
- * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
- * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
- *
- * \subsection debuglinux Debugging under LINUX/UNIX
- *
- * 	The speed of the debug version of the XMLParser library is tolerable so no extra
- * work.has been done.
- *
- ****************************************************************************/
-
-#ifndef __INCLUDE_XML_NODE__
-#define __INCLUDE_XML_NODE__
-
-#include <stdlib.h>
-
-#ifdef _UNICODE
-// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
-// This is useful when you get error messages like:
-//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
-// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
-// must be defined) or utf8-mode(the pre-processor variable must be undefined).
-#define _XMLWIDECHAR
-#endif
-
-#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
-// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
-#define _XMLWINDOWS
-#endif
-
-#ifdef XMLDLLENTRY
-#undef XMLDLLENTRY
-#endif
-#ifdef _USE_XMLPARSER_DLL
-#ifdef _DLL_EXPORTS_
-#define XMLDLLENTRY __declspec(dllexport)
-#else
-#define XMLDLLENTRY __declspec(dllimport)
-#endif
-#else
-#define XMLDLLENTRY
-#endif
-
-// uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
-//#define XML_NO_WIDE_CHAR
-
-#ifdef XML_NO_WIDE_CHAR
-#undef _XMLWINDOWS
-#undef _XMLWIDECHAR
-#endif
-
-#ifdef _XMLWINDOWS
-#include <tchar.h>
-#else
-#define XMLDLLENTRY
-#ifndef XML_NO_WIDE_CHAR
-#include <wchar.h> // to have 'wcsrtombs' for ANSI version
-                   // to have 'mbsrtowcs' for WIDECHAR version
-#endif
-#endif
-
-// Some common types for char set portable code
-#ifdef _XMLWIDECHAR
-    #define _CXML(c) L ## c
-    #define XMLCSTR const wchar_t *
-    #define XMLSTR  wchar_t *
-    #define XMLCHAR wchar_t
-#else
-    #define _CXML(c) c
-    #define XMLCSTR const char *
-    #define XMLSTR  char *
-    #define XMLCHAR char
-#endif
-#ifndef FALSE
-    #define FALSE 0
-#endif /* FALSE */
-#ifndef TRUE
-    #define TRUE 1
-#endif /* TRUE */
-
-
-/// Enumeration for XML parse errors.
-typedef enum XMLError
-{
-    eXMLErrorNone = 0,
-    eXMLErrorMissingEndTag,
-    eXMLErrorNoXMLTagFound,
-    eXMLErrorEmpty,
-    eXMLErrorMissingTagName,
-    eXMLErrorMissingEndTagName,
-    eXMLErrorUnmatchedEndTag,
-    eXMLErrorUnmatchedEndClearTag,
-    eXMLErrorUnexpectedToken,
-    eXMLErrorNoElements,
-    eXMLErrorFileNotFound,
-    eXMLErrorFirstTagNotFound,
-    eXMLErrorUnknownCharacterEntity,
-    eXMLErrorCharacterCodeAbove255,
-    eXMLErrorCharConversionError,
-    eXMLErrorCannotOpenWriteFile,
-    eXMLErrorCannotWriteFile,
-
-    eXMLErrorBase64DataSizeIsNotMultipleOf4,
-    eXMLErrorBase64DecodeIllegalCharacter,
-    eXMLErrorBase64DecodeTruncatedData,
-    eXMLErrorBase64DecodeBufferTooSmall
-} XMLError;
-
-
-/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
-typedef enum XMLElementType
-{
-    eNodeChild=0,
-    eNodeAttribute=1,
-    eNodeText=2,
-    eNodeClear=3,
-    eNodeNULL=4
-} XMLElementType;
-
-/// Structure used to obtain error details if the parse fails.
-typedef struct XMLResults
-{
-    enum XMLError error;
-    int  nLine,nColumn;
-} XMLResults;
-
-/// Structure for XML clear (unformatted) node (usually comments)
-typedef struct XMLClear {
-    XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
-} XMLClear;
-
-/// Structure for XML attribute.
-typedef struct XMLAttribute {
-    XMLCSTR lpszName; XMLCSTR lpszValue;
-} XMLAttribute;
-
-/// XMLElementPosition are not interchangeable with simple indexes
-typedef int XMLElementPosition;
-
-struct XMLNodeContents;
-
-/** @defgroup XMLParserGeneral The XML parser */
-
-/// Main Class representing a XML node
-/**
- * All operations are performed using this class.
- * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
- * <ul>
- *    <li> XMLNode::parseString </li>
- *    <li> XMLNode::parseFile </li>
- *    <li> XMLNode::openFileHelper </li>
- *    <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
- * </ul> */
-typedef struct XMLDLLENTRY XMLNode
-{
-  private:
-
-    struct XMLNodeDataTag;
-
-    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
-    XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
-    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
-    XMLNode(struct XMLNodeDataTag *p);
-
-  public:
-    static XMLCSTR getVersion();///< Return the XMLParser library version number
-
-    /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
-     * @ingroup XMLParserGeneral
-     * @{ */
-
-    /// Parse an XML string and return the root of a XMLNode tree representing the string.
-    static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
-    /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
-     * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
-     * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
-     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
-     * beginning of the "xmlParser.cpp" file.
-     *
-     * @param lpXMLString the XML string to parse
-     * @param tag  the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
-     * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
-     */
-
-    /// Parse an XML file and return the root of a XMLNode tree representing the file.
-    static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
-    /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
-     * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
-     * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
-     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
-     * beginning of the "xmlParser.cpp" file.
-     *
-     * @param filename the path to the XML file to parse
-     * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
-     * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
-     */
-
-    /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made.
-    static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL);
-    /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
-     * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each
-     * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
-     * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
-     * mechanism included inside the "openFileHelper" function).
-     *
-     * If the XML document is corrupted, the "openFileHelper" method will:
-     *         - display an error message on the console (or inside a messageBox for windows).
-     *         - stop execution (exit).
-     *
-     * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
-     * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
-     *
-     * @param filename the path of the XML file to parse.
-     * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
-     */
-
-    static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
-
-    /// Create an XML string starting from the current XMLNode.
-    XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;
-    /**< The returned string should be free'd using the "freeXMLString" function.
-     *
-     *   If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
-     *   with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
-
-    /// Save the content of an xmlNode inside a file
-    XMLError writeToFile(XMLCSTR filename,
-                         const char *encoding=NULL,
-                         char nFormat=1) const;
-    /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns.
-     * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
-     * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
-     * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
-     * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
-    /** @} */
-
-    /** @defgroup navigate Navigate the XMLNode structure
-     * @ingroup XMLParserGeneral
-     * @{ */
-    XMLCSTR getName() const;                                       ///< name of the node
-    XMLCSTR getText(int i=0) const;                                ///< return ith text field
-    int nText() const;                                             ///< nbr of text field
-    XMLNode getParentNode() const;                                 ///< return the parent node
-    XMLNode getChildNode(int i=0) const;                           ///< return ith child node
-    XMLNode getChildNode(XMLCSTR name, int i)  const;              ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name.
-    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;         ///< return next child node with specific name (return an empty node if failing)
-    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
-                                      XMLCSTR attributeName,
-                                      XMLCSTR attributeValue=NULL,
-                                      int *i=NULL)  const;         ///< return child node with specific name/attribute (return an empty node if failing)
-    XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
-                                                                   ///< return the first child node with specific path
-    XMLNode getChildNodeByPathNonConst(XMLSTR  path, char createNodeIfMissing=0, XMLCHAR sep='/');
-                                                                   ///< return the first child node with specific path.
-
-    int nChildNode(XMLCSTR name) const;                            ///< return the number of child node with specific name
-    int nChildNode() const;                                        ///< nbr of child node
-    XMLAttribute getAttribute(int i=0) const;                      ///< return ith attribute
-    XMLCSTR      getAttributeName(int i=0) const;                  ///< return ith attribute name
-    XMLCSTR      getAttributeValue(int i=0) const;                 ///< return ith attribute value
-    char  isAttributeSet(XMLCSTR name) const;                      ///< test if an attribute with a specific name is given
-    XMLCSTR getAttribute(XMLCSTR name, int i) const;               ///< return ith attribute content with specific name (return a NULL if failing)
-    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;         ///< return next attribute content with specific name (return a NULL if failing)
-    int nAttribute() const;                                        ///< nbr of attribute
-    XMLClear getClear(int i=0) const;                              ///< return ith clear field (comments)
-    int nClear() const;                                            ///< nbr of clear field
-    XMLNodeContents enumContents(XMLElementPosition i) const;      ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement();
-    int nElement() const;                                          ///< nbr of different contents for current node
-    char isEmpty() const;                                          ///< is this node Empty?
-    char isDeclaration() const;                                    ///< is this node a declaration <? .... ?>
-    XMLNode deepCopy() const;                                      ///< deep copy (duplicate/clone) a XMLNode
-    static XMLNode emptyNode();                                    ///< return XMLNode::emptyXMLNode;
-    /** @} */
-
-    ~XMLNode();
-    XMLNode(const XMLNode &A);                                     ///< to allow shallow/fast copy:
-    XMLNode& operator=( const XMLNode& A );                        ///< to allow shallow/fast copy:
-
-    XMLNode(): d(NULL){};
-    static XMLNode emptyXMLNode;
-    static XMLClear emptyXMLClear;
-    static XMLAttribute emptyXMLAttribute;
-
-    /** @defgroup xmlModify Create or Update the XMLNode structure
-     * @ingroup XMLParserGeneral
-     *  The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
-     *  node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
-     *  the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
-     *  end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
-     *
-     *  REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
-     */
-
-    /** @defgroup creation Creating from scratch a XMLNode structure
-     * @ingroup xmlModify
-     * @{ */
-    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);                    ///< Create the top node of an XMLNode structure
-    XMLNode        addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
-    XMLNode        addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1);                          ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode
-    XMLAttribute  *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);                              ///< Add a new attribute
-    XMLCSTR        addText(XMLCSTR lpszValue, XMLElementPosition pos=-1);                           ///< Add a new text content
-    XMLClear      *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
-    /**< Add a new clear tag
-     * @param lpszOpen default value "<![CDATA["
-     * @param lpszClose default value "]]>"
-     */
-    /** @} */
-
-    /** @defgroup xmlUpdate Updating Nodes
-     * @ingroup xmlModify
-     * Some update functions:
-     * @{
-     */
-    XMLCSTR       updateName(XMLCSTR lpszName);                                                  ///< change node's name
-    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);       ///< if the attribute to update is missing, a new one will be added
-    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);       ///< if the attribute to update is missing, a new one will be added
-    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
-    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
-    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
-    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
-    XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                    ///< if the clearTag to update is missing, a new one will be added
-    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
-    /** @} */
-
-    /** @defgroup xmlDelete Deleting Nodes or Attributes
-     * @ingroup xmlModify
-     * Some deletion functions:
-     * @{
-     */
-    /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
-    void deleteNodeContent();
-    /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */
-    void deleteAttribute(int i=0);                   ///< Delete the ith attribute of the current XMLNode
-    void deleteAttribute(XMLCSTR lpszName);          ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
-    void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
-    void deleteText(int i=0);                        ///< Delete the Ith text content of the current XMLNode
-    void deleteText(XMLCSTR lpszValue);              ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text)
-    void deleteClear(int i=0);                       ///< Delete the Ith clear tag inside the current XMLNode
-    void deleteClear(XMLCSTR lpszValue);             ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag)
-    void deleteClear(XMLClear *p);                   ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag)
-    /** @} */
-
-    /** @defgroup xmlWOSD ???_WOSD functions.
-     * @ingroup xmlModify
-     *  The strings given as parameters for the "add" and "update" methods that have a name with
-     *  the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
-     *  will be free'd by the XMLNode class. For example, it means that this is incorrect:
-     *  \code
-     *     xNode.addText_WOSD("foo");
-     *     xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
-     *  \endcode
-     *  In opposition, this is correct:
-     *  \code
-     *     xNode.addText("foo");
-     *     xNode.addText_WOSD(stringDup("foo"));
-     *     xNode.updateAttribute("#newcolor" ,NULL,"color");
-     *     xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
-     *  \endcode
-     *  Typically, you will never do:
-     *  \code
-     *     char *b=(char*)malloc(...);
-     *     xNode.addText(b);
-     *     free(b);
-     *  \endcode
-     *  ... but rather:
-     *  \code
-     *     char *b=(char*)malloc(...);
-     *     xNode.addText_WOSD(b);
-     *  \endcode
-     *  ('free(b)' is performed by the XMLNode class)
-     * @{ */
-    static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE);                     ///< Create the top node of an XMLNode structure
-    XMLNode        addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1);  ///< Add a new child node
-    XMLAttribute  *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue);                                 ///< Add a new attribute
-    XMLCSTR        addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1);                            ///< Add a new text content
-    XMLClear      *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
-
-    XMLCSTR        updateName_WOSD(XMLSTR lpszName);                                                  ///< change node's name
-    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);      ///< if the attribute to update is missing, a new one will be added
-    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0);        ///< if the attribute to update is missing, a new one will be added
-    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
-    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
-    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
-    XMLClear      *updateClear_WOSD(XMLSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
-    XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);                                   ///< if the clearTag to update is missing, a new one will be added
-    XMLClear      *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
-    /** @} */
-
-    /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
-     * @ingroup xmlModify
-     * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
-     * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
-     * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
-     * @{ */
-    XMLElementPosition positionOfText(int i=0) const;
-    XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
-    XMLElementPosition positionOfClear(int i=0) const;
-    XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
-    XMLElementPosition positionOfClear(XMLClear *a) const;
-    XMLElementPosition positionOfChildNode(int i=0) const;
-    XMLElementPosition positionOfChildNode(XMLNode x) const;
-    XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode
-    /** @} */
-
-    /// Enumeration for XML character encoding.
-    typedef enum XMLCharEncoding
-    {
-        char_encoding_error=0,
-        char_encoding_UTF8=1,
-        char_encoding_legacy=2,
-        char_encoding_ShiftJIS=3,
-        char_encoding_GB2312=4,
-        char_encoding_Big5=5,
-        char_encoding_GBK=6     // this is actually the same as Big5
-    } XMLCharEncoding;
-
-    /** \addtogroup conversions
-     * @{ */
-
-    /// Sets the global options for the conversions
-    static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
-                                 char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
-    /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
-     * parsing. First of all, you most-probably will never have to change these 3 global parameters.
-     *
-     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
-     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
-     *     characters. If this is the case, then the file will be loaded and converted in memory to
-     *     WideChar before being parsed. If 0, no conversion will be performed.
-     *
-     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
-     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
-     *     characters. If this is the case, then the file will be loaded and converted in memory to
-     *     ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
-     *
-     * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
-     *     In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
-     *     three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
-     *     XMLNode::encoding_ShiftJIS.
-     *
-     * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
-     *     are useless. Even more, these "empty" text fields are annoying because they increase the
-     *     complexity of the user's code for parsing. So, 99% of the time, it's better to drop
-     *     the "empty" text fields. However The XML specification indicates that no white spaces
-     *     should be lost when parsing the file. So to be perfectly XML-compliant, you should set
-     *     dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
-     *     slower and your code will be more complex.
-     *
-     * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
-     * \code
-     *        XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
-     * \endcode
-     *     If removeCommentsInMiddleOfText=0, then we will have:
-     * \code
-     *        x.getText(0) -> "foo"
-     *        x.getText(1) -> "bar"
-     *        x.getText(2) -> "chu"
-     *        x.getClear(0) --> "<!-- hello -->"
-     *        x.getClear(1) --> "<!DOCTYPE world >"
-     * \endcode
-     *     If removeCommentsInMiddleOfText=1, then we will have:
-     * \code
-     *        x.getText(0) -> "foobar"
-     *        x.getText(1) -> "chu"
-     *        x.getClear(0) --> "<!DOCTYPE world >"
-     * \endcode
-     *
-     * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error.
-     *
-     * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
-     * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
-
-    /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
-    static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
-    /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
-     * have to use this function. It then returns the appropriate value of the global parameter
-     * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
-     * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
-     * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
-     * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
-     * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
-     * forbids to use this attribute to do the guess but you can still use it if you set
-     * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
-     * If an inconsistency in the encoding is detected, then the return value is "0". */
-    /** @} */
-
-  private:
-      // these are functions and structures used internally by the XMLNode class (don't bother about them):
-
-      typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
-      {
-          XMLCSTR                lpszName;        // Element name (=NULL if root)
-          int                    nChild,          // Number of child nodes
-                                 nText,           // Number of text fields
-                                 nClear,          // Number of Clear fields (comments)
-                                 nAttribute;      // Number of attributes
-          char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
-          struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
-          XMLNode                *pChild;         // Array of child nodes
-          XMLCSTR                *pText;          // Array of text fields
-          XMLClear               *pClear;         // Array of clear fields
-          XMLAttribute           *pAttribute;     // Array of attributes
-          int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
-          int                    ref_count;       // for garbage collection (smart pointers)
-      } XMLNodeData;
-      XMLNodeData *d;
-
-      char parseClearTag(void *px, void *pa);
-      char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
-      int ParseXMLElement(void *pXML);
-      void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
-      int indexText(XMLCSTR lpszValue) const;
-      int indexClear(XMLCSTR lpszValue) const;
-      XMLNode addChild_priv(int,XMLSTR,char,int);
-      XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR);
-      XMLCSTR addText_priv(int,XMLSTR,int);
-      XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int);
-      void emptyTheNode(char force);
-      static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
-      static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
-      static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
-      static void exactMemory(XMLNodeData *d);
-      static int detachFromParent(XMLNodeData *d);
-} XMLNode;
-
-/// This structure is given by the function XMLNode::enumContents.
-typedef struct XMLNodeContents
-{
-    /// This dictates what's the content of the XMLNodeContent
-    enum XMLElementType etype;
-    /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
-    XMLNode child;
-    XMLAttribute attrib;
-    XMLCSTR text;
-    XMLClear clear;
-
-} XMLNodeContents;
-
-/** @defgroup StringAlloc String Allocation/Free functions
- * @ingroup xmlModify
- * @{ */
-/// Duplicate (copy in a new allocated buffer) the source string.
-XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
-/**< This is
- * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
- * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
- * this function should be free'd using the "freeXMLString" function. */
-
-/// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
-XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
-/** @} */
-
-/** @defgroup atoX ato? like functions
- * @ingroup XMLParserGeneral
- * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
- * The only difference is: If the variable "xmlString" is NULL, than the return value
- * is "defautValue". These 6 functions are only here as "convenience" functions for the
- * user (they are not used inside the XMLparser). If you don't need them, you can
- * delete them without any trouble.
- *
- * @{ */
-XMLDLLENTRY char    xmltob(XMLCSTR xmlString,char   defautValue=0);
-XMLDLLENTRY int     xmltoi(XMLCSTR xmlString,int    defautValue=0);
-XMLDLLENTRY long    xmltol(XMLCSTR xmlString,long   defautValue=0);
-XMLDLLENTRY double  xmltof(XMLCSTR xmlString,double defautValue=.0);
-XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML(""));
-XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,const XMLCHAR defautValue=_CXML('\0'));
-/** @} */
-
-/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
- * @ingroup XMLParserGeneral
- * @{ */
-/// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
-/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
- * The "ToXMLStringTool" class is processing strings so that all the characters
- * &,",',<,> are replaced by their XML equivalent:
- * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
- * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
- * way to produce VERY large XML documents VERY fast.
- * \note If you are creating from scratch an XML file using the provided XMLNode class
- * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
- * processing job for you during rendering).*/
-typedef struct XMLDLLENTRY ToXMLStringTool
-{
-public:
-    ToXMLStringTool(): buf(NULL),buflen(0){}
-    ~ToXMLStringTool();
-    void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
-
-    XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
-
-    /** The "toXMLUnSafe" function is deprecated because there is a possibility of
-     * "destination-buffer-overflow". It converts the string
-     * "source" to the string "dest". */
-    static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
-    static int lengthXMLString(XMLCSTR source);            ///< deprecated: use "toXML" instead
-
-private:
-    XMLSTR buf;
-    int buflen;
-} ToXMLStringTool;
-/** @} */
-
-/** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
- * @ingroup XMLParserGeneral
- * @{ */
-/// Helper class to include binary data inside XML strings using "Base64 encoding".
-/** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
- * into an XML document using "Base64 encoding". This class is completely
- * separated from the rest of the xmlParser library and can be removed without any problem.
- * To include some binary data into an XML file, you must convert the binary data into
- * standard text (using "encode"). To retrieve the original binary data from the
- * b64-encoded text included inside the XML file, use "decode". Alternatively, these
- * functions can also be used to "encrypt/decrypt" some critical data contained inside
- * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
-typedef struct XMLDLLENTRY XMLParserBase64Tool
-{
-public:
-    XMLParserBase64Tool(): buf(NULL),buflen(0){}
-    ~XMLParserBase64Tool();
-    void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
-
-    /**
-     * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
-    static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
-
-    /**
-     * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
-     * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
-     * The string will be free'd when the XMLParserBase64Tool object is deleted.
-     * All returned strings are sharing the same memory space. */
-    XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0); ///< returns a pointer to an internal buffer containing the base64 string containing the binary data encoded from "inByteBuf"
-
-    /// returns the number of bytes which will be decoded from "inString".
-    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
-
-    /**
-     * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
-     * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
-     * All output buffer are sharing the same memory space.
-     * @param inString If "instring" is malformed, NULL will be returned */
-    unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL); ///< returns a pointer to an internal buffer containing the binary data decoded from "inString"
-
-    /**
-     * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
-     * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
-     * will be returned; otherwise "TRUE". */
-    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
-
-private:
-    void *buf;
-    int buflen;
-    void alloc(int newsize);
-}XMLParserBase64Tool;
-/** @} */
-
-#undef XMLDLLENTRY
-
-#endif
diff --git a/geometry/Building.cpp b/geometry/Building.cpp
index 7adcccd123aeb80e434853dfe1c2a81babfc3c1b..a9390569d4530b0187858e853c67fc0dd3f77adf 100644
--- a/geometry/Building.cpp
+++ b/geometry/Building.cpp
@@ -26,16 +26,21 @@
  */
 
 #include "Building.h"
-#include "../general/xmlParser.h"
+#include "../tinyxml/tinyxml.h"
 
 #ifdef _SIMULATOR
-	#include "../pedestrian/Pedestrian.h"
-	#include "../mpi/LCGrid.h"
-	#include "../routing/RoutingEngine.h"
+#include "../pedestrian/Pedestrian.h"
+#include "../mpi/LCGrid.h"
+#include "../routing/RoutingEngine.h"
 #endif
 
+//#undef _OPENMP
+
 #ifdef _OPENMP
 #include <omp.h>
+#else
+#define omp_get_thread_num()	0
+#define omp_get_max_threads()	1
 #endif
 
 
@@ -58,25 +63,27 @@ Building::~Building() {
 	for (int i = 0; i < GetNumberOfRooms(); i++)
 		delete _rooms[i];
 
+#ifdef _SIMULATOR
 	delete _routingEngine;
 	delete _linkedCellGrid;
+#endif
 
 	if (_pathWayStream.is_open())
 		_pathWayStream.close();
 
-// FIXME:
-//	for (map<int, Crossing*>::const_iterator iter = pCrossings.begin();
-//				iter != pCrossings.end(); ++iter) {
-//			delete iter->second;
-//		}
-//		for (map<int, Transition*>::const_iterator iter = pTransitions.begin();
-//				iter != pTransitions.end(); ++iter) {
-//			delete iter->second;
-//		}
-//		for (map<int, Hline*>::const_iterator iter = pHlines.begin();
-//				iter != pHlines.end(); ++iter) {
-//			delete iter->second;
-//		}
+
+	for (map<int, Crossing*>::const_iterator iter = _crossings.begin();
+			iter != _crossings.end(); ++iter) {
+		delete iter->second;
+	}
+	for (map<int, Transition*>::const_iterator iter = _transitions.begin();
+			iter != _transitions.end(); ++iter) {
+		delete iter->second;
+	}
+	for (map<int, Hline*>::const_iterator iter = _hLines.begin();
+			iter != _hLines.end(); ++iter) {
+		delete iter->second;
+	}
 }
 
 /************************************************************
@@ -138,6 +145,13 @@ Room* Building::GetRoom(int index) const {
 
 
 
+LCGrid* Building::GetGrid() const {
+	return _linkedCellGrid;
+}
+/*************************************************************
+ Sonstiges
+ ************************************************************/
+
 void Building::AddRoom(Room* room) {
 	_rooms.push_back(room);
 }
@@ -237,65 +251,92 @@ void Building::InitGeometry() {
 	Log->Write("INFO: \tInit Geometry successful!!!\n");
 }
 
+/*************************************************************
+ Ein-Ausgabe
+ ************************************************************/
 
+void Building::LoadBuilding(string filename) {
 
+	Log->Write("INFO: \tParsing the geometry file");
 
+	TiXmlDocument docGeo(filename);
+	if (!docGeo.LoadFile()){
+		Log->Write("ERROR: \t%s", docGeo.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the geometry file");
+		exit(EXIT_FAILURE);
+	}
 
 
-void Building::LoadBuilding(string filename) {
+	TiXmlElement* xRootNode = docGeo.RootElement();
+	if( ! xRootNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
 
-	Log->Write("INFO: \tParsing the geometry file");
+	if( xRootNode->ValueStr () != "geometry" ) {
+		Log->Write("ERROR:\tRoot element value is not 'geometry'.");
+		exit(EXIT_FAILURE);
+	}
 
-	XMLNode xMainNode = XMLNode::openFileHelper(filename.c_str(), "geometry");
 
-	double version = xmltof(xMainNode.getAttribute("version"), -1);
+	double version = xmltof(xRootNode->Attribute("version"), -1);
 	if (version < 0.4) {
 		Log->Write("ERROR: \tOnly version > 0.4 supported");
 		Log->Write("ERROR: \tparsing geometry file failed!");
 		exit(EXIT_FAILURE);
 	}
-	_caption = xmltoa(xMainNode.getAttribute("caption"), "virtual building");
+	_caption = xmltoa(xRootNode->Attribute("caption"), "virtual building");
+
 
 	//The file has two main nodes
 	//<rooms> and <transitions>
 
-	XMLNode xRoomsNode = xMainNode.getChildNode("rooms");
-	int nRooms = xRoomsNode.nChildNode("room");
 
 	//processing the rooms node
-	for (int i = 0; i < nRooms; i++) {
-		XMLNode xRoom = xRoomsNode.getChildNode("room", i);
+	TiXmlNode*  xRoomsNode = xRootNode->FirstChild("rooms");
+	if (!xRoomsNode){
+		Log->Write("ERROR: \tThe geometry should have at least one room and one subroom");
+		exit(EXIT_FAILURE);
+	}
+
+	for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom;
+			xRoom = xRoom->NextSiblingElement("room")) {
+
 		Room* room = new Room();
 
-		string room_id = xmltoa(xRoom.getAttribute("id"), "-1");
+		string room_id = xmltoa(xRoom->Attribute("id"), "-1");
 		room->SetID(xmltoi(room_id.c_str(), -1));
 
 		string caption = "room " + room_id;
 		room->SetCaption(
-				xmltoa(xRoom.getAttribute("caption"), caption.c_str()));
+				xmltoa(xRoom->Attribute("caption"), caption.c_str()));
 
-		double position = xmltof(xRoom.getAttribute("zpos"), 0.0);
+		double position = xmltof(xRoom->Attribute("zpos"), 0.0);
+
+		//TODO?? what the hell is that for ?
 		if(position>6.0) position+=50;
 		room->SetZPos(position);
 
 		//parsing the subrooms
-		int nSubRooms = xRoom.nChildNode("subroom");
+		//processing the rooms node
+		//TiXmlNode*  xSubroomsNode = xRoom->FirstChild("subroom");
+
+		for(TiXmlElement* xSubRoom = xRoom->FirstChildElement("subroom"); xSubRoom;
+				xSubRoom = xSubRoom->NextSiblingElement("subroom")) {
 
-		for (int s = 0; s < nSubRooms; s++) {
-			XMLNode xSubroomsNode = xRoom.getChildNode("subroom", s);
 
-			string subroom_id = xmltoa(xSubroomsNode.getAttribute("id"), "-1");
-			string closed = xmltoa(xSubroomsNode.getAttribute("closed"), "0");
-			string type = xmltoa(xSubroomsNode.getAttribute("class"),
+			string subroom_id = xmltoa(xSubRoom->Attribute("id"), "-1");
+			string closed = xmltoa(xSubRoom->Attribute("closed"), "0");
+			string type = xmltoa(xSubRoom->Attribute("class"),
 					"subroom");
 
 			SubRoom* subroom = NULL;
 
 			if (type == "stair") {
-				double up_x = xmltof( xSubroomsNode.getChildNode("up").getAttribute("px"), 0.0);
-				double up_y = xmltof( xSubroomsNode.getChildNode("up").getAttribute("py"), 0.0);
-				double down_x = xmltof( xSubroomsNode.getChildNode("down").getAttribute("py"), 0.0);
-				double down_y = xmltof( xSubroomsNode.getChildNode("down").getAttribute("py"), 0.0);
+				double up_x = xmltof( xSubRoom->FirstChildElement("up")->Attribute("px"), 0.0);
+				double up_y = xmltof( xSubRoom->FirstChildElement("up")->Attribute("py"), 0.0);
+				double down_x = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0);
+				double down_y = xmltof( xSubRoom->FirstChildElement("down")->Attribute("py"), 0.0);
 				subroom = new Stair();
 				((Stair*)subroom)->SetUp(Point(up_x,up_y));
 				((Stair*)subroom)->SetDown(Point(down_x,down_y));
@@ -308,49 +349,32 @@ void Building::LoadBuilding(string filename) {
 			subroom->SetSubRoomID(xmltoi(subroom_id.c_str(), -1));
 
 			//looking for polygons (walls)
-			int nPoly = xSubroomsNode.nChildNode("polygon");
-			for (int p = 0; p < nPoly; p++) {
-				XMLNode xPolyVertices = xSubroomsNode.getChildNode("polygon",
-						p);
-				int nVertices =
-						xSubroomsNode.getChildNode("polygon", p).nChildNode(
-								"vertex");
-
-				for (int v = 0; v < nVertices - 1; v++) {
-					double x1 =
-							xmltof(
-									xPolyVertices.getChildNode("vertex", v).getAttribute(
-											"px"));
-					double y1 =
-							xmltof(
-									xPolyVertices.getChildNode("vertex", v).getAttribute(
-											"py"));
-
-					double x2 =
-							xmltof(
-									xPolyVertices.getChildNode("vertex", v + 1).getAttribute(
-											"px"));
-					double y2 =
-							xmltof(
-									xPolyVertices.getChildNode("vertex", v + 1).getAttribute(
-											"py"));
+			for(TiXmlElement* xPolyVertices = xSubRoom->FirstChildElement("polygon"); xPolyVertices;
+					xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) {
+
+				for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement(
+						"vertex");
+						xVertex && xVertex != xPolyVertices->LastChild("vertex");
+						xVertex = xVertex->NextSiblingElement("vertex")) {
+
+					double x1 = xmltof(xVertex->Attribute("px"));
+					double y1 = xmltof(xVertex->Attribute("py"));
+					double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px"));
+					double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py"));
+
 					subroom->AddWall(Wall(Point(x1, y1), Point(x2, y2)));
 				}
 
 			}
 
 			//looking for obstacles
-			int nObst = xSubroomsNode.nChildNode("obstacle");
-
-			for (int obst = 0; obst < nObst; obst++) {
-				XMLNode xObstacle = xSubroomsNode.getChildNode("obstacle",
-						obst);
-				int nPoly = xObstacle.nChildNode("polygon");
-				int id = xmltof(xObstacle.getAttribute("id"), -1);
-				int height = xmltof(xObstacle.getAttribute("height"), 0);
-				double closed = xmltof(xObstacle.getAttribute("closed"), 0);
-				string caption = xmltoa(xObstacle.getAttribute("caption"),
-						"-1");
+			for(TiXmlElement* xObstacle = xSubRoom->FirstChildElement("obstacle"); xObstacle;
+					xObstacle = xObstacle->NextSiblingElement("obstacle")) {
+
+				int id = xmltof(xObstacle->Attribute("id"), -1);
+				int height = xmltof(xObstacle->Attribute("height"), 0);
+				double closed = xmltof(xObstacle->Attribute("closed"), 0);
+				string caption = xmltoa(xObstacle->Attribute("caption"),"-1");
 
 				Obstacle* obstacle = new Obstacle();
 				obstacle->SetId(id);
@@ -358,30 +382,19 @@ void Building::LoadBuilding(string filename) {
 				obstacle->SetClosed(closed);
 				obstacle->SetHeight(height);
 
-				for (int p = 0; p < nPoly; p++) {
-					XMLNode xPolyVertices = xObstacle.getChildNode("polygon",
-							p);
-					int nVertices =
-							xObstacle.getChildNode("polygon", p).nChildNode(
-									"vertex");
-					for (int v = 0; v < nVertices - 1; v++) {
-						double x1 =
-								xmltof(
-										xPolyVertices.getChildNode("vertex", v).getAttribute(
-												"px"));
-						double y1 =
-								xmltof(
-										xPolyVertices.getChildNode("vertex", v).getAttribute(
-												"py"));
-
-						double x2 =
-								xmltof(
-										xPolyVertices.getChildNode("vertex",
-												v + 1).getAttribute("px"));
-						double y2 =
-								xmltof(
-										xPolyVertices.getChildNode("vertex",
-												v + 1).getAttribute("py"));
+				//looking for polygons (walls)
+				for(TiXmlElement* xPolyVertices = xObstacle->FirstChildElement("polygon"); xPolyVertices;
+						xPolyVertices = xPolyVertices->NextSiblingElement("polygon")) {
+
+					for (TiXmlElement* xVertex = xPolyVertices->FirstChildElement(
+							"vertex");
+							xVertex && xVertex != xPolyVertices->LastChild("vertex");
+							xVertex = xVertex->NextSiblingElement("vertex")) {
+
+						double x1 = xmltof(xVertex->Attribute("px"));
+						double y1 = xmltof(xVertex->Attribute("py"));
+						double x2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("px"));
+						double y2 = xmltof(xVertex->NextSiblingElement("vertex")->Attribute("py"));
 						obstacle->AddWall(Wall(Point(x1, y1), Point(x2, y2)));
 					}
 				}
@@ -389,25 +402,21 @@ void Building::LoadBuilding(string filename) {
 			}
 			room->AddSubRoom(subroom);
 		}
+
 		//parsing the crossings
-		XMLNode xCrossingsNode = xRoom.getChildNode("crossings");
-		int nCrossing = xCrossingsNode.nChildNode("crossing");
+		TiXmlNode*  xCrossingsNode = xRoom->FirstChild("crossings");
+		if(xCrossingsNode)
+		for(TiXmlElement* xCrossing = xCrossingsNode->FirstChildElement("crossing"); xCrossing;
+				xCrossing = xCrossing->NextSiblingElement("crossing")) {
 
-		//processing the rooms node
-		for (int i = 0; i < nCrossing; i++) {
-			XMLNode xCrossing = xCrossingsNode.getChildNode("crossing", i);
-
-			int id = xmltoi(xCrossing.getAttribute("id"), -1);
-			int sub1_id = xmltoi(xCrossing.getAttribute("subroom1_id"), -1);
-			int sub2_id = xmltoi(xCrossing.getAttribute("subroom2_id"), -1);
-			double x1 = xmltof(
-					xCrossing.getChildNode("vertex", 0).getAttribute("px"));
-			double y1 = xmltof(
-					xCrossing.getChildNode("vertex", 0).getAttribute("py"));
-			double x2 = xmltof(
-					xCrossing.getChildNode("vertex", 1).getAttribute("px"));
-			double y2 = xmltof(
-					xCrossing.getChildNode("vertex", 1).getAttribute("py"));
+			int id = xmltoi(xCrossing->Attribute("id"), -1);
+			int sub1_id = xmltoi(xCrossing->Attribute("subroom1_id"), -1);
+			int sub2_id = xmltoi(xCrossing->Attribute("subroom2_id"), -1);
+
+			double x1 = xmltof(	xCrossing->FirstChildElement("vertex")->Attribute("px"));
+			double y1 = xmltof(	xCrossing->FirstChildElement("vertex")->Attribute("py"));
+			double x2 = xmltof(	xCrossing->LastChild("vertex")->ToElement()->Attribute("px"));
+			double y2 = xmltof(	xCrossing->LastChild("vertex")->ToElement()->Attribute("py"));
 
 			Crossing* c = new Crossing();
 			c->SetID(id);
@@ -426,25 +435,28 @@ void Building::LoadBuilding(string filename) {
 		AddRoom(room);
 	}
 
-	// all rooms are read, now proceed with transitions
-	XMLNode xTransNode = xMainNode.getChildNode("transitions");
-	int nTrans = xTransNode.nChildNode("transition");
 
-	for (int i = 0; i < nTrans; i++) {
-		XMLNode xTrans = xTransNode.getChildNode("transition", i);
+	// all rooms are read, now proceed with transitions
+	TiXmlNode*  xTransNode = xRootNode->FirstChild("transitions");
+	if(xTransNode)
+	for(TiXmlElement* xTrans = xTransNode->FirstChildElement("transition"); xTrans;
+			xTrans = xTrans->NextSiblingElement("transition")) {
 
-		int id = xmltoi(xTrans.getAttribute("id"), -1);
+		int id = xmltoi(xTrans->Attribute("id"), -1);
 		string caption = "door " + id;
-		caption = xmltoa(xTrans.getAttribute("caption"), caption.c_str());
-		int room1_id = xmltoi(xTrans.getAttribute("room1_id"), -1);
-		int room2_id = xmltoi(xTrans.getAttribute("room2_id"), -1);
-		int subroom1_id = xmltoi(xTrans.getAttribute("subroom1_id"), -1);
-		int subroom2_id = xmltoi(xTrans.getAttribute("subroom2_id"), -1);
-		double x1 = xmltof(xTrans.getChildNode("vertex", 0).getAttribute("px"));
-		double y1 = xmltof(xTrans.getChildNode("vertex", 0).getAttribute("py"));
-		double x2 = xmltof(xTrans.getChildNode("vertex", 1).getAttribute("px"));
-		double y2 = xmltof(xTrans.getChildNode("vertex", 1).getAttribute("py"));
-		string type = xmltoa(xTrans.getAttribute("type"), "normal");
+		caption = xmltoa(xTrans->Attribute("caption"), caption.c_str());
+		int room1_id = xmltoi(xTrans->Attribute("room1_id"), -1);
+		int room2_id = xmltoi(xTrans->Attribute("room2_id"), -1);
+		int subroom1_id = xmltoi(xTrans->Attribute("subroom1_id"), -1);
+		int subroom2_id = xmltoi(xTrans->Attribute("subroom2_id"), -1);
+		string type = xmltoa(xTrans->Attribute("type"), "normal");
+
+		double x1 = xmltof(	xTrans->FirstChildElement("vertex")->Attribute("px"));
+		double y1 = xmltof(	xTrans->FirstChildElement("vertex")->Attribute("py"));
+
+		double x2 = xmltof(	xTrans->LastChild("vertex")->ToElement()->Attribute("px"));
+		double y2 = xmltof(	xTrans->LastChild("vertex")->ToElement()->Attribute("py"));
+
 
 		Transition* t = new Transition();
 		t->SetID(id);
@@ -481,6 +493,8 @@ void Building::LoadBuilding(string filename) {
 
 		AddTransition(t);
 	}
+
+
 	Log->Write("INFO: \tLoading building file successful!!!\n");
 }
 
@@ -620,131 +634,13 @@ Crossing* Building::GetGoal(string caption) const {
 	exit(EXIT_FAILURE);
 }
 
-
-
-void Building::LoadTrafficInfo(string filename) {
-
-	Log->Write("INFO:\tLoading  the traffic info file");
-
-	if (filename == "") {
-		Log->Write("INFO:\t No file supplied !");
-		Log->Write("INFO:\t done with loading traffic info file");
-		return;
-	}
-
-	XMLNode xMainNode = XMLNode::openFileHelper(filename.c_str(), "traffic");
-
-	double version = xmltof(xMainNode.getAttribute("version"), -1);
-	if (version < 0.4) {
-		Log->Write("ERROR: \tOnly version > 0.4 supported");
-		Log->Write("ERROR: \tparsing traffic file failed!");
-		exit(EXIT_FAILURE);
-	}
-
-	//The file has two main nodes
-	//<rooms> and <transitions>
-
-	XMLNode xRoomsNode = xMainNode.getChildNode("rooms");
-	int nRooms = xRoomsNode.nChildNode("room");
-
-	//processing the rooms node
-	for (int i = 0; i < nRooms; i++) {
-		XMLNode xRoom = xRoomsNode.getChildNode("room", i);
-		double id = xmltof(xRoom.getAttribute("room_id"), -1);
-		string state = xmltoa(xRoom.getAttribute("state"), "good");
-		RoomState status = (state == "good") ? ROOM_CLEAN : ROOM_SMOKED;
-		_rooms[id]->SetState(status);
-	}
-
-	//processing the doors node
-	XMLNode xDoorsNode = xMainNode.getChildNode("doors");
-	int nDoors = xDoorsNode.nChildNode("door");
-
-	for (int i = 0; i < nDoors; i++) {
-		XMLNode xDoor = xDoorsNode.getChildNode("door", i);
-		int id = xmltoi(xDoor.getAttribute("trans_id"), -1);
-		string state = xmltoa(xDoor.getAttribute("state"), "open");
-
-		//maybe the door caption is specified ?
-		if(id==-1){
-			string caption=xmltoa(xDoor.getAttribute("caption"), "-1");
-			if( (caption!="-1") && (state =="close") ){
-				GetTransition(caption)->Close();
-			}
-		}
-		else {
-			//store transition in a map and call getTransition/getCrossin
-			if (state == "open") {
-				GetTransition(id)->Open();
-			} else if (state == "close") {
-				GetTransition(id)->Close();
-			} else {
-				char tmp[CLENGTH];
-				sprintf(tmp, "WARNING:\t Unknown door state: %s", state.c_str());
-				Log->Write(tmp);
-			}
-		}
-	}
-	Log->Write("INFO:\t done with loading traffic info file");
-}
-
-void Building::StringExplode(string str, string separator,
-		vector<string>* results) {
-	size_t found;
-	found = str.find_first_of(separator);
-	while (found != string::npos) {
-		if (found > 0) {
-			results->push_back(str.substr(0, found));
-		}
-		str = str.substr(found + 1);
-		found = str.find_first_of(separator);
-	}
-	if (str.length() > 0) {
-		results->push_back(str);
-	}
-}
-
-
-//void Building::InitRoomsAndSubroomsMap(){
-//	Log->write("INFO: \tcreating the rooms maps!!!\n");
-//
-//	for (int i=0;i<16;i++)
-//		for (int j=0;j<130;j++)
-//			for (int k=0;k<16;k++)
-//				for (int l=0;l<130;l++)
-//					pSubroomConnectionMap[i][j][k][l]=0;
-//
-//	//create the subroom connections map
-//	for (unsigned int r1=0;r1< pRooms.size();r1++){
-//		Room* room1= GetRoom(r1);
-//		const vector <SubRoom*> sb1s=room1->GetAllSubRooms();
-//
-//		for (unsigned int r2=0;r2<pRooms.size();r2++){
-//			Room* room2= GetRoom(r2);
-//			const vector <SubRoom*> sb2s=room2->GetAllSubRooms();
-//
-//			// now looping over all subrooms
-//			for(unsigned int s1=0;s1<sb1s.size();s1++){
-//				for(unsigned int s2=0;s2<sb2s.size();s2++){
-//					if(sb1s[s1]->IsDirectlyConnectedWith(sb2s[s2])){
-//						pSubroomConnectionMap[r1][s1][r2][s2]=1;
-//						//cout<<"connected"<<endl;
-//					}else{
-//						pSubroomConnectionMap[r1][s1][r2][s2]=0;
-//					}
-//				}
-//			}
-//		}
-//	}
-//}
-
 #ifdef _SIMULATOR
 
 void Building::Update() {
 	// some peds may change the room via another crossing than the primary intended one
 	// in that case they are set in the wrong room.
 	vector<Pedestrian*> nonConformPeds;
-
+        printf("enter Building::update\n");
 	for (int i = 0; i < GetNumberOfRooms(); i++) {
 		Room* room = GetRoom(i);
 
@@ -852,20 +748,17 @@ void Building::Update() {
 	// find the new goals, the parallel way
 
 	unsigned int nSize = _allPedestians.size();
-	int nThreads = 1;
-
-#ifdef _OPENMP
-	nThreads = omp_get_max_threads();
-#endif
+	int nThreads = omp_get_max_threads();
 
 	// check if worth sharing the work
-	if (nSize < 12)
-		nThreads = 1;
+	//if (nSize < 12)
+	//	nThreads = 1;
+
 	int partSize = nSize / nThreads;
 
 #pragma omp parallel  default(shared) num_threads(nThreads)
 	{
-		const int threadID = omp_get_thread_num();
+        const int threadID = omp_get_thread_num();
 		int start = threadID * partSize;
 		int end = (threadID + 1) * partSize - 1;
 		if ((threadID == nThreads - 1))
@@ -885,6 +778,7 @@ void Building::Update() {
 	//CleanUpTheScene();
 }
 
+
 void Building::InitPhiAllPeds(double pDt) {
 	for (int i = 0; i < GetNumberOfRooms(); i++) {
 		Room* room = GetRoom(i);
@@ -894,9 +788,12 @@ void Building::InitPhiAllPeds(double pDt) {
 				double cosPhi, sinPhi;
 				Pedestrian* ped = sub->GetPedestrian(k);
 				ped->Setdt(pDt); //set the simulation step
+				ped->SetRoomID(room->GetID(), room->GetCaption());
 				//a destination could not be found for that pedestrian
 				if (ped->FindRoute() == -1) {
-					DeletePedFromSim(ped);
+					// DeletePedFromSim(ped);
+					sub->DeletePedestrian(k--);
+					continue;
 				}
 				Line* e = ped->GetExitLine();
 				const Point& e1 = e->GetPoint1();
@@ -918,7 +815,6 @@ void Building::InitPhiAllPeds(double pDt) {
 				E.SetCosPhi(cosPhi);
 				E.SetSinPhi(sinPhi);
 				ped->SetEllipse(E);
-				ped->SetRoomID(room->GetID(), room->GetCaption());
 			}
 		}
 	}
@@ -1005,88 +901,6 @@ void Building::InitGrid(double cellSize) {
 
 
 
-void Building::InitSavePedPathway(string filename) {
-	_pathWayStream.open(filename.c_str());
-	_savePathway = true;
-
-	if (_pathWayStream.is_open()) {
-		Log->Write("#INFO:\tsaving pedestrian paths to [ " + filename + " ]");
-		_pathWayStream << "##pedestrian ways" << endl;
-		_pathWayStream << "#nomenclature roomid  caption" << endl;
-		//		for (unsigned int r=0;r< pRooms.size();r++){
-		//			Room* room= GetRoom(r);
-		//			const vector<int>& goals=room->GetAllTransitionsIDs();
-		//
-		//			for(unsigned int g=0;g<goals.size();g++){
-		//				int exitid=goals[g];
-		//				string exit_caption=pRouting->GetGoal(exitid)->GetCaption();
-		//				PpathWayStream<<exitid<<" "<<exit_caption<<endl;
-		//			}
-		//		}
-		//
-		_pathWayStream << "#data room exit_id" << endl;
-	} else {
-		Log->Write("#INFO:\t Unable to open [ " + filename + " ]");
-		Log->Write("#INFO:\t saving to stdout");
-
-	}
-}
-
-void Building::CleanUpTheScene() {
-	//return;
-	static int counter = 0;
-	counter++;
-	static int totalSliced = 0;
-
-	int updateRate = 80.0 / 0.01; // 20 seconds/pDt
-
-	if (counter % updateRate == 0) {
-		for (unsigned int i = 0; i < _allPedestians.size(); i++) {
-			Pedestrian* ped = _allPedestians[i];
-
-			if (ped->GetDistanceSinceLastRecord() < 0.1) {
-				//delete from the simulation
-				DeletePedFromSim(ped);
-
-				totalSliced++;
-				char msg[CLENGTH];
-				sprintf(msg, "INFO:\t slicing Ped %d from room %s, total [%d]",
-						ped->GetID(),
-						_rooms[ped->GetRoomID()]->GetCaption().c_str(),
-						totalSliced);
-				Log->Write(msg);
-			} else {
-				ped->RecordActualPosition();
-			}
-
-		}
-	}
-
-}
-
-//bool  Building::IsDirectlyConnected(int room1, int subroom1, int room2,
-//		int subroom2) {
-//	return pSubroomConnectionMap[room1][subroom1][room2][subroom2];
-//}
-
-
-
-Pedestrian* Building::GetPedestrian(int pedID) const {
-	for (unsigned int i = 0; i < _rooms.size(); i++) {
-		Room* room = _rooms[i];
-		for (int j = 0; j < room->GetNumberOfSubRooms(); j++) {
-			SubRoom* sub = room->GetSubRoom(j);
-			for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) {
-				Pedestrian* p = sub->GetPedestrian(k);
-				if (p->GetID() == pedID) {
-					return p;
-				}
-			}
-		}
-	}
-	return NULL;
-}
-
 void Building::DumpSubRoomInRoom(int roomID, int subID) {
 	SubRoom* sub = GetRoom(roomID)->GetSubRoom(subID);
 	if (sub->GetNumberOfPedestrians() == 0)
@@ -1097,8 +911,10 @@ void Building::DumpSubRoomInRoom(int roomID, int subID) {
 		cout << " ID: " << ped->GetID();
 		cout << " Index: " << p << endl;
 	}
+
 }
 
+
 void Building::LoadRoutingInfo(string filename) {
 	Log->Write("INFO:\tLoading extra routing information");
 	if (filename == "") {
@@ -1107,36 +923,50 @@ void Building::LoadRoutingInfo(string filename) {
 		return;
 	}
 
-	XMLNode xMainNode = XMLNode::openFileHelper(filename.c_str(), "routing");
+	TiXmlDocument docRouting(filename);
+	if (!docRouting.LoadFile()){
+		Log->Write("ERROR: \t%s", docRouting.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the routing file");
+		exit(EXIT_FAILURE);
+	}
+
+	TiXmlElement* xRootNode = docRouting.RootElement();
+	if( ! xRootNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
+
+	if( xRootNode->ValueStr () != "routing" ) {
+		Log->Write("ERROR:\tRoot element value is not 'routing'.");
+		exit(EXIT_FAILURE);
+	}
 
-	double version = xmltof(xMainNode.getAttribute("version"), -1);
+	double version = xmltof(xRootNode->Attribute("version"), -1);
 	if (version < 0.4) {
 		Log->Write("ERROR: \tOnly version > 0.4 supported");
 		Log->Write("ERROR: \tparsing routing file failed!");
 		exit(EXIT_FAILURE);
 	}
 
-	//actually only contains one Hlines node
-	XMLNode xHlinesNode = xMainNode.getChildNode("Hlines");
-	int nHlines = xHlinesNode.nChildNode("Hline");
+	//parsing the crossings
+	TiXmlNode*  xHlinesNode = xRootNode->FirstChild("Hlines");
 
-	//processing the rooms node
-	for (int i = 0; i < nHlines; i++) {
-		XMLNode hline = xHlinesNode.getChildNode("hline", i);
-		double id = xmltof(hline.getAttribute("id"), -1);
-		int room_id = xmltoi(hline.getAttribute("room_id"), -1);
-		int subroom_id = xmltoi(hline.getAttribute("subroom_id"), -1);
+	if(xHlinesNode)
+	for(TiXmlElement* hline = xHlinesNode->FirstChildElement("Hline"); hline;
+			hline = hline->NextSiblingElement("Hline")) {
 
-		double x1 = xmltof(hline.getChildNode("vertex", 0).getAttribute("px"));
-		double y1 = xmltof(hline.getChildNode("vertex", 0).getAttribute("py"));
-		double x2 = xmltof(hline.getChildNode("vertex", 1).getAttribute("px"));
-		double y2 = xmltof(hline.getChildNode("vertex", 1).getAttribute("py"));
+		double id = xmltof(hline->Attribute("id"), -1);
+		int room_id = xmltoi(hline->Attribute("room_id"), -1);
+		int subroom_id = xmltoi(hline->Attribute("subroom_id"), -1);
 
+		double x1 = xmltof(	hline->FirstChildElement("vertex")->Attribute("px"));
+		double y1 = xmltof(	hline->FirstChildElement("vertex")->Attribute("py"));
+		double x2 = xmltof(	hline->LastChild("vertex")->ToElement()->Attribute("px"));
+		double y2 = xmltof(	hline->LastChild("vertex")->ToElement()->Attribute("py"));
 
 		Room* room = _rooms[room_id];
 		SubRoom* subroom = room->GetSubRoom(subroom_id);
 
-
 		//new implementation
 		Hline* h = new Hline();
 		h->SetID(id);
@@ -1147,22 +977,21 @@ void Building::LoadRoutingInfo(string filename) {
 
 		AddHline(h);
 		subroom->AddHline(h);
-
 	}
 
 	//load the pre-defined trips
-	XMLNode xTripsNode = xMainNode.getChildNode("trips");
-	int nTrips = xTripsNode.nChildNode("trip");
+	TiXmlNode*  xTripsNode = xRootNode->FirstChild("trips");
 
-	//processing the rooms node
-	for (int i = 0; i < nTrips; i++) {
-		XMLNode trip = xTripsNode.getChildNode("trip", i);
-		double id = xmltof(trip.getAttribute("id"), -1);
+	if(xTripsNode)
+	for(TiXmlElement* trip = xTripsNode->FirstChildElement("trip"); trip;
+			trip = trip->NextSiblingElement("trip")) {
+
+		double id = xmltof(trip->Attribute("id"), -1);
 		if (id == -1) {
 			Log->Write("ERROR:\t id missing for trip");
 			exit(EXIT_FAILURE);
 		}
-		string sTrip = trip.getText();
+		string sTrip = trip->FirstChild()->ValueStr();
 		vector<string> vTrip;
 		vTrip.clear();
 
@@ -1174,7 +1003,84 @@ void Building::LoadRoutingInfo(string filename) {
 		}
 		_routingEngine->AddTrip(vTrip);
 	}
-	Log->Write("INFO:\t done with loading extra routing information");
+	Log->Write("INFO:\tdone with loading extra routing information");
+}
+
+void Building::LoadTrafficInfo(string filename) {
+
+	Log->Write("INFO:\tLoading  the traffic info file");
+
+	if (filename == "") {
+		Log->Write("INFO:\t No file supplied !");
+		Log->Write("INFO:\tdone with loading traffic info file");
+		return;
+	}
+
+	TiXmlDocument docTraffic(filename);
+	if (!docTraffic.LoadFile()){
+		Log->Write("ERROR: \t%s", docTraffic.ErrorDesc());
+		Log->Write("ERROR: \t could not parse the traffic file");
+		exit(EXIT_FAILURE);
+	}
+
+	TiXmlElement* xRootNode = docTraffic.RootElement();
+	if( ! xRootNode ) {
+		Log->Write("ERROR:\tRoot element does not exist");
+		exit(EXIT_FAILURE);
+	}
+
+	if( xRootNode->ValueStr () != "traffic" ) {
+		Log->Write("ERROR:\tRoot element value is not 'traffic'.");
+		exit(EXIT_FAILURE);
+	}
+
+	double version = xmltof(xRootNode->Attribute("version"), -1);
+	if (version < 0.4) {
+		Log->Write("ERROR: \tOnly version > 0.4 supported");
+		Log->Write("ERROR: \tparsing traffic file failed!");
+		exit(EXIT_FAILURE);
+	}
+
+	//processing the rooms node
+	TiXmlNode*  xRoomsNode = xRootNode->FirstChild("rooms");
+	for(TiXmlElement* xRoom = xRoomsNode->FirstChildElement("room"); xRoom;
+			xRoom = xRoom->NextSiblingElement("room")) {
+
+		double id = xmltof(xRoom->Attribute("room_id"), -1);
+		string state = xmltoa(xRoom->Attribute("state"), "good");
+		RoomState status = (state == "good") ? ROOM_CLEAN : ROOM_SMOKED;
+		_rooms[id]->SetState(status);
+	}
+
+	//processing the doors node
+	TiXmlNode*  xDoorsNode = xRootNode->FirstChild("doors");
+		for(TiXmlElement* xDoor = xDoorsNode->FirstChildElement("door"); xDoor;
+				xDoor = xDoor->NextSiblingElement("door")) {
+
+		int id = xmltoi(xDoor->Attribute("trans_id"), -1);
+		string state = xmltoa(xDoor->Attribute("state"), "open");
+
+		//maybe the door caption is specified ?
+		if(id==-1){
+			string caption=xmltoa(xDoor->Attribute("caption"), "-1");
+			if( (caption!="-1") && (state =="close") ){
+				GetTransition(caption)->Close();
+			}
+		}
+		else {
+			//store transition in a map and call getTransition/getCrossin
+			if (state == "open") {
+				GetTransition(id)->Open();
+			} else if (state == "close") {
+				GetTransition(id)->Close();
+			} else {
+				char tmp[CLENGTH];
+				sprintf(tmp, "WARNING:\t Unknown door state: %s", state.c_str());
+				Log->Write(tmp);
+			}
+		}
+	}
+	Log->Write("INFO:\t done with loading traffic info file");
 }
 
 void Building::DeletePedestrian(Pedestrian* ped) {
@@ -1234,6 +1140,99 @@ void Building::AddPedestrian(Pedestrian* ped) {
 
 }
 
+
+void Building::InitSavePedPathway(string filename) {
+	_pathWayStream.open(filename.c_str());
+	_savePathway = true;
+
+	if (_pathWayStream.is_open()) {
+		Log->Write("#INFO:\tsaving pedestrian paths to [ " + filename + " ]");
+		_pathWayStream << "##pedestrian ways" << endl;
+		_pathWayStream << "#nomenclature roomid  caption" << endl;
+		//		for (unsigned int r=0;r< pRooms.size();r++){
+		//			Room* room= GetRoom(r);
+		//			const vector<int>& goals=room->GetAllTransitionsIDs();
+		//
+		//			for(unsigned int g=0;g<goals.size();g++){
+		//				int exitid=goals[g];
+		//				string exit_caption=pRouting->GetGoal(exitid)->GetCaption();
+		//				PpathWayStream<<exitid<<" "<<exit_caption<<endl;
+		//			}
+		//		}
+		//
+		_pathWayStream << "#data room exit_id" << endl;
+	} else {
+		Log->Write("#INFO:\t Unable to open [ " + filename + " ]");
+		Log->Write("#INFO:\t saving to stdout");
+
+	}
+}
+
+void Building::CleanUpTheScene() {
+	//return;
+	static int counter = 0;
+	counter++;
+	static int totalSliced = 0;
+
+	int updateRate = 80.0 / 0.01; // 20 seconds/pDt
+
+	if (counter % updateRate == 0) {
+		for (unsigned int i = 0; i < _allPedestians.size(); i++) {
+			Pedestrian* ped = _allPedestians[i];
+
+			if (ped->GetDistanceSinceLastRecord() < 0.1) {
+				//delete from the simulation
+				DeletePedFromSim(ped);
+
+				totalSliced++;
+				char msg[CLENGTH];
+				sprintf(msg, "INFO:\t slicing Ped %d from room %s, total [%d]",
+						ped->GetID(),
+						_rooms[ped->GetRoomID()]->GetCaption().c_str(),
+						totalSliced);
+				Log->Write(msg);
+			} else {
+				ped->RecordActualPosition();
+			}
+
+		}
+	}
+
+}
+
+
+void Building::StringExplode(string str, string separator,
+		vector<string>* results) {
+	size_t found;
+	found = str.find_first_of(separator);
+	while (found != string::npos) {
+		if (found > 0) {
+			results->push_back(str.substr(0, found));
+		}
+		str = str.substr(found + 1);
+		found = str.find_first_of(separator);
+	}
+	if (str.length() > 0) {
+		results->push_back(str);
+	}
+}
+
+Pedestrian* Building::GetPedestrian(int pedID) const {
+	for (unsigned int i = 0; i < _rooms.size(); i++) {
+		Room* room = _rooms[i];
+		for (int j = 0; j < room->GetNumberOfSubRooms(); j++) {
+			SubRoom* sub = room->GetSubRoom(j);
+			for (int k = 0; k < sub->GetNumberOfPedestrians(); k++) {
+				Pedestrian* p = sub->GetPedestrian(k);
+				if (p->GetID() == pedID) {
+					return p;
+				}
+			}
+		}
+	}
+	return NULL;
+}
+
 int Building::GetNumberOfPedestrians() const {
 	int sum = 0;
 	for (unsigned int wa = 0; wa < _rooms.size(); wa++) {
@@ -1242,12 +1241,7 @@ int Building::GetNumberOfPedestrians() const {
 	return sum;
 }
 
-LCGrid* Building::GetGrid() const {
-	return _linkedCellGrid;
-}
-
 // FIXME: you should get rid of this method
-
 Crossing* Building::GetGoal(int index) {
 	if (_transitions.count(index) == 1) {
 		return _transitions[index];
@@ -1270,4 +1264,5 @@ Crossing* Building::GetGoal(int index) {
 	}
 }
 
-#endif //_SIMULATOR
+
+#endif // _SIMULATOR
diff --git a/geometry/Building.h b/geometry/Building.h
index abfb45e290dff59f0454d7b1ab1c844630fec935..5fe4869b16cacc8a6847a0169acdaa0da666b667 100644
--- a/geometry/Building.h
+++ b/geometry/Building.h
@@ -121,7 +121,6 @@ public:
 	void AddHline(Hline* line);
 
 
-
     // Ein-Ausgabe
     void LoadBuilding(std::string filename); // Laedt Geometrie-Datei
     void LoadTrafficInfo(std::string filename);
@@ -135,7 +134,6 @@ public:
 	//bool IsDirectlyConnected(int room1, int subroom1,int room2, int subroom2);
 
 private:
-	// wird nur innerhalb von Building benötigt
 	void StringExplode(std::string str, std::string separator, std::vector<std::string>* results);
 
 };
diff --git a/geometry/Line.cpp b/geometry/Line.cpp
index d3581af5d8a1d38dbc6b0e2e531745d07653ddc8..b3bd07ed4d98300b4abddf3c826f6b23d42e5266 100644
--- a/geometry/Line.cpp
+++ b/geometry/Line.cpp
@@ -31,7 +31,6 @@
 
 #include  <cmath>
 #include  <sstream>
-#include  <cstdlib>
 
 int Line::_static_UID=0;
 
@@ -132,7 +131,7 @@ Point Line::NormalVec() const {
 		norm = sqrt(nx * nx + ny * ny);
 		if (fabs(norm) < J_EPS) {
 			Log->Write("ERROR: \tLine::NormalVec() norm==0\n");
-			exit(EXIT_FAILURE);
+			exit(0);
 		}
 		nx /= norm;
 		ny /= norm;
@@ -222,7 +221,7 @@ bool Line::IsInLine(const Point& p) const {
 		lambda = (py - ay) / (by - ay);
 	} else {
 		Log->Write("ERROR: \tIsInLine: Endpunkt = Startpunkt!!!");
-		exit(EXIT_FAILURE);
+		exit(0);
 	}
 	return (0 <= lambda) && (lambda <= 1);
 }
@@ -293,12 +292,12 @@ double Line::LengthSquare() const {
 
 bool Line::IntersectionWith(const Line& l) const {
 
-	double deltaACy = this->_point1.GetY() - l.GetPoint1().GetY();
+	double deltaACy = _point1.GetY() - l.GetPoint1().GetY();
 	double deltaDCx = l.GetPoint2().GetX() - l.GetPoint1().GetX();
-	double deltaACx = this->_point1.GetX() - l.GetPoint1().GetX();
+	double deltaACx = _point1.GetX() - l.GetPoint1().GetX();
 	double deltaDCy = l.GetPoint2().GetY() - l.GetPoint1().GetY();
-	double deltaBAx = this->_point2.GetX() - this->_point1.GetX();
-	double deltaBAy = this->_point2.GetY() - this->_point1.GetY();
+	double deltaBAx = _point2.GetX() - _point1.GetX();
+	double deltaBAy = _point2.GetY() - _point1.GetY();
 
 	double denominator = deltaBAx * deltaDCy - deltaBAy * deltaDCx;
 	double numerator = deltaACy * deltaDCx - deltaACx * deltaDCy;
@@ -335,6 +334,29 @@ bool Line::IntersectionWith(const Line& l) const {
 	return true;
 }
 
+bool Line::IsHorizontal(){
+	return fabs (_point1._y-_point2._y ) <= J_EPS;
+}
+
+bool Line::IsVertical(){
+	return fabs (_point1._x-_point2._x ) <= J_EPS;
+}
+
+int Line::WichSide(const Point& pt) {
+	//special case for horizontal lines
+	if (IsVertical()) {
+		//left
+		if (pt._x < _point1._x)
+			return 0;
+		//right or colinear
+		if (pt._x >= _point1._x)
+			return 1;
+	}
+
+	return ((_point2._x - _point1._x) * (pt._y - _point1._y)
+			- (_point2._y - _point1._y) * (pt._x - _point1._x)) > 0;
+}
+
 bool Line::IntersectionWithCircle(const Point& centre, double radius /*cm for pedestrians*/){
 
 	double r=radius;
diff --git a/geometry/Line.h b/geometry/Line.h
index 834003de320b77eaa8f33b9a38e8a7ef789f7cc9..eb707b911f303a5c0f3ef56e6dcb4835fb76f595 100644
--- a/geometry/Line.h
+++ b/geometry/Line.h
@@ -71,7 +71,6 @@ public:
 	 */
 	void SetPoint2(const Point& p);
 
-
 	/**
 	 * Set/Get the first end point of the line
 	 */
@@ -87,7 +86,6 @@ public:
 	 */
 	const Point& GetCentre(void) const;
 
-
     /**
      * @return a normal vector to this line
      */
@@ -130,7 +128,6 @@ public:
      */
     double DistToSquare(const Point& p) const;
 
-
     /**
      * @return the length (Norm) of the line
      */
@@ -165,6 +162,27 @@ public:
 	 */
 	bool IntersectionWithCircle(const Point& centre, double radius=0.30 /*m for pedestrians*/);
 
+	/**
+	 * return the same value if the checked points are all situated on the same side.
+	 * @return 0 or 1 depending on which side of the line the point is located.
+	 */
+	int WichSide (const Point& pt);
+
+	/**
+	 * @return true if the point is located in the left hand side of the line.
+	 * For horizontal lines return true if the point is above the line.
+	 */
+	bool IsLeft (const Point& pt);
+
+	/**
+	 * @return true for horizontal lines
+	 */
+	bool IsHorizontal();
+
+	/**
+	 * @return true for vertical lines
+	 */
+	bool IsVertical();
 
 	/**
 	 * @return a nice formated string describing the line
diff --git a/geometry/Obstacle.cpp b/geometry/Obstacle.cpp
index d0ba34d676dd9b36da49b3da27c3d075d7f22dc9..254d4996d2bd62764b702b4f8fd0f077c871339b 100644
--- a/geometry/Obstacle.cpp
+++ b/geometry/Obstacle.cpp
@@ -30,7 +30,6 @@
 #include "Wall.h"
 #include "Point.h"
 
-#include  <cstdlib>
 
 using namespace std;
 
diff --git a/geometry/Room.cpp b/geometry/Room.cpp
index cefd707c6830cd0eaf2d513e4d9d6b30fed939e1..40dab33a4ddb479b89f766dd32495e7b22d100e6 100644
--- a/geometry/Room.cpp
+++ b/geometry/Room.cpp
@@ -122,9 +122,24 @@ SubRoom* Room::GetSubRoom(int index) const {
 }
 
 
+#ifdef _SIMULATOR
+
+int Room::GetNumberOfPedestrians() const {
+    int sum = 0;
+    for (int i = 0; i < GetNumberOfSubRooms(); i++) {
+        sum += GetSubRoom(i)->GetNumberOfPedestrians();
+    }
+    return sum;
+}
+
+#endif // _SIMULATOR
+
 RoomState Room::GetState() const {
 	return _state;
 }
+
+
+
 /*************************************************************
  Sonstige Funktionen
  ************************************************************/
@@ -141,6 +156,10 @@ void Room::DeleteSubRoom(int index) {
     }
 }
 
+/*************************************************************
+ Ein-Ausgabe
+ ************************************************************/
+
 
 void Room::WriteToErrorLog() const {
     char tmp[CLENGTH];
@@ -171,15 +190,3 @@ void Room::SetOutputHandler(OutputHandler* oh){
 OutputHandler* Room::GetOutputHandler() const {
 	return _outputFile;
 }
-
-#ifdef _SIMULATOR
-
-int Room::GetNumberOfPedestrians() const {
-    int sum = 0;
-    for (int i = 0; i < GetNumberOfSubRooms(); i++) {
-        sum += GetSubRoom(i)->GetNumberOfPedestrians();
-    }
-    return sum;
-}
-
-#endif
diff --git a/geometry/Room.h b/geometry/Room.h
index 357c5f451f507d571e1e475668e2488c0e6f4637..7917089bc9899b8a92036f9c140313c95fd31be5 100644
--- a/geometry/Room.h
+++ b/geometry/Room.h
@@ -116,13 +116,11 @@ public:
 	 */
     SubRoom* GetSubRoom(int index) const;
 
-#ifdef _SIMULATOR
     /**
      * @return the number of pedestrians in the rooms (all subrooms)
      */
     int GetNumberOfPedestrians() const;
 
-#endif
     /**
      * @return the state for this room
      */
diff --git a/geometry/SubRoom.cpp b/geometry/SubRoom.cpp
index e16f4eaf3899db9db83c368ec165441e6c621789..0d60b8808f5296e9385fdb6aa98ca3b4541467f3 100644
--- a/geometry/SubRoom.cpp
+++ b/geometry/SubRoom.cpp
@@ -33,14 +33,11 @@
 #include "Wall.h"
 
 #ifdef _SIMULATOR
-
 #include "../pedestrian/Pedestrian.h"
-
-#endif
+#endif //_SIMULATOR
 
 #include <cmath>
 
-
 using namespace std;
 
 /************************************************************
@@ -71,7 +68,7 @@ SubRoom::SubRoom() {
 
 #ifdef _SIMULATOR
 	_peds = vector<Pedestrian* > ();
-#endif
+#endif //_SIMULATOR
 
 }
 
@@ -87,24 +84,23 @@ SubRoom::SubRoom(const SubRoom& orig) {
 
 #ifdef _SIMULATOR
 	_peds = orig.GetAllPedestrians();
-#endif
-
+#endif //_SIMULATOR
 }
 
 SubRoom::~SubRoom() {
 	if (_walls.size() > 0) _walls.clear();
 	if (_poly.size() > 0) _poly.clear();
+	for (unsigned int i = 0; i < _obstacles.size(); i++) {
+		delete _obstacles[i];
+	}
+	_obstacles.clear();
 
 #ifdef _SIMULATOR
 	for (unsigned int i = 0; i < _peds.size(); i++) {
 		delete _peds[i];
 	}
-#endif
+#endif //_SIMULATOR
 
-	for (unsigned int i = 0; i < _obstacles.size(); i++) {
-		delete _obstacles[i];
-	}
-	_obstacles.clear();
 }
 
 // Setter -Funktionen
@@ -120,29 +116,8 @@ void SubRoom::SetRoomID(int ID) {
 	_roomID = ID;
 }
 
-//void SubRoom::SetAllWalls(const vector<Wall>& walls) {
-//	_walls = walls;
-//}
-//
-//void SubRoom::SetWall(const Wall& wall, int index) {
-//	if ((index >= 0) && (index < GetAnzWalls())) {
-//		_walls[index] = wall;
-//	} else {
-//		Log->Write("ERROR: Wrong Index in SubRoom::SetWall()");
-//		exit(0);
-//	}
-//}
-
-//void SubRoom::SetPolygon(const vector<Point>& poly) {
-//	_poly = poly;
-//}
-
 
 
-//void SubRoom::SetArea(double a) {
-//	_area = a;
-//}
-// Getter - Funktionen
 
 int SubRoom::GetSubRoomID() const {
 	return _id;
@@ -188,79 +163,22 @@ const vector<Point>& SubRoom::GetPolygon() const {
 	return _poly;
 }
 
+
 const vector<Obstacle*>& SubRoom::GetAllObstacles() const {
 	return _obstacles;
 }
 
-void SubRoom::AddObstacle(Obstacle* obs){
-	_obstacles.push_back(obs);
-}
 
-#ifdef _SIMULATOR
-void SubRoom::SetAllPedestrians(const vector<Pedestrian*>& peds) {
-	_peds = peds;
-}
-
-void SubRoom::SetPedestrian(Pedestrian* ped, int index) {
-	if ((index >= 0) && (index < GetNumberOfPedestrians())) {
-		_peds[index] = ped;
-	} else {
-		Log->Write("ERROR: Wrong Index in SubRoom::SetPedestrian()");
-		exit(0);
-	}
-}
 
-int SubRoom::GetNumberOfPedestrians() const {
-	return _peds.size();
-}
-
-const vector<Pedestrian*>& SubRoom::GetAllPedestrians() const {
-	return _peds;
-}
-
-Pedestrian* SubRoom::GetPedestrian(int index) const {
-	if ((index >= 0) && (index < (int) GetNumberOfPedestrians()))
-		return _peds[index];
-	else {
-		Log->Write("ERROR: Wrong 'index' in SubRoom::GetPedestrian()");
-		exit(0);
-	}
-}
-
-
-void SubRoom::AddPedestrian(Pedestrian* ped) {
-	_peds.push_back(ped);
-}
-
-
-void SubRoom::DeletePedestrian(int index) {
-	if ((index >= 0) && (index < (int) GetNumberOfPedestrians())) {
-		_peds.erase(_peds.begin() + index);
-
-	} else {
-		Log->Write("ERROR: Wrong Index in SubRoom::DeletePedestrian()");
-		exit(0);
-	}
-}
-
-bool SubRoom::IsInSubRoom(Pedestrian* ped) const {
-	Point pos = ped->GetPos();
-	if (ped->GetExitLine()->DistTo(pos) <= J_EPS_GOAL)
-		return true;
-	else
-		return IsInSubRoom(pos);
+int SubRoom::GetNumberOfGoalIDs() const {
+	return _goalIDs.size();
 }
 
-void SubRoom::ClearAllPedestrians(){
-	for(unsigned int p=0;p<_peds.size();p++){
-		delete _peds[p];
-	}
-	_peds.clear();
+const vector<int>& SubRoom::GetAllGoalIDs() const {
+	return _goalIDs;
 }
 
 
-#endif
-
 // Sonstiges
 
 void SubRoom::AddWall(const Wall& w) {
@@ -268,16 +186,11 @@ void SubRoom::AddWall(const Wall& w) {
 }
 
 
-int SubRoom::GetNumberOfGoalIDs() const {
-	return _goalIDs.size();
-}
-
-const vector<int>& SubRoom::GetAllGoalIDs() const {
-	return _goalIDs;
+void SubRoom::AddObstacle(Obstacle* obs){
+	_obstacles.push_back(obs);
 }
 
 
-
 void SubRoom::AddGoalID(int ID) {
 	_goalIDs.push_back(ID);
 }
@@ -506,12 +419,12 @@ const double* SubRoom::GetPlanEquation() const {
 	return _planeEquation;
 }
 
-
-
-
 double SubRoom::GetElevation(const Point& p) {
 	return _planeEquation[0] * p._x + _planeEquation[1] * p._y + _planeEquation[2];
 }
+
+
+
 /************************************************************
  NormalSubRoom
  ************************************************************/
@@ -902,3 +815,70 @@ bool Stair::IsInSubRoom(const Point& ped) const {
 	return rueck;
 }
 
+
+#ifdef _SIMULATOR
+
+void SubRoom::SetAllPedestrians(const vector<Pedestrian*>& peds) {
+	_peds = peds;
+}
+
+void SubRoom::SetPedestrian(Pedestrian* ped, int index) {
+	if ((index >= 0) && (index < GetNumberOfPedestrians())) {
+		_peds[index] = ped;
+	} else {
+		Log->Write("ERROR: Wrong Index in SubRoom::SetPedestrian()");
+		exit(0);
+	}
+}
+
+bool SubRoom::IsInSubRoom(Pedestrian* ped) const {
+	Point pos = ped->GetPos();
+	if (ped->GetExitLine()->DistTo(pos) <= J_EPS_GOAL)
+		return true;
+	else
+		return IsInSubRoom(pos);
+}
+
+
+int SubRoom::GetNumberOfPedestrians() const {
+	return _peds.size();
+}
+
+const vector<Pedestrian*>& SubRoom::GetAllPedestrians() const {
+	return _peds;
+}
+
+
+Pedestrian* SubRoom::GetPedestrian(int index) const {
+	if ((index >= 0) && (index < (int) GetNumberOfPedestrians()))
+		return _peds[index];
+	else {
+		Log->Write("ERROR: Wrong 'index' in SubRoom::GetPedestrian()");
+		exit(0);
+	}
+}
+
+
+void SubRoom::AddPedestrian(Pedestrian* ped) {
+	_peds.push_back(ped);
+}
+
+
+void SubRoom::DeletePedestrian(int index) {
+	if ((index >= 0) && (index < (int) GetNumberOfPedestrians())) {
+		_peds.erase(_peds.begin() + index);
+
+	} else {
+		Log->Write("ERROR: Wrong Index in SubRoom::DeletePedestrian()");
+		exit(0);
+	}
+}
+
+void SubRoom::ClearAllPedestrians(){
+	for(unsigned int p=0;p<_peds.size();p++){
+		delete _peds[p];
+	}
+	_peds.clear();
+}
+
+#endif // _SIMULATOR
diff --git a/tinyxml/tinystr.cpp b/tinyxml/tinystr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..066576820516de3bae97b08f9258468f9cc136f4
--- /dev/null
+++ b/tinyxml/tinystr.cpp
@@ -0,0 +1,111 @@
+/*
+www.sourceforge.net/projects/tinyxml
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
+
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
diff --git a/tinyxml/tinystr.h b/tinyxml/tinystr.h
new file mode 100644
index 0000000000000000000000000000000000000000..89cca3341564c0337e3e940bfa4ae053e84e656c
--- /dev/null
+++ b/tinyxml/tinystr.h
@@ -0,0 +1,305 @@
+/*
+www.sourceforge.net/projects/tinyxml
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*	The support for explicit isn't that universal, and it isn't really
+	required - it is used to check that the TiXmlString class isn't incorrectly
+	used. Be nice to old compilers and macro it here:
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+	// Microsoft visual studio, version 6 and higher.
+	#define TIXML_EXPLICIT explicit
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+	// GCC version 3 and higher.s
+	#define TIXML_EXPLICIT explicit
+#else
+	#define TIXML_EXPLICIT
+#endif
+
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef size_t size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString ( const TiXmlString & copy) : rep_(0)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
diff --git a/tinyxml/tinyxml.cpp b/tinyxml/tinyxml.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c161dfcb934e855ff679998c34669bfdd66aa21
--- /dev/null
+++ b/tinyxml/tinyxml.cpp
@@ -0,0 +1,1886 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#include <iostream>
+#endif
+
+#include "tinyxml.h"
+
+FILE* TiXmlFOpen( const char* filename, const char* mode );
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+// Microsoft compiler security
+FILE* TiXmlFOpen( const char* filename, const char* mode )
+{
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		FILE* fp = 0;
+		errno_t err = fopen_s( &fp, filename, mode );
+		if ( !err && fp )
+			return fp;
+		return 0;
+	#else
+		return fopen( filename, mode );
+	#endif
+}
+
+void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+	target->location = location;
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
+	if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		delete node;
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
+	{
+		if ( GetDocument() ) 
+			GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( !replaceThis )
+		return 0;
+
+	if ( replaceThis->parent != this )
+		return 0;
+
+	if ( withThis.ToDocument() ) {
+		// A document can never be a child.	Thanks to Noam.
+		TiXmlDocument* document = GetDocument();
+		if ( document ) 
+			document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( !removeThis ) {
+		return false;
+	}
+
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
+	#else
+	TiXmlAttribute* node = attributeSet.Find( name );
+	#endif
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+	return *this;
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char* TiXmlElement::Attribute( const char* name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return node->Value();
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( attrib )
+		return &attrib->ValueStr();
+	return 0;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( i ) {
+			attrib->QueryIntValue( i );
+		}
+	}
+	return result;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const char* result = 0;
+
+	if ( attrib ) {
+		result = attrib->Value();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	const std::string* result = 0;
+
+	if ( attrib ) {
+		result = &attrib->ValueStr();
+		if ( d ) {
+			attrib->QueryDoubleValue( d );
+		}
+	}
+	return result;
+}
+#endif
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+
+
+int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	int ival = 0;
+	int result = node->QueryIntValue( &ival );
+	*value = (unsigned)ival;
+	return result;
+}
+
+
+int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	
+	int result = TIXML_WRONG_TYPE;
+	if (    StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN ) 
+		 || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN ) 
+		 || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) ) 
+	{
+		*bval = true;
+		result = TIXML_SUCCESS;
+	}
+	else if (    StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN ) 
+			  || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN ) 
+			  || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) ) 
+	{
+		*bval = false;
+		result = TIXML_SUCCESS;
+	}
+	return result;
+}
+
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryIntValue( ival );
+}
+#endif
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
+{
+	const TiXmlAttribute* attrib = attributeSet.Find( name );
+	if ( !attrib )
+		return TIXML_NO_ATTRIBUTE;
+	return attrib->QueryDoubleValue( dval );
+}
+#endif
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetIntValue( val );
+	}
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
+{	
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
+	if ( attrib ) {
+		attrib->SetDoubleValue( val );
+	}
+}
+#endif 
+
+
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
+	if ( attrib ) {
+		attrib->SetValue( cvalue );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
+{
+	TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
+	if ( attrib ) {
+		attrib->SetValue( _value );
+	}
+}
+#endif
+
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	assert( cfile );
+	for ( i=0; i<depth; i++ ) {
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+	return *this;
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	return LoadFile( Value(), encoding );
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	return SaveFile( Value() );
+}
+
+bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
+{
+	TIXML_STRING filename( _filename );
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = TiXmlFOpen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		bool result = LoadFile( file, encoding );
+		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
+
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file ) 
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length <= 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external 
+	// parsed entities (including the document entity) on input, before parsing, by translating 
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		delete [] buf;
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Process the buffer in place to normalize new lines. (See comment above.)
+	// Copies from the 'p' to 'q' pointer, where p can advance faster if
+	// a newline-carriage return is hit.
+	//
+	// Wikipedia:
+	// Systems based on ASCII or a compatible character set use either LF  (Line feed, '\n', 0x0A, 10 in decimal) or 
+	// CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
+	//		* LF:    Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
+    //		* CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
+    //		* CR:    Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
+
+	const char* p = buf;	// the read head
+	char* q = buf;			// the write head
+	const char CR = 0x0d;
+	const char LF = 0x0a;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		assert( q <= (buf+length) );
+		assert( q <= p );
+
+		if ( *p == CR ) {
+			*q++ = LF;
+			p++;
+			if ( *p == LF ) {		// check for CR+LF (and skip LF)
+				p++;
+			}
+		}
+		else {
+			*q++ = *p++;
+		}
+	}
+	assert( q <= (buf+length) );
+	*q = 0;
+
+	Parse( buf, 0, encoding );
+
+	delete [] buf;
+	return !Error();
+}
+
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = TiXmlFOpen( filename, "w" );
+	if ( fp )
+	{
+		bool result = SaveFile( fp );
+		fclose( fp );
+		return result;
+	}
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM ) 
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return (ferror(fp) == 0);
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorId = errorId;
+	target->errorDesc = errorDesc;
+	target->tabsize = tabsize;
+	target->errorLocation = errorLocation;
+	target->useMicrosoftBOM = useMicrosoftBOM;
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+
+bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+*/
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+*/
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	TIXML_STRING n, v;
+
+	EncodeString( name, &n );
+	EncodeString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos) {
+		if ( cfile ) {
+			fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
+		}
+	}
+	else {
+		if ( cfile ) {
+			fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
+		}
+	}
+}
+
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
+	#else
+		sprintf (buf, "%g", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+	return *this;
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( int i=0; i<depth; i++ )
+	{
+		fprintf( cfile,  "    " );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		EncodeString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+	return *this;
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml " );
+	if ( str )	 (*str) += "<?xml ";
+
+	if ( !version.empty() ) {
+		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
+		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
+	}
+	if ( !encoding.empty() ) {
+		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
+	}
+	if ( !standalone.empty() ) {
+		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf( cfile, "?>" );
+	if ( str )	 (*str) += "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+    #ifdef TIXML_USE_STL
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
+	#else
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	#endif
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+#endif
+
+
+TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
+{
+	TiXmlAttribute* attrib = Find( _name );
+	if ( !attrib ) {
+		attrib = new TiXmlAttribute();
+		Add( attrib );
+		attrib->SetName( _name );
+	}
+	return attrib;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::istream& operator>> (std::istream & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+#ifdef TIXML_USE_STL	
+std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out << printer.Str();
+
+	return out;
+}
+
+
+std::string& operator<< (std::string& out, const TiXmlNode& base )
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out.append( printer.Str() );
+
+	return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += element.Value();
+
+	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
+	{
+		buffer += " ";
+		attrib->Print( 0, 0, &buffer );
+	}
+
+	if ( !element.FirstChild() ) 
+	{
+		buffer += " />";
+		DoLineBreak();
+	}
+	else 
+	{
+		buffer += ">";
+		if (    element.FirstChild()->ToText()
+			  && element.LastChild() == element.FirstChild()
+			  && element.FirstChild()->ToText()->CDATA() == false )
+		{
+			simpleTextPrint = true;
+			// no DoLineBreak()!
+		}
+		else
+		{
+			DoLineBreak();
+		}
+	}
+	++depth;	
+	return true;
+}
+
+
+bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
+{
+	--depth;
+	if ( !element.FirstChild() ) 
+	{
+		// nothing.
+	}
+	else 
+	{
+		if ( simpleTextPrint )
+		{
+			simpleTextPrint = false;
+		}
+		else
+		{
+			DoIndent();
+		}
+		buffer += "</";
+		buffer += element.Value();
+		buffer += ">";
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlText& text )
+{
+	if ( text.CDATA() )
+	{
+		DoIndent();
+		buffer += "<![CDATA[";
+		buffer += text.Value();
+		buffer += "]]>";
+		DoLineBreak();
+	}
+	else if ( simpleTextPrint )
+	{
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+	}
+	else
+	{
+		DoIndent();
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
+{
+	DoIndent();
+	declaration.Print( 0, 0, &buffer );
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlComment& comment )
+{
+	DoIndent();
+	buffer += "<!--";
+	buffer += comment.Value();
+	buffer += "-->";
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += unknown.Value();
+	buffer += ">";
+	DoLineBreak();
+	return true;
+}
+
diff --git a/tinyxml/tinyxml.h b/tinyxml/tinyxml.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3f08d658abb934b968d4ff57c97b7686b3ef207
--- /dev/null
+++ b/tinyxml/tinyxml.h
@@ -0,0 +1,1807 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#define TIXML_USE_STL
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#include <sstream>
+	#define TIXML_STRING		std::string
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING		TiXmlString
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
+
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		// Microsoft visual studio, version 2005 and higher.
+		#define TIXML_SNPRINTF _snprintf_s
+		#define TIXML_SSCANF   sscanf_s
+	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SSCANF   sscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SSCANF   sscanf
+	#else
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SSCANF   sscanf
+	#endif
+#endif	
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 6;
+const int TIXML_PATCH_VERSION = 2;
+
+/*	Internal structure for tracking location of items 
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+/**
+	Implements the interface to the "Visitor pattern" (see the Accept() method.)
+	If you call the Accept() method, it requires being passed a TiXmlVisitor
+	class to handle callbacks. For nodes that contain other nodes (Document, Element)
+	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+	are simply called with Visit().
+
+	If you return 'true' from a Visit method, recursive parsing will continue. If you return
+	false, <b>no children of this node or its sibilings</b> will be Visited.
+
+	All flavors of Visit methods have a default implementation that returns 'true' (continue 
+	visiting). You need to only override methods that are interesting to you.
+
+	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+	You should never change the document from a callback.
+
+	@sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+	virtual ~TiXmlVisitor() {}
+
+	/// Visit a document.
+	virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )			{ return true; }
+	/// Visit a document.
+	virtual bool VisitExit( const TiXmlDocument& /*doc*/ )			{ return true; }
+
+	/// Visit an element.
+	virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )	{ return true; }
+	/// Visit an element.
+	virtual bool VisitExit( const TiXmlElement& /*element*/ )		{ return true; }
+
+	/// Visit a declaration
+	virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )	{ return true; }
+	/// Visit a text node
+	virtual bool Visit( const TiXmlText& /*text*/ )					{ return true; }
+	/// Visit a comment node
+	virtual bool Visit( const TiXmlComment& /*comment*/ )			{ return true; }
+	/// Visit an unknown node
+	virtual bool Visit( const TiXmlUnknown& /*unknown*/ )			{ return true; }
+};
+
+// Only used by Attribute::Query functions
+enum 
+{ 
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0)		{}
+	virtual ~TiXmlBase()			{}
+
+	/**	All TinyXml classes can print themselves to a filestream
+		or the string class (TiXmlString in non-STL mode, std::string
+		in STL mode.) Either or both cfile and str can be null.
+		
+		This is a formatted print, and will insert 
+		tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		value is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
+	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
+	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p, 
+								TiXmlParsingData* data, 
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
+		or they will be transformed into entities!
+	*/
+	static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+		TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+
+	inline static bool IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+	inline static bool IsWhiteSpace( int c )
+	{
+		if ( c < 256 )
+			return IsWhiteSpace( (char) c );
+		return false;	// Again, only truly correct for English/Latin...but usually works.
+	}
+
+	#ifdef TIXML_USE_STL
+	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((const unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+	
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */	
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		TINYXML_DOCUMENT,
+		TINYXML_ELEMENT,
+		TINYXML_COMMENT,
+		TINYXML_UNKNOWN,
+		TINYXML_TEXT,
+		TINYXML_DECLARATION,
+		TINYXML_TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	const TIXML_STRING& ValueTStr() const { return value; }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const		{ return firstChild; }	///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()						{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	/// The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * _value ) {
+		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+		// call the method, cast the return back to non-const.
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+	}
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * _value ) {
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+	}
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char *_prev ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char* _next ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char *_next ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+	}
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * _value ) const;
+	TiXmlElement* FirstChildElement( const char * _value ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
+								TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument() {
+		return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+	}
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller. 
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
+		XML tree will be conditionally visited and the host will be called back
+		via the TiXmlVisitor interface.
+
+		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+		interface versus any other.)
+
+		The interface has been based on ideas from:
+
+		- http://www.saxproject.org/
+		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
+
+		Which are both good references for "visiting".
+
+		An example of using Accept():
+		@verbatim
+		TiXmlPrinter printer;
+		tinyxmlDoc.Accept( &printer );
+		const char* xmlcstr = printer.CStr();
+		@endverbatim
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
+	#ifdef TIXML_USE_STL
+	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
+	#endif
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	// Get the tinyxml string representation
+	const TIXML_STRING& NameTStr() const { return name; }
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	{ name = _name; }	
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
+	}
+
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
+	}
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	TiXmlAttribute*	Find( const char* _name ) const;
+	TiXmlAttribute* FindOrCreate( const char* _name );
+
+#	ifdef TIXML_USE_STL
+	TiXmlAttribute*	Find( const std::string& _name ) const;
+	TiXmlAttribute* FindOrCreate( const std::string& _name );
+#	endif
+
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	TiXmlElement& operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/	
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
+	int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
+	/** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). 
+		Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
+		and 'no' are considered false.
+	*/
+	int QueryBoolAttribute( const char* name, bool* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+    #ifdef TIXML_USE_STL
+	/// QueryStringAttribute examines the attribute - see QueryIntAttribute().
+	int QueryStringAttribute( const char* name, std::string* _value ) const {
+		const char* cstr = Attribute( name );
+		if ( cstr ) {
+			*_value = std::string( cstr );
+			return TIXML_SUCCESS;
+		}
+		return TIXML_NO_ATTRIBUTE;
+	}
+
+	/** Template form of the attribute query which will try to read the
+		attribute into the specified type. Very easy, very powerful, but
+		be careful to make sure to call this with the correct type.
+		
+		NOTE: This method doesn't work correctly for 'string' types that contain spaces.
+
+		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+	*/
+	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+
+		std::stringstream sstream( node->ValueStr() );
+		sstream >> *outValue;
+		if ( !sstream.fail() )
+			return TIXML_SUCCESS;
+		return TIXML_WRONG_TYPE;
+	}
+
+	int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+		*outValue = node->ValueStr();
+		return TIXML_SUCCESS;
+	}
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const std::string* Attribute( const std::string& name ) const;
+	const std::string* Attribute( const std::string& name, int* i ) const;
+	const std::string* Attribute( const std::string& name, double* d ) const;
+	int QueryIntAttribute( const std::string& name, int* _value ) const;
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value );
+	///< STL std::string form.
+	void SetDoubleAttribute( const std::string& name, double value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+	
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text". 
+		
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo> 
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo> 
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the 
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
+	/// Construct a comment from text.
+	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
+		SetValue( _value );
+	}
+	TiXmlComment( const TiXmlComment& );
+	TiXmlComment& operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlComment*  ToComment() const	{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual		  TiXmlComment*  ToComment()		{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output 
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with 
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as 
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )	{ copy.CopyTo( this ); }
+	TiXmlText& operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); return *this; }
+
+	// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA() const				{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )		{ copy.CopyTo( this ); }
+	TiXmlUnknown& operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); return *this; }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlUnknown*     ToUnknown()     const	{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()				{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	TiXmlDocument& operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+	/** Load a file using the given FILE*. Returns true if successful. Note that this method
+		doesn't stream - the entire object pointed at by the FILE*
+		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+		file location. Streaming may be added in the future.
+	*/
+	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given FILE*. Returns true if successful.
+	bool SaveFile( FILE* ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		return LoadFile( filename.c_str(), encoding );
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		return SaveFile( filename.c_str() );
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/	
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1, 
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow() const	{ return errorLocation.row+1; }
+	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+		
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false; 
+												errorId = 0; 
+												errorDesc = ""; 
+												errorLocation.row = errorLocation.col = 0; 
+												//errorLocation.last = 0; 
+											}
+
+	/** Write the document to standard out using formatted printing ("pretty print"). */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/* Write the document to a string using formatted printing ("pretty print"). This
+		will allocate a character array (new char[]) and return it as a pointer. The
+		calling code pust call delete[] on the return char* to avoid a memory leak.
+	*/
+	//char* PrintToMemory() const; 
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children. 
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0; 
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
+	a linear walk to find the element, so this code would iterate much more than it needs 
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/** Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* ToNode() const			{ return node; } 
+	/** Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/**	Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/** Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+	/** @deprecated use ToNode. 
+		Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* Node() const			{ return ToNode(); } 
+	/** @deprecated use ToElement. 
+		Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* Element() const	{ return ToElement(); }
+	/**	@deprecated use ToText()
+		Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* Text() const			{ return ToText(); }
+	/** @deprecated use ToUnknown()
+		Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
+
+private:
+	TiXmlNode* node;
+};
+
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+	-# Print to memory (especially in non-STL mode)
+	-# Control formatting (line endings, etc.)
+
+	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+	Before calling Accept() you can call methods to control the printing
+	of the XML document. After TiXmlNode::Accept() is called, the printed document can
+	be accessed via the CStr(), Str(), and Size() methods.
+
+	TiXmlPrinter uses the Visitor API.
+	@verbatim
+	TiXmlPrinter printer;
+	printer.SetIndent( "\t" );
+
+	doc.Accept( &printer );
+	fprintf( stdout, "%s", printer.CStr() );
+	@endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
+
+	virtual bool VisitEnter( const TiXmlDocument& doc );
+	virtual bool VisitExit( const TiXmlDocument& doc );
+
+	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+	virtual bool VisitExit( const TiXmlElement& element );
+
+	virtual bool Visit( const TiXmlDeclaration& declaration );
+	virtual bool Visit( const TiXmlText& text );
+	virtual bool Visit( const TiXmlComment& comment );
+	virtual bool Visit( const TiXmlUnknown& unknown );
+
+	/** Set the indent characters for printing. By default 4 spaces
+		but tab (\t) is also useful, or null/empty string for no indentation.
+	*/
+	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
+	/// Query the indention string.
+	const char* Indent()							{ return indent.c_str(); }
+	/** Set the line breaking string. By default set to newline (\n). 
+		Some operating systems prefer other characters, or can be
+		set to the null/empty string for no indenation.
+	*/
+	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
+	/// Query the current line breaking string.
+	const char* LineBreak()							{ return lineBreak.c_str(); }
+
+	/** Switch over to "stream printing" which is the most dense formatting without 
+		linebreaks. Common when the XML is needed for network transmission.
+	*/
+	void SetStreamPrinting()						{ indent = "";
+													  lineBreak = "";
+													}	
+	/// Return the result.
+	const char* CStr()								{ return buffer.c_str(); }
+	/// Return the length of the result string.
+	size_t Size()									{ return buffer.size(); }
+
+	#ifdef TIXML_USE_STL
+	/// Return the result.
+	const std::string& Str()						{ return buffer; }
+	#endif
+
+private:
+	void DoIndent()	{
+		for( int i=0; i<depth; ++i )
+			buffer += indent;
+	}
+	void DoLineBreak() {
+		buffer += lineBreak;
+	}
+
+	int depth;
+	bool simpleTextPrint;
+	TIXML_STRING buffer;
+	TIXML_STRING indent;
+	TIXML_STRING lineBreak;
+};
+
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
diff --git a/tinyxml/tinyxmlerror.cpp b/tinyxml/tinyxmlerror.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..538c21d0bd95fb114e70636bc1a776937975a912
--- /dev/null
+++ b/tinyxml/tinyxmlerror.cpp
@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
+};
diff --git a/tinyxml/tinyxmlparser.cpp b/tinyxml/tinyxmlparser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a7e0137264ed4da6c19a6e75f34477c9761e8f3d
--- /dev/null
+++ b/tinyxml/tinyxmlparser.cpp
@@ -0,0 +1,1639 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code by Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include <ctype.h>
+#include <stddef.h>
+#include <assert.h>
+
+#include "tinyxml.h"
+
+//#define DEBUG_PARSER
+#if defined( DEBUG_PARSER )
+#	if defined( DEBUG ) && defined( _MSC_VER )
+#		include <windows.h>
+#		define TIXML_LOG OutputDebugString
+#	else
+#		define TIXML_LOG printf
+#	endif
+#endif
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor() const	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
+// "assign" optimization removes over 10% of the execution time.
+//
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	// Oddly, not supported on some comilers,
+	//name->clear();
+	// So use this:
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		const char* start = p;
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			//(*name) += *p; // expensive
+			++p;
+		}
+		if ( p-start > 0 ) {
+			name->assign( start, p-start );
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
+					// Just writes strange XML.
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	if ( p && *p )
+		p += strlen( endTag );
+	return ( p && *p ) ? p : 0;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		cdata text (which looks like another node)
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				// Early out if we find the CDATA id.
+				if ( c == '[' && tag->size() >= 9 )
+				{
+					size_t len = tag->size();
+					const char* start = tag->c_str() + len - 9;
+					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
+						assert( !closingTag );
+						break;
+					}
+				}
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p ) {
+				// We were looking for the end tag, but found nothing.
+				// Fix for [ 1663758 ] Failure to report error on bad XML
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+
+			// We should find the end tag now
+			// note that:
+			// </foo > and
+			// </foo> 
+			// are both valid end tags.
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				p = SkipWhiteSpace( p, encoding );
+				if ( p && *p && *p == '>' ) {
+					++p;
+					return p;
+				}
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			#ifdef TIXML_USE_STL
+			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
+			#else
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			#endif
+			if ( node )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+			    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	
+			document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( p && *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		if ( document )
+			document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+
+	// [ 1475201 ] TinyXML parses entities in comments
+	// Oops - ReadText doesn't work, because we don't want to parse the entities.
+	// p = ReadText( p, &value, false, endTag, false, encoding );
+	//
+	// from the XML spec:
+	/*
+	 [Definition: Comments may appear anywhere in a document outside other markup; in addition, 
+	              they may appear within the document type declaration at places allowed by the grammar. 
+				  They are not part of the document's character data; an XML processor MAY, but need not, 
+				  make it possible for an application to retrieve the text of comments. For compatibility, 
+				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity 
+				  references MUST NOT be recognized within comments.
+
+				  An example of a comment:
+
+				  <!-- declarations for <head> & <body> -->
+	*/
+
+    value = "";
+	// Keep all the white space.
+	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
+	{
+		value.append( p, 1 );
+		++p;
+	}
+	if ( p && *p ) 
+		p += strlen( endTag );
+
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+	const char SINGLE_QUOTE = '\'';
+	const char DOUBLE_QUOTE = '\"';
+
+	if ( *p == SINGLE_QUOTE )
+	{
+		++p;
+		end = "\'";		// single quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == DOUBLE_QUOTE )
+	{
+		++p;
+		end = "\"";		// double quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p											// existence
+				&& !IsWhiteSpace( *p )								// whitespace
+				&& *p != '/' && *p != '>' )							// tag end
+		{
+			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
+				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
+				// We did not have an opening quote but seem to have a 
+				// closing one. Give up and throw an error.
+				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+				return 0;
+			}
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();	
+		if ( !cdata && (c == '<' ) ) 
+		{
+			return;
+		}
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+		in->get();	// "commits" the peek made above
+
+		if ( cdata && c == '>' && tag->size() >= 3 ) {
+			size_t len = tag->size();
+			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
+				// terminator of cdata.
+				return;
+			}
+		}    
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			if ( document )
+				document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p && *p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+