Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h	(revision 2111)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h	(revision 2113)
@@ -122,5 +122,5 @@
 	list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
 	// find the bbox which is closest to the current bbox
-	for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(); ++ sit)
+	for (sit = sceneNodeList.begin(); sit != sit_end; ++ sit)
 	{
 		SceneNode *sn = *sit;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.h	(revision 2113)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.h	(revision 2113)
@@ -0,0 +1,28 @@
+#ifndef __VIEWCELLSDPARSER_H
+#define __VIEWCELLSDPARSER_H
+
+#include "Parser.h"
+#include "Containers.h"
+
+namespace GtpVisibilityPreprocessor {
+
+class ViewCellsManager;
+class VspBspTree;
+class BoundingBoxConverter;
+class Environment;
+
+class ViewCellsParser : public Parser
+{
+public:
+  ViewCellsParser():Parser() {}
+  
+  bool ParseViewCellsFile(const string &filename, 
+						  ViewCellsManager **viewCells,
+						  ObjectContainer &pvsObjects,
+						  ObjectContainer &preprocessorObjects,
+						  BoundingBoxConverter *bconverter);
+};
+
+}
+
+#endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h	(revision 1344)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h	(revision 2113)
@@ -17,9 +17,9 @@
   ViewCellsParser():Parser() {}
   
-  bool ParseViewCellsFile(
-	  const string filename, 
-	  ViewCellsManager **viewCells,
-	  ObjectContainer *objects,
-	  BoundingBoxConverter *bconverter);
+  bool ParseViewCellsFile(const string &filename, 
+						  ViewCellsManager **viewCells,
+						  ObjectContainer &pvsObjects,
+						  ObjectContainer &preprocessorObjects,
+						  BoundingBoxConverter *bconverter);
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2111)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2113)
@@ -571,10 +571,11 @@
 	*/
 	static ViewCellsManager *LoadViewCells(const string &filename, 
-										   ObjectContainer *objects, 
+										   ObjectContainer &pvsObjects,
+										   ObjectContainer &preprocessorObjects,
 										   bool finalizeViewCells = false,
 										   BoundingBoxConverter *bconverter = NULL);
 
 
-	////////////////////////////////////////////////////////7
+	///////////////////////
 	// visiblity filter options
 
@@ -1212,5 +1213,6 @@
 public:
 
-	VspOspViewCellsManager(ViewCellsTree *vcTree, const string &hierarchyType);
+	VspOspViewCellsManager(ViewCellsTree *vcTree, 
+						   const string &hierarchyType);
 	
 	~VspOspViewCellsManager();
@@ -1245,5 +1247,6 @@
 	float GetProbability(ViewCell *viewCell);
 	
-	ViewCell *GetViewCell(const Vector3 &point, const bool active = false) const;
+	ViewCell *GetViewCell(const Vector3 &point, 
+						  const bool active = false) const;
 
 	bool GetViewPoint(Vector3 &viewPoint) const;
@@ -1260,9 +1263,4 @@
 
 	void Finalize(ViewCell *viewCell, const bool createMesh);
-
-  	ViewCellsManager *LoadViewCells(const string &filename, 
-									ObjectContainer *objects,
-									const bool finalizeViewCells,
-									BoundingBoxConverter *bconverter);
 
 	void ExportSingleViewCells(const ObjectContainer &objects,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2111)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2113)
@@ -733,5 +733,9 @@
 		cout << "loading view cells from " << buf << endl<<flush;
 
-		mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects, true, NULL);
+		mViewCellsManager = ViewCellsManager::LoadViewCells(buf, 
+															mObjects, 
+															mObjects, 
+															true, 
+															NULL);
 
 		cout << "view cells loaded." << endl<<flush;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2100)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2113)
@@ -518,4 +518,10 @@
 			</File>
 			<File
+				RelativePath=".\IntersectionBoundingBoxConverter.cpp">
+			</File>
+			<File
+				RelativePath=".\IntersectionBoundingBoxConverter.h">
+			</File>
+			<File
 				RelativePath="..\src\KdTree.cpp">
 			</File>
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.h	(revision 2113)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.h	(revision 2113)
@@ -0,0 +1,35 @@
+#ifndef _IntersectionBoundingBoxConverter_H__
+#define _IntersectionBoundingBoxConverter_H__
+
+#include "Containers.h"
+#include "BoundingBoxConverter.h"
+
+namespace GtpVisibilityPreprocessor {
+
+class AxisAlignedBox3;
+class KdTree;
+
+/**	Class which converts preprocessor types to OGRE types
+*/
+class IntersectionBoundingBoxConverter: public BoundingBoxConverter
+{
+public:
+	IntersectionBoundingBoxConverter(KdTree *kdTree): mKdTree(kdTree) {}
+	
+	bool IdentifyObjects(const IndexedBoundingBoxContainer &iboxes,
+						 ObjectContainer &objects) const;
+
+
+protected:
+
+	/** find objects which are intersected by this box
+	*/
+	void FindIntersectingObjects(const AxisAlignedBox3 &box,
+								 ObjectContainer &objects) const;
+
+	KdTree *mKdTree;
+};
+
+} 
+
+#endif // IntersectionBoundingBoxConverter
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2105)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2113)
@@ -1023,5 +1023,6 @@
 
 ViewCellsManager *ViewCellsManager::LoadViewCells(const string &filename, 
-												  ObjectContainer *objects,
+												  ObjectContainer &pvsObjects,
+												  ObjectContainer &preprocessorObjects,
 												  bool finalizeViewCells,
 												  BoundingBoxConverter *bconverter)
@@ -1032,55 +1033,58 @@
 
 	const long startTime = GetTime();
-	bool success = parser.ParseViewCellsFile(filename, &vm, objects, bconverter);
-
-	cout<<"viewcells parsed "<<endl<<flush;
-	
-	if (success)
-	{
-		if (0)
-		{
-			vm->ResetViewCells();
-		}
-		else
-		{
-			//hack: should work with reset function
-			ViewCellContainer leaves;
-
-			vm->mViewCells.clear();
-			vm->mViewCellsTree->CollectLeaves(vm->mViewCellsTree->GetRoot(), leaves);
-		
-			ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-			for (it = leaves.begin(); it != it_end; ++ it)
-			{
-				vm->mViewCells.push_back(*it);
-			}
-		}
-
-		vm->mViewCellsFinished = true;
-		vm->mMaxPvsSize = (int)objects->size();
-
-		
-		if (finalizeViewCells)
-		{
-			// create the meshes and compute volumes
-			const bool createMeshes = true;
-			//const bool createMeshes = false;
-
-			vm->FinalizeViewCells(createMeshes);
-		}
-
-		cout << (int)vm->mViewCells.size() << " view cells loaded in "
-			 << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
-
-		Debug << (int)vm->mViewCells.size() << " view cells loaded in "
-			  << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
-	}
-	else
+	const bool success = parser.ParseViewCellsFile(filename, 
+												   &vm, 
+												   pvsObjects, 
+												   preprocessorObjects, 
+												   bconverter);
+
+	if (!success)
 	{
 		Debug << "Error: loading view cells failed!" << endl;
 		DEL_PTR(vm);
-	}
-
+
+		return NULL;
+	}
+	
+	//cout << "viewcells parsed " <<endl;
+
+	if (0)
+	{
+		vm->ResetViewCells();
+	}
+	else
+	{
+		//hack: should work with reset function
+		ViewCellContainer leaves;
+
+		vm->mViewCells.clear();
+		vm->mViewCellsTree->CollectLeaves(vm->mViewCellsTree->GetRoot(), leaves);
+		
+		ViewCellContainer::const_iterator it, it_end = leaves.end();
+
+		for (it = leaves.begin(); it != it_end; ++ it)
+		{
+			vm->mViewCells.push_back(*it);
+		}
+	}
+
+	vm->mViewCellsFinished = true;
+	vm->mMaxPvsSize = (int)pvsObjects.size();
+
+	if (finalizeViewCells)
+	{
+		// create the meshes and compute volumes
+		const bool createMeshes = true;
+		//const bool createMeshes = false;
+
+		vm->FinalizeViewCells(createMeshes);
+	}
+
+	cout << (int)vm->mViewCells.size() << " view cells loaded in "
+		 << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
+
+	Debug << (int)vm->mViewCells.size() << " view cells loaded in "
+		  << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
+	
 	return vm;
 }
