Index: branches/powerups/src/lib/Makefile.am
===================================================================
--- branches/powerups/src/lib/Makefile.am	(revision 5871)
+++ branches/powerups/src/lib/Makefile.am	(revision 5955)
@@ -15,5 +15,6 @@
 			    network/libORXnet.a \
                             graphics/spatial_separation/libORXquadtree.a \
-                            tinyxml/libtinyxml.a \
+                            parser/tinyxml/libtinyxml.a \
+                            parser/ini_parser/libIniParser.a \
                             shell/libORXshell.a
 
@@ -29,5 +30,4 @@
 			    network/libORXnet.a \
                             graphics/spatial_separation/libORXquadtree.a \
-                            tinyxml/libtinyxml.a \
                             shell/libORXshell.a \
                             $(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
@@ -37,5 +37,4 @@
                         lang/base_object.cc \
                         lang/class_list.cc \
-                        util/ini_parser.cc \
                         util/substring.cc \
                         util/color.cc \
@@ -53,5 +52,4 @@
                         graphics/render2D/render_2d.h \
                         lang/class_list.h \
-                        util/ini_parser.h \
                         util/substring.h \
                         util/array.h \
@@ -75,5 +73,5 @@
           collision_detection \
 	  network \
-          tinyxml \
+          parser \
           shell \
           gui \
Index: branches/powerups/src/lib/collision_detection/cd_engine.cc
===================================================================
--- branches/powerups/src/lib/collision_detection/cd_engine.cc	(revision 5871)
+++ branches/powerups/src/lib/collision_detection/cd_engine.cc	(revision 5955)
@@ -24,5 +24,5 @@
 #include "world_entity.h"
 #include "terrain.h"
-#include "player.h"
+// #include "player.h"
 
 #include "spatial_separation.h"
@@ -119,5 +119,5 @@
     Quadtree* q = this->terrain->ssp->getQuadtree();
 
-    QuadtreeNode* n = q->getQuadtreeFromPosition(this->player->getAbsCoor());
+//    QuadtreeNode* n = q->getQuadtreeFromPosition(this->player->getAbsCoor());
   }
   //sTriangleExt* tri = q->getTriangleFromPosition(this->player->getAbsCoor());
Index: branches/powerups/src/lib/collision_detection/cd_engine.h
===================================================================
--- branches/powerups/src/lib/collision_detection/cd_engine.h	(revision 5871)
+++ branches/powerups/src/lib/collision_detection/cd_engine.h	(revision 5955)
@@ -17,5 +17,5 @@
 class OBBTree;
 class Terrain;
-class Player;
+//class Player;
 
 
@@ -51,5 +51,5 @@
   inline void setEntityList(tList<WorldEntity>* entityList) { this->entityList = entityList; }
   inline void setTerrain(Terrain* terrain) { this->terrain = terrain; }
-  inline void setPlayer(Player* player) { this->player = player; } /* only for debug purposes \todo: delete*/
+  //  inline void setPlayer(Player* player) { this->player = player; } /* only for debug purposes \todo: delete*/
 
   void drawBV(int depth, int drawMode) const;
@@ -79,5 +79,5 @@
 
   Terrain*                terrain;                          //!< this it a ref to the terrain, serving as a ground for all WE
-  Player*                 player;
+//  Player*                 player;
 };
 
Index: branches/powerups/src/lib/coord/p_node.cc
===================================================================
--- branches/powerups/src/lib/coord/p_node.cc	(revision 5871)
+++ branches/powerups/src/lib/coord/p_node.cc	(revision 5955)
@@ -428,4 +428,5 @@
 
   this->bias = bias;
+  this->bRelDirChanged = true;
 }
 
@@ -836,4 +837,5 @@
         glEnd();
       }
+
       /* if we want to draw the children too */
       if (depth == 0) /* -> all of them */
Index: branches/powerups/src/lib/coord/p_node.h
===================================================================
--- branches/powerups/src/lib/coord/p_node.h	(revision 5871)
+++ branches/powerups/src/lib/coord/p_node.h	(revision 5955)
@@ -76,5 +76,5 @@
   inline const Vector& getRelCoor () const { return this->prevRelCoordinate; };
   /** @returns the Relative Coordinate Destination */
-  inline const Vector& getRelCoorSoft2D() const { return (this->toCoordinate)?*this->toCoordinate:this->relCoordinate; };
+  inline const Vector& getRelCoorSoft2D() const { return (this->toCoordinate)? *this->toCoordinate : this->relCoordinate; };
   void setAbsCoor (const Vector& absCoord);
   void setAbsCoor (float x, float y, float z);
@@ -93,5 +93,5 @@
   inline const Quaternion& getRelDir () const { return this->prevRelDirection; };
   /** @returns the Relative Directional Destination */
-  inline const Quaternion& getRelDirSoft2D() const { return (this->toDirection)?*this->toDirection:this->relDirection; };
+  inline const Quaternion& getRelDirSoft2D() const { return (this->toDirection)? *this->toDirection : this->relDirection; };
   /** @returns a Vector pointing into the relative Direction */
   inline Vector getRelDirV() const { return this->prevRelDirection.apply(Vector(0,1,0)); };
@@ -100,9 +100,15 @@
   void setAbsDirSoft(const Quaternion& absDirSoft, float bias = 1.0);
   void setAbsDirSoft(float x, float y, float z, float bias = 1.0);
+  void shiftDir (const Quaternion& shift);
   /** @returns the absolute Direction */
   inline const Quaternion& getAbsDir () const { return this->absDirection; };
   /** @returns a Vector pointing into the absolute Direction */
   inline Vector getAbsDirV() const { return this->absDirection.apply(Vector(0,1,0)); };
-  void shiftDir (const Quaternion& shift);
+  /** @returns A Vector pointing into the forward direction (X) of the Node */
+  inline Vector getAbsDirX() const { return this->absDirection.apply(Vector(1,0,0)); };
+  /** @returns A Vector pointing into the upward direction (Y) of the Node */
+  inline Vector getAbsDirY() const { return this->absDirection.apply(Vector(0,1,0)); };
+  /** @returns A Vector pointing into the right direction (Z) of the Node */
+  inline Vector getAbsDirZ() const { return this->absDirection.apply(Vector(0,0,1)); };
 
   /** @returns the Speed of the Node */
Index: branches/powerups/src/lib/event/key_mapper.cc
===================================================================
--- branches/powerups/src/lib/event/key_mapper.cc	(revision 5871)
+++ branches/powerups/src/lib/event/key_mapper.cc	(revision 5955)
@@ -21,8 +21,11 @@
 #include "key_mapper.h"
 
+#include "event_def.h"
+
 #include "globals.h"
-#include "ini_parser.h"
+#include "parser/ini_parser/ini_parser.h"
 #include "key_names.h"
 #include "debug.h"
+
 
 using namespace std;
@@ -129,5 +132,5 @@
   int* index;
 
-  iniParser->getFirstVar();
+  iniParser->firstVar();
   while(iniParser->getCurrentName())
   {
@@ -148,5 +151,5 @@
   }
 
-  iniParser->getFirstVar();
+  iniParser->firstVar();
   while(iniParser->getCurrentName())
   {
@@ -191,14 +194,14 @@
       {
         if( index[0] == 0)
-	{
+        {
           *map[i].pValue = index[1];
           PRINTF(4)("Mapping %s to '%s' (id %i)\n", name, SDLKToKeyname(index[1]), index[1]);
           break;
-	}
-	else { 
+        }
+        else {
           *map[i].pValue = index[1];
           PRINTF(4)("Mapping %s to '%s' (id %i)\n", name, SDLBToButtonname(index[1]), index[1]);
           break;
-	}
+        }
       }
     }
Index: branches/powerups/src/lib/event/key_mapper.h
===================================================================
--- branches/powerups/src/lib/event/key_mapper.h	(revision 5871)
+++ branches/powerups/src/lib/event/key_mapper.h	(revision 5955)
@@ -10,5 +10,5 @@
 
 #include "base_object.h"
-#include "event_def.h"
+//#include "event_def.h"
 
 class IniParser;
@@ -66,5 +66,5 @@
 
  private:
-  Sint32     coord[2];              //!< temp place to save variables in nameToIndex() function
+  int         coord[2];              //!< temp place to save variables in nameToIndex() function
 };
 
Index: branches/powerups/src/lib/graphics/graphics_engine.cc
===================================================================
--- branches/powerups/src/lib/graphics/graphics_engine.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/graphics_engine.cc	(revision 5955)
@@ -26,13 +26,13 @@
 #include "debug.h"
 
-#include "ini_parser.h"
+#include "parser/ini_parser/ini_parser.h"
 #include "substring.h"
 #include "text.h"
 
 #include "globals.h"
+#include "texture.h"
 
 #ifdef __WIN32__
  #include "class_list.h"
- #include "texture.h"
  #include "list.h"
  #include "model.h"
@@ -131,7 +131,7 @@
   const char* textures = iniParser->getVar(CONFIG_NAME_TEXTURES, CONFIG_SECTION_VIDEO_ADVANCED, "0");
   if (strchr(textures, '1') || !strcasecmp(textures, "true"))
-    this->texturesEnabled = true;
+    Texture::setTextureEnableState( true);
   else
-    this->texturesEnabled = false;
+    Texture::setTextureEnableState(false);
 
   // searching for a usefull resolution
@@ -365,9 +365,4 @@
 
 /**
- * if Textures should be enabled
-*/
-bool GraphicsEngine::texturesEnabled = true;
-
-/**
  *
  * @param show if The mouse-cursor should be visible
Index: branches/powerups/src/lib/graphics/graphics_engine.h
===================================================================
--- branches/powerups/src/lib/graphics/graphics_engine.h	(revision 5871)
+++ branches/powerups/src/lib/graphics/graphics_engine.h	(revision 5955)
@@ -83,6 +83,4 @@
 
   public:
-    static bool             texturesEnabled;    //!< if textures should be enabled (globally)
-
 
   private:
Index: branches/powerups/src/lib/graphics/importer/Makefile.am
===================================================================
--- branches/powerups/src/lib/graphics/importer/Makefile.am	(revision 5871)
+++ branches/powerups/src/lib/graphics/importer/Makefile.am	(revision 5955)
@@ -9,5 +9,6 @@
                            md2Model.cc \
                            material.cc \
-                           texture.cc
+                           texture.cc \
+                           texture_sequence.cc
 
 
@@ -20,4 +21,5 @@
                  material.h \
                  texture.h \
+                 texture_sequence.h \
                  anorms.h \
                  anormtab.h
Index: branches/powerups/src/lib/graphics/importer/material.h
===================================================================
--- branches/powerups/src/lib/graphics/importer/material.h	(revision 5871)
+++ branches/powerups/src/lib/graphics/importer/material.h	(revision 5955)
@@ -51,15 +51,15 @@
   static void addTexturePath(const char* pathName);
 
- private:
-  int         illumModel;       //!< The IlluminationModel is either flat or smooth.
-  float       diffuse [4];      //!< The diffuse color of the Material.
-  float       ambient [4];      //!< The ambient color of the Material.
-  float       specular [4];     //!< The specular color of the Material.
-  float       shininess;        //!< The shininess of the Material.
-  float       transparency;     //!< The transperency of the Material.
+  private:
+    int         illumModel;       //!< The IlluminationModel is either flat or smooth.
+    float       diffuse [4];      //!< The diffuse color of the Material.
+    float       ambient [4];      //!< The ambient color of the Material.
+    float       specular [4];     //!< The specular color of the Material.
+    float       shininess;        //!< The shininess of the Material.
+    float       transparency;     //!< The transperency of the Material.
   public:
-  Texture*    diffuseTexture;   //!< The diffuse texture of the Material.
-  Texture*    ambientTexture;   //!< The ambient texture of the Material.
-  Texture*    specularTexture;  //!< The specular texture of the Material.
+    Texture*    diffuseTexture;   //!< The diffuse texture of the Material.
+    Texture*    ambientTexture;   //!< The ambient texture of the Material.
+    Texture*    specularTexture;  //!< The specular texture of the Material.
 };
 #endif
Index: branches/powerups/src/lib/graphics/importer/texture.cc
===================================================================
--- branches/powerups/src/lib/graphics/importer/texture.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/importer/texture.cc	(revision 5955)
@@ -19,6 +19,6 @@
 
 #include "debug.h"
-#include "graphics_engine.h"
-
+
+// INCLUDING SDL_Image
 #ifdef HAVE_SDL_IMAGE_H
 #include <SDL_image.h>
@@ -45,4 +45,5 @@
 }
 
+
 /**
  *  Destructor of a Texture
@@ -65,5 +66,5 @@
 bool Texture::loadImage(const char* imageName)
 {
-  if (GraphicsEngine::texturesEnabled)
+  if (Texture::texturesEnabled)
     {
       if (this->image != NULL)
@@ -80,5 +81,5 @@
         {
           SDL_Surface* tmpSurf;
-          if (this->texture)
+          if (this->texture != 0 && glIsTexture(this->texture))
             glDeleteTextures(1, &this->texture);
           // load the new Image to memory
@@ -87,6 +88,13 @@
           {
             PRINTF(4)("loading Image %s\n", imageName);
-            if (this->prepareSurface(tmpSurf))
-              loadTexToGL();
+            bool hasAlpha;
+            SDL_Surface* newSurf = this->prepareSurface(tmpSurf, hasAlpha);
+            if (newSurf != NULL)
+            {
+              this->setSurface(newSurf);
+              this->setAlpha(hasAlpha);
+              this->setTexture(Texture::loadTexToGL(newSurf));
+            }
+
             SDL_FreeSurface(tmpSurf);
             return true;
@@ -108,10 +116,16 @@
 }
 
+
+/**
+ * rebuilds the texture.
+ * reloads the Texture from Memory to OpenGL.
+ */
 bool Texture::rebuild()
 {
   if (this->texture != 0)
     {
-      glDeleteTextures(1,&this->texture);
-      this->texture = 0;
+      if (glIsTexture(this->texture))
+        glDeleteTextures(1,&this->texture);
+      this->setTexture(0);
     }
 
@@ -119,26 +133,61 @@
     {
       PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
-      this->loadTexToGL();
+      this->setTexture(loadTexToGL(this->image));
     }
-
-}
-
+}
+
+
+/**
+ * set the surface this Texture handles
+ * @param newSurface the new Surface to set as the image for this Texture.
+ *
+ * This deletes the old version of the stored Texture,
+ * and sets the newly given Surface as current.
+ */
+bool Texture::setSurface(SDL_Surface* newSurface)
+{
+  if (this->image != NULL)
+    SDL_FreeSurface(this->image);
+
+  this->image = newSurface;
+
+  return (this->image != NULL);
+}
+
+
+bool Texture::texturesEnabled = true;
+
+/**
+ * enables, disables textures
+ * @param texturesEnabled true if the textures should be enabled
+ */
+void Texture::setTextureEnableState(bool texturesEnabled)
+{
+  Texture::texturesEnabled = texturesEnabled;
+}
+
+
+//////////////////////////////////////
+// UTILITY FUNCTIONALITY OF TEXTURE //
+//////////////////////////////////////
 /**
  * converts surface to a new SDL_Surface, that is loadable by openGL
  * @param surface the Surface to convert
+ * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
  * @returns a !!new!! Surface, that is loadable by openGL.
  */
-bool Texture::prepareSurface(SDL_Surface* surface)
+SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
 {
   PRINTF(4)("Loading texture to OpenGL-Environment.\n");
 
-  SDL_Surface* putSurface;
+  SDL_Surface* retSurface;
   SDL_Rect area;
   Uint32 saved_flags;
   Uint8  saved_alpha;
 
-  putSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
-                               surface->w, surface->h,
-                               32,
+  hasAlpha = false;
+  retSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                    surface->w, surface->h,
+                                    32,
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
                                0x000000FF,
@@ -147,14 +196,13 @@
                                0xFF000000
 #else
-                               0xFF000000,
+                                   0xFF000000,
                                0x00FF0000,
                                0x0000FF00,
                                0x000000FF
 #endif
-                               );
-  if ( putSurface == NULL )
+                                   );
+  if ( retSurface == NULL )
   {
-    this->setSurface(NULL);
-    return false;
+    return NULL;
   }
 
@@ -171,5 +219,5 @@
   area.w = surface->w;
   area.h = surface->h;
-  SDL_BlitSurface(surface, &area, putSurface, &area);
+  SDL_BlitSurface(surface, &area, retSurface, &area);
 
   /* Restore the alpha blending attributes */
@@ -177,18 +225,8 @@
   {
     SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
-    this->bAlpha = true;
-  }
-
-  return (this->setSurface(putSurface));
-}
-
-bool Texture::setSurface(SDL_Surface* newSurface)
-{
-  if (this->image != NULL)
-    SDL_FreeSurface(this->image);
-
-  this->image = newSurface;
-
-  return (this->image != NULL);
+    hasAlpha = true;
+  }
+
+  return (retSurface);
 }
 
@@ -199,16 +237,18 @@
  * @returns The ID of the texture.
  */
-GLuint Texture::loadTexToGL ()
-{
-  if (this->texture != 0 && glIsTexture(this->texture))
-    glDeleteTextures(1, &this->texture);
-  this->texture = 0;
-
-  if (this->image == NULL)
+GLuint Texture::loadTexToGL (const SDL_Surface* surface)
+{
+//   if (this->texture != 0 && glIsTexture(this->texture))
+//     glDeleteTextures(1, &this->texture);
+//   this->texture = 0;
+
+  GLuint texture;
+
+  if (surface == NULL)
     return 0;
 
   /* Create an OpenGL texture for the image */
-  glGenTextures(1, &this->texture);
-  glBindTexture(GL_TEXTURE_2D, this->texture);
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -217,18 +257,18 @@
                0,
                GL_RGBA,
-               this->image->w, this->image->h,
+               surface->w, surface->h,
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
-               this->image->pixels);
+               surface->pixels);
   // build the MipMaps
   gluBuild2DMipmaps(GL_TEXTURE_2D,
                     GL_RGBA,
-                    this->image->w,
-                    this->image->h,
+                    surface->w,
+                    surface->h,
                     GL_RGBA,
                     GL_UNSIGNED_BYTE,
-                    this->image->pixels);
+                    surface->pixels);
   glBindTexture(GL_TEXTURE_2D, 0);
-  return this->texture;
-}
+  return texture;
+}
Index: branches/powerups/src/lib/graphics/importer/texture.h
===================================================================
--- branches/powerups/src/lib/graphics/importer/texture.h	(revision 5871)
+++ branches/powerups/src/lib/graphics/importer/texture.h	(revision 5955)
@@ -14,8 +14,4 @@
 struct SDL_Surface;
 
-//! an enumerator for different procedural texture-types
-typedef enum TEXTURE_TYPE { TEXTURE_RADIAL_ALIAS,
-  TEXTURE_NOISE };
-
 //! A Class, that reads in Textures from different fileformats.
   class Texture : public BaseObject
@@ -27,5 +23,5 @@
 
       bool loadImage(const char* imageName);
-      bool rebuild();
+      virtual bool rebuild();
 
       /** @returns The textureID of this texture.  */
@@ -33,15 +29,30 @@
       /** @returns true if texture has alpha, false otherwise */
       inline bool hasAlpha() const {return bAlpha;}
+      /** @returns the stored image of this Texture */
+      const SDL_Surface* const getStoredImage() const { return this->image; };
+
+
+
+      static void setTextureEnableState(bool texturesEnabled);
+      /** @returns true if Textures are enabled */
+      inline static bool getTextureEnableState() { return Texture::texturesEnabled; };
+
+      // Utility functionality:
+      static SDL_Surface* prepareSurface(SDL_Surface* input, bool& hasAlpha);
+      static GLuint loadTexToGL (const SDL_Surface* surface);
 
     protected:
-      bool prepareSurface(SDL_Surface* input);
+
       bool setSurface(SDL_Surface* newSurface);
+      bool setAlpha(bool hasAlpha) { this->bAlpha = hasAlpha; };
+      bool setTexture(GLuint texture) { this->texture = texture; };
 
-      GLuint loadTexToGL ();
 
     private:
-      GLuint        texture;            //!< The Texture-ID of opengl from this Texture.
-      bool          bAlpha;             //!< if the texture has an alpha channel.
-      SDL_Surface*  image;              //!< The SDL_Surfce that stores the Texture on it.
+      GLuint           texture;            //!< The Texture-ID of opengl from this Texture.
+      bool             bAlpha;             //!< if the texture has an alpha channel.
+      SDL_Surface*     image;              //!< The SDL_Surfce that stores the Texture on it.
+
+      static bool      texturesEnabled;    //!< If the Textures are enabled.
   };
 
Index: branches/powerups/src/lib/graphics/importer/texture_sequence.cc
===================================================================
--- branches/powerups/src/lib/graphics/importer/texture_sequence.cc	(revision 5955)
+++ branches/powerups/src/lib/graphics/importer/texture_sequence.cc	(revision 5955)
@@ -0,0 +1,164 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program 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 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture_sequence.h"
+
+#include "debug.h"
+#include "graphics_engine.h"
+
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+/**
+ *  Constructor for a Texture
+ */
+TextureSequence::TextureSequence(unsigned int count, ...)
+{
+  this->setClassID(CL_TEXTURE_SEQUENCE, "TextureSequence");
+
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  this->loadImageSeries(count, textureNameList);
+}
+
+/**
+ * Destructor of a TextureSequence
+ *
+ * Frees Data, and deletes the textures from GL
+ */
+TextureSequence::~TextureSequence()
+{
+  // delete all images
+  while(!this->images.empty())
+  {
+    SDL_FreeSurface(this->images.back());
+    this->images.pop_back();
+  }
+
+  this->setTexture(0);
+  // delete all textures.
+  while(!this->textures.empty())
+  {
+    if (glIsTexture(this->textures.back()))
+      glDeleteTextures(1, &this->textures.back());
+    this->textures.pop_back();
+  }
+}
+
+
+/**
+ * @brief rebuilds all the textures from the Images stored in this FrameSequence
+ */
+bool TextureSequence::rebuild()
+{
+  PRINTF(3)("Reloading TextureSequence of %s '%s'\n", this->getClassName(), this->getName());
+
+  for (unsigned int i = 0; i < this->textures.size(); i++)
+  {
+    if (glIsTexture(this->textures[i]))
+    {
+      glDeleteTextures(1, &this->textures[i]);
+      this->textures[i] = 0;
+    }
+
+    if (this->images[i] != NULL)
+      this->textures[i] = loadTexToGL(this->images[i]);
+  }
+}
+
+/**
+ * @brief loads an image Sequence
+ * @param count how many images to load to the TextureSequence
+ * @param ... the names of the Images to load
+ * @returns true on success, false otherwise
+ */
+bool TextureSequence::loadImageSeries(unsigned int count, ...)
+{
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  return this->loadImageSeries(count, textureNameList);
+}
+
+/**
+ * @brief loads an image Sequence
+ * @param count how many images to load to the TextureSequence
+ * @param textures the names of the Images to load
+ * @returns true on success, false otherwise
+ */
+bool TextureSequence::loadImageSeries(unsigned int count, va_list textures)
+{
+  bool retVal = true;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if( !this->addFrame(va_arg(textures, char*)))
+      retVal = false;
+  }
+  return retVal;
+}
+
+/**
+ * @brief adds a new Frame to this Sequence (at the end)
+ * @param imageName the Name of the Image to add
+ * @returns true on success
+ */
+bool TextureSequence::addFrame(const char* imageName)
+{
+  if (imageName == NULL)
+    return false;
+
+  SDL_Surface* addSurface = IMG_Load(imageName);
+  bool success = this->addFrame(addSurface);
+  delete addSurface;
+
+  return success;
+}
+
+/**
+ * @brief adds a new Frame at the end of the Sequence.
+ * @param surface the Surface to add at the end of the Sequence.
+ */
+bool TextureSequence::addFrame(SDL_Surface* surface)
+{
+  if (surface == NULL)
+    return false;
+  bool hasAlpha;
+  SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->images.push_back(newSurf);
+    this->textures.push_back(Texture::loadTexToGL(newSurf));
+  }
+  this->setAlpha(hasAlpha);
+  return true;
+}
+
+
+
+/**
+ * @brief moves to the n'th texture which can then be retrieved via the Texture function: this->getTexture()
+ * @param frameNumber the n-th frame
+ */
+void TextureSequence::gotoFrame(unsigned int frameNumber)
+{
+  if (this->textures.size() > frameNumber)
+    this->setTexture(this->textures[frameNumber]);
+}
Index: branches/powerups/src/lib/graphics/importer/texture_sequence.h
===================================================================
--- branches/powerups/src/lib/graphics/importer/texture_sequence.h	(revision 5955)
+++ branches/powerups/src/lib/graphics/importer/texture_sequence.h	(revision 5955)
@@ -0,0 +1,48 @@
+/*!
+ * @file texture.h
+ * @brief Contains the texture class, that handles the reading of Images into Texutre-files.
+ */
+
+#ifndef _TEXTURE_SEQUENCE_H
+#define _TEXTURE_SEQUENCE_H
+
+#include "texture.h"
+
+#include "glincl.h"
+
+#include <vector>
+#include <stdarg.h>
+
+/* Forward Declaration */
+struct SDL_Surface;
+
+//! A Class, that reads in Textures from different fileformats.
+class TextureSequence : public Texture
+{
+  public:
+    TextureSequence(unsigned int count = 0, ...);
+  //  Texture(TEXTURE_TYPE type, int resolution);
+    ~TextureSequence();
+
+    bool loadImageSeries(unsigned int count, ...);
+    bool loadImageSeries(unsigned int count, va_list textureNames);
+    bool addFrame(const char* image);
+    bool addFrame(SDL_Surface* surface);
+
+    virtual bool rebuild();
+
+    /** @returns the count of frames in this sequence */
+    inline unsigned int getFrameCount() const { return this->textures.size(); };
+
+    void gotoFrame(unsigned int frameNumber);
+    /** @returns The textureID of the Frame @param frameNumber the n-th frame this texture-series.  */
+    inline GLuint getFrameTexture(unsigned int frameNumber) const { return (this->textures.size()>frameNumber)?this->textures[frameNumber]:0; };
+    /** @returns The SDL_Surface of the image at Frame @param frameNumber the n-th frame of this image-seriers */
+    const SDL_Surface* const getFrameImage(unsigned int frameNumber) const { return (this->images.size()>frameNumber)?this->images[frameNumber]:NULL; };
+
+  private:
+    std::vector<GLuint>          textures;            //!< The Texture-ID of opengl from this Texture.
+    std::vector<SDL_Surface*>    images;              //!< The SDL_Surfce that stores the Texture on it.
+};
+
+#endif /* _TEXTURE_SEQUENCE_H */
Index: branches/powerups/src/lib/graphics/light.cc
===================================================================
--- branches/powerups/src/lib/graphics/light.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/light.cc	(revision 5955)
@@ -22,5 +22,5 @@
 #include "glincl.h"
 #include "vector.h"
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 #include "load_param.h"
 #include "factory.h"
Index: branches/powerups/src/lib/graphics/render2D/element_2d.cc
===================================================================
--- branches/powerups/src/lib/graphics/render2D/element_2d.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/render2D/element_2d.cc	(revision 5955)
@@ -23,5 +23,5 @@
 #include "graphics_engine.h"
 #include "load_param.h"
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 #include "class_list.h"
 
Index: branches/powerups/src/lib/graphics/text_engine/font.cc
===================================================================
--- branches/powerups/src/lib/graphics/text_engine/font.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/text_engine/font.cc	(revision 5955)
@@ -181,6 +181,12 @@
     this->fontTTF = NULL;
   }
-  if (this->prepareSurface(surface))
-    this->loadTexToGL( );
+  bool hasAlpha;
+  SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->setSurface(newSurf);
+    this->setAlpha(hasAlpha);
+    this->setTexture(Texture::loadTexToGL(newSurf));
+  }
 
   // initializing the Glyphs.
@@ -491,5 +497,5 @@
 
   if (this->setSurface(tmpSurf))
-    loadTexToGL();
+    (this->setTexture(Texture::loadTexToGL(tmpSurf)));
 }
 