@@ -6781,19 +6785,6 @@
 
 
-ViewCellsManager *VspOspViewCellsManager::LoadViewCells(const string &filename, 
-														ObjectContainer *objects,
-														const bool finalizeViewCells,
-														BoundingBoxConverter *bconverter)
-												 
-{
-	ViewCellsManager *vm = 
-		ViewCellsManager::LoadViewCells(filename, objects, finalizeViewCells, bconverter);
-
-	return vm;
-}
-
-
-void
-VspOspViewCellsManager::CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects)
+void VspOspViewCellsManager::CollectObjects(const AxisAlignedBox3 &box, 
+											ObjectContainer &objects)
 {
 	mHierarchyManager->CollectObjects(box, objects);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2066)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2113)
@@ -413,5 +413,5 @@
 
   void GetBoxIntersections(const AxisAlignedBox3 &box, 
-						  vector<KdLeaf *> &leaves);
+						   vector<KdLeaf *> &leaves);
 
   int
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParserXerces.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParserXerces.h	(revision 2113)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParserXerces.h	(revision 2113)
@@ -0,0 +1,263 @@
+#ifndef _X3D_PARSER_XERCES__H
+#define _X3D_PARSER_XERCES__H
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <xercesc/sax/HandlerBase.hpp>
+#include "Mesh.h"
+#include "BoundingBoxConverter.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+XERCES_CPP_NAMESPACE_USE
+XERCES_CPP_NAMESPACE_BEGIN
+class AttributeList;
+XERCES_CPP_NAMESPACE_END
+
+class VspBspTree;
+class BspTree;
+class ViewCellsManager;
+class ViewCellsTree;
+class VspTree;
+class OspTree;
+class VspNode;
+class BvhNode;
+class BvHierarchy;
+class HierarchyManager;
+
+
+class ViewCellsParseHandlers: public HandlerBase
+{
+public:
+  // -----------------------------------------------------------------------
+  //  Constructors and Destructor
+  // -----------------------------------------------------------------------
+  ViewCellsParseHandlers(ObjectContainer &pvsObjects, 
+						 ObjectContainer &preprocessorObjects, 
+						 BoundingBoxConverter *bconverter);
+  ~ViewCellsParseHandlers();
+  
+  
+  // -----------------------------------------------------------------------
+  //  Getter methods
+  // -----------------------------------------------------------------------
+  unsigned int GetElementCount()
+  {
+    return mElementCount;
+  }
+  
+  unsigned int GetAttrCount()
+  {
+    return mAttrCount;
+  }
+  
+  unsigned int GetCharacterCount()
+  {
+    return mCharacterCount;
+  }
+  
+  unsigned int GetSpaceCount()
+  {
+    return mSpaceCount;
+  }
+
+
+  // -----------------------------------------------------------------------
+  //  Handlers for the SAX DocumentHandler interface
+  // -----------------------------------------------------------------------
+  void endElement(const XMLCh* const name);
+  void startElement(const XMLCh* const name, AttributeList& attributes);
+  void characters(const XMLCh* const chars, const unsigned int length);
+  void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
+  void resetDocument();
+
+  void CreateViewCellsManager(/*const char *name*/);
+
+  void ReplacePvs();
+  void ReplaceBvhPvs(ViewCell *vc);
+
+
+  /////////////////////////
+
+  VspBspTree *mVspBspTree;
+  HierarchyManager *mHierarchyManager;
+ 
+  BspTree *mBspTree;
+  ViewCellsTree *mViewCellsTree;
+  VspTree *mVspTree;
+
+  BspNode *mCurrentBspNode;
+  BvhNode *mCurrentBvhNode;
+  KdNode *mCurrentOspNode;
+  VspNode *mCurrentVspNode;
+ 
+  ViewCell *mCurrentViewCell;
+    
+  BspNode *mBspRoot;
+  VspNode *mVspRoot;
+  ViewCell *mViewCellRoot;
+  
+  int mUniqueObjectId;
+  vector<BvhLeaf *> mBvhLeaves;
+  //typedef map<int, ViewCell *> ViewCellsMap;
+  //ViewCellsMap mViewCells;
+  ViewCellContainer mViewCells;
+
+  ViewCellsManager *mViewCellsManager;
+
+  ObjectContainer &mPvsObjects;
+  ObjectContainer &mPreprocessorObjects;
+
+  bool mCreatePvsObjects;
+
+  BoundingBoxConverter *mBoundingBoxConverter;
+  AxisAlignedBox3 mViewSpaceBox;
+  IndexedBoundingBoxContainer mIBoundingBoxes;
+ 
+  /// current state of the parser
+  int mCurrentState;
+  
+  enum {
+	  PARSE_OPTIONS, 
+	  PARSE_VIEWCELLS, 
+	  PARSE_VIEWSPACE_HIERARCHY, 
+	  PARSE_OBJECTSPACE_HIERARCHY};
+
+  /// view space / object space hierarchy types
+  enum {BSP, VSP, OSP, BVH};
+
+  int mViewSpaceHierarchyType;
+  int mObjectSpaceHierarchyType;
+  int nViewCells;
+  int nObjects;
+  
+  
+  ////////////////////////////////
+
+
+  // Handlers for X3D
+  
+  void StartBspLeaf(AttributeList& attributes);
+  void StartBspInterior(AttributeList& attributes);
+  void EndBspInterior();
+
+  void StartVspLeaf(AttributeList& attributes);
+  void StartVspInterior(AttributeList& attributes);
+  void EndVspInterior();
+
+  void StartViewCellPvs(ObjectPvs &pvs, const char *ptr);
+
+  void EndViewCells();
+  void EndBoundingBoxes();
+
+  void StartBspElement(string element, AttributeList& attributes);
+  void StartVspElement(string element, AttributeList& attributes);
+
+  void StartViewSpaceHierarchy(AttributeList& attributes);
+  void StartObjectSpaceHierarchy(AttributeList& attributes);
+
+  void StartBoundingBox(AttributeList& attributes);
+  void StartViewCell(AttributeList& attributes, const bool isLeaf);
+  void EndViewCellInterior();
+
+  void StartViewSpaceHierarchyElement(const std::string &element, AttributeList& attributes);
+  void StartObjectSpaceHierarchyElement(const std::string &element, AttributeList& attributes);
+  void StartViewCellHierarchyElement(const std::string &element, AttributeList& attributes);
+
+  void StartOspElement(string element, AttributeList& attributes);
+
+  void StartOspLeaf(AttributeList& attributes);
+  void StartOspInterior(AttributeList& attributes);
+
+  void CreateViewSpaceHierarchy();
+
+  void StartBvhLeaf(AttributeList& attributes);
+  void StartBvhInterior(AttributeList& attributes);
+  void StartBvhElement(string element, AttributeList& attributes);
+
+  void EndViewSpaceHierarchyInterior();
+  void EndObjectSpaceHierarchyInterior();
+
+  void EndBvhInterior();
+  void EndOspInterior();
+
+  void EndObjectSpaceHierarchy();
+
+  void StartBvhLeafObjects(ObjectContainer &objects, const char *ptr);
+
+  // -----------------------------------------------------------------------
+  //  Handlers for the SAX ErrorHandler interface
+  // -----------------------------------------------------------------------
+
+  void warning(const SAXParseException& exc);
+  void error(const SAXParseException& exc);
+  void fatalError(const SAXParseException& exc);
+  
+  
+private:
+  // -----------------------------------------------------------------------
+  //  Private data members
+  //
+  //  fAttrCount
+  //  fCharacterCount
+  //  fElementCount
+  //  fSpaceCount
+  //      These are just counters that are run upwards based on the input
+  //      from the document handlers.
+  // -----------------------------------------------------------------------
+  unsigned int    mAttrCount;
+  unsigned int    mCharacterCount;
+  unsigned int    mElementCount;
+  unsigned int    mSpaceCount;
+};
+
+// ---------------------------------------------------------------------------
+//  This is a simple class that lets us do easy (though not terribly efficient)
+//  trancoding of XMLCh data to local code page for display.
+// ---------------------------------------------------------------------------
+class StrX
+{
+public :
+  // -----------------------------------------------------------------------
+  //  Constructors and Destructor
+  // -----------------------------------------------------------------------
+  StrX(const XMLCh* const toTranscode)
+  {
+	  // Call the private transcoding method
+	  mLocalForm = XMLString::transcode(toTranscode);
+  }
+  
+  ~StrX()
+  {
+	  XMLString::release(&mLocalForm);
+  }
+  
+  // -----------------------------------------------------------------------
+  //  Getter methods
+  // -----------------------------------------------------------------------
+  const char* LocalForm() const
+  {
+    return mLocalForm;
+  }
+  
+private :
+  // -----------------------------------------------------------------------
+  //  Private data members
+  //
+  //  fLocalForm
+  //      This is the local code page form of the string.
+  // -----------------------------------------------------------------------
+  char*   mLocalForm;
+};
+
+inline XERCES_STD_QUALIFIER ostream&
+operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)
+{
+  target << toDump.LocalForm();
+  return target;
+}
+}
+
+#endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 2066)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 2113)
@@ -56,4 +56,5 @@
 		 DUMMY_INTERSECTABLE,
 		 ENGINE_INTERSECTABLE,
+		 CONTAINER_INTERSECTABLE
 		};
   
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 2093)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 2113)
@@ -35,5 +35,7 @@
   //  Constructors and Destructor
   // -----------------------------------------------------------------------
-  ViewCellsParseHandlers(ObjectContainer *objects, BoundingBoxConverter *bconverter);
+  ViewCellsParseHandlers(ObjectContainer &pvsObjects, 
+						 ObjectContainer &preprocessorObjects, 
+						 BoundingBoxConverter *bconverter);
   ~ViewCellsParseHandlers();
   
@@ -74,6 +76,6 @@
   void CreateViewCellsManager(/*const char *name*/);
 
-  void ExchangeElements();
-  void ExchangePvs(ViewCell *vc);
+  void ReplacePvs();
+  void ReplaceBvhPvs(ViewCell *vc);
 
 
@@ -97,5 +99,6 @@
   VspNode *mVspRoot;
   ViewCell *mViewCellRoot;
-int mUniqueObjectId;
+  
+  int mUniqueObjectId;
   vector<BvhLeaf *> mBvhLeaves;
   //typedef map<int, ViewCell *> ViewCellsMap;
@@ -104,5 +107,10 @@
 
   ViewCellsManager *mViewCellsManager;
-  ObjectContainer *mObjects;
+
+  ObjectContainer &mPvsObjects;
+  ObjectContainer &mPreprocessorObjects;
+
+  bool mCreatePvsObjects;
+
   BoundingBoxConverter *mBoundingBoxConverter;
   AxisAlignedBox3 mViewSpaceBox;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp	(revision 2113)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp	(revision 2113)