Index: branches/powerups/src/lib/graphics/text_engine/text_engine.cc
===================================================================
--- branches/powerups/src/lib/graphics/text_engine/text_engine.cc	(revision 5871)
+++ branches/powerups/src/lib/graphics/text_engine/text_engine.cc	(revision 5955)
@@ -64,5 +64,5 @@
 {
   // first remove all the remaining Texts (if any).
-  std::list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
+  const std::list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
   if (textList != NULL)
   {
@@ -71,5 +71,5 @@
   }
   // delete all remaining fonts (There should not be Anything to do here)
-  std::list<BaseObject*>* fontList = ClassList::getList(CL_FONT);
+  const std::list<BaseObject*>* fontList = ClassList::getList(CL_FONT);
   if (fontList != NULL)
   {
@@ -124,5 +124,5 @@
 void TextEngine::debug() const
 {
-  list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
+  const list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
   if (textList != NULL)
   {
@@ -132,5 +132,5 @@
     PRINT(0)("Reference: %p; Text Counts: %d\n", this, textList->size());
 
-    list<BaseObject*>::iterator text;
+    list<BaseObject*>::const_iterator text;
     for ( text = textList->begin(); text != textList->end(); text++)
       dynamic_cast<Text*>(*text)->debug();
Index: branches/powerups/src/lib/gui/gtk_gui/gui_audio.cc
===================================================================
--- branches/powerups/src/lib/gui/gtk_gui/gui_audio.cc	(revision 5871)
+++ branches/powerups/src/lib/gui/gtk_gui/gui_audio.cc	(revision 5955)
@@ -42,4 +42,5 @@
     {
       CheckButton* enableSound; //!< A Ckeckbutton for enabling Sound.
+      Slider* audioChannels;    //!< A Slider for the count of audio-channels.
       Slider* musicVolume;      //!< A Slider for music volume.
       Slider* effectsVolume;    //!< A Slider for effects volume.
@@ -51,4 +52,14 @@
       enableSound->saveability();
       audioBox->fill(enableSound);
+
+      Label* audioChannelsLabel = new Label(CONFIG_NAME_AUDIO_CHANNELS);
+      audioBox->fill(audioChannelsLabel);
+      audioChannels = new Slider(CONFIG_NAME_AUDIO_CHANNELS, 0, 32);
+      audioChannels->setFlagName("channels", "c", 32);
+      audioChannels->setDescription("Sets the count of channels in the game");
+      audioChannels->saveability();
+      audioBox->fill (audioChannels);
+
+
       Label* musicVolumeLabel = new Label(CONFIG_NAME_MUSIC_VOLUME);
       audioBox->fill(musicVolumeLabel);
@@ -58,4 +69,5 @@
       musicVolume->saveability();
       audioBox->fill (musicVolume);
+
       Label* effectsVolumeLabel = new Label (CONFIG_NAME_EFFECTS_VOLUME);
       audioBox->fill (effectsVolumeLabel);
Index: branches/powerups/src/lib/gui/gtk_gui/gui_exec.cc
===================================================================
--- branches/powerups/src/lib/gui/gtk_gui/gui_exec.cc	(revision 5871)
+++ branches/powerups/src/lib/gui/gtk_gui/gui_exec.cc	(revision 5955)
@@ -27,5 +27,5 @@
 
 #include "resource_manager.h"
-#include "ini_parser.h"
+#include "parser/ini_parser/ini_parser.h"
 
 #include <string.h>
@@ -254,5 +254,5 @@
 
 /**
- *  Reads in Configuration Data.
+ * @brief Reads in Configuration Data.
  * @param widget from which Widget on should be saved.
 */
@@ -265,5 +265,5 @@
     return;
 
-  iniParser.getFirstSection();
+  iniParser.firstSection();
   Widget* groupWidget = widget;
   const char* groupName;
@@ -272,17 +272,20 @@
   while (groupName = iniParser.getCurrentSection())
   {
+    printf("GROUP:::%s\n", groupName);
     if((groupWidget = locateGroup(widget, groupName, 1))==NULL)
-    {
-      PRINTF(2)("!!There is no group called %s in this GUI.\n First best Widget will get the Infos assigned.\n Config-File will be updated in next Save\n", groupName);
-      groupWidget = widget;
-      continue;
-    }
+      {
+	PRINTF(2)("!!There is no group called %s in this GUI.\n First best Widget will get the Infos assigned.\n Config-File will be updated in next Save\n", groupName);
+	groupWidget = widget;
+	continue;
+      }
     else
-      PRINT(0)("Group %s located.\n", static_cast<Packer*>(groupWidget)->groupName);
-
-    iniParser.getFirstVar();
-    while(iniParser.getCurrentName())
-    {
-      varInfo.variableName = iniParser.getCurrentName();
+      PRINT(4)("Group %s located.\n", static_cast<Packer*>(groupWidget)->groupName);
+
+    const char* entryName;
+    iniParser.firstVar();
+    while(entryName = iniParser.getCurrentName())
+    {
+      PRINTF(4)("ENTRY:::%s = %s\n", entryName, iniParser.getCurrentValue());
+      varInfo.variableName = entryName;
       varInfo.variableValue = iniParser.getCurrentValue();
       groupWidget->walkThrough(this->readFileText, &varInfo, 0);
@@ -303,9 +306,13 @@
 {
   VarInfo* info =(VarInfo*)varInfo;
+  if (info == NULL || info->variableName == NULL)
+    return;
+
   if(widget->title && !strcmp(widget->title, info->variableName))
     {
       PRINT(5)("Located Option %s.\n", widget->title);
       if(widget->optionType > GUI_NOTHING)
-        static_cast<Option*>(widget)->load(info->variableValue);
+	if (info->variableValue != NULL)
+	  static_cast<Option*>(widget)->load(info->variableValue);
     }
 }
@@ -323,15 +330,16 @@
 {
   Widget* tmp;
+  if (widget  == NULL || groupName == NULL)
+    return NULL;
 
   if(widget->optionType < GUI_NOTHING)
     {
-      if(static_cast<Packer*>(widget)->getGroupName() &&
+      if(static_cast<Packer*>(widget)->getGroupName() != NULL &&
          !strcmp(groupName, static_cast<Packer*>(widget)->getGroupName()))
-        {
-          return widget;
-        }
+	return widget;
       else
         {
-          if((tmp = locateGroup(static_cast<Packer*>(widget)->down, groupName, depth+1)) != NULL)
+          if((tmp = locateGroup(static_cast<Packer*>(widget)->down,
+				groupName, depth+1)) != NULL)
             return tmp;
         }
Index: branches/powerups/src/lib/gui/gtk_gui/gui_keys.cc
===================================================================
--- branches/powerups/src/lib/gui/gtk_gui/gui_keys.cc	(revision 5871)
+++ branches/powerups/src/lib/gui/gtk_gui/gui_keys.cc	(revision 5955)
@@ -119,5 +119,5 @@
         pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_LEFT, "LEFT"));
         pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_RIGHT, "RIGHT"));
-        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_FIRE, "MOUSE_LEFT"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_FIRE, "BUTTON_LEFT"));
         pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_NEXT_WEAPON, "m"));
         pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_PREV_WEAPON, "n"));
Index: branches/powerups/src/lib/lang/base_object.cc
===================================================================
--- branches/powerups/src/lib/lang/base_object.cc	(revision 5871)
+++ branches/powerups/src/lib/lang/base_object.cc	(revision 5955)
@@ -112,6 +112,6 @@
   else if (classID & CL_MASK_SUBSUPER_CLASS)
   {
-    if (likely(((this->classID & CL_MASK_SUBSUPER_CLASS_ID) == (this->classID & CL_MASK_SUBSUPER_CLASS_ID)) &&
-        this->classID & classID & CL_MASK_SUBSUPER_CLASS_ID2))
+    if (likely(((this->classID & CL_MASK_SUBSUPER_CLASS_IDA) == (this->classID & CL_MASK_SUBSUPER_CLASS_IDA)) &&
+        this->classID & classID & CL_MASK_SUBSUPER_CLASS_IDB))
       return true;
   }
Index: branches/powerups/src/lib/lang/class_list.cc
===================================================================
--- branches/powerups/src/lib/lang/class_list.cc	(revision 5871)
+++ branches/powerups/src/lib/lang/class_list.cc	(revision 5955)
@@ -133,5 +133,5 @@
  * @return the List accessed by classID, or NULL if not found
  */
-std::list<BaseObject*>* ClassList::getList(ClassID classID)
+const std::list<BaseObject*>* ClassList::getList(ClassID classID)
 {
   ClassList* fl;
@@ -156,5 +156,5 @@
  * @return the List accessed by classID, or NULL if not found
  */
-std::list<BaseObject*>* ClassList::getList(const char* className)
+const std::list<BaseObject*>* ClassList::getList(const char* className)
 {
   ClassList* fl;
Index: branches/powerups/src/lib/lang/class_list.h
===================================================================
--- branches/powerups/src/lib/lang/class_list.h	(revision 5871)
+++ branches/powerups/src/lib/lang/class_list.h	(revision 5955)
@@ -40,9 +40,11 @@
     static void                           removeFromClassList(BaseObject* objectPointer);
 
-    static std::list<BaseObject*>*        getList(ClassID classID = CL_NULL);// { return (ClassList* fl = ClassList::getClassList(classID) != NULL)? &(fl->objectList) : NULL; };
-    static std::list<BaseObject*>*        getList(const char* className); // { return (ClassList* fl = ClassList::getClassList(className) != NULL)? &(fl->objectList) : NULL;  };
+    static const std::list<BaseObject*>*  getList(ClassID classID = CL_NULL);// { return (ClassList* fl = ClassList::getClassList(classID) != NULL)? &(fl->objectList) : NULL; };
+    static const std::list<BaseObject*>*  getList(const char* className); // { return (ClassList* fl = ClassList::getClassList(className) != NULL)? &(fl->objectList) : NULL;  };
     static const std::list<const char*>*  getClassNames();
     static BaseObject*                    getObject(const char* name, ClassID classID = CL_NULL);
     static bool                           exists(const BaseObject* object, ClassID classID = CL_NULL);
+
+    void                                  sendBack(std::list<BaseObject*>::const_iterator it);
 
     static void                           whatIs(const BaseObject* object);
@@ -51,5 +53,5 @@
     static long                           StringToID(const char* className);
     static void                           debug(unsigned int debugLevel = 0, long classID = CL_NULL);
-    static void                           debugS(const char* className = 0x0, unsigned int debugLevel = 0);
+    static void                           debugS(const char* className = NULL, unsigned int debugLevel = 0);
 
     inline bool                           operator==(ClassID classID) { return (this->classID == classID); };
Index: branches/powerups/src/lib/network/network_manager.cc
===================================================================
--- branches/powerups/src/lib/network/network_manager.cc	(revision 5871)
+++ branches/powerups/src/lib/network/network_manager.cc	(revision 5955)
@@ -161,5 +161,5 @@
   if (this->netStreamList != NULL || (this->netStreamList = ClassList::getList(CL_NETWORK_STREAM)) != NULL)
   {
-    std::list<BaseObject*>::iterator stream;
+    std::list<BaseObject*>::const_iterator stream;
     for (stream = this->netStreamList->begin(); stream != this->netStreamList->end(); ++stream)
       static_cast<NetworkStream*>(*stream)->processData();
Index: branches/powerups/src/lib/network/network_manager.h
===================================================================
--- branches/powerups/src/lib/network/network_manager.h	(revision 5871)
+++ branches/powerups/src/lib/network/network_manager.h	(revision 5955)
@@ -41,6 +41,6 @@
 
 private:
-  std::list<BaseObject*>*    netStreamList;            // list with refs to all network streams
-  std::list<BaseObject*>*    syncList;                 // list of synchronizeables
+  const std::list<BaseObject*>*    netStreamList;            // list with refs to all network streams
+  const std::list<BaseObject*>*    syncList;                 // list of synchronizeables
 
 };
Index: branches/powerups/src/lib/parser/Makefile.am
===================================================================
--- branches/powerups/src/lib/parser/Makefile.am	(revision 5955)
+++ branches/powerups/src/lib/parser/Makefile.am	(revision 5955)
@@ -0,0 +1,5 @@
+SUBDIRS = \
+          tinyxml \
+	  ini_parser
+
+
Index: branches/powerups/src/lib/parser/ini_parser/Makefile.am
===================================================================
--- branches/powerups/src/lib/parser/ini_parser/Makefile.am	(revision 5955)
+++ branches/powerups/src/lib/parser/ini_parser/Makefile.am	(revision 5955)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libIniParser.a
+
+libIniParser_a_SOURCES = ini_parser.cc
+
+libIniParser_a_CPPFLAGS = "-DNO_SHELL"
+
+noinst_HEADERS = ini_parser.h
+
+
Index: branches/powerups/src/lib/parser/ini_parser/ini_parser.cc
===================================================================
--- branches/powerups/src/lib/parser/ini_parser/ini_parser.cc	(revision 5955)
+++ branches/powerups/src/lib/parser/ini_parser/ini_parser.cc	(revision 5955)
@@ -0,0 +1,771 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program 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 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Christian Meyer
+
+   2005-08-14: complete reimplementation:
+               now the File is parsed at the initialisation,
+               and informations is gathered there.
+*/
+
+
+#include "ini_parser.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef DEBUG
+ #include "../../../defs/debug.h"
+#else
+ #define PRINTF(x) printf
+#endif
+
+using namespace std;
+
+/**
+ * @brief constructs an IniParser using a file
+ * @param fileName: the path and name of the file to parse
+ */
+IniParser::IniParser (const char* fileName)
+{
+  this->fileName = NULL;
+  this->comment = NULL;
+
+  if (fileName != NULL)
+    this->readFile(fileName);
+}
+
+
+/**
+ * @brief removes the IniParser from memory
+ */
+IniParser::~IniParser ()
+{
+  this->deleteSections();
+  this->setFileName(NULL);
+}
+
+
+/**
+ * @brief removes all the sections. This is like delete, but even cooler :)
+ */
+void IniParser::deleteSections()
+{
+  // in all sections
+  while(!this->sections.empty())
+  {
+     IniSection section = this->sections.front();
+
+    // in all entries of the sections
+    while(!section.entries.empty())
+    {
+      // delete all strings of entries.
+      IniEntry entry = section.entries.front();
+      delete[] entry.name;
+      delete[] entry.value;
+      delete[] entry.comment;
+      section.entries.pop_front();
+    }
+    // delete all Sections
+    delete[] section.name;
+    delete[] section.comment;
+    this->sections.pop_front();
+  }
+  this->currentSection = this->sections.end();
+  this->setFileName(NULL);
+}
+
+
+/**
+ * @brief sets the Name of the input-file
+ * @param fileName The new FileName to set to the IniParser
+ * If fileName is NULL the new Name will be set to NULL too.
+ */
+void IniParser::setFileName(const char* fileName)
+{
+  if (this->fileName != NULL)
+    delete[] this->fileName;
+  if  (this->comment != NULL)
+    delete[] this->comment;
+  this->comment = NULL;
+
+  if (fileName != NULL)
+  {
+    this->fileName = new char[strlen(fileName)+1];
+    strcpy(this->fileName, fileName);
+  }
+  else
+    this->fileName = NULL;
+}
+
+
+/**
+ * @brief opens a file to parse
+ * @param fileName: path and name of the new file to parse
+ * @return true on success false otherwise;
+ *
+ * If there was already an opened file, the file will be closed,
+ * and the new one will be opened.
+ */
+bool IniParser::readFile(const char* fileName)
+{
+  FILE*    stream;           //< The stream we use to read the file.
+  int      lineCount = 0;    //< The Count of lines.
+
+  if (this->fileName != NULL)
+    this->deleteSections();
+  if( fileName == NULL)
+    return false;
+
+  if( (stream = fopen (fileName, "r")) == NULL)
+  {
+    PRINTF(1)("IniParser could not open %s\n", fileName);
+    return false;
+  }
+  else
+  {
+    this->setFileName(fileName);
+
+    /////////////////////////////
+    // READING IN THE INI-FILE //
+    /////////////////////////////
+    char lineBuffer[PARSELINELENGHT];
+    char buffer[PARSELINELENGHT];
+    const char* lineBegin;
+    char* ptr;
+
+    while( fgets (lineBuffer, PARSELINELENGHT, stream))
+    {
+      lineBegin = lineBuffer;
+      // remove newline char, and \0-terminate
+      if( (ptr = strchr( lineBuffer, '\n')) != NULL)
+        *ptr = 0;
+      // cut up to the beginning of the line.
+      while((*lineBegin == ' ' || *lineBegin == '\t') && lineBegin < lineBuffer + strlen(lineBuffer))
+        ++lineBegin;
+
+      // check if we have a FileComment
+      if ( (*lineBegin == '#' || *lineBegin == ';'))
+      {
+        char* newCommenLine = new char[strlen(lineBegin)+1];
+        strcpy(newCommenLine, lineBegin);
+        this->commentList.push_back(newCommenLine);
+        continue;
+      }
+      if (lineCount == 0 && !this->commentList.empty())
+      {
+        this->setFileComment();
+        lineCount++;
+      }
+
+      // check for section identifyer
+      else if( sscanf (lineBegin, "[%s", buffer) == 1)
+      {
+        if( (ptr = strchr( buffer, ']')) != NULL)
+        {
+          *ptr = 0;
+          this->addSection(buffer);
+          this->setSectionComment();
+        }
+      }
+      // check for Entry identifier (Entry = Value)
+      else if( (ptr = strchr( lineBegin, '=')) != NULL)
+      {
+        if (currentSection == NULL)
+        {
+          PRINTF(2)("Not in a Section yet for %s\n", lineBegin);
+          lineCount++;
+          continue;
+        }
+        if( ptr == lineBegin) {
+          lineCount++;
+          continue;
+        }
+        char* valueBegin = ptr+1;
+        while ((*valueBegin == ' ' || *valueBegin == '\t') && valueBegin <= lineBegin + strlen(lineBegin))
+          ++valueBegin;
+        char* valueEnd = valueBegin + strlen(valueBegin)-1;
+        while ((*valueEnd == ' ' || *valueEnd == '\t') && valueEnd >= valueBegin)
+          --valueEnd;
+        valueEnd[1] = '\0';
+        char* nameEnd = ptr-1;
+        while ((*nameEnd == ' ' || *nameEnd == '\t' ) && nameEnd >= lineBegin)
+          --nameEnd;
+        nameEnd[1] = '\0';
+
+        this->addVar(lineBegin, valueBegin);
+        this->setEntryComment();
+
+        lineCount++;
+      }
+    }
+  }
+  this->currentSection = this->sections.begin();
+  if (!this->sections.empty())
+    this->currentEntry = (*this->currentSection).entries.begin();
+
+  fclose(stream);
+  return true;
+}
+
+
+/**
+ * @brief opens a file and writes to it
+ * @param fileName: path and name of the new file to write to
+ * @return true on success false otherwise
+ */
+bool IniParser::writeFile(const char* fileName) const
+{
+  FILE*    stream;           //!< The stream we use to read the file.
+  if( fileName == NULL && (fileName = this->fileName) == NULL )
+    return false;
+
+  if( (stream = fopen (fileName, "w")) == NULL)
+  {
+    PRINTF(1)("IniParser could not open %s\n", fileName);
+    return false;
+  }
+  else
+  {
+    if (this->comment != NULL)
+      fprintf(stream, "%s\n\n", this->comment);
+
+    std::list<IniSection>::const_iterator section;
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      {
+        if ((*section).comment != NULL)
+          fprintf(stream, "%s", (*section).comment);
+        fprintf(stream, "\n [%s]\n", (*section).name);
+
+        std::list<IniEntry>::const_iterator entry;
+        for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+        {
+          if ((*entry).comment != NULL)
+            fprintf(stream, "%s", (*entry).comment);
+          fprintf(stream, "   %s = %s\n", (*entry).name, (*entry).value);
+         }
+      }
+  }
+  fclose(stream);
+}
+
+void IniParser::setFileComment(const char* fileComment)
+{
+  if (this->comment != NULL)
+    delete this->comment;
+
+  if (fileComment != NULL)
+  {
+    this->comment = new char[strlen(fileComment)+1];
+    strcpy(this->comment, fileComment);
+  }
+  else
+    this->comment = NULL;
+}
+
+
+/**
+ * @brief adds a section to the list of Sections,
+ * if no Section list is availiable, it will create it
+ * @param sectionName the Name of the section to add
+ * @return true on success... there is only success or segfault :)
+ */
+bool IniParser::addSection(const char* sectionName)
+{
+  if (sectionName == NULL)
+    return false;
+  this->sections.push_back(IniSection());
+  this->sections.back().comment = NULL;
+  this->sections.back().name = new char[strlen(sectionName)+1];
+  strcpy(this->sections.back().name, sectionName);
+
+  this->currentSection = --this->sections.end();
+  if (!this->sections.empty())
+      this->currentEntry = (*this->currentSection).entries.begin();
+  PRINTF(5)("Added Section %s\n", sectionName);
+  return true;
+}
+
+
+/**
+ * @brief Set the parsing cursor to the specified section
+ * @param sectionName: the name of the section to set the cursor to
+ * @return true on success or false if the section could not be found
+ */
+bool IniParser::getSection(const char* sectionName)
+{
+  this->currentSection = this->getSectionIT(sectionName);
+  if (this->currentSection != this->sections.end())
+  {
+    this->currentEntry = (*this->currentSection).entries.begin();
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ *
+ */
+void IniParser::setSectionComment(const char* comment, const char* sectionName)
+{
+  std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
+  if (section == this->sections.end())
+    return;
+
+  if ((*section).comment != NULL)
+    delete[] (*section).comment;
+  if (comment != NULL)
+  {
+    (*section).comment = new char[strlen (comment)+1];
+    strcpy((*section).comment, comment);
+  }
+  else
+    (*section).comment = NULL;
+}
+
+/**
+ * @param sectionName the Section to query for
+ * @returns the Comment, or NULL on error.
+ */
+const char* IniParser::getSectionComment(const char* sectionName) const
+{
+  std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
+  if (section != this->sections.end())
+    return (*section).comment;
+  else
+    return NULL;
+}
+
+
+/**
+ * @brief moves to the first section
+ */
+void IniParser::firstSection()
+{
+  this->currentSection = this->sections.begin();
+  if (!this->sections.empty())
+    this->currentEntry = (*this->currentSection).entries.begin();
+}
+
+
+/**
+ * @brief searches the next section
+ * @returns the name of the section if found, NULL otherwise
+ */
+const char* IniParser::nextSection()
+{
+  if (this->currentSection == this->sections.end())
+    return NULL;
+
+  this->currentSection++;
+
+  if (this->currentSection != this->sections.end())
+    {
+      this->currentEntry = (*this->currentSection).entries.begin();
+      return this->currentSection->name;
+    }
+  else
+    return NULL;
+}
+
+
+/**
+ * @brief adds a new Entry to either the currentSection or the section called by sectionName
+ * @param entryName the Name of the Entry to add
+ * @param value the value to assign to this entry
+ * @param sectionName if NULL then this entry will be set to the currentSection
+ * otherwise to the section refered to by sectionName.
+ * If both are NULL no entry will be added
+ * @return true if everything is ok false on error
+ */
+bool IniParser::addVar(const char* entryName, const char* value, const char* sectionName)
+{
+  std::list<IniSection>::iterator section;
+
+  if (sectionName != NULL)
+  {
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  }
+  else
+    section = this->currentSection;
+
+  if (section == this->sections.end())
+    return false;
+
+  if (section == this->sections.end())
+  {
+    PRINTF(2)("section '%s' not found for value '%s'\n", sectionName, entryName);
+    return false;
+  }
+  else
+  {
+    (*section).entries.push_back(IniEntry());
+    (*section).entries.back().comment = NULL;
+    (*section).entries.back().name = new char[strlen(entryName)+1];
+    strcpy((*section).entries.back().name, entryName);
+    (*section).entries.back().value = new char[strlen(value)+1];
+    strcpy((*section).entries.back().value, value);
+    PRINTF(5)("Added Entry %s with Value '%s' to Section %s\n",
+              (*section).entries.back().name,
+              (*section).entries.back().value,
+              (*section).name);
+    this->currentEntry = --(*section).entries.end();
+    return true;
+  }
+}
+
+
+/**
+ * @brief directly acesses an entry in a section
+ * @param entryName: the name of the entry to find
+ * @param sectionName: the section where the entry is to be found
+ * @param defaultValue: what should be returned in case the entry cannot be found
+ * @return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
+ *
+ *  The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
+ * lead to unwanted behaviour.
+*/
+const char* IniParser::getVar(const char* entryName, const char* sectionName, const char* defaultValue) const
+{
+  if (this->fileName != NULL)
+  {
+    std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
+    if (entry != NULL &&  !strcmp((*entry).name, entryName))
+      return (*entry).value;
+    PRINTF(2)("Entry '%s' in section '%s' not found.\n", entryName, sectionName);
+
+  }
+  else
+    PRINTF(2)("no File opened\n");
+
+  return defaultValue;
+
+}
+
+/**
+ * Set the Comment of a specified Entry.
+ * @param comment the Comment to set
+ * @param entryName the Name of the Entry
+ * @param sectionName the Name of the Section
+ */
+void IniParser::setEntryComment(const char* comment, const char* entryName, const char* sectionName)
+{
+  std::list<IniEntry>::iterator entry = this->getEntryIT(entryName, sectionName);
+
+  if ((*entry).comment != NULL)
+    delete[] (*entry).comment;
+  if (comment != NULL)
+  {
+    (*entry).comment = new char[strlen (comment)+1];
+    strcpy((*entry).comment, comment);
+  }
+  else
+    (*entry).comment = NULL;
+
+
+}
+
+/**
+ * @param entryName the Entry to query for
+ * @param sectionName the Section to Query for
+ * @returns the queried Comment.
+ */
+const char* IniParser::getEntryComment(const char* entryName, const char* sectionName) const
+{
+  std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
+
+  return (*entry).comment;
+}
+
+
+/**
+ * @brief moves to the first Variable of the current Section
+ */
+void IniParser::firstVar()
+{
+  if (!this->sections.empty() &&
+       this->currentSection != this->sections.end())
+    this->currentEntry = (*this->currentSection).entries.begin();
+}
+
+
+/**
+ * @brief gets the next VarName = VarValue pair from the parsing stream
+ * @return true on success, false otherwise (in the latter case name and value will be NULL)
+ */
+bool IniParser::nextVar()
+{
+  if ( this->sections.empty()
+       || this->currentSection == this->sections.end()
+       || this->currentEntry == (*this->currentSection).entries.end())
+    return false;
+
+  this->currentEntry++;
+
+  if (this->currentEntry == (*this->currentSection).entries.end())
+    return false;
+  else
+    return true;
+}
+
+
+
+/**
+ * @returns the name of the Current selected Section
+ */
+const char* IniParser::getCurrentSection() const
+{
+  if (!this->sections.empty() &&
+      this->currentSection != this->sections.end())
+    return this->currentSection->name;
+  else
+    return NULL;
+ }
+
+
+/**
+ * @returns the current entries Name, or NULL if we havn't selected a Entry
+ */
+const char* IniParser::getCurrentName() const
+{
+ if (!this->sections.empty() &&
+     this->currentSection != this->sections.end() &&
+     this->currentEntry != (*this->currentSection).entries.end())
+   return (*this->currentEntry).name;
+ else
+   return NULL;
+}
+
+/**
+ * @returns the current entries Value, or NULL if we havn't selected a Entry
+ */
+const char* IniParser::getCurrentValue() const
+{
+  if (!this->sections.empty() &&
+      this->currentSection != this->sections.end() &&
+      this->currentEntry != (*this->currentSection).entries.end())
+    return (*this->currentEntry).value;
+  else
+    return NULL;
+}
+
+
+/**
+ * Finds the Section Iterator of the Section Called sectionName
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniSection>::const_iterator IniParser::getSectionIT(const char* sectionName) const
+{
+  std::list<IniSection>::const_iterator section = this->currentSection;
+  if (sectionName == NULL)
+    return this->currentSection;
+  else
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  return section;
+}
+
+
+/**
+ * Finds the Section Iterator of the Section Called sectionName
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniSection>::iterator IniParser::getSectionIT(const char* sectionName)
+{
+  std::list<IniSection>::iterator section = this->currentSection;
+  if (sectionName == NULL)
+    return this->currentSection;
+  else
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  return section;
+}
+
+
+/**
+ * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
+ * @param entryName the Name of the Entry to get the Iterator from
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniEntry>::const_iterator IniParser::getEntryIT(const char* entryName, const char* sectionName) const
+{
+  if (entryName == NULL)
+    return this->currentEntry;
+  std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
+  std::list<IniEntry>::const_iterator entry = this->currentEntry;
+
+  if (section != this->sections.end())
+    for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      if (!strcmp((*entry).name, entryName))
+        break;
+  if (entry == (*section).entries.end())
+    return NULL;
+  else
+    return entry;
+}
+
+
+/**
+ * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
+ * @param entryName the Name of the Entry to get the Iterator from
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniEntry>::iterator IniParser::getEntryIT(const char* entryName, const char* sectionName)
+{
+  if (entryName == NULL)
+    return this->currentEntry;
+  std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
+  std::list<IniEntry>::iterator entry = this->currentEntry;
+
+  if (section != this->sections.end())
+    for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      if (!strcmp((*entry).name, entryName))
+        break;
+  if (entry == (*section).entries.end())
+    return NULL;
+  else
+    return entry;
+}
+
+
+/**
+ * takes lines together to form one FileComment, ereasing the commentList
+ */
+void IniParser::setFileComment()
+{
+  if (this->comment != NULL)
+    delete[] this->comment;
+
+  if (this->commentList.empty()) {
+    this->comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  this->comment = new char[stringLength];
+  this->comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*this->comment != '\0')
+      strcat(this->comment, "\n");
+    strcat(this->comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+}
+
+/**
+ * takes lines together to form one SectionComment, ereasing the commentList
+ */
+void IniParser::setSectionComment()
+{
+  if ((*this->currentSection).comment != NULL)
+    delete[] (*this->currentSection).comment;
+
+  if (this->commentList.empty()) {
+    (*this->currentSection).comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  (*this->currentSection).comment = new char[stringLength];
+  (*this->currentSection).comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*(*this->currentSection).comment != '\0')
+      strcat((*this->currentSection).comment, "\n");
+    strcat((*this->currentSection).comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+}
+
+/**
+ * takes lines together to form one EntryComment, ereasing the commentList
+ */
+void IniParser::setEntryComment()
+{
+  if ((*this->currentEntry).comment != NULL)
+    delete[] (*this->currentEntry).comment;
+
+  if (this->commentList.empty()) {
+    (*this->currentEntry).comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  (*this->currentEntry).comment = new char[stringLength];
+  (*this->currentEntry).comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*(*this->currentEntry).comment != '\0')
+      strcat((*this->currentEntry).comment, "\n");
+    strcat((*this->currentEntry).comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+
+}
+
+
+/**
+ * @brief output the whole tree in a nice and easy way.
+ */
+void IniParser::debug() const
+{
+  PRINTF(0)("Iniparser %s - debug\n", this->fileName);
+  if (this->comment != NULL)
+    PRINTF(0)("FileComment:\n %s\n\n", this->comment);
+
+  if (this->fileName != NULL)
+  {
+    std::list<IniSection>::const_iterator section;
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+    {
+      if ((*section).comment != NULL)
+        PRINTF(0)(" %s\n", (*section).comment);
+      PRINTF(0)(" [%s]\n", (*section).name);
+
+      std::list<IniEntry>::const_iterator entry;
+      for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      {
+        if ((*entry).comment != NULL)
+          PRINTF(0)(" %s\n", (*entry).comment);
+        PRINTF(0)("   '%s' -> '%s'\n", (*entry).name, (*entry).value);
+      }
+    }
+  }
+  else
+    PRINTF(1)("no opened ini-file.\n");
+}
+
Index: branches/powerups/src/lib/parser/ini_parser/ini_parser.h
===================================================================
--- branches/powerups/src/lib/parser/ini_parser/ini_parser.h	(revision 5955)
+++ branches/powerups/src/lib/parser/ini_parser/ini_parser.h	(revision 5955)
@@ -0,0 +1,112 @@
+/*!
+ * @file ini_parser.h
+ * A small ini file parser
+ *
+ * Can be used to find a defined [Section] in an ini file and get the VarName = Value entries
+ */
+
+#ifndef _INI_PARSER_H
+#define _INI_PARSER_H
+
+#define PARSELINELENGHT     512       //!< how many chars to read at once
+#ifndef NULL
+ #define NULL 0x0                     //!< NULL
+#endif
+
+#include <list>
+
+//! ini-file parser
+/**
+ * This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
+ */
+class IniParser
+{
+  private:
+    ////////////////////////////////////
+    //! a struct for Entries in the Parser's File's Sections
+    struct IniEntry
+    {
+      char*               comment;  //!< A Comment that is appendet to the Top of this Entry.
+      char*               name;     //!< name of a given Entry
+      char*               value;    //!< value of a given Entry
+    };
+
+    //! a struct for Sections in the Parser's file
+    struct IniSection
+    {
+      char*               comment;  //!< A Comment that is appendet to the Top of this Section.
+      char*               name;     //!< name of a given section
+      std::list<IniEntry> entries;  //!< a list of entries for this section
+    };
+    ////////////////////////////////////
+
+  public:
+    IniParser (const char* filename = NULL);
+    ~IniParser ();
+
+    /** @returns true if the file is opened, false otherwise*/
+    bool isOpen() const { return (this->fileName != NULL)? true : false; };
+    /** @returns the fileName we have opened. */
+    const char* getFileName() const { return this->fileName; };
+
+    bool readFile(const char* fileName);
+    bool writeFile(const char* fileName) const;
+
+    void setFileComment(const char* fileComment);
+    const char* getFileComment() const { return this->comment; };
+
+    bool addSection(const char* sectionName);
+    bool getSection(const char* sectionName);
+    void setSectionComment(const char* comment, const char* sectionName);
+    const char* getSectionComment(const char* sectionNane) const;
+
+    // iterate through sections with these Functions
+    void firstSection();
+    const char* nextSection();
+
+
+    bool addVar(const char* entryName, const char* value, const char* sectionName = NULL);
+    const char* getVar(const char* entryName, const char* sectionName, const char* defaultValue = "") const;
+    void setEntryComment(const char* comment, const char* entryName, const char* sectionName);
+    const char* getEntryComment(const char* entryName, const char* sectionName) const;
+
+    // iterate Through Variables with these Functions.
+    void firstVar();
+    bool nextVar();
+
+
+    // retrieving functions when iterating.
+    const char* getCurrentSection() const;
+    const char* getCurrentName() const;
+    const char* getCurrentValue() const;
+
+
+    // maintenance.
+    void debug() const;
+
+
+  private:
+    void deleteSections();
+    void setFileName(const char* fileName);
+
+    void setFileComment();
+    void setSectionComment();
+    void setEntryComment();
+
+    std::list<IniSection>::const_iterator getSectionIT(const char* sectionName) const;
+    std::list<IniSection>::iterator getSectionIT(const char* sectionName);
+
+    std::list<IniEntry>::const_iterator getEntryIT(const char* entryName, const char* sectionName = NULL) const;
+    std::list<IniEntry>::iterator getEntryIT(const char* entryName, const char* sectionName = NULL);
+
+  private:
+    char*                            fileName;        //!< The name of the File that was parsed.
+    char*                            comment;         //!< A Comment for the header of this File.
+    std::list<IniSection>            sections;        //!< a list of all stored Sections of the Parser
+    std::list<IniSection>::iterator  currentSection;  //!< the current selected Section
+    std::list<IniEntry>::iterator    currentEntry;    //!< the current selected entry (in currentSection)
+
+    std::list<char*>                 commentList;     //!< A list of Comments. (this is for temporary saving of Comments, that are inserted in front of Sections/Entries.)
+};
+
+#endif /* _INI_PARSER_H */
Index: branches/powerups/src/lib/parser/tinyxml/Makefile.am
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/Makefile.am	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/Makefile.am	(revision 5955)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libtinyxml.a 
+
+libtinyxml_a_SOURCES = tinyxml.cc \
+		       tinystr.cc \
+		       tinyxmlerror.cc \
+		       tinyxmlparser.cc
+
+noinst_HEADERS= tinyxml.h \
+		tinystr.h
Index: branches/powerups/src/lib/parser/tinyxml/tinystr.cc
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinystr.cc	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinystr.cc	(revision 5955)
@@ -0,0 +1,115 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+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.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< 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
Index: branches/powerups/src/lib/parser/tinyxml/tinystr.h
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinystr.h	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinystr.h	(revision 5955)
@@ -0,0 +1,304 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+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.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*
+   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 unsigned int 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)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * copy)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * str, size_type len)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	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
Index: branches/powerups/src/lib/parser/tinyxml/tinyxml.cc
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinyxml.cc	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinyxml.cc	(revision 5955)
@@ -0,0 +1,1732 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 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 "tinyxml.h"
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#endif
+
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
+{
+	TIXML_STRING buffer;
+	PutString( str, &buffer );
+	(*stream) << buffer;
+}
+
+void TiXmlBase::PutString( 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;
+		}
+	}
+}
+
+
+// <-- Strange class for a bug fix. Search for STL_STRING_BUG
+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
+{
+	buffer = new char[ str.length()+1 ];
+	if ( buffer )
+	{
+		strcpy( buffer, str.c_str() );
+	}
+}
+
+
+TiXmlBase::StringToBuffer::~StringToBuffer()
+{
+	delete [] buffer;
+}
+// End strange bug fix. -->
+
+
+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; 
+}
+
+
+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 )
+{
+	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 )
+{
+	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;
+
+	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;
+
+	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->parent != this )
+		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->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;
+}
+
+
+TiXmlNode* TiXmlNode::FirstChild( const char * _value )
+{
+	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;
+}
+
+TiXmlNode* TiXmlNode::LastChild( const char * _value )
+{
+	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();
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
+{
+	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 );
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )
+{
+	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;
+}
+
+TiXmlNode* TiXmlNode::NextSibling( const char * _value )
+{
+	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;
+}
+
+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )
+{
+	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 )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	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;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement()
+{
+	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;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value )
+{
+	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;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement()
+{
+	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;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )
+{
+	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;
+}
+
+TiXmlDocument* TiXmlNode::GetDocument()
+{
+	TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( 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;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, int* i ) const
+{
+	const char * s = Attribute( name );
+	if ( i )
+	{
+		if ( s )
+			*i = atoi( s );
+		else
+			*i = 0;
+	}
+	return s;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, double* d ) const
+{
+	const char * s = Attribute( name );
+	if ( d )
+	{
+		if ( s )
+			*d = atof( s );
+		else
+			*d = 0;
+	}
+	return s;
+}
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryIntValue( ival );
+}
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryDoubleValue( dval );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	char buf[64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
+	#else
+		sprintf( buf, "%d", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	char buf[256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
+	#else
+		sprintf( buf, "%f", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, const char * _value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	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::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value;
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{	
+		(*stream) << " ";
+		attrib->StreamOut( stream );
+	}
+
+	// If this node has children, give it a closing tag. Else
+	// make it an empty tag.
+	TiXmlNode* node;
+	if ( firstChild )
+	{ 		
+		(*stream) << ">";
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			node->StreamOut( stream );
+		}
+		(*stream) << "</" << value << ">";
+	}
+	else
+	{
+		(*stream) << " />";
+	}
+}
+
+
+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() );
+	}
+}
+
+
+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::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
+		return true;
+
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && SaveFile( buf.buffer ) )
+		return true;
+
+	return false;
+}
+
+bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
+{
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// See STL_STRING_BUG above.
+	// Fixed with the StringToBuffer class.
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = fopen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		// 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 )
+		{
+			fclose( file );
+			return false;
+		}
+
+		// If we have a file, assume it is all one big XML file, and read it in.
+		// The document parser may decide the document ends sooner than the entire file, however.
+		TIXML_STRING data;
+		data.reserve( length );
+
+		// 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 ) {
+		//if ( fread( buf, 1, length, file ) != (size_t)length ) {
+			SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+			fclose( file );
+			return false;
+		}
+		fclose( file );
+
+		const char* lastPos = buf;
+		const char* p = buf;
+
+		buf[length] = 0;
+		while( *p ) {
+			assert( p < (buf+length) );
+			if ( *p == 0xa ) {
+				// Newline character. No special rules for this. Append all the characters
+				// since the last string, and include the newline.
+				data.append( lastPos, p-lastPos+1 );	// append, include the newline
+				++p;									// move past the newline
+				lastPos = p;							// and point to the new buffer (may be 0)
+				assert( p <= (buf+length) );
+			}
+			else if ( *p == 0xd ) {
+				// Carriage return. Append what we have so far, then
+				// handle moving forward in the buffer.
+				if ( (p-lastPos) > 0 ) {
+					data.append( lastPos, p-lastPos );	// do not add the CR
+				}
+				data += (char)0xa;						// a proper newline
+
+				if ( *(p+1) == 0xa ) {
+					// Carriage return - new line sequence
+					p += 2;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+				else {
+					// it was followed by something else...that is presumably characters again.
+					++p;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+			}
+			else {
+				++p;
+			}
+		}
+		// Handle any left over characters.
+		if ( p-lastPos ) {
+			data.append( lastPos, p-lastPos );
+		}		
+		delete [] buf;
+		buf = 0;
+
+		Parse( data.c_str(), 0, encoding );
+
+		if (  Error() )
+            return false;
+        else
+			return true;
+	}
+	SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+	return false;
+}
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = fopen( filename, "w" );
+	if ( fp )
+	{
+		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 );
+		fclose( fp );
+		return true;
+	}
+	return false;
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorDesc = errorDesc.c_str ();
+
+	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
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->StreamOut( out );
+
+		// Special rule for streams: stop after the root element.
+		// The stream in code will only read one element, so don't
+		// write more than one.
+		if ( node->ToElement() )
+			break;
+	}
+}
+
+
+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*/ ) const
+{
+	TIXML_STRING n, v;
+
+	PutString( name, &n );
+	PutString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos)
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+	else
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+}
+
+
+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if (value.find( '\"' ) != TIXML_STRING::npos)
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "'";
+		PutString( value, stream );
+		(*stream) << "'";
+	}
+	else
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "\"";
+		PutString( value, stream );
+		(*stream) << "\"";
+	}
+}
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( sscanf( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( 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), "%lf", _value);
+	#else
+		sprintf (buf, "%lf", _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::COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+	{
+		fputs( "    ", cfile );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<!--";
+	//PutString( value, stream );
+	(*stream) << value;
+	(*stream) << "-->";
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[" );
+		fprintf( cfile, "%s", value.c_str() );	// unformatted output
+		fprintf( cfile, "]]>\n" );
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		PutString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if ( cdata )
+	{
+		(*stream) << "<![CDATA[" << value << "]]>";
+	}
+	else
+	{
+		PutString( value, stream );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+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::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::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
+{
+	fprintf (cfile, "<?xml ");
+
+	if ( !version.empty() )
+		fprintf (cfile, "version=\"%s\" ", version.c_str ());
+	if ( !encoding.empty() )
+		fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+	if ( !standalone.empty() )
+		fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+	fprintf (cfile, "?>");
+}
+
+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<?xml ";
+
+	if ( !version.empty() )
+	{
+		(*stream) << "version=\"";
+		PutString( version, stream );
+		(*stream) << "\" ";
+	}
+	if ( !encoding.empty() )
+	{
+		(*stream) << "encoding=\"";
+		PutString( encoding, stream );
+		(*stream ) << "\" ";
+	}
+	if ( !standalone.empty() )
+	{
+		(*stream) << "standalone=\"";
+		PutString( standalone, stream );
+		(*stream) << "\" ";
+	}
+	(*stream) << "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+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::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value << ">";		// Don't use entities here! It is unknown.
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+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 )
+{
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+
+	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.
+}
+
+const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
+{
+	const TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char * name )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+#ifdef TIXML_USE_STL	
+TIXML_ISTREAM & operator >> (TIXML_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
+
+
+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
+{
+	base.StreamOut (& out);
+	return out;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::string & operator<< (std::string& out, const TiXmlNode& base )
+{
+   std::ostringstream os_stream( std::ostringstream::out );
+   base.StreamOut( &os_stream );
+   
+   out.append( os_stream.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 );
+}
Index: branches/powerups/src/lib/parser/tinyxml/tinyxml.h
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinyxml.h	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinyxml.h	(revision 5955)
@@ -0,0 +1,1511 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 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.
+*/
+
+
+#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
+
+#if defined( DEBUG ) && defined( _MSC_VER )
+#include <windows.h>
+#define TIXML_LOG OutputDebugString
+#else
+#define TIXML_LOG printf
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#define TIXML_STRING	std::string
+	#define TIXML_ISTREAM	std::istream
+	#define TIXML_OSTREAM	std::ostream
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING	TiXmlString
+	#define TIXML_OSTREAM	TiXmlOutStream
+#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		// TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+	#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 = 4;
+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.
+};
+
+
+// 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.
+		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
+		values 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; }
+	void* GetUserData()						{ return userData; }
+
+	// 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;
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		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_STRING_COUNT
+	};
+
+protected:
+
+	// See STL_STRING_BUG
+	// Utility class to overcome a bug.
+	class StringToBuffer
+	{
+	  public:
+		StringToBuffer( const TIXML_STRING& str );
+		~StringToBuffer();
+		char* buffer;
+	};
+
+	static const char*	SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+	inline static bool	IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+
+	virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+
+	#ifdef TIXML_USE_STL
+	    static bool	StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	    static bool StreamTo( TIXML_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[ *((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;
+		}
+	}
+
+	// Puts a string to a stream, expanding entities as it goes.
+	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
+	static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
+
+	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	// 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 );
+
+	#else
+	    // Used internally, not part of the public API.
+	    friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		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
+
+	/** 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 )    
+	{	  
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "" );    	
+	}	
+	#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.
+	TiXmlNode* FirstChild( const char * value );						///< The first child of this node with the matching 'value'. Will be null if none found.
+
+	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 );	
+
+    #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( TiXmlNode* 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, TiXmlNode* 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, 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 * );
+
+    #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 * );
+
+	/** 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();
+
+	/** 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 * );
+
+    #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();
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * value ) const;
+	TiXmlElement* FirstChildElement( const char * 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: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and 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();
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	const TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlElement*  ToElement() const			{ return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlComment*  ToComment() const			{ return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlUnknown*  ToUnknown() const			{ return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	TiXmlDocument* ToDocument()			{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlElement*  ToElement()			{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlComment*  ToComment()			{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlUnknown*  ToUnknown()			{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlText*	   ToText()   			{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlDeclaration* ToDeclaration()	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null 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;
+
+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( TIXML_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.
+	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.
+
+	/** 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 )	
+	{	
+		StringToBuffer buf( _name );
+		SetName ( buf.buffer ? buf.buffer : "error" );	
+	}
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	
+	{	
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "error" );	
+	}
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next();
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* 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;
+
+	virtual void StreamOut( TIXML_OSTREAM * out ) 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; }
+
+	const TiXmlAttribute*	Find( const char * name ) const;
+	TiXmlAttribute*	Find( const char * name );
+
+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& );
+
+	void 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;
+	/// 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;
+	}
+
+	/** 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 char* Attribute( const std::string& name ) const				{ return Attribute( name.c_str() ); }
+	const char* Attribute( const std::string& name, int* i ) const		{ return Attribute( name.c_str(), i ); }
+	const char* Attribute( const std::string& name, double* d ) const	{ return Attribute( name.c_str(), d ); }
+	int QueryIntAttribute( const std::string& name, int* _value ) const	{ return QueryIntAttribute( name.c_str(), _value ); }
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value )	
+	{	
+		StringToBuffer n( name );
+		StringToBuffer v( _value );
+		if ( n.buffer && v.buffer )
+			SetAttribute (n.buffer, v.buffer );	
+	}	
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value )	
+	{	
+		StringToBuffer n( name );
+		if ( n.buffer )
+			SetAttribute (n.buffer, _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 );
+
+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( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+	/*	[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::COMMENT ) {}
+	TiXmlComment( const TiXmlComment& );
+	void 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 );
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_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::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( 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()					{ 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 );
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_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::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 );
+	void 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 ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+
+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::UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( 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 );
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+
+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 );
+	void 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;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && LoadFile( f.buffer, encoding ));
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && SaveFile( f.buffer ));
+	}
+	#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()	{ return errorLocation.row+1; }
+	int ErrorCol()	{ 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; 
+											}
+
+	/** Dump the document to standard out. */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/// 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 );
+
+protected :
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_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 ).Element();
+	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 ).Element();
+		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" ).Element();
+
+	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 ) { 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* Node() const			{ return node; } 
+	/// Return the handle as a TiXmlElement. This may return null.
+	TiXmlElement* Element() const	{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/// Return the handle as a TiXmlText. This may return null.
+	TiXmlText* Text() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/// Return the handle as a TiXmlUnknown. This may return null;
+	TiXmlUnknown* Unknown() const			{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+private:
+	TiXmlNode* node;
+};
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+
Index: branches/powerups/src/lib/parser/tinyxml/tinyxmlerror.cc
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 5955)
@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 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[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"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.",
+};
Index: branches/powerups/src/lib/parser/tinyxml/tinyxmlparser.cc
===================================================================
--- branches/powerups/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 5955)
+++ branches/powerups/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 5955)
@@ -0,0 +1,1572 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 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"
+#include <ctype.h>
+#include <stddef.h>
+
+//#define DEBUG_PARSER
+
+// 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[ 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()	{ 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[*((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 ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_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( TIXML_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
+
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	*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 == '_' ) )
+	{
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			(*name) += *p;
+			++p;
+		}
+		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!
+	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 );
+			}
+		}
+	}
+	return p + strlen( endTag );
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( TIXML_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;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	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;
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (TIXML_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
+		//		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();
+
+				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;
+	endTag += ">";
+
+	// 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 )
+				return 0;
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			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 )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			const char* 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:
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			if ( node )
+			{
+				node->SetValue( attrib->Value() );
+				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 )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+				    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( TIXML_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 == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( TIXML_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 ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+	p = ReadText( p, &value, false, endTag, false, encoding );
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	int tabsize = 4;
+	if ( document )
+		tabsize = document->TabSize();
+
+	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;
+
+	if ( *p == '\'' )
+	{
+		++p;
+		end = "\'";
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == '"' )
+	{
+		++p;
+		end = "\"";
+		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 ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )						// tag end
+		{
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	if ( cdata )
+	{
+		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;		
+		}
+	}
+	else
+	{
+		while ( in->good() )
+		{
+			int c = in->peek();	
+			if ( 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();
+		}
+	}
+}
+#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 ) )
+		{
+			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 )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( TIXML_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;
+}
+
Index: branches/powerups/src/lib/particles/particle_engine.h
===================================================================
--- branches/powerups/src/lib/particles/particle_engine.h	(revision 5871)
+++ branches/powerups/src/lib/particles/particle_engine.h	(revision 5955)
@@ -12,5 +12,5 @@
 #include "particle_emitter.h"
 
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 
 // FORWARD DECLARATION
Index: branches/powerups/src/lib/particles/particle_system.cc
===================================================================
--- branches/powerups/src/lib/particles/particle_system.cc	(revision 5871)
+++ branches/powerups/src/lib/particles/particle_system.cc	(revision 5955)
@@ -30,5 +30,5 @@
 #include "shell_command.h"
 
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 
 CREATE_FACTORY(ParticleSystem, CL_PARTICLE_SYSTEM);
Index: branches/powerups/src/lib/physics/physics_engine.cc
===================================================================
--- branches/powerups/src/lib/physics/physics_engine.cc	(revision 5871)
+++ branches/powerups/src/lib/physics/physics_engine.cc	(revision 5955)
@@ -20,5 +20,5 @@
 #include "class_list.h"
 #include "list.h"
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 #include "factory.h"
 #include "load_param.h"
Index: branches/powerups/src/lib/shell/shell_command.cc
===================================================================
--- branches/powerups/src/lib/shell/shell_command.cc	(revision 5871)
+++ branches/powerups/src/lib/shell/shell_command.cc	(revision 5955)
@@ -159,5 +159,5 @@
   long classID = CL_NULL;                      //< the classID retrieved from the Class.
   ShellCommandClass* commandClass = NULL;      //< the command class this command applies to.
-  std::list<BaseObject*>* objectList = NULL;   //< the list of Objects stored in classID
+  const std::list<BaseObject*>* objectList = NULL;   //< the list of Objects stored in classID
   BaseObject* objectPointer = NULL;            //< a pointer to th Object to Execute the command on
   bool emptyComplete = false;                  //< if the completion input is empty string. e.g ""
Index: branches/powerups/src/lib/shell/shell_completion.cc
===================================================================
--- branches/powerups/src/lib/shell/shell_completion.cc	(revision 5871)
+++ branches/powerups/src/lib/shell/shell_completion.cc	(revision 5955)
@@ -58,5 +58,5 @@
 
   long classID;                         //< the classID retrieved from the Class.
-  std::list<BaseObject*>* objectList;   //< the list of Objects stored in classID
+  const std::list<BaseObject*>* objectList;   //< the list of Objects stored in classID
   bool emptyComplete = false;           //< if the completion input is empty string. e.g ""
   long completeType = SHELLC_NONE;      //< the Type we'd like to complete.
Index: branches/powerups/src/lib/sound/sound_buffer.cc
===================================================================
--- branches/powerups/src/lib/sound/sound_buffer.cc	(revision 5871)
+++ branches/powerups/src/lib/sound/sound_buffer.cc	(revision 5955)
@@ -20,7 +20,5 @@
 #include "sound_engine.h"
 
-
 using namespace std;
-
 
 //////////////////
@@ -36,6 +34,4 @@
   this->setName(fileName);
 
-  SoundEngine::getInstance()->addBuffer(this);
-
   ALenum format;
   ALvoid* data;
@@ -47,5 +43,5 @@
   alGenBuffers(1, &this->bufferID);
   if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
 
   // read in the wav data
@@ -59,15 +55,15 @@
 #endif
   if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
 
   // send the loaded wav data to the buffer
   alBufferData(this->bufferID, format, data, this->size, freq);
   if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
 
   // remove the wav data (redundant)
   alutUnloadWAV(format, data, this->size, freq);
   if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
 }
 
Index: branches/powerups/src/lib/sound/sound_engine.cc
===================================================================
--- branches/powerups/src/lib/sound/sound_engine.cc	(revision 5871)
+++ branches/powerups/src/lib/sound/sound_engine.cc	(revision 5955)
@@ -27,5 +27,5 @@
 #include "resource_manager.h"
 #include "debug.h"
-#include "ini_parser.h"
+#include "parser/ini_parser/ini_parser.h"
 #include "globals.h"
 
@@ -47,4 +47,9 @@
   this->bufferList = NULL;
   this->sourceList = NULL;
+
+  this->device = NULL;
+  this->context = NULL;
+
+  this->maxSourceCount = 32;
 }
 
@@ -64,4 +69,10 @@
     while (this->sourceList->size() > 0)
       delete dynamic_cast<SoundSource*>(this->sourceList->front());
+  }
+
+  while(!this->ALSources.empty())
+  {
+    alDeleteSources(1, &this->ALSources.top());
+    this->ALSources.pop();
   }
 