@@ -0,0 +1,1548 @@
+// ---------------------------------------------------------------------------
+//  Includes for all the program files to see
+// ---------------------------------------------------------------------------
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+//#include <ext/algorithm>
+
+using namespace std;
+#include <xercesc/util/PlatformUtils.hpp>
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <xercesc/framework/StdInInputSource.hpp>
+#include <xercesc/parsers/SAXParser.hpp>
+#include <xercesc/util/OutOfMemoryException.hpp>
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <xercesc/sax/AttributeList.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax/SAXException.hpp>
+
+#include "ViewCellsParser.h"
+
+#include "ViewCellsParserXerces.h"
+#include "Mesh.h"
+#include "VspBspTree.h"
+#include "ViewCellBsp.h"
+#include "ViewCellsManager.h"
+#include "GzFileInputSource.h"
+#include "OspTree.h"
+#include "VspTree.h"
+#include "KdTree.h"
+#include "BvHierarchy.h"
+#include "HierarchyManager.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+
+// ---------------------------------------------------------------------------
+//  Local data
+//
+//  doNamespaces
+//      Indicates whether namespace processing should be enabled or not.
+//      The default is no, but -n overrides that.
+//
+//  doSchema
+//      Indicates whether schema processing should be enabled or not.
+//      The default is no, but -s overrides that.
+//
+//  schemaFullChecking
+//      Indicates whether full schema constraint checking should be enabled or not.
+//      The default is no, but -s overrides that.
+//
+//  valScheme
+//      Indicates what validation scheme to use. It defaults to 'auto', but
+//      can be set via the -v= command.
+// ---------------------------------------------------------------------------
+static bool     doNamespaces       = false;
+static bool     doSchema           = false;
+static bool     schemaFullChecking = false;
+static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
+
+// hack for loading bvh nodes
+#define PVS_HACK 0
+
+inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
+{
+	return obj1->mId < obj2->mId;
+}
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Constructors and Destructor
+// ---------------------------------------------------------------------------
+ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer &pvsObjects, 
+											   ObjectContainer &preprocessorObjects,
+											   BoundingBoxConverter *bconverter
+											   ):
+  mElementCount(0)
+  , mAttrCount(0)
+  , mCharacterCount(0)
+  , mSpaceCount(0)
+  , mViewCellsManager(NULL)
+  , mVspBspTree(NULL)
+  , mBspTree(NULL)
+  , mViewCellsTree(NULL)
+  , mCurrentState(PARSE_OPTIONS)
+  , mCurrentViewCell(NULL)
+  , mCurrentBspNode(NULL)
+  , mCurrentVspNode(NULL)
+  , mCurrentOspNode(NULL)
+  , mCurrentBvhNode(NULL)
+  , mPvsObjects(pvsObjects)
+  , mPreprocessorObjects(preprocessorObjects)
+  , mBoundingBoxConverter(bconverter)
+  , mHierarchyManager(NULL)
+  , nViewCells(0)
+  , nObjects(0)
+{
+	mCreatePvsObjects = mPvsObjects.empty();
+
+	// sort objects so we can search in them
+	//if (!is_sorted(mPvsObjects.begin(), mPvsObjects.end(), ilt))
+		sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
+
+	//if (!is_sorted(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt))
+		sort(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt);
+}
+
+
+ViewCellsParseHandlers::~ViewCellsParseHandlers()
+{
+}
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
+// ---------------------------------------------------------------------------
+
+
+void ViewCellsParseHandlers::endElement(const XMLCh* const name)
+{
+	StrX lname(name);
+	string element(lname.LocalForm());
+
+	if (element == "BoundingBoxes")
+	{
+		EndBoundingBoxes();
+	}
+
+	if (element == "ViewCells")
+	{	
+		EndViewCells();
+	}
+
+	if (element == "ObjectSpaceHierarchy")
+	{
+		EndObjectSpaceHierarchy();
+	}
+
+	// finished, create view cells manager
+	if (element == "VisibilitySolution")
+	{
+		CreateViewCellsManager();
+	}
+
+	if (element == "Interior")
+	{
+		switch (mCurrentState)
+		{
+		case PARSE_VIEWCELLS:
+			EndViewCellInterior();
+			break;
+		case PARSE_OBJECTSPACE_HIERARCHY:
+			EndObjectSpaceHierarchyInterior();
+			break;
+		case PARSE_VIEWSPACE_HIERARCHY:	
+			EndViewSpaceHierarchyInterior();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
+{
+	if (mObjectSpaceHierarchyType == OSP)
+	{
+		// for a spatial subdivision, it is not necessary to store
+		// the objects with the leaves, they can be classified geometrically
+		mHierarchyManager->mOspTree->
+			InsertObjects(mHierarchyManager->mOspTree->mRoot, mPvsObjects);
+	}
+}
+
+
+void ViewCellsParseHandlers::EndViewSpaceHierarchyInterior()
+{
+	switch (mViewSpaceHierarchyType)
+	{
+	case BSP:
+		EndBspInterior();
+		break;
+	case VSP:
+		EndVspInterior();
+		break;	
+	default:
+		Debug << "not implemented view space hierarchy type " << mViewSpaceHierarchyType << endl;
+		break;
+	}
+}
+
+
+void ViewCellsParseHandlers::EndObjectSpaceHierarchyInterior()
+{
+	switch (mObjectSpaceHierarchyType)
+	{
+	case OSP:
+		EndOspInterior();
+		break;
+	case BVH:
+		EndBvhInterior();
+		break;	
+	default:
+		Debug << "not implemented object space hierarchy type " << mViewSpaceHierarchyType << endl;
+		break;
+	}
+}
+
+
+void ViewCellsParseHandlers::EndBspInterior()
+{
+	// go one up in the tree
+	if (mCurrentBspNode->GetParent())
+	{	//cout << "]";
+		mCurrentBspNode = mCurrentBspNode->GetParent();
+	}
+}
+
+
+void ViewCellsParseHandlers::EndBvhInterior()
+{
+	// go one up in the tree
+	if (mCurrentBvhNode->GetParent())
+	{	//cout << "]";
+		mCurrentBvhNode = mCurrentBvhNode->GetParent();
+	}
+}
+
+
+void ViewCellsParseHandlers::EndOspInterior()
+{
+	// go one up in the tree
+	if (mCurrentOspNode->mParent)
+	{	
+		//cout << "]";
+		mCurrentOspNode = mCurrentOspNode->mParent;
+	}
+}
+
+
+void ViewCellsParseHandlers::EndVspInterior()
+{
+	// go one up in the tree
+	if (mCurrentVspNode->GetParent())
+	{	
+		//cout << "]";
+		mCurrentVspNode = mCurrentVspNode->GetParent();
+	}
+}
+
+
+void ViewCellsParseHandlers::EndViewCellInterior()
+{
+	// go one up in the tree
+	if (mCurrentViewCell->GetParent())
+	{	
+		//cout << "]";
+		mCurrentViewCell = mCurrentViewCell->GetParent();
+	}
+}
+
+
+inline static bool vlt(ViewCell *v1, ViewCell *v2)
+{
+	return v1->mId < v2->mId;
+}
+
+
+void ViewCellsParseHandlers::EndViewCells()
+{
+	// sort view cells to help associating view cells according to their id
+	stable_sort(mViewCells.begin(), mViewCells.end(), vlt);
+
+	// not parsing view cells anymore
+	mCurrentState = PARSE_OPTIONS;
+}
+
+
+void ViewCellsParseHandlers::EndBoundingBoxes()
+{
+	// all bounding boxes gathered in this step => 
+	// associate object ids with bounding boxes
+	const long startTime = GetTime();
+	
+	if (mBoundingBoxConverter)
+	{
+		mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, mPvsObjects);
+	}
+
+	Debug << "\nconverted bounding boxes to objects in "
+		  << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+}
+
+
+void ViewCellsParseHandlers::StartBspElement(string element,
+											 AttributeList& attributes)
+{
+	if (element == "Interior") 
+	{
+		//cout << "[";
+		StartBspInterior(attributes);
+	}
+
+	if (element == "Leaf") 
+	{
+		//cout << "l";
+		StartBspLeaf(attributes);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartVspElement(string element,
+											 AttributeList& attributes)
+{
+	if (element == "Interior") 
+	{
+		//cout << "[";
+		StartVspInterior(attributes);
+	}
+	if (element == "Leaf") 
+	{
+		//cout << "l";
+		StartVspLeaf(attributes);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartOspElement(string element,
+											 AttributeList& attributes)
+{
+	if (element == "Interior") 
+	{
+		//cout << "[";
+		StartOspInterior(attributes);
+	}
+
+	if (element == "Leaf") 
+	{
+		//cout << "l";
+		StartOspLeaf(attributes);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhElement(string element,
+											 AttributeList& attributes)
+{
+	if (element == "Interior") 
+	{
+		//cout << "[";
+		StartBvhInterior(attributes);
+	}
+
+	if (element == "Leaf") 
+	{
+		//cout << "l";
+		StartBvhLeaf(attributes);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartViewSpaceHierarchyElement(const std::string &element,
+															AttributeList& attributes)
+{
+	//-- use cell type according to the chosen method
+	switch (mViewSpaceHierarchyType)
+	{
+	case BSP:
+		StartBspElement(element, attributes);
+		break;
+	case VSP:
+		StartVspElement(element, attributes);
+		break;
+	default:
+		Debug << "not implemented" << endl;
+		break;
+	}
+}
+
+
+void ViewCellsParseHandlers::StartObjectSpaceHierarchyElement(const std::string &element,
+															  AttributeList& attributes)
+{
+	//-- use cell type according to the chosen method
+	switch (mObjectSpaceHierarchyType)
+	{
+		case OSP:
+			StartOspElement(element, attributes);
+			break;
+		case BVH:
+			StartBvhElement(element, attributes);
+			break;
+		default:
+			Debug << "not implemented" << endl;
+			break;
+	}
+}
+
+
+void ViewCellsParseHandlers::ReplaceBvhPvs(ViewCell *vc)
+{
+	//cout << "exchanging pvs" << endl;
+	ObjectPvs newPvs;
+
+	ObjectPvsIterator pit = vc->GetPvs().GetIterator();
+
+	BvhLeaf *dummyInst = new BvhLeaf(AxisAlignedBox3());
+
+	ObjectContainer oldIntersectables;
+
+	// output PVS of view cell
+	while (pit.HasMoreEntries())
+	{		
+		ObjectPvsEntry entry = pit.Next();
+
+		Intersectable *intersect = entry.mObject;
+		oldIntersectables.push_back(intersect);
+
+		DummyIntersectable *dummyIntersect = static_cast<DummyIntersectable *>(intersect);
+
+		const int objId = dummyIntersect->GetItem();	
+		dummyInst->SetId(objId);
+
+		vector<BvhLeaf *>::iterator oit =
+			lower_bound(mBvhLeaves.begin(), 
+						mBvhLeaves.end(), 
+						dummyInst, ilt);	
+
+		if ((oit != mBvhLeaves.end()) && ((*oit)->GetId() == objId))
+		{
+			// $$JB we should store a float a per object which corresponds
+			// to sumof pdfs, i.e. its relative visibility
+			// temporarily set to 1.0f
+			//cout << (*oit)->GetId() << " ";
+			
+			newPvs.AddSample(*oit, 1.0f);
+		}
+		else
+		{
+			Debug << "exchangePvs error: object with id " << objId << " does not exist" << endl;
+		}
+	}
+
+	//newPvs.SimpleSort();
+	delete dummyInst;
+	vc->SetPvs(newPvs);
+
+	CLEAR_CONTAINER(oldIntersectables);
+}
+
+
+void ViewCellsParseHandlers::ExchangeElements()
+{
+	ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();
+	
+	sort(mBvhLeaves.begin(), mBvhLeaves.end(), ilt);
+
+	//cout << "viewcells : " << mViewCells.size() << endl;
+	for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		ReplaceBvhPvs(*vit);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartViewCellHierarchyElement(const std::string &element,
+														   AttributeList& attributes)
+{
+	// interiors + leaves interpreted view cells else
+	if (element == "Interior") 
+	{
+		//cout << "[";
+		StartViewCell(attributes, false);
+	}
+
+	if (element == "Leaf") 
+	{
+		//cout << "l";
+		StartViewCell(attributes, true);
+	}
+}
+
+
+void ViewCellsParseHandlers::startElement(const XMLCh* const name,
+										  AttributeList& attributes)
+{
+	StrX lname(name);
+	string element(lname.LocalForm());
+
+	if (element == "ViewCells")
+	{
+		cout << "\nparsing view cells" << endl;
+		Debug << "\nparsing view cells" << endl;
+		
+		mCurrentState = PARSE_VIEWCELLS;
+
+		// create new view cells hierarchy
+		mViewCellsTree = new ViewCellsTree();
+	}
+
+	// decides about the view cell hierarchy
+	if (element == "ViewSpaceHierarchy")
+	{		
+		Debug << "\nparsing view space hierarchy" << endl;
+		cout << "\nparsing view space hierarchy" << endl;
+		mCurrentState = PARSE_VIEWSPACE_HIERARCHY;
+		StartViewSpaceHierarchy(attributes);
+	}
+
+	// decides about the view cell hierarchy
+	if (element == "ObjectSpaceHierarchy")
+	{
+		cout << "\nparsing object space hierarchy" << endl;
+		Debug << "\nparsing object space hierarchy" << endl;
+
+		mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
+		StartObjectSpaceHierarchy(attributes);
+	}
+	
+	// decides the used view cell hierarchy
+	if (element == "BoundingBox")
+	{
+		// cout << "b";
+		StartBoundingBox(attributes);
+	}
+
+	// parse view space hierarchy
+	switch (mCurrentState)
+	{
+	case PARSE_VIEWSPACE_HIERARCHY:
+		if ((++ nViewCells % 1000) == 0)
+			cout<<"\r"<<nViewCells<<" view cells parsed\r";
+		
+		StartViewSpaceHierarchyElement(element, attributes);
+		break;
+	case PARSE_OBJECTSPACE_HIERARCHY:
+		if ((++ nObjects % 1000) == 0)
+		 cout<<"\r"<< nObjects <<" objects parsed\r";
+		
+		StartObjectSpaceHierarchyElement(element, attributes);
+		break;
+	case PARSE_VIEWCELLS:
+		StartViewCellHierarchyElement(element, attributes);
+		break;
+	default:
+		break;
+	}
+	
+	++ mElementCount;
+	mAttrCount += attributes.getLength();
+}
+
+
+void ViewCellsParseHandlers::StartViewCellPvs(ObjectPvs &pvs, const char *ptr)
+{
+	// handle obect indices
+	vector<int> objIndices;
+	char *endptr;
+			
+	while (1)
+	{	// read object ids
+		const int index = strtol(ptr, &endptr, 10);
+		if (ptr == endptr) 
+			break;
+		objIndices.push_back(index);
+		ptr = endptr;
+	}
+
+	// TODO: 
+	// 1) find objects and add them to pvs
+	// 2) get view cell with specified id
+	MeshInstance dummyInst(NULL);
+
+	vector<int>::const_iterator it, it_end = objIndices.end();
+	for (it = objIndices.begin(); it != it_end; ++ it)
+	{
+#if PVS_HACK
+		//cout << "u";
+		pvs.AddSample(new DummyIntersectable(*it), 1);
+#else
+		const int objId = *it;	
+		dummyInst.SetId(objId);
+
+		ObjectContainer::iterator oit =	
+								lower_bound(mPvsObjects.begin(), 
+											mPvsObjects.end(), 
+											(Intersectable *)&dummyInst, ilt);	
+
+		if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
+		{
+			// $$JB we should store a float a per object which corresponds
+			// to sumof pdfs, i.e. its relative visibility
+			// temporarily set to 1.0f
+			pvs.AddSample(*oit, 1.0f);
+			//Debug << "y";
+		}
+		else
+		{
+			Debug << "x";
+			//Debug << "StartViewCellPvs error: object with id " << objId << " does not exist" << endl;
+		}
+#endif
+	}
+}
+
+
+void ViewCellsParseHandlers::StartViewSpaceHierarchy(AttributeList& attributes)
+{
+	int len = attributes.getLength();
+
+	Vector3 bmin, bmax;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		// hierarchy type
+		if (attrName == "type")
+		{
+			if (strcmp(ptr, "bsp") == 0)
+			{
+				Debug << "\nview space hierarchy: Bsp" << endl;
+				mViewSpaceHierarchyType = BSP;
+			}
+			else if (strcmp(ptr, "vsp") == 0)
+			{
+				Debug << "\nview space hierarchy: Vsp" << endl;
+				mViewSpaceHierarchyType = VSP;
+			}
+		}
+		else if (attrName == "min") // the view space extent
+		{
+			sscanf(ptr, "%f %f %f",
+				   &bmin.x, &bmin.y, &bmin.z);
+		}
+		else if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f",
+				   &bmax.x, &bmax.y, &bmax.z);
+		}
+	}
+
+	mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
+
+	// create the hierarchy based on this information
+	CreateViewSpaceHierarchy();
+}
+
+
+void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
+{
+	const int len = attributes.getLength();
+	Vector3 bmin, bmax;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		// hierarchy type
+		if (attrName == "type")
+		{
+			if (strcmp(ptr, "osp") == 0)
+			{
+				Debug << "\nobject space hierarchy: Osp" << endl;
+
+				mHierarchyManager = 
+					new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
+
+				DEL_PTR(mHierarchyManager->mVspTree);
+				mHierarchyManager->mVspTree = mVspTree;
+
+				mObjectSpaceHierarchyType = OSP;
+
+				//std::stable_sort(objects.begin(), objects.end(), ilt);
+				mHierarchyManager->mOspTree->mBoundingBox.Initialize();
+				ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
+				
+				//-- compute bounding box
+				for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
+				{
+					Intersectable *obj = *oit;
+					// compute bounding box of view space
+					mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
+				}
+			}
+			else if (strcmp(ptr, "bvh") == 0)
+			{
+				Debug << "\nobject space hierarchy: Bvh" << endl;
+				mObjectSpaceHierarchyType = BVH;
+				mHierarchyManager = 
+					new HierarchyManager(HierarchyManager::BV_BASED_OBJ_SUBDIV);
+
+				DEL_PTR(mHierarchyManager->mVspTree);
+				mHierarchyManager->mVspTree = mVspTree;
+			}
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
+{
+	int len = attributes.getLength();
+
+	Vector3 bmin, bmax;
+	int id;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "id")
+		{
+			sscanf(ptr, "%d", &id);
+		}
+		if (attrName == "min") 
+		{
+			sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
+		}
+		else if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
+		}
+	}
+
+	AxisAlignedBox3 box(bmin, bmax);
+	mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
+	//Debug << "bbox: " << box << endl;
+}
+
+
+void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
+{
+	BspLeaf * leaf;
+
+	if (mCurrentBspNode) // replace front or (if not NULL) back child
+	{
+		BspInterior *interior = static_cast<BspInterior *>(mCurrentBspNode);
+
+		leaf = new BspLeaf(interior);
+		interior->ReplaceChildLink(NULL, leaf);
+	}
+	else
+	{
+		leaf = new BspLeaf();
+		mVspBspTree->mRoot = leaf;
+	}
+
+	///////////
+	//-- find associated view cell
+
+	int viewCellId;
+	const int len = attributes.getLength();
+	  
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+
+		const char *ptr = attrValue.LocalForm();
+		char *endptr = NULL;
+
+		if (attrName == "viewCellId") 
+		{
+			viewCellId = strtol(ptr, &endptr, 10);
+		}
+	}
+	
+	if (viewCellId >= 0) // valid view cell found
+	{
+		// TODO: get view cell with specified id
+		ViewCellInterior dummyVc;
+		dummyVc.SetId(viewCellId);
+
+		ViewCellContainer::iterator vit =
+			lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
+		
+		//ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
+//		BspViewCell *viewCell = static_cast<BspViewCell *>((*vit).second);
+
+		BspViewCell *viewCell = static_cast<BspViewCell *>(*vit);
+		if (viewCell->GetId() == viewCellId)
+		{
+			// create new view cell for bsp nodes
+			leaf->SetViewCell(viewCell);
+			viewCell->mLeaves.push_back(leaf);
+		}
+		else
+		{
+			cerr << "error: view cell does not exist" << endl;
+		}
+	}
+	else
+	{
+		// add to invalid view space
+		leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
+		leaf->SetTreeValid(false);
+		mVspBspTree->PropagateUpValidity(leaf);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
+{
+	Plane3 plane;
+	int len = attributes.getLength();
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "plane") 
+		{
+			sscanf(ptr, "%f %f %f %f",
+				   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
+		}
+	}
+
+	BspInterior* interior = new BspInterior(plane);
+	
+	if (mCurrentBspNode) // replace NULL child of parent with current node
+	{
+		BspInterior *parent = static_cast<BspInterior *>(mCurrentBspNode);
+
+		parent->ReplaceChildLink(NULL, interior);
+		interior->SetParent(parent);
+	}
+	else
+	{
+		mVspBspTree->mRoot = interior;
+	}
+
+	mCurrentBspNode = interior;
+}
+
+
+void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf)
+{
+	ViewCell *viewCell = NULL;
+	
+	const int len = attributes.getLength();
+	float mergeCost;
+	
+	if (isLeaf)
+	{
+		viewCell = new ViewCellLeaf();
+	}
+	else
+	{
+		viewCell = new ViewCellInterior();
+	}
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		const string attrName(StrX(attributes.getName(i)).LocalForm());
+	
+		if (attrName == "id") 
+		{
+			const StrX attrValue(attributes.getValue(i));
+			const char *ptr = attrValue.LocalForm();
+			char *endptr = NULL;
+			const int id = strtol(ptr, &endptr, 10);
+
+			// create new view cell, otherwise use reference.
+			viewCell->SetId(id);
+
+			if (mCurrentViewCell) // replace front or (if not NULL) back child
+			{	
+				ViewCellInterior *interior = 
+					static_cast<ViewCellInterior *>(mCurrentViewCell);
+				interior->SetupChildLink(viewCell);
+			}
+			else 
+			{	// set the new root
+				mViewCellsTree->SetRoot(viewCell);
+			}
+			
+			if (!isLeaf)
+			{
+				mCurrentViewCell = viewCell;
+			}
+		}
+		if (attrName == "pvs") 
+		{
+			StrX attrValue(attributes.getValue(i));
+			const char *ptr = attrValue.LocalForm();
+
+			// note: id must come before pvs! 
+			// otherwise view cell is undefined
+
+			// hack: assume that view cell comes before pvs
+			StartViewCellPvs(viewCell->GetPvs(), ptr); 
+			//StartViewCellPvs(pvs, ptr);
+		}
+		else if (attrName == "active")
+		{
+			StrX attrValue(attributes.getValue(i));
+			const char *ptr = attrValue.LocalForm();
+			char *endptr = NULL;
+			const bool isActive = (bool)strtol(ptr, &endptr, 10);
+
+			if (isActive)
+			{
+				// TODO
+			}
+		}
+		else if (attrName == "mergecost")
+		{
+			StrX attrValue(attributes.getValue(i));
+			
+			const char *ptr = attrValue.LocalForm();
+			char *endptr = NULL;
+			mergeCost = (float)strtod(ptr, &endptr);
+		}
+	}
+
+	viewCell->SetMergeCost(mergeCost);
+	//viewCell->SetPvs(pvs);
+	mViewCells.push_back(viewCell);
+}
+
+
+void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
+{
+	if (mViewSpaceHierarchyType == BSP)
+	{
+		Debug << "hierarchy type: Bsp" << endl;
+		mVspBspTree = new VspBspTree();
+
+		// set view space box
+		mVspBspTree->mBoundingBox = mViewSpaceBox;
+
+		//ViewCellsMap::iterator vit, vit_end = mViewCells.end();
+		ViewCellContainer::iterator vit, vit_end = mViewCells.end();
+
+		int i = 0;
+		// remove view cells and exchange them with the 
+		// view cells specialized for the current hierarchy node type
+		for (vit = mViewCells.begin(); vit != vit_end; ++ vit, ++ i)
+		{
+			//if ((i % 1000) == 0)
+			//	Debug << "\n exchanged " << i << " boxes" << endl;
+			ViewCell *vc = (*vit);
+
+			if (!vc->IsLeaf()) // exchange only leaves
+				continue;
+		
+			BspViewCell *bspVc = new BspViewCell();
+
+			bspVc->SetId(vc->GetId());
+			//bspVc->GetPvs().reserve(vc->GetPvs().size());
+			bspVc->SetPvs(vc->GetPvs());
+
+			if (vc->IsRoot())
+			{
+				mViewCellsTree->mRoot = bspVc;
+			}
+			else
+			{
+                vc->GetParent()->ReplaceChildLink(vc, bspVc);
+			}
+
+			// delete old view cell
+			DEL_PTR(vc);
+
+//			(*vit).second = bspVc;
+			(*vit) = bspVc;
+		}
+		cout << "finished creating view space hierarchy" << endl;
+	}
+	else if (mViewSpaceHierarchyType == VSP) 
+	{
+		Debug << "hierarchy type: Vsp" << endl;
+		mVspTree = new VspTree();
+
+		// set view space box
+		mVspTree->mBoundingBox = mViewSpaceBox;
+
+		// ViewCellsMap::iterator vit, vit_end = mViewCells.end();
+		ViewCellContainer::iterator vit, vit_end = mViewCells.end();
+
+		// reset view cells using the current node type
+		for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			//ViewCell *vc = (*vit).second;
+			ViewCell *vc = (*vit);
+			
+			if (!vc->IsLeaf()) // exchange only leaves
+				continue;
+
+			VspViewCell *vspVc = new VspViewCell();
+
+			vspVc->SetPvs(vc->GetPvs());
+			vspVc->SetId(vc->GetId());
+
+			if (vc->IsRoot())
+			{
+				mViewCellsTree->mRoot = vspVc;
+			}
+			else
+			{
+				vc->GetParent()->ReplaceChildLink(vc, vspVc);
+			}
+			
+			// exchange view cell with new one
+			DEL_PTR(vc);
+
+			//(*vit).second = vspVc;
+			(*vit) = vspVc;
+		}
+
+		if (mHierarchyManager)
+		{
+			// come here only if object space hierarchy already constructed
+			mHierarchyManager->mVspTree = mVspTree;
+			mVspTree->mHierarchyManager = mHierarchyManager;
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::CreateViewCellsManager()
+{
+	if (mViewSpaceHierarchyType == BSP)
+	{
+		Debug << "\ncreating view cells manager: VspBsp" << endl;
+		mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
+	}
+	else if (mViewSpaceHierarchyType == VSP) 
+	{
+		Debug << "\ncreating view cells manager: VspOsp" << endl;
+		mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
+	}
+
+	mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
+}
+
+
+void ViewCellsParseHandlers::characters(const XMLCh* const chars,
+										const unsigned int length)
+{
+	mCharacterCount += length;
+}
+
+
+void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
+												 const unsigned int length)
+{
+	mSpaceCount += length;
+}
+
+
+void ViewCellsParseHandlers::resetDocument()
+{
+	mAttrCount = 0;
+	mCharacterCount = 0;
+	mElementCount = 0;
+	mSpaceCount = 0;
+}
+
+
+void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
+{
+	VspLeaf * leaf;
+		
+	if (mCurrentVspNode) // replace front or (if not NULL) back child
+	{
+		VspInterior *interior = static_cast<VspInterior *>(mCurrentVspNode);
+		leaf = new VspLeaf(interior);
+		interior->ReplaceChildLink(NULL, leaf);
+	}
+	else
+	{
+		leaf = new VspLeaf();
+		mVspTree->mRoot = leaf;
+	}
+
+	/////////////
+	//-- find view cell associated with the id
+
+	int viewCellId;
+	const int len = attributes.getLength();
+	  
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+
+		const char *ptr = attrValue.LocalForm();
+		char *endptr = NULL;
+
+		if (attrName == "viewCellId") 
+		{
+			viewCellId = strtol(ptr, &endptr, 10);
+		}
+	}
+	
+	if (viewCellId >= 0) // valid view cell found
+	{
+		// TODO: get view cell with specified id
+		ViewCellInterior dummyVc;
+		dummyVc.SetId(viewCellId);
+
+		ViewCellContainer::iterator vit =
+			lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
+		
+		//ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
+		if (vit == mViewCells.end())
+			Debug << "error: view cell " << viewCellId << " not found" << endl;
+	
+		//VspViewCell *viewCell = static_cast<VspViewCell *>((*vit).second);
+		VspViewCell *viewCell = static_cast<VspViewCell *>(*vit);
+		
+		if (viewCell->GetId() == viewCellId)
+		{
+			leaf->SetViewCell(viewCell);
+			viewCell->mLeaves.push_back(leaf);
+		}
+		else
+		{
+			Debug << "error: view cell does not exist" << endl;
+		}
+	}
+	else
+	{	
+		// add to invalid view space
+		leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
+		leaf->SetTreeValid(false);
+		mVspTree->PropagateUpValidity(leaf);
+	}
+}
+
+
+void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
+{
+	AxisAlignedPlane plane;
+	const int len = attributes.getLength();
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "plane") 
+		{
+			sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
+		}
+	}
+
+	VspInterior* interior = new VspInterior(plane);
+	
+	if (mCurrentVspNode) // replace NULL child of parent with current node
+	{
+		VspInterior *parent = static_cast<VspInterior *>(mCurrentVspNode);
+
+		parent->ReplaceChildLink(NULL, interior);
+		interior->SetParent(parent);
+		
+		AxisAlignedBox3 frontBox, backBox;
+
+		parent->GetBoundingBox().Split(
+			parent->GetPlane().mAxis, 
+			parent->GetPlane().mPosition, 
+			frontBox, 
+			backBox);
+
+		if (parent->GetFront() == interior)
+			interior->SetBoundingBox(frontBox);
+		else
+			interior->SetBoundingBox(backBox);
+	}
+	else
+	{
+		mVspTree->mRoot = interior;
+		interior->SetBoundingBox(mVspTree->GetBoundingBox());
+	}
+
+	mCurrentVspNode = interior;
+}
+
+
+void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
+{
+	AxisAlignedPlane plane;
+	int len = attributes.getLength();
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "plane") 
+		{
+			sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
+		}
+	}
+
+	KdInterior* interior = new KdInterior(NULL);
+	
+	interior->mAxis = plane.mAxis;
+	interior->mPosition = plane.mPosition;
+
+	if (mCurrentOspNode) // replace NULL child of parent with current node
+	{
+		KdInterior *parent = static_cast<KdInterior *>(mCurrentOspNode);
+		parent->ReplaceChildLink(NULL, interior);
+		interior->mParent = parent;
+
+		AxisAlignedBox3 frontBox, backBox;
+
+		parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
+
+		if (parent->mFront == interior)
+			interior->mBox = frontBox;
+		else
+			interior->mBox = backBox;
+	}
+	else
+	{
+		mHierarchyManager->mOspTree->mRoot = interior;
+		interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
+	}
+
+	mCurrentOspNode = interior;
+}
+
+
+void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
+{
+	KdLeaf * leaf = new KdLeaf(static_cast<KdInterior *>(mCurrentOspNode), NULL);
+
+	if (mCurrentOspNode)
+	{
+		 // replace front or (if not NULL) back child
+		static_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
+	}
+	else
+	{
+		mHierarchyManager->mOspTree->mRoot = leaf;
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
+{
+	const int len = attributes.getLength();
+	Vector3 minBox, maxBox;
+
+	ObjectContainer objects;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "min") 
+		{
+			sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
+		}
+		if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
+		}
+		if (attrName == "objects")
+		{
+			StartBvhLeafObjects(objects, ptr);
+		}
+	}
+
+	AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
+
+	BvhLeaf *leaf;
+
+	if (mCurrentBvhNode) // replace front or (if not NULL) back child
+	{
+		BvhInterior *interior = static_cast<BvhInterior *>(mCurrentBvhNode);
+		leaf = new BvhLeaf(box, interior, (int)objects.size());
+		interior->ReplaceChildLink(NULL, leaf);
+	}
+	else
+	{
+		leaf = new BvhLeaf(box, NULL, (int)objects.size());
+		mHierarchyManager->mBvHierarchy->mRoot = leaf;
+	}
+
+	leaf->mObjects = objects;
+	BvHierarchy::AssociateObjectsWithLeaf(leaf);
+	
+	if (PVS_HACK)
+	{
+		if (0) // Temp matt: should already have right id
+			leaf->SetId((int)mBvhLeaves.size());
+		
+		mBvhLeaves.push_back(leaf);	
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects, 
+												 const char *ptr)
+{
+	vector<int> objIndices;
+	char *endptr;
+			
+	while (1)
+	{
+		const int index = strtol(ptr, &endptr, 10);
+		if (ptr == endptr) break;
+
+		objIndices.push_back(index);
+		ptr = endptr;
+	}
+
+	MeshInstance dummyInst(NULL);
+
+	vector<int>::const_iterator it, it_end = objIndices.end();
+
+	for (it = objIndices.begin(); it != it_end; ++ it)
+	{
+		const int objId = *it;	
+		dummyInst.SetId(objId);
+
+		ObjectContainer::iterator oit =
+			lower_bound(mPvsObjects.begin(), 
+						mPvsObjects.end(), 
+						(Intersectable *)&dummyInst, 
+						ilt);	
+							
+		if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
+		{
+			objects.push_back(*oit);
+			Debug << "x";
+		}
+		else
+		{
+			Debug << "y";
+			//cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
+{
+	const int len = attributes.getLength();
+	Vector3 minBox, maxBox;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "min") 
+		{
+			sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
+		}
+		if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
+		}
+	}
+
+	BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
+
+	if (mCurrentBvhNode) // replace NULL child of parent with current node
+	{
+		BvhInterior *parent = static_cast<BvhInterior *>(mCurrentBvhNode);
+		parent->ReplaceChildLink(NULL, interior);
+		interior->SetParent(parent);
+	}
+	else
+	{
+		mHierarchyManager->mBvHierarchy->mRoot = interior;
+	}
+
+	mCurrentBvhNode = interior;
+}
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
+// ---------------------------------------------------------------------------
+
+
+void
+ViewCellsParseHandlers::error(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+void
+ViewCellsParseHandlers::fatalError(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+void
+ViewCellsParseHandlers::warning(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+
+bool ViewCellsParser::ParseViewCellsFile(const string &filename, 
+										 ViewCellsManager **viewCells,
+										 ObjectContainer &pvsObjects,
+										 ObjectContainer &preprocessorObjects,
+										 BoundingBoxConverter *bconverter)
+{
+  // Initialize the XML4C system
+  try {
+    XMLPlatformUtils::Initialize();
+  }
+  
+  catch (const XMLException& toCatch)
+    {
+      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
+				<< StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
+      return false;
+    }
+
+  //  cout<<"parsing started"<<endl<<flush;
+
+  //
+  //  Create a SAX parser object. Then, according to what we were told on
+  //  the command line, set the options.
+  //
+  SAXParser* parser = new SAXParser;
+  parser->setValidationScheme(valScheme);
+  parser->setDoNamespaces(doNamespaces);
+  parser->setDoSchema(doSchema);
+  parser->setValidationSchemaFullChecking(schemaFullChecking);
+  
+
+  //
+  //  Create our SAX handler object and install it on the parser, as the
+  //  document and error handler. We are responsible for cleaning them
+  //  up, but since its just stack based here, there's nothing special
+  //  to do.
+  //
+  ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
+  parser->setDocumentHandler(&handler);
+  parser->setErrorHandler(&handler);
+  
+  unsigned long duration;
+  int errorCount = 0;
+  // create a faux scope so that 'src' destructor is called before
+  // XMLPlatformUtils::Terminate
+  {
+    //
+    //  Kick off the parse and catch any exceptions. Create a standard
+    //  input input source and tell the parser to parse from that.
+    //
+    //    StdInInputSource src;
+    try
+	{
+	const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
+
+#if USE_GZLIB
+	XMLCh *myFilePath = XMLString::transcode(filename.c_str());
+	
+	GzFileInputSource isource(myFilePath);
+	parser->parse(isource);
+#else
+	parser->parse(filename.c_str());
+
+#endif
+
+	if (1 && PVS_HACK)
+		handler.ExchangeElements();
+
+	const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
+	duration = endMillis - startMillis;
+	errorCount = parser->getErrorCount();
+      }
+    catch (const OutOfMemoryException&)
+      {
+	XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
+	errorCount = 2;
+	return false;
+      }
+    catch (const XMLException& e)
+      {
+			XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
+				  << StrX(e.getMessage())
+				  << "\n" << XERCES_STD_QUALIFIER endl;
+			errorCount = 1;
+			return false;
+      }
+
+    
+    // Print out the stats that we collected and time taken
+    if (!errorCount) {
+		XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
+				<< handler.GetElementCount() << " elems, "
+				<< handler.GetAttrCount() << " attrs, "
+				<< handler.GetSpaceCount() << " spaces, "
+				<< handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
+    }
+  }
+
+  cout<<"parsed - will delete the parser"<<endl<<flush;
+  //
+  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
+  //
+  delete parser;
+  
+  XMLPlatformUtils::Terminate();
+  
+  //-- assign new view cells manager
+  *viewCells = handler.mViewCellsManager;
+  
+  if (errorCount > 0)
+    return false;
+  else
+    return true;
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 2097)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 2113)
@@ -5,4 +5,6 @@
 #include <stdlib.h>
 #include <iostream>
+//#include <ext/algorithm>
+
 using namespace std;
 #include <xercesc/util/PlatformUtils.hpp>
@@ -76,6 +78,8 @@
 //  StdInParseHandlers: Constructors and Destructor
 // ---------------------------------------------------------------------------
-ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer *objects, 
-											   BoundingBoxConverter *bconverter):
+ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer &pvsObjects, 
+											   ObjectContainer &preprocessorObjects,
+											   BoundingBoxConverter *bconverter
+											   ):
   mElementCount(0)
   , mAttrCount(0)
@@ -92,5 +96,6 @@
   , mCurrentOspNode(NULL)
   , mCurrentBvhNode(NULL)
-  , mObjects(objects)
+  , mPvsObjects(pvsObjects)
+  , mPreprocessorObjects(preprocessorObjects)
   , mBoundingBoxConverter(bconverter)
   , mHierarchyManager(NULL)
@@ -98,5 +103,12 @@
   , nObjects(0)
 {
-	std::stable_sort(mObjects->begin(), mObjects->end(), ilt);
+	mCreatePvsObjects = mPvsObjects.empty();
+
+	// sort objects so we can search in them
+	//if (!is_sorted(mPvsObjects.begin(), mPvsObjects.end(), ilt))
+		sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
+
+	//if (!is_sorted(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt))
+		sort(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt);
 }
 
@@ -165,5 +177,5 @@
 		// the objects with the leaves, they can be classified geometrically
 		mHierarchyManager->mOspTree->
-			InsertObjects(mHierarchyManager->mOspTree->mRoot, *mObjects);
+			InsertObjects(mHierarchyManager->mOspTree->mRoot, mPvsObjects);
 	}
 }
@@ -278,8 +290,8 @@
 	// associate object ids with bounding boxes
 	const long startTime = GetTime();
-	Debug<<"here32232"<<endl;
+	
 	if (mBoundingBoxConverter)
-	{Debug<<"here3772"<<endl;
-		mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, *mObjects);
+	{
+		mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, mPvsObjects);
 	}
 
@@ -394,5 +406,5 @@
 
 
-void ViewCellsParseHandlers::ExchangePvs(ViewCell *vc)
+void ViewCellsParseHandlers::ReplaceBvhPvs(ViewCell *vc)
 {
 	//cout << "exchanging pvs" << endl;
@@ -404,4 +416,5 @@
 
 	ObjectContainer oldIntersectables;
+
 	// output PVS of view cell
 	while (pit.HasMoreEntries())
@@ -454,5 +467,5 @@
 	for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
 	{
-		ExchangePvs(*vit);
+		ReplaceBvhPvs(*vit);
 	}
 }
@@ -486,4 +499,5 @@
 	{
 		cout << "\nparsing view cells" << endl;
+		Debug << "\nparsing view cells" << endl;
 		
 		mCurrentState = PARSE_VIEWCELLS;
@@ -496,4 +510,5 @@
 	if (element == "ViewSpaceHierarchy")
 	{		
+		Debug << "\nparsing view space hierarchy" << endl;
 		cout << "\nparsing view space hierarchy" << endl;
 		mCurrentState = PARSE_VIEWSPACE_HIERARCHY;
@@ -505,4 +520,6 @@
 	{
 		cout << "\nparsing object space hierarchy" << endl;
+		Debug << "\nparsing object space hierarchy" << endl;
+
 		mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
 		StartObjectSpaceHierarchy(attributes);
@@ -574,9 +591,9 @@
 
 		ObjectContainer::iterator oit =	
-								lower_bound(mObjects->begin(), 
-											mObjects->end(), 
+								lower_bound(mPvsObjects.begin(), 
+											mPvsObjects.end(), 
 											(Intersectable *)&dummyInst, ilt);	
 
-		if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
+		if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
 		{
 			// $$JB we should store a float a per object which corresponds
@@ -669,8 +686,8 @@
 				//std::stable_sort(objects.begin(), objects.end(), ilt);
 				mHierarchyManager->mOspTree->mBoundingBox.Initialize();
-				ObjectContainer::const_iterator oit, oit_end = mObjects->end();
+				ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
 				
 				//-- compute bounding box
-				for (oit = mObjects->begin(); oit != oit_end; ++ oit)
+				for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
 				{
 					Intersectable *obj = *oit;
@@ -1324,16 +1341,18 @@
 
 		ObjectContainer::iterator oit =
-			lower_bound(mObjects->begin(), 
-						mObjects->end(), 
+			lower_bound(mPvsObjects.begin(), 
+						mPvsObjects.end(), 
 						(Intersectable *)&dummyInst, 
 						ilt);	
 							
-		if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
+		if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
 		{
 			objects.push_back(*oit);
+			Debug << "x";
 		}
 		else
 		{
-			cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
+			Debug << "y";
+			//cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
 		}
 	}
@@ -1412,7 +1431,8 @@
 
 
-bool ViewCellsParser::ParseViewCellsFile(const string filename, 
+bool ViewCellsParser::ParseViewCellsFile(const string &filename, 
 										 ViewCellsManager **viewCells,
-										 ObjectContainer *objects,
+										 ObjectContainer &pvsObjects,
+										 ObjectContainer &preprocessorObjects,
 										 BoundingBoxConverter *bconverter)
 {
@@ -1448,5 +1468,5 @@
   //  to do.
   //
-  ViewCellsParseHandlers handler(objects, bconverter);
+  ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
   parser->setDocumentHandler(&handler);
   parser->setErrorHandler(&handler);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 2069)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 2113)
@@ -10,18 +10,13 @@
 
 
-struct VssRayContainer;
 class KdNode;
-//class BvhNode;
 class BvhLeaf;
 class Ray;
-
+class KdTree;
+struct VssRayContainer;
+struct Triangle3;
 struct Face;
-struct Triangle3;
-
-class KdTree;
-
-
-/**
-	Wrapper used for creating a PVS compliant intersectable.
+
+/** Wrapper used for creating a PVS compliant intersectable.
 */
 template<typename T>
@@ -219,9 +214,11 @@
 
 
+/** Intersectable acting as a proxy.
+*/
 class DummyIntersectable: public IntersectableWrapper<int>
 {
 public:
-  DummyIntersectable(const int item):
-	IntersectableWrapper<int>(item) {}
+	DummyIntersectable(const int item):
+	  IntersectableWrapper<int>(item) {}
 
 	int Type() const
@@ -231,4 +228,25 @@
 };
 
+
+/** Intersectable wrapping is a group of objects.
+*/
+class ContainerIntersectable: public GtpVisibilityPreprocessor::IntersectableWrapper<ObjectContainer *>
+{
+public:
+	ContainerIntersectable(ObjectContainer *item):
+	  IntersectableWrapper<ObjectContainer *>(item) {}
+
+	// hack
+	ContainerIntersectable::~ContainerIntersectable() 
+	{
+		delete mItem;
+	}
+
+	int Type() const
+	{
+		return Intersectable::CONTAINER_INTERSECTABLE;
+	}
+};
+
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.cpp	(revision 2113)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectionBoundingBoxConverter.cpp	(revision 2113)
@@ -0,0 +1,68 @@
+#include "IntersectionBoundingBoxConverter.h"
+#include "KdTree.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+void IntersectionBoundingBoxConverter::FindIntersectingObjects(const AxisAlignedBox3 &box,
+															   ObjectContainer &objects) const
+{
+	vector<KdLeaf *> leaves;
+
+	// find intersecting scene nodes to get candidates for intersection
+    // note: this function has to be provided by scene manager
+	mKdTree->GetBoxIntersections(box, leaves);
+	
+	vector<KdLeaf *>::const_iterator lit, lit_end = leaves.end();
+
+	// loop through the intersected scene nodes
+	for (lit = leaves.begin(); lit != lit_end; ++ lit)
+	{
+		KdLeaf *leaf = *lit;
+
+		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+		// find the objects that intersect the box
+		for (oit = leaf->mObjects.begin(); oit != leaf->mObjects.end(); ++ oit)
+		{
+			Intersectable *obj = *oit;
+
+			// test for intersection (note: function provided of preprocessor)
+			if (Overlap(box, obj->GetBox()))
+			{
+				objects.push_back(obj);
+			}
+		}
+	}
+}
+
+
+bool IntersectionBoundingBoxConverter::IdentifyObjects(
+			const IndexedBoundingBoxContainer &iboxes,
+			ObjectContainer &objects) const
+{
+	GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
+		const_iterator iit, iit_end = iboxes.end();
+  
+	for (iit = iboxes.begin(); iit != iit_end; ++ iit)
+	{
+		const AxisAlignedBox3 box = (*iit).second;
+		
+		ObjectContainer *entryObjects = new ObjectContainer();
+
+		// find all objects that intersect the bounding box
+		FindIntersectingObjects(box, *entryObjects);
+
+		ContainerIntersectable *entry = 
+			new ContainerIntersectable(entryObjects);
+
+		entry->SetId((*iit).first);
+
+		objects.push_back(entry);
+	}
+
+	return true;
+}
+
+
+}