@@ -86,4 +97,6 @@
 void SoundEngine::loadSettings(IniParser* iniParser)
 {
+  const char* channels = iniParser->getVar(CONFIG_NAME_AUDIO_CHANNELS, CONFIG_SECTION_AUDIO, "32");
+  this->maxSourceCount = atoi(channels);
   const char* musicVolume = iniParser->getVar(CONFIG_NAME_MUSIC_VOLUME, CONFIG_SECTION_AUDIO, "80");
   this->musicVolume = atof(musicVolume)/100.0;
@@ -118,40 +131,22 @@
 
 
-/**
- *  adds a SoundBuffer to the bufferList of the SoundEngine
- * @param buffer The buffer to add to the bufferList
-*/
-void SoundEngine::addBuffer(SoundBuffer* buffer)
-{
-  if (unlikely(this->bufferList == NULL))
-    this->bufferList = ClassList::getList(CL_SOUND_BUFFER);
-}
-
-/**
- *  removes a SoundBuffer from the bufferList of the SoundEngine
- * @param buffer The buffer to delete from the SoundEngine
-*/
-void SoundEngine::removeBuffer(SoundBuffer* buffer)
-{
-  // look if there are any sources that have the buffer still loaded
-  if (this->sourceList != NULL)
-  {
-    list<BaseObject*>::iterator source;
-    for (source = this->sourceList->begin(); source != this->sourceList->end(); source++)
-    {
-      if (buffer == static_cast<SoundSource*>(*source)->getBuffer())
-        delete (*source);
+void SoundEngine::popALSource(ALuint& source)
+{
+  if (source != 0)
+    return;
+  else
+  {
+
+    /// @TODO try to create more sources if needed
+    if (!this->ALSources.empty())
+    {
+
+      source = this->ALSources.top();
+      printf("test: : %d\n", source);
+      this->ALSources.pop();
     }
   }
 }
 
-/**
- * adds a SoundSource to the sourceList of the SoundEngine
- * @param source The source to add to the sourceList
-*/
-void SoundEngine::addSource(SoundSource* source)
-{
-  this->sourceList = ClassList::getList(CL_SOUND_SOURCE);
-}
 
 /**
@@ -180,21 +175,34 @@
 
   // updating all the Sources positions
-  if (likely(this->sourceList != NULL))
-  {
-    list<BaseObject*>::iterator sourceIT;
+  if (likely(this->sourceList != NULL || (this->sourceList = ClassList::getList(CL_SOUND_SOURCE)) != NULL))
+  {
+    list<BaseObject*>::const_iterator sourceIT;
     SoundSource* source;
     for (sourceIT = this->sourceList->begin(); sourceIT != this->sourceList->end(); sourceIT++)
     {
       source = static_cast<SoundSource*>(*sourceIT);
-      if (likely(source->getNode() != NULL))
+      if (source->isPlaying())
       {
-        alSource3f(source->getID(), AL_POSITION,
-                   source->getNode()->getAbsCoor().x,
-                   source->getNode()->getAbsCoor().y,
-                   source->getNode()->getAbsCoor().z);
-        alSource3f(source->getID(), AL_VELOCITY,
-                   source->getNode()->getVelocity().x,
-                   source->getNode()->getVelocity().y,
-                   source->getNode()->getVelocity().z);
+        int play;
+        alGetSourcei(source->getID(), AL_SOURCE_STATE, &play);
+        if(play == AL_PLAYING)
+        {
+          if (likely(source->getNode() != NULL))
+          {
+            alSource3f(source->getID(), AL_POSITION,
+                       source->getNode()->getAbsCoor().x,
+                       source->getNode()->getAbsCoor().y,
+                       source->getNode()->getAbsCoor().z);
+            alSource3f(source->getID(), AL_VELOCITY,
+                       source->getNode()->getVelocity().x,
+                       source->getNode()->getVelocity().y,
+                       source->getNode()->getVelocity().z);
+          }
+
+        }
+        else
+        {
+          source->stop();
+        }
       }
     }
@@ -281,9 +289,13 @@
 
   // INITIALIZING THE DEVICE:
+#ifndef AL_VERSION_1_1
   ALubyte deviceName[] =
+#else
+  ALCchar deviceName[] =
+#endif
 #ifdef __WIN32__
-      "native";
+      "Direct3D";
 #else
-      "'( ( devices '( native arts null ) ) )";
+      "'( ( devices '( native null ) ) )";
 #endif
   //
@@ -296,7 +308,33 @@
 
   if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
 
   this->setDopplerValues(SOUND_DOPPLER_FACTOR, SOUND_DOPPLER_VELOCITY);
+}
+
+
+/**
+ * Allocates openAL sources
+ * @param count how many sources to allocate
+ * @returns true on success, false if at least one source could not be allocated
+ */
+bool SoundEngine::allocateSources(unsigned int count)
+{
+  ALenum result;
+  // Setting default values.
+  for (unsigned int i = 0; i < count; i++)
+  {
+    ALuint source;
+
+    alGenSources(1, &source);
+    if ((result = alGetError()) != AL_NO_ERROR)
+      PRINTF(1)("Error Generating Sources: '%s'\n", SoundEngine::getALErrorString(result));
+
+    alSourcef (source, AL_PITCH,    1.0      );
+    alSourcef (source, AL_GAIN,     this->getEffectsVolume() );
+    alSourcei (source, AL_LOOPING,  AL_FALSE );
+    this->ALSources.push(source);
+  }
+  return true;
 }
 
@@ -305,31 +343,20 @@
  * @param err The error found
 */
-void SoundEngine::PrintALErrorString(ALenum err)
+const char* SoundEngine::getALErrorString(ALenum err)
 {
   switch(err)
     {
     case AL_NO_ERROR:
-      PRINTF(4)("AL_NO_ERROR\n");
-      break;
-
+      return ("AL_NO_ERROR");
     case AL_INVALID_NAME:
-      PRINTF(2)("AL_INVALID_NAME\n");
-      break;
-
+      return ("AL_INVALID_NAME");
     case AL_INVALID_ENUM:
-      PRINTF(2)("AL_INVALID_ENUM\n");
-      break;
-
+      return ("AL_INVALID_ENUM");
     case AL_INVALID_VALUE:
-      PRINTF(2)("AL_INVALID_VALUE\n");
-      break;
-
+      return ("AL_INVALID_VALUE");
     case AL_INVALID_OPERATION:
-      PRINTF(2)("AL_INVALID_OPERATION\n");
-      break;
-
+      return ("AL_INVALID_OPERATION");
     case AL_OUT_OF_MEMORY:
-      PRINTF(2)("AL_OUT_OF_MEMORY\n");
-      break;
+      return ("AL_OUT_OF_MEMORY");
     };
 }
@@ -337,5 +364,4 @@
 void SoundEngine::listDevices()
 {
-
   printf("%s\n",(const char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER));
 }
Index: branches/powerups/src/lib/sound/sound_engine.h
===================================================================
--- branches/powerups/src/lib/sound/sound_engine.h	(revision 5871)
+++ branches/powerups/src/lib/sound/sound_engine.h	(revision 5955)
@@ -14,4 +14,5 @@
 
 #include <list>
+#include <stack>
 
 #define SOUND_DOPPLER_FACTOR       0.001          //!< A factor for the audible doppler effect
@@ -22,7 +23,7 @@
 class IniParser;
 
+
 //! A class that handles audio via the openAudioLibrary
 class SoundEngine : public BaseObject {
-
   public:
     virtual ~SoundEngine();
@@ -47,36 +48,37 @@
 
   // administrative
-    void addBuffer(SoundBuffer* buffer);
-    void removeBuffer(SoundBuffer* buffer);
-    void addSource(SoundSource* source);
+    void popALSource(ALuint& source);
+    void pushALSource(ALuint& source) { if (source != 0) this->ALSources.push(source); };
 
     void flushUnusedBuffers();
     void flushAllBuffers();
     void flushAllSources();
+
     bool initAudio();
+    bool allocateSources(unsigned int count);
 
   // error handling:
-    static void PrintALErrorString(ALenum err);
-  //  static void PrintALCErrorString(ALenum err);
-
+    static const char* getALErrorString(ALenum err);
 
   private:
     SoundEngine();
+
     void listDevices();
 
   private:
-    static SoundEngine*      singletonRef;             //!< Reference to this class
+    static SoundEngine*            singletonRef;             //!< Reference to this class
 
-    ALCdevice*               device;                   //!< the used audio-device.
-    ALCcontext*              context;                  //!< the context, currently in use.
+    ALCdevice*                     device;                   //!< the used audio-device.
+    ALCcontext*                    context;                  //!< the context, currently in use.
 
-    float                    musicVolume;              //!< the maximum volume of the music in % (0f,1f]
-    float                    effectsVolume;            //!< the maximum volume of sound-effects in % (0f,1f]
-    PNode*                   listener;                 //!< The listener of the Scene
+    float                          musicVolume;              //!< the maximum volume of the music in % (0f,1f]
+    float                          effectsVolume;            //!< the maximum volume of sound-effects in % (0f,1f]
+    PNode*                         listener;                 //!< The listener of the Scene
 
-    std::list<BaseObject*>*  bufferList;               //!< A list of buffers
-    std::list<BaseObject*>*  sourceList;               //!< A list for all the sources in the scene.
+    const std::list<BaseObject*>*  bufferList;               //!< A list of buffers
+    const std::list<BaseObject*>*  sourceList;               //!< A list for all the sources in the scene.
 
-
+    unsigned int                   maxSourceCount;           //!< How many Sources is the Maximum
+    std::stack<ALuint>             ALSources;                //!< A list of real openAL-Sources, the engine allocates, and stores for reuse.
 };
 
Index: branches/powerups/src/lib/sound/sound_source.cc
===================================================================
--- branches/powerups/src/lib/sound/sound_source.cc	(revision 5871)
+++ branches/powerups/src/lib/sound/sound_source.cc	(revision 5955)
@@ -18,4 +18,5 @@
 #include "sound_source.h"
 #include "sound_engine.h"
+
 #include "alincl.h"
 #include "compiler.h"
@@ -33,17 +34,9 @@
 
   // adding the Source to the SourcesList of the SoundEngine
-  SoundEngine::getInstance()->addSource(this);
-
   this->buffer = buffer;
   this->sourceNode = sourceNode;
 
-  alGenSources(1, &this->sourceID);
-  if ((result = alGetError()) != AL_NO_ERROR)
-    SoundEngine::PrintALErrorString(result);
-  if (this->buffer != NULL)
-    alSourcei (this->sourceID, AL_BUFFER,   this->buffer->getID());
-  alSourcef (this->sourceID, AL_PITCH,    1.0      );
-  alSourcef (this->sourceID, AL_GAIN,     SoundEngine::getInstance()->getEffectsVolume() );
-  alSourcei (sourceID, AL_LOOPING,  AL_FALSE     );
+  this->sourceID = 0;
+  this->bPlay = false;
 }
 
@@ -53,6 +46,5 @@
 SoundSource::~SoundSource()
 {
-  //SoundEngine::getInstance()->removeSource(this);
-  alDeleteSources(1, &this->sourceID);
+  SoundEngine::getInstance()->pushALSource(this->sourceID);
 }
 
@@ -62,5 +54,8 @@
 void SoundSource::play()
 {
+  if (this->sourceID == 0)
+    SoundEngine::getInstance()->popALSource(this->sourceID);
   alSourcePlay(this->sourceID);
+  this->bPlay = true;
 }
 
@@ -71,4 +66,8 @@
 void SoundSource::play(const SoundBuffer* buffer)
 {
+  if (unlikely(this->sourceID == 0))
+    SoundEngine::getInstance()->popALSource(this->sourceID);
+
+  printf("%d\n",sourceID);
   alSourceStop(this->sourceID);
   alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
@@ -77,4 +76,5 @@
   if (unlikely(this->buffer != NULL))
     alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+  this->bPlay = true;
 }
 
@@ -84,5 +84,7 @@
 void SoundSource::stop()
 {
+  this->bPlay = false;
   alSourceStop(this->sourceID);
+  SoundEngine::getInstance()->pushALSource(this->sourceID);
 }
 
Index: branches/powerups/src/lib/sound/sound_source.h
===================================================================
--- branches/powerups/src/lib/sound/sound_source.h	(revision 5871)
+++ branches/powerups/src/lib/sound/sound_source.h	(revision 5955)
@@ -31,4 +31,6 @@
     /** @returns The ID of this Source */
     inline ALuint getID() const { return this->sourceID; }
+    /** @returns true, if the Source is Playing */
+    inline bool   isPlaying() const { return this->bPlay; };
     /** @returns the SoundBuffer of this Source */
     inline const SoundBuffer* getBuffer() const { return this->buffer; }
@@ -39,4 +41,5 @@
 
   private:
+    bool                   bPlay;                 //!< If the Source is Playing.
     ALuint                 sourceID;              //!< The ID of the Source
     const SoundBuffer*     buffer;                //!< The buffer to play in this source.
Index: branches/powerups/src/lib/util/executor/executor_specials.h
===================================================================
--- branches/powerups/src/lib/util/executor/executor_specials.h	(revision 5871)
+++ branches/powerups/src/lib/util/executor/executor_specials.h	(revision 5955)
@@ -10,5 +10,5 @@
 
 #include "compiler.h"
-#include "tinyxml.h"
+#include "parser/tinyxml/tinyxml.h"
 // FORWARD DECLARATION
 
Index: branches/powerups/src/lib/util/ini_parser.cc
===================================================================
--- branches/powerups/src/lib/util/ini_parser.cc	(revision 5871)
+++ 	(revision )
@@ -1,473 +1,0 @@
-/*
-   orxonox - the future of 3D-vertical-scrollers
-
-   Copyright (C) 2004 orx
-
-   This program 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 2, or (at your option)
-   any later version.
-
-   ### File Specific:
-   main-programmer: Benjamin Grauer
-   co-programmer: Christian Meyer
-
-   2005-08-14: complete reimplementation:
-               now the File is parsed at the initialisation,
-               and informations is gathered there.
-*/
-
-
-#include "ini_parser.h"
-
-#include "list.h"
-#include <stdlib.h>
-#include <string.h>
-#include "debug.h"
-
-using namespace std;
-
-/**
- *  constructs an IniParser using a file
- * @param fileName: the path and name of the file to parse
-*/
-IniParser::IniParser (const char* fileName)
-{
-  this->currentEntry = NULL;
-  this->currentSection = NULL;
-  this->sections = NULL;
-  this->fileName = NULL;
-  if (fileName != NULL)
-    this->readFile(fileName);
-}
-
-/**
- *  removes the IniParser from memory
-*/
-IniParser::~IniParser ()
-{
-  deleteSections();
-}
-
-/**
- * removes all the sections. This is like delete, but even cooler :)
- */
-void IniParser::deleteSections()
-{
-  if (this->sections)
-  {
-    tIterator<IniSection>* sectionIt = this->sections->getIterator();
-    IniSection* sectionEnum = sectionIt->firstElement();
-    while (sectionEnum)
-    {
-      tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
-      IniEntry* entryEnum = entryIt->firstElement();
-      while (entryEnum)
-      {
-        delete []entryEnum->name;
-        delete []entryEnum->value;
-        delete entryEnum;
-        entryEnum = entryIt->nextElement();
-      }
-      delete entryIt;
-
-      delete []sectionEnum->name;
-      delete sectionEnum->entries;
-      delete sectionEnum;
-      sectionEnum = sectionIt->nextElement();
-    }
-    delete sectionIt;
-  }
-  delete this->sections;
-  this->currentEntry = NULL;
-  this->currentSection = NULL;
-  this->sections = NULL;
-  this->setFileName(NULL);
-}
-
-/**
- * opens another file to parse
- * @param fileName: path and name of the new file to parse
- * @return true on success false otherwise;
-*/
-bool IniParser::readFile(const char* fileName)
-{
-  FILE*    stream;           //!< The stream we use to read the file.
-  if (sections != NULL)
-    deleteSections();
-  if( fileName == NULL)
-    return false;
-  this->setFileName(fileName);
-
-  if( (stream = fopen (fileName, "r")) == NULL)
-  {
-    PRINTF(1)("IniParser could not open %s\n", fileName);
-    return false;
-  }
-  else
-  {
-    this->currentEntry = NULL;
-    this->currentSection = NULL;
-    this->sections = new tList<IniSection>;
-
-    /////////////////////////////
-    // READING IN THE INI-FILE //
-    /////////////////////////////
-    char lineBuffer[PARSELINELENGHT];
-    char buffer[PARSELINELENGHT];
-    const char* lineBegin;
-    char* ptr;
-
-    while( fgets (lineBuffer, PARSELINELENGHT, stream))
-    {
-      lineBegin = lineBuffer;
-      // remove newline char, and \0-terminate
-      if( (ptr = strchr( lineBuffer, '\n')) != NULL)
-        *ptr = 0;
-      // cut up to the beginning of the line.
-      while((*lineBegin == ' ' || *lineBegin == '\t') && lineBegin < lineBuffer + strlen(lineBuffer))
-        ++lineBegin;
-      if (strlen(lineBegin) <= 1 || *lineBegin == '#' || *lineBegin == ';')
-        continue;//printf("empty Line\n");
-      // check for section identifyer
-      else if( sscanf (lineBegin, "[%s", buffer) == 1)
-      {
-        if( (ptr = strchr( buffer, ']')) != NULL)
-        {
-          *ptr = 0;
-          this->addSection(buffer);
-        }
-      }
-      // check for Entry identifier (Entry = Value)
-      else if( (ptr = strchr( lineBegin, '=')) != NULL)
-      {
-        if (currentSection == NULL)
-        {
-          PRINTF(2)("Not in a Section yet for %s\n", lineBegin);
-          continue;
-        }
-        if( ptr == lineBegin)
-          continue;
-        char* valueBegin = ptr+1;
-        while ((*valueBegin == ' ' || *valueBegin == '\t') && valueBegin <= lineBegin + strlen(lineBegin))
-          ++valueBegin;
-        char* valueEnd = valueBegin + strlen(valueBegin)-1;
-        while ((*valueEnd == ' ' || *valueEnd == '\t') && valueEnd >= valueBegin)
-          --valueEnd;
-        valueEnd[1] = '\0';
-        char* nameEnd = ptr-1;
-        while ((*nameEnd == ' ' || *nameEnd == '\t' ) && nameEnd >= lineBegin)
-          --nameEnd;
-        nameEnd[1] = '\0';
-
-        this->addVar(lineBegin, valueBegin);
-      }
-    }
-  }
-  fclose(stream);
-  return true;
-}
-
-/**
- * opens a file and writes to it
- * @param fileName: path and name of the new file to write to
- * @return true on success false otherwise
- */
-bool IniParser::writeFile(const char* fileName)
-{
-  FILE*    stream;           //!< The stream we use to read the file.
-  if( fileName == NULL)
-    return false;
-
-  if( (stream = fopen (fileName, "w")) == NULL)
-  {
-    PRINTF(1)("IniParser could not open %s\n", fileName);
-    return false;
-  }
-  else
-  {
-    if (this->sections)
-    {
-      tIterator<IniSection>* sectionIt = this->sections->getIterator();
-      IniSection* sectionEnum = sectionIt->firstElement();
-      while (sectionEnum)
-      {
-        fprintf(stream, "\n [%s]\n", sectionEnum->name);
-
-        tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
-        IniEntry* entryEnum = entryIt->firstElement();
-        while (entryEnum)
-        {
-          fprintf(stream, "   %s = %s\n", entryEnum->name, entryEnum->value);
-
-          entryEnum = entryIt->nextElement();
-        }
-        delete entryIt;
-
-        sectionEnum = sectionIt->nextElement();
-      }
-      delete sectionIt;
-    }
-    else
-      PRINTF(1)("%s no sections defined yet\n", fileName);
-  }
-  fclose(stream);
-}
-
-/**
- * adds a section to the list of Sections,
- * if no Section list is availiable, it will create it
- * @param sectionName the Name of the section to add
- * @return true on success... there is only success or segfault :)
- */
-bool IniParser::addSection(const char* sectionName)
-{
-  if (this->sections == NULL)
-    this->sections = new tList<IniSection>;
-
-  IniSection* newSection = new IniSection;
-  newSection->name = new char[strlen(sectionName)+1];
-  strcpy(newSection->name, sectionName);
-  newSection->entries = new tList<IniEntry>;
-  this->currentSection = newSection;
-  this->sections->add(newSection);
-  PRINTF(5)("Added Section %s\n", sectionName);
-  return true;
-}
-
-/**
- *  set the parsing cursor to the specified section
- * @param sectionName: the name of the section to set the cursor to
- * @return true on success or false if the section could not be found
-*/
-bool IniParser::getSection( const char* sectionName)
-{
-  tIterator<IniSection>* sectionIt = this->sections->getIterator();
-  IniSection* sectionEnum = sectionIt->firstElement();
-  while (sectionEnum)
-  {
-    if (!strcmp(sectionEnum->name, sectionName))
-    {
-      this->currentSection = sectionEnum;
-      this->currentEntry = NULL;
-      delete sectionIt;
-      return true;
-    }
-
-    sectionEnum = sectionIt->nextElement();
-  }
-  delete sectionIt;
-  return false;
-}
-
-/**
- * moves to the first section
- */
-void IniParser::getFirstSection()
-{
-  if (this->sections)
-    this->currentSection = this->sections->firstElement();
-  else
-    this->currentSection = NULL;
-  this->currentEntry = NULL;
-}
-
-/**
- * searches the next section
- * @returns the name of the section if found, NULL otherwise
- */
-const char* IniParser::nextSection()
-{
-  if (this->currentSection == NULL)
-    return NULL;
-  else
-  {
-    if (this->sections)
-    {
-      if (this->currentSection == this->sections->lastElement())
-        this->currentSection = NULL;
-      else
-        this->currentSection = this->sections->nextElement(this->currentSection);
-    }
-  }
-
-  if (this->currentSection != NULL)
-    return this->currentSection->name;
-  else
-    return NULL;
-}
-
-/**
- * moves to the first Variable of the current Section
- */
-void IniParser::getFirstVar()
-{
-  if (this->currentSection)
-    this->currentEntry = this->currentSection->entries->firstElement();
-  else
-    this->currentEntry = NULL;
-}
-
-/**
- *  gets the next VarName=VarValue pair from the parsing stream
- * @return true on success, false otherwise (in the latter case name and value will be NULL)
- */
-bool IniParser::nextVar()
-{
-  if (this->currentSection == NULL
-      || this->currentEntry == NULL
-      || this->currentEntry == this->currentSection->entries->lastElement())
-  {
-    this->currentEntry = NULL;
-    return false;
-  }
-  this->currentEntry = this->currentSection->entries->nextElement(this->currentEntry);
-
-  if (this->currentEntry == NULL)
-    return false;
-  else
-    return true;
-}
-
-/**
- * adds a new Entry to either the currentSection or the section called by sectionName
- * @param entryName the Name of the Entry to add
- * @param value the value to assign to this entry
- * @param sectionName if NULL then this entry will be set to the currentSection
- * otherwise to the section refered to by sectionName.
- * If both are NULL no entry will be added
- * @return true if everything is ok false on error
- */
-bool IniParser::addVar(const char* entryName, const char* value, const char* sectionName)
-{
-  IniSection* addSection = NULL;
-  if (sectionName != NULL)
-  {
-    tIterator<IniSection>* sectionIt = this->sections->getIterator();
-    IniSection* sectionEnum = sectionIt->firstElement();
-    while (sectionEnum)
-    {
-      if (!strcmp(sectionEnum->name, sectionName))
-      {
-        addSection = sectionEnum;
-        break;
-      }
-      sectionEnum = sectionIt->nextElement();
-    }
-    delete sectionIt;
-  }
-  else
-    addSection = this->currentSection;
-
-  if (addSection == NULL)
-  {
-    PRINTF(2)("section not found for value %s\n", entryName);
-    return false;
-  }
-  else
-  {
-    IniEntry* newEntry = new IniEntry;
-    newEntry->name = new char[strlen (entryName)+1];
-    strcpy(newEntry->name, entryName);
-    newEntry->value = new char[strlen(value)+1];
-    strcpy(newEntry->value, value);
-    this->currentSection->entries->add(newEntry);
-    PRINTF(5)("Added Entry %s with Value '%s' to Section %s\n", newEntry->name, newEntry->name, addSection->name);
-    return true;
-  }
-}
-
-/**
- *  directly acesses an entry in a section
- * @param entryName: the name of the entry to find
- * @param sectionName: the section where the entry is to be found
- * @param defaultValue: what should be returned in case the entry cannot be found
- * @return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
- *
- *  The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
- * lead to unwanted behaviour.
-*/
-const char* IniParser::getVar(const char* entryName, const char* sectionName, const char* defaultValue) const
-{
-  if (this->sections)
-  {
-    tIterator<IniSection>* sectionIt = this->sections->getIterator();
-    IniSection* sectionEnum = sectionIt->firstElement();
-    while (sectionEnum)
-    {
-      if (!strcmp(sectionEnum->name, sectionName))
-      {
-        tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
-        IniEntry* entryEnum = entryIt->firstElement();
-        while (entryEnum)
-        {
-          if (!strcmp(entryEnum->name, entryName))
-          {
-            delete entryIt;
-            delete sectionIt;
-            return entryEnum->value;
-          }
-          entryEnum = entryIt->nextElement();
-        }
-         delete entryIt;
-         PRINTF(2)("Entry %s in section %s not found.\n", entryName, sectionName);
-         break;
-      }
-      sectionEnum = sectionIt->nextElement();
-    }
-    delete sectionIt;
-    PRINTF(2)("Section %s that should be containing %s not found.\n", sectionName, entryName);
-  }
-  else
-    PRINTF(1)("%s not opened\n", fileName);
-
-  return defaultValue;
-
-}
-
-
-void IniParser::setFileName(const char* fileName)
-{
-  if (this->fileName)
-    delete []this->fileName;
-  if (fileName)
-  {
-    this->fileName = new char[strlen(fileName)+1];
-    strcpy(this->fileName, fileName);
-  }
-  else
-    this->fileName = NULL;
-}
-
-
-/**
- * output the whole tree in a nice and easy way.
- */
-void IniParser::debug() const
-{
-  PRINTF(0)("Iniparser %s - debug\n", this->fileName);
-  if (this->sections)
-  {
-    tIterator<IniSection>* sectionIt = this->sections->getIterator();
-    IniSection* sectionEnum = sectionIt->firstElement();
-    while (sectionEnum)
-    {
-      PRINTF(0)(" [%s]\n", sectionEnum->name);
-
-      tIterator<IniEntry>* entryIt = sectionEnum->entries->getIterator();
-      IniEntry* entryEnum = entryIt->firstElement();
-      while (entryEnum)
-      {
-        PRINTF(0)("   :%s: -> '%s'\n", entryEnum->name, entryEnum->value);
-
-        entryEnum = entryIt->nextElement();
-      }
-      delete entryIt;
-
-      sectionEnum = sectionIt->nextElement();
-    }
-    delete sectionIt;
-  }
-  else
-    PRINTF(1)("%s not opened\n", fileName);
-}
Index: branches/powerups/src/lib/util/ini_parser.h
===================================================================
--- branches/powerups/src/lib/util/ini_parser.h	(revision 5871)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*!
- * @file ini_parser.h
- * A small ini file parser
- *
- * Can be used to find a defined [Section] in an ini file and get the VarName = Value entries
- */
-
-#ifndef _INI_PARSER_H
-#define _INI_PARSER_H
-
-#define PARSELINELENGHT     512       //!< how many chars to read at once
-#ifndef NULL
-#define NULL 0x0                      //!< NULL
-#endif
-
-// FORWARD DECLARATION //
-template<class T> class tList;
-
-//! ini-file parser
-/**
- * This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
- */
-class IniParser
-{
-  private:
-    ////////////////////////////////////
-    //! a struct for Entries in the Parser's File's Sections
-    struct IniEntry
-    {
-      char*              name;     //!< name of a given Entry
-      char*              value;    //!< value of a given Entry
-    };
-    //! a struct for Sections in the Parser's file
-    struct IniSection
-    {
-      char*               name;    //!< name of a given section
-      tList<IniEntry>*    entries; //!< a list of entries for this section
-    };
-    ////////////////////////////////////
-
-  public:
-    IniParser (const char* filename = NULL);
-    ~IniParser ();
-
-    bool readFile(const char* fileName);
-    bool writeFile(const char* fileName);
-
-    bool addSection(const char* sectionName);
-    bool getSection(const char* sectionName);
-
-    void getFirstSection();
-    const char* nextSection();
-
-    /** @returns true if the file is opened, false otherwise*/
-    bool isOpen() const { return (sections != NULL)?true:false; };
-    /** @returns the fileName we have opened. */
-    const char* getFileName() const { return this->fileName; };
-
-    bool addVar(const char* entryName, const char* value, const char* sectionName = NULL);
-    const char* getVar(const char* entryName, const char* sectionName, const char* defaultValue = "") const;
-
-    void getFirstVar();
-    bool nextVar();
-
-    /** @returns the name of the Current selected Section */
-    const char* getCurrentSection() const { return (this->currentSection!=NULL)?this->currentSection->name:NULL; };
-    /** @returns the current entries Name, or NULL if we havn't selected a Entry */
-    const char* getCurrentName() const { return (this->currentEntry!=NULL)?this->currentEntry->name:NULL; };
-    /** @returns the current entries Value, or NULL if we havn't selected a Entry */
-    const char* getCurrentValue() const { return (this->currentEntry!=NULL)?this->currentEntry->value:NULL; };
-
-    void debug() const;
-
-  private:
-    void deleteSections();
-    void setFileName(const char* fileName);
-
-  private:
-    char*                 fileName;        //!< The name of the File that was parsed.
-    tList<IniSection>*    sections;        //!< a list of all stored Sections of the Parser
-    IniSection*           currentSection;  //!< the current selected Section
-    IniEntry*             currentEntry;    //!< the current selected entry (in currentSection)
-};
-
-#endif /* _INI_PARSER_H */
