[ossim-planet] 01/06: Imported Upstream version 1.8.20.3+ds

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sat Jun 4 12:57:19 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository ossim-planet.

commit 743f9befdf0d01bce3d6a0dc44e64b4727f690fe
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Jun 3 23:35:35 2016 +0200

    Imported Upstream version 1.8.20.3+ds
---
 ossimPlanet/AUTHORS.txt                            |    6 +
 ossimPlanet/CMakeLists.txt                         |  122 +
 ossimPlanet/Doxyfile                               | 1541 ++++++++++
 ossimPlanet/GNUmakefile.old                        |   12 +
 ossimPlanet/LICENSE.txt                            |   76 +
 ossimPlanet/Make/cygwin_plugin_def                 |   15 +
 ossimPlanet/Make/dependencies                      |    9 +
 ossimPlanet/Make/distrules                         |   16 +
 ossimPlanet/Make/dolink.sh                         |   66 +
 ossimPlanet/Make/help.sh                           |  155 +
 ossimPlanet/Make/helprules                         |   11 +
 ossimPlanet/Make/instexamplesrc                    |  107 +
 ossimPlanet/Make/instrules                         |  149 +
 ossimPlanet/Make/makedefs                          |  597 ++++
 ossimPlanet/Make/makedirdefs                       |   26 +
 ossimPlanet/Make/makedirrules                      |    6 +
 ossimPlanet/Make/makeinnosetup                     |  152 +
 ossimPlanet/Make/makeirixdist                      |  158 +
 ossimPlanet/Make/makepkg                           |  220 ++
 ossimPlanet/Make/makerpms                          |  200 ++
 ossimPlanet/Make/makerules                         |  199 ++
 ossimPlanet/Make/maketoprule                       |   20 +
 ossimPlanet/Make/versionrules                      |   16 +
 ossimPlanet/README.txt                             |   12 +
 .../apps/ossimplanet-chip/ossimplanet-chip.cpp     |  496 +++
 ossimPlanet/binds.act                              |   26 +
 ossimPlanet/examples/GNUmakefile                   |   11 +
 ossimPlanet/examples/ossimplanetinfo/GNUmakefile   |   20 +
 .../examples/ossimplanetinfo/ossimplanetinfo.cpp   |   93 +
 .../ossimplanetinfo/ossimplanetinfo.vcproj         |  208 ++
 ossimPlanet/examples/ossimplanetklv/GNUmakefile    |   20 +
 .../examples/ossimplanetklv/ossimplanetklv.cpp     |  179 ++
 ossimPlanet/examples/ossimplanettest/GNUmakefile   |   20 +
 .../examples/ossimplanettest/ossimplanettest.cpp   | 1657 ++++++++++
 ossimPlanet/examples/ossimplanetviewer/GNUmakefile |   21 +
 .../examples/ossimplanetviewer/archive_manager.kwl |   36 +
 .../examples/ossimplanetviewer/opvLoadModel.cpp    |  354 +++
 .../examples/ossimplanetviewer/opvLoadModel.h      |    9 +
 .../ossimplanetviewer/ossimplanetviewer.cpp        |  743 +++++
 .../ossimplanetviewer/ossimplanetviewer.vcproj     |  212 ++
 ossimPlanet/examples/ossimplanetviewer/readme.txt  |    9 +
 ossimPlanet/include/ossimPlanet/compiler.h         |  470 +++
 ossimPlanet/include/ossimPlanet/ioapi.h            |   75 +
 ossimPlanet/include/ossimPlanet/iochannel.h        |  180 ++
 ossimPlanet/include/ossimPlanet/iowin32.h          |   21 +
 ossimPlanet/include/ossimPlanet/mkUtils.h          |  332 ++
 ossimPlanet/include/ossimPlanet/net.h              |   12 +
 ossimPlanet/include/ossimPlanet/netBuffer.h        |  234 ++
 ossimPlanet/include/ossimPlanet/netChannel.h       |  116 +
 ossimPlanet/include/ossimPlanet/netChat.h          |   86 +
 ossimPlanet/include/ossimPlanet/netMessage.h       |  294 ++
 ossimPlanet/include/ossimPlanet/netMonitor.h       |  106 +
 ossimPlanet/include/ossimPlanet/netSocket.h        |  115 +
 ossimPlanet/include/ossimPlanet/ossimPlanet.h      |  135 +
 .../include/ossimPlanet/ossimPlanetAction.h        |  161 +
 .../ossimPlanet/ossimPlanetActionReceiver.h        |   39 +
 .../include/ossimPlanet/ossimPlanetActionRouter.h  |  247 ++
 .../ossimPlanet/ossimPlanetAnimatedPointModel.h    |   68 +
 .../include/ossimPlanet/ossimPlanetAnimationPath.h |   92 +
 .../ossimPlanet/ossimPlanetAnnotationLayer.h       |   83 +
 .../ossimPlanet/ossimPlanetAnnotationLayerNode.h   |  453 +++
 ossimPlanet/include/ossimPlanet/ossimPlanetApi.h   |  770 +++++
 .../include/ossimPlanet/ossimPlanetArchive.h       |   37 +
 .../ossimPlanet/ossimPlanetArchiveMapping.h        |   29 +
 .../include/ossimPlanet/ossimPlanetBillboardIcon.h |   75 +
 .../include/ossimPlanet/ossimPlanetBoundingBox.h   |  234 ++
 ossimPlanet/include/ossimPlanet/ossimPlanetCache.h |  178 ++
 .../ossimPlanet/ossimPlanetCacheTextureLayer.h     |   79 +
 .../include/ossimPlanet/ossimPlanetCallback.h      |  110 +
 .../include/ossimPlanet/ossimPlanetClientThread.h  |   94 +
 .../include/ossimPlanet/ossimPlanetCloudLayer.h    |  231 ++
 .../include/ossimPlanet/ossimPlanetCompass.h       |  103 +
 .../include/ossimPlanet/ossimPlanetConstants.h     |  111 +
 .../include/ossimPlanet/ossimPlanetCubeGrid.h      |   37 +
 .../include/ossimPlanet/ossimPlanetDatabasePager.h |   67 +
 .../ossimPlanet/ossimPlanetDepthPartitionNode.h    |  104 +
 .../ossimPlanetDestinationCommandAction.h          |   85 +
 .../ossimPlanet/ossimPlanetDistanceAccumulator.h   |  116 +
 .../ossimPlanet/ossimPlanetDtedElevationDatabase.h |   85 +
 .../ossimPlanet/ossimPlanetElevationDatabase.h     |   69 +
 .../ossimPlanetElevationDatabaseGroup.h            |   58 +
 .../ossimPlanet/ossimPlanetElevationFactory.h      |   12 +
 .../include/ossimPlanet/ossimPlanetElevationGrid.h |   60 +
 .../ossimPlanet/ossimPlanetElevationRegistry.h     |   36 +
 .../include/ossimPlanet/ossimPlanetEphemeris.h     |  392 +++
 .../include/ossimPlanet/ossimPlanetExport.h        |   60 +
 .../include/ossimPlanet/ossimPlanetExtents.h       |  351 +++
 .../include/ossimPlanet/ossimPlanetFadeText.h      |   77 +
 .../ossimPlanetGeneralRasterElevationDatabase.h    |   63 +
 .../include/ossimPlanet/ossimPlanetGeoRefModel.h   |  370 +++
 .../include/ossimPlanet/ossimPlanetGeocoder.h      |   82 +
 ossimPlanet/include/ossimPlanet/ossimPlanetGrid.h  |  310 ++
 .../include/ossimPlanet/ossimPlanetGridUtility.h   |  166 +
 .../include/ossimPlanet/ossimPlanetIconGeom.h      |   44 +
 ossimPlanet/include/ossimPlanet/ossimPlanetId.h    |   79 +
 .../include/ossimPlanet/ossimPlanetIdManager.h     |   15 +
 .../include/ossimPlanet/ossimPlanetIdolBridge.h    |  105 +
 .../include/ossimPlanet/ossimPlanetIdolLayer.h     |  140 +
 ossimPlanet/include/ossimPlanet/ossimPlanetImage.h |  186 ++
 .../include/ossimPlanet/ossimPlanetInputDevice.h   |   20 +
 .../ossimPlanet/ossimPlanetInteractionController.h |  154 +
 .../ossimPlanet/ossimPlanetIntersectUserData.h     |   27 +
 ossimPlanet/include/ossimPlanet/ossimPlanetIo.h    |  156 +
 .../ossimPlanet/ossimPlanetIoMessageHandler.h      |   40 +
 .../ossimPlanetIoRoutableMessageHandler.h          |   15 +
 .../include/ossimPlanet/ossimPlanetIoSocket.h      |  125 +
 .../ossimPlanet/ossimPlanetIoSocketServerChannel.h |   98 +
 .../include/ossimPlanet/ossimPlanetIoThread.h      |   76 +
 .../include/ossimPlanet/ossimPlanetJpegImage.h     |   24 +
 ossimPlanet/include/ossimPlanet/ossimPlanetKml.h   | 2553 ++++++++++++++++
 .../include/ossimPlanet/ossimPlanetKmlLayer.h      |  201 ++
 .../include/ossimPlanet/ossimPlanetKmlLayerNode.h  |   49 +
 .../ossimPlanet/ossimPlanetKmlNetworkLinkNode.h    |   18 +
 .../ossimPlanet/ossimPlanetKmlPlacemarkNode.h      |   72 +
 .../ossimPlanet/ossimPlanetKmlReaderWriter.h       |   16 +
 .../ossimPlanet/ossimPlanetKmlScreenOverlayNode.h  |   49 +
 .../include/ossimPlanet/ossimPlanetLabelGeom.h     |   77 +
 ossimPlanet/include/ossimPlanet/ossimPlanetLand.h  |  181 ++
 .../include/ossimPlanet/ossimPlanetLandCache.h     |  114 +
 .../ossimPlanet/ossimPlanetLandCullCallback.h      |   55 +
 .../include/ossimPlanet/ossimPlanetLandNode.h      |  115 +
 .../ossimPlanet/ossimPlanetLandNormalType.h        |   10 +
 .../ossimPlanet/ossimPlanetLandReaderWriter.h      |  202 ++
 .../ossimPlanet/ossimPlanetLandTextureRequest.h    |  226 ++
 .../include/ossimPlanet/ossimPlanetLandTreeNode.h  |   26 +
 .../include/ossimPlanet/ossimPlanetLatLonHud.h     |   86 +
 ossimPlanet/include/ossimPlanet/ossimPlanetLayer.h |   58 +
 .../include/ossimPlanet/ossimPlanetLayerFactory.h  |   21 +
 .../ossimPlanet/ossimPlanetLayerFactoryBase.h      |   15 +
 .../include/ossimPlanet/ossimPlanetLayerRegistry.h |   39 +
 .../include/ossimPlanet/ossimPlanetLookAt.h        |  230 ++
 .../ossimPlanet/ossimPlanetLsrSpaceTransform.h     |  363 +++
 .../ossimPlanet/ossimPlanetManipulator.back        |  125 +
 .../include/ossimPlanet/ossimPlanetManipulator.h   |  309 ++
 .../include/ossimPlanet/ossimPlanetMessage.h       |   48 +
 .../include/ossimPlanet/ossimPlanetNavigator.h     |  277 ++
 .../ossimPlanet/ossimPlanetNetworkConnection.h     |   41 +
 ossimPlanet/include/ossimPlanet/ossimPlanetNode.h  |  255 ++
 .../include/ossimPlanet/ossimPlanetNodeFactory.h   |   17 +
 .../ossimPlanet/ossimPlanetNodeFactoryBase.h       |   18 +
 .../include/ossimPlanet/ossimPlanetNodeRegistry.h  |   30 +
 .../include/ossimPlanet/ossimPlanetOperation.h     |  422 +++
 .../ossimPlanet/ossimPlanetOrthoFlatLandNode.h     |   26 +
 .../ossimPlanetOssimElevationDatabase.h            |   56 +
 .../include/ossimPlanet/ossimPlanetOssimImage.h    |   21 +
 .../ossimPlanet/ossimPlanetOssimImageLayer.h       |  370 +++
 .../include/ossimPlanet/ossimPlanetPagedLandLod.h  |  199 ++
 .../ossimPlanetPagedLandLodRefreshType.h           |   16 +
 .../ossimPlanet/ossimPlanetPagedRequestNode.h      |   70 +
 .../include/ossimPlanet/ossimPlanetPlaneGrid.h     |   28 +
 .../include/ossimPlanet/ossimPlanetPointModel.h    |  150 +
 .../ossimPlanetPredatorVideoLayerNode.h            |  264 ++
 .../include/ossimPlanet/ossimPlanetPrimaryBody.h   |  130 +
 .../ossimPlanet/ossimPlanetReentrantMutex.h        |  110 +
 .../include/ossimPlanet/ossimPlanetRefBlock.h      |   15 +
 .../include/ossimPlanet/ossimPlanetSceneView.h     |   37 +
 .../ossimPlanet/ossimPlanetServerMessageHandler.h  |   30 +
 .../include/ossimPlanet/ossimPlanetServerThread.h  |   75 +
 ossimPlanet/include/ossimPlanet/ossimPlanetSetup.h |    8 +
 .../ossimPlanet/ossimPlanetShaderProgramSetup.h    |   86 +
 .../ossimPlanetSocketNetworkConnection.h           |   68 +
 .../include/ossimPlanet/ossimPlanetSousaLayer.h    |   97 +
 .../ossimPlanet/ossimPlanetSrtmElevationDatabase.h |   65 +
 .../ossimPlanetStandardTextureLayerFactory.h       |   30 +
 .../include/ossimPlanet/ossimPlanetTerrain.h       |  435 +++
 .../ossimPlanetTerrainGeometryTechnique.h          |  255 ++
 .../include/ossimPlanet/ossimPlanetTerrainLayer.h  |  191 ++
 .../ossimPlanet/ossimPlanetTerrainTechnique.h      |  170 ++
 .../include/ossimPlanet/ossimPlanetTerrainTile.h   |  223 ++
 .../include/ossimPlanet/ossimPlanetTerrainTileId.h |   76 +
 .../include/ossimPlanet/ossimPlanetTexture2D.h     |   34 +
 .../include/ossimPlanet/ossimPlanetTextureLayer.h  |  380 +++
 .../ossimPlanet/ossimPlanetTextureLayerFactory.h   |   19 +
 .../ossimPlanet/ossimPlanetTextureLayerGroup.h     |  115 +
 .../ossimPlanet/ossimPlanetTextureLayerRegistry.h  |   40 +
 .../include/ossimPlanet/ossimPlanetThread.h        |   30 +
 .../include/ossimPlanet/ossimPlanetThreadImp.h     |   38 +
 .../include/ossimPlanet/ossimPlanetThreadPool.h    |   32 +
 .../include/ossimPlanet/ossimPlanetTileRequest.h   |  256 ++
 .../include/ossimPlanet/ossimPlanetUtility.h       |   29 +
 .../include/ossimPlanet/ossimPlanetVideoLayer.h    |   61 +
 .../ossimPlanet/ossimPlanetVideoLayerNode.h        |   72 +
 .../ossimPlanet/ossimPlanetViewMatrixBuilder.h     |  680 +++++
 .../include/ossimPlanet/ossimPlanetViewer.h        |  487 +++
 .../include/ossimPlanet/ossimPlanetVisitors.h      |  140 +
 .../include/ossimPlanet/ossimPlanetWmsClient.h     |   99 +
 .../include/ossimPlanet/ossimPlanetWmsImageLayer.h |  128 +
 .../include/ossimPlanet/ossimPlanetXmlAction.h     |   81 +
 .../include/ossimPlanet/ossimPlanetYahooGeocoder.h |   23 +
 ossimPlanet/include/ossimPlanet/sg_file.h          |  101 +
 ossimPlanet/include/ossimPlanet/sg_socket.h        |  181 ++
 ossimPlanet/include/ossimPlanet/sg_socket_udp.h    |  137 +
 ossimPlanet/include/ossimPlanet/ul.h               |  868 ++++++
 ossimPlanet/include/ossimPlanet/ulLocal.h          |   52 +
 ossimPlanet/include/ossimPlanet/ulRTTI.h           |  420 +++
 ossimPlanet/include/ossimPlanet/unzip.h            |  354 +++
 ossimPlanet/include/ossimPlanet/zip.h              |  235 ++
 ossimPlanet/projects/vs2005/ossimPlanet.sln        |   34 +
 ossimPlanet/projects/vs2005/ossimPlanet.vcproj     | 1381 +++++++++
 ossimPlanet/schema/AnimationPath.xsd               |   51 +
 ossimPlanet/schema/ossimPlanet.xsd                 |  447 +++
 ossimPlanet/src/GNUmakefile                        |    7 +
 ossimPlanet/src/ossimPlanet/GNUmakefile            |  144 +
 ossimPlanet/src/ossimPlanet/crypt.h                |  132 +
 ossimPlanet/src/ossimPlanet/ioapi.c                |  177 ++
 ossimPlanet/src/ossimPlanet/iochannel.cpp          |   84 +
 ossimPlanet/src/ossimPlanet/iowin32.c              |  270 ++
 ossimPlanet/src/ossimPlanet/mkUtils.cpp            |  471 +++
 ossimPlanet/src/ossimPlanet/netBuffer.cpp          |   69 +
 ossimPlanet/src/ossimPlanet/netChannel.cpp         |  279 ++
 ossimPlanet/src/ossimPlanet/netChat.cpp            |  125 +
 ossimPlanet/src/ossimPlanet/netMessage.cpp         |   50 +
 ossimPlanet/src/ossimPlanet/netMonitor.cpp         |  180 ++
 ossimPlanet/src/ossimPlanet/netSocket.cpp          |  503 +++
 ossimPlanet/src/ossimPlanet/ossimPlanet.cpp        |  507 +++
 ossimPlanet/src/ossimPlanet/ossimPlanetAction.cpp  |   55 +
 .../src/ossimPlanet/ossimPlanetActionReceiver.cpp  |   31 +
 .../src/ossimPlanet/ossimPlanetActionRouter.cpp    |  374 +++
 .../ossimPlanet/ossimPlanetAnimatedPointModel.cpp  |  307 ++
 .../src/ossimPlanet/ossimPlanetAnimationPath.cpp   |  407 +++
 .../src/ossimPlanet/ossimPlanetAnnotationLayer.cpp |  246 ++
 .../ossimPlanet/ossimPlanetAnnotationLayerNode.cpp |  557 ++++
 ossimPlanet/src/ossimPlanet/ossimPlanetApi.cpp     | 1135 +++++++
 ossimPlanet/src/ossimPlanet/ossimPlanetArchive.cpp |  199 ++
 .../src/ossimPlanet/ossimPlanetArchiveMapping.cpp  |   36 +
 .../src/ossimPlanet/ossimPlanetBillboardIcon.cpp   |  129 +
 .../src/ossimPlanet/ossimPlanetBoundingBox.cpp     |   56 +
 ossimPlanet/src/ossimPlanet/ossimPlanetCache.cpp   |  195 ++
 .../ossimPlanet/ossimPlanetCacheTextureLayer.cpp   |  283 ++
 .../src/ossimPlanet/ossimPlanetClientThread.cpp    |  360 +++
 .../src/ossimPlanet/ossimPlanetCloudLayer.cpp      |  666 ++++
 ossimPlanet/src/ossimPlanet/ossimPlanetCompass.cpp |  638 ++++
 .../src/ossimPlanet/ossimPlanetCubeGrid.cpp        |  221 ++
 .../src/ossimPlanet/ossimPlanetDatabasePager.cpp   |  583 ++++
 .../ossimPlanet/ossimPlanetDepthPartitionNode.cpp  |  272 ++
 .../ossimPlanetDestinationCommandAction.cpp        |   97 +
 .../ossimPlanet/ossimPlanetDistanceAccumulator.cpp |  402 +++
 .../ossimPlanetDtedElevationDatabase.cpp           |  715 +++++
 .../ossimPlanet/ossimPlanetElevationDatabase.cpp   |   92 +
 .../ossimPlanetElevationDatabaseGroup.cpp          |  518 ++++
 .../ossimPlanet/ossimPlanetElevationFactory.cpp    |   49 +
 .../src/ossimPlanet/ossimPlanetElevationGrid.cpp   |  174 ++
 .../ossimPlanet/ossimPlanetElevationRegistry.cpp   |   61 +
 .../src/ossimPlanet/ossimPlanetEphemeris.cpp       | 2508 +++++++++++++++
 .../src/ossimPlanet/ossimPlanetFadeText.cpp        |  471 +++
 .../ossimPlanetGeneralRasterElevationDatabase.cpp  |  616 ++++
 .../src/ossimPlanet/ossimPlanetGeocoder.cpp        |   81 +
 ossimPlanet/src/ossimPlanet/ossimPlanetGrid.cpp    | 1100 +++++++
 .../src/ossimPlanet/ossimPlanetGridUtility.cpp     |  526 ++++
 .../src/ossimPlanet/ossimPlanetIconGeom.cpp        |  157 +
 ossimPlanet/src/ossimPlanet/ossimPlanetId.cpp      |    8 +
 .../src/ossimPlanet/ossimPlanetIdManager.cpp       |   12 +
 ossimPlanet/src/ossimPlanet/ossimPlanetImage.cpp   | 1157 +++++++
 .../ossimPlanetInteractionController.cpp           |  338 ++
 .../ossimPlanetIoRoutableMessageHandler.cpp        |   20 +
 .../src/ossimPlanet/ossimPlanetIoSocket.cpp        |  665 ++++
 .../ossimPlanetIoSocketServerChannel.cpp           |  330 ++
 .../src/ossimPlanet/ossimPlanetIoThread.cpp        |  748 +++++
 .../src/ossimPlanet/ossimPlanetJpegImage.cpp       |  363 +++
 ossimPlanet/src/ossimPlanet/ossimPlanetKml.cpp     | 2818 +++++++++++++++++
 .../src/ossimPlanet/ossimPlanetKmlLayer.cpp        |  504 +++
 .../src/ossimPlanet/ossimPlanetKmlLayerNode.cpp    |   50 +
 .../ossimPlanet/ossimPlanetKmlNetworkLinkNode.cpp  |  108 +
 .../ossimPlanet/ossimPlanetKmlPlacemarkNode.cpp    | 1176 +++++++
 .../ossimPlanetKmlScreenOverlayNode.cpp            |  359 +++
 .../src/ossimPlanet/ossimPlanetLabelGeom.cpp       |  166 +
 ossimPlanet/src/ossimPlanet/ossimPlanetLand.cpp    | 1695 +++++++++++
 .../src/ossimPlanet/ossimPlanetLandCache.cpp       |  290 ++
 .../ossimPlanet/ossimPlanetLandCullCallback.cpp    |  481 +++
 .../ossimPlanet/ossimPlanetLandReaderWriter.cpp    | 1864 ++++++++++++
 .../src/ossimPlanet/ossimPlanetLatLonHud.cpp       |  506 +++
 ossimPlanet/src/ossimPlanet/ossimPlanetLayer.cpp   |  226 ++
 .../src/ossimPlanet/ossimPlanetLayerFactory.cpp    |   63 +
 .../src/ossimPlanet/ossimPlanetLayerRegistry.cpp   |   89 +
 ossimPlanet/src/ossimPlanet/ossimPlanetLookAt.cpp  |   48 +
 .../ossimPlanet/ossimPlanetLsrSpaceTransform.cpp   |  210 ++
 .../src/ossimPlanet/ossimPlanetManipulator.cpp     |  806 +++++
 .../src/ossimPlanet/ossimPlanetNavigator.cpp       | 1460 +++++++++
 ossimPlanet/src/ossimPlanet/ossimPlanetNode.cpp    |  350 +++
 .../src/ossimPlanet/ossimPlanetNodeFactory.cpp     |   35 +
 .../src/ossimPlanet/ossimPlanetNodeRegistry.cpp    |   84 +
 .../src/ossimPlanet/ossimPlanetOperation.cpp       |  652 ++++
 .../ossimPlanetOssimElevationDatabase.cpp          |  355 +++
 .../src/ossimPlanet/ossimPlanetOssimImage.cpp      |   43 +
 .../src/ossimPlanet/ossimPlanetOssimImageLayer.cpp | 1374 +++++++++
 .../src/ossimPlanet/ossimPlanetPagedLandLod.cpp    |  505 +++
 .../src/ossimPlanet/ossimPlanetPlaneGrid.cpp       |   73 +
 .../src/ossimPlanet/ossimPlanetPointModel.cpp      |  115 +
 .../ossimPlanetPredatorVideoLayerNode.cpp          |  936 ++++++
 .../src/ossimPlanet/ossimPlanetSceneView.cpp       |  214 ++
 .../src/ossimPlanet/ossimPlanetServerThread.cpp    |  310 ++
 .../ossimPlanet/ossimPlanetShaderProgramSetup.cpp  |   17 +
 .../ossimPlanetSocketNetworkConnection.cpp         |  186 ++
 .../src/ossimPlanet/ossimPlanetSousaLayer.cpp      |  749 +++++
 .../ossimPlanetSrtmElevationDatabase.cpp           |  804 +++++
 .../ossimPlanetStandardTextureLayerFactory.cpp     |  207 ++
 ossimPlanet/src/ossimPlanet/ossimPlanetTerrain.cpp | 1716 +++++++++++
 .../ossimPlanetTerrainGeometryTechnique.cpp        | 1744 +++++++++++
 .../src/ossimPlanet/ossimPlanetTerrainLayer.cpp    |    1 +
 .../ossimPlanet/ossimPlanetTerrainTechnique.cpp    |  343 +++
 .../src/ossimPlanet/ossimPlanetTerrainTile.cpp     |  359 +++
 .../src/ossimPlanet/ossimPlanetTexture2D.cpp       |   83 +
 .../src/ossimPlanet/ossimPlanetTextureLayer.cpp    | 1641 ++++++++++
 .../ossimPlanet/ossimPlanetTextureLayerGroup.cpp   | 1086 +++++++
 .../ossimPlanetTextureLayerRegistry.cpp            |  105 +
 ossimPlanet/src/ossimPlanet/ossimPlanetThread.cpp  |   77 +
 .../src/ossimPlanet/ossimPlanetThreadImp.cpp       |   33 +
 .../src/ossimPlanet/ossimPlanetThreadPool.cpp      |   84 +
 .../src/ossimPlanet/ossimPlanetTileRequest.cpp     |  864 ++++++
 ossimPlanet/src/ossimPlanet/ossimPlanetUtility.cpp |  129 +
 .../src/ossimPlanet/ossimPlanetVideoLayer.cpp      |   46 +
 .../ossimPlanet/ossimPlanetViewMatrixBuilder.cpp   |  615 ++++
 ossimPlanet/src/ossimPlanet/ossimPlanetViewer.cpp  | 1127 +++++++
 .../src/ossimPlanet/ossimPlanetVisitors.cpp        |  112 +
 .../src/ossimPlanet/ossimPlanetWmsClient.cpp       |  246 ++
 .../src/ossimPlanet/ossimPlanetWmsImageLayer.cpp   |  922 ++++++
 .../src/ossimPlanet/ossimPlanetXmlAction.cpp       |  225 ++
 .../src/ossimPlanet/ossimPlanetYahooGeocoder.cpp   |   87 +
 ossimPlanet/src/ossimPlanet/sg_file.cpp            |  143 +
 ossimPlanet/src/ossimPlanet/sg_socket.cpp          |  494 +++
 ossimPlanet/src/ossimPlanet/sg_socket_udp.cpp      |  200 ++
 ossimPlanet/src/ossimPlanet/ul.cpp                 |  544 ++++
 ossimPlanet/src/ossimPlanet/ulClock.cpp            |  117 +
 ossimPlanet/src/ossimPlanet/ulError.cpp            |   90 +
 ossimPlanet/src/ossimPlanet/ulLinkedList.cpp       |  272 ++
 ossimPlanet/src/ossimPlanet/ulList.cpp             |  109 +
 ossimPlanet/src/ossimPlanet/ulRTTI.cpp             |  109 +
 ossimPlanet/src/ossimPlanet/unzip.c                | 1630 ++++++++++
 ossimPlanet/src/ossimPlanet/zip.c                  | 1219 ++++++++
 .../ossimPlanet/English.lproj/InfoPlist.strings    |  Bin 0 -> 152 bytes
 ossimPlanet/xcode/ossimPlanet/Info.plist           |   26 +
 .../ossimPlanet.xcodeproj/project.pbxproj          | 3219 ++++++++++++++++++++
 332 files changed, 94604 insertions(+)

diff --git a/ossimPlanet/AUTHORS.txt b/ossimPlanet/AUTHORS.txt
new file mode 100644
index 0000000..98be0a4
--- /dev/null
+++ b/ossimPlanet/AUTHORS.txt
@@ -0,0 +1,6 @@
+// $Id: AUTHORS.txt 9332 2006-07-31 14:55:34Z gpotts $
+Garrett Potts <gpotts at intelligence-data.com>
+
+Norman Vine
+
+Eric Sokolowski
diff --git a/ossimPlanet/CMakeLists.txt b/ossimPlanet/CMakeLists.txt
new file mode 100644
index 0000000..ba9ff0a
--- /dev/null
+++ b/ossimPlanet/CMakeLists.txt
@@ -0,0 +1,122 @@
+PROJECT(ossimPlanet)
+MESSAGE("**********************Setting up ossimPlanet********************")
+INCLUDE(OssimVersion)
+INCLUDE(OssimUtilities)
+INCLUDE(OssimCommonVariables)
+
+OPTION(OSSIMPLANET_ENABLE_EPHEMERIS "Set to ON enable ephemeris support if GPSTK is found.  Use OFF to not enable ephemeris." ON)
+
+IF(NOT APPLE)
+  cmake_minimum_required(VERSION 2.6)
+ELSE(NOT APPLE)
+  cmake_minimum_required(VERSION 2.8)
+ENDIF(NOT APPLE)
+
+find_package(OpenThreads)
+find_package(ossim)
+find_package(ossimPredator)
+find_package(GPSTK)
+find_package(JPEG)
+find_package(OSG)
+find_package(WMS)
+find_package(ZLIB)
+find_package(OpenGL)
+find_package(FFmpeg)
+find_package(Regex)
+
+MESSAGE( STATUS "OSSIM_INCLUDE_DIR         = ${OSSIM_INCLUDE_DIR}")
+MESSAGE( STATUS "OSSIM_LIBRARIES           = ${OSSIM_LIBRARIES}")
+MESSAGE( STATUS "OPENGL_INCLUDE_DIR        = ${OPENGL_INCLUDE_DIR}")
+MESSAGE( STATUS "OPENGL_LIBRARIES          = ${OPENGL_LIBRARIES}")
+MESSAGE( STATUS "OSSIM_LIBRARIES           = ${OSSIM_LIBRARIES}")
+MESSAGE( STATUS "OSSIMPREDATOR_LIBRARIES   = ${OSSIMPREDATOR_LIBRARIES}")
+MESSAGE( STATUS "OSSIMPREDATOR_INCLUDE_DIR = ${OSSIMPREDATOR_INCLUDE_DIR}")
+MESSAGE( STATUS "OPENTHREADS_LIBRARY       = ${OPENTHREADS_LIBRARY}")
+MESSAGE( STATUS "OPENTHREADS_INCLUDE_DIR   = ${OPENTHREADS_INCLUDE_DIR}")
+MESSAGE( STATUS "FFMPEG_LIBRARIES = ${FFMPEG_LIBRARIES}")
+MESSAGE( STATUS "FFMPEG_INCLUDE_DIRS = ${FFMPEG_INCLUDE_DIRS}")
+MESSAGE( STATUS "WMS_LIBRARY               = ${WMS_LIBRARY}")
+MESSAGE( STATUS "WMS_INCLUDE_DIR           = ${WMS_INCLUDE_DIR}")
+
+MESSAGE( STATUS "OSG_LIBRARY               = ${OSG_LIBRARY}")
+MESSAGE( STATUS "OSG_INCLUDE_DIR           = ${OSG_INCLUDE_DIR}")
+MESSAGE( STATUS "OSGUTIL_LIBRARY           = ${OSGUTIL_LIBRARY}")
+################################################## BUILD THE LIBRARY #######################################
+SET(LIB_NAME ossimPlanet)
+
+INCLUDE_DIRECTORIES(${${PROJECT_NAME}_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${OSSIM_INCLUDE_DIR})
+
+IF(OSSIMPREDATOR_FOUND AND BUILD_OSSIMPREDATOR)
+   INCLUDE_DIRECTORIES(${OSSIMPREDATOR_INCLUDE_DIR})
+   ADD_DEFINITIONS("-DOSSIMPLANET_ENABLE_PREDATOR")
+   INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIRS})
+ELSE(OSSIMPREDATOR_FOUND AND BUILD_OSSIMPREDATOR)
+   MESSAGE(STATUS "Disabling Predator support in Planet")
+   SET(OSSIMPREDATOR_LIBRARY "")
+   SET(OSSIMPREDATOR_LIBRARIES "")
+   SET(OSSIMPREDATOR_INCLUDE_DIR "")
+   SET(FFMPEG_LIBRARIES "")
+   SET(FFMPEG_LIBRARY "")
+ENDIF(OSSIMPREDATOR_FOUND AND BUILD_OSSIMPREDATOR)
+
+INCLUDE_DIRECTORIES(${OPENTHREADS_INCLUDE_DIR})
+INCLUDE_DIRECTORIES(${WMS_INCLUDE_DIR})
+
+IF(GPSTK_FOUND AND OSSIMPLANET_ENABLE_EPHEMERIS)
+    MESSAGE(STATUS "GPSTK_LIBRARY               = ${GPSTK_LIBRARY}")
+    MESSAGE(STATUS "GPSTK_INCLUDE_DIR           = ${GPSTK_INCLUDE_DIR}")
+    ADD_DEFINITIONS("-DOSSIMPLANET_ENABLE_EPHEMERIS")
+    INCLUDE_DIRECTORIES(${GPSTK_INCLUDE_DIR})
+    IF(REGEX_FOUND)
+      INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
+      MESSAGE(STATUS "REGEX_INCLUDE_DIR          =  ${REGEX_INCLUDE_DIR}")
+      MESSAGE(STATUS "REGEX_LIBRARIES            =  ${REGEX_LIBRARIES}")
+    ELSE()
+      set(REGEX_LIBRARIES "")
+    ENDIF()
+ELSE(GPSTK_FOUND AND OSSIMPLANET_ENABLE_EPHEMERIS)
+    SET(GPSTK_LIBRARY "")
+ENDIF(GPSTK_FOUND AND OSSIMPLANET_ENABLE_EPHEMERIS)
+
+
+INCLUDE_DIRECTORIES(${OSG_INCLUDE_DIR})
+INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
+
+
+FILE(GLOB OSSIMPLANET_SRCS RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/src/ossimPlanet/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ossimPlanet/*.c")
+FILE(GLOB OSSIMPLANET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/ossimPlanet/*.h")
+
+IF(NOT BUILD_OSSIMPREDATOR)
+   LIST(REMOVE_ITEM OSSIMPLANET_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/ossimPlanet/ossimPlanetPredatorVideoLayerNode.cpp")
+   LIST(REMOVE_ITEM OSSIMPLANET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/ossimPlanet/ossimPlanetPredatorVideoLayerNode.h")
+ENDIF()
+
+IF(NOT WIN32)
+   LIST(REMOVE_ITEM OSSIMPLANET_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/ossimPlanet/iowin32.c")
+ELSE(NOT WIN32)
+   LIST(APPEND ${LIB_NAME}_EXTRA_LIBS "ws2_32" "winmm")
+ENDIF(NOT WIN32)
+
+SET(INSTALL_INCLUDE_DIR "include/ossimPlanet")
+OSSIM_LINK_LIBRARY(${LIB_NAME} COMPONENT_NAME ossim TYPE "${OSSIM_USER_DEFINED_DYNAMIC_OR_STATIC}" HEADERS ${OSSIMPLANET_HEADERS} SOURCE_FILES ${OSSIMPLANET_SRCS} 
+                   LIBRARIES ${OSSIM_LIBRARIES} ${OSGVIEWER_LIBRARY} ${OSGDB_LIBRARY} ${OSGGA_LIBRARY}  ${OSGTEXT_LIBRARY} ${OSGUTIL_LIBRARY}  ${OSG_LIBRARY}  ${OPENTHREADS_LIBRARY} ${JPEG_LIBRARY} ${WMS_LIBRARY} ${GPSTK_LIBRARY} ${OSSIMPREDATOR_LIBRARY} ${ZLIB_LIBRARY} ${OPENGL_LIBRARIES} ${FFMPEG_LIBRARIES} ${REGEX_LIBRARIES}
+                   INSTALL_LIB INSTALL_HEADERS VERSION_SYMLINKS ADDITIONAL_COMPILE_FLAGS "-DOSSIMPLANET_LIBRARY")
+
+
+############################################################# SETUP APPLICATIONS ##################################################
+set(TARGET_COMMON_LIBRARIES ossimPlanet ${OSSIMPREDATOR_LIBRARIES})
+FILE(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/examples/ossimplanetviewer/*.cpp")
+OSSIM_SETUP_APPLICATION(ossimplanetviewer INSTALL COMMAND_LINE COMPONENT_NAME ossim SOURCE_FILES ${SOURCE_FILES})
+FILE(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/examples/ossimplanettest/*.cpp")
+OSSIM_SETUP_APPLICATION(ossimplanettest INSTALL COMMAND_LINE COMPONENT_NAME ossim SOURCE_FILES ${SOURCE_FILES})
+IF(BUILD_OSSIMPREDATOR)
+   FILE(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/examples/ossimplanetklv/*.cpp")
+   OSSIM_SETUP_APPLICATION(ossimplanetklv INSTALL COMMAND_LINE COMPONENT_NAME ossim SOURCE_FILES ${SOURCE_FILES})
+ENDIF()
+
+FILE(GLOB SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/apps/ossimplanet-chip/*.cpp")
+OSSIM_SETUP_APPLICATION(ossimplanet-chip INSTALL COMMAND_LINE COMPONENT_NAME ossim SOURCE_FILES ${SOURCE_FILES})
+
+####################################### SETUP THE UNINSTALL #################################
+OSSIM_ADD_COMMON_MAKE_UNINSTALL()
diff --git a/ossimPlanet/Doxyfile b/ossimPlanet/Doxyfile
new file mode 100644
index 0000000..2f95bb6
--- /dev/null
+++ b/ossimPlanet/Doxyfile
@@ -0,0 +1,1541 @@
+# Doxyfile 1.5.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = ossimPlanet
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = "Version 1.8.6"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = dox
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = include src examples
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.vhd \
+                         *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = .svn
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = 
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to FRAME, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list; 
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which 
+# disables this behavior completely. For backwards compatibility with previous 
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE 
+# respectively.
+
+GENERATE_TREEVIEW      = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/ossimPlanet/GNUmakefile.old b/ossimPlanet/GNUmakefile.old
new file mode 100644
index 0000000..a55b01c
--- /dev/null
+++ b/ossimPlanet/GNUmakefile.old
@@ -0,0 +1,12 @@
+TOPDIR = .
+include $(TOPDIR)/Make/makedefs
+include $(TOPDIR)/Make/makedirdefs
+
+DIRS = $(TOP_LEVEL_DIRS)
+
+include $(TOPDIR)/Make/makedirrules
+include $(TOPDIR)/Make/versionrules
+include $(TOPDIR)/Make/instrules
+include $(TOPDIR)/Make/distrules
+include $(TOPDIR)/Make/helprules
+include $(TOPDIR)/Make/maketoprule
diff --git a/ossimPlanet/LICENSE.txt b/ossimPlanet/LICENSE.txt
new file mode 100644
index 0000000..c57eb30
--- /dev/null
+++ b/ossimPlanet/LICENSE.txt
@@ -0,0 +1,76 @@
+                libwms Public License, Version 0.0
+                ==========================================
+                
+  Copyright (C) 2004 Garrett Potts.
+  
+  Everyone is permitted to copy and distribute verbatim copies
+  of this licence document, but changing it is not allowed.
+
+                       LIBWMS PUBLIC LICENCE
+     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the libwms Public License (WMSGPL) version 0.0
+  or later.
+  
+  Notes: the OSGPL is based on the LGPL, with the 4 exceptions laid in in
+  the wxWindows section below.  The LGPL in the final section of this
+  license.
+
+
+-------------------------------------------------------------------------------
+
+                wxWindows Library Licence, Version 3
+                ====================================
+
+  Copyright (C) 1998 Julian Smart, Robert Roebling [, ...]
+
+  Everyone is permitted to copy and distribute verbatim copies
+  of this licence document, but changing it is not allowed.
+
+                       WXWINDOWS LIBRARY LICENCE
+     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Library General Public Licence as published by
+  the Free Software Foundation; either version 2 of the Licence, or (at
+  your option) any later version.
+
+  This library is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library
+  General Public Licence for more details.
+
+  You should have received a copy of the GNU Library General Public Licence
+  along with this software, usually in a file named COPYING.LIB.  If not,
+  write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+  Boston, MA 02111-1307 USA.
+
+  EXCEPTION NOTICE
+
+  1. As a special exception, the copyright holders of this library give
+  permission for additional uses of the text contained in this release of
+  the library as licenced under the wxWindows Library Licence, applying
+  either version 3 of the Licence, or (at your option) any later version of
+  the Licence as published by the copyright holders of version 3 of the
+  Licence document.
+
+  2. The exception is that you may use, copy, link, modify and distribute
+  under the user's own terms, binary object code versions of works based
+  on the Library.
+
+  3. If you copy code from files distributed under the terms of the GNU
+  General Public Licence or the GNU Library General Public Licence into a
+  copy of this library, as this licence permits, the exception does not
+  apply to the code that you add in this way.  To avoid misleading anyone as
+  to the status of such modified files, you must delete this exception
+  notice from such code and/or adjust the licensing conditions notice
+  accordingly.
+
+  4. If you write modifications of your own for this library, it is your
+  choice whether to permit this exception to apply to your modifications.
+  If you do not wish that, you must delete the exception notice from such
+  code and/or adjust the licensing conditions notice accordingly.
+  
+  
+------------------------------------------------------------------------------
diff --git a/ossimPlanet/Make/cygwin_plugin_def b/ossimPlanet/Make/cygwin_plugin_def
new file mode 100644
index 0000000..010d27c
--- /dev/null
+++ b/ossimPlanet/Make/cygwin_plugin_def
@@ -0,0 +1,15 @@
+
+#
+# blessed are those who try to make Windows behave like it should ...
+#
+
+ifeq ($(OS),CYGWIN)
+TARGET_BASENAME := $(PLUGIN_PREFIX)$(TARGET_BASENAME)
+PLUGIN_PREFIX := cyg
+endif
+
+ifeq ($(OS),MINGW)
+TARGET_BASENAME := $(PLUGIN_PREFIX)$(TARGET_BASENAME)
+PLUGIN_PREFIX := lib
+endif
+
diff --git a/ossimPlanet/Make/dependencies b/ossimPlanet/Make/dependencies
new file mode 100644
index 0000000..c9bb116
--- /dev/null
+++ b/ossimPlanet/Make/dependencies
@@ -0,0 +1,9 @@
+################################################################
+# Dependency library which have been installed on this system
+
+##########################################
+#
+# For any getCapabilities parsing expat must be installed
+# on your system.
+#
+EXPAT_INSTALLED = yes
diff --git a/ossimPlanet/Make/distrules b/ossimPlanet/Make/distrules
new file mode 100644
index 0000000..b47b959
--- /dev/null
+++ b/ossimPlanet/Make/distrules
@@ -0,0 +1,16 @@
+distribution : 
+	@$(MAKEDIST) \
+		$(OS)\
+		$(TOPDIR)\
+		$(INST_LIBS)\
+		$(INST_INCLUDE)\
+		$(INST_EXAMPLES)\
+		$(INST_SRC)\
+		$(INST_EXAMPLE_SRC)\
+		"$(VERSION)-$(VERSION_REVISION)" \
+		$(INST_DOC) 
+
+	
+
+cleandist:
+	@$(MAKECLEANDIST)
diff --git a/ossimPlanet/Make/dolink.sh b/ossimPlanet/Make/dolink.sh
new file mode 100644
index 0000000..c071613
--- /dev/null
+++ b/ossimPlanet/Make/dolink.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+bye()
+{
+    echo $1
+    exit 1
+}
+
+TOPDIR=$1
+LNSRC=$2
+LNDEST=$3
+LINKCMD=$4
+
+## Check command line
+
+
+[ $# -lt 4 ] && bye "Usage: $0 <Top Directory> <Link Source> <Link Destination> <Link command>"
+
+## Check for existence of link source file
+[ -n "$LNSRC" ] || bye "Internal error (LNSRC definition)"
+
+## Check for existence of link destination file
+[ -n "$LNDEST" ] || bye "Internal error (LNDEST definition)"
+
+if diff -s $TOPDIR/$LNDEST $LNSRC >/dev/null 2>&1
+then
+    echo "  =====> $LNSRC and $TOPDIR/$LNDEST are in sync"
+else
+    echo "  =====> resetting $TOPDIR/$LNDEST to point to $LNSRC"
+
+    ## At this point, we must create a link at the link destination
+    ## which points back to our link source.  This requires us to
+    ## build a path FROM the destination back to the source
+  
+    #1) Get the source directory as an absolute path
+    SRCDIR=`pwd`/`dirname $LNSRC`
+   
+    #2) Get the destination directory as an absolute path (TOPDIR is
+    ##  a relative path from the current directory).
+    cd $TOPDIR
+    ROOTDIR=`pwd`
+    DESTDIR=`dirname "$ROOTDIR"/"$LNDEST"`
+
+    #3) Build a ../../ chain from the destination directory to the
+    ## current directory (ROOTDIR), which will become the prefix to
+    ## the path
+    T=`dirname $LNDEST`
+    while [ "$T" != "." ] 
+    do 
+        T=`dirname $T`;PFX=../"$PFX"
+    done
+
+    #4) strip the absolute path prefix of SRCDIR leading to the current
+    ## directory, so we are left with the relative path from the current
+    ## directory to the link source directory.  Prefix that with PFX.
+    LINK="$PFX"`echo $SRCDIR $ROOTDIR  | awk '{ print substr($1,length($2)+2,512) }'`/`basename $LNDEST`
+
+    #5) Create the links by changing to the destination directory,
+    ## removing any old versions of the link and creating a new one
+    [ -d `dirname $LNDEST` ] || mkdir -p `dirname $LNDEST`
+    cd `dirname $LNDEST`
+    rm -f `basename $LNDEST`
+    $LINKCMD $LINK `basename $LNDEST`
+fi
+
+exit 0
diff --git a/ossimPlanet/Make/help.sh b/ossimPlanet/Make/help.sh
new file mode 100755
index 0000000..9a35cfa
--- /dev/null
+++ b/ossimPlanet/Make/help.sh
@@ -0,0 +1,155 @@
+#!/bin/sh
+
+OS=$1
+TOPDIR=$2
+INST_LIBS=$3
+INST_PLUGINS=$4
+INST_INCLUDE=$5
+INST_EXAMPLES=$6
+INST_EXAMPLE_SRC=$7
+INST_DOC=$8
+INST_DATA=$9
+
+
+cat <<- EOF
+
+The following targets can be used with any subsystem as well as the top
+level build (build in the libwms Root directory).  Note that debug versions 
+and optimized version of targets reside in parallel.
+
+  make                - Same as 'make opt'
+  make opt            - Makes optimized versions of all targets
+  make debug          - Makes debug versions of all targets.
+  make clean          - Removes all object files (both optimized and debug 
+                        versions) and Makedepend files.
+  make cleanopt       - Removes optimized version of object files and 
+                        Makedepend files.
+  make cleandbg       - Removes debug version of object files and Makedepend
+                        files.
+  make cleandepend    - Removes Makedepend file(s) (both optimized and debug 
+                        versions)
+  make cleandependopt - Removes optimized version Makedepend file(s) 
+  make cleandependdbg - Removes debug version Makedepend file(s)
+  make cleantarget    - Removes only targets but leaves object files (both
+                        optimized and debug versions)
+  make cleantargetopt - Removes only optimized targets but leaves optimized
+                        objects files.
+  make cleantargetdbg - Removes only debug targets but leaves debug object
+                        files
+  make clobber        - Removes object files and targets (both optimized and
+                        debug versions)
+  make clobberopt     - Removes optimized object files and targets
+  make clobberdbg     - Removes debug object files and targets
+  make beautify       - Pretty print C++ files
+  make docs           - Builds documentation database for current target
+  make depend         - Force a rebuild of the dependency file.  Note that
+                        dependency files are generated automatically during
+                        builds.
+
+
+Solaris, IRIX and Linux (some compilers) can build 64 bit targets.  These 
+require the ARCH=64 argument.  For example:
+
+  make ARCH=64         - Same as 'make ARCH=64 opt'
+  make ARCH=64 opt     - Builds 64 bit optimized targets
+  make ARCH=64 debug   - Builds 64 bit debug versions of targets
+  make ARCH=64 clean   - Removes all 64 bit object files (both optimized and
+                         debug versions).
+
+  etc.
+
+The following targets may only be issued from the top-level libwms build:
+
+  make install      - Install both execution environment and development
+                      targets 
+  make instbin      - Install execution environment targets only.  These
+                      consist of libraries, plugins and example programs.
+                      Libraries are installed in
+                        o $INST_LIBS,
+                      plugins are installed in 
+                        o $INST_PLUGINS,
+                      and examples are installed in 
+                        o $INST_EXAMPLES
+                      on $OS
+
+  make instdev      - Install development targets only.  These consist of
+                      header files, source code to the example programs, and
+                      documentation.
+                      Header files are install in 
+                        o $INST_INCLUDE,
+                      example source code is installed in
+                        o $INST_EXAMPLE_SRC,
+                      and documentation is installed in
+                        o $INST_DOC
+                      on $OS
+
+  make instlinks    - Installs symbolic links at install locations for both
+                      execution environment and development targets rather
+                      than copyied files.  Installing links is ideal for a
+                      development environment for avoiding confusion about
+                      which binaries are being run or linked to.
+
+  make instlinksbin  - Installs symbolic links at install locations for
+                       execution environment targets only.
+  make instlinksdev  - Installs symbolic links at install locations for
+                       development targets only
+  make instclean     - Removes installed targets (files or links) from 
+                       installation locations for both execution environment
+                       and development targets
+  make instcleanbin  - Removes installed targets from installation locations
+                       for execution environment targets only
+  make instcleandev  - Removes installed targets from installation locations
+                       for defelopment targets only
+
+Note that the following variables can be used to directly override the default 
+installation locations for $OS.
+
+  make  INST_LIBS=<libs_location> \\
+        INST_PLUGINS=<plugins_location>\\
+        INST_INCLUDE=<header_file_location>\\
+        INST_EXAMPLES=<examples_location>\\
+        INST_EXAMPLE_SRC=<example_src_location>\\
+        INST_DOC=<doc_location>\\
+        install
+
+                     - Installs libraries in <libs_location>, plugins in 
+                       <plugins_location>, header files in 
+                       <header_file_location>, examples in <examples_location>,
+                       example source code in <example_src_location> and 
+                       documentation in <doc_location>
+
+Note also that INST_LIBS, INST_PLUGINS, INST_INCLUDE, and INST_SHARE share 
+a common prefix by default: INST_LOCATION. Further INST_EXAMPLES, INST_EXAMPLE_SRC, 
+INST_DOC, and INST_DATA share a common prefix by default : INST_SHARE, which
+is located under INST_LOCATION by default.  This provides a short cut for the 
+above 'make' usage.  For example,
+
+  make INST_LOCATION=/usr/local/libwms \\
+       INST_SHARE=/usr/share/libwms \\
+       install
+
+
+These values can be tested by reissuing 'make help' with these arguments.
+
+After doing a 'make install' or 'make instlinks', and if not already added, 
+add
+
+    $INST_EXAMPLES
+
+to your PATH environmental variable to run the examples.  If it is not already 
+present, add
+
+    $INST_LIBS
+
+and  
+
+    $INST_PLUGINS
+
+to your LD_LIBRARY_PATH environmental variable.  When compiling programs 
+using libwms headers add to your -I compile flags:
+
+    $INST_INCLUDE
+
+EOF
+
+exit 0
diff --git a/ossimPlanet/Make/helprules b/ossimPlanet/Make/helprules
new file mode 100644
index 0000000..42b210c
--- /dev/null
+++ b/ossimPlanet/Make/helprules
@@ -0,0 +1,11 @@
+help:
+	@$(TOPDIR)/Make/help.sh\
+		$(OS)\
+		$(TOPDIR)\
+		$(INST_LIBS)\
+		$(INST_PLUGINS)\
+		$(INST_INCLUDE)\
+		$(INST_DEMOS)\
+		$(INST_DEMO_SRC)\
+		$(INST_DOC)\
+		$(INST_DATA) | more
diff --git a/ossimPlanet/Make/instexamplesrc b/ossimPlanet/Make/instexamplesrc
new file mode 100755
index 0000000..6c6ad05
--- /dev/null
+++ b/ossimPlanet/Make/instexamplesrc
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+TOPDIR=$1
+INST_LIBS=$2
+INST_INCLUDE=$3
+INST_SRC=$4
+INST_EXAMPLE_SRC=$5
+INSTALLCMD=$6
+COMPILER=$7
+OPTF=$8
+shift; shift; shift; shift; shift; shift; shift; shift;
+DEPARG=$1
+LINKARGS=$2
+shift; shift;
+OTHER_LIBS=$1
+MAKE=$2
+
+copy_example_source()
+{
+    for d in `ls $TOPDIR/examples/ | grep -v CVS`
+    do
+        if [ -d $TOPDIR/examples/$d ]
+        then
+            THISDIR=`pwd`
+            cd $TOPDIR/examples/$d
+            [ -d "$INST_EXAMPLE_SRC/$d" ] || mkdir -m 0755 -p $INST_EXAMPLE_SRC/$d
+            echo "         installing $d"
+            for f in `$MAKE __instfiles`
+	    do
+                src=`echo $f | cut -f1 -d"="`
+                dst=`echo $f | cut -f2 -d"="`
+                if [ -z "$dst" ] ; then dst=$src; fi
+		if [ -f "$src" ] ; then
+		    ###echo $INSTALLCMD `pwd`/$src $INST_EXAMPLE_SRC/$d/$dst
+		    $INSTALLCMD `pwd`/$src $INST_EXAMPLE_SRC/$d/$dst ;
+		fi
+            done
+            cd $THISDIR
+        fi
+    done
+}
+
+generate_makedefs()
+{
+    cat <<-EOF 
+
+TOPDIR              ?= ../
+THISDIR             = .
+INC                 = -I$INST_INCLUDE -I./
+DEF                 = $DEF
+CXXFLAGS            = \$(ARCHARGS) $OPTF \$(DEF) \$(INC)
+LDFLAGS             = \$(ARCHARGS) $OPTF -L$INST_LIBS $LINKARGS
+OBJS                = \$(C++FILES:.cpp=.o) \$(CXXFILES:.cpp=.o) \$(CFILES:.c=.o) 
+C++                 = $COMPILER
+OTHER_LIBS          = $OTHER_LIBS
+VPATH               = ..
+
+EOF
+}
+
+
+
+generate_makerules()
+{
+    cat <<-EOF1 | sed 's/TAB/	/' 
+
+all : \$(EXEC) \$(LIB) \$(PLUGIN)
+
+\$(EXEC) : Makedepend \$(OBJS) 
+TAB\$(C++) \$(LDFLAGS) \$(OBJS) \$(LIBS) -o \$@
+
+\$(LIB) \$(PLUGIN) : \$(OBJS)
+TAB\$(C++) \$(LDFLAGS) \$(SHARED) \$(OBJS) \$(LIBS) -o \$@
+
+clean : 
+TABrm -f \$(OBJS) \$(MAKEDEPEND)
+
+clobber : clean
+TABrm -f \$(EXEC) \$(LIB) \$(PLUGIN)
+
+
+Makedepend : \$(CXXFILES) \$(CFILES) 
+TAB\$(C++) \$(INC) $DEPARG \$? > \$@
+
+
+.SUFFIXES: .cpp .o
+.cpp.o:
+TAB\$(C++) \$(CXXFLAGS) -c $<
+
+sinclude Makedepend
+
+EOF1
+}
+
+
+[ -d $INST_SRC/Make ] || mkdir -m 0755 -p $INST_SRC/Make
+
+echo =========== Installing Example Source Code =================
+
+echo "  generating make files ..."
+generate_makedefs > $INST_SRC/Make/makedefs
+generate_makerules > $INST_SRC/Make/makerules
+
+echo "  copying example files ..."
+copy_example_source
+
+exit 0
diff --git a/ossimPlanet/Make/instrules b/ossimPlanet/Make/instrules
new file mode 100644
index 0000000..bbbdb90
--- /dev/null
+++ b/ossimPlanet/Make/instrules
@@ -0,0 +1,149 @@
+install  : 
+	@rm -f $(INSTLOGFILE)
+	@$(MAKE) __instbin __instdev
+	@cat $(INSTLOGFILE)
+
+instbin instdev : 
+	@$(MAKE) __$@
+
+__instbin:
+	@$(MAKE) INSTSRC=$(TOPDIR)/bin/$(OS)$(ARCH) INSTDEST=$(INST_EXAMPLES)  \
+		INSTALL?="$(INSTBINCMD)" __install
+	@$(MAKE) INSTSRC=$(TOPDIR)/lib/$(OS)$(ARCH) INSTDEST=$(INST_LIBS)  \
+		INSTALL?="$(INSTBINCMD)" __install
+	@echo  >> $(INSTLOGFILE)
+	@echo "    Run-time environment installation successful.  Add " \
+	  >> $(INSTLOGFILE)
+	@echo "        $(INST_EXAMPLES)" \
+	  >> $(INSTLOGFILE)
+	@echo "    to your PATH environmental variable, and" \
+	  >> $(INSTLOGFILE)
+	@echo "        $(INST_LIBS) and $(INST_PLUGINS)" \
+	  >> $(INSTLOGFILE)
+	@echo "    to your LD_LIBRARY_PATH if not already present." \
+	  >> $(INSTLOGFILE)
+	@echo >> $(INSTLOGFILE)
+	
+
+__instdev:
+	@for d in `ls -1  $(TOPDIR)/include/ | grep -v CVS`;  \
+	do \
+	  if [ -d $(TOPDIR)/include/$$d ];  \
+	  then  \
+	    $(MAKE) INSTSRC=$(TOPDIR)/include/$$d INSTDEST=$(INST_INCLUDE)/$$d \
+		   INSTALL?="$(INSTDEVCMD)" __install; \
+	  fi \
+	done
+	@$(TOPDIR)/Make/instexamplesrc  \
+		$(TOPDIR) \
+		$(INST_LIBS) \
+		$(INST_INCLUDE) \
+		$(INST_SRC) \
+		$(INST_EXAMPLE_SRC) \
+		"$(INSTDEVCMD)" \
+		"$(C++)" \
+		"$(OPTF)" \
+		"$(DEPARG)" \
+		"$(LINKARGS)" \
+		"$(OTHER_LIBS)" \
+        $(MAKE)  \
+
+
+	@echo \
+	  >> $(INSTLOGFILE)
+	@echo "    Development environment installation successful.  Add" \
+	  >> $(INSTLOGFILE)
+	@echo "        -I$(INST_INCLUDE)" \
+	  >> $(INSTLOGFILE)
+	@echo "    compile flag when compiling with libwms header files." \
+	  >> $(INSTLOGFILE)
+	@echo "    Example programs can be found at $(INST_EXAMPLE_SRC)." \
+	  >> $(INSTLOGFILE)
+	@echo  >> $(INSTLOGFILE)
+	  
+instlinks : 
+	@rm -f $(INSTLOGFILE)
+	$(MAKE) INSTBINCMD="$(INSTLINKBINCMD)" __instbin
+	$(MAKE) INSTDEVCMD="$(INSTLINKDEVCMD)" __instdev
+	@cat $(INSTLOGFILE)
+
+instlinksbin :
+	@rm -f $(INSTLOGFILE)
+	$(MAKE) INSTBINCMD="$(INSTLINKBINCMD)" __instbin
+	@cat $(INSTLOGFILE)
+
+instlinksdev :
+	@rm -f $(INSTLOGFILE)
+	@$(MAKE) INSTDEVCMD="$(INSTLINKDEVCMD)" __instdev
+	@cat $(INSTLOGFILE)
+
+
+instclean : instcleanbin instcleandev
+
+instcleanbin :
+	@$(MAKE) INSTSRC=$(TOPDIR)/bin/$(OS)$(ARCH) INSTDEST=$(INST_EXAMPLES)  \
+		INSTALL?="$(INSTBINCMD)" __instclean
+	@$(MAKE) INSTSRC=$(TOPDIR)/lib/$(OS)$(ARCH) INSTDEST=$(INST_LIBS)  \
+		INSTALL?="$(INSTBINCMD)" __instclean
+
+instcleandev :
+	@for d in `ls -1  $(TOPDIR)/include/ | grep -v CVS`;  \
+	do \
+	  if [ -d $(TOPDIR)/include/$$d ];  \
+	  then  \
+	    $(MAKE) INSTSRC=$(TOPDIR)/include/$$d INSTDEST=$(INST_INCLUDE)/$$d \
+		   INSTALL?="$(INSTDEVCMD)" __instclean; \
+	  fi \
+	done
+	@for d in `ls -1  $(TOPDIR)/examples | grep -v CVS`;  \
+	do \
+	  if [ -d $(TOPDIR)/examples/$$d ];  \
+	  then  \
+	    $(MAKE) INSTSRC=$(TOPDIR)/examples/$$d INSTDEST=$(INST_EXAMPLE_SRC)/$$d \
+		   INSTALL?="$(INSTDEVCMD)" __instclean; \
+	  fi \
+	done
+
+__install :
+	@[ -n "$(INSTSRC)" ] || echo "Internal error (INSTSRC definition)"
+	@[ -n "$(INSTSRC)" ] && echo > /dev/null
+	@[ -n "$(INSTDEST)" ] || echo "Internal error (INSTDEST) definition)"
+	@[ -n "$(INSTDEST)" ] && echo > /dev/null
+	@[ -d $(INSTDEST) ] || mkdir -p $(INSTDEST)
+	@cd $(INSTSRC); \
+	THISDIR=`pwd`; \
+	if [ -n "`ls -1 | grep -v CVS`" ]; then \
+	  for f in `ls -1 | grep -v CVS`;  \
+	  do \
+	    if [ -f $$f ] ;  \
+	    then  \
+	        INSTPATH=$$THISDIR/$$f;  \
+	        $(INSTALL) $$INSTPATH $(INSTDEST)/$$f; \
+	    fi \
+	  done \
+	fi
+
+__instclean :
+	@[ -n "$(INSTSRC)" ] || echo "Internal error (INSTSRC definition)"
+	@[ -n "$(INSTSRC)" ] && echo > /dev/null
+	@[ -n "$(INSTDEST)" ] || echo "Internal error (INSTDEST definition)"
+	@[ -n "$(INSTDEST)" ] && echo > /dev/null
+	@if [ -d $(INSTDEST) ] ;  \
+	then \
+	  cd $(INSTSRC); \
+	  if [ -n "`ls -1 | grep -v CVS`" ]; then \
+	    for f in `ls -1 | grep -v CVS`;  \
+	    do \
+	      if [ -f $$f ] ;  \
+	      then  \
+	          echo "rm -f $(INSTDEST)/$$f"; \
+	          rm -f $(INSTDEST)/$$f; \
+	      fi \
+	    done \
+	  fi; \
+	  empty=`ls $(INSTDEST)`; \
+	  if [ -z "$$empty" ]; \
+	  then \
+	    rm -rf $(INSTDEST); \
+	  fi \
+	fi
diff --git a/ossimPlanet/Make/makedefs b/ossimPlanet/Make/makedefs
new file mode 100644
index 0000000..9e8448c
--- /dev/null
+++ b/ossimPlanet/Make/makedefs
@@ -0,0 +1,597 @@
+SHELL = /bin/sh
+OS := $(shell uname)
+
+include $(TOPDIR)/Make/dependencies
+
+## We don't care about architectural distinguishers in the OS
+## such as IRIX64, IRIX32, etc. so we truncate IRIX?? to IRIX
+ifeq ($(findstring IRIX,$(OS)),IRIX)
+OS := IRIX
+endif
+
+## Make CYGWIN_XXXX CYGWIN so it's "Windows cross platform" :)
+ifeq ($(findstring CYGWIN,$(OS)),CYGWIN)
+OS := CYGWIN
+#OS := MINGW
+endif
+
+# uncomment if you want allocation counting turned on.
+# Used for debugging memory leaks.
+#
+# DEF += -DOSGPLANET_ENABLE_ALLOCATION_COUNT
+# Enable Predator video (uncomment the next line)
+ifneq ("$(ENABLE_PREDATOR)","no")
+DEF += -DOSSIMPLANET_ENABLE_PREDATOR -DOSSIMPLANET_ENABLE_EPHEMERIS
+endif
+
+
+## Make MINGW_XXXX MINGW so it's "Windows cross platform" :)
+ifeq ($(findstring MINGW,$(OS)),MINGW)
+OS := MINGW
+endif
+
+# TOPDIR needs to be redefined for every GNUmakefile
+TOPDIR     ?= ../
+THISDIR    = .
+MAKEDEPEND = ignore
+
+####################################################################### 
+##
+##                   VERSIONING SEMANTICS
+##
+## Version consistes of <major> . <minor> . <release> - <revision>
+## Where:
+##    major   : Production (0 = pre-production)
+##    minor   : 0-7 = Production minor, 8 = Alpha, 9 = Beta
+##    release : Release tag
+##    revision: Release revision - 0 = development (cutting edge). 
+##
+## Usage:
+##     Default - VERSION_REVISION is set to the value defined here
+##     Env variable OSGPLANET_VERSION_REVISION overrides default    
+##           e.g.:
+##               % setenv OSGPLANET_VERSION_REVISION 5
+##               % make version
+##     Command line overrides env variable
+##               % make VERSION_REVISION=  
+####################################################################### 
+VERSION_MAJOR    = 1
+VERSION_MINOR    = 0
+VERSION_RELEASE  = 0
+VERSION_REVISION ?= 0
+VERSION       = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
+
+INC        = -I$(TOPDIR)/include
+
+############################################################################
+## NOTE - Semantics for the use of ARCH, ARCHARGS, and ARCHINST parameters
+## ARCH     - must be defined if the OS supports both 64 and 32 bit 
+##           architectures may remain undefined if it does not.
+## ARCHARGS - Compiler directives to indicate for which architecture 
+##           to build for
+## ARCHINST - Installation target directory.  Define if the OS supports 
+##           more than one architecture (32 and 64).
+##              for ARCH=32 - define ARCHINST only if the system uses an 
+##                            extension on 'lib' to indicate 32 bit.  e.g. 
+##                            IRIX defines /usr/lib32
+##              for ARCH=64 - Always define ARCHINST.  Even if the OS 
+##                            doesn't make a distinction, we will.
+############################################################################
+
+CXXFLAGS   = $(ARCHARGS) $(DOF) $(DEF) $(INC)
+LDFLAGS    = $(ARCHARGS) $(DOF) $(LINKARGS) -L$(TOPDIR)/lib/$(OS)$(ARCH) 
+OBJS       = $(C++FILES:.cpp=.o) \
+             $(CXXFILES:.cpp=.o) \
+             $(CFILES:.c=.o) \
+
+EXE_EXT    =
+
+DOF        = $(OPTF)
+DEBUGDIR   = $(OS)$(ARCH).Debug
+OPTDIR     = $(OS)$(ARCH).Opt
+BININST    = bin
+LIBINST    = lib
+
+
+ifeq ("$(INST_LOCATION)","")
+INST_LOCATION  = /usr/local
+endif
+#INST_LOCATION  = /Users/Shared/Development/package/ossimPlanetInstall
+INST_LIBS      = $(INST_LOCATION)/lib$(ARCHINST)
+INST_INCLUDE   = $(INST_LOCATION)/include
+INST_SHARE     = $(INST_LOCATION)/share
+INST_EXAMPLES  = $(INST_SHARE)/libossimplanet/bin
+INST_SRC       = $(INST_SHARE)/libossimplanet/src
+INST_EXAMPLE_SRC = $(INST_SRC)/examples
+INST_DOC       = $(INST_SHARE)/libossimplanet/doc
+INST_DATA      = $(INST_SHARE)/libossimplanet/data
+LINK           = ln -sf
+INSTBINCMD     = install -m 755
+INSTDEVCMD     = install -m 644
+INSTLINKBINCMD = $(LINK)
+INSTLINKDEVCMD = $(LINK)
+LIB_PREFIX     = lib
+LIB_EXT        = so
+PLUGIN_EXT     = so
+MAKEDIST       = echo "   === Distribution build is not implemented yet for $(OS)"; printf "\n"
+INSTLOGFILE    = /tmp/.ossimplanet_inst_log
+
+ifneq ("$(LIBWMS_INC_DIR)","")
+INC += -I$(LIBWMS_INC_DIR)
+endif
+
+ifneq ("$(LIBWMS_LIB_DIR)","")
+LDFLAGS += -L$(LIBWMS_LIB_DIR)
+endif
+
+ifneq ("$(OSSIMPREDATOR_INC_DIR)","")
+INC += -I$(OSSIMPREDATOR_INC_DIR)
+endif
+
+ifneq ("$(OSSIMPREDATOR_LIB_DIR)","")
+LDFLAGS += -L$(OSSIMPREDATOR_LIB_DIR) -lossimPredator
+endif
+
+ifneq ("$(OSSIM_INC_DIR)","")
+INC += -I$(OSSIM_INC_DIR)
+endif
+
+ifneq ("$(OSSIM_LIB_DIR)","")
+LDFLAGS += -L$(OSSIM_LIB_DIR)
+endif
+
+ifneq ("$(GPSTK_INC_DIR)","")
+INC += -I$(GPSTK_INC_DIR)
+endif
+
+ifneq ("$(GPSTK_LIB_DIR)","")
+LDFLAGS += -L$(GPSTK_LIB_DIR)
+endif
+
+ifneq ("$(OSSIM_LIB_DIR)","")
+LDFLAGS += -L$(OSSIM_LIB_DIR)
+endif
+
+ifneq ("$(OPENTHREADS_INC_DIR)","")
+INC += -I$(OPENTHREADS_INC_DIR)
+endif
+
+ifneq ("$(OPENTHREADS_LIB_DIR)","")
+LDFLAGS += -L$(OPENTHREADS_LIB_DIR)
+endif
+
+ifneq ("$(PRODUCER_INC_DIR)","")
+INC += -I$(PRODUCER_INC_DIR)
+endif
+
+ifneq ("$(PRODUCER_LIB_DIR)","")
+LDFLAGS += -L$(PRODUCER_LIB_DIR)
+endif
+
+ifneq ("$(OSG_INC_DIR)","")
+INC += -I$(OSG_INC_DIR)
+endif
+
+ifneq ("$(OSG_LIB_DIR)","")
+LDFLAGS += -L$(OSG_LIB_DIR)
+endif
+
+ifneq ("$(OSSIM_PREDATOR_LIB)","")
+LDFLAGS += -L$(OSSIM_PREDATOR_LIB)
+endif
+
+CC=gcc
+
+OSSIM_LIBS=
+OSG_LIBS          = -L/usr/local/lib64 -L/usr/local/lib -L/usr/local/bin -losgViewer -losgText -losgGA -losgDB -losgUtil -losg -lOpenThreads -lossimPredator -lossim -ljpeg -lz -lgpstk
+
+RECURSIVE_TARGETS = \
+	  opt\
+	  debug\
+	  clean\
+	  cleandepend\
+	  cleandependopt\
+	  cleandependdbg\
+	  cleandbg\
+	  cleanopt\
+	  cleantarget\
+	  cleantargetopt\
+	  cleantargetdbg\
+	  clobber\
+	  clobberdbg\
+	  clobberopt\
+	  cleantmp\
+	  docs\
+	  depend
+
+#### SUN OS Specific definitions 
+ifeq ($(OS),SunOS)
+
+  #### if useing g++ on a sun
+  ifeq ($(COMPILER),gnu)
+    C++               = g++
+    DEPARG            = -M
+    INC               += 
+    DEF               += -W -Wall -fPIC -fpermissive
+    OPTF              = -O2
+    DBGF              = -g 
+    SHARED            = -shared -fPIC 
+    ARCH              = 32
+  ifeq ($(ARCH),64)
+      ARCHARGS        = -m64 -DARCH64
+      ARCHINST        = 64 
+  else
+      ARCHARGS        = 
+  endif
+    OTHER_LIBS        = -lexpat -lcurl 
+
+  #### using forte compilers (default)
+  else
+    C++               = CC
+    DEPARG            = -xM1
+    INC               += 
+    DEF               += -features=extensions -w
+    OPTF              = -xO4
+    DBGF              = -g 
+    SHARED            = -G
+    ARCH              = 32
+  ifeq ($(ARCH),64)
+      ARCHARGS        = -xarch=v9 -DARCH64
+      ARCHINST        = 64
+  else
+      ARCHARGS        = 
+      ARCHINST        = 
+  endif
+    OTHER_LIBS        = -lCstd -lexpat -lcurl
+    LINKARGS          =  
+  endif 
+    DYNAMICLIBRARYLIB = -ldl
+    SOCKET_LIBS       = -lsocket -lnsl
+    INSTBINCMD        = cp
+    INSTDEVCMD        = cp
+    INST_LOCATION     = /opt/libossimPlanet
+    MAKEDIST          = $(TOPDIR)/Make/makepkg
+    OTHER_LIBS        = -lexpat -lcurl -lfreetype
+    PNG_LIBS          = -lpng -lz
+    JPEG_LIBS         = -ljpeg
+    GIF_LIBS          = -lungif
+    TIFF_LIB          = -ltiff -lz -ljpeg
+    FREETYPE_LIB      = -lfreetype
+endif
+
+#### IRIX Specific definitions
+ifeq ($(OS),IRIX)
+	CXX = CC
+	ifeq ($(CXX),CC)
+		LINKARGS          = -L${TOPDIR}/lib -LANG:std -OPT:Olimit=0  
+		C++               = CC
+		DEPARG            = -M
+		INC               += -I${TOPDIR}/include -I/usr/freeware/include
+		DEF               += -LANG:std -OPT:Olimit=0 \
+		                   -DEBUG:woff=1681 -DEBUG:woff=1682 -DEBUG:woff=3303\
+		                   -MDupdate $(MAKEDEPEND)
+		OPTF              = -O2 
+		DBGF              = -g 
+		SHARED            = -shared
+		PFLIBS            = \
+		                  -lpf3ds -lpfdem -lpfdted -lpfdwb -lpfdxf -lpfevt \
+		                  -lpfflt -lpfgds -lpfgfo -lpfim -lpflsa -lpflsb \
+		                  -lpfnff -lpfobj -lpfpegg -lpfpfb -lpfphd -lpfpts \
+		                  -lpfrot -lpfscale -lpfsgf -lpfsgo -lpfsphere -lpfsv \
+		                  -lpftri -lpfunc -lpfvct -lpfdu -lpfutil -lpf -all -limage
+		ARCH              = 32
+		ifeq ($(ARCH),64)
+			ARCHARGS          = -64 -DARCH64
+			ARCHINST          = 64
+			LINKARGS          += -L/usr/freeware/lib64
+			PF_XTRA_LIBS      = -L/usr/lib64/libpfdb -rpath /usr/lib64/libpfdb \
+			                     $(PFLIBS)
+		else 
+			ARCHARGS          = -n32
+			ARCHINST          = 32
+			LINKARGS          += -L/usr/freeware/lib32
+			PF_XTRA_LIBS      = -L/usr/lib32/libpfdb -rpath /usr/lib32/libpfdb \
+			                     $(PFLIBS)
+		endif
+	else		
+	 	LIBS              = -lstdc++
+		LINKARGS          = -L${TOPDIR}/lib  
+		C++               = g++
+		INC               += -I${TOPDIR}/include -I/usr/freeware/include
+		DEF               += -fPIC -W -Wno-unused 
+		OPTF              = -O2 
+		DBGF              = -g -gstabs+
+		SHARED            = -shared
+		PFLIBS            = \
+		                  -lpf3ds -lpfdem -lpfdted -lpfdwb -lpfdxf -lpfevt \
+		                  -lpfflt -lpfgds -lpfgfo -lpfim -lpflsa -lpflsb \
+		                  -lpfnff -lpfobj -lpfpegg -lpfpfb -lpfphd -lpfpts \
+		                  -lpfrot -lpfscale -lpfsgf -lpfsgo -lpfsphere -lpfsv \
+		                  -lpftri -lpfunc -lpfvct -lpfdu -lpfutil -lpf -all -limage
+		ARCH              = 32
+		ifeq ($(ARCH),64)
+			ARCHARGS          = -mabi=64 -mips4 -DARCH64
+			ARCHINST          = 64
+			LINKARGS          += -L/usr/freeware/lib64
+			PF_XTRA_LIBS      = -L/usr/lib64/libpfdb -rpath /usr/lib64/libpfdb \
+			                     $(PFLIBS)
+		else 
+			ARCHARGS          = -mabi=n32 -mips4
+			ARCHINST          = 32
+			LINKARGS          += -L/usr/freeware/lib32
+			PF_XTRA_LIBS      = -L/usr/lib32/libpfdb -rpath /usr/lib32/libpfdb \
+			                     $(PFLIBS)
+		endif	
+	endif
+
+	DYNAMICLIBRARYLIB = 
+	OTHER_LIBS        = -lm -lexpat -lcurl  -lfreetype
+	PNG_LIBS          = -lpng -lz
+	JPEG_LIBS         = -ljpeg
+	GIF_LIBS          = -lungif
+	TIFF_LIB          = -ltiff -lz -ljpeg
+	FREETYPE_LIB      = -lfreetype
+	MAKEDIST          = $(TOPDIR)/Make/makeirixdist
+endif
+
+#### Linux specific definitions
+
+ifeq ($(OS),Linux)
+
+  ifeq (x$(CXX),x)
+    C++             = g++
+  else
+    C++             = $(CXX)
+  endif
+
+  DEPARG            = -M
+  INC               += 
+
+  ifeq ($(COMPILER),intel)
+    C++             = ecc
+    LIBS            = -lgcc_s
+    DEF             += -KPIC
+    OPTF            = -O2 
+    DBGF            = -g 
+    ifeq ($(SYSARCH),ia64)
+      ARCHARGS        = 
+      ARCH            = IA64
+      ARCHINST        = IA64
+    else
+      ARCHARGS        = 
+      ARCH            = 32
+      ARCHINST        = 
+    endif
+  else
+    LIBS            = -lstdc++
+    DEF             += -W -Wall -fPIC
+    OPTF            = -O2 
+    DBGF            = -g -gstabs+
+    SYSARCH           := $(shell arch)
+    ifeq ($(SYSARCH),x86_64)
+      ARCHARGS        =
+      ARCH            = 64
+      ARCHINST        = 64
+    else
+      ARCHARGS        = 
+      ARCH            = 32
+      ARCHINST        = 
+    endif
+  endif
+
+
+  SHARED            = -shared
+  DYNAMICLIBRARYLIB = -ldl
+  PF_XTRA_LIBS      = -L/usr/lib/libpfdb   -Xlinker -rpath /usr/lib/libpfdb \
+                      -lpfdu -lpfutil -lpf -lossimPredator
+  SOCKET_LIBS       = 
+  OTHER_LIBS        = -lwms -lexpat -lcurl -lfreetype
+  PNG_LIBS          = -lpng -lz
+  JPEG_LIBS         = -ljpeg
+  GIF_LIBS          = -lungif
+  TIFF_LIB          = -ltiff -lz -ljpeg
+  FREETYPE_LIB      = -lfreetype
+  MAKEDIST          = $(TOPDIR)/Make/makerpms
+endif
+
+#### FreeBSD specific definitions
+ifeq ($(OS),FreeBSD)
+  C++               = g++
+  DEPARG            = -MM
+  INC               +=  -I/usr/local/include
+  DEF               += -W -Wall
+  OPTF              = -O2 
+  DBGF              = -g 
+  SHARED            = -shared
+  ARCH              = 
+  ARCHINST          = 
+  ARCHARGS          = 
+  LINKARGS          = -L/usr/local/lib -rpath /usr/local/lib
+ DYNAMICLIBRARYLIB = 
+  SOCKET_LIBS       = 
+  OTHER_LIBS        = -lwms -lexpat -lcurl -lfreetype
+  PNG_LIBS          = -lpng -lz
+  JPEG_LIBS         = -ljpeg
+  GIF_LIBS          = -lungif
+  TIFF_LIB          = -ltiff -lz -ljpeg
+  FREETYPE_LIB      = -lfreetype
+endif
+
+#### MacOS X specific definitions
+ifeq ($(OS),Darwin)
+  ifeq (x$(CXX),x)
+    C++             = g++
+  else
+    C++             = $(CXX)
+  endif
+  INC               += -F/System/Library/Frameworks -I/opt/local/include
+  LDFLAGS	    += -F/System/Library/Frameworks -L/usr/X11R6/lib -L/opt/local/lib
+  DEF               += -Wall -D__USE_OSX_AGL_IMPLEMENTATION__
+  OPTF              = -O2
+  DBGF              = -g
+  DEPARG            = -M $(DEF)
+  SHARED            = -dynamic
+  ARCH              = 32
+  ARCHINST          = 
+  ARCHARGS          = 
+  LINKARGS          =
+  DYNAMICLIBRARYLIB =
+  CARBON_LIB        = -framework Carbon
+#  OTHER_LIBS        = -lm -lstdc++ -lwms -lexpat -lcurl -ljpeg -lOpenThreads -lossim -llammpi++ -lmpi -llam -llammpio -flat_namespace -undefined suppress -lfreetype -lpng12
+  OTHER_LIBS        = -lm -lstdc++ -lwms -lexpat -lcurl -ljpeg -lOpenThreads -lossim -flat_namespace -undefined suppress -lfreetype -lpng12 -framework OpenGL
+  PNG_LIBS          = -lpng -lz
+  JPEG_LIBS         = -ljpeg
+  GIF_LIBS          = -lungif
+  TIFF_LIB          = -ltiff -lz -ljpeg
+  FREETYPE_LIB      = -lfreetype
+  X_INC             = -I/usr/X11R6/include
+  X_LIBS            = -lX11 
+  LIB_EXT           = dylib
+  LIBVERSION	    = -current_version $(VERSION) \
+                        -compatibility_version \
+                        $(VERSION_MAJOR).$(VERSION_MINOR).0
+
+  ifeq ($(DARWIN_QUICKTIME),yes)
+    DEF             += -DDARWIN_QUICKTIME
+  endif
+
+  QUICKTIME	    = -framework QuickTime $(CARBON_LIB)
+
+endif
+
+#### Cygwin specific definitions
+ifeq ($(OS),CYGWIN)
+  C++               = c++
+  DEPARG            = -M
+  INC               += 
+  DEF               += -DWIN32 -W -Wall -DNOMINMAX -D_WIN32_IMPLEMENTATION
+  OPTF              = -O2 
+  DBGF              = -g 
+  SHARED            = -shared\
+                        -Wl,--out-implib,$(TOPDIR)/lib/$(OS)/lib$(TARGET_BASENAME).dll.a -Wl,--export-all-symbols
+
+  EXE_EXT           =.exe
+  ARCH              = 
+  ARCHINST          =
+  ARCHARGS          = 
+  LINKARGS          = -W -Wall
+  DYNAMICLIBRARYLIB =
+  SOCKET_LIBS       = 
+  OTHER_LIBS        = -lwms -lexpat `curl-config --libs`  -lfreetype -ljpeg -lz -lOpenThreads
+  PNG_LIBS          = -lpng -lz
+  JPEG_LIBS         = -ljpeg
+  GIF_LIBS          = -lungif
+  TIFF_LIB          = -ltiff -lz -ljpeg
+  FREETYPE_LIB      = -lfreetype
+
+  LIBINST    = bin
+  PLUGININST = bin/$(OS)$(ARCH)
+
+  LIB_PREFIX        = cyg
+  LIB_EXT           = dll
+  PLUGIN_EXT        = dll
+  LINK              = cp -f
+  INST_LOCATION   = /usr/local/libossimPlanet
+  INST_LIBS         = $(INST_LOCATION)/bin
+  INST_PLUGINS      = $(INST_LOCATION)/bin
+  INST_INCLUDE      = $(INST_LOCATION)/include
+  INST_SHARE_PREFIX = /usr/local/libossimPlanet
+  INST_SRC          = $(INST_SHARE_PREFIX)/src
+  INST_EXAMPLES        = $(INST_SHARE_PREFIX)/bin
+  INST_EXAMPLE_SRC     = $(INST_SHARE_PREFIX)/src/demos
+  INST_DOC          = $(INST_SHARE_PREFIX)/doc
+  INST_DATA         = $(INST_SHARE_PREFIX)/data
+  MAKEDIST          = $(TOPDIR)/Make/makeinnosetup
+endif
+
+#### Mingw specific definitions
+ifeq ($(OS),MINGW)
+  C++               = c++ -mthreads
+  DEPARG            = -M
+  INC               += -I/usr/local/include -I/usr/local/include/ossim -I$(HOME)/ossim/src/packages/gdal/frmts/jpeg/libjpeg -I$(HOME)/ossim/src/packages/gdal/frmts/gtiff/libtiff
+   DEF               += -DWIN32 -Wall -DOSSIMUSINGDLL 
+# -W
+  OPTF              = -O2 
+  DBGF              = -g 
+  SHARED            = -shared -mthreads \
+                      -Wl,--out-implib,$(TOPDIR)/lib/$(OS)/lib$(TARGET_BASENAME).dll.a -Wl,--export-all-symbols
+
+  EXE_EXT           =.exe
+  ARCH              = 
+  ARCHINST          =
+  ARCHARGS          = 
+  LINKARGS          = -W -Wall
+  DYNAMICLIBRARYLIB =
+  OTHER_LIBS        = -L/usr/local/lib/ossim -L/usr/local/bin -L/usr/local/lib -lwms -lglu32 -lopengl32
+
+  LIBINST    = bin
+  PLUGININST = bin/$(OS)$(ARCH)
+
+  LIB_PREFIX        = lib
+  LIB_EXT           = dll
+  PLUGIN_EXT        = dll
+  LINK              = cp -f
+  INST_LOCATION     = /usr/local
+  INST_LIBS         = $(INST_LOCATION)/bin
+  INST_PLUGINS      = $(INST_LOCATION)/bin
+  INST_INCLUDE      = $(INST_LOCATION)/include
+  INST_SHARE_PREFIX = /usr/local
+  INST_SRC          = $(INST_SHARE_PREFIX)/src
+  INST_EXAMPLES     = $(INST_SHARE_PREFIX)/bin
+  INST_EXAMPLE_SRC  = $(INST_SHARE_PREFIX)/src/examples
+  INST_DOC          = $(INST_SHARE_PREFIX)/doc
+  INST_DATA         = $(INST_SHARE_PREFIX)/data
+  PNG_LIBS          = 
+  JPEG_LIBS         = 
+  GIF_LIBS          = 
+  TIFF_LIB          = 
+  FREETYPE_LIB      = -lfreetype
+endif
+
+#### HP-UX Specific definitions
+# contributed by tino.schwarze at informatik.tu-chemnitz.de
+
+ifeq ($(OS),HP-UX)
+
+  C++               = g++
+  DEPARG            = -M
+  INC               += 
+  DEF               += -W -Wall -fPIC
+  OPTF              = -O2 
+  # gcc 3.1 uses DWARF as default, my GDB might not yet support this...
+  # at least I've got problems everywhere
+  DBGF              = -g -gstabs+ 
+  SHARED            = -shared -fPIC
+  ARCH              = 32
+ifeq ($(ARCH),64)
+    # not yet tested
+    ARCHARGS          = -march=2.0 -DARCH64
+    ARCHINST          = 64
+else
+   # at least my gcc 3.1 defaults to HP-PA RISC 1.1
+  ARCHARGS          = 
+  ARCHINST          = 
+endif
+  LINKARGS          = 
+  LIB_EXT           = sl
+  PLUGIN_EXT        = sl
+  DYNAMICLIBRARYLIB = -ldld
+  SOCKET_LIBS       = 
+  # make sure that global constructors/destructors are called upon
+  # shl_load() / shl_unload() - this is a gcc specific workaround
+  OTHER_LIBS        = -lm -Wl,+init -Wl,_GLOBAL__DI -Wl,+fini -Wl,_GLOBAL__DD -lexpat -lcurl -lfreetype
+  FREETYPE_INCLUDE  = -I/opt/freetype/include -I/opt/freetype/include/freetype2
+  FREETYPE_LIB      = -L/opt/freetype/lib -lfreetype
+  PNG_INCLUDE       = -I/opt/libpng/include
+  PNG_LIBS          = -L/opt/libpng/lib -lpng -L/opt/zlib/lib -lz
+  JPEG_INCLUDE		= -I/opt/jpeg-6/include
+  JPEG_LIBS         = -L/opt/jpeg-6/lib -ljpeg
+  TIFF_INCLUDE      = -I/opt/tiff-3.5/include
+  TIFF_LIB          = -L/opt/tiff-3.5/lib -ltiff
+  GIF_INCLUDE		= -I/opt/libungif/include
+  GIF_LIBS          = -L/opt/libungif/lib -lungif
+
+endif
+
+VPATH=..
+
diff --git a/ossimPlanet/Make/makedirdefs b/ossimPlanet/Make/makedirdefs
new file mode 100644
index 0000000..61c2cb6
--- /dev/null
+++ b/ossimPlanet/Make/makedirdefs
@@ -0,0 +1,26 @@
+
+################################################################
+# Directories traversed from the top level
+TOP_LEVEL_DIRS = \
+		src \
+		examples
+
+
+################################################################
+# Directories traversed in the TOPDIR/src directory
+SRC_DIRS = ossimPlanet
+
+
+SRC_DIRS += \
+	../examples
+
+################################################################
+# Directories traversed in the TOPDIR/src/osgPlugins directory
+
+PLUGIN_DIRS = 
+
+
+EXAMPLE_DIRS = \
+		ossimplanetviewer \
+		ossimplanettest		
+
diff --git a/ossimPlanet/Make/makedirrules b/ossimPlanet/Make/makedirrules
new file mode 100644
index 0000000..68056f5
--- /dev/null
+++ b/ossimPlanet/Make/makedirrules
@@ -0,0 +1,6 @@
+
+default : $(DIRS)
+	@for f in $(DIRS); do echo "Entering directory $$f"; cd $$f; $(MAKE) $@ || exit 1; cd ..; done
+
+$(RECURSIVE_TARGETS) :  $(DIRS)
+	@for f in $(DIRS); do echo "Entering directory $$f"; cd $$f; $(MAKE) $@ || exit 1; cd ..; done
diff --git a/ossimPlanet/Make/makeinnosetup b/ossimPlanet/Make/makeinnosetup
new file mode 100755
index 0000000..88ab159
--- /dev/null
+++ b/ossimPlanet/Make/makeinnosetup
@@ -0,0 +1,152 @@
+#!/bin/sh
+
+VERSION=`make -s version`
+
+print_header()
+{
+    cat <<- EOF 
+[Setup]
+AppName=Open Scene Graph
+AppVerName=Open Scene Graph $VERSION
+AppPublisher=OpenSceneGraph
+AppPublisherURL=http://www.openscenegraph.com
+AppSupportURL=http://www.openscenegraph.com
+AppUpdatesURL=http://www.openscenegraph.com
+DefaultDirName={pf}\OpenSceneGraph
+DisableDirPage=yes
+DefaultGroupName=OpenSceneGraph
+DisableProgramGroupPage=yes
+LicenseFile=LICENSE.txt
+EOF
+}
+
+# Usage:
+# do_dir $DIR
+#
+
+print_file_entry()
+{
+    DIR=$1
+    FILE=$2
+    printf "Source: \"%s\\\%s\"; DestDir: \"{app}\\\%s\\\"; Flags: ignoreversion\n"\
+            $DIR $FILE  $DIR
+
+}
+
+do_dir()
+{
+    DIR=$1
+    shift;
+
+    DOS_DIR=`echo $DIR | sed 's/\\//\\\/g'`
+
+    if [ $# -gt 0 ]
+    then 
+	while [ $# -gt 0 ]
+        do
+	    match=$1
+            shift;
+	    for f in `find $DIR -type f | \
+				grep -v CVS | \
+				grep osg |
+				grep "$match"` 
+            do
+		print_file_entry $DOS_DIR `basename $f`
+            done
+        done
+    else
+	for f in `find $DIR -type f | grep -v CVS | grep osg`
+        do
+	    print_file_entry $DOS_DIR `basename $f`
+	done
+ 
+    fi
+}
+
+print_files()
+{
+    echo "[Files]"
+
+    do_dir lib .lib
+    do_dir bin .exe .dll
+    for dir in `ls -1 include | grep osg | grep -v CVS`
+    do
+        do_dir include/"$dir"
+    done
+}
+
+print_script()
+{
+    print_header 
+    print_files  
+}
+
+BUILD_ISS=1
+BUILD_DISTRIBUTION=1
+CLEAN_UP=1
+
+while [ $# -gt 0 ]
+do
+    case $1 in
+       -c )
+            BUILD_ISS=0
+            BUILD_DISTRIBUTION=0
+            CLEAN_UP=1
+            ;;
+
+       -d )
+	    BUILD_ISS=0
+            BUILD_DISTRIBUTION=1
+            CLEAN_UP=0
+		;;
+
+       -n )
+	   CLEAN_UP=0
+	    ;;
+
+       -s )
+           BUILD_ISS=1
+           BUILD_DISTRIBUTION=0
+           CLEAN_UP=0
+           ;;
+    esac
+
+    shift;
+done
+
+if [ $BUILD_ISS = 1 ]
+then
+    echo Building Inno Setup script ....
+    rm -f osg.iss
+	
+    print_script | awk '{ printf "%s\r\n", $0 }' > osg.iss
+fi
+
+if [ $BUILD_DISTRIBUTION = 1 ]
+then
+    echo Building distribution ...
+    OS=`uname | cut -b1-6`
+
+    if [ "$OS" = "CYGWIN" ]
+    then 
+        C:/Program\ Files/Inno\ Setup\ 3/iscc.exe osg.iss
+        [ -d dist/Win32 ] || mkdir -p dist/Win32
+        mv Output/setup.exe dist/Win32/OpenSceneGraph_"$VERSION"_setup.exe
+        rm -rf Output
+     else
+        echo "     Distribution may only be built under Cygwin with Inno Setup"
+    fi
+fi
+
+if [ $CLEAN_UP = 1 ]
+then
+    echo Cleaning up...
+    rm -f osg.iss
+fi
+
+
+
+
+
+
+
diff --git a/ossimPlanet/Make/makeirixdist b/ossimPlanet/Make/makeirixdist
new file mode 100755
index 0000000..5340687
--- /dev/null
+++ b/ossimPlanet/Make/makeirixdist
@@ -0,0 +1,158 @@
+#!/bin/sh
+
+echo_idb()
+{
+
+## EOE 
+    #####################################################################
+    #  Capture bin directory
+
+    dd=`echo $INST_EXAMPLES | sed -e 's/\///'`
+    echo d 0755 root sys $dd $dd osg.eoe.sw
+    cd bin
+    for f in `find . -type l -print | grep -v CVS | sed -e 's/\.\///' | grep -v "\."`
+    do
+	echo f 0755 root sys $dd/$f $dd/$f osg.eoe.sw
+    done
+    cd ..
+
+    #####################################################################
+    #  Capture lib and lib/osgPlugins directory
+
+    dd=`echo $INST_LIBS | sed -e 's/\///'`
+    echo d 0755 root sys $dd $dd osg.eoe.sw
+    echo d 0755 root sys $dd/osgPlugins $dd/osgPlugins osg.eoe.sw
+    cd lib
+    for f in `find . -type l -print | grep -v CVS | sed -e 's/\.\///' `
+    do
+	echo f 0755 root sys $dd/$f $dd/$f osg.eoe.sw
+    done
+    cd ..
+
+## DEV
+    #####################################################################
+    #  Capture include directories and files
+    dd=`echo $INST_INCLUDE | sed -e 's/\///'`
+
+    cd include
+    
+    echo d 0755 root sys $dd $dd osg.dev.sw
+    for d in  `find . -type d -print | grep -v CVS | sed -e 's/\.\///' | grep -v "\."`
+    do
+        echo d 0755 root sys $dd/$d $dd/$d osg.dev.sw
+    done
+    cd ..
+
+    #####################################################################
+    #  Capture installed example source
+
+     dd=`echo $INST_SRC | sed -e 's/\///'`
+     THISDIR=`pwd`
+     cd $INST_SRC
+     for d in `find . -type d -print | sed -e 's/\.\///' | grep -v "\." `
+     do
+         echo d 0755 root sys $dd/$d $dd/$d osg.dev.sw
+     done
+     for f in `find . -type f -print | sed -e 's/\.\///'`
+     do
+         echo f 0755 root sys $dd/$f $dd/$f osg.dev.sw
+     done
+     cd $THISDIR
+}
+
+make_idb()
+{
+    echo_idb | sort -k5
+}
+
+make_spec()
+{
+    cat <<- SPEC_EOF  
+product osg
+    id "Open Scene Graph `bin/osgversion`"
+    image eoe
+        id "Open Scene Graph `bin/osgversion` Run-Time Environment"
+        version `bin/osgversion`
+        order 9999
+        subsys sw default
+            id "Open Scene Graph `bin/osgversion` Run-Time Environment"
+            replaces self
+            exp osg.eoe.sw
+        endsubsys
+    endimage
+    image dev
+        id "Open Scene Graph `bin/osgversion` Development Environment"
+        version `bin/osgversion`
+        order 9999
+        subsys sw default
+            id "Open Scene Graph `bin/osgversion` Development Environment"
+            replaces self
+            exp osg.dev.sw
+        endsubsys
+    endimage
+endproduct
+SPEC_EOF
+}
+
+intro()
+{
+    echo; echo;
+    echo "============ Building the $OS Distribution Package ==================="
+    echo ""
+    echo "    Please note that this script requires that" 
+    echo 
+    echo "        'make install' "
+    echo 
+    echo "    be previously run.  Please run "
+    echo 
+    echo "        'make distribution' "
+    echo 
+    echo "    with the same arguments (if any) as 'make install'"
+    echo
+    repeat=1
+    while [ $repeat = 1 ] 
+    do 
+      printf "    Continue? (y/n) [y]: "
+      read resp
+      case $resp in  
+       ""|Yes|YES|yes|Y|y) repeat=0 ;; 
+	        n|N|no|NO) return 1; repeat=0;;
+                *)         repeat=1;; 
+      esac
+   done
+
+   return 0
+}
+
+OS=$1
+TOPDIR=$2
+INST_LIBS=$3
+INST_PLUGINS=$4
+INST_INCLUDE=$5
+INST_EXAMPLES=$6
+INST_SRC=$7
+INST_EXAMPLE_SRC=$8
+shift;shift; shift;shift; shift;shift; shift;shift;
+INST_DOC=$1
+INST_DATA=$2
+
+
+intro || exit 0
+
+make_spec > dist/Irix/osg.spec
+make_idb > dist/Irix/osg.idb
+
+DIST_DIR=Distribution-`bin/osgversion`
+
+cd dist/Irix
+rm -rf $DIST_DIR
+mkdir $DIST_DIR
+/usr/sbin/gendist -sbase / -idb osg.idb -spec osg.spec -dist $DIST_DIR
+cd $DIST_DIR
+tar cvf ../osg.tardist *
+mv ../osg.tardist .
+cd ../../../
+
+
+
+exit 0
diff --git a/ossimPlanet/Make/makepkg b/ossimPlanet/Make/makepkg
new file mode 100755
index 0000000..3f9f3ed
--- /dev/null
+++ b/ossimPlanet/Make/makepkg
@@ -0,0 +1,220 @@
+#!/bin/sh
+
+
+die()
+{
+    echo >& $1
+    exit 1
+}
+
+x() 
+{ 
+    echo $*
+    $* 
+}
+
+
+
+print_pkginfo()
+{
+    
+    __pstamp=`fgrep $LOGNAME /etc/passwd | cut -f5 -d":"`
+    cat <<- EOF
+PKG="$1"
+NAME="$2"
+`[ "$OS" = "SunOS" ] && echo ARCH=sparc`
+VERSION=`gmake -s version`
+CATEGORY="application,graphics,opengl"
+DESC="$3"
+BASEDIR="/opt/"
+VENDOR="OpenSceneGraph"
+EMAIL="info at openscenegraph.org"
+PSTAMP=$__pstamp
+URL="http://openscenegraph.org"
+MAXINST="1"
+EOF
+
+}
+
+print_prototype()
+{
+    echo "i pkginfo"
+    [ -f depend ] && echo "i depend"
+
+    for d in $*
+    do
+	d=`echo $d | sed 's/\/opt\///` 
+        echo "d none $d ? root sys"
+    done
+
+    for d in $*
+    do
+	for f in `ls -1 $d`
+	do 
+	     f=$d/$f
+	     if [ -f $f ] 
+	     then
+ 		[ -x $f ] && MODE=0555 || MODE=0444
+		dest=`echo $f | sed 's/\/opt\///'`
+	        echo "f none $dest=$f $MODE root sys"
+	     fi
+	done
+    done
+
+}
+
+make_installable()
+{
+    PKGNAME=$1
+    PKGDIR=$PKGNAME.pkg
+    DISTNAME="$PKGNAME"-"`gmake -s version`"-"$OS".shar
+
+    THISDIR=`pwd`
+    cd $PKGSUBDIR
+
+    cat << INSTALL_EOF > $DISTNAME
+
+#!/bin/sh
+cat <<-	 'LEOF' | uudecode -p | gzip -d -c | tar xvf -
+`tar cvf - $PKGDIR | gzip | uuencode .tmpuu`
+LEOF
+
+/bin/sh << EOF
+echo =========== INSTALLING  $DISTNAME =================
+pkgadd -d $PKGNAME.pkg $PKGNAME
+rm -rf $PKGDIR
+EOF
+
+
+INSTALL_EOF
+
+    chmod +x $DISTNAME
+    cd $THISDIR
+}
+
+
+make_package()
+{
+    PKGNAME=$1
+    PKGDIR=$PKGSUBDIR/$PKGNAME.pkg
+    x rm -rf $PKGDIR
+    x mkdir  $PKGDIR
+
+    echo Making pkginfo ...
+    print_pkginfo "$1" "$2" "$3"  > $PKGDIR/pkginfo
+
+    shift; shift; shift
+
+    echo Making prototype ...
+
+    print_prototype  $*  > $PKGDIR/prototype
+
+#    DISTNAME="$PKGNAME"-"`$TOPDIR/bin/osgversion`"-"$OS"-"local"
+
+    THISDIR=`pwd`
+    x cd $PKGDIR
+    x pkgmk -d .
+    x cd $THISDIR
+#    make_installable $PKGNAME $PKGDIR $DISTNAME 
+#    x pkgtrans -s $PKGDIR $DISTNAME $PKGNAME
+#    x mv "$PKGDIR"/"$DISTNAME" "$PKGDIR"/..
+}
+
+
+intro()
+{
+    echo; echo;
+    echo "============ Building the $OS Distribution Package ==================="
+    echo ""
+    echo "    Please note that this script requires that" 
+    echo 
+    echo "        'make install' "
+    echo 
+    echo "    be previously run.  Please run "
+    echo 
+    echo "        'make distribution' "
+    echo 
+    echo "    with the same arguments (if any) as 'make install'"
+    echo
+    repeat=1
+    while [ $repeat = 1 ] 
+    do 
+      printf "    Continue? (y/n) [y]: "
+      read resp
+      case $resp in  
+       ""|Yes|YES|yes|Y|y) repeat=0 ;; 
+	        n|N|no|NO) return 1; repeat=0;;
+                *)         repeat=1;; 
+      esac
+   done
+
+   return 0
+}
+
+intro || exit 0
+
+OS=$1
+TOPDIR=$2
+INST_LIBS=$3
+INST_PLUGINS=$4
+INST_INCLUDE=$5
+INST_EXAMPLES=$6
+INST_SRC=$7
+INST_EXAMPLE_SRC=$8
+shift;shift; shift;shift; shift;shift; shift;shift;
+INST_DOC=$1
+INST_DATA=$2
+
+
+PKGSUBDIR=dist/PKG
+
+make_package\
+	"OpenSceneGraph" \
+	"Open Scene Graph - Run-time environment"\
+	"An OpenGL based scene graph. This installation includes a set of run-time libraries, and example programs"\
+        $INST_LIBS $INST_PLUGINS $INST_EXAMPLES\
+
+make_installable "OpenSceneGraph"
+
+#
+# Capture include directories
+#
+SUBDIRS=`ls $TOPDIR/include | grep -v CVS`
+INSTARG=""
+for d in $SUBDIRS
+do
+    dd="$INST_INCLUDE"/"$d"
+    [ -d $dd ] && INSTARG="$INSTARG $dd"
+done
+
+#
+# Capthre examples subdirectories
+#
+SUBDIRS=`ls $TOPDIR/src/examples | grep -v CVS`
+for d in $SUBDIRS
+do
+    dd="$INST_EXAMPLE_SRC"/"$d"
+    [ -d $dd ] && INSTARG="$INSTARG $dd"
+done
+
+#
+# Capture Make subdirectory
+#
+dd="$INST_SRC"/"Make"
+
+echo dd is $dd
+ls $dd
+
+[ -d $dd ] && INSTARG="$INSTARG $dd"
+
+
+make_package\
+	"OpenSceneGraph-dev"\
+	"Open Scene Graph - Development environment"\
+	"An OpenGL based scene graph. This installation includes header files and example program source files"\
+	$INSTARG
+
+make_installable "OpenSceneGraph-dev"
+
+
+exit 0
diff --git a/ossimPlanet/Make/makerpms b/ossimPlanet/Make/makerpms
new file mode 100755
index 0000000..5764f76
--- /dev/null
+++ b/ossimPlanet/Make/makerpms
@@ -0,0 +1,200 @@
+#!/bin/sh
+
+die()
+{
+    echo $1
+    exit 1
+}
+
+
+s_install()
+{
+    src_DIR=$1
+    mode=$2
+    dst_DIR=$RPM_BUILD_DIR/`echo $3 | sed 's/\///'`	
+
+    [ -d $dst_DIR ] || mkdir -p $dst_DIR
+
+    THISDIR=`pwd`
+    cd $src_DIR
+    for f in `ls -1`
+    do
+        if [ -f $f ]
+	then
+	   install -m $mode $f $dst_DIR/$f
+	fi
+    done
+    cd $THISDIR
+}
+
+
+print_attr()
+{
+    dst_DIR=$1
+    mode=$2
+    t_dir=$RPM_BUILD_DIR/$dst_DIR
+
+    THISDIR=`pwd`
+    cd $t_dir
+    for f in `ls -1`
+    do
+        [ -f $f ] && echo "%attr($mode, root, root) $dst_DIR/$f"
+    done
+    cd $THISDIR
+}
+
+make_targz()
+{
+    THISDIR=`pwd`
+    src_dir=$1
+    cd $RPM_BUILD_DIR/..
+    tar cvf - $src_dir |\
+	gzip > /usr/src/redhat/SOURCES/$src_dir.tar.gz
+    cd $THISDIR
+}
+
+make_spec()
+{
+    name=$1
+    cat <<-LEOF > $TOPDIR/dist/RPM/$name.spec
+
+Summary: libwms - get and parse wms data
+Name: $name
+Version: $REV
+Release: $REL
+Copyright: LGPL
+Group: Graphics
+Source: $name-$REV.tar.gz
+URL: http://www.flids.com
+Packager: `awk -f - /etc/passwd <<-EOF
+BEGIN { FS=":"}
+{
+    if( \\$1 == "$LOGNAME" )
+    print \\$5
+}
+EOF`
+
+%description
+
+
+%prep
+
+%setup
+
+%build
+
+%install
+
+cd $RPM_BUILD_DIR 
+tar cvf - . | tar xvfC - /
+
+# ---------------------
+# FILES Sections
+%files
+
+LEOF
+}
+
+
+make_wms()
+{
+    RPM_BUILD_DIR=/usr/src/redhat/BUILD/libwms-$REV
+    rm -rf $RPM_BUILD_DIR
+    mkdir $RPM_BUILD_DIR
+
+    s_install $TOPDIR/lib 755 $INST_LIBS
+    s_install $TOPDIR/bin 755 $INST_EXAMPLES
+
+    make_targz -$REV
+    make_spec libwms
+
+    print_attr $INST_LIBS 755    >> $TOPDIR/dist/RPM/libwms.spec
+    print_attr $INST_EXAMPLES 755   >> $TOPDIR/dist/RPM/libwms.spec
+
+    rpmbuild -bb --clean $TOPDIR/dist/RPM/libwms.spec
+
+    mv /usr/src/redhat/RPMS/i386/libwms-$REV-$REL.i386.rpm dist/RPM
+}
+
+make_wms_dev()
+{
+    RPM_BUILD_DIR=/usr/src/redhat/BUILD/libwms_dev-$REV
+    rm -rf $RPM_BUILD_DIR
+    mkdir $RPM_BUILD_DIR
+
+    for d in `ls $TOPDIR/include | grep -v CVS`
+    do
+        [ -d $TOPDIR/include/$d ] && \
+            s_install $TOPDIR/include/$d 644 $INST_INCLUDE/$d
+    done
+
+
+    for d in `ls -1 $INST_EXAMPLE_SRC`
+    do
+        if [ -d $INST_EXAMPLE_SRC/$d ] 
+        then
+           s_install $INST_EXAMPLE_SRC/$d 644 $INST_EXAMPLE_SRC/$d
+        fi
+        cd $THISDIR
+    done
+
+    s_install $INST_SRC/Make 644 $INST_SRC/Make
+
+
+    make_targz libwms_dev-$REV
+    make_spec libwms_dev
+
+    for d in `ls -1 $RPM_BUILD_DIR/$INST_INCLUDE`
+    do
+        print_attr $INST_INCLUDE/$d 755  >> $TOPDIR/dist/RPM/libwms_dev.spec
+    done
+
+    for d in `ls -1 $RPM_BUILD_DIR/$INST_EXAMPLE_SRC`
+    do
+        print_attr $INST_EXAMPLE_SRC/$d 755  >> $TOPDIR/dist/RPM/libwms_dev.spec
+    done
+
+    print_attr $INST_SRC/Make 755 >>  $TOPDIR/dist/RPM/libwms_dev.spec
+
+    rpm -ba --clean $TOPDIR/dist/RPM/libwms_dev.spec
+
+    mv /usr/src/redhat/RPMS/i386/libwms_dev-$REV-$REL.i386.rpm dist/RPM
+}
+
+if [ "`whoami`" != "root" ] 
+then
+    echo
+    echo  "    === makerpm : You must be root do make the RPM distribution."
+    echo
+    exit 1
+fi
+
+if [ $# -ne 9 ] 
+then
+    echo
+    echo makerpm : Internal Error - Bad Usage
+    echo 
+    exit 1
+fi
+
+OS=$1
+TOPDIR=$2
+INST_LIBS=$3
+INST_INCLUDE=$4
+INST_EXAMPLES=$5
+INST_SRC=$6
+INST_EXAMPLE_SRC=$7
+VERSION=$8
+shift; shift;shift; shift;shift; shift;shift;shift;
+INST_DOC=$1
+
+REV=$VERSION
+REL=1
+
+make_wms
+
+make_wms_dev
+
+
+
+exit 0
diff --git a/ossimPlanet/Make/makerules b/ossimPlanet/Make/makerules
new file mode 100644
index 0000000..b3e32de
--- /dev/null
+++ b/ossimPlanet/Make/makerules
@@ -0,0 +1,199 @@
+
+default: opt 
+
+opt: $(EXEC:=.opt)\
+	$(LIB:=.opt)\
+	$(PLUGIN:=.opt)
+
+debug: $(EXEC:=.dbg)\
+	$(LIB:=.dbg)\
+	$(PLUGIN:=.dbg)
+
+cleandepend: cleandependopt cleandependdbg
+
+cleandependopt:
+	@[ -d $(OPTDIR) ] && cd $(OPTDIR); rm -f Makedepend; rm -rf .depend
+
+cleandependdbg:
+	@[ -d $(DEBUGDIR) ] && cd $(DEBUGDIR); rm -f Makedepend; rm -rf .depend
+
+cleantarget: cleantargetopt cleantargetdbg
+
+cleantargetopt: 
+	@[ -d $(OPTDIR) ] && cd $(OPTDIR); rm -f $(EXEC) $(LIB) $(PLUGIN)
+
+cleantargetdbg: 
+	@[ -d $(DEBUGDIR) ] && cd $(DEBUGDIR); rm -f $(EXEC) $(LIB) $(PLUGIN)
+
+clean: cleanopt cleandbg cleantmp cleandepend
+
+cleanopt: 
+	@[ -d $(OPTDIR) ] && cd $(OPTDIR); rm -f $(OBJS) Makedepend; rm -rf .depend
+
+cleandbg: 
+	@[ -d $(DEBUGDIR) ] && cd $(DEBUGDIR); rm -f $(OBJS) Makedepend; rm -rf .depend
+
+clobber: clobberdbg clobberopt
+
+clobberopt: 
+	rm -rf $(OPTDIR)
+
+clobberdbg: 
+	rm -rf $(DEBUGDIR)
+
+cleanlib:
+	rm -rf $(TOPDIR)/lib/*
+
+cleanbin:
+	rm -rf $(TOPDIR)/bin/*
+
+cleandoc:
+	rm -rf $(TOPDIR)/doc/*
+
+cleantmp: 
+	@for f in * ; do [ -d $$f ]||rm -f $$f~; done
+
+docs:
+	[ "$(TARGET_BASENAME)" != "" ] && \
+	mkdir -p $(TOPDIR)/doc/$(TARGET_BASENAME) && \
+	doc++ -d $(TOPDIR)/doc/doc++/$(TARGET_BASENAME) -H -A \
+	    $(TOPDIR)/include/$(TARGET_BASENAME)/* && \
+	echo "$(TARGET_BASENAME) HTML documentation created in "\
+	     "$(TOPDIR)/doc/doc++/$(TARGET_BASENAME)"
+
+
+$(EXEC): $(OBJS) 
+	$(C++) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
+
+
+## Mac OSX makes the distinction between -dynamiclib and -bundle
+## causing us to have to make a special case here, rather than 
+## just redefining the SHARED argument.
+
+ifeq ($(OS),Darwin)
+
+$(LIB): $(OBJS)
+	$(C++) $(LDFLAGS) $(LIBVERSION) -dynamiclib $(OBJS) $(LIBS) -o $@
+
+$(PLUGIN): $(OBJS)
+	$(C++) $(LDFLAGS) -bundle $(OBJS) $(LIBS) -o $@
+else
+ifeq ($(OS),HP-UX)
+# we need to explicitly tell the linker the library name - else it will
+# include paths like ../../../libosg.sl into executables
+$(LIB) $(PLUGIN) : $(OBJS)
+	$(C++) $(LDFLAGS) $(SHARED) $(OBJS) $(LIBS) -Wl,+h -Wl,$@ -o $@
+else
+$(LIB) $(PLUGIN) : $(OBJS)
+	$(C++) $(LDFLAGS) $(SHARED) $(OBJS) $(LIBS) -o $@
+
+endif # not HP-UX
+endif # not Darwin
+
+$(EXEC:=.dbg) :
+	@[ -d $(DEBUGDIR) ] || mkdir $(DEBUGDIR)
+	@cd $(DEBUGDIR); \
+	  $(MAKE) -f ../GNUmakefile "DOF=$(DBGF)"  TOPDIR=../${TOPDIR} \
+	      THISDIR=../$(THISDIR)\
+	      MAKEDEPEND=Makedepend $(EXEC)
+	@$(MAKE) LNSRC=$(DEBUGDIR)/$(EXEC)$(EXE_EXT) LNDEST=$(BININST)/$(OS)$(ARCH)/$(EXEC)$(EXE_EXT) __link
+
+$(LIB:=.dbg) : $(PLUGIN:=.dbg)
+	@[ -d $(DEBUGDIR) ] || mkdir $(DEBUGDIR)
+	@[ -d "$(TOPDIR)/lib/$(OS)$(ARCH)" ] || mkdir -p $(TOPDIR)/lib/$(OS)$(ARCH)
+	@cd $(DEBUGDIR);\
+	  $(MAKE) -f ../GNUmakefile "DOF=$(DBGF)"  TOPDIR=../${TOPDIR} \
+	      THISDIR=../$(THISDIR)\
+	      MAKEDEPEND=Makedepend $(LIB)
+	@$(MAKE) LNSRC=$(DEBUGDIR)/$(LIB) LNDEST=$(LIBINST)/$(OS)$(ARCH)/$(LIB) __link
+
+$(PLUGIN:=.dbg) : 
+	@[ -d $(DEBUGDIR) ] || mkdir $(DEBUGDIR)
+	@cd $(DEBUGDIR); \
+	  $(MAKE) -f ../GNUmakefile "DOF=$(DBGF)"  TOPDIR=../${TOPDIR} \
+	      THISDIR=../$(THISDIR)\
+	      MAKEDEPEND=Makedepend $(PLUGIN)
+	@$(MAKE) LNSRC=$(DEBUGDIR)/$(PLUGIN) LNDEST=$(PLUGININST)/$(PLUGIN) __link
+
+$(EXEC:=.opt) : 
+	@[ -d $(OPTDIR) ] || mkdir $(OPTDIR)
+	@cd $(OPTDIR); \
+	  $(MAKE) -f ../GNUmakefile DOF=$(OPTF)  TOPDIR=../${TOPDIR} \
+	      THISDIR=../$(THISDIR)\
+	      MAKEDEPEND=Makedepend $(EXEC)
+	@$(MAKE) LNSRC=$(OPTDIR)/$(EXEC)$(EXE_EXT) LNDEST=$(BININST)/$(OS)$(ARCH)/$(EXEC)$(EXE_EXT) __link
+
+
+$(LIB:=.opt) : 
+	@[ -d $(OPTDIR) ] || mkdir -p $(OPTDIR)
+	@[ -d "$(TOPDIR)/lib/$(OS)$(ARCH)" ] || mkdir -p $(TOPDIR)/lib/$(OS)$(ARCH)
+	@cd $(OPTDIR);\
+	  $(MAKE) -f ../GNUmakefile DOF=$(OPTF) TOPDIR=../${TOPDIR} \
+	        THISDIR=../$(THISDIR)\
+	        MAKEDEPEND=Makedepend $(LIB)
+	@$(MAKE) LNSRC=$(OPTDIR)/$(LIB) LNDEST=$(LIBINST)/$(OS)$(ARCH)/$(LIB) __link
+
+$(PLUGIN:=.opt) : 
+	@[ -d $(OPTDIR) ] || mkdir -p $(OPTDIR)
+	@cd $(OPTDIR); \
+	  $(MAKE) -f ../GNUmakefile DOF=$(OPTF) TOPDIR=../${TOPDIR} \
+	    THISDIR=../$(THISDIR)\
+	               MAKEDEPEND=Makedepend $(PLUGIN)
+	@$(MAKE) LNSRC=$(OPTDIR)/$(PLUGIN) LNDEST=$(PLUGININST)/$(PLUGIN) __link
+
+
+## Revamped method for making Makedepend files
+## Under this method, Makedepend simply includes
+## all dependency files which are built for each 
+## individual source file.  At update, only the individual
+## dependency file is updated rather than the whole of Makedepend
+
+Makedepend : $(CXXFILES) $(CFILES)
+ifeq ($(OS),IRIX)
+	touch $@
+else
+	@ touch $@
+	@if [ ! -d .depend ] ; then  \
+		mkdir .depend;\
+		depfiles="$+";\
+	else\
+		depfiles="$?";\
+	fi;\
+	if [ ! -z "$$depfiles" ]; then \
+	for f in $$depfiles; do \
+		echo "$(C++) $(DEPARG) $(INC) $$f  pipeto .depend/`basename $$f`"; \
+		$(C++) $(DEPARG) $(INC) $$f > .depend/`basename $$f`; \
+		grep $$f $@ || echo include .depend/`basename $$f` >> Makedepend ;\
+	done;\
+	fi
+endif
+
+
+ifeq (0,1) ##### OLD WAY : Keep until we've proven that this doesn't trip up
+           ##### on other OS's.
+    Makedepend : $(CXXFILES) $(CFILES) 
+    ifeq ($(OS),IRIX)   
+    	touch $@
+    else
+    	$(C++) $(INC) $(DEPARG) $^ > $(MAKEDEPEND)
+    endif
+
+endif
+
+
+.SUFFIXES: .cpp .c .o
+.cpp.o:
+	$(C++) $(CXXFLAGS) -c $<
+.c.o:
+	$(CC) $(CXXFLAGS) -c $<
+
+depend : $(MAKEDEPEND)
+
+__link : 
+	@sh $(TOPDIR)/Make/dolink.sh $(TOPDIR) $(LNSRC) $(LNDEST) "$(LINK)"
+		
+__instfiles :
+	@echo $(INSTFILES)
+
+sinclude $(MAKEDEPEND)
+
diff --git a/ossimPlanet/Make/maketoprule b/ossimPlanet/Make/maketoprule
new file mode 100644
index 0000000..d91f797
--- /dev/null
+++ b/ossimPlanet/Make/maketoprule
@@ -0,0 +1,20 @@
+veryclean: clobber cleanlib cleanbin cleandoc
+
+cleanlib:
+	rm -rf $(TOPDIR)/lib
+
+cleanbin:
+	rm -rf $(TOPDIR)/bin
+
+cleandoc:
+	rm -rf $(TOPDIR)/doc/*
+
+rpm:
+	$(TOPDIR)/Make/makerpms "$(OS)" \
+				"$(TOPDIR)" \
+				"$(INST_LIBS)" \
+				"$(INST_INCLUDE)" \
+				"$(INST_EXAMPLES)" \
+				"$(INST_SRC)" \
+				"$(INST_EXAMPLE_SRC)" \
+				"$(INST_DOC)"
diff --git a/ossimPlanet/Make/versionrules b/ossimPlanet/Make/versionrules
new file mode 100644
index 0000000..61af727
--- /dev/null
+++ b/ossimPlanet/Make/versionrules
@@ -0,0 +1,16 @@
+####################################################################### 
+##
+##                   VERSIONING SEMANTICS
+##
+## Version consistes of <major> . <minor> . <release> - <revision>
+## Where:
+##    major   : Production (0 = pre-production)
+##    minor   : 0-7 = Production minor, 8 = Alpha, 9 = Beta
+##    release : Release tag
+##    revision: Release revision - 0 = development (cutting edge). 
+##
+##
+##  'make version' will print the version with a 
+####################################################################### 
+version : 
+	@echo $(VERSION)-$(VERSION_REVISION);
diff --git a/ossimPlanet/README.txt b/ossimPlanet/README.txt
new file mode 100644
index 0000000..ded52ef
--- /dev/null
+++ b/ossimPlanet/README.txt
@@ -0,0 +1,12 @@
+
+PACKAGES required:
+
+1. OSSIM, found at ossim.org.  This is the core geospatial image and corrdinate processing ngine used by ossimPlanet
+
+2. libwms.  Used for WMS access.  This uses libcurl for the http protocol.
+
+3. OpenSceneGraph.  Found at http://www.openscenegraph.org.  This is used for the 3-D visualization.
+
+
+
+
diff --git a/ossimPlanet/apps/ossimplanet-chip/ossimplanet-chip.cpp b/ossimPlanet/apps/ossimplanet-chip/ossimplanet-chip.cpp
new file mode 100644
index 0000000..df503e9
--- /dev/null
+++ b/ossimPlanet/apps/ossimplanet-chip/ossimplanet-chip.cpp
@@ -0,0 +1,496 @@
+#include <ossimPlanet/ossimPlanetApi.h>
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/init/ossimInit.h>
+#include <ossim/elevation/ossimElevManager.h>
+#include <ossim/imaging/ossimMemoryImageSource.h>
+#include <ossim/imaging/ossimJpegWriter.h>
+#include <iostream>
+#include <sstream>
+#include <osg/ArgumentParser>
+#include <osg/Texture>
+#include <osg/PositionAttitudeTransform>
+#include <osgDB/ReadFile>
+#include <osgDB/WriteFile>
+#include <osg/Drawable>
+#include <osg/io_utils>
+#include <time.h>
+#include <osgViewer/Renderer>
+#include <osgViewer/ViewerEventHandlers>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetManipulator.h>
+#include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetTerrainGeometryTechnique.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <ossimPlanet/ossimPlanetViewMatrixBuilder.h>
+#include <ossimPlanet/ossimPlanetCloudLayer.h>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/StateSetManipulator>
+#include <osgGA/AnimationPathManipulator>
+#include <osgGA/TerrainManipulator>
+#include <ossimPlanet/ossimPlanetAnimationPath.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <osg/Geometry>
+#include <osg/MatrixTransform>
+#include <osg/LineWidth>
+#include <osgText/Text>
+#include <osgUtil/CullVisitor>
+#include <osg/ClipPlane>
+
+#include <osg/Program>
+#include <osg/Uniform>
+
+#include <osg/Geode>
+#include <osg/Geometry>
+
+
+class CustomRenderer : public osgViewer::Renderer
+{
+public:
+   CustomRenderer( osg::Camera* camera )
+   : osgViewer::Renderer(camera), _cullOnly(true)
+   {
+   }
+   
+   void setCullOnly(bool on) { _cullOnly = on; }
+   
+   virtual void operator ()( osg::GraphicsContext* )
+   {
+      if ( _graphicsThreadDoesCull )
+      {
+         if (_cullOnly) 
+         {
+            cull();
+         }
+         else
+         {
+            cull_draw();
+         }
+      }
+   }
+   virtual void cull()
+   {
+      osgUtil::SceneView* sceneView = _sceneView[0].get();
+      if ( !sceneView || _done  )
+         return;
+      
+      updateSceneView( sceneView );
+      
+      osgViewer::View* view = dynamic_cast<osgViewer::View*>( _camera->getView() );
+      if ( view )
+         sceneView->setFusionDistance( view->getFusionDistanceMode(), view->getFusionDistanceValue() );
+      sceneView->inheritCullSettings( *(sceneView->getCamera()) );
+      sceneView->cull();
+   }
+   bool _cullOnly;
+};
+
+int main(int argc, char* argv[])
+{
+   ossimInit::instance()->initialize(argc, argv);
+   
+   osg::ref_ptr<ossimPlanetGrid> grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_CAP);  
+   
+   ossimString tempString;
+   osg::ArgumentParser::Parameter stringParam(tempString);
+   
+   osg::ArgumentParser arguments(&argc,argv);
+   arguments.getApplicationUsage()->addCommandLineOption("--terrain-requests-per-frame", 
+                                                         "Specify the number of requests to apply to the terrain graph per frame");
+   arguments.getApplicationUsage()->addCommandLineOption("--terrain-threads", 
+                                                         "Specify the number of terrain threads to use  Specify between 1 and 3 for now");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-image", "Image to add");
+	arguments.getApplicationUsage()->addCommandLineOption("--polar-cap", "Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--osg-view", "no ossimPlanet just use osg's readNode to add to scene");
+	arguments.getApplicationUsage()->addCommandLineOption("--split-merge-speed", "enumeration that maps to split merge ratio.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--elevation-density-type", "enumeration that maps amount of elevation posts to use per patch.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--texture-density-type", "enumeration that maps amount of texture samples to use per patch.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--elevation-exaggeration", "Scales the elevation by this factor");
+	arguments.getApplicationUsage()->addCommandLineOption("--cull-amount", "Sets the amount of culling in the graph.  Values can be low, medium, high");
+	arguments.getApplicationUsage()->addCommandLineOption("--min-time-compile", "sets the minimum time to compile per frame in seconds.  So 3 milliseconds is .003");
+	arguments.getApplicationUsage()->addCommandLineOption("--animation-path", "Reads in an animation path");
+	arguments.getApplicationUsage()->addCommandLineOption("--animation-node", "Reads in an animation node");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-kml", "Adds a kml layer to planet");
+	arguments.getApplicationUsage()->addCommandLineOption("--moon-image", "Moon image used for the moon sprite for the Ephemeris");
+	arguments.getApplicationUsage()->addCommandLineOption("--sun-image", "Moon image used for the moon sprite for the Ephemeris");
+	arguments.getApplicationUsage()->addCommandLineOption("--visibility", "Visibility in meters");
+	arguments.getApplicationUsage()->addCommandLineOption("--fog-near", "near plane for fog attenuation in meters");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-coverage", "integer value used to adjust the perlin noise");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-sharpness", "float value (0..1) used to adjust the perlin noise");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-altitude", "Altitude of the cloud");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-cloud", "float value (0..1) used to adjust the perlin noise");
+	arguments.getApplicationUsage()->addCommandLineOption("--fog-near", "near plane for fog attenuation in meters");
+   
+   
+   
+	ossim_uint32 helpType = 0;
+	
+	if ((helpType = arguments.readHelpType()))
+	{
+		arguments.getApplicationUsage()->write(std::cout, helpType);
+		return 1;
+	}
+	
+   
+   osg::MatrixTransform* rootScene = new osg::MatrixTransform();
+   
+   // osg::DisplaySettings::instance()->setRGB(true);
+   // osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(1);
+   ossimPlanetTerrainGeometryTechnique* technique = new ossimPlanetTerrainGeometryTechnique();
+   ossimPlanetViewer viewer(arguments);
+   ossimPlanetTerrain::CullAmountType cullAmount = ossimPlanetTerrain::HIGH_CULL;
+   ossimPlanetTerrain::SplitMergeSpeedType splitMergeSpeed = ossimPlanetTerrain::LOW_SPEED;
+   ossimPlanetTerrain::ElevationDensityType elevationDensity = ossimPlanetTerrain::LOW_ELEVATION_DENSITY;
+   ossimPlanetTerrain::TextureDensityType textureDensity = ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY;
+   std::vector<osg::ref_ptr<ossimPlanetAnimationPath> > animationPathArray;
+   std::vector<osg::ref_ptr<ossimPlanetPointModel> > pointModels;
+   std::vector<osg::ref_ptr<ossimPlanetAnimatedPointModel> > animatedPointModels;
+   osg::ref_ptr<ossimPlanetGeoRefModel> model;
+   osg::ref_ptr<ossimPlanetManipulator> manipulator = new ossimPlanetManipulator();
+   osg::ref_ptr<ossimPlanetAnnotationLayer> annotationLayer =new ossimPlanetAnnotationLayer();
+   osg::ref_ptr<ossimPlanetKmlLayer> kmlLayer;
+   std::vector<ossimFilename> kmlFiles;
+   ossimFilename flightgearFile = "";
+   osg::ref_ptr<ossimPlanet> planet;
+   double elevationExaggeration = 1.0;
+   double minTimeToCompilePerFrame = 10000;
+   ossimFilename sunTextureFile = "";
+   ossimFilename moonTextureFile = "";
+   ossim_float64 visibility = 1000000000.0;
+   ossim_float64 fogNear = 0.0;
+   ossim_int32 cloudCoverage = 20;
+   ossim_float64 cloudSharpness = .95;
+   ossim_float64 cloudAltitude = 20000;
+   bool addCloud = false;
+   
+   if(arguments.read("--cloud-coverage", stringParam))
+   {
+      cloudCoverage = tempString.toDouble();
+   }
+   if(arguments.read("--cloud-sharpness", stringParam))
+   {
+      cloudSharpness = tempString.toDouble();
+   }
+   if(arguments.read("--cloud-altitude", stringParam))
+   {
+      cloudAltitude = tempString.toDouble();
+   }
+   if(arguments.read("--add-cloud"))
+   {
+      addCloud = true;
+   }
+   
+   if(arguments.read("--visibility", stringParam))
+   {
+      visibility = tempString.toDouble();
+   }
+   if(arguments.read("--fog-near", stringParam))
+   {
+      fogNear = tempString.toDouble();
+   }
+   while(arguments.read("--add-kml", stringParam))
+   {
+      kmlFiles.push_back(ossimFilename(tempString));
+   }
+   if(arguments.read("--animation-node", stringParam))
+   {
+      flightgearFile = ossimFilename(tempString);
+   }
+   while(arguments.read("--animation-path", stringParam))
+   {
+      osg::ref_ptr<ossimPlanetAnimationPath> animationPath = new ossimPlanetAnimationPath;
+      
+      if(animationPath->openAnimationPathByXmlDocument(ossimFilename(tempString)))
+      {
+         animationPathArray.push_back(animationPath.get());
+      }
+   }
+   if(arguments.read("--moon-image", stringParam))
+   {
+      moonTextureFile = ossimFilename(tempString);
+   }
+   if(arguments.read("--sun-image", stringParam))
+   {
+      sunTextureFile = ossimFilename(tempString);
+   }
+   if(arguments.read("--min-time-compile", stringParam))
+   {
+      minTimeToCompilePerFrame = tempString.toDouble();
+   }
+   if(arguments.read("--elevation-exaggeration", stringParam))
+   {
+      elevationExaggeration = tempString.toDouble();
+   }
+   if(arguments.read("--texture-density-type", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         textureDensity = ossimPlanetTerrain::LOW_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium_low")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_LOW_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium_high")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_HIGH_TEXTURE_DENSITY;
+      }
+      else if(tempString == "high")
+      {
+         textureDensity = ossimPlanetTerrain::HIGH_TEXTURE_DENSITY;
+      }
+   }
+   if(arguments.read("--elevation-density-type", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         elevationDensity = ossimPlanetTerrain::LOW_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium_low")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_LOW_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium_high")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_HIGH_ELEVATION_DENSITY;
+      }
+      else if(tempString == "high")
+      {
+         elevationDensity = ossimPlanetTerrain::HIGH_ELEVATION_DENSITY;
+      }
+   }
+   if(arguments.read("--split-merge-speed", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::LOW_SPEED;
+      }
+      
+      else if(tempString == "medium_low")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_LOW_SPEED;
+      }
+      else if(tempString == "medium")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_SPEED;
+      }
+      else if(tempString == "medium_high")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_HIGH_SPEED;
+      }
+      else if(tempString == "high")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::HIGH_SPEED;
+      }
+   }
+   if(arguments.read("--polar-cap", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::LOW_CAP);
+      }
+      else if(tempString == "medium_low")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_LOW_CAP);
+      }
+      else if(tempString == "medium")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_CAP);
+      }
+      else if(tempString == "medium_high")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_HIGH_CAP);
+      }
+      else if(tempString == "high")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::HIGH_CAP);
+      }
+   }
+   if(arguments.read("--cull-amount", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "none")
+      {
+         cullAmount = ossimPlanetTerrain::NO_CULL;
+      }
+      if(tempString == "low")
+      {
+         cullAmount = ossimPlanetTerrain::LOW_CULL;
+      }
+      else if(tempString == "medium_low")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_LOW_CULL;
+      }
+      else if(tempString == "medium")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_CULL;
+      }
+      else if(tempString == "medium_high")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_HIGH_CULL;
+      }
+      else if(tempString == "high")
+      {
+         cullAmount = ossimPlanetTerrain::HIGH_CULL;
+      }
+   }
+   
+   
+   planet = new ossimPlanet();
+   model = planet->model().get();
+   osg::ref_ptr<ossimPlanetTerrain> terrain = new ossimPlanetTerrain(grid.get());
+   terrain->setTerrainTechnique(technique);
+   terrain->setCullAmountType(cullAmount);
+   terrain->setSplitMergeSpeedType(splitMergeSpeed);
+   terrain->setTextureDensityType(textureDensity);
+   terrain->setElevationDensityType(elevationDensity);
+   terrain->setElevationExaggeration(elevationExaggeration);
+   terrain->setMinimumTimeToCompilePerFrameInSeconds(minTimeToCompilePerFrame);
+   terrain->setPrecompileEnabledFlag(false);
+   //terrain->setTextureLayer(0, group);
+   terrain->initElevation();
+   planet->addChild(terrain.get());
+   planet->addChild(annotationLayer.get());
+   rootScene->addChild(planet.get());
+   viewer.setSceneData( rootScene );
+   
+   osg::ref_ptr<osg::StateSet> sset = planet->getOrCreateStateSet();
+   if(arguments.read("--terrain-requests-per-frame", stringParam))
+   {
+      ossim_int32 requestsPerFrame = ossimString(tempString).toInt32();
+      if(requestsPerFrame <= 0)
+      {
+         requestsPerFrame = 1;
+      }
+      viewer.setTerrainMaxNumberOfOperationsToApplyToGraphPerFrame(requestsPerFrame);
+   }
+   while(arguments.read("--add-image", stringParam))
+   {
+      osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(tempString);
+      if(layer.valid())
+      {
+         viewer.addImageTexture(layer.get());
+         
+      }
+   }	
+   viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
+   viewer.addEphemeris(ossimPlanetEphemeris::SUN_LIGHT
+                       //|ossimPlanetEphemeris::MOON_LIGHT
+                       //|ossimPlanetEphemeris::AMBIENT_LIGHT
+                       // |ossimPlanetEphemeris::SUN
+                       |ossimPlanetEphemeris::MOON
+                       |ossimPlanetEphemeris::SKY
+                       |ossimPlanetEphemeris::FOG
+                       );
+   ossimLocalTm date;
+   date.now();
+   viewer.ephemeris()->setDate(date);
+
+   osg::ref_ptr<osg::GraphicsContext> pbuffer;
+   osg::Image *image = new osg::Image();
+
+   osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
+   traits->readDISPLAY();
+   traits->alpha = 8;
+   traits->width = 1920;
+   traits->height = 1080;
+   traits->pbuffer = true;
+   pbuffer = osg::GraphicsContext::createGraphicsContext(traits.get());
+   manipulator->setEventHandlingFlag(true);
+   manipulator->viewMatrixBuilder()->setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_Y);
+   viewer.setCameraManipulator(manipulator.get());
+   
+   osg::ref_ptr<CustomRenderer> renderer; 
+   if (pbuffer.valid())
+   {
+      osg::Camera *camera = viewer.getCamera();
+      renderer = new CustomRenderer( camera );
+      camera->setGraphicsContext(pbuffer.get());
+      camera->setDrawBuffer(GL_FRONT);
+      camera->setReadBuffer(GL_FRONT);
+      camera->setViewport(new osg::Viewport(0,0,traits->width,traits->height));
+      double fovy, aspectRatio, near, far;
+      camera->getProjectionMatrixAsPerspective(fovy, aspectRatio, near, far);
+      double newAspectRatio = double(traits->width) / double(traits->height);
+      double aspectRatioChange = newAspectRatio / aspectRatio;
+      if (aspectRatioChange != 1.0)
+         camera->getProjectionMatrix() *=
+         osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
+      
+      camera->attach(osg::Camera::COLOR_BUFFER0, image);
+      if(renderer.valid()) camera->setRenderer( renderer.get() );
+   
+      viewer.realize();
+   }
+   else 
+   {
+      std::cout << "Invalid pbuffer!!!!!!!!!!!!!!!!!!!!" << std::endl;
+      exit(1);
+   }
+   double time = 0.0;
+   GLenum pixelFormat = GL_RGB;
+   bool gotTheImage = false;
+   manipulator->viewMatrixBuilder()->setLookFrom(osg::Vec3d(37,87,15000),
+                                                 osg::Vec3d(0, 0.0, 0.0),
+                                                 0);   
+   manipulator->viewMatrixBuilder()->setLookTo(osg::Vec3d(38,87,5500));   
+   
+   if(!viewer.done())
+   {
+      osg::Timer_t lastFrameTick = osg::Timer::instance()->tick();
+      viewer.frame();
+      //viewer.advance();
+      if(renderer.valid())renderer->setCullOnly( true );
+      while(viewer.getAndSetRedrawFlag(false)) 
+      {
+         viewer.frame();
+//         viewer.eventTraversal();
+//         viewer.updateTraversal();
+//         viewer.renderingTraversals();
+      }
+      if(renderer.valid()) renderer->setCullOnly( false );
+      viewer.frame();
+      osg::Timer_t frameTick = osg::Timer::instance()->tick();
+      double delta = osg::Timer::instance()->delta_s(lastFrameTick, frameTick);
+      std::cout << "delta = " << delta << std::endl;
+      if(!gotTheImage)
+      {
+         unsigned char* buffer = image->data();
+         ossimRefPtr<ossimImageData> imageData = new ossimImageData(0,OSSIM_UINT8, 4, image->s(), image->t());
+         imageData->initialize();
+         
+         imageData->loadTile(image->data(), ossimIrect(0,0,image->s()-1, image->t()-1), OSSIM_BIP);
+         imageData->validate();
+         ossimRefPtr<ossimMemoryImageSource> memSource = new ossimMemoryImageSource();
+         memSource->setImage(imageData.get());
+         ossimRefPtr<ossimJpegWriter> jpegWriter = new ossimJpegWriter();
+         jpegWriter->connectMyInputTo(0, memSource.get());
+         jpegWriter->setFilename(ossimFilename("/tmp/output.jpg"));
+         jpegWriter->execute();
+         
+         delta = osg::Timer::instance()->delta_s(frameTick, osg::Timer::instance()->tick());
+         
+         std::cout << "SAVED /tmp/output.jpg in " << delta << " seconds" <<std::endl;
+      }
+   }
+}
diff --git a/ossimPlanet/binds.act b/ossimPlanet/binds.act
new file mode 100644
index 0000000..208975e
--- /dev/null
+++ b/ossimPlanet/binds.act
@@ -0,0 +1,26 @@
+#   // need to say something like this in C++ when create the iac (InteractionController)
+
+:iac tie x_mouse LON YAW
+:iac tie y_mouse LAT ZOOM PITCH
+
+:iac bind left_mousedown    {:navigator rotatestart}
+:iac bind left_mouseup      {:navigator rotatestop}
+:iac bind middle_mousedown    {:navigator losrotatestart}
+:iac bind middle_mouseup      {:navigator losrotatestop}
+:iac bind right_mousedown    {:navigator loszoomstart}
+:iac bind right_mouseup      {:navigator loszoomstop}
+:iac bind shift_middle_mousedown  {:navigator zoomstart}
+:iac bind shift_middle_mouseup    {:navigator zoomstop}
+:iac bind shift_right_mousedown   {:navigator lookstart}
+:iac bind shift_right_mouseup     {:navigator lookstop}
+:iac bind left_key            {:navigator flystart .015625 0}
+:iac bind right_key          {:navigator flystart -.015625 0.0}
+:iac bind down_key          {:navigator flystart 0.0 .015625}
+:iac bind up_key         {:navigator flystart 0.0 -.015625}
+:iac bind u_key 	    {:navigator resetzoomlook}
+:iac bind z_key 	    {:navigator recordanimation}
+:iac bind Z_key 	    {:navigator playanimation}
+:iac bind p_key     	    {:navigator printlatlonelev}
+:iac bind P_key     	    {:navigator printlookcoordinates}
+:iac bind space_key         {:navigator reset}
+:iac bind return_key        {:navigator stop}
diff --git a/ossimPlanet/examples/GNUmakefile b/ossimPlanet/examples/GNUmakefile
new file mode 100644
index 0000000..3d18103
--- /dev/null
+++ b/ossimPlanet/examples/GNUmakefile
@@ -0,0 +1,11 @@
+TOPDIR = ..
+include $(TOPDIR)/Make/makedefs
+include $(TOPDIR)/Make/makedirdefs
+
+DIRS = $(EXAMPLE_DIRS)
+
+include $(TOPDIR)/Make/makedirrules
+include $(TOPDIR)/Make/versionrules
+include $(TOPDIR)/Make/instrules
+include $(TOPDIR)/Make/distrules
+include $(TOPDIR)/Make/helprules
diff --git a/ossimPlanet/examples/ossimplanetinfo/GNUmakefile b/ossimPlanet/examples/ossimplanetinfo/GNUmakefile
new file mode 100644
index 0000000..d5afe30
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetinfo/GNUmakefile
@@ -0,0 +1,20 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs 
+
+CXXFILES =\
+	ossimplanetinfo.cpp
+
+LIBS     += $(OSSIM_LIBS) -lossimPlanet -lossimPredator $(OSG_LIBS) $(OTHER_LIBS) 
+
+ifeq ($(OS),Darwin)
+	LIBS += -bind_at_load
+endif
+
+INSTFILES = \
+	$(CXXFILES)\
+	GNUmakefile.inst=GNUmakefile
+LIB=
+EXEC = ossimplanetinfo
+
+include $(TOPDIR)/Make/makerules 
+
diff --git a/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.cpp b/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.cpp
new file mode 100644
index 0000000..b2d5561
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.cpp
@@ -0,0 +1,93 @@
+#include <ossim/init/ossimInit.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <iostream>
+#ifdef OSSIMPLANET_ENABLE_PREDATOR
+#include <ossimPredator/ossimPredatorApi.h>
+#include <iomanip>
+
+bool printPredatorInfo(const ossimFilename& file, std::ostream& out)
+{
+	out << std::setprecision(20);
+	bool result = false;
+	ossimRefPtr<ossimPredatorVideo> video = new ossimPredatorVideo();
+	ossimRefPtr<ossimPredatorVideo::FrameInfo> frameInfo;
+	result = video->open(file);
+	if(result)
+	{
+		// look at the first couple of seconds worth of video to find a klv stream
+		//
+		ossim_uint32 maxFramesToCheck = video->videoFrameRate()*2;
+		bool foundInfo = false;
+		ossim_uint32 frameCount=0;
+		while((!foundInfo)&&
+				(frameCount <= maxFramesToCheck)&&
+				((frameInfo = video->nextFrame()).valid()))
+		{
+			++frameCount;
+			ossimRefPtr<ossimPredatorKlvTable> klvTable = frameInfo->klvTable();
+			if(klvTable.valid())
+			{
+				ossimGpt ulg, urg, lrg, llg;
+				ossimString prefix = "video0.frame0.";
+				foundInfo = klvTable->getCornerPoints(ulg, urg, lrg, llg);
+				if(!foundInfo)
+				{
+					ossim_float64 lat, lon, elev;
+					
+					foundInfo = klvTable->getFrameCenter(lat, lon, elev);
+					if(foundInfo)
+					{
+						ulg = ossimGpt(lat, lon, elev);
+						urg = ulg;
+						lrg = ulg;
+						llg = ulg;
+					}
+				}					
+				if(foundInfo)
+				{
+					out << "video0.type: ossimPredatorVideo\n"
+					    << prefix << "ul_lat: " << ulg.latd() << "\n"
+					    << prefix << "ul_lon: " << ulg.lond() << "\n"
+					    << prefix << "ur_lat: " << urg.latd() << "\n"
+					    << prefix << "ur_lon: " << urg.lond() << "\n"
+					    << prefix << "lr_lat: " << lrg.latd() << "\n"
+					    << prefix << "lr_lon: " << lrg.lond() << "\n"
+					    << prefix << "ll_lat: " << llg.latd() << "\n"
+					    << prefix << "ll_lon: " << llg.lond() << "\n";
+				}
+			}
+		}
+	}
+	return result;
+}
+#endif
+
+
+bool printVideoInfo(const ossimFilename& file, std::ostream& out)
+{
+	bool result = false;
+#ifdef OSSIMPLANET_ENABLE_PREDATOR
+	result = printPredatorInfo(file, out);
+#endif
+	
+	return result;
+}
+
+int main(int argc, char* argv[])
+{
+	ossimInit::instance()->initialize(argc, argv);
+
+	if(argc < 2)
+	{
+		std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
+		return 0;
+	}
+	ossimFilename file(argv[1]);
+	if(printVideoInfo(file, std::cout))
+	{
+		return 0;
+	}
+	
+	return 0;
+}
diff --git a/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.vcproj b/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.vcproj
new file mode 100755
index 0000000..73e24cb
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetinfo/ossimplanetinfo.vcproj
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="ossimplanetinfo"
+	ProjectGUID="{ADACE05C-5874-451F-8ED8-E75884170892}"
+	RootNamespace="ossimplanetinfo"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\ossim_dependencies\src\3rdParty\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\zziplib-0.13.49";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph\include""
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CONSOLE;OSGPLANET_WITHOUT_WMS;FREETYPE_SETTING=1;GEOTIFF_ENABLED;HAVE_CONFIG_H"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)bin\ossimplanetinfo.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="C:\Svs_dev_C\ossim\lib;C:\Svs_dev_C\3rdParty\lib;C:\Svs_dev_C\OpenThreads\lib\win32;C:\Svs_dev_C\Producer\lib;C:\Svs_dev_C\OpenSceneGraph\lib;C:\Svs_dev_C\gdal"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/ossimplanetinfo.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\include""
+				PreprocessorDefinitions="NDEBUG;_WINDOWS;WIN32;_CONSOLE;NOMINMAX"
+				RuntimeLibrary="2"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="OpenThreads.lib osg.lib osgDB.lib osgViewer.lib osgGA.lib osgText.lib osgUtil.lib"
+				OutputFile="$(OutDir)\bin\$(ProjectName).exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\ossim\projects\vs2005\bin\Release";"$(ProjectDir)..\..\..\ossim_dependencies\lib";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph-2.8.1\build\lib""
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)\lib\$(ProjectName).lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\ossimplanetinfo.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\opvLoadModel.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/ossimPlanet/examples/ossimplanetklv/GNUmakefile b/ossimPlanet/examples/ossimplanetklv/GNUmakefile
new file mode 100644
index 0000000..4db081c
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetklv/GNUmakefile
@@ -0,0 +1,20 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs 
+
+CXXFILES =\
+	ossimplanetpredator.cpp
+
+LIBS     += $(OSSIM_LIBS) -lossimPlanet -lossimPredator $(OSG_LIBS) $(OTHER_LIBS) 
+
+ifeq ($(OS),Darwin)
+	LIBS += -bind_at_load
+endif
+
+INSTFILES = \
+	$(CXXFILES)\
+	GNUmakefile.inst=GNUmakefile
+LIB=
+EXEC = ossimplanetpredator
+
+include $(TOPDIR)/Make/makerules 
+
diff --git a/ossimPlanet/examples/ossimplanetklv/ossimplanetklv.cpp b/ossimPlanet/examples/ossimplanetklv/ossimplanetklv.cpp
new file mode 100644
index 0000000..b35ed35
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetklv/ossimplanetklv.cpp
@@ -0,0 +1,179 @@
+#include <ossim/init/ossimInit.h>
+#include <ossim/base/ossimGeoidManager.h>
+#include <ossimPredator/ossimPredatorApi.h>
+#include <ossimPredator/ossimPredatorUavProjection.h>
+#include <osg/ArgumentParser>
+#include <fstream>
+int main(int argc, char* argv[])
+{
+   ossimInit::instance()->initialize(argc, argv);
+   ossimString tempString;
+   ossimString tempString2;
+   osg::ArgumentParser::Parameter stringParam(tempString);
+   osg::ArgumentParser::Parameter stringParam2(tempString2);
+   
+   osg::ArgumentParser arguments(&argc,argv);
+   arguments.getApplicationUsage()->addCommandLineOption("--video", 
+                                                         "specify the input video to process");
+   arguments.getApplicationUsage()->addCommandLineOption("--animation-path-out", 
+                                                         "specify the filename to output the animation path to");
+   arguments.getApplicationUsage()->addCommandLineOption("--test-sensor-projection", 
+                                                         "Test sensor projection from KlvInfo");
+   unsigned int helpType = 0;
+   if ((helpType = arguments.readHelpType()))
+   {
+      arguments.getApplicationUsage()->write(std::cout, helpType);
+      return 1;
+   }
+   while(arguments.read("--video", stringParam))
+   {
+      if(arguments.read("--test-sensor-projection"))
+      {
+         ossimRefPtr<ossimPredatorUavProjection> proj = new ossimPredatorUavProjection;
+         ossimRefPtr<ossimPredatorVideo> predatorVideo = new ossimPredatorVideo();
+         
+         if(predatorVideo->open(ossimFilename(tempString)))
+         {
+            ossim_uint32 imageWidth  = predatorVideo->imageWidth();
+            ossim_uint32 imageHeight = predatorVideo->imageHeight();
+            ossimRefPtr<ossimPredatorVideo::KlvInfo> klvinfo;
+            ossim_float64 prevTime = -1.0;
+            while(( klvinfo = predatorVideo->nextKlv()).valid())
+            {
+               ossim_float64 lat,lon,elev;
+               ossim_float32 hfov;
+               ossim_float32 vfov;
+               ossim_float32 h,p,r;
+               ossim_float32 obliquityAngle;
+               ossim_float32 angleToNorth;
+               ossim_float32 slantRange;
+               ossim_float32 sensorRoll = 0.0;
+               klvinfo->table()->print(std::cout) << std::endl;
+               if(klvinfo->table()->getSensorPosition(lat, lon, elev)&&
+                  klvinfo->table()->getPlatformOrientation(h,p,r))
+               {
+                  if(!klvinfo->table()->getObliquityAngle(obliquityAngle))
+                  {
+                     obliquityAngle = 0.0;
+                  }
+                  if(!klvinfo->table()->getSlantRange(slantRange))
+                  {
+                     slantRange = 1.0;
+                  }
+                  bool gotHfov = true;
+                  if(!klvinfo->table()->getHorizontalFieldOfView(hfov))
+                  {
+                     hfov = 1.0;
+                     gotHfov = false;
+                  }
+                  if(!klvinfo->table()->getVerticalFieldOfView(vfov))
+                  {
+                     vfov = hfov;
+                  }
+                  else if(!gotHfov)
+                  {
+                     hfov = vfov;
+                  }
+                  klvinfo->table()->getSensorRollAngle(sensorRoll);
+                  if(!klvinfo->table()->getAngleToNorth(angleToNorth))
+                  {
+                     angleToNorth = 0.0;
+                  }
+                  ossim_float64 value = ossimGeoidManager::instance()->offsetFromEllipsoid(ossimGpt(lat, lon, elev));
+                  if(!ossim::isnan(value))
+                  {
+                     elev += value;
+                  }
+                  proj->setParameters(imageWidth, 
+                                      imageHeight, 
+                                      ossimGpt(lat, lon, elev), 
+                                      ossimGpt(), 
+                                      h, p, sensorRoll,
+                                      hfov,
+                                      vfov,
+                                      obliquityAngle,
+                                      angleToNorth,
+                                      0.0,
+                                      0.0);
+                  ossimDpt ipt(imageWidth*.5, imageHeight*.5);
+                  ossimGpt centerProj;
+                  ossimGpt ul;
+                  ossimGpt ur;
+                  ossimGpt lr;
+                  ossimGpt ll;
+                  proj->lineSampleToWorld(ipt, centerProj);
+                  proj->lineSampleToWorld(ossimDpt(0,0), ul);
+                  proj->lineSampleToWorld(ossimDpt(imageWidth,0), ur);
+                  proj->lineSampleToWorld(ossimDpt(imageWidth,imageHeight), lr);
+                  proj->lineSampleToWorld(ossimDpt(imageHeight,0), ll);
+                  
+                  std::cout << std::setprecision(15);
+                  std::cout << "position = " << ossimGpt(lat, lon, elev) << std::endl;
+                  std::cout << "centerGpt = " << centerProj << std::endl;
+                  std::cout << "ul        = " << ul << std::endl;
+                  std::cout << "ur        = " << ur << std::endl;
+                  std::cout << "lr        = " << lr << std::endl;
+                  std::cout << "ll        = " << ll << std::endl;
+                  
+//                  std::cout << "angle to north = " << angleToNorth << std::endl;
+//                  std::cout << "ObliquityAngle = " << obliquityAngle << std::endl;
+//                  std::cout << "hpr = " << h << ", " << p << ", " << r << std::endl;
+//                  std::cout << "Platform  = " << ossimGpt(lat, lon, elev) << std::endl;
+//                  std::cout << "World point = " << centerProj << std::endl;
+                  if(klvinfo->table()->getFrameCenter(lat, lon, elev))
+                  {
+                     std::cout << "Center frame = " << ossimGpt(lat, lon, elev) << std::endl;
+                  }
+               }
+            }
+         }
+      }
+      
+      if(arguments.read("--animation-path-out", stringParam2))
+      {
+         std::ofstream out(tempString2.c_str());
+         if(out.good())
+         {
+            out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+            out << "<AnimationPath>";
+            out << "<GeospatialPath timeUnit='seconds' positionType='latlonhgt' orientationType='lsrhpr'>";
+            out << "<description>Cool path</description>";
+            out << "<coordinates>";
+            
+            ossimRefPtr<ossimPredatorVideo> predatorVideo = new ossimPredatorVideo();
+            
+            if(predatorVideo->open(ossimFilename(tempString)))
+            {
+               ossim_float32 srange;
+               ossimRefPtr<ossimPredatorVideo::KlvInfo> klvinfo;
+               ossim_float64 prevTime = -1.0;
+               while(( klvinfo = predatorVideo->nextKlv()).valid())
+               {
+                  klvinfo->table()->getSlantRange(srange);
+                  //std::cout << "range === " << srange << std::endl;
+                  if(!ossim::almostEqual(klvinfo->time(), prevTime, 1e-10))
+                  {
+                     prevTime = klvinfo->time();
+                     ossimString sensorLat, sensorLon, sensorAlt, h,p,r;
+                     if(klvinfo->table()->valueAsString(sensorLat, KLV_KEY_SENSOR_LATITUDE)&&
+                        klvinfo->table()->valueAsString(sensorLon, KLV_KEY_SENSOR_LONGITUDE)&&
+                        klvinfo->table()->valueAsString(sensorAlt, KLV_KEY_SENSOR_TRUE_ALTITUDE))
+                     {
+                        klvinfo->table()->valueAsString(h,KLV_KEY_PLATFORM_HEADING_ANGLE);
+                        klvinfo->table()->valueAsString(p,KLV_KEY_PLATFORM_PITCH_ANGLE);
+                        klvinfo->table()->valueAsString(r,KLV_KEY_PLATFORM_ROLL_ANGLE);
+                        
+                        double headingAdjust = h.toDouble();
+                        if(headingAdjust > 180.0) headingAdjust -= 360.0;
+                        out << klvinfo->time() << "," 
+                        << sensorLat <<"," << sensorLon << "," <<sensorAlt.toDouble()*0.304801 << ","
+                        << headingAdjust << "," << p.toDouble() << "," << r.toDouble() <<std::endl;
+                     }
+                  }
+               }
+            }
+            out << "</coordinates></GeospatialPath></AnimationPath>";
+         }
+      }
+   }
+}
diff --git a/ossimPlanet/examples/ossimplanettest/GNUmakefile b/ossimPlanet/examples/ossimplanettest/GNUmakefile
new file mode 100644
index 0000000..e025281
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanettest/GNUmakefile
@@ -0,0 +1,20 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs 
+
+CXXFILES =\
+	ossimplanettest.cpp 
+
+LIBS     += $(OSSIM_LIBS) -lossimPlanet $(OSG_LIBS) $(OTHER_LIBS) 
+
+ifeq ($(OS),Darwin)
+	LIBS += -bind_at_load
+endif
+
+INSTFILES = \
+	$(CXXFILES)\
+	GNUmakefile.inst=GNUmakefile
+LIB=
+EXEC = ossimplanettest
+
+include $(TOPDIR)/Make/makerules 
+
diff --git a/ossimPlanet/examples/ossimplanettest/ossimplanettest.cpp b/ossimPlanet/examples/ossimplanettest/ossimplanettest.cpp
new file mode 100644
index 0000000..0957d4d
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanettest/ossimplanettest.cpp
@@ -0,0 +1,1657 @@
+#include <ossim/init/ossimInit.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetManipulator.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetTerrainGeometryTechnique.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <ossimPlanet/ossimPlanetViewMatrixBuilder.h>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+#include <ossimPlanet/ossimPlanetOssimImageLayer.h>
+#include <osgDB/ReadFile>
+#include <osgGA/GUIEventHandler>
+#include <osg/Camera>
+#include <osg/CameraNode>
+#include <osg/MatrixTransform>
+#include <osg/Geode>
+#include <osgText/Text>
+#include <osgText/Font>
+#include <osg/PolygonMode>
+#include <osgViewer/ViewerEventHandlers>
+#include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanetApi.h>
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/init/ossimInit.h>
+#include <ossim/elevation/ossimElevManager.h>
+#include <ossim/base/ossimGeoidEgm96.h>
+#include <iostream>
+#include <sstream>
+#include <osg/ArgumentParser>
+#include <osg/Texture>
+#include <osg/PositionAttitudeTransform>
+#include <osgDB/ReadFile>
+#include <osg/Drawable>
+#include <osg/io_utils>
+#include <time.h>
+#include <osgViewer/ViewerEventHandlers>
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/StateSetManipulator>
+#include <osgGA/AnimationPathManipulator>
+#include <osgGA/TerrainManipulator>
+#include <ossimPlanet/ossimPlanetAnimationPath.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <osg/Geometry>
+#include <osg/LineWidth>
+#include <osgUtil/CullVisitor>
+#include <osg/ClipPlane>
+#include <osg/Program>
+#include <osg/Uniform>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/PolygonMode>
+#include <osg/ref_ptr>
+#include <osg/Texture>
+#include <osg/Texture2D>
+#include <osg/TextureRectangle>
+#include <osg/TextureCubeMap>
+#include <ossimPlanet/ossimPlanetCloudLayer.h>
+
+osg::Node* loadFlightGearModel(const ossimFilename& file,
+                               ossimPlanetGeoRefModel* model, double scale = 1.0)
+{
+	osg::MatrixTransform* orientedModel = new osg::MatrixTransform;
+	osg::Node* flightgearModel = osgDB::readNodeFile(file.c_str(), 0);
+	osg::Matrixd mr;
+	osg::Matrixd ms;
+	double adjustedScale = scale/model->getNormalizationScale();
+	ms.makeScale(osg::Vec3d(adjustedScale, adjustedScale, adjustedScale));
+	mr.makeRotate(osg::DegreesToRadians(-90.0), osg::Vec3d(0.0,0.0,1.0),
+                 osg::DegreesToRadians(-90.0), osg::Vec3d(0.0,1.0,0.0),
+                 osg::DegreesToRadians(0.0), osg::Vec3d(1.0,0.0,0.0));
+	orientedModel->setMatrix(ms*mr);
+	if(flightgearModel)
+	{
+		orientedModel->addChild(flightgearModel);
+	}
+	return orientedModel;
+}
+
+class TestHandler : public osgGA::GUIEventHandler
+{
+public:
+	enum TestStage
+	{
+		OSSIMPLANET_INIT_TERRAIN = 0,
+		
+		OSSIMPLANET_SET_GEOID,
+		OSSIMPLANET_SET_ELEVATION_DENSITY,
+		OSSIMPLANET_SET_CAP_LOCATION,
+		OSSIMPLANET_ADD_IMAGE_TEXTURE,
+		OSSIMPLANET_ADD_FLORIDA_DATA,
+      OSSIMPLANET_ADD_REMOVE_TEXTURE_LAYER,
+		OSSIMPLANET_SET_TEXTURE_DENSITY,
+		OSSIMPLANET_ADD_ANNOTATION_NODE,
+		OSSIMPLANET_ADJUST_HEADING,
+		OSSIMPLANET_ADJUST_PITCH,
+		OSSIMPLANET_ADJUST_ROLL,
+		OSSIMPLANET_ADD_ELEVATION,
+		OSSIMPLANET_ELEVATION_EXAGGERATION,
+		OSSIMPLANET_INITIALIZE_EPHEMERIS,
+		OSSIMPLANET_ADD_CLOUDS,
+		OSSIMPLANET_ADD_FOG,
+		OSSIMPLANET_EPHEMERIS_ANIMATE,
+		OSSIMPLANET_ANIMATION_PATH,
+		OSSIMPLANET_ANIMATION_PATH2,
+		OSSIMPLANET_LOOKFROM,
+      OSSIMPLANET_LOOKTO,
+      OSSIMPLANET_LOOKTO_DISPLACEMENT,
+      OSSIMPLANET_LOOKFROM_CONVERSION,
+      OSSIMPLANET_LOOKFROM_CONVERSION_RANGE_FLATTEN,
+      OSSIMPLANET_LOOKTO_ALONG_AXIS,
+		OSSIMPLANET_LAST_TEST
+	};
+
+	enum texture_density
+	{
+		low_texture = 0,
+		medium_low_texture,
+		medium_texture,
+		medium_high_texture,
+		high_texture,
+		last_texture
+	};
+	
+	enum elevation_density
+	{
+		low_elevation = 0,
+		medium_low_elevation,
+		medium_elevation,
+		medium_high_elevation,
+		high_elevation,
+		last_elevation
+	};
+	
+	enum cap
+	{
+		low_cap = 0,
+		medium_low_cap,
+		medium_cap,
+		medium_high_cap,
+		high_cap,
+		last_cap
+	};
+	
+   enum AnimationFromMode
+   {
+      ANIMATION_FROM_INIT = 0,
+      RELATIVE_FROM_GLOBAL_RANGE_NONE,
+      RELATIVE_FROM_NONE,
+      RELATIVE_FROM_HEADING,
+      ANIMATION_FROM_STOP,
+      RELATIVE_FROM_PITCH,
+      RELATIVE_FROM_ROLL,
+      RELATIVE_FROM_ALL,
+      FROM_DISPLACEMENT_XYPLANE_RELATIVE_ALL_AXIS,
+      FROM_DISPLACEMENT_XYPLANE_RELATIVE_NONE_AXIS,
+      FROM_DISPLACEMENT_ZXPLANE_RELATIVE_ALL_AXIS,
+      FROM_DISPLACEMENT_ZXPLANE_RELATIVE_NONE_AXIS,
+      ANIMATION_FROM_LAST
+   };
+   
+	enum AnimationToMode
+   {
+      ANIMATION_TO_MODE_INIT = 0,
+      ANIMATION_TO_BOTH_MOVING_NO_RELATVE,
+      ANIMATION_TO_LAST
+   };
+	enum FogVisibilityMode
+   {
+      FOG_CLEAR= 0,
+		FOG_VERY_LIGHT,
+		FOG_LIGHT,
+		FOG_MEDIUM,
+		FOG_MEDIUM_HEAVY,
+		FOG_HEAVY,
+      FOG_LAST
+   };
+	
+	TestHandler()
+	:
+	theFontName("arial.ttf"),
+	thePlanetManipulator(new ossimPlanetManipulator),
+	theTestStage(-1),
+	theSwitchModeKey('m'),
+	theMaxTestStages(2),
+	theUpdateHudTextFlag(true),
+   theLookModeDuration(5.0)
+	{
+	}
+   ossim_float64 simtime()const
+   {
+      return theSimTime;
+   }
+	virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
+	void setRootDirectory(const ossimFilename& rootDir)
+	{
+		theRootDirectory = rootDir;
+	}
+protected:
+	void updateCurrentStage(ossimPlanetViewer* viewer);
+	void setupStage(ossimPlanetViewer* viewer);
+	void initScene(ossimPlanetViewer* viewer);
+	void updateText()
+	{
+		theHudText->setText(theHudTextString.c_str());
+		// puts the text in the lower left corner.
+		osg::BoundingBox bb = osg::BoundingBox();
+		bb.expandBy(theHudText->getBound());
+		theHudText->setPosition(osg::Vec3d(5.0,bb.yMax()-bb.yMin(),0.0));
+	}
+	void updateHudCoordinatesIfNeeded(ossimPlanetViewer* viewer)
+	{
+		// get master camera
+		osg::ref_ptr<osg::Camera> camera           = viewer->getCamera();
+		osg::ref_ptr<osg::Viewport> masterViewport = camera->getViewport();
+		// now make sure the viewport is mirrored
+		//
+		double x = masterViewport->x();
+		double y = masterViewport->y();
+		double w = masterViewport->width();
+		double h = masterViewport->height();
+		
+		if(!ossim::almostEqual(theHudViewport->x(),      x)||
+		   !ossim::almostEqual(theHudViewport->y(),      y)||
+		   !ossim::almostEqual(theHudViewport->width(),  w)||
+		   !ossim::almostEqual(theHudViewport->height(), h))
+		{
+			theHudViewport->setViewport(x,y,w,h);
+			theHudCamera->setProjectionMatrix(osg::Matrix::ortho2D(theHudViewport->x(),
+                                                                theHudViewport->width(),
+                                                                theHudViewport->y(),
+                                                                theHudViewport->height()));
+			updateText();
+		}
+	}
+	osg::ref_ptr<osg::CameraNode> theHudCamera;
+	osg::ref_ptr<osgText::Text> theHudText;
+	std::string theFontName;
+	osg::ref_ptr<osgText::Font> theFont;
+	osg::ref_ptr<osg::Viewport> theHudViewport;
+	osg::ref_ptr<osg::MatrixTransform> theRootScene;
+	osg::ref_ptr<ossimPlanetManipulator> thePlanetManipulator;
+	ossim_int32 theTestStage;
+	char theSwitchModeKey;
+	ossim_int32 theMaxTestStages;
+	bool theUpdateHudTextFlag;
+	ossimString theHudTextString;
+   osg::ref_ptr<osg::Node>             theFlightGearModel;
+   osg::ref_ptr<osg::MatrixTransform>  theFlightGearModelScaleTransform1;
+	osg::ref_ptr<ossimPlanetPointModel> thePointModel1;
+	osg::ref_ptr<ossimPlanetPointModel> thePointModel2;
+	ossim_float64 theLookModeDuration;
+	ossimFilename theRootDirectory;
+	
+	std::queue<ossimFilename> theTexturesToTest;
+   
+   double theSimTime;
+	double theDuration;
+   osg::Timer_t theStartTick;
+	osg::Timer_t theStartTick2;
+	osg::Timer_t lastHeadingTick;
+   osg::Timer_t theLastAnimationModeTick;
+   ossim_uint32 theAnimationFromMode;
+   ossim_uint32 theAnimationToMode;
+	ossim_uint32 texture_density;
+	ossim_uint32 elevation_density;
+	ossim_uint32 cap_location;
+	ossim_uint32 fogMode;
+   
+   ossimPlanetTextureLayerGroup* theAddRemoveLayer;
+   ossimString theSwapFile1;
+   ossimString theSwapFile2;
+#if 0
+   ossimPlanetTextureLayerGroup* theSwapTestGroup;
+   ossim_int32 theSwapTestIndex1;
+   ossim_int32 theSwapTestIndex2;
+#endif
+};
+
+bool TestHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) 
+{ 
+	ossimPlanetViewer* viewer = dynamic_cast<ossimPlanetViewer*>(&aa);
+	if(viewer)
+	{
+		switch(ea.getEventType())
+		{
+			case osgGA::GUIEventAdapter::FRAME:
+			{
+				if(!theHudCamera.valid())
+				{
+					initScene(viewer);
+				}
+				updateHudCoordinatesIfNeeded(viewer);
+				updateCurrentStage(viewer);
+				if(theUpdateHudTextFlag)
+				{
+					theUpdateHudTextFlag = false;
+					updateText();
+				}
+				break;
+			}
+			case osgGA::GUIEventAdapter::KEYDOWN:
+			{
+				if(ea.getKey() == theSwitchModeKey)
+				{
+					++theTestStage;
+					theTestStage = theTestStage % OSSIMPLANET_LAST_TEST;
+					setupStage(viewer);
+					return true;
+				}
+			}
+			default:
+			{
+				break;
+			}
+		}
+	}
+	return false; // go ahead and not consume any events and let them pass. 
+}
+
+void TestHandler::updateCurrentStage(ossimPlanetViewer* viewer)
+{
+	switch(theTestStage)
+	{
+		case OSSIMPLANET_SET_TEXTURE_DENSITY:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         bool textureDensityChanged = false;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > theDuration)
+         {
+            ++texture_density;
+            texture_density = texture_density%last_texture;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            
+            theUpdateHudTextFlag = true;
+            textureDensityChanged = true;
+            switch(texture_density)
+            {
+               case low_texture:
+               {
+                  viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::LOW_TEXTURE_DENSITY);
+                  viewer->terrainLayer()->refreshImageLayers();
+                  
+                  theHudTextString = "setTextureDensity: Low Texture";
+                  break;
+               }
+               case medium_low_texture:
+               {
+                  viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::MEDIUM_LOW_TEXTURE_DENSITY);
+                  viewer->terrainLayer()->refreshImageLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium Low Texture";
+                  break;
+               }
+               case medium_texture:
+               {
+                  viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY);
+                  viewer->terrainLayer()->refreshImageLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium Texture";
+                  break;
+               }
+               case medium_high_texture:
+               {
+                  viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::MEDIUM_HIGH_TEXTURE_DENSITY);
+                  viewer->terrainLayer()->refreshImageLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium High Texture";
+                  break;
+               }
+               case high_texture:
+               {
+                  viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::HIGH_TEXTURE_DENSITY);
+                  viewer->terrainLayer()->refreshImageLayers();
+                  
+                  theHudTextString = "setTextureDensity: High Texture";
+                  break;
+               }
+            }
+         }
+         break;
+      }
+      case OSSIMPLANET_ADD_REMOVE_TEXTURE_LAYER:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         if(osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick()) > theDuration)
+         {
+            std::swap(theSwapFile1, theSwapFile2);
+            theAddRemoveLayer->removeLayers(0, theAddRemoveLayer->numberOfLayers(), false);
+            osg::ref_ptr<ossimPlanetTextureLayer> layer1 = ossimPlanetTextureLayerRegistry::instance()->createLayer(theSwapFile1);
+            osg::ref_ptr<ossimPlanetTextureLayer> layer2 = ossimPlanetTextureLayerRegistry::instance()->createLayer(theSwapFile2);
+            
+            theAddRemoveLayer->addTop(layer1);
+            theAddRemoveLayer->addTop(layer2);
+            theHudTextString = "Swapping data";
+            theStartTick = osg::Timer::instance()->tick();
+         }
+#if 0
+         if(theSwapTestGroup&&
+            (theSwapTestIndex1>=0)&&
+            (theSwapTestIndex2>=0))
+         {
+            double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+            if(osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick()) > theDuration)
+            {
+               osg::ref_ptr<ossimPlanetTextureLayer> savedLayer = theSwapTestGroup->layer(theSwapTestIndex1);
+               osg::ref_ptr<ossimPlanetTextureLayer> savedLayer2 = theSwapTestGroup->layer(theSwapTestIndex2);
+               theSwapTestGroup->swapLayers(theSwapTestIndex1, theSwapTestIndex2);
+               std::swap(theSwapTestIndex1, theSwapTestIndex2);
+               theStartTick = osg::Timer::instance()->tick();
+               theUpdateHudTextFlag = true;
+               theHudTextString = "Swap texture: " + ossimString::toString(theSwapTestIndex1) + " with " 
+               +ossimString::toString(theSwapTestIndex2);
+#endif
+//               viewer->terrainLayer()->refreshImageLayers(savedLayer->getExtents().get());
+//               viewer->terrainLayer()->refreshImageLayers(savedLayer2->getExtents().get());
+#if 0
+               // now swap layers
+               //
+               osg::ref_ptr<ossimPlanetTextureLayer> savedLayer = theSwapTestGroup->layer(theSwapTestIndex1);
+               osg::ref_ptr<ossimPlanetTextureLayer> savedLayer2 = theSwapTestGroup->layer(theSwapTestIndex2);
+               theSwapTestGroup->replaceLayer(theSwapTestIndex1, savedLayer2.get());
+               theSwapTestGroup->replaceLayer(theSwapTestIndex2, savedLayer.get());
+               theHudTextString = "Swap texture: " + ossimString::toString(theSwapTestIndex1) + " with " 
+                                   +ossimString::toString(theSwapTestIndex2);
+               std::swap(theSwapTestIndex1, theSwapTestIndex2);
+               
+               theStartTick = osg::Timer::instance()->tick();
+               theUpdateHudTextFlag = true;
+               viewer->terrainLayer()->refreshImageLayers(savedLayer->getExtents().get());
+               viewer->terrainLayer()->refreshImageLayers(savedLayer2->getExtents().get());
+#endif
+//           }
+//         }
+         break;
+      }
+      case OSSIMPLANET_SET_ELEVATION_DENSITY:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > theDuration)
+         {
+            ++elevation_density;
+            elevation_density = elevation_density%last_elevation;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            
+            theUpdateHudTextFlag = true;
+            switch(elevation_density)
+            {
+               case low_elevation:
+               {                  
+                  viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::LOW_ELEVATION_DENSITY);
+                  viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setTextureDensity: Low Elevation";
+                  break;
+               }
+               case medium_low_elevation:
+               {
+                  viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::MEDIUM_LOW_ELEVATION_DENSITY);
+                  viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium Low Elevation";
+                  break;
+               }				
+               case medium_elevation:
+               {
+                  viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::MEDIUM_ELEVATION_DENSITY);
+                  viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium Elevation";
+                  break;
+               }
+               case medium_high_elevation:
+               {
+                  viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::MEDIUM_HIGH_ELEVATION_DENSITY);
+                  viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setTextureDensity: Medium High Elevation";
+                  break;
+               }
+               case high_elevation:
+               {
+                  viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::HIGH_ELEVATION_DENSITY);
+                  viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setTextureDensity: High Elevation";
+                  break;
+               }
+            }
+         }
+         break;
+      }
+		
+		case OSSIMPLANET_SET_CAP_LOCATION:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > theDuration)
+         {
+            ++elevation_density;
+            elevation_density = elevation_density%last_elevation;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            
+            theUpdateHudTextFlag = true;
+            switch(elevation_density)
+            {
+               case low_cap:
+               {                  
+						ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::LOW_CAP);
+						viewer->terrainLayer()->setGrid(grid);
+						viewer->terrainLayer()->refreshImageLayers();
+						viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setCapLocation: Low Cap";
+                  break;
+               }
+					case medium_low_cap:
+               {                  
+						ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_LOW_CAP);
+						viewer->terrainLayer()->setGrid(grid);
+						viewer->terrainLayer()->refreshImageLayers();
+						viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setCapLocation: Medium Low Cap";
+                  break;
+               }
+					case medium_cap:
+               {                  
+						ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_CAP);
+						viewer->terrainLayer()->setGrid(grid);
+						viewer->terrainLayer()->refreshImageLayers();
+						viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setCapLocation: Medium Cap";
+                  break;
+               }	
+					case medium_high_cap:
+               {                  
+						ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_HIGH_CAP);
+						viewer->terrainLayer()->setGrid(grid);
+						viewer->terrainLayer()->refreshImageLayers();
+						viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setCapLocation: Medium High Cap";
+                  break;
+               }
+						
+					case high_cap:
+               {                  
+						ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::HIGH_CAP);
+						viewer->terrainLayer()->setGrid(grid);
+						viewer->terrainLayer()->refreshImageLayers();
+						viewer->terrainLayer()->refreshElevationLayers();
+                  
+                  theHudTextString = "setCapLocation: High Cap";
+                  break;
+               }
+            }
+         }
+         break;
+      }
+			
+		case OSSIMPLANET_ADJUST_HEADING:
+      {
+         double currentHeading = thePointModel1->lsrSpace()->heading();
+         const double timeDelta60Hertz = 1.0/60.0;
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > timeDelta60Hertz)
+         {
+            currentHeading += (360*timeDelta60Hertz);
+            currentHeading = fmod(currentHeading, 360.0);
+            thePointModel1->lsrSpace()->setHeadingPitchRoll(osg::Vec3d(currentHeading,0,0));
+            theHudTextString = "Heading: " + ossimString::toString(currentHeading) + " degrees";
+            theUpdateHudTextFlag = true;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+         }
+         break;
+      }
+			
+		case OSSIMPLANET_ADJUST_PITCH:
+      {
+         double currentPitch = thePointModel1->lsrSpace()->pitch()+90.0;
+         const double timeDelta60Hertz = 1.0/60.0;
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > timeDelta60Hertz)
+         {
+            currentPitch += (180*timeDelta60Hertz);
+            currentPitch = fmod(currentPitch, 180.0);
+            thePointModel1->lsrSpace()->setHeadingPitchRoll(osg::Vec3d(0.0,currentPitch-90.0,0));
+            theHudTextString = "Pitch: " + ossimString::toString(currentPitch-90.0) + " degrees";
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            theUpdateHudTextFlag = true;
+         }
+         break;
+      }
+		
+		case OSSIMPLANET_ADJUST_ROLL:
+      {
+         double currentRoll = thePointModel1->lsrSpace()->roll()+90.0;
+         const double timeDelta60Hertz = 1.0/60.0;
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > timeDelta60Hertz)
+         {
+            currentRoll += (180*timeDelta60Hertz);
+            currentRoll = fmod(currentRoll, 180.0);
+            thePointModel1->lsrSpace()->setHeadingPitchRoll(osg::Vec3d(0.0,0.0,currentRoll-90.0));
+            theHudTextString = "Roll: " + ossimString::toString(currentRoll-90.0) + " degrees";
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            theUpdateHudTextFlag = true;
+         }
+         break;
+      }
+		
+		case OSSIMPLANET_EPHEMERIS_ANIMATE:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec*3600;
+         theUpdateHudTextFlag = true;
+         theHudTextString = "Initialize ephemeris: 3600x real time";
+         
+         break;
+      }
+      case OSSIMPLANET_ANIMATION_PATH:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         break;
+      }
+		case OSSIMPLANET_ANIMATION_PATH2:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         break;
+      }
+      case OSSIMPLANET_LOOKFROM:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         double range = (viewer->model()->calculateUnnormalizedLength(thePointModel1->getBound().radius()));
+         if((osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > theLookModeDuration)||
+            theAnimationFromMode == ANIMATION_FROM_INIT)
+         {
+            ++theAnimationFromMode;
+            theAnimationFromMode = theAnimationFromMode%ANIMATION_FROM_LAST;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            
+            switch(theAnimationFromMode)
+            {
+               case RELATIVE_FROM_GLOBAL_RANGE_NONE:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::NO_ORIENTATION);
+//                  thePlanetManipulator->viewMatrixBuilder()->setRange(-range*10);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  theHudTextString = "No realtive from global range mode";
+                  break;
+               }
+               case RELATIVE_FROM_NONE:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::NO_ORIENTATION);
+//                  thePlanetManipulator->viewMatrixBuilder()->setRange(0.0);
+                  
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  
+                  theHudTextString = "No realtive from mode";
+                  break;
+               }
+               case RELATIVE_FROM_HEADING:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::HEADING);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  theHudTextString = "Relative Heading";
+                  break;
+               }
+               case ANIMATION_FROM_STOP:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->invalidate();
+                  theHudTextString = "Stop Animation";
+                 break;
+               }
+               case RELATIVE_FROM_PITCH:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::PITCH);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  
+                  theHudTextString = "Relative Pitch";
+                  break;
+               }
+               case RELATIVE_FROM_ROLL:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::ROLL);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  theHudTextString = "Relative Roll";
+                  break;
+               }
+               case RELATIVE_FROM_ALL:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range*10,
+                                                                                   ossimPlanetViewMatrixBuilder::ALL_ORIENTATION);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  theHudTextString = "Relative All";
+                  break;
+               }
+               case FROM_DISPLACEMENT_XYPLANE_RELATIVE_ALL_AXIS:
+               {
+                  double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+                  osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,0.0,rotateAmount);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   0.0,
+                                                                                   ossimPlanetViewMatrixBuilder::ALL_ORIENTATION);
+                  osg::Vec3d displace = osg::Vec3d(0.0,1.0,0.0)*rotate;
+                  displace = displace*(range*2);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+                  theHudTextString = "Displacement In XY Plane Relative All Axis";
+                  break;
+               }
+               case FROM_DISPLACEMENT_XYPLANE_RELATIVE_NONE_AXIS:
+               {
+                  double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+                  osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,0.0,rotateAmount);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   0.0,
+                                                                                   ossimPlanetViewMatrixBuilder::NO_ORIENTATION);
+                  osg::Vec3d displace = osg::Vec3d(0.0,1.0,0.0)*rotate;
+                  displace = displace*(range*2);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+                  theHudTextString = "Displacement In XY Plane Relative No Axis (North aligned)";
+                  break;
+               }
+               case FROM_DISPLACEMENT_ZXPLANE_RELATIVE_ALL_AXIS:
+               {
+                  double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+                  osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,rotateAmount,0.0);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   0.0,
+                                                                                   ossimPlanetViewMatrixBuilder::ALL_ORIENTATION);
+                  osg::Vec3d displace = osg::Vec3d(0.0,0.0,1.0)*rotate;
+                  displace = displace*(range*2);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+                  theHudTextString = "Displacement In XZ Plane Relative All Axis";
+                  break;
+               }
+               case FROM_DISPLACEMENT_ZXPLANE_RELATIVE_NONE_AXIS:
+               {
+                  double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+                  osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,rotateAmount,0.0);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   0.0,
+                                                                                   ossimPlanetViewMatrixBuilder::NO_ORIENTATION);
+                  osg::Vec3d displace = osg::Vec3d(0.0,0.0,1.0)*rotate;
+                  displace = displace*(range*2);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+                  theHudTextString = "Displacement In XZ Plane Relative No Axis (North aligned)";
+                  break;
+               }
+            }
+            
+            theUpdateHudTextFlag = true;
+         }
+         switch(theAnimationFromMode)
+         {
+            case FROM_DISPLACEMENT_XYPLANE_RELATIVE_ALL_AXIS:
+            {
+               double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+               osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,0.0,rotateAmount);
+               osg::Vec3d displace = osg::Vec3d(0.0,1.0,0.0)*rotate;
+               displace = displace*(range*2);
+               thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+               break;
+            }
+            case FROM_DISPLACEMENT_XYPLANE_RELATIVE_NONE_AXIS:
+            {
+               double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+               osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,0.0,rotateAmount);
+               osg::Vec3d displace = osg::Vec3d(0.0,1.0,0.0)*rotate;
+               displace = displace*(range*2);
+               thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+               break;
+            }
+            case FROM_DISPLACEMENT_ZXPLANE_RELATIVE_ALL_AXIS:
+            {
+               double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+               osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,rotateAmount,0.0);
+               osg::Vec3d displace = osg::Vec3d(0.0,0.0,1.0)*rotate;
+               displace = displace*(range*2);
+               thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+               break;
+            }
+            case FROM_DISPLACEMENT_ZXPLANE_RELATIVE_NONE_AXIS:
+            {
+               double rotateAmount = osg::DegreesToRadians(360.0*(fmod(deltaSec, 3.0)/3.0));
+               osg::Matrixd rotate = osg::Matrixd::rotate(rotateAmount, 0.0,rotateAmount,0.0);
+               osg::Vec3d displace = osg::Vec3d(0.0,0.0,1.0)*rotate;
+               displace = displace*(range*2);
+               thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(displace);
+               break;
+            }
+               
+         }
+         break;
+      }
+		case OSSIMPLANET_LOOKTO:
+      {
+         double range = (viewer->model()->calculateUnnormalizedLength(thePointModel1->getBound().radius()))*10;
+         
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         if((osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > 3)||
+            (theAnimationToMode == ANIMATION_TO_MODE_INIT))
+         {
+            ++theAnimationToMode;
+            theAnimationToMode = theAnimationToMode%ANIMATION_TO_LAST;
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            switch(theAnimationToMode)
+            {
+               case ANIMATION_TO_BOTH_MOVING_NO_RELATVE:
+               {
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+                                                                                   osg::Vec3d(0.0, 0.0, 0.0),
+                                                                                   -range,
+                                                                                   ossimPlanetViewMatrixBuilder::NO_ORIENTATION);
+                  thePlanetManipulator->viewMatrixBuilder()->setLookToNode(thePointModel2.get());
+                  thePlanetManipulator->viewMatrixBuilder()->setLookToLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+                  
+//                  thePlanetManipulator->viewMatrixBuilder()->setRange(-range);
+                  thePlanetManipulator->viewMatrixBuilder()->setAttitudeHpr(osg::Vec3d(0,0,0));
+                  theHudTextString = "Animation To Both Moving No Relative";               
+                  break;
+               }
+            }
+            
+            theUpdateHudTextFlag = true;
+         }
+         
+         break;
+      }
+      case OSSIMPLANET_LOOKTO_DISPLACEMENT:
+      case OSSIMPLANET_LOOKFROM_CONVERSION:
+      case OSSIMPLANET_LOOKFROM_CONVERSION_RANGE_FLATTEN:
+      {
+         double deltaSec = osg::Timer::instance()->delta_s(theStartTick, osg::Timer::instance()->tick());
+         theSimTime = deltaSec;
+         break;
+      }
+      case OSSIMPLANET_LOOKTO_ALONG_AXIS:
+      {
+         break;
+      }
+      case OSSIMPLANET_ADD_FOG:
+      {
+         if(osg::Timer::instance()->delta_s(theLastAnimationModeTick, osg::Timer::instance()->tick()) > theDuration)
+         {
+            theLastAnimationModeTick = osg::Timer::instance()->tick();
+            ++fogMode;
+            fogMode = fogMode%FOG_LAST;
+            
+            switch(fogMode)
+            {
+               case FOG_CLEAR:
+               {
+                  viewer->ephemeris()->setFogEnableFlag(false);
+                  theHudTextString = "Fog: Clear Day";
+                  theUpdateHudTextFlag = true;
+                  break;
+               }
+               case FOG_VERY_LIGHT:
+               {
+                  viewer->ephemeris()->setFogEnableFlag(true);
+                  viewer->ephemeris()->setVisibility(1000000);
+                  theHudTextString = "Fog: Very Light";
+                  theUpdateHudTextFlag = true;
+                  break;
+               }
+               case FOG_LIGHT:
+               {
+                  theHudTextString = "Fog: Light";
+                  theUpdateHudTextFlag = true;
+                  viewer->ephemeris()->setVisibility(500000);
+                 break;
+               }
+               case FOG_MEDIUM:
+               {
+                  theHudTextString = "Fog: Medium Fog";
+                  theUpdateHudTextFlag = true;
+                  viewer->ephemeris()->setVisibility(200000);
+                  break;
+               }
+               case FOG_MEDIUM_HEAVY:
+               {
+                  theHudTextString = "Fog: Medium Heavy Fog";
+                  theUpdateHudTextFlag = true;
+                  viewer->ephemeris()->setVisibility(100000);
+                  break;
+               }
+               case FOG_HEAVY:
+               {
+                  theHudTextString = "Fog: Heavy Fog";
+                  theUpdateHudTextFlag = true;
+                  viewer->ephemeris()->setVisibility(50000);
+                  break;
+               }
+            }
+         }
+         break;
+      }
+   }
+}
+
+void TestHandler::setupStage(ossimPlanetViewer* viewer)
+{
+	theUpdateHudTextFlag = true;
+	switch (theTestStage)
+	{
+		// Init Terrain
+		case OSSIMPLANET_INIT_TERRAIN:
+		{
+				// clear pointers that need clearing
+				//
+				thePointModel1 = 0;
+				thePointModel2 = 0;
+				theFlightGearModel = 0;
+				theFlightGearModelScaleTransform1 = 0;
+				thePlanetManipulator = 0;
+				if(viewer->planet())
+				{
+					viewer->planet()->removeChildren(0, viewer->planet()->getNumChildren());
+				}
+				viewer->setSceneData(0);
+				viewer->setCameraManipulator(0);
+				viewer->removeEphemeris();
+				
+				// done clearing pointers
+				
+				// Now init the new pointers
+				//
+				thePlanetManipulator = new ossimPlanetManipulator;
+				ossimPlanet* planet = new ossimPlanet;
+				theRootScene = new osg::MatrixTransform();
+				theRootScene->addChild(planet);
+				theRootScene->addChild(theHudCamera.get());
+				viewer->setSceneData(theRootScene.get());
+				viewer->setCameraManipulator(thePlanetManipulator.get());
+				viewer->planet()->addChild(new ossimPlanetTerrain);
+				
+				//  latLon Hud Overlay
+				//ossimPlanetLatLonHud* latLonHud = new ossimPlanetLatLonHud();
+				//viewer->planet()->addChild(latLonHud);
+				
+				osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(0.0,
+																									-89.999999999999,
+																									20410038.400000,
+																									0,
+																									0,
+																									0,
+																									0.0,
+																									ossimPlanetAltitudeMode_ABSOLUTE);
+				thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+				
+				theHudTextString = "Terrain Test";
+				theUpdateHudTextFlag = true;
+				viewer->planet()->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
+			
+				// for any other stage we should have a root scene
+				if(!theRootScene.valid()) return;
+			
+         viewer->addEphemeris(ossimPlanetEphemeris::SUN_LIGHT|
+                              ossimPlanetEphemeris::SKY);
+				
+				break;
+		}
+		
+		// Set Geoid
+		case OSSIMPLANET_SET_GEOID:
+		{
+			ossimGeoidEgm96* geoid = new ossimGeoidEgm96(theRootDirectory.dirCat("geoid/egm96.grd"));
+			viewer->planet()->model()->setGeoid(geoid);
+			
+			viewer->terrainLayer()->setElevationExaggeration(10000);
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			theHudTextString = "setGeoid: " + theRootDirectory + "/geoid/egm96.grd\n";
+			theHudTextString += "setElevationExaggeration: 10000x";
+			
+			break;
+		}
+		
+		// Set Elevation Density
+		case OSSIMPLANET_SET_ELEVATION_DENSITY:
+		{
+			viewer->terrainLayer()->setElevationExaggeration(1); // set elevation exaggeration back to 1x
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			osg::StateSet* state = viewer->terrainLayer()->getOrCreateStateSet();
+			osg::PolygonMode* polygonMode = new osg::PolygonMode(osg::PolygonMode::FRONT,osg::PolygonMode::LINE);
+			state->setAttributeAndModes(polygonMode);
+			
+			theSimTime = 0.0;
+			theDuration = 5.0; // duration between elevation density modes
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			elevation_density = low_elevation;
+			
+			viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::LOW_ELEVATION_DENSITY);
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			theUpdateHudTextFlag = true;
+			theHudTextString = "setElevationDensity: Low Elevation Density";
+			
+			break;
+		}
+		
+		// Set Cap Position
+		case OSSIMPLANET_SET_CAP_LOCATION:
+		{
+			viewer->terrainLayer()->setElevationDensityType(ossimPlanetTerrain::LOW_ELEVATION_DENSITY); // set elevation density back to low
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(45.000000000000,
+                                                                        -89.999999999999,
+                                                                        20410038.400000,
+                                                                        0,
+                                                                        0,
+                                                                        0,
+                                                                        ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+			
+			theSimTime = 0.0;
+			theDuration = 5.0; // duration between cap location modes
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			cap_location = low_cap;
+			
+			ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::LOW_CAP);
+			viewer->terrainLayer()->setGrid(grid);
+			viewer->terrainLayer()->refreshImageLayers();
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			theUpdateHudTextFlag = true;
+			theHudTextString = "setCapLocation: Low Cap Location";
+			
+			break;	
+		}
+		
+		// Add Image Texture
+		case OSSIMPLANET_ADD_IMAGE_TEXTURE:
+		{
+			ossimPlanetAdjustableCubeGrid* grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::LOW_CAP); // set cap position back to low
+			viewer->terrainLayer()->setGrid(grid);
+			viewer->terrainLayer()->refreshImageLayers();
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(0.000000000000,
+                                                                        -89.999999999999,
+                                                                        20410038.400000,
+                                                                        0,
+                                                                        0,
+                                                                        0,
+                                                                        ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+			
+			osg::StateSet* state = viewer->terrainLayer()->getOrCreateStateSet();
+			osg::PolygonMode* polygonMode = new osg::PolygonMode(osg::PolygonMode::FRONT,osg::PolygonMode::FILL);
+			state->setAttributeAndModes(polygonMode);
+			
+			viewer->addImageTexture(theRootDirectory.dirCat("images/textures/reference/earth.jpg"));
+			viewer->terrainLayer()->refreshImageLayers();
+			
+			theHudTextString = "addImageTexture: " + theRootDirectory + "/images/textures/reference/earth.jpg";
+			
+			break;
+		}
+			
+		// Add Florida Data
+		case OSSIMPLANET_ADD_FLORIDA_DATA:
+		{
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(28.239487609273,
+                                                                        -80.607619385637,
+                                                                        1938857.036673,
+                                                                        0,
+                                                                        0,
+                                                                        0,
+                                                                        ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+			
+			viewer->addImageTexture(theRootDirectory.dirCat("images/textures/florida/brevard.tif"));
+			viewer->terrainLayer()->refreshImageLayers();
+			
+			theHudTextString = "addImageTexture: adding Florida data";
+			
+			break;	
+		}
+		case OSSIMPLANET_ADD_REMOVE_TEXTURE_LAYER:
+		{
+         theAddRemoveLayer = new ossimPlanetTextureLayerGroup;
+         viewer->addImageTexture(theAddRemoveLayer);
+         theSwapFile1 = theRootDirectory.dirCat("images/textures/sanfran/sanfran.tif").c_str();
+         theSwapFile2 = theRootDirectory.dirCat("images/textures/sanfran/sanfran_map.tif").c_str();
+         
+         osg::ref_ptr<ossimPlanetTextureLayer> layer1 = ossimPlanetTextureLayerRegistry::instance()->createLayer(theSwapFile1);
+         osg::ref_ptr<ossimPlanetTextureLayer> layer2 = ossimPlanetTextureLayerRegistry::instance()->createLayer(theSwapFile2);
+         if(layer1.valid())
+         {
+            layer1->resetLookAt();
+            thePlanetManipulator->navigator()->gotoLookAt(*layer1->getLookAt(), false);
+         }
+         
+         theAddRemoveLayer->addTop(layer1.get(), false);
+         theAddRemoveLayer->addTop(layer2.get(), false);
+			theHudTextString = "addImageTexture: adding Sanfran data for swap test";
+			theStartTick = osg::Timer::instance()->tick();
+			theDuration = .1; // duration between elevation density modes
+#if 0
+         osg::ref_ptr<ossimPlanetTextureLayer> layer1 = viewer->addImageTexture(theRootDirectory.dirCat("images/textures/sanfran/sanfran.tif"));
+         theSwapTestGroup = 0;
+         if(layer1.valid())
+         {
+            theSwapTestGroup = layer1->parent(0);
+            layer1->resetLookAt();
+            thePlanetManipulator->navigator()->gotoLookAt(*layer1->getLookAt(), false);
+         }
+			
+         osg::ref_ptr<ossimPlanetTextureLayer> layer2 = viewer->addImageTexture(theRootDirectory.dirCat("images/textures/sanfran/sanfran_map.tif"));
+         if(layer1.valid()&&layer2.valid()&&theSwapTestGroup)
+         {
+            theSwapTestIndex1 = theSwapTestGroup->findLayerIndex(layer1.get());
+            theSwapTestIndex2 = theSwapTestGroup->findLayerIndex(layer2.get());
+         }
+         else
+         {
+            theSwapTestIndex1 = -1;
+            theSwapTestIndex2 = -1;
+         }
+			theUpdateHudTextFlag = true;
+			theHudTextString = "addImageTexture: adding Sanfran data for swap test";
+			theStartTick = osg::Timer::instance()->tick();
+			theDuration = .1; // duration between elevation density modes
+#endif
+			break;	
+		}
+         
+		// Set Texture Density
+		case OSSIMPLANET_SET_TEXTURE_DENSITY:
+		{
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(0.000000000000,
+                                                                        -89.999999999999,
+                                                                        20410038.400000,
+                                                                        0,
+                                                                        0,
+                                                                        0,
+                                                                        ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+						
+			theSimTime = 0.0;
+			theDuration = 5.0; // duration between texture density modes
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			texture_density = low_texture;
+			
+			viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::LOW_TEXTURE_DENSITY);
+			viewer->terrainLayer()->refreshImageLayers();
+			
+			theUpdateHudTextFlag = true;
+			theHudTextString = "setTextureDensity: Low Texture Density";
+			
+			break;
+		}
+		
+		// Add Annotation Node
+		case OSSIMPLANET_ADD_ANNOTATION_NODE:
+		{
+			viewer->terrainLayer()->setTextureDensityType(ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY); // set texture density back to medium
+			viewer->terrainLayer()->refreshImageLayers();
+			
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(28.2395,
+                                                                        -80.6076,
+                                                                        100.9824,
+                                                                        0,
+                                                                        0,
+                                                                        0,
+                                                                        ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+			
+			if(!viewer->annotationLayer())
+			{
+				viewer->planet()->addChild(new ossimPlanetAnnotationLayer);
+			}
+			
+			else
+			{
+				viewer->annotationLayer()->removeChildren(0, viewer->annotationLayer()->getNumChildren());
+			}
+			
+			if(!theFlightGearModel.valid())
+         {
+          //  theFlightGearModel = loadFlightGearModel(theRootDirectory.dirCat("flight_models/f16/f16.osg"),viewer->planet()->model().get());
+            theFlightGearModel = loadFlightGearModel(theRootDirectory.dirCat("flight_models/flightgear/Aircraft/f16/Models/f16.ac"),viewer->planet()->model().get());
+            theFlightGearModelScaleTransform1 = new osg::MatrixTransform;
+            theFlightGearModelScaleTransform1->addChild(theFlightGearModel.get());
+				theFlightGearModelScaleTransform1->setMatrix(osg::Matrixd());
+				
+				thePointModel1 = new ossimPlanetPointModel();
+            viewer->annotationLayer()->addChild(thePointModel1.get());
+            thePointModel1->setNode(theFlightGearModelScaleTransform1.get());
+				thePointModel1->lsrSpace()->setLatLonAltitude(osg::Vec3d(28.2395, -80.6076, 50.9824));
+			}
+			
+			theHudTextString = "setNode: " + theRootDirectory + "flight_models/flightgear/Aircraft/f16/Models/f16.ac";
+			
+			break;	
+		}
+		
+		// Adjust Heading
+		case OSSIMPLANET_ADJUST_HEADING:
+		{
+			theSimTime = 0.0;
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			
+			break;	
+		}
+		
+		// Adjust Pitch
+		case OSSIMPLANET_ADJUST_PITCH:
+		{
+			theSimTime = 0.0;
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			
+			break;	
+		}
+		
+		// Adjust Roll
+		case OSSIMPLANET_ADJUST_ROLL:
+		{
+			theSimTime = 0.0;
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			
+			break;	
+		}
+		
+		// Add the following...
+		// lat jog
+		// lon jog
+		// alt jog
+		// scale .5x 1x 2x
+		
+		// Add Elevation
+		case OSSIMPLANET_ADD_ELEVATION:
+		{
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(35.421021580041,
+																								-83.080005227486,
+																								4062.174155,
+																								0,
+																								90,
+																								0,
+																								0.0,
+																								ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+			
+			viewer->terrainLayer()->addElevation(theRootDirectory.dirCat("srtm30plus/"), 1);
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			theHudTextString = "addElevation: " + theRootDirectory + "/srtm30plus/";
+			
+			break;
+		}
+		
+		case OSSIMPLANET_ELEVATION_EXAGGERATION:
+		{
+			viewer->terrainLayer()->setElevationExaggeration(1.5);
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			theHudTextString = "setElevationExaggeration: 1.5x";
+			
+			break;
+		}
+		
+		case OSSIMPLANET_INITIALIZE_EPHEMERIS:
+		{
+			viewer->terrainLayer()->setElevationExaggeration(1); // set elevation exaggeration back to 1x
+			viewer->terrainLayer()->refreshElevationLayers();
+			
+			osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(35.421021580041,
+																								-83.080005227486,
+																								3562.174155,
+																								0,
+																								90,
+																								0,
+																								0.0,
+																								ossimPlanetAltitudeMode_ABSOLUTE);
+			thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+						
+			viewer->planet()->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
+			
+			theSimTime = 0.0;
+			
+			ossimFilename sunTextureFile = theRootDirectory.dirCat("images/icons/sun.png");
+			ossimFilename moonTextureFile = theRootDirectory.dirCat("images/icons/moon.png");
+			ossim_float64 visibility = 1000000000.0;
+			ossim_float64 fogNear = 20.0;
+			
+			viewer->addEphemeris(ossimPlanetEphemeris::SUN_LIGHT
+										//|ossimPlanetEphemeris::MOON_LIGHT
+										//|ossimPlanetEphemeris::AMBIENT_LIGHT
+										|ossimPlanetEphemeris::SUN
+										|ossimPlanetEphemeris::MOON
+										|ossimPlanetEphemeris::SKY
+										|ossimPlanetEphemeris::FOG
+										);
+			
+			ossimLocalTm date;
+			date.now();
+			viewer->ephemeris()->setDate(date);
+			
+			viewer->ephemeris()->setApplySimulationTimeOffsetFlag(false);
+			viewer->ephemeris()->setSunTextureFromFile(sunTextureFile);
+			viewer->ephemeris()->setMoonTextureFromFile(moonTextureFile);
+			//viewer->ephemeris()->setGlobalAmbientLight(osg::Vec3d(0.1, 0.1, 0.1));
+			viewer->ephemeris()->setVisibility(visibility);
+			viewer->ephemeris()->setFogNear(fogNear);
+			viewer->ephemeris()->setFogMode(ossimPlanetEphemeris::LINEAR);
+			viewer->ephemeris()->setFogEnableFlag(true);
+			
+			theHudTextString = "addEphemeris: Real Time";
+			
+			break;	
+		}
+		
+		// Add Clouds
+		case OSSIMPLANET_ADD_CLOUDS:
+		{
+			ossim_int32 cloudCoverage = 20;
+			ossim_float64 cloudSharpness = .95;
+			ossim_float64 cloudAltitude = 20000;
+			
+			osg::ref_ptr<ossimPlanetCloudLayer> cloud = new ossimPlanetCloudLayer;
+			viewer->planet()->addChild(cloud.get());
+			
+			cloud->computeMesh(cloudAltitude, 32,32,1);
+			cloud->updateTexture(time(0), cloudCoverage, cloudSharpness);
+			cloud->setSpeedPerHour(60.0, OSSIM_MILES);
+			cloud->setScale(4);
+			
+			theHudTextString = "Enable Clouds";
+			
+			break;	
+		}
+			
+		// Add Fog
+		case OSSIMPLANET_ADD_FOG:
+		{
+			theSimTime = 0.0;
+			theDuration = 5.0; // duration between fog modes
+			
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			fogMode = FOG_CLEAR;
+			
+			viewer->ephemeris()->setFogEnableFlag(false);
+			
+			theUpdateHudTextFlag = true;
+			theHudTextString = "Enable Fog: Clear Day";
+			
+			break;	
+		}
+		
+		case OSSIMPLANET_EPHEMERIS_ANIMATE:
+			{
+				viewer->ephemeris()->setApplySimulationTimeOffsetFlag(true);
+				
+				theStartTick = osg::Timer::instance()->tick();
+				
+				theUpdateHudTextFlag = true;
+				theHudTextString = "addEphemeris: Sim time = 3600x";
+				
+				break;
+			}
+		
+		case OSSIMPLANET_ANIMATION_PATH:
+		{
+			viewer->planet()->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
+			
+			osg::ref_ptr<ossimPlanetAnimationPath> animationPath = new ossimPlanetAnimationPath;
+			
+			theStartTick = osg::Timer::instance()->tick();
+			
+			theFlightGearModelScaleTransform1->setMatrix(osg::Matrixd::scale(50.0,50.0,50.0));
+			theFlightGearModelScaleTransform1->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
+			
+			animationPath->openAnimationPathByXmlDocument(ossimFilename(theRootDirectory.dirCat("flight_paths/flight1.xml")));
+			thePointModel1->setCullingActive(false);
+			theFlightGearModelScaleTransform1->setCullingActive(false);
+			
+			if(animationPath->geospatialPath()&&(!animationPath->geospatialPath()->empty()))
+			{
+				ossimPlanetAnimationPath::Tuple value = animationPath->geospatialPath()->timeTupleMap().begin()->second;
+				osg::ref_ptr<ossimPlanetLookAt> lookAt = new ossimPlanetLookAt(value.position()[0],
+																									value.position()[1],
+																									value.position()[2],
+																									0.0,
+																									45.0,
+																									0.0,
+																									5000,
+																									ossimPlanetAltitudeMode_ABSOLUTE);
+				thePlanetManipulator->navigator()->gotoLookAt(*lookAt, false);
+				
+				osg::ref_ptr<ossimPlanetAnimatedPointModel> animatedPath = new ossimPlanetAnimatedPointModel();
+				
+				animationPath->setGeoRefModel(viewer->planet()->model().get());
+				animationPath->setLoopMode(osg::AnimationPath::LOOP);
+				animatedPath->setPointModel(thePointModel1.get());
+				animatedPath->setAnimationPath(animationPath.get());
+				animatedPath->setTimeScale(10.0);
+				animatedPath->setTimeOffset(0.0);
+				animatedPath->setAnimationPathColor(osg::Vec4f(2.0,0.0, 2.0, .5));
+				
+				viewer->annotationLayer()->addChild(animatedPath.get());
+				theSimTime = 0.0;
+				theHudTextString = "Add Animation Path 1";		
+			}
+			else
+			{
+				theHudTextString = "No points in flightpath file";		
+			}	
+			
+		break;
+		}
+		
+		case OSSIMPLANET_ANIMATION_PATH2:
+		{
+			theStartTick = osg::Timer::instance()->tick();
+				if(!thePointModel2.valid())
+				{
+					thePointModel2 = new ossimPlanetPointModel;
+					thePointModel2->setNode(theFlightGearModelScaleTransform1.get());
+				}
+				thePointModel2->setCullingActive(false);
+				osg::ref_ptr<ossimPlanetAnimationPath> animationPath2 = new ossimPlanetAnimationPath;;
+				
+				animationPath2->openAnimationPathByXmlDocument(ossimFilename(theRootDirectory.dirCat("flight_paths/flight2.xml")));
+				
+				osg::ref_ptr<ossimPlanetAnimatedPointModel> animatedPath2 = new ossimPlanetAnimatedPointModel();
+				
+				animationPath2->setGeoRefModel(viewer->planet()->model().get());
+				animationPath2->setLoopMode(osg::AnimationPath::LOOP);
+				animatedPath2->setPointModel(thePointModel2.get());
+				animatedPath2->setAnimationPath(animationPath2.get());
+				animatedPath2->setTimeScale(62.0);
+				animatedPath2->setTimeOffset(0.0);
+				viewer->annotationLayer()->addChild(animatedPath2.get());
+				theHudTextString = "Add Animation Path 2";		
+		
+				break;
+			}
+			
+		case OSSIMPLANET_LOOKFROM:
+		{
+			
+			thePlanetManipulator->setEventHandlingFlag(true);
+			thePlanetManipulator->viewMatrixBuilder()->setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_Y);
+			theSimTime = 0.0;
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			theAnimationFromMode = ANIMATION_FROM_INIT;
+			theHudTextString     = "No realtive from mode";
+			theUpdateHudTextFlag = true;
+			break;	
+		}
+			
+		case OSSIMPLANET_LOOKTO:
+		{
+			thePlanetManipulator->setEventHandlingFlag(true);
+			thePlanetManipulator->viewMatrixBuilder()->setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_Y);
+			theSimTime = 0.0;
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			theAnimationToMode = ANIMATION_TO_MODE_INIT;
+			theHudTextString = "Animation To Both Moving No Relative";
+			theUpdateHudTextFlag = true;
+			
+			break;
+		}
+			
+		case OSSIMPLANET_LOOKTO_DISPLACEMENT:
+		{
+			
+			thePlanetManipulator->setEventHandlingFlag(true);
+			thePlanetManipulator->viewMatrixBuilder()->setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_Y);
+			theSimTime = 0.0;
+			theStartTick = osg::Timer::instance()->tick();
+			theLastAnimationModeTick = theStartTick;
+			double range = (viewer->model()->calculateUnnormalizedLength(thePointModel1->getBound().radius()))*10;
+			
+			// setup Local LSR to calculate displacement
+			//
+			thePlanetManipulator->viewMatrixBuilder()->setLookFromNodeOffset(thePointModel1.get(),
+																								  osg::Vec3d(0.0, 0.0, 0.0),
+																								  0.0,
+																								  ossimPlanetViewMatrixBuilder::HEADING);
+			
+			thePlanetManipulator->viewMatrixBuilder()->setLookToNode(thePointModel2.get());
+			thePlanetManipulator->viewMatrixBuilder()->setAttitudeHpr(osg::Vec3d(0.0,0.0, 0.0));
+			thePlanetManipulator->viewMatrixBuilder()->setLookToLocalDisplacement(osg::Vec3d(0.0,range*.1,-range*2));
+			theHudTextString = "Animation Look To displacement";
+			theUpdateHudTextFlag = true;
+			
+			break;
+		}
+      case OSSIMPLANET_LOOKFROM_CONVERSION:
+      {
+         thePlanetManipulator->viewMatrixBuilder()->convertToAFromViewMatrix(false);
+			theHudTextString = "Converted to a look from without flatten";
+			theUpdateHudTextFlag = true;
+         break;
+      }
+      case OSSIMPLANET_LOOKFROM_CONVERSION_RANGE_FLATTEN:
+      {
+         //thePlanetManipulator->viewMatrixBuilder()->convertToAFromViewMatrix(true);
+         thePlanetManipulator->viewMatrixBuilder()->setParametersByMatrix(thePlanetManipulator->viewMatrixBuilder()->viewMatrix());
+			theHudTextString = "Converted to a look from with range flattened";
+			theUpdateHudTextFlag = true;
+         break;
+      }
+      case OSSIMPLANET_LOOKTO_ALONG_AXIS:
+      {
+ 			double range = (viewer->model()->calculateUnnormalizedLength(thePointModel1->getBound().radius()))*10;
+         osg::Vec3d from(thePointModel1->lsrSpace()->latLonAltitude());
+         osg::Vec3d to(thePointModel1->lsrSpace()->latLonAltitude());
+         from[2]+=range;
+         thePlanetManipulator->viewMatrixBuilder()->setLookFrom(from,
+                                                                osg::Vec3d(0.0, 0.0, 0.0),
+                                                                0.0);
+         thePlanetManipulator->viewMatrixBuilder()->updateFromLocalDisplacement(osg::Vec3d(0.0,0.0,0.0));
+         thePlanetManipulator->viewMatrixBuilder()->setLookTo(to);
+			theHudTextString = "Looking down Z to a point";
+			theUpdateHudTextFlag = true;
+         break;
+      }
+		default:
+			break;
+	}
+	
+}
+
+void TestHandler::initScene(ossimPlanetViewer* viewer)
+{
+	theFont = osgText::readFontFile(theFontName.c_str());
+	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+	osg::StateSet* stateset = geode->getOrCreateStateSet();
+	stateset->setMode(GL_LIGHTING,
+                     osg::StateAttribute::OFF);
+	stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+	stateset->setRenderBinDetails(11,"RenderBin");
+	stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+	stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+	stateset->setAttribute(new osg::PolygonMode(), 
+                          osg::StateAttribute::PROTECTED); // don't allow to go to wireframe
+	theHudCamera = new osg::CameraNode;
+	theHudViewport = new osg::Viewport(0,0,1024,1024);
+	theHudText   = new osgText::Text;
+	theHudText->setSupportsDisplayList(false);
+	theHudText->setFont(theFont.get());
+	geode->addDrawable(theHudText.get());
+	theHudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+	theHudCamera->setProjectionMatrix(osg::Matrix::ortho2D(theHudViewport->x(),
+                                                          theHudViewport->width(),
+                                                          theHudViewport->y(),
+                                                          theHudViewport->height()));
+	theHudCamera->setViewMatrix(osg::Matrix::identity());
+	theHudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
+	theHudCamera->setRenderOrder(osg::CameraNode::POST_RENDER);
+	theHudCamera->addChild(geode.get());
+	osg::BoundingBox bb = osg::BoundingBox();
+	bb.expandBy(theHudText->getBound());	
+	theHudText->setPosition(osg::Vec3d(5.0,bb.yMax()-bb.yMin(),0.0));
+}
+
+int main(int argc, char* argv[])
+{
+	ossimInit::instance()->initialize(argc, argv);
+	
+	osg::ArgumentParser arguments(&argc,argv);
+	arguments.getApplicationUsage()->addCommandLineOption("--root-dir", "Root directory for testing");
+	//add more arguments
+	
+	ossim_uint32 helpType = 0;
+	
+	if ((helpType = arguments.readHelpType()))
+	{
+		arguments.getApplicationUsage()->write(std::cout, helpType);
+		return 1;
+	}
+	
+	ossimString tempString;
+	osg::ArgumentParser::Parameter stringParam(tempString);
+	
+	//Viewer and Test Handler Objects
+	osg::ref_ptr<ossimPlanetViewer> viewer = new ossimPlanetViewer(arguments); // object for viewer
+	osg::ref_ptr<TestHandler> testHandler = new TestHandler;
+	//osg::ref_ptr<ossimPlanetTerrain> terrain = new ossimPlanetTerrain();
+	
+	//Event Handlers
+	
+	viewer->addEventHandler(testHandler.get());
+	viewer->addEventHandler(new osgViewer::WindowSizeHandler);
+	viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
+	viewer->addEventHandler(new osgViewer::StatsHandler);
+	
+	if(arguments.read("--root-dir", stringParam))
+	{
+		testHandler->setRootDirectory(ossimFilename(tempString));
+	}
+	while(!viewer->done())
+	{
+		viewer->frame(testHandler->simtime());
+	}
+	
+	return 0;
+}
diff --git a/ossimPlanet/examples/ossimplanetviewer/GNUmakefile b/ossimPlanet/examples/ossimplanetviewer/GNUmakefile
new file mode 100644
index 0000000..d860c13
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/GNUmakefile
@@ -0,0 +1,21 @@
+TOPDIR = ../..
+include $(TOPDIR)/Make/makedefs 
+
+CXXFILES =\
+	ossimplanetviewer.cpp \
+	opvLoadModel.cpp
+
+LIBS     += $(OSSIM_LIBS) -lossimPlanet $(OSG_LIBS) $(OTHER_LIBS) 
+
+ifeq ($(OS),Darwin)
+	LIBS += -bind_at_load
+endif
+
+INSTFILES = \
+	$(CXXFILES)\
+	GNUmakefile.inst=GNUmakefile
+LIB=
+EXEC = ossimplanetviewer
+
+include $(TOPDIR)/Make/makerules 
+
diff --git a/ossimPlanet/examples/ossimplanetviewer/archive_manager.kwl b/ossimPlanet/examples/ossimplanetviewer/archive_manager.kwl
new file mode 100644
index 0000000..d0eb96b
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/archive_manager.kwl
@@ -0,0 +1,36 @@
+// Note: If you are specifying opacity values then the 
+// bottom layer is not applied since it is just initially copied into the destination
+// All layers after that are blended based on the apacity.  The default opacity is 255
+// which indicates completely opaque and anything less than that defines how 
+// translucent the layer is.
+//
+// Note:  You must name each layer archive0 upto archive<n-1> .  
+//        So currently if you delete a layer you must manually re-number
+//        each keyword in the list.
+//
+// We support local and remote files.  Currently for remote we only support
+// wms and you must give the full string  for STYLES and layers you want and
+// make sure you end it with an &.
+//
+
+
+
+//archive0.type: local
+//archive0.file0: /data/earth/land_shallow_topo_east_tiled.tif
+//archive0.file1: /data/earth/land_shallow_topo_west_tiled.tif
+//archive0.transparent_color_flag:0
+//archive0.transparent_color: 0 0 0
+//archive0.opacity: 255
+
+//archive0.type: wms
+//archive0.server: http://neptune.flids.com/cgi-bin/ngos.cgi?LAYERS=Earth_Image,ngos
+//archive0.cache_dir: c:/data/wms/ngos/all
+
+//archive0.server: http://wmt.jpl.nasa.gov/cgi-bin/wmt.cgi?STYLES=visual&LAYERS=global_mosaic&sharp=0.0&
+
+archive0.type:wms
+archive0.server: http://wms.telascience.org/cgi-bin/bmng_wms_t?LAYERS=BMNG
+archive0.cache_dir: /data/wms/bmng
+archive0.opacity: 255
+
+
diff --git a/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.cpp b/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.cpp
new file mode 100644
index 0000000..d86abf9
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.cpp
@@ -0,0 +1,354 @@
+//
+// opvLoadModel.cpp
+//
+// osgPlanetView load model functionality
+//
+
+#include <osgDB/ReadFile>
+#include <osgUtil/SmoothingVisitor>
+
+#include <ossimPlanet/ossimPlanet.h>
+
+#include <ossim/base/ossimEcefPoint.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/projection/ossimUtmProjection.h>
+#include <ossim/base/ossimGeoidManager.h>
+#include <ossim/elevation/ossimElevManager.h>
+
+//
+// This visitor modifies each geometry it finds by creating
+//  a transformArrayVisitor.
+// 
+class geomVisitor : public osg::NodeVisitor
+{
+public:
+   geomVisitor()
+         :osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
+          theMode(ossimPlanetLandType_NORMALIZED_ELLIPSOID)
+      {
+      }
+
+   virtual void apply(osg::Geode& node);
+   virtual void apply(osg::Node& node);
+   ossimPlanetLandType       theMode;
+   osg::Vec3d              theCenter;
+   ossimMapProjection*     theProj;
+   ossimDpt                theLocation;
+};
+
+//
+// This visitor modifies a vertex list by transforming each
+//  vertex to ossimPlanet coordinates.
+// 
+class transformArrayVisitor: public osg::ArrayVisitor
+{
+public:
+   transformArrayVisitor(ossimPlanetLandType mode=ossimPlanetLandType_NORMALIZED_ELLIPSOID):theMode(mode)
+      {
+      }
+   virtual void apply(osg::Vec3Array& array);
+
+   ossimPlanetLandType      theMode;
+   osg::Vec3d             theCenter;
+   ossimMapProjection*    theProj;
+   ossimDpt               theLocation;
+};
+
+void transformArrayVisitor::apply(osg::Vec3Array& array)
+{
+   unsigned int idx = 0;
+
+   switch(theMode)
+   {
+      case ossimPlanetLandType_NORMALIZED_ELLIPSOID:
+      {
+         ossimGpt gpt;
+         ossimEcefPoint ecef;
+         ecef = gpt;
+         double normalizationFactor = ecef.getMagnitude();
+         for(idx = 0; idx < array.size(); ++idx)
+         {
+            // Treat the coordinate of the model as meters
+            ossimDpt point(array[idx][0],
+    	                   array[idx][1]);
+
+            // Offset to place the model at the desired UTM X,Y location
+            point += theLocation;
+
+            // Transform to geographic coordinates
+            theProj->eastingNorthingToWorld(point,
+                                            gpt);
+            double deltaH = ossimElevManager::instance()->getHeightAboveMSL(gpt);
+            if(ossim::isnan(deltaH))
+            {
+               deltaH = 0.0;
+            }
+            gpt.height(array[idx][2] +deltaH+ ossimGeoidManager::instance()->offsetFromEllipsoid(gpt));
+            // Transform to ossimPlanet coordinates
+            ecef = gpt;
+            array[idx][0] = ecef.x()/normalizationFactor;
+            array[idx][1] = ecef.y()/normalizationFactor;
+            array[idx][2] = ecef.z()/normalizationFactor;
+         }
+         break;
+      }
+      case ossimPlanetLandType_FLAT:
+      {
+         ossimGpt gpt;
+         ossimEcefPoint ecef;
+         for(idx = 0; idx < array.size(); ++idx)
+         {
+            theProj->eastingNorthingToWorld(ossimDpt(array[idx][0],
+                                                     array[idx][1]),
+                                            gpt);
+            gpt.height(array[idx][2]);
+            array[idx][0] = gpt.lond();
+            array[idx][1] = gpt.latd();
+            array[idx][2] = gpt.height()/1000;
+         }
+         break;
+      }
+      default:
+      {
+         for(idx = 0; idx < array.size(); ++idx)
+         {
+            array[idx][0] -= theCenter[0];
+            array[idx][1] -= theCenter[1];
+            array[idx][2] -= theCenter[2];
+         }
+         break;
+      }
+   }
+}
+
+void geomVisitor::apply(osg::Geode& node)
+{
+   unsigned int drawableIdx = 0;
+
+   for(drawableIdx = 0; drawableIdx < node.getNumDrawables();++drawableIdx)
+   {
+      if(node.getDrawable(drawableIdx))
+      {
+         osg::Geometry* geomNode = node.getDrawable(drawableIdx)->asGeometry();
+
+         if(geomNode)
+         {
+            transformArrayVisitor visitor;
+            visitor.theProj      = theProj;
+            visitor.theCenter    = theCenter;
+            visitor.theLocation  = theLocation;
+            visitor.theMode      = theMode;
+            osg::Array* vertexArray = geomNode->getVertexArray();
+
+            vertexArray->accept(visitor);
+            geomNode->dirtyBound();
+         }
+      }
+   }
+
+   traverse(node);
+}
+
+void geomVisitor::apply(osg::Node& node)
+{
+   std::string name = node.getName();
+
+   if(name == "o1") // hack: remove the ground polygon so that only the city show up
+   {
+      osg::Group* group = node.asGroup();
+      if(group)
+      {
+         group->removeChild(0, group->getNumChildren());
+      }
+   }
+   osg::NodeVisitor::apply(node);
+}
+
+
+void transformPointsToLandType(osg::ref_ptr<osg::Node>& node,
+                               const ossimFilename& /* file */ ,
+                               ossimPlanetLandType landType,
+                               int utmZone, int utmX, int utmY)
+{
+   geomVisitor visitor;
+   ossimRefPtr<ossimUtmProjection> proj = new ossimUtmProjection;
+   visitor.theMode = landType;
+   proj->setZone(utmZone);
+   visitor.theProj = proj.get();
+   visitor.theLocation.x = utmX;
+   visitor.theLocation.y = utmY;
+   node->accept(visitor);
+   node->dirtyBound();
+
+   osg::Vec3d v = node->getBound().center();
+   visitor.theMode = ossimPlanetLandType_NONE;
+   visitor.theCenter = v;
+   node->accept(visitor);
+   node->dirtyBound();
+   osg::MatrixTransform* mTransform = new osg::MatrixTransform;
+   osg::Matrixd localToWorld;
+   localToWorld.makeTranslate(v);
+   mTransform->setMatrix(localToWorld);
+   mTransform->addChild(node.get());
+//    osgUtil::SmoothingVisitor smoother;
+//    mTransform->accept(smoother);
+
+   node = mTransform;
+}
+
+/**
+ * Create a city by loading an OSG-supported 3D model file and
+ * transforming it onto the ossimPlanet ellipsoid.
+ *
+ * \param file Filename of the 3D model.
+ * \param landType Landtype of the ossimPlanet terrain.
+ * \param utmZone UTM Zone (from 1 to 60, or -1 to -60 for the
+ *		southern hemisphere) in which to place the model.
+ * \param utmX X (easting) utm coordinate.
+ * \param utmY Y (northing) utm coordinate.
+ *
+ * \return The osg Node of the transformed model.  Note that you
+ *		will still need to add it to the scene graph with
+ *		ossimPlanet::addChild()
+ */
+osg::ref_ptr<osg::Node> createCityModel(const ossimFilename& file,
+                                        ossimPlanetLandType landType,
+                                        int utmZone, int utmX, int utmY)
+{
+   osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(file.c_str()));
+
+   transformPointsToLandType(loadedModel, file, landType, utmZone, utmX, utmY);
+
+   return loadedModel;
+}
+
+
+#if 0
+//--------------------------------------------------------------------------------------------------
+class osgTestGroup : public osg::Group
+{
+public:
+   osgTestGroup(){}
+
+   virtual void traverse(osg::NodeVisitor& nv)
+      {
+         switch(nv.getVisitorType())
+         {
+            case osg::NodeVisitor::CULL_VISITOR:
+            {
+               if((nv.getFrameStamp()->getFrameNumber()%5)==0)
+               {
+                  nv.getDatabaseRequestHandler()->requestNodeFile("TEST",
+                                                                  this,
+                                                                  99999999,
+                                                                  nv.getFrameStamp());
+               }
+               break;
+            }
+            default:
+            {
+               break;
+            }
+         }
+         osg::Group::traverse(nv);
+      }
+   virtual bool addChild(osg::Node* node)
+      {
+         osg::Geode* geode = dynamic_cast<osg::Geode*>(node);
+
+         if(geode)
+         {
+            if(getNumChildren() > 0)
+            {
+               removeChild(0, getNumChildren());
+            }
+         }
+         return osg::Group::addChild(node);
+      }
+};
+
+static int texCount = 0;
+class osgMyTexture : public osg::Texture2D
+{
+public:
+   osgMyTexture()
+      {
+         ++texCount;
+         std::cout << "Texture " << texCount << std::endl;
+      }
+   virtual ~osgMyTexture()
+      {
+         --texCount;
+         std::cout << "Texture " << texCount << std::endl;
+      }
+};
+class osgTestReaderWriter : public osgDB::ReaderWriter
+{
+public:
+   virtual ReadResult readNode(const std::string& fileName, const Options*)const
+   {
+      ReadResult result = 0;
+      if(fileName == "TEST")
+      {
+      std::cout << "Allocating geometry" << std::endl;
+      osg::ref_ptr<osg::Geode> geode = new osg::Geode;
+      osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
+
+      osg::ref_ptr<osg::Vec3Array> vArray = new osg::Vec3Array;
+      osg::ref_ptr<osg::Vec2Array> tArray = new osg::Vec2Array;
+      vArray->push_back(osg::Vec3d(-.5, .5,0.0));
+      vArray->push_back(osg::Vec3d(-.5, -.5, 0.0));
+      vArray->push_back(osg::Vec3d(.5, -.5, 0.0));
+      vArray->push_back(osg::Vec3d(.5, .5, 0.0));
+
+      tArray->push_back(osg::Vec2d(0.0,0.0));
+      tArray->push_back(osg::Vec2d(0,1.0));
+      tArray->push_back(osg::Vec2d(1.0,1.0));
+      tArray->push_back(osg::Vec2d(1.0,0.0));
+
+      osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
+//          osg::ref_ptr<osg::Texture2D> tex = new osgMyTexture;
+      osg::ref_ptr<osg::Image> img   = new osg::Image;
+      osg::ref_ptr<osg::StateSet> dstate = geom->getOrCreateStateSet();
+      unsigned char* newData = new unsigned char[256*256*4];
+      memset(newData, 255, 256*256*4);
+      img->setImage(256, 256, 1,
+                      GL_RGBA,
+                      GL_RGBA,
+                      GL_UNSIGNED_BYTE,
+                      newData,
+                      osg::Image::USE_NEW_DELETE);
+
+      tex->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+      tex->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+      tex->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+      tex->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+      tex->setDataVariance(osg::Object::DYNAMIC);
+      tex->setImage(img.get());
+      osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
+      color->push_back(osg::Vec4(1.0,
+                                  1.0,
+                                  1.0,
+                                  1.0));
+      geom->setColorBinding(osg::Geometry::BIND_OVERALL);
+      geom->setColorArray(color.get());
+
+      dstate->setTextureAttributeAndModes(0, tex.get(),
+                                          osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
+
+      geom->setVertexArray(vArray.get());
+      geom->setTexCoordArray( 0, tArray.get());
+
+      osg::DrawArrays* drawArray = new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 1);
+      geom->addPrimitiveSet(drawArray);
+
+      geode->addDrawable(geom.get());
+      result = geode.get();
+      }
+      return result;
+   }
+};
+//-------------------------------------------------------------------------------------------------------------
+#endif
+
+
diff --git a/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.h b/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.h
new file mode 100644
index 0000000..861f28c
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/opvLoadModel.h
@@ -0,0 +1,9 @@
+//
+// opvLoadModel.h
+//
+// osgPlanetView load model functionality
+//
+
+osg::ref_ptr<osg::Node> createCityModel(const ossimFilename& file,
+	ossimPlanetLandType landType, int utmZone, int utmX, int utmY);
+
diff --git a/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.cpp b/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.cpp
new file mode 100644
index 0000000..9a616ea
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.cpp
@@ -0,0 +1,743 @@
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/init/ossimInit.h>
+#include <ossim/elevation/ossimElevManager.h>
+#include <iostream>
+#include <sstream>
+#include <osg/ArgumentParser>
+#include <osg/Texture>
+#include <osg/PositionAttitudeTransform>
+#include <osgDB/ReadFile>
+#include <osg/Drawable>
+#include <osg/io_utils>
+#include <time.h>
+#include <osgViewer/ViewerEventHandlers>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetManipulator.h>
+#include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetTerrainGeometryTechnique.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <ossimPlanet/ossimPlanetViewMatrixBuilder.h>
+#include <ossimPlanet/ossimPlanetCloudLayer.h>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/StateSetManipulator>
+#include <osgGA/AnimationPathManipulator>
+#include <osgGA/TerrainManipulator>
+#include <ossimPlanet/ossimPlanetAnimationPath.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <osg/Geometry>
+#include <osg/MatrixTransform>
+#include <osg/LineWidth>
+#include <osgText/Text>
+#include <osgUtil/CullVisitor>
+#include <osg/ClipPlane>
+
+#include <osg/Program>
+#include <osg/Uniform>
+
+#include <osg/Geode>
+#include <osg/Geometry>
+void setUpViewForMultipipeTest(ossimPlanetViewer& viewer, ossim_uint32 numberOfPipes)
+{
+   //unsigned int width = 640, height = 480, aspectRatio = 1.33;
+   
+   osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
+   if (!wsi)
+   {
+      osg::notify(osg::NOTICE)<<"setUpViewForMultipipeTest() : Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
+      return;
+   }
+   
+   osg::DisplaySettings* ds = osg::DisplaySettings::instance();
+   osg::GraphicsContext::ScreenIdentifier si;
+   si.readDISPLAY();
+   unsigned int screenWidth, screenHeight;
+   wsi->getScreenResolution(si, screenWidth, screenHeight);
+   ossim_float64 screenAspectRatio = (double)screenWidth/(double)screenHeight;
+   ossim_float64 targetWidth = screenWidth/numberOfPipes;
+   ossim_float64 targetHeight = screenHeight*.5;
+   ossim_float64 aspectRatio  = targetWidth/targetHeight;//targetWidth/targetHeight;
+   // displayNum has not been set so reset it to 0.
+   if (si.displayNum<0) si.displayNum = 0;
+   
+   double translate_x = 0.0;
+   for(unsigned int i=0; i<numberOfPipes; ++i)
+   {
+      translate_x += double(targetWidth) / (double(targetHeight) * aspectRatio);
+   }
+   
+   for(unsigned int i=0; i<numberOfPipes; ++i)
+   {
+      osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
+      traits->hostName = si.hostName;
+      traits->displayNum = si.displayNum;
+      traits->screenNum = si.screenNum;
+      traits->x = i*targetWidth;
+      traits->y = 0;
+      traits->width = targetWidth;
+      traits->height = targetHeight;
+      traits->alpha = ds->getMinimumNumAlphaBits();
+      traits->stencil = ds->getMinimumNumStencilBits();
+      traits->windowDecoration = false;
+      traits->doubleBuffer = true;
+      traits->sharedContext = 0;
+      traits->sampleBuffers = ds->getMultiSamples();
+      traits->samples = ds->getNumMultiSamples();
+      
+      osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
+      
+      osg::ref_ptr<osg::Camera> camera = new osg::Camera;
+      camera->setGraphicsContext(gc.get());
+      
+      osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
+      if (gw)
+      {
+         osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<gw<<std::endl;
+         
+         gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(traits->x, traits->y, traits->width, traits->height );
+      }
+      else
+      {
+         osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
+      }
+      
+      camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
+      
+      GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
+      camera->setDrawBuffer(buffer);
+      camera->setReadBuffer(buffer);
+#if 0      
+      if(i==0)
+      {
+         // we will set a predraw callback here because the master camera is loosing the callback for some reason
+         //
+         camera->setPreDrawCallback(new ossimPlanetViewer::DrawCallback(&viewer));
+      }
+#endif
+      double newAspectRatio = double(traits->width) / double(traits->height);
+      double aspectRatioChange = newAspectRatio / aspectRatio;
+      //double aspectRatioChange = newAspectRatio / screenAspectRatio;
+      
+//      viewer.addSlave(camera.get(), 
+//                      (osg::Matrixd::translate( translate_x - aspectRatioChange, 0.0, 0.0) * 
+//                       osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0)),
+//                      osg::Matrixd(), true );
+      viewer.addSlave(camera.get(), 
+                      (osg::Matrixd::translate( translate_x - aspectRatioChange, 0.0, 0.0) * 
+                      osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0)),
+                      osg::Matrixd(), true );
+      translate_x -= aspectRatioChange * 2.0;
+   }
+   viewer.assignSceneDataToCameras();
+}
+osg::Node* loadFlightGearModel(ossimFilename& file,
+                               ossimPlanetGeoRefModel* model)
+{
+   osg::MatrixTransform* orientedModel = new osg::MatrixTransform;
+   osg::Node* flightgearModel = osgDB::readNodeFile(file.c_str(), 0); 
+   osg::Matrixd mr;
+   osg::Matrixd ms;
+   double scale = 50.0/model->getNormalizationScale();
+   ms.makeScale(osg::Vec3d(scale, scale, scale));
+   mr.makeRotate(osg::DegreesToRadians(-90.0), osg::Vec3d(0.0,0.0,1.0),
+                 osg::DegreesToRadians(-90.0), osg::Vec3d(0.0,1.0,0.0),
+                 osg::DegreesToRadians(0.0), osg::Vec3d(1.0,0.0,0.0));
+   orientedModel->setMatrix(ms*mr);
+   if(flightgearModel)
+   {
+      orientedModel->addChild(flightgearModel);
+   }
+  // orientedModel->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
+   return orientedModel;
+}
+
+void test(ossimPlanetGeoRefModel* model)
+{
+   osg::ref_ptr<ossimPlanetViewMatrixBuilder> builder = new ossimPlanetViewMatrixBuilder(model);
+   osg::Vec3d llh, hpr;
+   builder->setLookFrom(osg::Vec3d(45, -28, 3000),
+                        osg::Vec3d(45,45,0.0),
+                        0.0);
+   
+   osg::ref_ptr<ossimPlanetViewMatrixBuilder> builder2 = new ossimPlanetViewMatrixBuilder(builder->viewMatrix(),
+                                                                                          model);
+   
+   builder->extractCompositedLlhHprParameters(llh, hpr);
+   std::cout << "llh: " << llh << "\n" << "hpr: " << hpr << std::endl;
+   
+}
+
+void testHprInvert()
+{
+   osg::ref_ptr<ossimPlanetViewMatrixBuilder> builder = new ossimPlanetViewMatrixBuilder;
+   
+   builder->setGeoRefModel(new ossimPlanetNormalizedEllipsoidModel());
+   builder->setLookFrom(osg::Vec3d(56.7725, -3.84375, 6224.26),
+                        osg::Vec3d(-7.69345, -10.4819, 0.0),
+                        0.0);
+   builder->setLookTo(osg::Vec3d(57.0337, -3.90847, 860.493));
+   
+   osg::Matrix targetOrientation = builder->viewMatrix();
+   osg::Vec3d targetXaxis(targetOrientation(0,0), targetOrientation(0,1), targetOrientation(0,2));
+   osg::Vec3d targetYaxis(targetOrientation(1,0), targetOrientation(1,1), targetOrientation(1,2));
+   osg::Vec3d targetZaxis(targetOrientation(2,0), targetOrientation(2,1), targetOrientation(2,2));
+   builder->setParametersByMatrix(builder->viewMatrix());
+   //builder->convertToAFromViewMatrix();
+   //builder->convertToAFromViewMatrix(true);
+
+   osg::Matrix tempM=  builder->viewMatrix();
+   
+   osg::Vec3d xAxis(tempM(0,0), tempM(0,1), tempM(0,2));
+   osg::Vec3d yAxis(tempM(1,0), tempM(1,1), tempM(1,2));
+   osg::Vec3d zAxis(tempM(2,0), tempM(2,1), tempM(2,2));
+   
+   std::cout << "Result X = " << xAxis*targetXaxis << std::endl;
+   std::cout << "Result Y = " << yAxis*targetYaxis << std::endl;
+   std::cout << "Result Z = " << zAxis*targetZaxis << std::endl;
+   
+   
+   std::cout << builder->fromPositionLlh() << std::endl;
+   std::cout << builder->fromHpr() << std::endl;
+   std::cout << builder->fromRange() << std::endl;
+}
+int main(int argc, char* argv[])
+{
+   ossimInit::instance()->initialize(argc, argv);
+   
+//   testHprInvert();
+//   return 0;
+   osg::ref_ptr<ossimPlanetGrid> grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_CAP);  
+   
+   ossimString tempString;
+   osg::ArgumentParser::Parameter stringParam(tempString);
+   
+   osg::ArgumentParser arguments(&argc,argv);
+   arguments.getApplicationUsage()->addCommandLineOption("--terrain-requests-per-frame", 
+                                                         "Specify the number of requests to apply to the terrain graph per frame");
+   arguments.getApplicationUsage()->addCommandLineOption("--terrain-threads", 
+                                                         "Specify the number of terrain threads to use  Specify between 1 and 3 for now");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-image", "Image to add");
+	arguments.getApplicationUsage()->addCommandLineOption("--polar-cap", "Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--osg-view", "no ossimPlanet just use osg's readNode to add to scene");
+	arguments.getApplicationUsage()->addCommandLineOption("--split-merge-speed", "enumeration that maps to split merge ratio.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--elevation-density-type", "enumeration that maps amount of elevation posts to use per patch.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--texture-density-type", "enumeration that maps amount of texture samples to use per patch.  Values can be LOW, MEDIUM_LOW, MEDIUM, MEDIUM_HIGH, and HIGH");
+	arguments.getApplicationUsage()->addCommandLineOption("--elevation-exaggeration", "Scales the elevation by this factor");
+	arguments.getApplicationUsage()->addCommandLineOption("--cull-amount", "Sets the amount of culling in the graph.  Values can be low, medium, high");
+	arguments.getApplicationUsage()->addCommandLineOption("--min-time-compile", "sets the minimum time to compile per frame in seconds.  So 3 milliseconds is .003");
+	arguments.getApplicationUsage()->addCommandLineOption("--animation-path", "Reads in an animation path");
+	arguments.getApplicationUsage()->addCommandLineOption("--animation-node", "Reads in an animation node");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-kml", "Adds a kml layer to planet");
+	arguments.getApplicationUsage()->addCommandLineOption("--moon-image", "Moon image used for the moon sprite for the Ephemeris");
+	arguments.getApplicationUsage()->addCommandLineOption("--sun-image", "Moon image used for the moon sprite for the Ephemeris");
+	arguments.getApplicationUsage()->addCommandLineOption("--visibility", "Visibility in meters");
+	arguments.getApplicationUsage()->addCommandLineOption("--fog-near", "near plane for fog attenuation in meters");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-coverage", "integer value used to adjust the perlin noise");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-sharpness", "float value (0..1) used to adjust the perlin noise");
+	arguments.getApplicationUsage()->addCommandLineOption("--cloud-altitude", "Altitude of the cloud");
+	arguments.getApplicationUsage()->addCommandLineOption("--add-cloud", "float value (0..1) used to adjust the perlin noise");
+   arguments.getApplicationUsage()->addCommandLineOption("--fog-near", "near plane for fog attenuation in meters");
+   arguments.getApplicationUsage()->addCommandLineOption("--time-scale", "time scale for animation path locking");
+   arguments.getApplicationUsage()->addCommandLineOption("--time-offset", "time offset");
+   arguments.getApplicationUsage()->addCommandLineOption("--lockview-path", "lock the view to the path");
+   arguments.getApplicationUsage()->addCommandLineOption("--add-ephemeris", "Adds the ephemeris defaults");
+
+
+
+	ossim_uint32 helpType = 0;
+	
+	if ((helpType = arguments.readHelpType()))
+	{
+		arguments.getApplicationUsage()->write(std::cout, helpType);
+		return 1;
+	}
+	
+#if 1
+   
+   osg::MatrixTransform* rootScene = new osg::MatrixTransform();
+   
+  // osg::DisplaySettings::instance()->setRGB(true);
+  // osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(1);
+   ossimPlanetTerrainGeometryTechnique* technique = new ossimPlanetTerrainGeometryTechnique();
+   ossimPlanetViewer viewer(arguments);
+   ossimPlanetTerrain::CullAmountType cullAmount = ossimPlanetTerrain::HIGH_CULL;
+   ossimPlanetTerrain::SplitMergeSpeedType splitMergeSpeed = ossimPlanetTerrain::LOW_SPEED;
+   ossimPlanetTerrain::ElevationDensityType elevationDensity = ossimPlanetTerrain::LOW_ELEVATION_DENSITY;
+   ossimPlanetTerrain::TextureDensityType textureDensity = ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY;
+   std::vector<osg::ref_ptr<ossimPlanetAnimationPath> > animationPathArray;
+   std::vector<osg::ref_ptr<ossimPlanetPointModel> > pointModels;
+   std::vector<osg::ref_ptr<ossimPlanetAnimatedPointModel> > animatedPointModels;
+   osg::ref_ptr<ossimPlanetGeoRefModel> model;
+   osg::ref_ptr<ossimPlanetManipulator> manipulator = new ossimPlanetManipulator();
+   osg::ref_ptr<ossimPlanetAnnotationLayer> annotationLayer =new ossimPlanetAnnotationLayer();
+   osg::ref_ptr<ossimPlanetKmlLayer> kmlLayer;
+   std::vector<ossimFilename> kmlFiles;
+   ossimFilename flightgearFile = "";
+   osg::ref_ptr<ossimPlanet> planet;
+   double elevationExaggeration = 1.0;
+   double minTimeToCompilePerFrame = .003;
+   ossimFilename sunTextureFile = "";
+   ossimFilename moonTextureFile = "";
+   ossim_float64 visibility = 1000000000.0;
+   ossim_float64 fogNear = 0.0;
+   ossim_int32 cloudCoverage = 20;
+   ossim_float64 cloudSharpness = .95;
+   ossim_float64 cloudAltitude = 20000;
+   double timeScale = 1.0;
+   double timeOffset = 0.0;
+   bool addCloud = false;
+   bool lockViewToPathFlag = false;
+   bool addEphemerisFlag = false;
+   if(arguments.read("--lockview-path", stringParam))
+   {
+      lockViewToPathFlag =tempString.toBool();
+   }
+   if(arguments.read("--time-scale", stringParam))
+   {
+      timeScale = tempString.toDouble();
+   }
+   if(arguments.read("--time-offset", stringParam))
+   {
+      timeOffset = tempString.toDouble();
+   }
+   if(arguments.read("--cloud-coverage", stringParam))
+   {
+      cloudCoverage = tempString.toDouble();
+   }
+   if(arguments.read("--cloud-sharpness", stringParam))
+   {
+      cloudSharpness = tempString.toDouble();
+   }
+   if(arguments.read("--cloud-altitude", stringParam))
+   {
+      cloudAltitude = tempString.toDouble();
+   }
+   if(arguments.read("--add-ephemeris"))
+   {
+      addEphemerisFlag = true;
+   }
+   if(arguments.read("--add-cloud"))
+   {
+      addCloud = true;
+   }
+   if(arguments.read("--visibility", stringParam))
+   {
+      visibility = tempString.toDouble();
+   }
+   if(arguments.read("--fog-near", stringParam))
+   {
+      fogNear = tempString.toDouble();
+   }
+   while(arguments.read("--add-kml", stringParam))
+   {
+      kmlFiles.push_back(ossimFilename(tempString));
+   }
+   if(arguments.read("--animation-node", stringParam))
+   {
+      flightgearFile = ossimFilename(tempString);
+   }
+   while(arguments.read("--animation-path", stringParam))
+   {
+      osg::ref_ptr<ossimPlanetAnimationPath> animationPath = new ossimPlanetAnimationPath;
+      
+      if(animationPath->openAnimationPathByXmlDocument(ossimFilename(tempString)))
+      {
+         animationPathArray.push_back(animationPath.get());
+      }
+   }
+   if(arguments.read("--moon-image", stringParam))
+   {
+      moonTextureFile = ossimFilename(tempString);
+   }
+   if(arguments.read("--sun-image", stringParam))
+   {
+      sunTextureFile = ossimFilename(tempString);
+   }
+   if(arguments.read("--min-time-compile", stringParam))
+   {
+      minTimeToCompilePerFrame = tempString.toDouble();
+   }
+   if(arguments.read("--elevation-exaggeration", stringParam))
+   {
+      elevationExaggeration = tempString.toDouble();
+   }
+   if(arguments.read("--texture-density-type", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         textureDensity = ossimPlanetTerrain::LOW_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium_low")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_LOW_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_TEXTURE_DENSITY;
+      }
+      else if(tempString == "medium_high")
+      {
+         textureDensity = ossimPlanetTerrain::MEDIUM_HIGH_TEXTURE_DENSITY;
+      }
+      else if(tempString == "high")
+      {
+         textureDensity = ossimPlanetTerrain::HIGH_TEXTURE_DENSITY;
+      }
+   }
+   if(arguments.read("--elevation-density-type", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         elevationDensity = ossimPlanetTerrain::LOW_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium_low")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_LOW_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_ELEVATION_DENSITY;
+      }
+      else if(tempString == "medium_high")
+      {
+         elevationDensity = ossimPlanetTerrain::MEDIUM_HIGH_ELEVATION_DENSITY;
+      }
+      else if(tempString == "high")
+      {
+         elevationDensity = ossimPlanetTerrain::HIGH_ELEVATION_DENSITY;
+      }
+   }
+   if(arguments.read("--split-merge-speed", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::LOW_SPEED;
+      }
+      
+      else if(tempString == "medium_low")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_LOW_SPEED;
+      }
+      else if(tempString == "medium")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_SPEED;
+      }
+      else if(tempString == "medium_high")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::MEDIUM_HIGH_SPEED;
+      }
+      else if(tempString == "high")
+      {
+         splitMergeSpeed = ossimPlanetTerrain::HIGH_SPEED;
+      }
+   }
+   if(arguments.read("--polar-cap", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "low")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::LOW_CAP);
+      }
+      else if(tempString == "medium_low")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_LOW_CAP);
+      }
+      else if(tempString == "medium")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_CAP);
+      }
+      else if(tempString == "medium_high")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::MEDIUM_HIGH_CAP);
+      }
+      else if(tempString == "high")
+      {
+         grid = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::HIGH_CAP);
+      }
+   }
+   if(arguments.read("--cull-amount", stringParam))
+   {
+      tempString = tempString.downcase();
+      if(tempString == "none")
+      {
+         cullAmount = ossimPlanetTerrain::NO_CULL;
+      }
+      if(tempString == "low")
+      {
+         cullAmount = ossimPlanetTerrain::LOW_CULL;
+      }
+      else if(tempString == "medium_low")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_LOW_CULL;
+      }
+      else if(tempString == "medium")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_CULL;
+      }
+      else if(tempString == "medium_high")
+      {
+         cullAmount = ossimPlanetTerrain::MEDIUM_HIGH_CULL;
+      }
+      else if(tempString == "high")
+      {
+         cullAmount = ossimPlanetTerrain::HIGH_CULL;
+      }
+   }
+   
+   viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
+   
+   // add the thread model handler
+   viewer.addEventHandler(new osgViewer::ThreadingHandler);
+   
+   // add the window size toggle handler
+   viewer.addEventHandler(new osgViewer::WindowSizeHandler);
+   
+   // add the stats handler
+   viewer.addEventHandler(new osgViewer::StatsHandler);
+   
+   // add the help handler
+   viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
+   
+   // add the record camera path handler
+   viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
+   
+   // add the LOD Scale handler
+   // viewer.addEventHandler(new osgViewer::LODScaleHandler);
+   
+   // add the screen capture handler
+   //   viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
+   osg::ref_ptr<osg::Node> lockNode;
+   if(arguments.read("--osg-view", stringParam))
+   {
+      osg::ref_ptr<osg::Node> n = osgDB::readNodeFile(tempString);
+      if(n.valid())
+      {
+         osg::Group* group = new osg::Group();
+         group->addChild(n.get());
+         viewer.setSceneData(group);
+      }
+      osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
+      keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
+      viewer.setCameraManipulator(keyswitchManipulator.get());
+      viewer.realize();
+      
+      while(!viewer.done())
+      {
+         viewer.frame();//time);
+      }
+      
+      return 0;
+   }
+   else
+   {
+      planet = new ossimPlanet();
+//      osg::ref_ptr<ossimPlanetLatLonHud> latLonHud = new ossimPlanetLatLonHud;
+      model = planet->model().get();
+      osg::ref_ptr<ossimPlanetTerrain> terrain = new ossimPlanetTerrain(grid.get());
+      terrain->setTerrainTechnique(technique);
+      terrain->setCullAmountType(cullAmount);
+      terrain->setSplitMergeSpeedType(splitMergeSpeed);
+      terrain->setTextureDensityType(textureDensity);
+      terrain->setElevationDensityType(elevationDensity);
+      terrain->setElevationExaggeration(elevationExaggeration);
+      terrain->setMinimumTimeToCompilePerFrameInSeconds(minTimeToCompilePerFrame);
+      //terrain->setTextureLayer(0, group);
+      terrain->initElevation();
+      planet->addChild(terrain.get());
+      planet->addChild(annotationLayer.get());
+//      planet->addChild(latLonHud.get());
+      
+      //     ossimPlanetEphemeris* ephemeris = new ossimPlanetEphemeris(ossimPlanetEphemeris::SUN_LIGHT);//|
+      //ossimPlanetEphemeris::MOON_LIGHT);
+      //planet->addChild(ephemeris);
+      if(kmlFiles.size() > 0)
+      {
+         kmlLayer = new ossimPlanetKmlLayer();
+         planet->addChild(kmlLayer.get());
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < kmlFiles.size(); ++idx)
+         {
+            kmlLayer->addKml(kmlFiles[idx]);
+         }
+      }
+      if(!flightgearFile.empty())
+      {
+         osg::ref_ptr<osg::Node> flightgearNode = loadFlightGearModel(flightgearFile,
+                                                                      planet->model().get());
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < animationPathArray.size(); ++idx)
+         {
+            osg::ref_ptr<ossimPlanetAnimatedPointModel> animatedNode = new ossimPlanetAnimatedPointModel();
+            osg::ref_ptr<ossimPlanetPointModel> pointModel = new ossimPlanetPointModel;
+            pointModel->setCullingActive(false);
+            pointModel->setNode(flightgearNode.get());
+            animationPathArray[idx]->setLoopMode(osg::AnimationPath::LOOP);
+            animatedNode->setPointModel(pointModel.get());
+            animatedNode->setAnimationPath(animationPathArray[idx].get());
+            animatedNode->setTimeScale(timeScale);
+            animatedNode->setTimeOffset(timeOffset);
+            animatedNode->setShowModelFlag(true);
+            annotationLayer->addChild(animatedNode.get());
+            pointModels.push_back(pointModel.get());
+            animatedPointModels.push_back(animatedNode.get());
+            if(lockViewToPathFlag)
+            {
+               lockNode = pointModel.get(); 
+            }   
+         }
+      }
+      else if(!animationPathArray.empty()){
+            osg::ref_ptr<ossimPlanetAnimatedPointModel> animatedNode = new ossimPlanetAnimatedPointModel();
+            osg::ref_ptr<ossimPlanetPointModel> pointModel = new ossimPlanetPointModel;
+            pointModel->setCullingActive(false);
+            animationPathArray[0]->setLoopMode(osg::AnimationPath::LOOP);
+            animatedNode->setPointModel(pointModel.get());
+            animatedNode->setAnimationPath(animationPathArray[0].get());
+            animatedNode->setTimeScale(timeScale);
+            animatedNode->setTimeOffset(timeOffset);
+            animatedNode->setShowModelFlag(false);
+            annotationLayer->addChild(animatedNode.get());
+            pointModels.push_back(pointModel.get());
+            animatedPointModels.push_back(animatedNode.get());
+            if(lockViewToPathFlag)
+            {
+               lockNode = pointModel.get(); 
+            }   
+      } 
+      rootScene->addChild(planet.get());
+      viewer.setSceneData( rootScene );
+      
+      osg::ref_ptr<osg::StateSet> sset = planet->getOrCreateStateSet();
+      if(arguments.read("--terrain-requests-per-frame", stringParam))
+      {
+         ossim_int32 requestsPerFrame = ossimString(tempString).toInt32();
+         if(requestsPerFrame <= 0)
+         {
+            requestsPerFrame = 1;
+         }
+         viewer.setTerrainMaxNumberOfOperationsToApplyToGraphPerFrame(requestsPerFrame);
+      }
+      while(arguments.read("--add-image", stringParam))
+      {
+         osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(tempString);
+         if(layer.valid())
+         {
+            viewer.addImageTexture(layer.get());
+            
+         }
+      }	
+      osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
+      keyswitchManipulator->addMatrixManipulator( '1', "Standard", manipulator.get() );
+      keyswitchManipulator->addMatrixManipulator( '2', "Trackball", new osgGA::TrackballManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '3', "Flight", new osgGA::FlightManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '4', "Drive", new osgGA::DriveManipulator() );
+      keyswitchManipulator->addMatrixManipulator( '5', "Terrain", new osgGA::TerrainManipulator() );
+      viewer.setCameraManipulator(keyswitchManipulator.get());
+   }
+  // test(planet->model().get());
+  // return 0;
+   viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
+   
+if(addEphemerisFlag)
+{
+
+   viewer.addEphemeris(ossimPlanetEphemeris::SUN_LIGHT
+                       //|ossimPlanetEphemeris::MOON_LIGHT
+                       //|ossimPlanetEphemeris::AMBIENT_LIGHT
+                      // |ossimPlanetEphemeris::SUN
+                       |ossimPlanetEphemeris::MOON
+                       |ossimPlanetEphemeris::SKY
+                       |ossimPlanetEphemeris::FOG
+                       );
+   ossimLocalTm date;
+   date.now();
+   viewer.ephemeris()->setDate(date);
+   //viewer.ephemeris()->setApplySimulationTimeOffsetFlag(true);
+   viewer.ephemeris()->setApplySimulationTimeOffsetFlag(true);
+   viewer.ephemeris()->setSunTextureFromFile(sunTextureFile);
+   viewer.ephemeris()->setMoonTextureFromFile(moonTextureFile);
+   viewer.ephemeris()->setMoonScale(osg::Vec3d(1.0, 1.0, 1.0));
+//   viewer.ephemeris()->setGlobalAmbientLight(osg::Vec3d(0.1, 0.1, 0.1));
+   viewer.ephemeris()->setVisibility(visibility);
+   viewer.ephemeris()->setFogNear(fogNear);
+   viewer.ephemeris()->setFogMode(ossimPlanetEphemeris::LINEAR);
+   //viewer.ephemeris()->setSunLightCallback(new ossimPlanetEphemeris::LightingCallback());
+   double fov_y, aspect_ratio, z_near, z_far;
+   viewer.getCamera()->getProjectionMatrixAsPerspective(fov_y, aspect_ratio, z_near, z_far);
+   viewer.getCamera()->setProjectionMatrixAsPerspective(45, aspect_ratio, 1.0, 20.0);
+   //osg::ref_ptr<ossimPlanetCloudLayer> cloud;
+   if(addCloud)
+   {
+//      viewer.ephemeris()->setNumberOfCloudLayers(1);
+#if 0
+      viewer.ephemeris()->createCloudPatch(0,
+                                           osg::Vec3d(28, -90, cloudAltitude),
+                                           64,
+                                           45,
+                                           (ossim_uint64)time(0),
+                                           cloudCoverage,
+                                           cloudSharpness);
+      //   viewer.ephemeris()->cloudLayer(0)->setMaxAltitudeToShowClouds(cloudAltitude*2.0);
+#else
+      //      viewer.ephemeris()->cloudLayer(0)->setGrid(new ossimPlanetCloudLayer::Patch(45.0, 45.0));
+      viewer.ephemeris()->setNumberOfCloudLayers(1);
+      viewer.ephemeris()->cloudLayer(0)->computeMesh(cloudAltitude, 128, 128, 0);
+      viewer.ephemeris()->cloudLayer(0)->updateTexture(time(0), cloudCoverage, cloudSharpness);
+      viewer.ephemeris()->cloudLayer(0)->setSpeedPerHour(1000, OSSIM_MILES);
+      viewer.ephemeris()->cloudLayer(0)->setScale(3);
+      viewer.ephemeris()->cloudLayer(0)->setMaxAltitudeToShowClouds(cloudAltitude*2.0);
+#endif
+   }
+   viewer.terrainLayer()->setElevationMemoryCache(new ossimPlanetMemoryImageCache);
+   viewer.terrainLayer()->elevationCache()->setMinMaxCacheSizeInMegaBytes(16, 20);
+}
+   if(arguments.read("--multi-pipe-test", stringParam))
+   {
+      setUpViewForMultipipeTest(viewer, tempString.toUInt32());
+   }
+   viewer.realize();
+   
+   //   viewer.setLightingMode(osg::View::HEADLIGHT);
+   //   if(viewer.getLight())
+   //   {
+   //      osg::Vec4f amb(.3,.3,.3,1.0);
+   //    viewer.getLight()->setAmbient(amb);
+   //   }
+   
+   //   osg::ref_ptr<ossimPlanetViewMatrixBuilder> viewMatrixBuilder;
+   //   if(planet.valid())
+   //   {
+   //      viewMatrixBuilder = new ossimPlanetViewMatrixBuilder(planet->model().get());
+   //   }
+   
+   //animatedNode->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+   //viewer.setCameraManipulator(0);
+   double time = 0.0;
+   manipulator->setEventHandlingFlag(true);
+   manipulator->viewMatrixBuilder()->setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_Y);
+   if(lockNode.get())
+   {
+      manipulator->viewMatrixBuilder()->updateFromNode(lockNode.get());
+   }
+   while(!viewer.done())
+   {
+      viewer.frame();//time);
+      time += 1.0/60.0;//60;//.016;
+    }
+   //return viewer.run();
+#endif
+}
diff --git a/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.vcproj b/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.vcproj
new file mode 100644
index 0000000..93b5627
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/ossimplanetviewer.vcproj
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="ossimplanetviewer"
+	ProjectGUID="{982CDBCD-0217-4E0D-8870-338D101EB982}"
+	RootNamespace="ossimplanetviewer"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\ossim_dependencies\src\3rdParty\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\zziplib-0.13.49";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph\include""
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CONSOLE;OSGPLANET_WITHOUT_WMS;FREETYPE_SETTING=1;GEOTIFF_ENABLED;HAVE_CONFIG_H"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)bin\ossimplanetviewer.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="C:\Svs_dev_C\ossim\lib;C:\Svs_dev_C\3rdParty\lib;C:\Svs_dev_C\OpenThreads\lib\win32;C:\Svs_dev_C\Producer\lib;C:\Svs_dev_C\OpenSceneGraph\lib;C:\Svs_dev_C\gdal"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/ossimplanetviewer.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\include""
+				PreprocessorDefinitions="NDEBUG;_WINDOWS;WIN32;_CONSOLE;NOMINMAX"
+				RuntimeLibrary="2"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="OpenThreads.lib osg.lib osgDB.lib osgViewer.lib osgGA.lib osgText.lib osgUtil.lib"
+				OutputFile="$(OutDir)\bin\$(ProjectName).exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\ossim\projects\vs2005\bin\Release";"$(ProjectDir)..\..\..\ossim_dependencies\lib";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph-2.8.1\build\lib""
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)\lib\$(ProjectName).lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\opvLoadModel.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ossimplanetviewer.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\opvLoadModel.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/ossimPlanet/examples/ossimplanetviewer/readme.txt b/ossimPlanet/examples/ossimplanetviewer/readme.txt
new file mode 100644
index 0000000..200039a
--- /dev/null
+++ b/ossimPlanet/examples/ossimplanetviewer/readme.txt
@@ -0,0 +1,9 @@
+The osgplanetviewer now only accepts a keywordlist.  See archive_manager.kwl for the sample format.  You will have to modify the cache_dir.  See the comments in archive_manager.kwl
+
+example:
+
+osgplanetviewer archive_manager.kwl
+
+
+
+
diff --git a/ossimPlanet/include/ossimPlanet/compiler.h b/ossimPlanet/include/ossimPlanet/compiler.h
new file mode 100644
index 0000000..5d5534d
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/compiler.h
@@ -0,0 +1,470 @@
+/**************************************************************************
+ * compiler.h -- C++ Compiler Portability Macros
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * $Id: compiler.h 10524 2007-02-26 18:27:24Z gpotts $
+ *
+ **************************************************************************/
+
+/** \file compiler.h
+ * A set of defines to encapsulate compiler and platform differences.
+ * Please refer to the source code for full documentation on this file.
+ *
+ * Here is a summary of what this file does.
+ *
+ *  (1)  Defines macros for some STL includes which may be affected
+ *       by file name length limitations.
+ *
+ *  (2)  Defines macros for some features not supported by all C++ compilers.
+ *
+ *  (3)  Defines 'explicit' as a null macro if the compiler doesn't support
+ *       the explicit keyword.
+ *
+ *  (4)  Defines 'typename' as a null macro if the compiler doesn't support
+ *       the typename keyword.
+ *
+ *  (5)  Defines bool, true and false if the compiler doesn't do so.
+ *
+ *  (6)  Defines SG_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
+ *       supports calling a function template by providing its template
+ *       arguments explicitly.
+ *
+ *  (7)  Defines SG_NEED_AUTO_PTR if STL doesn't provide auto_ptr<>.
+ *
+ *  (8)  Defines SG_NO_ARROW_OPERATOR if the compiler is unable
+ *       to support operator->() for iterators.
+ *
+ *  (9)  Defines SG_USE_EXCEPTIONS if the compiler supports exceptions.
+ *       Note: no FlightGear code uses exceptions.
+ *
+ *  (10) Define SG_NAMESPACES if the compiler supports namespaces.
+ *
+ *  (11) SG_MATH_FN_IN_NAMESPACE_STD -- not used??
+ *
+ *  (12) Define SG_HAVE_STD if std namespace is supported.
+ *
+ *  (13) Defines SG_CLASS_PARTIAL_SPECIALIZATION if the compiler 
+ *       supports partial specialization of class templates.
+ *
+ *  (14) Defines SG_HAVE_STD_INCLUDES to use ISO C++ Standard headers.
+ *
+ *  (15) Defines SG_HAVE_STREAMBUF if <streambuf> of <streambuf.h> are present.
+ *
+ *  (16) Define SG_MATH_EXCEPTION_CLASH if math.h defines an exception class
+ *       that clashes with the one defined in <stdexcept>.
+ */
+
+#ifndef _SG_COMPILER_H
+#define _SG_COMPILER_H
+
+/*
+ * Helper macro SG_STRINGIZE:
+ * Converts the parameter X to a string after macro replacement
+ * on X has been performed.
+ */
+#define SG_STRINGIZE(X) SG_DO_STRINGIZE(X)
+#define SG_DO_STRINGIZE(X) #X
+
+#ifdef __GNUC__
+#  if __GNUC__ == 2 
+#    if __GNUC_MINOR__ < 8
+
+       // g++-2.7.x
+#      define STL_ALGORITHM  <algorithm>
+#      define STL_FUNCTIONAL <functional>
+#      define STL_IOMANIP    <iomanip.h>
+#      define STL_IOSTREAM   <iostream.h>
+#      define STL_ITERATOR   <iterator.h>
+#      define STL_FSTREAM    <fstream.h>
+#      define STL_STDEXCEPT  <stdexcept>
+#      define STL_STRING     <string>
+#      define STL_STRSTREAM  <strstream.h>
+
+#      define SG_NEED_AUTO_PTR
+#      define SG_NO_DEFAULT_TEMPLATE_ARGS
+#      define SG_INCOMPLETE_FUNCTIONAL
+#      define SG_NO_ARROW_OPERATOR
+
+#    elif __GNUC_MINOR__ >= 8
+
+       // g++-2.8.x and egcs-1.x
+#      define SG_EXPLICIT_FUNCTION_TMPL_ARGS
+#      define SG_NEED_AUTO_PTR
+#      define SG_MEMBER_TEMPLATES
+#      define SG_NAMESPACES
+#      define SG_HAVE_STD
+#      define SG_HAVE_STREAMBUF
+#      define SG_CLASS_PARTIAL_SPECIALIZATION
+
+#      define STL_ALGORITHM  <algorithm>
+#      define STL_FUNCTIONAL <functional>
+#      define STL_IOMANIP    <iomanip>
+#      define STL_IOSTREAM   <iostream>
+#      define STL_ITERATOR   <iterator>
+#      define STL_FSTREAM    <fstream>
+#      define STL_STDEXCEPT  <stdexcept>
+#      define STL_STRING     <string>
+#      define STL_STRSTREAM  <strstream>
+
+#    endif
+#  elif __GNUC__ >= 3
+       // g++-3.0.x
+#      define SG_EXPLICIT_FUNCTION_TMPL_ARGS
+#      define SG_NEED_AUTO_PTR
+#      define SG_MEMBER_TEMPLATES
+#      define SG_NAMESPACES
+#      define SG_HAVE_STD
+#      define SG_HAVE_STREAMBUF
+#      define SG_CLASS_PARTIAL_SPECIALIZATION
+#      define SG_HAVE_STD_INCLUDES
+
+#      define STL_ALGORITHM  <algorithm>
+#      define STL_FUNCTIONAL <functional>
+#      define STL_IOMANIP    <iomanip>
+#      define STL_IOSTREAM   <iostream>
+#      define STL_ITERATOR   <iterator>
+#      define STL_FSTREAM    <fstream>
+#      define STL_STDEXCEPT  <stdexcept>
+#      define STL_STRING     <string>
+#      define STL_STRSTREAM  <strstream>
+#  else
+#    error Time to upgrade. GNU compilers < 2.7 not supported
+#  endif
+
+#  define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
+
+#endif // __GNUC__
+
+/* KAI C++ */
+#if defined(__KCC)
+
+#  define SG_NAMESPACES
+#  define SG_HAVE_STD
+#  define SG_HAVE_STREAMBUF
+#  define SG_HAVE_TRAITS
+#  define SG_HAVE_STD_INCLUDES
+
+#  define STL_ALGORITHM  <algorithm>
+#  define STL_FUNCTIONAL <functional>
+#  define STL_IOMANIP    <iomanip>
+#  define STL_IOSTREAM   <iostream>
+#  define STL_ITERATOR   <iterator>
+#  define STL_FSTREAM    <fstream>
+#  define STL_STDEXCEPT  <stdexcept>
+#  define STL_STRING     <string>
+#  define STL_STRSTREAM  <strstream>
+
+#  define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
+
+#endif // __KCC
+
+//
+// Metrowerks 
+//
+#if defined(__MWERKS__)
+/*
+  CodeWarrior compiler from Metrowerks, Inc.
+*/
+#  define SG_HAVE_TRAITS
+#  define SG_HAVE_STD_INCLUDES
+#  define SG_HAVE_STD
+#  define SG_NAMESPACES
+
+#  define STL_ALGORITHM  <algorithm>
+#  define STL_FUNCTIONAL <functional>
+#  define STL_IOMANIP    <iomanip>
+#  define STL_IOSTREAM   <iostream>
+#  define STL_ITERATOR   <iterator>
+#  define STL_FSTREAM    <fstream>
+#  define STL_STDEXCEPT  <stdexcept>
+#  define STL_STRING     <string>
+
+// Temp:
+#  define bcopy(from, to, n) memcpy(to, from, n)
+
+// -rp- please use FG_MEM_COPY everywhere !
+// #define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
+
+// -dw- currently used glut has no game mode stuff
+#  define GLUT_WRONG_VERSION
+
+#  define SG_COMPILER_STR "Metrowerks CodeWarrior C++ version " SG_STRINGIZE(__MWERKS__)
+
+#endif // __MWERKS__
+
+//
+// Microsoft compilers.
+//
+#ifdef _MSC_VER
+#  define bcopy(from, to, n) memcpy(to, from, n)
+#  define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
+
+#  if _MSC_VER >= 1200  // msvc++ 6.0 or greater
+#    define SG_NAMESPACES
+#    define SG_HAVE_STD
+#    define SG_HAVE_STD_INCLUDES
+#    define SG_HAVE_STREAMBUF
+
+#    define STL_ALGORITHM  <algorithm>
+#    define STL_FUNCTIONAL <functional>
+#    define STL_IOMANIP    <iomanip>
+#    define STL_IOSTREAM   <iostream>
+#    define STL_ITERATOR   <iterator>
+#    define STL_FSTREAM    <fstream>
+#    define STL_STDEXCEPT  <stdexcept>
+#    define STL_STRING     <string>
+#    define STL_STRSTREAM  <strstream>
+
+#    define isnan _isnan
+#    define snprintf _snprintf
+
+#    pragma warning(disable: 4786) // identifier was truncated to '255' characters
+#    pragma warning(disable: 4244) // conversion from double to float
+#    pragma warning(disable: 4305) //
+
+#  else
+#    error What version of MSVC++ is this?
+#  endif
+
+#    define SG_COMPILER_STR "Microsoft Visual C++ version " SG_STRINGIZE(_MSC_VER)
+
+#endif // _MSC_VER
+
+#ifdef __BORLANDC__
+# if defined(HAVE_SGI_STL_PORT)
+
+// Use quotes around long file names to get around Borland's include hackery
+
+#  define STL_ALGORITHM  "algorithm"
+#  define STL_FUNCTIONAL "functional"
+
+#  define SG_MATH_EXCEPTION_CLASH
+
+# else
+
+#  define STL_ALGORITHM  <algorithm>
+#  define STL_FUNCTIONAL <functional>
+#  define STL_IOMANIP    <iomanip>
+#  define STL_STDEXCEPT  <stdexcept>
+#  define STL_STRSTREAM  <strstream>
+
+#  define SG_INCOMPLETE_FUNCTIONAL
+
+# endif // HAVE_SGI_STL_PORT
+
+#  define STL_IOSTREAM   <iostream>
+#  define STL_ITERATOR   <iterator>
+#  define STL_FSTREAM    <fstream>
+#  define STL_STRING     <string>
+#  define SG_NO_DEFAULT_TEMPLATE_ARGS
+#  define SG_NAMESPACES
+// #  define SG_HAVE_STD
+
+#  define SG_COMPILER_STR "Borland C++ version " SG_STRINGIZE(__BORLANDC__)
+
+#endif // __BORLANDC__
+
+//
+// Native SGI compilers
+//
+
+#if defined ( sgi ) && !defined( __GNUC__ )
+#  define SG_HAVE_NATIVE_SGI_COMPILERS
+
+#  define SG_EXPLICIT_FUNCTION_TMPL_ARGS
+#  define SG_CLASS_PARTIAL_SPECIALIZATION
+#  define SG_NEED_AUTO_PTR
+#  define SG_MEMBER_TEMPLATES
+#  define SG_NAMESPACES
+#  define SG_HAVE_STD
+#  define SG_HAVE_STREAMBUF
+#  define SG_HAVE_TRAITS
+#  define SG_HAVE_STD_INCLUDES
+
+#  define STL_ALGORITHM  <algorithm>
+#  define STL_FUNCTIONAL <functional>
+#  define STL_IOMANIP    <iomanip>
+#  define STL_IOSTREAM   <iostream>
+#  define STL_ITERATOR   <iterator>
+#  define STL_FSTREAM    <fstream>
+#  define STL_STDEXCEPT  <stdexcept>
+#if (_COMPILER_VERSION < 740)
+#  define STL_STRING     <irix_string>
+#else
+#  define STL_STRING     <string>
+#endif
+#  define STL_STRSTREAM  <strstream>
+
+#pragma set woff 1001,1012,1014,1116,1155,1172,1174
+#pragma set woff 1401,1460,1551,1552,1681
+
+#ifdef __cplusplus
+#pragma set woff 1682,3303
+#if (_COMPILER_VERSION >= 740)
+#  pragma set woff 3624
+#endif
+#endif
+
+#  define SG_COMPILER_STR "SGI MipsPro compiler version " SG_STRINGIZE(_COMPILER_VERSION)
+
+#endif // Native SGI compilers
+
+
+#if defined (__sun)
+#  include <strings.h>
+#  include <memory.h>
+#  if defined ( __cplusplus )
+     // typedef unsigned int size_t;
+     extern "C" {
+       extern void *memmove(void *, const void *, size_t);
+     }
+#  else
+     extern void *memmove(void *, const void *, size_t);
+#  endif // __cplusplus
+
+#  if  !defined( __GNUC__ )
+#   define SG_COMPILER_STR "Sun compiler version " SG_STRINGIZE(__SUNPRO_CC)
+#  endif
+
+#endif // sun
+
+//
+// Intel C++ Compiler
+//
+#if defined(__ICC) || defined (__ECC)
+#  define SG_NAMESPACES
+#  define SG_HAVE_STD
+#  define SG_HAVE_STREAMBUF
+#  define SG_HAVE_TRAITS
+#  define SG_HAVE_STD_INCLUDES
+
+#  define STL_ALGORITHM  <algorithm>
+#  define STL_FUNCTIONAL <functional>
+#  define STL_IOMANIP    <iomanip>
+#  define STL_IOSTREAM   <iostream>
+#  define STL_ITERATOR   <iterator>
+#  define STL_FSTREAM    <fstream>
+#  define STL_STDEXCEPT  <stdexcept>
+#  define STL_STRING     <string>
+#  define STL_STRSTREAM  <strstream>
+
+#  define SG_COMPILER_STR "Intel C++ version " SG_STRINGIZE(__ICC)
+
+#endif // __ICC
+
+//
+// Platform dependent gl.h and glut.h definitions
+//
+
+#ifdef __APPLE__
+#  define SG_GL_H <OpenGL/gl.h>
+#  define SG_GLX_H <AGL/agl.h>
+#  define SG_GLU_H <OpenGL/glu.h>
+#  define SG_GLEXT_H <OpenGL/glext.h>
+#  define SG_GLUT_H <GLUT/glut.h>
+
+inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
+#else
+#  define SG_GL_H <GL/gl.h>
+#  define SG_GLX_H <GL/glx.h>
+#  define SG_GLU_H <GL/glu.h>
+#  define SG_GLEXT_H <GL/glext.h>
+#  define SG_GLUT_H <GL/glut.h>
+#endif
+
+
+//
+// No user modifiable definitions beyond here.
+//
+
+#ifdef SG_NEED_EXPLICIT
+#  define explicit
+#endif
+
+#ifdef SG_NEED_TYPENAME
+#  define typename
+#endif
+
+#ifdef SG_NEED_MUTABLE
+#  define mutable
+#endif
+
+#ifdef SG_NEED_BOOL
+   typedef int bool;
+#  define true 1
+#  define false 0
+#endif
+
+#ifdef SG_EXPLICIT_FUNCTION_TMPL_ARGS
+#  define SG_NULL_TMPL_ARGS <>
+#else
+#  define SG_NULL_TMPL_ARGS
+#endif
+
+#ifdef SG_CLASS_PARTIAL_SPECIALIZATION
+# define SG_TEMPLATE_NULL template<>
+#else
+# define SG_TEMPLATE_NULL
+#endif
+
+// SG_NO_NAMESPACES is a hook so that users can disable namespaces
+// without having to edit library headers.
+#if defined(SG_NAMESPACES) && !defined(SG_NO_NAMESPACES)
+#   define SG_NAMESPACE(X) namespace X {
+#   define SG_NAMESPACE_END }
+#   define SG_USING_NAMESPACE(X) using namespace X
+# else
+#   define SG_NAMESPACE(X)
+#   define SG_NAMESPACE_END
+#   define SG_USING_NAMESPACE(X)
+#endif
+
+/** \def SG_USING_STD(x)
+ *  Expands to using std::x if SG_HAVE_STD is defined 
+ */
+# ifdef SG_HAVE_STD
+#  define SG_USING_STD(X) using std::X
+#  define STD std
+# else
+#  define SG_USING_STD(X) 
+#  define STD
+# endif
+
+// Additional <functional> implementation from SGI STL 3.11
+// Adapter function objects: pointers to member functions
+#ifdef SG_INCOMPLETE_FUNCTIONAL
+
+template <class _Ret, class _Tp>
+class const_mem_fun_ref_t
+#ifndef __BORLANDC__
+    : public unary_function<_Tp,_Ret>
+#endif // __BORLANDC__
+{
+public:
+  explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
+  _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); }
+private:
+  _Ret (_Tp::*_M_f)() const;
+};
+
+template <class _Ret, class _Tp>
+inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
+  { return const_mem_fun_ref_t<_Ret,_Tp>(__f); }
+
+#endif // SG_INCOMPLETE_FUNCTIONAL
+
+#endif // _SG_COMPILER_H
+
diff --git a/ossimPlanet/include/ossimPlanet/ioapi.h b/ossimPlanet/include/ossimPlanet/ioapi.h
new file mode 100644
index 0000000..7d457ba
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ioapi.h
@@ -0,0 +1,75 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   files using zlib + zip or unzip API
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+*/
+
+#ifndef _ZLIBIOAPI_H
+#define _ZLIBIOAPI_H
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+
+
+#ifndef ZCALLBACK
+
+#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+#define ZCALLBACK CALLBACK
+#else
+#define ZCALLBACK
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong  (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong  (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef long   (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long   (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+typedef int    (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int    (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+
+
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
+#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
+#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
+#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
+#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/iochannel.h b/ossimPlanet/include/ossimPlanet/iochannel.h
new file mode 100644
index 0000000..789d450
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/iochannel.h
@@ -0,0 +1,180 @@
+/**
+ * \file iochannel.hxx
+ * High level IO channel base class.
+ */
+
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: iochannel.h 10940 2007-05-16 16:04:36Z gpotts $
+
+
+#ifndef _IOCHANNEL_HXX
+#define _IOCHANNEL_HXX
+
+#include <osg/Referenced>
+#include <ossimPlanet/compiler.h>
+
+// #include "protocol.hxx"
+
+#include STL_STRING
+#include <vector>
+
+SG_USING_STD(vector);
+SG_USING_STD(string);
+
+#define SG_IO_MAX_MSG_SIZE 16384
+
+/**
+ * Specify if this is a read (IN), write (OUT), or r/w (BI) directional
+ * channel
+ */
+enum SGProtocolDir {
+    SG_IO_NONE = 0,
+    SG_IO_IN = 1,
+    SG_IO_OUT = 2,
+    SG_IO_BI = 3
+};
+
+/**
+ * Specify the channel type
+ */
+enum SGChannelType {
+    sgFileType = 0,
+    sgSerialType = 1,
+    sgSocketType = 2
+};
+
+
+/**
+ * The SGIOChannel base class provides a consistent method for
+ * applications to communication through various mediums. By providing
+ * a base class with multiple derived classes, and application such as
+ * FlightGear can implement a way to speak any protocol via any kind
+ * of I/O channel.
+ *
+ * All of the SGIOChannel derived classes have exactly the same usage
+ * interface once an instance has been created.
+ *
+ */
+class SGIOChannel :public osg::Referenced
+{
+public:
+
+    /** Constructor */
+    SGIOChannel();
+
+    /** Destructor */
+    virtual ~SGIOChannel();
+
+    /** Open a channel.
+     * @param d channel communication "direction"
+     * Direction can be one of: 
+     *  - SG_IO_IN - data will be flowing into this object to the application. 
+     *  - SG_IO_OUT - data will be flowing out of this object from the
+     *                application. 
+     *  - SG_IO_BI - data will be flowing in both directions. 
+     *  - SG_IO_NONE - data will not be flowing in either direction.
+     *                 This is here for the sake of completeness. 
+     * @return result of open
+     */
+    virtual bool open( const SGProtocolDir d );
+
+    /**
+     * The read() method is modeled after the read() Unix system
+     * call. You must provide a pointer to a character buffer that has
+     * enough allocated space for your potential read. You can also
+     * specify the maximum number of bytes allowed for this particular
+     * read. The actual number of bytes read is returned.  You are
+     * responsible to ensure that the size of buf is large enough to
+     * accomodate your input message
+     * @param buf a char pointer to your input buffer 
+     * @param length max number of bytes to read
+     * @return number of bytes read
+     */
+    virtual int read( char *buf, int length );
+
+    /**
+     * The readline() method is similar to read() except that it will
+     * stop at the first end of line encountered in the input buffer.
+     * @param buf a char pointer to your input buffer 
+     * @param length max number of bytes to read
+     * @return number of bytes read
+     */
+    virtual int readline( char *buf, int length );
+    void setReadlineDelimiter(char delimiter='\n');
+
+
+    /**
+     * The write() method is modeled after the write() Unix system
+     * call and is analogous to the read() method. You provide a
+     * pointer to a buffer of data, and then length of that data to be
+     * written out. The number of bytes written is returned.
+     * @param buf a char pointer to your output buffer 
+     * @param length number of bytes to write
+     * @return number of bytes written
+     */
+    virtual int write( const char *buf, const int length );
+
+    /**
+     * The writestring() method is a simple wrapper that will
+     * calculate the length of a null terminated character array and
+     * write it to the output channel.
+     * @param buf a char pointer to your output buffer 
+     * @return number of bytes written
+     */
+    virtual int writestring( const char *str );
+
+    /**
+     * The close() method is modeled after the close() Unix system
+     * call and will close an open device. You should call this method
+     * when you are done using your IO class, before it is destructed.
+     * @return result of close
+     */
+    virtual bool close();
+
+    /**
+     * The eof() method returns true if end of file has been reached
+     * in a context where that makes sense.  Otherwise it returns
+     * false.
+     * @return result of eof check
+     */
+    virtual bool eof();
+
+    inline void set_type( SGChannelType t ) { type = t; }
+    inline SGChannelType get_type() const { return type; }
+
+    inline void set_dir( const SGProtocolDir d ) { dir = d; }
+    inline SGProtocolDir get_dir() const { return dir; }
+    inline bool isvalid() const { return valid; }
+    inline void set_valid( const bool v ) { valid = v; }
+
+protected:
+    char theReadlineDelimiter;
+    
+private:
+    SGChannelType type;
+    SGProtocolDir dir;
+    bool valid;
+
+};
+
+
+#endif // _IOCHANNEL_HXX
+
+
diff --git a/ossimPlanet/include/ossimPlanet/iowin32.h b/ossimPlanet/include/ossimPlanet/iowin32.h
new file mode 100644
index 0000000..a3a437a
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/iowin32.h
@@ -0,0 +1,21 @@
+/* iowin32.h -- IO base function header for compress/uncompress .zip
+   files using zlib + zip or unzip API
+   This IO API version uses the Win32 API (for Microsoft Windows)
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+*/
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/mkUtils.h b/ossimPlanet/include/ossimPlanet/mkUtils.h
new file mode 100644
index 0000000..673323f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/mkUtils.h
@@ -0,0 +1,332 @@
+#ifndef MKUTILS_H
+#define MKUTILS_H
+
+// Defines namespace mkUtils containing various helpful utility functions.
+#ifdef WIN32
+#ifndef __MINGW32__
+#ifdef __MSC_VER
+# if __MSC_VER < 1600
+#   include <xmath.h>
+# endif
+#endif
+#define M_LOG2E    1.44269504088896340736
+#endif
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <cmath>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <osg/Vec3>
+#include <osg/Vec4>
+#include <osg/Vec3d>
+#include <osg/Vec4d>
+#include <osg/Matrixd>
+#include <osg/Matrix>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimXmlNode.h>
+//#include <ossim/base/ossimCommon.h>
+#include <limits>
+#include <ossim/base/ossimXmlNode.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <iostream>
+
+
+namespace mkUtils
+{
+#define OSG_INNER_PRODUCT_3X3(a,b,r,c) \
+(((a(r,0)) * (b(0,c))) \
++((a(r,1)) * (b(1,c))) \
++((a(r,2)) * (b(2,c)))) 
+   
+   OSSIMPLANET_DLL std::istream& planetSkipws(std::istream& in);
+   
+   OSSIMPLANET_DLL bool writeOsgObjectToStream(std::ostream& out, const osg::Object* node, const std::string& extension);
+   
+   inline void mult3x3(osg::Matrixd& result,
+                       const osg::Matrixd& lhs,
+                       const osg::Matrixd& rhs)
+   {
+      result(0,0) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 0, 0);   
+      result(0,1) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 0, 1);
+      result(0,2) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 0, 2);
+      result(1,0) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 1, 0);
+      result(1,1) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 1, 1);
+      result(1,2) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 1, 2);
+      result(2,0) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 2, 0);
+      result(2,1) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 2, 1);
+      result(2,2) = OSG_INNER_PRODUCT_3X3(lhs, rhs, 2, 2);
+   }
+      
+   inline bool almostEqual(const osg::Matrixd& lhs,
+                           const osg::Matrixd& rhs,
+                           double epsilon=DBL_EPSILON)
+   {
+      return ((std::fabs(lhs(0,0)-rhs(0,0)) <= epsilon) &&
+              (std::fabs(lhs(1,0)-rhs(1,0)) <= epsilon) &&
+              (std::fabs(lhs(2,0)-rhs(2,0)) <= epsilon) &&
+              (std::fabs(lhs(3,0)-rhs(3,0)) <= epsilon) &&
+              (std::fabs(lhs(0,1)-rhs(0,1)) <= epsilon) &&
+              (std::fabs(lhs(1,1)-rhs(1,1)) <= epsilon) &&
+              (std::fabs(lhs(2,1)-rhs(2,1)) <= epsilon) &&
+              (std::fabs(lhs(3,1)-rhs(3,1)) <= epsilon) &&
+              (std::fabs(lhs(0,2)-rhs(0,2)) <= epsilon) &&
+              (std::fabs(lhs(1,2)-rhs(1,2)) <= epsilon) &&
+              (std::fabs(lhs(2,2)-rhs(2,2)) <= epsilon) &&
+              (std::fabs(lhs(3,2)-rhs(3,2)) <= epsilon) &&
+              (std::fabs(lhs(0,3)-rhs(0,3)) <= epsilon) &&
+              (std::fabs(lhs(1,3)-rhs(1,3)) <= epsilon) &&
+              (std::fabs(lhs(2,3)-rhs(2,3)) <= epsilon) &&
+              (std::fabs(lhs(3,3)-rhs(3,3)) <= epsilon));
+   }
+   
+   /**
+    * Gives you a nice coefficient that can be used to fade values in and out as a multiplier.  
+    * Could also be used as an alpha on billboard colors and other color bindings.
+    */
+   inline double fadeCoefficient(double currentValue, 
+                                 double referenceValue)
+   {
+      return exp( - currentValue / referenceValue );
+   }
+   
+   /*     template<typename T> */
+   /*     inline bool almostEqual(T x, T y, T tolerence = std::numeric_limits<T>::epsilon()) */
+   /*         // are x and y within tolerence distance of each other */
+   /*         { return std::abs(x - y) <= tolerence; } */
+   
+   inline bool hasPrefix(const std::string& s, const std::string& prefix)
+   // does s have the given prefix?
+   { return prefix == s.substr(0, prefix.size()); }
+   
+   OSSIMPLANET_DLL bool hasSuffix(const std::string& s, const std::string& suffix);
+   // does s have the given suffix?
+   
+   OSSIMPLANET_DLL bool isDouble(const std::string& s);
+   // does s represent a C-style double constant?
+   
+   OSSIMPLANET_DLL bool isInt(const std::string& s);
+   // does s represent a C-style integer constant?
+   
+   OSSIMPLANET_DLL double asDouble(const std::string& s);
+   // value of s as a double, or NAN if not a double.
+   
+   inline float asFloat(const std::string& s)
+   // value of s as a float, or NAN if not a float.
+   { return static_cast<float>(asDouble(s)); }
+   
+   inline long asInt(const std::string& s)
+   // value of s as a long, or 0 if not a long
+   { return strtoul(s.c_str(), NULL, 0); }
+   
+   template <typename T>
+   inline std::string asString(const T& x)
+   // string representation of x
+   {
+      std::ostringstream s;
+      s.precision(16);
+      s << x;
+      return s.str();
+   }
+   
+   template <typename T>
+   inline bool inInterval(T x, T a, T b)
+   // is x in the closed interval [a,b]?
+   { return x >= a && x <= b; }
+   
+   template <typename T>
+   inline bool inOpenInterval(T x, T a, T b)
+   // is x in the open interval (a,b)?
+   { return x > a && x < b; }
+   
+   template <typename S, typename T> 
+   inline T lerp(S x, T begin, T end)
+   // linear interpolation from begin to end by x
+   { return x*(end - begin) + begin; }
+   
+   template <typename T> 
+   inline T inverseLerp(T x, T begin, T end)
+   // inverse of lerp
+   { return begin != end ? (x - begin)/(end - begin) : T(0); }
+   
+   template <typename S, typename T> 
+   T quaderp(S x, T begin, T middle, T end)
+   // quadratic interpolation through begin,middle,end by x
+   {
+      // newton interpolation
+      const T a1 = S(2)*(middle - begin);
+      const T a2 = S(2)*(end - middle) - a1;
+      return x*((x - S(0.5))*a2 + a1) + begin;
+   }
+   
+   template <typename T>
+   inline T step(T x, T a)
+   // x >= a
+   { return T(x >= a); }
+   
+   template <typename T>
+   T smoothstep(T x, T a, T b)
+   // like step() but smoothly over [a,b] rather than sharply at a
+   {
+      assert(a <= b);
+      
+      T t = clamp((x - a)/(b - a), T(0), T(1));
+      return t*t*(T(3) - T(2)*t);
+   }
+   
+   template <typename T>
+   T boxpulse(T x, T a, T b)
+   // box function that is 1 in [a,b] but 0 elsewhere
+   {
+      assert(a <= b);
+      
+      return inInterval(x, a, b);
+   }
+   
+   template <typename T> 
+   inline T clamp(T x, T a, T b)
+   // clamp x to [a, b]
+   {
+      // assert(a <= b);  // XXX we removed this, but we need to fix the real problem
+      
+      return std::min(std::max(x, a), b);
+   }
+   
+   template <typename T>
+   T wrap(T x, T a, T b)
+   // wrap x modularly into [a,b)
+   {
+      assert(a <= b); 
+      
+      if (a == b)
+         return a;
+      else {
+         T z = x < a ? b : a;
+         return std::fmod(x - z, b - a) + z;
+      }
+   }
+   
+   void hprToQuat(osg::Quat& quat, const osg::Vec3d& hpr);
+   void quatToHpr(osg::Vec3d& hpr, const osg::Quat& quat);
+   bool matrixToHpr(osg::Vec3d& hpr, const osg::Matrixd& rotation );
+   bool matrixToHpr(osg::Vec3d& hpr, const osg::Matrixd& lsrMatrix, 
+                    const osg::Matrixd& rotationalMatrix);
+   
+   inline float negativeOneNthPow(int n)
+   // compute pow(-1, n)
+   {
+      // this implementation avoids a conditional branch
+      const float possibleResults[] = {1.0, -1.0};
+      return possibleResults[n & 0x1];   
+   }
+   
+   template <typename T>
+   std::pair<T, T> quadraticRoots(T a, T b, T c)
+   // evaluates quadradic formula (positive sqrt is first)
+   {
+      T s = sqrt(b*b - T(4)*a*c);
+      T twoA = T(2)*a;
+      return std::pair<T, T>((-b + s)/twoA, (-b - s)/twoA);
+   }
+   
+   template <typename T>
+   inline T fmodPos(T a, T b)
+   {
+      T x = std::fmod(a, b);
+      return (x < T(0)) ? x + b : x;
+   }
+   
+   template <typename T>
+   inline T fmodPosAvg(T a, T b)
+   { return fmodPos(a + b*T(0.5), b) - b*T(0.5); }
+   
+   template <typename T>
+   inline T fmodPosClosest(T a, T b, T c)
+   { return c + fmodPosAvg(a - c, b); }
+   
+   template <typename T>
+   inline T grayCode(T x)
+   // x's binary reflected Gray code
+   { return (x >> 1) ^ x; }
+   
+   template <typename T>
+   inline bool isPower2(T x)
+   // is x a power of 2?  T should be integral
+   { return !(x & (x - 1)) && x; }
+   
+   inline double round(double x) 
+   { return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); }
+   
+   template <typename T>
+   inline T logbase(T x, T base) 
+   { return log(x)/log(base); }
+   
+   inline double log2(double x)
+   { return M_LOG2E*log(x); }
+   
+   inline int log2int(double x)
+   { return (int)round(log2(x)); }
+   
+   template <typename T>
+   T ceilPow2(T x)
+   // return the smallest power of two that is >= x; T should be integral
+   {
+      T result(1);
+      while (result < x) {
+         assert(result != 0);  // assert we don't overflow result 
+         result <<= 1;
+      }
+      return result;
+   }
+   
+   inline osg::Vec3d modsphere2xyz(double radius, double theta, double phi) 
+   // convert "modified" spherical coordinates (in radians) to cartesian coords.
+   //     "modified" since angle measurements don't match mathematicians' standard conventions,
+   //     instead use phi = lat and theta = lon convention, but in radians
+   { return osg::Vec3d(radius*cos(phi)*cos(theta), radius*cos(phi)*sin(theta), radius*sin(phi)); }
+   
+   inline std::ostream& operator<<(std::ostream& s, const osg::Vec3f& v)
+   { return (s << v.x() << ' ' << v.y() << ' ' << v.z()); } 
+   inline std::ostream& operator<<(std::ostream& s, const osg::Vec4f& v)
+   { return (s << v.x() << ' ' << v.y() << ' ' << v.z() << ' ' << v.w()); } 
+   inline std::ostream& operator<<(std::ostream& s, const osg::Vec3d& v)
+   { return (s << v.x() << ' ' << v.y() << ' ' << v.z()); } 
+   inline std::ostream& operator<<(std::ostream& s, const osg::Vec4d& v)
+   { return (s << v.x() << ' ' << v.y() << ' ' << v.z() << ' ' << v.w()); } 
+   // convenient streaming operators not defined by osg
+   
+   ossim_int64 factorial(int n);
+   // compute n!
+   // require(n >= 0 && n < 21)
+   
+   void lexBraceQuotedTokens(const std::string& str, unsigned int startIdx, const char* whitespace, std::vector<std::string>* tokens, bool* unbalancedBraces);
+   // lex str into tokens starting at position start using whitespace  
+   //    chars as delimiters and curly braces to quote tokens containing
+   //    whitespace. unbalancedBraces is true iff it aborted when detecting 
+   //    unbalanced braces.
+   // assert(whitespace != NULL);
+   // assert(tokens != NULL);
+   // assert(unbalancedBraces != NULL);
+   
+   OSSIMPLANET_DLL bool extractObjectAndArg(std::string& resultObject,
+                                            std::string& resultArg,
+                                            const std::string& inputValue,
+                                            const char quotes[2] ="{}");
+   template <typename T>
+   inline void memClear(T& var)
+   // zero out a variable's memory
+   { memset(&var, 0, sizeof(T)); }
+   
+   OSSIMPLANET_DLL ossimRefPtr<ossimXmlNode> newNodeFromObjectMessageRoute(const ossimString& v,
+                                                                           const char quotes[2]="{}");
+   
+   OSSIMPLANET_DLL ossimRefPtr<ossimXmlNode> newNodeFromObjectMessageRoute(const ossimString& receiverPath,
+                                                                           const ossimString& command,
+                                                                           const ossimString& v,
+                                                                           const char quotes[2]);   
+}
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/net.h b/ossimPlanet/include/ossimPlanet/net.h
new file mode 100644
index 0000000..e7b0c90
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/net.h
@@ -0,0 +1,12 @@
+#ifndef __PLIB_NET_H__
+#define __PLIB_NET_H__ 1
+
+#include <plib/netBuffer.h>
+#include <plib/netChannel.h>
+#include <plib/netChat.h>
+#include <plib/netMessage.h>
+#include <plib/netMonitor.h>
+#include <plib/netSocket.h>
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/netBuffer.h b/ossimPlanet/include/ossimPlanet/netBuffer.h
new file mode 100644
index 0000000..c5ff59b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netBuffer.h
@@ -0,0 +1,234 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netBuffer.h 1901 2004-03-21 18:19:11Z sjbaker $
+*/
+
+/****
+* NAME
+*   netBuffer - network buffer class
+*
+* DESCRIPTION
+*   Clients and servers built on top of netBufferChannel
+*   automatically support pipelining.
+*
+*   Pipelining refers to a protocol capability. Normally,
+*   a conversation with a server has a back-and-forth
+*   quality to it.  The client sends a command, and
+*   waits for the response. If a client needs to send
+*   many commands over a high-latency connection,
+*   waiting for each response can take a long time. 
+*
+*   For example, when sending a mail message to many recipients
+*   with SMTP, the client will send a series of RCPT commands, one
+*   for each recipient. For each of these commands, the server will
+*   send back a reply indicating whether the mailbox specified is
+*   valid. If you want to send a message to several hundred recipients,
+*   this can be rather tedious if the round-trip time for each command
+*   is long. You'd like to be able to send a bunch of RCPT commands
+*   in one batch, and then count off the responses to them as they come. 
+*
+*   I have a favorite visual when explaining the advantages of
+*   pipelining. Imagine each request to the server is a boxcar on a train.
+*   The client is in Los Angeles, and the server is in New York.
+*   Pipelining lets you hook all your cars in one long chain; send
+*   them to New York, where they are filled and sent back to you.
+*   Without pipelining you have to send one car at a time. 
+*
+*   Not all protocols allow pipelining. Not all servers support it;
+*   Sendmail, for example, does not support pipelining because it tends
+*   to fork unpredictably, leaving buffered data in a questionable state.
+*   A recent extension to the SMTP protocol allows a server to specify
+*   whether it supports pipelining. HTTP/1.1 explicitly requires that
+*   a server support pipelining. 
+*
+* NOTES
+*   When a user passes in a buffer object, it belongs to
+*   the user.  When the library gives a buffer to the user,
+*   the user should copy it.
+*
+* AUTHORS
+*   Sam Rushing <rushing at nightmare.com> - original version for Medusa
+*   Dave McClurg <dpm at efn.org> - modified for use in PLIB
+*
+* CREATION DATE
+*   Dec-2000
+*
+****/
+
+#ifndef NET_BUFFER_H
+#define NET_BUFFER_H
+
+#include "netChannel.h"
+
+
+// ===========================================================================
+// netName
+// ===========================================================================
+
+enum { NET_MAX_NAME = 31 } ;
+//eg. char name [ NET_MAX_NAME+1 ] ;
+
+
+inline char* netCopyName ( char* dst, const char* src )
+{
+  if ( src != NULL )
+  {
+    strncpy ( dst, src, NET_MAX_NAME ) ;
+    dst [ NET_MAX_NAME ] = 0 ;
+  }
+  else
+    *dst = 0 ;
+  return dst ;
+}
+
+
+// ===========================================================================
+// netBuffer
+// ===========================================================================
+
+class netBuffer
+{
+protected:
+  int length ;
+  int max_length ;
+  char* data ;
+
+public:
+  netBuffer ( int _max_length )
+  {
+    length = 0 ;
+    max_length = _max_length ;
+    data = new char [ max_length+1 ] ;  //for null terminator
+  }
+
+  ~netBuffer ()
+  {
+    delete[] data ;
+  }
+
+  int getLength() const { return length ; }
+  int getMaxLength() const { return max_length ; }
+
+  /*
+  **  getData() returns a pointer to the data
+  **  Note: a zero (0) byte is appended for convenience
+  **  but the data may have internal zero (0) bytes already
+  */
+  char* getData() { data [length] = 0 ; return data ; }
+  const char* getData() const { ((char*)data) [length] = 0 ; return data ; }
+
+  void remove ()
+  {
+    length = 0 ;
+  }
+
+  void remove (int pos, int n)
+  {
+    assert (pos>=0 && pos<length && (pos+n)<=length) ;
+    //if (pos>=0 && pos<length && (pos+n)<=length)
+    {
+      memmove(&data[pos],&data[pos+n],length-(pos+n)) ;
+      length -= n ;
+    }
+  }
+
+  bool append (const char* s, int n)
+  {
+    if ((length+n)<=max_length)
+    {
+      memcpy(&data[length],s,n) ;
+      length += n ;
+      return true ;
+    }
+    return false ;
+  }
+
+  bool append (int n)
+  {
+    if ((length+n)<=max_length)
+    {
+      length += n ;
+      return true ;
+    }
+    return false ;
+  }
+} ;
+
+// ===========================================================================
+// netBufferChannel
+// ===========================================================================
+
+class netBufferChannel : public netChannel
+{
+  netBuffer in_buffer;
+  netBuffer out_buffer;
+  int should_close ;
+  
+  virtual bool readable (void)
+  {
+    return (netChannel::readable() &&
+      (in_buffer.getLength() < in_buffer.getMaxLength()));
+  }
+
+  virtual void handleRead (void) ;
+
+  virtual bool writable (void)
+  {
+    return (out_buffer.getLength() || should_close);
+  }
+
+  virtual void handleWrite (void) ;
+
+public:
+
+  netBufferChannel (int in_buffer_size = 4096, int out_buffer_size = 16384) :
+    in_buffer (in_buffer_size),
+    out_buffer (out_buffer_size),
+    should_close (0)
+  { /* empty */
+  }
+
+  virtual void handleClose ( void )
+  {
+    in_buffer.remove () ;
+    out_buffer.remove () ;
+    should_close = 0 ;
+    netChannel::handleClose () ;
+  }
+
+  void closeWhenDone (void) { should_close = 1 ; }
+
+  virtual bool bufferSend (const char* msg, int msg_len)
+  {
+    if ( out_buffer.append(msg,msg_len) )
+      return true ;
+    ulSetError ( UL_WARNING, "netBufferChannel: output buffer overflow!" ) ;
+    return false ;
+  }
+
+  virtual void handleBufferRead (netBuffer& buffer)
+  {
+    /* do something here */
+    buffer.remove();
+  }
+};
+
+#endif // NET_BUFFER_H
diff --git a/ossimPlanet/include/ossimPlanet/netChannel.h b/ossimPlanet/include/ossimPlanet/netChannel.h
new file mode 100644
index 0000000..2bbc001
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netChannel.h
@@ -0,0 +1,116 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netChannel.h 1899 2004-03-21 17:41:07Z sjbaker $
+*/
+
+/****
+* NAME
+*   netChannel - network channel class
+*
+* DESCRIPTION
+*   netChannel is adds event-handling to the low-level
+*   netSocket class.  Otherwise, it can be treated as
+*   a normal non-blocking socket object.
+*
+*   The direct interface between the netPoll() loop and
+*   the channel object are the handleReadEvent and
+*   handleWriteEvent methods. These are called
+*   whenever a channel object 'fires' that event.
+*
+*   The firing of these low-level events can tell us whether
+*   certain higher-level events have taken place, depending on
+*   the timing and state of the connection.
+*
+* AUTHORS
+*   Sam Rushing <rushing at nightmare.com> - original version for Medusa
+*   Dave McClurg <dpm at efn.org> - modified for use in PLIB
+*
+* CREATION DATE
+*   Dec-2000
+*
+****/
+
+#ifndef NET_CHANNEL_H
+#define NET_CHANNEL_H
+
+#include "netSocket.h"
+
+class netChannel : public netSocket
+{
+  bool closed, connected, accepting, write_blocked, should_delete ;
+  netChannel* next_channel ;
+  
+  friend bool netPoll (unsigned int timeout);
+
+public:
+
+  netChannel () ;
+  virtual ~netChannel () ;
+
+  void setHandle (int s, bool is_connected = true);
+  bool isConnected () const { return connected; }
+  bool isClosed () const { return closed; }
+  void shouldDelete () { should_delete = true ; }
+
+  // --------------------------------------------------
+  // socket methods
+  // --------------------------------------------------
+  
+  bool  open    ( bool streamFlag=true ) ;
+  void  close   ( void ) ;
+  int   listen  ( int backlog ) ;
+  int   connect ( const char* host, int port ) ;
+  int   send    ( const void * buf, int size, int flags = 0 ) ;
+  int   recv    ( void * buf, int size, int flags = 0 ) ;
+
+  // poll() eligibility predicates
+  virtual bool readable (void) { return (connected || accepting); }
+  virtual bool writable (void) { return (!connected || write_blocked); }
+  
+  // --------------------------------------------------
+  // event handlers
+  // --------------------------------------------------
+  
+  void handleReadEvent (void);
+  void handleWriteEvent (void);
+  
+  // These are meant to be overridden.
+  virtual void handleClose (void) {
+    //ulSetError(UL_WARNING,"Network: %d: unhandled close",getHandle());
+  }
+  virtual void handleRead (void) {
+    //ulSetError(UL_WARNING,"Network: %d: unhandled read",getHandle());
+  }
+  virtual void handleWrite (void) {
+    //ulSetError(UL_WARNING,"Network: %d: unhandled write",getHandle());
+  }
+  virtual void handleAccept (void) {
+    //ulSetError(UL_WARNING,"Network: %d: unhandled accept",getHandle());
+  }
+  virtual void handleError (int /* error */) {
+    //ulSetError(UL_WARNING,"Network: %d: errno: %s(%d)",getHandle(),strerror(errno),errno);
+  }
+
+  static bool poll (unsigned int timeout = 0 ) ;
+  static void loop (unsigned int timeout = 0 ) ;
+};
+
+#endif // NET_CHANNEL_H
diff --git a/ossimPlanet/include/ossimPlanet/netChat.h b/ossimPlanet/include/ossimPlanet/netChat.h
new file mode 100644
index 0000000..1a89559
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netChat.h
@@ -0,0 +1,86 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netChat.h 1568 2002-09-02 06:05:49Z sjbaker $
+*/
+
+/****
+* NAME
+*   netChat - network chat class
+*
+* DESCRIPTION
+*   This class adds support for 'chat' style protocols -
+*   where one side sends a 'command', and the other sends
+*   a response (examples would be the common internet
+*   protocols - smtp, nntp, ftp, etc..).
+*
+*   The handle_buffer_read() method looks at the input
+*   stream for the current 'terminator' (usually '\r\n'
+*   for single-line responses, '\r\n.\r\n' for multi-line
+*   output), calling found_terminator() on its receipt.
+*
+* EXAMPLE
+*   Say you build an nntp client using this class.
+*   At the start of the connection, you'll have
+*   terminator set to '\r\n', in order to process
+*   the single-line greeting.  Just before issuing a
+*   'LIST' command you'll set it to '\r\n.\r\n'.
+*   The output of the LIST command will be accumulated
+*   (using your own 'collect_incoming_data' method)
+*   up to the terminator, and then control will be
+*   returned to you - by calling your found_terminator()
+*
+* AUTHORS
+*   Sam Rushing <rushing at nightmare.com> - original version for Medusa
+*   Dave McClurg <dpm at efn.org> - modified for use in PLIB
+*
+* CREATION DATE
+*   Dec-2000
+*
+****/
+
+#ifndef NET_CHAT_H
+#define NET_CHAT_H
+
+#include "netBuffer.h"
+
+class netChat : public netBufferChannel
+{
+  char* terminator;
+  
+  virtual void handleBufferRead (netBuffer& buffer) ;
+
+public:
+
+  netChat () : terminator (0) {}
+
+  void setTerminator (const char* t);
+  const char* getTerminator (void);
+
+  bool push (const char* s)
+  {
+    return bufferSend ( s, strlen(s) ) ;
+  }
+
+  virtual void collectIncomingData	(const char* /* s */, int /* n */) {}
+  virtual void foundTerminator (void) {}
+};
+
+#endif // NET_CHAT_H
diff --git a/ossimPlanet/include/ossimPlanet/netMessage.h b/ossimPlanet/include/ossimPlanet/netMessage.h
new file mode 100644
index 0000000..57a4a89
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netMessage.h
@@ -0,0 +1,294 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netMessage.h 2112 2006-12-12 18:45:28Z fayjf $
+*/
+
+/****
+* NAME
+*   netMessage - message buffer and channel classes
+*
+* DESCRIPTION
+*   messages are a binary format for sending buffers over a channel.
+*   message headers contain a type field and length.
+*
+* AUTHOR
+*   Dave McClurg <dpm at efn.org>
+*
+* CREATION DATE
+*   Dec-2000
+****/
+
+#ifndef __NET_MESSAGE__
+#define __NET_MESSAGE__
+
+
+#include "netBuffer.h"
+
+// ntohs() etc prototypes
+#ifdef UL_MSVC
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <arpa/inet.h>
+#endif
+
+
+class netGuid //Globally Unique IDentifier
+{
+public:
+  unsigned char data [ 16 ] ;
+
+  netGuid () {}
+
+  netGuid ( unsigned int   l,
+            unsigned short w1, unsigned short w2,
+            unsigned char  b1, unsigned char  b2,
+            unsigned char  b3, unsigned char  b4,
+            unsigned char  b5, unsigned char  b6,
+            unsigned char  b7, unsigned char  b8 )
+  {
+    //store in network format (big-endian)
+
+    data[ 0] = (unsigned char)(l>>24) ;
+    data[ 1] = (unsigned char)(l>>16) ;
+    data[ 2] = (unsigned char)(l>> 8) ;
+    data[ 3] = (unsigned char)(l    ) ;
+    data[ 4] = (unsigned char)(w1>>8) ;
+    data[ 5] = (unsigned char)(w1   ) ;
+    data[ 6] = (unsigned char)(w2>>8) ;
+    data[ 7] = (unsigned char)(w2   ) ;
+
+    data[ 8] = b1 ;
+    data[ 9] = b2 ;
+    data[10] = b3 ;
+    data[11] = b4 ;
+    data[12] = b5 ;
+    data[13] = b6 ;
+    data[14] = b7 ;
+    data[15] = b8 ;
+  }
+
+  bool operator ==( const netGuid& guid ) const
+  { 
+    return memcmp ( data, guid.data, sizeof(data) ) == 0 ;
+  }
+
+  bool operator !=( const netGuid& guid ) const
+  { 
+    return memcmp ( data, guid.data, sizeof(data) ) != 0 ;
+  }
+} ;
+
+
+class netMessage : public netBuffer
+{
+  int pos ;
+
+  void seek ( int new_pos ) const
+  {
+    if ( new_pos < 0 )
+      new_pos = 0 ;
+    else
+    if ( new_pos > length )
+      new_pos = length ;
+
+    //logical const-ness
+
+    ((netMessage*)this) -> pos = new_pos ;
+  }
+
+  void skip ( int off ) const
+  {
+    seek(pos+off);
+  }
+
+public:
+
+  // incoming message; header is already there
+  netMessage ( const char* s, int n ) : netBuffer(n)
+  {
+    assert ( n >= 5 ) ;
+    append(s,n);
+    pos = 5 ; // seek past header
+  }
+
+  // outgoing message
+  netMessage ( int type, int to_id, int from_id=0, int n=256 ) : netBuffer(n)
+  {
+    // output header
+    putw ( 0 ) ;  //msg_len
+    putbyte ( type ) ;
+    putbyte ( to_id ) ;
+    putbyte ( from_id ) ;
+  }
+
+  int getType () const { return ( (unsigned char*)data )[ 2 ] ; }
+  int getToID () const { return ( (unsigned char*)data )[ 3 ] ; }
+  int getFromID () const { return ( (unsigned char*)data )[ 4 ] ; }
+  void setFromID ( int from_id ) { ( (unsigned char*)data )[ 4 ] = (unsigned char)from_id; }
+
+  void geta ( void* a, int n ) const
+  {
+    assert (pos>=0 && pos<length && (pos+n)<=length) ;
+    //if (pos>=0 && pos<length && (pos+n)<=length)
+    {
+      memcpy(a,&data[pos],n) ;
+      seek(pos+n);
+    }
+  }
+  void puta ( const void* a, int n )
+  {
+    append((const char*)a,n);
+    pos = length;
+    *((unsigned short*)data) = (unsigned short)length ; //update msg_len
+  }
+
+  int getbyte () const
+  {
+    unsigned char temp ;
+    geta(&temp,sizeof(temp)) ;
+    return temp ;
+  }
+  void putbyte ( int c )
+  {
+    unsigned char temp = c ;
+    puta(&temp,sizeof(temp)) ;
+  }
+
+  bool getb () const
+  {
+    unsigned char temp ;
+    geta(&temp,sizeof(temp)) ;
+    return temp != 0 ;
+  }
+  void putb ( bool b )
+  {
+    unsigned char temp = b? 1: 0 ;
+    puta(&temp,sizeof(temp)) ;
+  }
+
+  int getw () const
+  {
+    unsigned short temp ;
+    geta ( &temp, sizeof(temp) ) ;
+    return int ( ntohs ( temp ) ) ;
+  }
+  void putw ( int i )
+  {
+    unsigned short temp = htons ( (unsigned short) i ) ;
+    puta ( &temp, sizeof(temp) ) ;
+  }
+
+  int geti () const
+  {
+    unsigned int temp ;
+    geta ( &temp, sizeof(temp) ) ;
+    return int ( ntohl ( temp ) ) ;
+  }
+  void puti ( int i )
+  {
+    unsigned int temp = htonl ( (unsigned int) i ) ;
+    puta ( &temp, sizeof(temp) ) ;
+  }
+
+  void getfv ( float* fv, int n ) const
+  {
+    unsigned int* v = (unsigned int*)fv;
+    geta ( v, (n<<2) ) ;
+    for ( int i=0; i<n; i++ )
+      v[i] = ntohl ( v[i] ) ;
+  }
+  void putfv ( const float* fv, int n )
+  {
+    const unsigned int* v = (const unsigned int*)fv;
+    for ( int i=0; i<n; i++ )
+    {
+      unsigned int temp = htonl ( v[i] ) ;
+      puta ( &temp, sizeof(temp) ) ;
+    }
+  }
+  
+  float getf () const
+  {
+    unsigned int temp ;
+    geta ( &temp, sizeof(temp) ) ;
+    temp = ntohl ( temp ) ;
+    return *((float*)&temp) ;
+  }
+  void putf ( float f )
+  {
+    unsigned int temp = *((unsigned int*)&f) ;
+    temp = htonl ( temp ) ;
+    puta ( &temp, sizeof(temp) ) ;
+  }
+
+  void gets ( char* s, int n ) const
+  {
+    char* src = &data[pos];
+    char* dst = s;
+    while (pos<length)
+    {
+      char ch = *src++;
+      if ((dst-s)<(n-1))
+        *dst++ = ch ;
+      ((netMessage*)this)->pos++;
+      if (ch==0)
+        break;
+    }
+    *dst = 0 ;
+  }
+  void puts ( const char* s )
+  {
+    puta(s,strlen(s)+1);
+  }
+
+  void print ( FILE *fd = stderr ) const
+  {
+    fprintf ( fd, "netMessage: %p, length=%d\n", this, length ) ;
+    fprintf ( fd, "  header (type,to,from) = (%d,%d,%d)\n",
+      getType(), getToID(), getFromID() ) ;
+    fprintf ( fd, "  data = " ) ;
+    for ( int i=0; i<length; i++ )
+      fprintf ( fd, "%02x ", data[i] ) ;
+    fprintf ( fd, "\n" ) ;
+  }
+};
+
+
+class netMessageChannel : public netBufferChannel
+{
+  virtual void handleBufferRead (netBuffer& buffer) ;
+
+public:
+
+  bool sendMessage ( const netMessage& msg )
+  {
+    return bufferSend ( msg.getData(), msg.getLength() ) ;
+  }
+
+  virtual void handleMessage ( const netMessage& msg ) {}
+};
+
+
+#endif //__NET_MESSAGE__
diff --git a/ossimPlanet/include/ossimPlanet/netMonitor.h b/ossimPlanet/include/ossimPlanet/netMonitor.h
new file mode 100644
index 0000000..d3cd6f5
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netMonitor.h
@@ -0,0 +1,106 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netMonitor.h 1899 2004-03-21 17:41:07Z sjbaker $
+*/
+
+/****
+* NAME
+*   netMonitor - network monitor server
+*
+* DESCRIPTION
+*   netMonitor is a telnet command port with
+*   password authorization.  It can be paired
+*   with and used to remotely admin another server.
+*
+* AUTHORS
+*   Sam Rushing <rushing at nightmare.com> - original version for Medusa
+*   Dave McClurg <dpm at efn.org> - modified for use in PLIB
+*
+* CREATION DATE
+*   Dec-2000
+*
+****/
+
+#ifndef NET_MONITOR_H
+#define NET_MONITOR_H
+
+#include "netChat.h"
+
+
+class netMonitorServer : private netChannel
+{
+  char* name ;
+  char* password ;
+  char* prompt ;
+  void (*cmdfunc)(const char*) ;
+  class netMonitorChannel* active ;
+
+  friend class netMonitorChannel ;
+
+  virtual bool writable (void) { return false ; }
+  virtual void handleAccept (void) ;
+  
+public:
+
+  netMonitorServer( const char* _name, int port )
+  {
+    name = ulStrDup(_name);
+    password = ulStrDup("") ;
+		prompt = ulStrDup(">>> ");
+    cmdfunc = 0 ;
+    active = 0 ;
+
+		open () ;
+		bind ("", port);
+		listen (1);
+
+    ulSetError(UL_DEBUG, "Monitor \"%s\" started on port %d",name,port);
+  }
+
+  ~netMonitorServer()
+  {
+    delete[] name ;
+    delete[] password ;
+    delete[] prompt ;
+  }
+
+  const char* getPassword () const { return password; }
+  void setPassword ( const char* string )
+  {
+    delete[] password ;
+    password = ulStrDup ( string?string:"" ) ;
+  }
+
+  void setPrompt ( const char* string )
+  {
+    delete[] prompt ;
+    prompt = ulStrDup ( string?string:"" ) ;
+  }
+
+  void setCommandFunc ( void (*func)(const char*) )
+  {
+    cmdfunc = func ;
+  }
+
+  bool push (const char* s) ;
+} ;
+
+#endif // NET_MONITOR_H
diff --git a/ossimPlanet/include/ossimPlanet/netSocket.h b/ossimPlanet/include/ossimPlanet/netSocket.h
new file mode 100644
index 0000000..c29a023
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/netSocket.h
@@ -0,0 +1,115 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netSocket.h 2052 2005-11-10 20:55:54Z fayjf $
+*/
+
+/****
+* NAME
+*   netSocket - network sockets
+*
+* DESCRIPTION
+*   netSocket is a thin C++ wrapper over bsd sockets to
+*   facilitate porting to other platforms
+*
+* AUTHOR
+*   Dave McClurg <dpm at efn.org>
+*
+* CREATION DATE
+*   Dec-2000
+*
+****/
+
+#ifndef NET_SOCKET_H
+#define NET_SOCKET_H
+
+#include "ul.h"
+#include <errno.h>
+
+/*
+ * Socket address, internet style.
+ */
+class netAddress
+{
+  /* DANGER!!!  This MUST match 'struct sockaddr_in' exactly! */
+  short          sin_family     ;
+  unsigned short sin_port       ;
+  unsigned int   sin_addr       ;
+  char           sin_zero [ 8 ] ;
+
+public:
+  netAddress () {}
+  netAddress ( const char* host, int port ) ;
+
+  void set ( const char* host, int port ) ;
+  const char* getHost () const ;
+  unsigned int getPort() const ;
+  unsigned int getIP () const ;
+  unsigned int getFamily () const ;
+  static const char* getLocalHost () ;
+
+  bool getBroadcast () const ;
+};
+
+
+/*
+ * Socket type
+ */
+class netSocket
+{
+  int handle ;
+
+public:
+
+  netSocket () ;
+  virtual ~netSocket () ;
+
+  int getHandle () const { return handle; }
+  void setHandle (int handle) ;
+  
+  bool  open        ( bool stream=true ) ;
+  void  close       ( void ) ;
+  int   bind        ( const char* host, int port ) ;
+  int   listen	    ( int backlog ) ;
+  int   accept      ( netAddress* addr ) ;
+  int   connect     ( const char* host, int port ) ;
+  int   send	    ( const void * buffer, int size, int flags = 0 ) ;
+  int   sendto      ( const void * buffer, int size, int flags, const netAddress* to ) ;
+  int   recv	    ( void * buffer, int size, int flags = 0 ) ;
+  int   recvfrom    ( void * buffer, int size, int flags, netAddress* from ) ;
+
+  void setBlocking ( bool blocking ) ;
+  void setBroadcast ( bool broadcast ) ;
+
+  static bool isNonBlockingError () ;
+  static int select ( netSocket** reads, netSocket** writes, int timeout ) ;
+} ;
+
+
+int netInit ( int* argc, char** argv = NULL ) ;  /* Legacy */
+
+int netInit () ;
+
+
+const char* netFormat ( const char* fmt, ... ) ;
+
+
+#endif // NET_SOCKET_H
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanet.h b/ossimPlanet/include/ossimPlanet/ossimPlanet.h
new file mode 100644
index 0000000..2090a05
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanet.h
@@ -0,0 +1,135 @@
+#ifndef ossimPlanet_HEADER
+#define ossimPlanet_HEADER
+#include <osg/MatrixTransform>
+#include <vector>
+#include "ossimPlanetExport.h"
+#include <osg/MatrixTransform>
+#include <osgUtil/CullVisitor>
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetSousaLayer.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+
+class ossimPlanetLand;
+class OSSIMPLANET_DLL ossimPlanet : public osg::MatrixTransform,
+                                    public ossimPlanetActionReceiver,
+                                    public ossimPlanetCallbackListInterface<ossimPlanetNodeCallback>
+
+{
+public:   
+   friend class ossimPlanetUpdateCallback;
+   class LayerListener : public ossimPlanetNodeCallback
+      {
+      public:
+         LayerListener(ossimPlanet* planet);
+         virtual void needsRedraw(ossimPlanetNode* node);
+         void setPlanet(ossimPlanet* planet);
+      protected:
+         ossimPlanet* thePlanet;
+      };
+   ossimPlanet();
+   virtual osg::Object* cloneType() const { return new ossimPlanet(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanet *>(obj)!=NULL; }
+   virtual const char* className() const { return "ossimPlanet"; } 
+   virtual const char* libraryName() const { return "ossimPlanet"; }
+   virtual void setupDefaults();
+   virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove);
+   
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual osg::BoundingSphere computeBound() const;
+   //   virtual bool computeBound() const;
+   osg::ref_ptr<ossimPlanetGeoRefModel> model()
+	{
+		return theModel;
+	}
+   const osg::ref_ptr<ossimPlanetGeoRefModel> model()const
+	{
+		return theModel;
+	}
+   
+   const osg::Vec3d& getEyePositionLatLonHeight()const;
+   osg::Vec3d getNadirPoint()const;
+   osg::Vec3d getLineOfSitePoint()const;
+   osg::Vec3d getNadirLatLonHeightPoint()const;
+   osg::Vec3d getLineOfSiteLatLonHeightPoint()const;
+   const osg::Vec3d& hpr()const;
+   
+    void setComputeIntersectionFlag(bool flag);
+    bool getComputeIntersectionFlag()const;
+   static ossimPlanet* findPlanet(osg::Node* startNode);
+   static ossimPlanet* findPlanet(osg::NodePath& currentNodePath);
+	void resetAllRedrawFlags();
+   void setRedrawFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theRedrawFlag = flag;
+   }
+   bool redrawFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theRedrawFlag;
+   }
+   /**
+    * This executes passed in actions.
+    *
+    */
+   virtual void execute(const ossimPlanetAction& action);
+   
+   void notifyNeedsRedraw(ossimPlanetNode* node);
+   const ossimPlanetLookAt* lookAt()const
+   {
+      return theLookAt.get();
+   }
+   void setLookAt(osg::ref_ptr<ossimPlanetLookAt> look)
+   {
+      theLookAt = look.get();
+   }
+   const ossimPlanetLookAt* eyePosition()const
+   {
+      return theEyePosition.get();
+   }
+   void setEyePosition(osg::ref_ptr<ossimPlanetLookAt> eye)
+   {
+      theEyePosition = eye.get();
+   }
+   
+protected:
+   ~ossimPlanet();
+   virtual void xmlExecute(const ossimPlanetXmlAction& xmlAction);
+   virtual void childInserted(unsigned int pos);
+	virtual void childRemoved(unsigned int /*pos*/, unsigned int /*numChildrenToRemove*/);
+   void notifyLayerAdded(ossimPlanetLayer* layer);
+   void notifyLayerRemoved(ossimPlanetLayer* layer);
+   void computeIntersection(osgUtil::CullVisitor* cullVisitor);
+   bool theComputeIntersectionFlag;
+   bool theRedrawFlag;
+   osg::Vec3d theNadirPoint;
+   osg::Vec3d theLineOfSitePoint;
+   osg::Vec3d theNadirLatLonHeightPoint;
+   osg::Vec3d theLineOfSiteLatLonHeightPoint;
+   osg::Vec3d theEyePositionLatLonHeight;
+   mutable ossimPlanetReentrantMutex theTraversalMutex;
+   mutable ossimPlanetReentrantMutex thePropertyMutex;
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+   osg::Vec3d theLsrHeadingPitchRoll;
+   osg::ref_ptr<ossimPlanet::LayerListener> theLayerListener;
+   
+   ossimPlanetReentrantMutex theLayersToAddListMutex;
+   // Internal list that is maintained through creation of layers through the
+   // recever commands.  It will be synched to the graph on next Update visitation
+   //
+   std::vector<osg::ref_ptr<ossimPlanetLayer> > theLayersToAddList;
+   
+   osg::ref_ptr<ossimPlanetLookAt> theLookAt;
+   osg::ref_ptr<ossimPlanetLookAt> theEyePosition;
+
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetAction.h b/ossimPlanet/include/ossimPlanet/ossimPlanetAction.h
new file mode 100644
index 0000000..97efd35
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetAction.h
@@ -0,0 +1,161 @@
+#ifndef ossimPlanetAction_HEADER
+#define ossimPlanetAction_HEADER
+
+// message to make an ActionReceiver do something
+#include <assert.h>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Referenced>
+#include <ossim/base/ossimString.h>
+
+class ossimPlanetDestinationCommandAction;
+class ossimPlanetXmlAction;
+class OSSIMPLANET_DLL ossimPlanetAction : public osg::Referenced
+{
+public:
+   ossimPlanetAction(const ossimString& originatingFederate=ossimString());
+   ossimPlanetAction(const ossimPlanetAction& action)
+	:osg::Referenced(),
+        theOrigin(action.theOrigin),
+	theTarget(action.theTarget),
+   theCommand(action.theCommand),
+   theSourceCode(action.theSourceCode)
+   {
+      
+   }
+   virtual ~ossimPlanetAction()
+   {}
+   virtual ossimPlanetDestinationCommandAction* toDestinationCommandAction()
+   {
+      return 0;
+   }
+   virtual const ossimPlanetDestinationCommandAction* toDestinationCommandAction()const
+   {
+      return 0;
+   }
+   virtual ossimPlanetXmlAction* toXmlAction()
+   {
+      return 0;
+   }
+   virtual const ossimPlanetXmlAction* toXmlAction()const
+   {
+      return 0;
+   }
+   virtual ossimPlanetAction* clone()const=0;
+   virtual ossimPlanetAction* cloneType()const=0; 
+   /**
+    * Will allow one to set the source code for the derived actions
+    *
+    */
+	virtual bool setSourceCode(const ossimString& code)=0;
+	void sourceCode(ossimString& code)const
+   {
+      code = theSourceCode;
+   }
+	const ossimString& sourceCode()const
+   {
+      return theSourceCode;
+   }
+	void target(ossimString& value)  const
+   {
+      value = theTarget;
+   }
+   const ossimString& target()const
+   {
+      return theTarget;
+   }
+   virtual void setTarget(const ossimString& value)
+   {
+      theTarget = value;
+   }
+   
+   void command(ossimString& value) const
+   {
+      value = theCommand;
+   }
+   const ossimString& command() const
+   {
+      return theCommand;
+   }
+   virtual void setCommand(const ossimString& value)
+   {
+      theCommand = value;
+   }
+	const ossimString& origin() const
+	{ 
+      return theOrigin; 
+   }
+	
+	virtual void setOrigin(const ossimString& originatingFederate)
+	{ 
+      theOrigin = originatingFederate; 
+   }
+	
+   friend std::ostream& operator<<(std::ostream& s, const ossimPlanetAction& a)
+   {
+      a.print(s);
+      return s;
+   }
+	
+   friend std::istream& operator>>(std::istream& s, ossimPlanetAction& a)
+   {
+      a.read(s);
+      return s;
+   }
+	virtual void print(std::ostream& out)const = 0;
+   virtual void read(std::istream& in) = 0;
+   
+	void printError(const char* message) const;
+	void printError(const ossimString& message) const;
+	// print error message containing message followed by action source to
+	// stderr. usually called in ActionReceiver::execute() error handling.
+	
+	/**
+	 * post the action to the threaded action queue
+	 */ 
+	virtual void post() const;
+	
+	virtual void execute() const;
+	// execute yourself
+	
+	virtual void allExecute() const;
+	// tell all machines to execute yourself (distributed sims only)
+	
+	virtual void tellExecute(const ossimString& destination) const;
+	// tell another machine to execute yourself (distributed sims only)
+	
+//   static ossimPlanetAction createNestedAction(const ossimString& argument,
+//                                               bool wrapWithBracketsFlag = true)
+//   {
+//      return createNestedAction(":dummy", "dummy", argument, wrapWithBracketsFlag);
+//   }
+//	static ossimPlanetAction createNestedAction(const ossimString& receiverName,
+//													        const ossimString& actionName,
+//															  const ossimString& argument,
+//                                               bool wrapWithBracketsFlag = true)
+//	{
+//      if(!wrapWithBracketsFlag)
+//      {
+//         return ossimPlanetAction(receiverName + " " + actionName + " " + argument);
+//      }
+//		return ossimPlanetAction(receiverName + " " + actionName + " { " + argument + " }");
+//	}
+	// streaming operators
+	
+protected:
+	// federate this Action originated from (for distributed sims)
+	ossimString theOrigin;
+	
+   ossimString theTarget;
+   ossimString theCommand;
+   ossimString theSourceCode;
+	static const ossimString& defaultOrigin();
+	// default origin for newly created Actions
+};
+
+
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetActionReceiver.h b/ossimPlanet/include/ossimPlanet/ossimPlanetActionReceiver.h
new file mode 100644
index 0000000..edcb5c4
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetActionReceiver.h
@@ -0,0 +1,39 @@
+#ifndef ossimPlanetActionReciever_HEADER
+#define ossimPlanetActionReciever_HEADER
+
+// abstract superclass for objects that can receive Actions. 
+
+/* #include <assert> */
+#include <string>
+#include "ossimPlanetAction.h"
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetActionReceiver {
+public:
+    virtual ~ossimPlanetActionReceiver();
+    
+    std::string name() const;
+	// this receiver's name, the last name in its pathname
+	
+    const std::string& pathname() const
+	// this receiver's full name
+	{ return pathname_; }
+	
+    void setPathname(const std::string& newPath);
+	
+    void setPathnameAndRegister(const std::string& newPath);
+	// call setPathname() and register *this with ActionRouter
+	// assert(newPath[0] == ':')
+    
+    virtual void execute(const ossimPlanetAction& a) = 0;
+	// execute the given action
+    
+protected:
+    
+    std::string pathname_;
+	// this receiver's full name
+};
+
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetActionRouter.h b/ossimPlanet/include/ossimPlanet/ossimPlanetActionRouter.h
new file mode 100644
index 0000000..7536f42
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetActionRouter.h
@@ -0,0 +1,247 @@
+#ifndef ACTIONROUTER_H
+#define ACTIONROUTER_H
+
+// central router for routing Actions to all registered ActionRecievers
+
+#include <assert.h>
+#include <vector>
+#include <map>
+#include <queue>
+#include "ossimPlanetActionReceiver.h"
+#include "ossimPlanetNetworkConnection.h"
+#include "ossimPlanetExport.h"
+#include "ossimPlanetRefBlock.h"
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+#include <OpenThreads/Block>
+
+class OSSIMPLANET_DLL ossimPlanetActionRouterThreadQueue : virtual public osg::Referenced,
+                                                           public OpenThreads::Thread
+{
+public:
+   ossimPlanetActionRouterThreadQueue()
+      :theDoneFlag(false),
+      theBlock(new ossimPlanetRefBlock)
+   {
+      
+   }
+   virtual ~ossimPlanetActionRouterThreadQueue()
+   {
+      if(isRunning())
+      {
+         cancel();
+      }
+   }
+   
+   virtual void run()
+   {
+      while(!theDoneFlag)
+      {
+         theBlock->block();
+         /**
+			* if we were released from the cancel then return immediately
+          */ 
+         if(theDoneFlag) return;
+         osg::ref_ptr<ossimPlanetAction> a;
+         theActionQueueMutex.lock();
+         if(!theActionQueue.empty())
+         {
+            a = theActionQueue.front();
+            theActionQueue.pop();
+         }
+			theActionQueueMutex.unlock();  
+			if(a.valid())
+			{
+				a->execute();
+			}
+         updateThreadBlock();
+         OpenThreads::Thread::YieldCurrentThread();
+      }
+   }
+   virtual int cancel()
+   {
+      int result = 0;
+      
+      if( isRunning() )
+      {
+         theDoneFlag = true;
+         theBlock->release();
+         
+         while(isRunning())
+         {
+            OpenThreads::Thread::YieldCurrentThread();
+         }
+      }
+      return result;
+   }
+   void updateThreadBlock()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionQueueMutex);
+      theBlock->set(!theActionQueue.empty());
+   }
+   void setDoneFlag(bool flag)
+   {
+      theDoneFlag = flag;
+   }
+   void addAction(const ossimPlanetAction& action)
+   {
+      theActionQueueMutex.lock();
+      theActionQueue.push(action.clone());
+      theActionQueueMutex.unlock();
+      updateThreadBlock();
+   }
+protected:
+   bool     theDoneFlag;
+   osg::ref_ptr<ossimPlanetRefBlock> theBlock;
+   mutable ossimPlanetReentrantMutex    theActionQueueMutex;
+   std::queue<osg::ref_ptr<ossimPlanetAction> > theActionQueue;
+};
+
+class OSSIMPLANET_DLL ossimPlanetActionRouter : public ossimPlanetActionReceiver
+{
+public:
+   typedef std::map<std::string, ossimPlanetActionReceiver*> MapType;
+    // initialize/shutdown
+    
+	static ossimPlanetActionRouter* instance();
+	    // pointer to the lazy initialized ActionRouter singleton
+	    // assert(instance() != NULL)
+	
+	static void shutdown();
+	    // clean up the singleton
+
+        // network
+        
+        void addNetworkConnection(ossimPlanetNetworkConnection* commLink);
+            // add an external communication interface to be used
+            // require(commLink != NULL && commLink->error().empty())
+        
+        void removeNetworkConnection(const ossimString& name);
+            // remove the named external communication interface from use
+            //    NB: this routine will not call delete on the removed connection!
+        
+        ossimPlanetNetworkConnection* networkConnection(const ossimString& name) const;
+            // return the NetworkConnection with the given name or NULL if nonexistent
+        
+        // federate name
+        
+        const ossimString& federateName() const
+            // the name of this federate as seen from the network
+            { return federateName_; }
+        
+        void setFederateName(const ossimString& newName);
+            // set the network name of this federate
+            // require(!newName.empty())
+            // require(newName.find(' ', 0) <= 0)
+            // ensure(newName == federateName())
+
+        /**
+         * This will post to the thread queue the action to route and route it later
+         */ 
+        void post(const ossimPlanetAction& a);
+        
+        /**
+         * Routes the Action immediately.
+         */ 
+	void route(const ossimPlanetAction& a);
+	    // cause the action's target to execute() the Action on the local machine 
+    
+	void allRoute(const ossimPlanetAction& a);
+	    // cause the action's target to execute() the Action on
+	    //    the local machine as well as all machines in the
+	    //    distributed sim.
+	
+	void tellRoute(const ossimPlanetAction& a, const ossimString& destination);
+	    // cause the action's target to execute() the Action on
+	    //    the the destination machine
+	    // require(!destination.empty())
+	
+	void executeFile(const ossimString& filename, const ossimString& origin = ossimPlanetActionRouter::instance()->federateName());
+	    // sequentially call execute() on each Action in the file,
+	    //    with all Actions having origin as their origin.
+	
+	void executeNetworkActions();
+	    // call execute() on pending Actions on all NetworkConnections
+        
+        // ActionReceiver management
+    
+	void registerReceiver(ossimPlanetActionReceiver* r);
+	    // r should receive actions
+	    // assert(r != NULL)
+	    // assert(receiver(r->pathName()) == r)
+	
+	void unregisterReceiver(ossimPlanetActionReceiver* r);
+	    // r should no longer receive actions
+	    // assert(r != NULL)
+	    // assert(receiver(r->pathname()) != r)
+	
+	ossimPlanetActionReceiver* receiver(const ossimString& receiverPathname) const;
+	    // the object with the specified pathname
+	    // assert(result == NULL || result->pathName() == receiverPathname)
+	
+	void printReceivers();
+	    // print the list of receivers
+
+    // ActionReceiver features
+
+	void execute(const ossimPlanetAction& a);
+	    // execute the given action 
+	
+protected:
+    
+    // hide these to enforce singleton
+    ossimPlanetActionRouter();
+    ~ossimPlanetActionRouter();
+    ossimPlanetActionRouter(const ossimPlanetActionRouter &other):ossimPlanetActionReceiver(other) { assert(false);}
+    ossimPlanetActionRouter& operator=(const ossimPlanetActionRouter &) { assert(false); return *this;}
+    
+    static ossimPlanetActionRouter* instance_;
+    osg::ref_ptr<ossimPlanetActionRouterThreadQueue> theThreadQueue;
+    // our singleton instance
+    mutable ossimPlanetReentrantMutex theReceiverMutex;
+   MapType receivers_;
+    std::vector<ossimPlanetNetworkConnection*> network_;
+	// receiver name/object pairs
+    
+    ossimString federateName_;
+        // this federate's name
+    
+    void remoteRouteImplementation(const ossimPlanetAction& a, const ossimString& destination);
+	// implementation for allRoute() and tellRoute()
+
+    // STL equality predicate used to find a NetworkConnection by name
+    class NCEqualPred
+    {
+    public:
+       NCEqualPred(const ossimString& n) : targetName_(n) {}
+          const ossimString& targetName_;
+	bool operator()(const ossimPlanetNetworkConnection* i) const
+        { return i->name() == targetName_.string(); }
+    };
+};
+
+inline ossimPlanetActionRouter* ossimPlanetActionRouter::instance()
+{
+    if (instance_ == 0)
+    {
+	    instance_ = new ossimPlanetActionRouter;
+        instance_->theThreadQueue = new ossimPlanetActionRouterThreadQueue;
+        instance_->theThreadQueue->setDoneFlag(false);
+        instance_->theThreadQueue->start();
+    }
+/*     assert(instance_ != NULL); */
+    return instance_;
+}
+
+inline void ossimPlanetActionRouter::shutdown()
+{
+   if(instance_)
+   {
+      delete instance_;
+      instance_ = 0;
+   }
+}
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetAnimatedPointModel.h b/ossimPlanet/include/ossimPlanet/ossimPlanetAnimatedPointModel.h
new file mode 100644
index 0000000..208bba0
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetAnimatedPointModel.h
@@ -0,0 +1,68 @@
+#ifndef ossimPlanetAnimatedPointModel_HEADER
+#define ossimPlanetAnimatedPointModel_HEADER
+#include <ossimPlanet/ossimPlanetPointModel.h>
+#include <ossimPlanet/ossimPlanetAnimationPath.h>
+#include <osg/Geode>
+#include <osg/MatrixTransform>
+#include <osg/Geometry>
+#include <osg/LineWidth>
+#include <OpenThreads/Mutex>
+
+class OSSIMPLANET_DLL ossimPlanetAnimatedPointModel : public ossimPlanetAnnotationLayerNode 
+{
+public:
+   ossimPlanetAnimatedPointModel();
+   virtual ~ossimPlanetAnimatedPointModel();
+   void execute(const ossimPlanetAction& action);
+   void setAnimationPath(ossimPlanetAnimationPath* path);
+   void setAnimationPathColor(const osg::Vec4f& value);
+   void setAnimationPathLineThickness(ossim_float32 value);
+   void setShowPathFlag(bool flag);
+   void setShowModelFlag(bool flag);
+   void setPointModel(osg::Node* value);
+   void setTimeScale(ossim_float64 scale);
+   void setTimeOffset(ossim_float64 offset);
+   virtual void traverse(osg::NodeVisitor& nv);
+	virtual void stage();
+   
+   osg::Node*          pointModel(){return thePointModel.get();}
+   const osg::Node*    pointModel()const{return thePointModel.get();}
+   ossimPlanetAnimationPath*       animationPath(){return theAnimationPath.get();}
+   const ossimPlanetAnimationPath* animationPath()const{return theAnimationPath.get();}
+   
+protected:
+   void updateCoordinates();
+   void updateColor();
+   class OSSIMPLANET_DLL PathCallback : public osg::AnimationPathCallback
+   {
+   public:
+      PathCallback();
+      PathCallback(const PathCallback& apc,
+                   const osg::CopyOp& copyop);
+      PathCallback(osg::AnimationPath* ap,
+                   double timeOffset=0.0,
+                   double timeMultiplier=1.0);
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+   };
+   OpenThreads::Mutex                     theUpdateCoordinatesMutex;
+   OpenThreads::Mutex                     theUpdateColorMutex;
+   bool                                   theShowPathFlag;
+   bool                                   theShowModelFlag;
+   osg::Vec4f                             theAnimationPathColor;
+   ossim_float32                          theAnimationPathLineThickness;
+   osg::ref_ptr<osg::Node>                thePointModel;
+   osg::ref_ptr<ossimPlanetAnimationPath> theAnimationPath;
+
+   // need drawing for the path
+   //
+   osg::ref_ptr<osg::MatrixTransform>     thePathMatrixTransform;
+   osg::ref_ptr<osg::Vec4Array>           thePathColor;
+   osg::ref_ptr<osg::Vec3Array>           thePathVertices;
+   osg::ref_ptr<osg::LineWidth>           theLineWidth;
+   osg::ref_ptr<osg::Geode>               thePathGeode;
+   osg::ref_ptr<osg::Geometry>            thePathGeometry;
+   
+   osg::ref_ptr<PathCallback>             theAnimationPathCallback;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetAnimationPath.h b/ossimPlanet/include/ossimPlanet/ossimPlanetAnimationPath.h
new file mode 100644
index 0000000..32edfdb
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetAnimationPath.h
@@ -0,0 +1,92 @@
+//*******************************************************************
+//
+// License: MIT
+// 
+// See LICENSE.txt file in the top level directory for more details.
+//
+// Author: Garrett Potts
+//
+//*************************************************************************
+// $Id$
+#ifndef ossimPlanetAnimationPath_HEADER
+#define ossimPlanetAnimationPath_HEADER
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/AnimationPath>
+class OSSIMPLANET_DLL ossimPlanetAnimationPath : public osg::AnimationPath
+{
+public:
+   class OSSIMPLANET_DLL Tuple
+   {
+   public:
+      Tuple(const osg::Vec3d& pos,
+            const osg::Vec3d& orient,
+            const osg::Vec3d& s = osg::Vec3(1.0,1.0,1.0))
+      :thePosition(pos),
+      theOrientation(orient),
+      theScale(s)
+      {
+         
+      }
+      const osg::Vec3d& position()const{return thePosition;}
+      const osg::Vec3d& orientation()const{return theOrientation;}
+      const osg::Vec3d& scale()const{return theScale;}
+      void setPosition(const osg::Vec3d& value){thePosition = value;}
+      void setScale(const osg::Vec3d& value){theScale = value;}
+      void setOrientation(const osg::Vec3d& value){theOrientation = value;}
+      
+      osg::Vec3d thePosition;
+      osg::Vec3d theOrientation;
+      osg::Vec3d theScale;
+   };
+   
+   typedef std::map<double, Tuple> TimeTupleMap;
+   class OSSIMPLANET_DLL GeospatialPath : public osg::Referenced
+   {
+   public:
+      GeospatialPath(){}
+      bool empty()const{return theTimeTupleMap.empty();}
+      TimeTupleMap& timeTupleMap(){return theTimeTupleMap;}
+      const TimeTupleMap& timeTupleMap()const{return theTimeTupleMap;}
+      double firstTime() const { if (!theTimeTupleMap.empty()) return theTimeTupleMap.begin()->first; else return 0.0;}
+      double lastTime() const { if (!theTimeTupleMap.empty()) return theTimeTupleMap.rbegin()->first; else return 0.0;}
+      double period() const { return lastTime()-firstTime();}
+   protected:
+      TimeTupleMap theTimeTupleMap;
+   };
+   typedef std::vector<osg::Vec3d> PointList;
+   ossimPlanetAnimationPath();
+   void setGeoRefModel(ossimPlanetGeoRefModel* model){theModel = model;}
+   ossimPlanetGeoRefModel* geoRefModel(){return theModel.get();}
+   const ossimPlanetGeoRefModel* geoRefModel()const{return theModel.get();}
+   bool openAnimationPathByXmlDocument(const ossimFilename& animationFile);
+   bool setAnimationPathByXmlDocument(const ossimString& xml);
+   bool setAnimationPathByXmlDocument(std::istream& xmlStream);
+   bool openAnimationPathByXmlNode(const ossimFilename& animationFile);
+   bool setAnimationPathByXmlNode(const ossimString& xml);
+   bool setAnimationPathByXmlNode(std::istream& xmlStream);
+   
+   bool setAnimationPathByXmlNode(ossimRefPtr<ossimXmlNode> node);
+   ossimXmlNode* saveXml()const;
+   GeospatialPath* geospatialPath(){return thePath.get();};
+   const GeospatialPath* geospatialPath()const{return thePath.get();};
+   void setGeospatialPath(GeospatialPath* path);
+   virtual bool getInterpolatedControlPoint(double time,
+                                            osg::AnimationPath::ControlPoint& controlPoint) const;
+   
+   bool generateWorldCoordinates(PointList& worldPoints)const;
+   bool generateModelCoordinates(PointList& modelPoints)const;
+   
+   bool moveToLocationLatLon(const osg::Vec2d& llh);
+   
+   
+protected:
+   virtual double adjustTime(double time)const;
+   void lsrMatrix(osg::Matrixd& result,
+                  const Tuple& tuple)const;
+   osg::ref_ptr<GeospatialPath>         thePath;
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+};
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayer.h
new file mode 100644
index 0000000..c1450fa
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayer.h
@@ -0,0 +1,83 @@
+#ifndef ossimPlanetAnnotationLayer_HEADER
+#define ossimPlanetAnnotationLayer_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetRefBlock.h>
+#include <osg/Image>
+#include <osg/Texture2D>
+#include <osg/ref_ptr>
+#include <osgText/Font>
+#include <ossimPlanet/ossimPlanetAnnotationLayerNode.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <queue>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationLayer : public ossimPlanetLayer
+{
+public:
+	class Stager : public ossimPlanetOperation
+		{
+		public:
+			Stager(ossimPlanetAnnotationLayerNode* node)
+			:theNode(node)
+			{
+				
+			}
+			virtual void run()
+			{
+				if(theNode.valid())
+				{
+					theNode->stage();
+				}
+			}
+		protected:
+			osg::ref_ptr<ossimPlanetAnnotationLayerNode> theNode;
+		};
+	ossimPlanetAnnotationLayer();
+	virtual ~ossimPlanetAnnotationLayer();
+   virtual osg::Object* cloneType() const { return new ossimPlanetAnnotationLayer(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanetAnnotationLayer *>(obj)!=0; }
+   virtual const char* className() const { return "ossimPlanetAnnotationLayer"; } 
+   virtual const char* libraryName() const { return "ossimPlanet"; }
+   virtual void traverse(osg::NodeVisitor& nv);
+	virtual void execute(const ossimPlanetAction& a);
+	osg::ref_ptr<osg::Texture2D> defaultIconTexture()
+	{
+		return theDefaultIconTexture;
+	}
+   osg::ref_ptr<osgText::Font> defaultFont()
+	{
+		return theDefaultFont.get();
+	}
+   const osg::ref_ptr<osgText::Font> defaultFont()const
+	{
+		return theDefaultFont.get();
+	}
+   void removeByNameAndId(const ossimString& name, const ossimString& id);
+   
+	osg::ref_ptr<ossimPlanetOperationThreadQueue> stagingThreadQueue()
+	{
+		return theStagingThreadQueue;
+	}
+	osg::ref_ptr<ossimPlanetOperationThreadQueue> updateThreadQueue()
+	{
+		return theUpdateThreadQueue;
+	}
+protected:
+   virtual void nodeAdded(osg::Node* node);
+	virtual void nodeRemoved(osg::Node* node);
+	virtual void needsRemoving(osg::Node* node);
+	osg::ref_ptr<osgText::Font> theDefaultFont;
+	osg::ref_ptr<osg::Image> theDefaultIconImage;
+	osg::ref_ptr<osg::Texture2D> theDefaultIconTexture;
+	mutable ossimPlanetReentrantMutex theGraphMutex;
+   
+	
+	ossimPlanetReentrantMutex theNodesToRemoveListMutex;
+	NodeListType theNodesToRemoveList;
+	
+   osg::ref_ptr<ossimPlanetOperationThreadQueue> theStagingThreadQueue;
+   osg::ref_ptr<ossimPlanetOperationThreadQueue> theUpdateThreadQueue;
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayerNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayerNode.h
new file mode 100644
index 0000000..b4f018a
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetAnnotationLayerNode.h
@@ -0,0 +1,453 @@
+#ifndef ossimPlanetAnnotationLayerNode_HEADER
+#define ossimPlanetAnnotationLayerNode_HEADER
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <ossim/base/ossimNotify.h>
+#include <osg/ref_ptr>
+#include <osg/Geometry>
+#include <osg/Vec3d>
+#include <osg/ClusterCullingCallback>
+#include <osg/Matrixd>
+#include <osg/Geode>
+#include <osg/MatrixTransform>
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetFadeText.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <osg/Vec4d>
+enum ossimPlanetAnnotationColorMode
+{
+   ossimPlanetAnnotationColorMode_NORMAL = 0,
+   ossimPlanetAnnotationColorMode_RANDOM = 1
+};
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationExpireTime : public osg::Referenced
+{
+public:
+   ossimPlanetAnnotationExpireTime(){}
+   virtual void initTimeStamp()=0;
+   virtual bool hasExpired()const=0;
+};
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationColorStyle : public osg::Referenced
+{
+public:
+   ossimPlanetAnnotationColorStyle()
+   :theColor(1.0,1.0,1.0,1.0),
+   theColorMode(ossimPlanetAnnotationColorMode_NORMAL)
+   {
+   }
+   void setColor(const osg::Vec4d& color)
+   {
+      theColor = color;
+   }
+   const osg::Vec4d& color()const
+   {
+      return theColor;
+   }
+   void color(osg::Vec4d& value)const
+   {
+      value = theColor;
+   }
+   void setColorMode(ossimPlanetAnnotationColorMode mode)
+   {
+      theColorMode = mode;
+   }
+   ossimPlanetAnnotationColorMode colorMode()const
+   {
+      return theColorMode;
+   }
+protected:
+   osg::Vec4d theColor;
+   ossimPlanetAnnotationColorMode theColorMode;
+};
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationLabelStyle : public ossimPlanetAnnotationColorStyle
+{
+public:
+   ossimPlanetAnnotationLabelStyle()
+   :theScale(1.0)
+   {
+   }
+   void setScale(ossim_float64 scale)
+   {
+      theScale = scale;
+   }
+   ossim_float64 scale()const
+   {
+      return theScale;
+   }
+protected:
+   ossim_float64 theScale;
+};
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationExpireDuration : public ossimPlanetAnnotationExpireTime
+{
+public:
+   ossimPlanetAnnotationExpireDuration(double duration=0.0)
+   :theDuration(duration),
+   theUnit(ossimPlanetTimeUnit_SECONDS),
+   theInitialStamp(osg::Timer::instance()->tick())
+   {
+   }
+   double duration()const
+   {
+      return theDuration;
+   }
+   void setDuration(double value)
+   {
+      theDuration = value;
+   }
+   ossimPlanetTimeUnit unit()const
+   {
+      return theUnit;
+   }
+   virtual void initTimeStamp()
+   {
+      theInitialStamp = osg::Timer::instance()->tick();
+   }
+   virtual bool hasExpired()const
+   {
+      return osg::Timer::instance()->delta_s(theInitialStamp, osg::Timer::instance()->tick())>=theDuration;
+   }
+protected:
+   double theDuration;
+   ossimPlanetTimeUnit theUnit;
+   osg::Timer_t theInitialStamp;
+};
+class ossimPlanetAnnotationGroupNode;
+class OSSIMPLANET_DLL ossimPlanetAnnotationLayerNode : public ossimPlanetNode
+{
+public:
+	enum DirtyBit
+	{
+		NOT_DIRTY = 0,
+		COORDINATE_DIRTY = 1,
+		COLOR_DIRTY      = 2,
+		LABEL_DIRTY      = 4,
+		ICON_DIRTY       = 8,
+		MATRIX_DIRTY     = 16,
+      GENERIC_DIRTY    = 32,
+		ALL_DIRTY        = (COORDINATE_DIRTY|COLOR_DIRTY|ICON_DIRTY|LABEL_DIRTY|MATRIX_DIRTY|GENERIC_DIRTY)
+	};
+	ossimPlanetAnnotationLayerNode();
+	
+	/**
+	 * Xml formatted custom data.
+	 */
+	void setExtendedData(const ossimString& value);
+   virtual void execute(const ossimPlanetAction& action);
+	virtual void update(){};
+	virtual void stage()
+   {		
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theStagedFlag = true;
+   }
+	virtual bool isStaged()const
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		return theStagedFlag;
+	}
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+	void setStagedFlag(bool flag)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		theStagedFlag = flag;
+	}
+   virtual ossimPlanetAnnotationGroupNode* asAnnotationGroup()
+   {
+      return 0;
+   }
+   virtual const ossimPlanetAnnotationGroupNode* asAnnotationGroup()const
+   {
+      return 0;
+   }
+	void setDirtyBits(DirtyBit bit)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		theDirtyBit = bit;
+	}
+	void setDirtyBit(DirtyBit bit)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		theDirtyBit |= (ossim_uint32)bit;
+	}
+	void clearDirtyBit(DirtyBit bit)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		
+		theDirtyBit &= (~((ossim_uint32)bit));
+	}
+	bool isDirtyBitSet(DirtyBit bit)const
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		return (theDirtyBit & bit);
+	}
+protected:
+	mutable ossimPlanetReentrantMutex thePropertyMutex;
+	ossim_uint32 theDirtyBit;
+	bool theStagedFlag;
+   osg::ref_ptr<ossimPlanetAnnotationExpireTime> theExpireTime;
+};
+
+class ossimPlanetAnnotationPoint;
+class OSSIMPLANET_DLL ossimPlanetAnnotationGeometry : public osg::Referenced
+{
+public:
+	ossimPlanetAnnotationGeometry()
+	:theExtrudeFlag(false),
+	theAltitudeMode(ossimPlanetAltitudeMode_CLAMP_TO_GROUND)
+	{
+		
+	}
+	virtual void setExtrudeFlag(bool flag)
+	{
+		theExtrudeFlag = flag;
+	}
+	virtual void setAltitudeMode(ossimPlanetAltitudeMode mode)
+	{
+		theAltitudeMode = mode;
+	}
+	ossimPlanetAltitudeMode altitudeMode()const
+	{
+		return theAltitudeMode;
+	}
+	virtual ossimPlanetAnnotationPoint* asPoint()
+	{
+		return 0;
+	}
+	virtual const ossimPlanetAnnotationPoint* asPoint()const
+	{
+		return 0;
+	}
+	virtual void traverse( osg::NodeVisitor& nv)=0;
+protected:
+	bool                    theExtrudeFlag;
+	ossimPlanetAltitudeMode theAltitudeMode;
+};
+
+class ossimPlanetAnnotationPoint: public ossimPlanetAnnotationGeometry
+{
+public:
+	ossimPlanetAnnotationPoint(const osg::Vec3d& coordinate=osg::Vec3d(0.0,0.0,0.0))
+	:theCoordinate(coordinate)
+	{
+		
+	}
+	virtual ossimPlanetAnnotationPoint* asPoint()
+	{
+		return this;
+	}
+	virtual const ossimPlanetAnnotationPoint* asPoint()const
+	{
+		return this;
+	}
+	void setCoordinate(const osg::Vec3d& coordinate)
+	{
+		theCoordinate = coordinate;
+	}
+	const osg::Vec3d& coordinate()const
+	{
+		return theCoordinate;
+	}
+	void setModelCoordinate(const osg::Vec3d& modelCoordinate)
+	{
+		theModelCoordinate = modelCoordinate;
+	}
+	const osg::Vec3d& modelCoordinate()const
+	{
+		return theModelCoordinate;
+	}
+	virtual void traverse( osg::NodeVisitor& nv)
+	{
+		if(theMatrixTransform.valid())
+		{
+			theMatrixTransform->accept(nv);
+		}
+	}
+	void setMatrixTransform(osg::ref_ptr<osg::MatrixTransform> m)
+	{
+		theMatrixTransform = m;
+	}
+	osg::ref_ptr<osg::MatrixTransform> matrixTransform()
+	{
+		return theMatrixTransform;
+	}
+	const osg::ref_ptr<osg::MatrixTransform> matrixTransform()const
+	{
+		return theMatrixTransform;
+	}
+	
+protected:
+	osg::Vec3d theCoordinate;
+	osg::Vec3d theModelCoordinate;
+	osg::Vec3d theLocalCoordinate;
+	osg::ref_ptr<osg::MatrixTransform> theMatrixTransform;
+};
+
+
+class ossimPlanetAnnotationGroupNode : public ossimPlanetAnnotationLayerNode
+{
+public:
+   ossimPlanetAnnotationGroupNode()
+   {
+      
+   }
+   virtual ossimPlanetAnnotationGroupNode* asAnnotationGroup()
+   {
+      return this;
+   }
+   virtual const ossimPlanetAnnotationGroupNode* asAnnotationGroup()const
+   {
+      return this;
+   }
+   virtual bool addChild( Node *child )
+   {
+      ossimPlanetAnnotationLayerNode* annotationLayerNode = dynamic_cast<ossimPlanetAnnotationLayerNode*>(child);
+      if(annotationLayerNode)
+      {
+         return ossimPlanetAnnotationLayerNode::addChild(annotationLayerNode);
+      }
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetAnnotationGroupNode::addChild: Only annotation layer nodes allowed to be added to an Annotation group\n";
+      return false;
+   }
+	virtual void stage()
+   {
+      
+   }
+	virtual void update()
+   {
+      
+   }
+protected:
+   
+};
+class ossimPlanetAnnotationTextGeode : public osg::Geode
+{
+public:
+	ossimPlanetAnnotationTextGeode(ossimPlanetNode* layerNode,
+											 ossimPlanetFadeText* text)
+	:theLayerNode(layerNode),
+	theText(text)
+	{
+		if(text)
+		{
+			addDrawable(text);
+		}
+		setUpdateCallback(new ossimPlanetTraverseCallback);
+		setCullCallback(new ossimPlanetTraverseCallback);
+      getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);
+      getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
+		
+	}
+	virtual void traverse(osg::NodeVisitor& nv) 
+	{
+      switch(nv.getVisitorType())
+      {
+         case osg::NodeVisitor::UPDATE_VISITOR:
+         {
+            theSavedOpacity = theText->opacity();
+            break;
+         }
+         default:
+         {
+            break;
+         }
+      }
+		osg::Geode::traverse(nv);
+      if(theSavedOpacity!=theText->opacity())
+      {
+         if(theLayerNode)
+         {
+            theLayerNode->setRedrawFlag(true);
+         }
+      }
+	}
+	
+protected:
+   ossim_float64 theSavedOpacity;
+	ossimPlanetNode* theLayerNode;
+	ossimPlanetFadeText* theText;
+};
+
+class OSSIMPLANET_DLL ossimPlanetAnnotationPlacemark : public ossimPlanetAnnotationLayerNode
+{
+public:
+	class PlacemarkUpdater;
+	friend class PlacemarkUpdater;
+	ossimPlanetAnnotationPlacemark();
+	ossimPlanetAnnotationPlacemark(const osg::Vec3d& location,
+                                  ossimPlanetAltitudeMode altitudeMode,
+                                  const ossimString& nameStr = "",
+                                  const ossimString& descriptionStr = "");
+	virtual void execute(const ossimPlanetAction& action);
+	virtual void stage();
+	virtual void update();
+	virtual void traverse(osg::NodeVisitor& nv);
+	virtual void setName(const ossimString& name);
+	const osg::ref_ptr<ossimPlanetFadeText> label()const
+	{
+		return theLabel.get();
+	}
+	osg::ref_ptr<ossimPlanetFadeText> label()
+	{
+	  return theLabel.get();
+	}
+  const osg::ref_ptr<ossimPlanetAnnotationTextGeode> labelGeode()const
+  {
+    return theLabelGeode.get();
+  }
+  osg::ref_ptr<ossimPlanetAnnotationTextGeode> labelGeode()
+  {
+    return theLabelGeode.get();
+  }
+	const osg::ref_ptr<ossimPlanetAnnotationGeometry> geometry()const
+	{
+		return theGeometry;
+	}
+	osg::ref_ptr<osg::ClusterCullingCallback> clusterCull()
+	{
+		return theClusterCull;
+	}
+	const osg::ref_ptr<osg::ClusterCullingCallback> clusterCull()const
+	{
+		return theClusterCull;
+	}
+	
+	const osg::ref_ptr<ossimPlanetAnnotationLabelStyle> labelStyle()const
+	{
+		return theLabelStyle;
+	}
+	osg::ref_ptr<ossimPlanetAnnotationGeometry> geometry()
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGeometryMutex);
+		return theGeometry;
+	}
+	void setGeometry(osg::ref_ptr<ossimPlanetAnnotationGeometry> geom)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGeometryMutex);
+		theGeometry = geom;
+	}
+	virtual void setEnableFlag(bool flag)
+	{
+		if(enableFlag()!=flag)
+		{
+			if(theLabel.valid())
+			{
+				theLabel->setOpacity(0.0);
+			}
+		}
+		ossimPlanetAnnotationLayerNode::setEnableFlag(flag);
+	}
+protected:
+   mutable ossimPlanetReentrantMutex theUpdateMutex;
+	osg::ref_ptr<osg::ClusterCullingCallback> theClusterCull;
+	osg::ref_ptr<ossimPlanetAnnotationTextGeode> theLabelGeode;
+	mutable ossimPlanetReentrantMutex theGeometryMutex;
+	osg::ref_ptr<ossimPlanetAnnotationGeometry> theGeometry;
+   osg::ref_ptr<ossimPlanetFadeText> theLabel;
+	
+   osg::ref_ptr<ossimPlanetAnnotationLabelStyle> theLabelStyle;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetApi.h b/ossimPlanet/include/ossimPlanet/ossimPlanetApi.h
new file mode 100644
index 0000000..d4619d6
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetApi.h
@@ -0,0 +1,770 @@
+#ifndef ossimPlanetViewApi_HEADER
+#define ossimPlanetViewApi_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimConstants.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+   /**
+    * ossimPlanet_StatePtr is the main pointer.  All API calls will manpulate this state pointer.  
+    * It will hold the planet layers, views, manipulators, ... etc. ossimPlanet_PlanetPtr is the native pointer
+    * to a Planet Object.  The ossimPlanet_LayerPtr is the native pointer to a Planet layer.     * 
+    */
+   typedef void*         ossimPlanet_StatePtr;
+   typedef void*         ossimPlanet_PlanetPtr;
+   typedef void*         ossimPlanet_LayerPtr;
+   typedef ossim_int64   ossimPlanet_IndexType;
+   typedef ossim_uint64  ossimPlanet_SizeType;
+   typedef const char*   ossimPlanet_ConstStringType;
+   typedef char*         ossimPlanet_StringType;
+   
+   /**
+    * The context type determines how much you want the API to manage and handle.  There
+    * are 3 ways you probably would like to use the library.  
+    * 
+    * - ossimPlanet_VIEWER_CONTEXT option is typical of a full command line application that all 
+    *   you are concerned about is scripting and running a full screen or windowed planet.  This
+    *   will interface into osg::Viewer.  
+    * - ossimPlanet_NOVIEWER_CONTEXT option is used to embed  the scenegraph and bridge view parameters.
+    *   There are 2 situations when you want to do this and both require that you create your own GL context and manage it.
+    *   The first situation is if Planet is the drawable and you are in a GUI environment that creates a Gl context for you.
+    *   you just make it current and then draw the planet and use the API to bridge view parameters and manipulate layers. 
+    *   The second situation is if you have a full GL application that you wrote and all you want to do is embed the planet
+    *   as a drawable then use this context.
+    * - ossimPlanet_PLANET_ONLY_CONTEXT option is used when you are wanting to use the API only to interface into the manipulation of the planet layers.
+    *   Typically this is done if you have your own OpenSceneGraph and your own View and gl context.  We will give you native access to
+    *   root planet class.
+    */
+   enum ossimPlanet_ContextType
+   {
+      ossimPlanet_NOVIEWER_CONTEXT    = 0,
+      ossimPlanet_PLANET_ONLY_CONTEXT = 1,
+      ossimPlanet_VIEWER_CONTEXT      = 2
+   };
+   enum ossimPlanet_BOOL
+   {
+      ossimPlanet_FALSE = 0,
+      ossimPlanet_TRUE  = 1
+   };
+ 
+   enum ossimPlanetFragShaderType
+   {
+      ossimPlanet_NO_SHADER = 0,
+      ossimPlanet_TOP,
+      ossimPlanet_REFERENCE,
+      ossimPlanet_OPACITY,
+      ossimPlanet_HORIZONTAL_SWIPE,
+      ossimPlanet_VERTICAL_SWIPE,
+      ossimPlanet_BOX_SWIPE,
+      ossimPlanet_CIRCLE_SWIPE,
+      ossimPlanet_ABSOLUTE_DIFFERENCE,
+      ossimPlanet_FALSE_COLOR_REPLACEMENT
+   };
+   
+#  define ossimPlanet_INVALID_INDEX ((ossimPlanet_IndexType)-1) 
+   /******************************** Setup and Initialization API *****************************/
+   
+   /**
+    * Add the passed in path to OpenSceneGraph's Library path.  This will be used mainly for finding OpenSceneGraph
+    * plugins.  If this needs to be setup it should be done before you call ossimPlanet_init and start adding layers
+    * to planet.
+    *
+    * @param path Path to add to the Library search path.
+    * @param insertFrontFlag Inserts the path to the front of the search path list if its ossimPlanet_TRUE and
+    *                        appends to the end otherwise.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addOpenSceneGraphLibraryPath(ossimPlanet_ConstStringType path,
+                                                                 ossimPlanet_BOOL insertFrontFlag);
+   
+   /**
+    * Adds the passed in path to OpenSceneGraph's data path.  This allows one to give relative path naming to 
+    * data that is loaded.  For example:  if you have a font called arial.ttf and it's located in /fonts then you can add
+    * /fonts to the search path and you can load a font by just the name "arial.ttf".  The /fonts will be prepended.  If 
+    * this needs to be setup it should be done before you call ossimPlanet_init and start adding layers to planet.
+    *
+    * @param path Path to add to the Data search path.
+    * @param insertFrontFlag Inserts the path to the front of the search path list if its ossimPlanet_TRUE and
+    *                        appends to the end otherwise.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addOpenSceneGraphDataPath(ossimPlanet_ConstStringType path,
+                                                              ossimPlanet_BOOL insertFrontFlag);
+   
+   /**
+    * Loads an ossim preference file.
+    *
+    * @param preferenceFile The preference file to load.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_loadOssimPreferenceFile(ossimPlanet_ConstStringType preferenceFile);
+   
+   /**
+    * This is a utility call that allows one to set preference variables directly.  This will allow one to
+    * modify preference variables.  If this needs to be setup it should be done before you call ossimPlanet_init 
+    * and start adding layers to planet.
+    *
+    * @param name The name of the preference variable.
+    * @param value The value of the preference variable.
+    */ 
+   OSSIMPLANET_DLL void ossimPlanet_setOssimPreferenceNameValue(ossimPlanet_ConstStringType name,
+                                                                ossimPlanet_ConstStringType value);
+   
+   /**
+    * Adds an ossim core plugin.  If this is a directory then all files in the directoy that are plugins are added
+    *
+    * @param path Path to add to the OSSIM Plugin search path.
+    * @param insertFrontFlag Inserts the path to the front of the search path list if its ossimPlanet_TRUE and
+    *                        appends to the end otherwise.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addOssimPlugin(ossimPlanet_ConstStringType path,
+                                                   ossimPlanet_BOOL insertFrontFlag);
+   
+  
+   /**
+    * Add elevation to the OSSIM core system.
+    *
+    * @param path Path to add to the Elevation.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addOssimElevation(ossimPlanet_ConstStringType path);
+   
+   /**
+    *
+    * Elevation data is typically relative to mean sea level.  The geoid grids will be used to shift the Mean Sea Level
+    * to ellipsoidal heights. 
+    * 
+    * @param path Path to add to the Geoid search path.
+    * @param byteOrder.  Most of the goid grids don't have Endian indication.  You can download little endian or big endian type geoid grids
+    *        The basic 96 grid that comes with OSSIM egm96.grd is a big endian byte order.  You can downlod from 
+    * @param insertFrontFlag Inserts the path to the front of the search path list if its ossimPlanet_TRUE and
+    *                        appends to the end otherwise.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addGeoid(ossimPlanet_ConstStringType path,
+                                             ossimByteOrder byteOrder,
+                                            ossimPlanet_BOOL insertFrontFlag);
+	
+   /**
+    * Used to initialize the system.  This is typically called one time.  It initializes internal registries.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_init();
+   
+   /**
+    * Allows one to init by passing command line arguments.  This is typically used by command line
+    * applications.
+    *
+    * @param argc A pointer to an integer.
+    * @param argv Pointer to the argv.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_initWithArgs(int* argc, char** argv[]);
+   
+   /**
+    * Allows you to set the trace on and off for various classes in the system.  This is in the format of a 
+    * regular expression.  Some of the special characters found in the regular expression are:
+    * ^        Matches at beginning of a line
+    * $        Matches at end of a line
+    * .        Matches any single character
+    * [ ]      Matches any character(s) inside the brackets
+    * [^ ]     Matches any character(s) not inside the brackets
+    * -        Matches any character in range on either side of a dash
+    * *        Matches preceding pattern zero or more times
+    * +        Matches preceding pattern one or more times
+    * ?        Matches preceding pattern zero or once only
+    *
+    * ()       Saves a matched expression and uses it in a  later match
+    *
+    * If you want to trace all
+    * ossim classes then do :
+    * 
+    * ossimPlanet_setTracePattern("ossim.*");
+    *
+    * @param pattern A regular expression pattern to describe what to trace.  
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setTracePattern(ossimPlanet_ConstStringType pattern);
+   
+   /**
+    * This is called to do any cleanup of the library.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_finalize();
+   
+   /**
+    * Gives access to a microsecond sleep.
+    *
+    * @param microSeconds Specify how many microseconds to sleep.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_microSecondSleep(ossimPlanet_SizeType microSeconds);
+   
+   /**
+    * Gives access to a millisecond sleep.
+    *
+    * @param milliSeconds Specify how many milli seconds to sleep.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_milliSecondSleep(ossimPlanet_SizeType milliSeconds);
+
+   /**
+    * Gives access to a seconds sleep.
+    *
+    * @param seconds Specify how many seconds to sleep.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_secondSleep(ossimPlanet_SizeType seconds);
+
+   /********************** DO STATE INTERFACE ***********************/
+   
+   /**
+    * This will return an internal class that contains all the needed 
+    * state information.  It will basically create a self contained manager for
+    * view, layers, manipulator, ... etc.
+    *
+    * Note: Currently there can be only 1 view assigned per state. Once the state is called you can create view, layers 
+    *       add manipulator, ...etc for the given state.
+    *
+    * @param contextType This specifies the type of context you would like to create.  @see ossimPlanet_contextType.
+    *
+    * @return State handle;
+    */
+   OSSIMPLANET_DLL ossimPlanet_StatePtr ossimPlanet_newState(ossimPlanet_ContextType type);
+       
+   /**
+    * ossimPlanet_deleteState()
+    *
+    * Will delete the passed in state.  
+    *
+    * @param state This is the state to delete.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_deleteState(ossimPlanet_StatePtr state);
+   
+   
+   /********************* ACCESS TO NATIVE POINTERS *********************/
+   
+   /**
+    * This will be mainly used in native C++ that wants to add callbacks to get direct feedback from 
+    * various actions that occur within planet.  People should be able to do reinterpret_cast<ossimPlanet*> on
+    * the native pointer returned.
+    *
+    * @return Returns the address of the ossimPlanet object.  
+    */
+   OSSIMPLANET_DLL ossimPlanet_PlanetPtr ossimPlanet_getNativePlanetPointer(ossimPlanet_StatePtr state);
+   
+   /************************************ API FOR THE VIEW ********************************/
+  
+   /**
+    *  Allows one to disable the texture shaders.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLandFragShaderType(ossimPlanet_StatePtr state,
+                                                          ossimPlanetFragShaderType type);
+   
+   /**
+    *
+    * When initially setting up your scene it is not set to the root Scene view or viewer.  This only has affect in ossimPlanet_NOVIEWER_CONTEXT
+    * and ossimPlanet_VIEWER_CONTEXT where you have a Scene managers and manipulators.
+    *
+    * @param state The state to modify.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setSceneDataToView(ossimPlanet_StatePtr state);
+   
+   /**
+    *  Only support ossimPlanetManipulator type for now.
+    *
+    * @param state The state to modify.
+    * @param typeName The type of Manipulator to create.  The current one is ossimPlanetManipulator.
+    * @param receverPathName The recever path name given to this object.  We can pass setup commands to it.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewManipulator(ossimPlanet_StatePtr state,
+                                                       ossimPlanet_ConstStringType typeName,
+                                                       ossimPlanet_ConstStringType receiverPathName);
+   /**
+    * This will assume that a Gl context is created and that the Viewport is set.  It will use 
+    * GL calls to get the current Viewport values and set to the internal structures associated 
+    * with the passed in state.  This is used when you are manipulating the Viewport through
+    * GL calls.  If this is the case then you can call this before rendering the planet.
+    *
+    * @param state State to modify.
+    */
+   OSSIMPLANET_DLL void setViewportToCurrentGlSettings(ossimPlanet_StatePtr state);
+   
+   
+   /**
+    * This will assume that a Gl context is created and that the Projection Matrix is set.  It will use 
+    * GL calls to get the current Projection Matrix values and set to the internal structures associated 
+    * with the passed in state.  This is used when you are manipulating the Projection Matrix through
+    * GL calls.  If this is the case then you can call this before rendering the planet.
+    *
+    * @param state State to modify.
+    */
+   OSSIMPLANET_DLL void setProjectionMatrixToCurrentGlSettings(ossimPlanet_StatePtr state);
+   
+   /**
+    * This will assume that a Gl context is created and that the ModelView Matrix is set.  It will use 
+    * GL calls to get the current ModelView Matrix values and set to the internal structures associated 
+    * with the passed in state.  This is used when you are manipulating the ModelView Matrix through
+    * GL calls.  If this is the case then you can call this before rendering the planet.
+    *
+    * @param state State to modify.
+    */
+   OSSIMPLANET_DLL void setModelViewMatrixToCurrentGlSettings(ossimPlanet_StatePtr state);
+   
+   
+   /***** DO PROJECTION MATRIX INTERFACE *****/
+   
+   /**
+    * This allows one to set the perspective.
+    *
+    * @param state The state to modify.
+    * @param fov Field of view in degrees.
+    * @param aspectRatio The aspect ratio of the view.
+    * @param near The near plane distance.
+    * @param far The far plane distance.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrixAsPerspective(ossimPlanet_StatePtr state,
+                                                                     double fov,
+                                                                     double aspectRatio,
+                                                                     double near, 
+                                                                     double far);
+   
+   /**
+    * This is identical to the glFrustum settings.
+    *
+    * @param state The state to modify.
+    * @param left Left value.
+    * @param right Right value.
+    * @param bottom Bottom value.
+    * @param top Top value.
+    * @param zNear zNear value.
+    * @param zFar zFar value.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrixAsFrustum(ossimPlanet_StatePtr state,
+                                                                 double left, double right,
+                                                                 double bottom, double top,
+                                                                 double zNear, double zFar);
+   
+   /**
+    * This is identical to the glOrtho call and creates and orthographic projection.
+    *
+    * @param state The state to modify.
+    * @param left Left value.
+    * @param right Right value.
+    * @param bottom Bottom value.
+    * @param top Top value.
+    * @param zNear zNear value.
+    * @param zFar zFar value.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrixAsOrtho(ossimPlanet_StatePtr state,
+                                                               double left, double right,
+                                                               double bottom, double top,
+                                                               double zNear, double zFar);
+   
+   /** 
+    * 
+    * Set to a 2D orthographic projection. See OpenGL glOrtho2D documentation for further details.
+    * @param state The state to modify.
+    * @param left Left value.
+    * @param right Right value.
+    * @param bottom Bottom value.
+    * @param top Top value.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrixAsOrtho2D(ossimPlanet_StatePtr state,
+                                                                 double left, double right,
+                                                                 double bottom, double top);
+   /**
+    * This assumes a 4x4 array or 16 consecutive values.  The values are stored row ordered.  
+    * This means that the first 4 values are for the first row and the second four values are
+    * for the second row, ... etc.
+    *
+    * @param m The array of 16 values
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrixAsRowOrderedArray(ossimPlanet_StatePtr state,
+                                                                         double* m);
+   
+   /**
+    * This will set the projection matrix to the passed in values.  Note m00 - m03 identifies the
+    * first row of the matrix, then the next is the second row, ... etc.
+    *
+    * @param state The state to modify the view orientation matrix.
+    * @param m00 row 0 col 0
+    * @param m01 row 0 col 1
+    * @param m02 row 0 col 2
+    * @param m03 row 0 col 3
+    * @param m10 row 1 col 0
+    * @param m11 row 1 col 1
+    * @param m12 row 1 col 2
+    * @param m13 row 1 col 3
+    * @param m20 row 2 col 0
+    * @param m21 row 2 col 1
+    * @param m22 row 2 col 2
+    * @param m23 row 2 col 3
+    * @param m30 row 3 col 0
+    * @param m31 row 3 col 1
+    * @param m32 row 3 col 2
+    * @param m33 row 3 col 3
+    *
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setProjectionMatrix(ossimPlanet_StatePtr state,
+                                                        double m00, double m01, double m02, double m03,
+                                                        double m10, double m11, double m12, double m13,
+                                                        double m20, double m21, double m22, double m23,
+                                                        double m30, double m31, double m32, double m33);
+   /****** NOW EXPOSE ORIENTATION MATRIX DEFINITIONS ****/
+   
+   /**
+    * This allows one to pass in the lat, lon height and the euler angles to define the view matrix.
+    * The Euler angles are relative to the tangent plane at the given lat lon position.  Note this is
+    * for the camera and the Z-Axis is the plumb/Nadir axis.  This means that a heading, pitch and roll of all
+    * 0 degrees will have the eye looking straight down.
+    *
+    * Note: all lat lon values are assumed to be relative to the WGS84 ellipsoid.  
+    *
+    * @param state The state to modify.
+    * @param lat The latitude of the view camera in degrees.
+    * @param lon The longitude of the view camera in degrees.
+    * @param height The height of the view camera in meters relative to the WGS84 ellipsoid.
+    * @param heading The heading of the view camera in degrees.
+    * @param pitch  The pitch of the view camera in degrees.
+    * @param roll  The roll of the view camera in degrees.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewMatrixAsLlhHprRelativeTangent(ossimPlanet_StatePtr state,
+                                                                         double lat,
+                                                                         double lon,
+                                                                         double height,
+                                                                         double heading,
+                                                                         double pitch,
+                                                                         double roll);
+   
+   /**
+    * This allows one to pass in the lat, lon height and the euler angles to define the view matrix.
+    * The Euler angles are not relative to the tangent plane at the given lat lon position but instead the unit axis is used.  
+    * for the camera and the Z-Axis is the plumb/Nadir axis.  
+    *
+    * Note: all lat lon values are assumed to be relative to the WGS84 ellipsoid.  
+    *
+    * @param state The state to modify.
+    * @param lat The latitude of the view camera in degrees.
+    * @param lon The longitude of the view camera in degrees.
+    * @param height The height of the view camera in meters relative to the WGS84 ellipsoid.
+    * @param heading The heading of the view camera in degrees.
+    * @param pitch  The pitch of the view camera in degrees.
+    * @param roll  The roll of the view camera in degrees.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewMatrixAsLlhHprAbsolute(ossimPlanet_StatePtr state,
+                                                                  double lat,
+                                                                  double lon,
+                                                                  double height,
+                                                                  double heading,
+                                                                  double pitch,
+                                                                  double roll);
+   
+   /**
+    * This Will set the matrix as a row ordered array.
+    *
+    * @param state The state to modify the view orientation matrix.
+    * @param m Row ordered view matrix.
+    *
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewMatrixAsRowOrderedArray(ossimPlanet_StatePtr state,
+                                                                   const double *m);
+   
+   /**
+    * This will set the matrix to the passed in values.  Note m00 - m03 identifies the
+    * first row of the matrix, then the next is the second row, ... etc.
+    *
+    * @param state The state to modify the view orientation matrix.
+    * @param m00 row 0 col 0
+    * @param m01 row 0 col 1
+    * @param m02 row 0 col 2
+    * @param m03 row 0 col 3
+    * @param m10 row 1 col 0
+    * @param m11 row 1 col 1
+    * @param m12 row 1 col 2
+    * @param m13 row 1 col 3
+    * @param m20 row 2 col 0
+    * @param m21 row 2 col 1
+    * @param m22 row 2 col 2
+    * @param m23 row 2 col 3
+    * @param m30 row 3 col 0
+    * @param m31 row 3 col 1
+    * @param m32 row 3 col 2
+    * @param m33 row 3 col 3
+    *
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewMatrix(ossimPlanet_StatePtr state,
+                                                  double m00, double m01, double m02, double m03,
+                                                  double m10, double m11, double m12, double m13,
+                                                  double m20, double m21, double m22, double m23,
+                                                  double m30, double m31, double m32, double m33);
+   
+   /*** NOW EXPOSE VIEWPORT DEFINITIONS *******/
+   
+   /**
+    * ossimPlanet_setViewport
+    *
+    * Sets the viewport of the for the view of the passed in state.
+    *
+    * @param state  The state to modify the viewport definitions.
+    * @param x The x location in pixels of the viewport.  Typically 0
+    * @param y The y location in pixels of the viewport.  Typically 0
+    * @param w The width in pixels of the viewport.
+    * @param h The height in pixels of the viewport.
+    *
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewport(ossimPlanet_StatePtr state,
+                                                int x, 
+                                                int y, 
+                                                int w, 
+                                                int h);
+   
+   /**
+    * Sets the color used to clear the viewport area.
+    *
+    * @param state  The state information to modify the clear color.
+    * @param red The red component of the clear color.
+    * @param green The green component of the clear color.
+    * @param blue The blue component of the clear color.
+    * @param alpha The alpha component of the clear color.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setViewportClearColor(ossimPlanet_StatePtr state,
+                                                          float red,
+                                                          float green,
+                                                          float blue,
+                                                          float alpha);
+   
+   
+   /**
+    * Save the gl attributes.  This is mainly only used if you are embedding in
+    * a non Open scenegraph application and you need the state attributes to be preserved
+    * after calling the ossimPlanet_frame.
+    *
+    * This will preserve the Matrix stacks (MODEL, TEXTURE, PROJECTION) and the
+    * GL_ALL_ATTRIB_BITS.  After the call to frame then you should call
+    * ossimPlanet_popState();
+    */
+   OSSIMPLANET_DLL void ossimPlanet_pushState();
+   
+   /**
+    * @see ossimPlanet_pushState();
+    */
+   OSSIMPLANET_DLL void ossimPlanet_popState();
+   
+   OSSIMPLANET_DLL void ossimPlanet_setStateReceiverPathName(ossimPlanet_StatePtr state,
+															 ossimPlanet_ConstStringType path);
+   OSSIMPLANET_DLL void ossimPlanet_setPlanetReceiverPathName(ossimPlanet_StatePtr state,
+															  ossimPlanet_ConstStringType path);
+   
+   
+   /*************************** General Layer interfaces *********************/
+   
+   /**
+    * This adds a layer to planet. the layer type is used in the ossimPlanetLayerRegistry 
+    * to construct a layer of the passed layerType.  The receiverName is used to set the receiver
+    * name of the layer created so action messages can be routed to it.
+    *
+    * @param state The state to modify.
+    * @param layerType Layer type name to add.  This is used by the layer registry to construct a layer
+    *                  specified by the layerType.
+    * @param name This is the name you wish to give the layer.
+    * @param id This is the id for the layer.
+    * @param description This is the description for the layer.
+    * @param receiverPathName Allows one to create a receiver name for the layer.  This is the target name for
+    *                         Action messages(@see ossimPlanet_routeAction).
+    *
+    * @return The natve pointer to the layer added.
+    */
+   OSSIMPLANET_DLL ossimPlanet_LayerPtr ossimPlanet_addLayer(ossimPlanet_StatePtr state,
+                                                             ossimPlanet_ConstStringType layerType,
+                                                             ossimPlanet_ConstStringType name,
+                                                             ossimPlanet_ConstStringType id,
+                                                             ossimPlanet_ConstStringType description,
+                                                             ossimPlanet_ConstStringType receiverPathName);
+   
+   OSSIMPLANET_DLL void ossimPlanet_removeLayerGivenPtr(ossimPlanet_StatePtr state,
+                                                        ossimPlanet_LayerPtr layerPtr);
+   /**
+    * @param state The state to use.
+    *
+    * @return Returns the number of layers defined in planet for the give state.
+    */
+   OSSIMPLANET_DLL ossimPlanet_SizeType ossimPlanet_getNumberOfLayers(ossimPlanet_StatePtr state);
+
+   /**
+    * @param state The state to use.
+    * @param layerPtr The layer pointer to use.
+    *
+    * @return Returns the index of the layer given it's pointer.
+    */
+   OSSIMPLANET_DLL ossimPlanet_IndexType ossimPlanet_getIndexOfLayerGivenPtr(ossimPlanet_StatePtr state,
+                                                                             ossimPlanet_LayerPtr layerPtr);
+   
+   /**
+    * @param state The state to use.
+    * @param idx The index number of the layer to return.
+    *
+    * @return Returns the layer pointer given an index.  NULL or 0 is returned if idx is out of range.
+    */
+   OSSIMPLANET_DLL ossimPlanet_LayerPtr ossimPlanet_getLayerGivenIndex(ossimPlanet_StatePtr state,
+                                                                       ossimPlanet_IndexType idx);
+   
+   /**
+    * @param state The state to use.
+    * @param idThe id of the layer to search.
+    *
+    * @return Returns the layer pointer identified by id.
+    */
+   OSSIMPLANET_DLL ossimPlanet_LayerPtr ossimPlanet_getLayerGivenId(ossimPlanet_StatePtr state,
+                                                                    ossimPlanet_ConstStringType id);
+   /**
+    * @param state The state to use.
+    * @param idx The index of the layer to access.
+    *
+    * @return The layer name for the layer at the specified index.
+    */
+   OSSIMPLANET_DLL ossimPlanet_ConstStringType ossimPlanet_getLayerName(ossimPlanet_LayerPtr layer);
+   
+   /**
+    * @param layer The layer to set.
+    * @param name The name to set the layer to.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLayerName(ossimPlanet_LayerPtr layer,
+                                                 ossimPlanet_ConstStringType name);   
+   
+   /**
+    * @param state The state to use.
+    * @param idx The index of the layer to access.
+    *
+    * @return The layer name for the layer at the specified index.
+    */
+   OSSIMPLANET_DLL ossimPlanet_ConstStringType ossimPlanet_getLayerId(ossimPlanet_LayerPtr layer);
+      
+   /**
+    * @param layer The layer to set.
+    * @param id The id to set the layer to.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLayerId(ossimPlanet_LayerPtr layer,
+                                               ossimPlanet_ConstStringType id);
+
+   /**
+    * @param state The state to use.
+    * @param idx The index of the layer to access.
+    *
+    * @return The layer description for the layer at the specified index.
+    */
+   OSSIMPLANET_DLL ossimPlanet_ConstStringType ossimPlanet_getLayerDescription(ossimPlanet_LayerPtr layer);
+
+   /**
+    * @param layer The layer to set.
+    * @param description The description to set the layer to.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLayerDescription(ossimPlanet_LayerPtr layer,
+                                                        ossimPlanet_ConstStringType description);
+
+   /**
+    * @param state The state to use.
+    * @param idx The index of the layer to access.
+    *
+    * @return The recever path name for the layer at the specified index.
+    */
+   OSSIMPLANET_DLL ossimPlanet_ConstStringType ossimPlanet_getLayerReceverPathName(ossimPlanet_LayerPtr layer);
+      
+   /**
+    * @param layer The layer to set.
+    * @param receiverName The description to set the layer to.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLayerReceiverPathName(ossimPlanet_LayerPtr layer,
+                                                             ossimPlanet_ConstStringType receiverPathName);
+   
+   
+   /**
+    * @param state The state to use.
+    * @param idx The index of the layer to access.
+    *
+    * @return The layer enable flag for the layer at the specified index.
+    */
+   OSSIMPLANET_DLL ossimPlanet_BOOL ossimPlanet_getLayerEnableFlag(ossimPlanet_LayerPtr layer);
+      
+   /**
+    *
+    * @param layer The layer to set.
+    * @param flag This specifies if the layer is enabled or not.  A value of ossimPlanet_TRUE will
+    *             enable the layer and a value of ossimPlanet_FALSE will disable the layer.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_setLayerEnableFlag(ossimPlanet_LayerPtr layer,
+                                                       ossimPlanet_BOOL flag);
+
+	
+	/**
+	 *
+	 * Adds an image to the reference layer. Note:  location is currently for local data and cann be a directory or
+	 * a file.  We currently do not recurse directories so if the passed in file is a directory no subdirectories will be scanned.
+	 *
+	 */
+	OSSIMPLANET_DLL void ossimPlanet_addImageToReceiver(ossimPlanet_ConstStringType location,
+																		 ossimPlanet_ConstStringType receverName,
+																		 ossimPlanet_BOOL addInTheBackgroundFlag);
+   
+   /**
+    * This is for legacy KWL support and is only for texture layers.
+    */
+   OSSIMPLANET_DLL void ossimPlanet_addTextureLayersFromKwlFile(ossimPlanet_StatePtr state,
+                                                                const char* kwlFile);
+   
+   /******************************* Action Routing Interface****************************/
+   /**
+    * This will use ossimPlanet's Action router to route the message to the destination.  For example: lets say
+    * we have a receiver name as foo and we have an action called Set.
+    * 
+    * ossimPlanet_routeActionForm1("<Set target=":foo">.....</Set>);
+    *
+    * This will route a action "Set" to the receiver "foo".
+    *
+    * @param action
+    */
+   OSSIMPLANET_DLL void ossimPlanet_executeXmlAction(ossimPlanet_ConstStringType completeAction);
+   
+   /**
+    * Will post the action to a threaded action queue so it executes in the background.
+    */ 
+   OSSIMPLANET_DLL void ossimPlanet_postXmlAction(ossimPlanet_ConstStringType completeAction);
+   
+   /**************************** Rendering Interfaces ***********************************/
+   
+   /**
+    * This is the main rendering step.  This will render 1 frame.     
+    * @param state The state to modify.
+    *
+    * @return Returns ossimPlanet_TRUE if the render frame can continue again or
+    *                 ossimPlanet_FALSE if it was canceled.  This is typically only important for ossimPlanet_VIEWER type
+    *                 context.
+    */
+   OSSIMPLANET_DLL ossimPlanet_BOOL ossimPlanet_renderFrame(ossimPlanet_StatePtr state);
+   
+   /**
+    * This is the main rendering step.  This will render 1 frame and preserve the state.  This will 
+    * call osismPlanet_pushState before rendering and ossimPlanet_popState after rendering and will preserve
+    * gl attributes, View, Projection and Texture matrices.
+    *
+    * @param state The state to modify.
+    *
+    * @return Returns ossimPlanet_TRUE if the render frame can continue again or
+    *                 ossimPlanet_FALSE if it was canceled.  This is typically only important for ossimPlanet_VIEWER type
+    *                 context.
+    */
+   OSSIMPLANET_DLL ossimPlanet_BOOL ossimPlanet_renderFramePreserveState(ossimPlanet_StatePtr state);
+   
+   /**
+    * This is used determine if another frame is required to be rendered.  Call this before
+    * you call ossimPlanet_Frame.  
+    *
+    * <pre>
+    *    if(ossimPlanet_needsRendering(state))
+    *    {
+    *        ossimPlanet_renderFrame(state);
+    *    }
+    * </pre>
+    *
+    * @param state The state to modify.
+    * @return ossimPlanet_TRUE if needs to continue rendering or ossimPlanet_FALSE if
+    *         no more rendering is required.
+    */
+   OSSIMPLANET_DLL ossimPlanet_BOOL ossimPlanet_needsRendering(ossimPlanet_StatePtr state);
+   
+	
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // end ossimPlanetViewApi_HEADER
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetArchive.h b/ossimPlanet/include/ossimPlanet/ossimPlanetArchive.h
new file mode 100755
index 0000000..59ee4dd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetArchive.h
@@ -0,0 +1,37 @@
+
+#ifndef ossimPlanetArchive_HEADER
+#define ossimPlanetArchive_HEADER
+
+#include <vector>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimFilename.h>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+#include <ossimPlanet/ossimPlanetArchiveMapping.h>
+
+
+class OSSIMPLANET_DLL ossimPlanetArchive : public osg::Referenced
+{
+private:
+	bool useArchiveMapping;
+	std::vector<ossimPlanetArchiveMapping> mappingList;
+	mutable ossimPlanetReentrantMutex theArchiveMutex;
+
+public:
+	ossimPlanetArchive();
+protected:
+	~ossimPlanetArchive();
+
+public:
+	void addMapping(ossimPlanetArchiveMapping &mapping);
+	void removeMapping(ossimPlanetArchiveMapping &mapping);
+	ossimFilename matchPath(const ossimFilename &filename);
+	ossimFilename convertToDirectory(ossimFilename &filename);
+	void setArchiveMappingEnabledFlag(bool enabled = false);
+	bool archiveMappingEnabled();
+	std::vector<ossimPlanetArchiveMapping> getMappingList();
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetArchiveMapping.h b/ossimPlanet/include/ossimPlanet/ossimPlanetArchiveMapping.h
new file mode 100755
index 0000000..aca687f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetArchiveMapping.h
@@ -0,0 +1,29 @@
+#ifndef ossimPlanetArchiveMapping_HEADER
+#define ossimPlanetArchiveMapping_HEADER
+
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimPreferences.h>
+#include <ossim/base/ossimFilename.h>
+
+
+class OSSIMPLANET_DLL ossimPlanetArchiveMapping
+{
+private:
+	ossimFilename src;
+	ossimFilename dest;
+
+public:
+	ossimPlanetArchiveMapping();
+	ossimPlanetArchiveMapping(const ossimFilename &source, const ossimFilename &destination);
+	~ossimPlanetArchiveMapping();
+
+	ossimFilename getSource();
+	void setSource(const ossimFilename &source);
+
+	ossimFilename getDestination();
+	void setDestination(const ossimFilename &destination);
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetBillboardIcon.h b/ossimPlanet/include/ossimPlanet/ossimPlanetBillboardIcon.h
new file mode 100644
index 0000000..de00845
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetBillboardIcon.h
@@ -0,0 +1,75 @@
+#ifndef ossimPlanetBillboardIcon_HEADER
+#define ossimPlanetBillboardIcon_HEADER
+#include <osg/Node>
+#include <osg/NodeVisitor>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <osg/Billboard>
+#include <osg/MatrixTransform>
+
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossimPlanet/ossimPlanetIconGeom.h>
+
+class ossimPlanetBillboardIcon :public osg::Node
+{
+public:
+   class ossimPlanetBillboardIconUpdateCallback : public osg::NodeCallback
+   {
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+         {
+            ossimPlanetBillboardIcon* n = dynamic_cast<ossimPlanetBillboardIcon*>(node);
+            if(n)
+            {
+               n->traverse(*nv);
+            }
+         }
+   };
+   /**
+    * The normalization factor is used to scale the bill board into the units of
+    * the scenegraph. This is done by the billboard transform.  This transform is wrapped
+    * with a fudge factor transform to make sure that the icon stays on top of the terrain
+    */ 
+   ossimPlanetBillboardIcon(double objectGroundSize = 50000.0/OSSIMPLANET_WGS_84_RADIUS_EQUATOR);
+   void setGroundObjectSize(double groundSize);
+   void setIcon(osg::ref_ptr<osg::Image> img);
+   void setIcon(osg::ref_ptr<osg::Texture2D> img);
+   osg::ref_ptr<ossimPlanetIconGeom> getGeom()
+   {
+      return theGeom.get();
+   }
+   void setGeom(osg::ref_ptr<ossimPlanetIconGeom> geom);
+   /**
+    * This turns on auto scaling so that the full texture size is reached once
+    * the gsd is approximately the passed in meters per pixel.
+    */ 
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual osg::BoundingSphere computeBound() const;
+   bool isCulled()const;
+   void setMinPixelSize(ossim_uint32 size)
+   {
+      theMinPixelSize = size;
+   }
+   void setMaxPixelSize(ossim_uint32 size)
+   {
+      theMaxPixelSize = size;
+   }
+protected:
+   osg::Billboard*                    theBillboard;
+   osg::ref_ptr<ossimPlanetIconGeom>  theGeom;
+   osg::ref_ptr<osg::MatrixTransform> theBillboardTransform;
+   osg::ref_ptr<osg::MatrixTransform> theFudgeFactorTransform;
+   osg::ref_ptr<osg::MatrixTransform> theLabelTransform;
+   osg::Matrixd                       theFudgeFactorMatrix;
+   bool                               theNeedsUpdateFlag;
+   bool                               theCulledFlag;
+   ossim_uint32                       theMinPixelSize;
+   ossim_uint32                       theMaxPixelSize;
+   ossim_uint32                       thePixelWidth;
+   ossim_uint32                       thePixelHeight;
+   osg::Vec3d                         theTranslate;
+   
+   bool                               theScaleFactorChangedFlag;
+   ossim_float64                      theScaleFactor;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetBoundingBox.h b/ossimPlanet/include/ossimPlanet/ossimPlanetBoundingBox.h
new file mode 100644
index 0000000..518b269
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetBoundingBox.h
@@ -0,0 +1,234 @@
+#ifndef ossimPlanetBoundingBox_HEADER
+#define ossimPlanetBoundingBox_HEADER
+#include <osg/Referenced>
+#include <osg/Polytope>
+#include <osg/CullSettings>
+#include <vector>
+#include <ossim/base/ossimCommon.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/mkUtils.h>
+
+class OSSIMPLANET_DLL ossimPlanetBoundingBox : public osg::Referenced
+{
+public:
+   ossimPlanetBoundingBox()
+   :osg::Referenced()
+   {
+      theCorners[0] = osg::Vec3d(0,0,0);
+      theCorners[1] = osg::Vec3d(0,0,0);
+      theCorners[2] = osg::Vec3d(0,0,0);
+      theCorners[3] = osg::Vec3d(0,0,0);
+      theCorners[4] = osg::Vec3d(0,0,0);
+      theCorners[5] = osg::Vec3d(0,0,0);
+      theCorners[6] = osg::Vec3d(0,0,0);
+      theCorners[7] = osg::Vec3d(0,0,0);
+
+      theCenter = osg::Vec3d(0,0,0);
+      theRadius = 0.0;
+   }
+   ossimPlanetBoundingBox(const osg::Vec3d &p0,
+                          const osg::Vec3d &p1,
+                          const osg::Vec3d &p2,
+                          const osg::Vec3d &p3,
+                          const osg::Vec3d &p4,
+                          const osg::Vec3d &p5,
+                          const osg::Vec3d &p6,
+                          const osg::Vec3d &p7)
+   :osg::Referenced()
+   {
+      theCorners[0] = p0;
+      theCorners[1] = p1;
+      theCorners[2] = p2;
+      theCorners[3] = p3;
+      theCorners[4] = p4;
+      theCorners[5] = p5;
+      theCorners[6] = p6;
+      theCorners[7] = p7;
+
+      theCenter = (p0+p1+p2+p3+p4+p5+p6+p7)*(1.0/8.0);
+      computeRadius();
+   }
+   ossimPlanetBoundingBox(const ossimPlanetBoundingBox& src)
+   :osg::Referenced()
+   {
+      theCorners[0] = src.theCorners[0];
+      theCorners[1] = src.theCorners[1];
+      theCorners[2] = src.theCorners[2];
+      theCorners[3] = src.theCorners[3];
+      theCorners[4] = src.theCorners[4];
+      theCorners[5] = src.theCorners[5];
+      theCorners[6] = src.theCorners[6];
+      theCorners[7] = src.theCorners[7];
+      theCenter     = src.theCenter;
+      theRadius      = src.theRadius;
+   }
+   // note the distance is a 2d vector.  the distance[0]
+   // is the distance to extrude the points in the direction
+   // of the normal and the distance[1] is the distance along
+   // the reflected direction.
+   //
+   void extrude(const osg::Vec3d &p0,
+                const osg::Vec3d &p1,
+                const osg::Vec3d &p2,
+                const osg::Vec3d &p3,
+                const osg::Vec3d &outwardNormal,
+                const osg::Vec2d &distance)
+   {
+      theCorners[0] = p0 + outwardNormal*distance[1];
+      theCorners[1] = p1 + outwardNormal*distance[1];
+      theCorners[2] = p2 + outwardNormal*distance[1];
+      theCorners[3] = p3 + outwardNormal*distance[1];
+
+      theCorners[4] = p0 + outwardNormal*distance[0];
+      theCorners[5] = p1 + outwardNormal*distance[0];
+      theCorners[6] = p2 + outwardNormal*distance[0];
+      theCorners[7] = p3 + outwardNormal*distance[0];
+      theCenter = (theCorners[0]+
+                   theCorners[1]+
+                   theCorners[2]+
+                   theCorners[3]+
+                   theCorners[4]+
+                   theCorners[5]+
+                   theCorners[6]+
+                   theCorners[7])*(1.0/8.0);
+      computeRadius();
+   }
+   void extrude(const osg::Vec3d& center,
+                const osg::Vec3d& up,
+                const osg::Vec3d& right,
+                const osg::Vec3d& normal,
+                const osg::Vec2d& distanceUp,
+                const osg::Vec2d& distanceRight,
+                const osg::Vec2d& distanceNormal)
+   {
+      // along negative normal
+      //ul, ur, lr, ll
+      theCorners[0] = center+((up*distanceUp[0])+
+                              (right*distanceRight[1]) +
+                              (normal*distanceNormal[1]));
+      theCorners[1] = center+((up*distanceUp[0])+
+                              (right*distanceRight[0]) +
+                              (normal*distanceNormal[1]));
+      theCorners[2] = center+((up*distanceUp[1])+
+                              (right*distanceRight[0]) +
+                              (normal*distanceNormal[1]));
+      
+      theCorners[3] = center+((up*distanceUp[1])+
+                              (right*distanceRight[1]) +
+                              (normal*distanceNormal[1]));
+      // along positive normal
+      //ul, ur, lr, ll
+      theCorners[4] = center+((up*distanceUp[0])+
+                              (right*distanceRight[1]) +
+                              (normal*distanceNormal[0]));
+      theCorners[5] = center+((up*distanceUp[0])+
+                              (right*distanceRight[0]) +
+                              (normal*distanceNormal[0]));
+      theCorners[6] = center+((up*distanceUp[1])+
+                              (right*distanceRight[0]) +
+                              (normal*distanceNormal[0]));
+      
+      theCorners[7] = center+((up*distanceUp[1])+
+                              (right*distanceRight[1]) +
+                              (normal*distanceNormal[0]));
+      theCenter = (theCorners[0]+
+                   theCorners[1]+
+                   theCorners[2]+
+                   theCorners[3]+
+                   theCorners[4]+
+                   theCorners[5]+
+                   theCorners[6]+
+                   theCorners[7])*(1.0/8.0);
+      computeRadius();
+   }
+
+   
+   osg::Vec3d& operator[](unsigned int idx)
+   {
+      return theCorners[idx];
+   }
+   const osg::Vec3d& operator[](unsigned int idx)const
+   {
+      return theCorners[idx];
+   }
+   bool intersects(const osg::Polytope& frustum)const;
+   bool isInFront(const osg::Vec3d& eye,
+                  const osg::Vec3d& direction)const;
+   
+   
+   void transform(const osg::Matrix& m)
+   {
+      theCorners[0] = theCorners[0]*m,
+      theCorners[1] = theCorners[1]*m,
+      theCorners[2] = theCorners[2]*m,
+      theCorners[3] = theCorners[3]*m,
+      theCorners[4] = theCorners[4]*m,
+      theCorners[5] = theCorners[5]*m,
+      theCorners[6] = theCorners[6]*m,
+      theCorners[7] = theCorners[7]*m,
+      theCenter = (theCorners[0]+
+                   theCorners[1]+
+                   theCorners[2]+
+                   theCorners[3]+
+                   theCorners[4]+
+                   theCorners[5]+
+                   theCorners[6]+
+                   theCorners[7])*(1.0/8.0);
+      theTopCenter = (theCorners[0]+
+                      theCorners[1]+
+                      theCorners[2]+
+                      theCorners[3])*.25;
+      theBottomCenter = (theCorners[4]+
+                         theCorners[5]+
+                         theCorners[6]+
+                         theCorners[7])*.25;
+      computeRadius();
+      
+   }
+   void setCenter(const osg::Vec3d& center)
+   {
+      theCenter = center;
+   }
+   const osg::Vec3d& center()const
+   {
+      return theCenter;
+   }
+   double radius()const
+   {
+      return theRadius;
+   }
+   double groundRadius()const
+   {
+      return theGroundRadius;
+   }
+protected:
+   void computeRadius()
+   {
+      theRadius = ossim::max((theCorners[0]-theCenter).length(),
+                           ossim::max((theCorners[1]-theCenter).length(),
+                                    ossim::max((theCorners[2]-theCenter).length(),
+                                             ossim::max((theCorners[3]-theCenter).length(),
+                                                      ossim::max((theCorners[4]-theCenter).length(),
+                                                               ossim::max((theCorners[5]-theCenter).length(),
+                                                                        ossim::max((theCorners[6]-theCenter).length(),
+                                                                                 (theCorners[7]-theCenter).length())))))));
+      // this is a crude ground radius estimate that just takes the top
+      // Quad and Bottom quad and see who has the largest radius and takes the Max of that
+      theGroundRadius = ossim::max((theCorners[0]-theTopCenter).length(),
+                           ossim::max((theCorners[1]-theTopCenter).length(),
+                                    ossim::max((theCorners[2]-theTopCenter).length(),
+                                             ossim::max((theCorners[3]-theTopCenter).length(),
+                                                      ossim::max((theCorners[4]-theBottomCenter).length(),
+                                                               ossim::max((theCorners[5]-theBottomCenter).length(),
+                                                                        ossim::max((theCorners[6]-theBottomCenter).length(),
+                                                                                 (theCorners[7]-theBottomCenter).length())))))));
+   }
+   osg::Vec3d theCorners[8];
+   osg::Vec3d theCenter;
+   osg::Vec3d theTopCenter;
+   osg::Vec3d theBottomCenter;
+   double theRadius;
+   double theGroundRadius;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCache.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCache.h
new file mode 100644
index 0000000..cc406f6
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCache.h
@@ -0,0 +1,178 @@
+#ifndef ossimPlanetCache_HEADER
+#define ossimPlanetCache_HEADER
+#include <osg/Referenced>
+#include <osg/Timer>
+#include <OpenThreads/ReentrantMutex>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <ossimPlanet/ossimPlanetTerrainTileId.h>
+#include <ossim/base/ossimKeywordlist.h>
+
+#include <map>
+
+class OSSIMPLANET_DLL ossimPlanetImageCache : public osg::Referenced
+{
+public:
+   struct TileInfo
+   {
+      osg::Timer_t                   theTimeStamp;
+      osg::ref_ptr<ossimPlanetImage> theImage;
+   };
+   ossimPlanetImageCache()
+   :theCurrentCacheSize(0),
+   theMinCacheSize(0),
+   theMaxCacheSize(0),
+   theEnabledFlag(true)
+   {
+      
+   }
+   virtual ~ossimPlanetImageCache()
+   {
+   }
+   void setEnabledFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      theEnabledFlag = flag;
+   }
+   bool enabledFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return theEnabledFlag;
+   }
+   virtual void clean() = 0;
+   virtual void shrink()=0;
+   virtual void addOrUpdate(ossimPlanetImage* image)=0;
+   virtual ossimPlanetImage* get(const ossimPlanetTerrainTileId& id)=0;
+   virtual bool hasImage(const ossimPlanetTerrainTileId& id)const=0;
+
+  void setMinMaxCacheSizeInBytes(ossim_int64 minSize, ossim_int64 maxSize)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      theMinCacheSize = minSize<maxSize?minSize:maxSize;
+      theMaxCacheSize = minSize>maxSize?minSize:maxSize;
+   }
+   void setMinMaxCacheSizeInMegaBytes(ossim_int64 minSize, ossim_int64 maxSize)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      theMinCacheSize = minSize<maxSize?minSize:maxSize;
+      theMaxCacheSize = minSize>maxSize?minSize:maxSize;
+      theMinCacheSize *= static_cast<ossim_int64>(1024*1024);
+      theMaxCacheSize *= static_cast<ossim_int64>(1024*1024);
+   }
+   void setMinMaxCacheSizeInGigaBytes(ossim_int64 minSize, ossim_int64 maxSize)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      theMinCacheSize = minSize<maxSize?minSize:maxSize;
+      theMaxCacheSize = minSize>maxSize?minSize:maxSize;
+      theMinCacheSize *= static_cast<ossim_int64>(1024*1024*1024);
+      theMaxCacheSize *= static_cast<ossim_int64>(1024*1024*1024);
+   }
+   ossim_int64 cacheSizeInBytes()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return theCurrentCacheSize;
+   }
+   ossim_int64 maxCacheSizeInBytes()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return theMaxCacheSize;
+   }
+   ossim_int64 minCacheSizeInBytes()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return theMinCacheSize;
+   }
+   bool exceedsMaxCacheSize()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return (theCurrentCacheSize>theMaxCacheSize);
+   }
+   bool exceedsMinCacheSize()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return (theCurrentCacheSize>theMinCacheSize);
+   }
+
+protected:
+   mutable OpenThreads::Mutex theMutex;
+   ossim_int64 theCurrentCacheSize;
+   ossim_int64 theMinCacheSize;
+   ossim_int64 theMaxCacheSize;
+   bool theEnabledFlag;
+};
+
+class OSSIMPLANET_DLL ossimPlanetMemoryImageCache : public ossimPlanetImageCache
+{
+public:
+   typedef std::map<ossimPlanetTerrainTileId, TileInfo> TileMap;
+   ossimPlanetMemoryImageCache()
+   :ossimPlanetImageCache()
+   {
+   }
+   virtual void clean()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      theCurrentCacheSize = 0;
+      theTileCache.clear();
+   }
+   virtual void shrink();
+   virtual void addOrUpdate(ossimPlanetImage* image);
+   virtual ossimPlanetImage* get(const ossimPlanetTerrainTileId& id);
+   bool hasImage(const ossimPlanetTerrainTileId& id)const;
+
+protected:
+   TileMap theTileCache;
+
+};
+
+class OSSIMPLANET_DLL ossimPlanetDiskImageCache : public ossimPlanetImageCache
+{
+public:
+    enum OutputType
+    {
+      DISK_CACHE_RAW = 0,
+      DISK_CACHE_JPEG
+    };
+    ossimPlanetDiskImageCache();
+    bool openDirectory(const ossimFilename& file, bool createIfNotExistsFlag=true);
+    virtual void clean();
+    virtual void shrink();
+    virtual void addOrUpdate(ossimPlanetImage* image);
+    virtual ossimPlanetImage* get(const ossimPlanetTerrainTileId& id);
+    bool hasImage(const ossimPlanetTerrainTileId& id)const;
+protected:
+    ossimFilename buildTileFile(const ossimPlanetTerrainTileId& id)const;
+    ossimFilename m_directory;
+    ossimFilename m_indexFile;
+    ossimKeywordlist m_indexFileKwl;
+    OutputType       m_outputType;
+};
+
+class OSSIMPLANET_DLL ossimPlanetImageCacheShrinkOperation : public ossimPlanetOperation
+{
+public:
+   ossimPlanetImageCacheShrinkOperation()
+   :theCache(0)
+   {
+   }
+   virtual ~ossimPlanetImageCacheShrinkOperation()
+   {
+      theCache = 0;
+   }
+   void setCache(ossimPlanetImageCache* value)
+   {
+      theCache = value;
+   }
+   virtual void run()
+   {
+      if(theCache.valid())
+      {
+         theCache->shrink();
+      }
+   }
+protected:
+   osg::ref_ptr<ossimPlanetImageCache> theCache;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCacheTextureLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCacheTextureLayer.h
new file mode 100644
index 0000000..9ca8807
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCacheTextureLayer.h
@@ -0,0 +1,79 @@
+#ifndef ossimPlanetCacheTextureLayer_HEADER
+#define ossimPlanetCacheTextureLayer_HEADER
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetCache.h>
+
+class OSSIMPLANET_DLL ossimPlanetCacheTextureLayer : public ossimPlanetTextureLayer
+{
+public:
+    ossimPlanetCacheTextureLayer();
+    ossimPlanetCacheTextureLayer(const ossimPlanetCacheTextureLayer& src);
+    virtual ossimPlanetTextureLayer* dup()const;
+    virtual ossimPlanetTextureLayer* dupType()const;
+    virtual ossimString getClassName()const;
+    virtual ossimPlanetTextureLayerStateCode updateExtents();
+    virtual void updateStats()const;
+    void setTextureLayer(ossimPlanetTextureLayer* layer);
+    void setCache(ossimPlanetImageCache* cache);
+
+
+    virtual bool hasTexture(ossim_uint32 width,
+                            ossim_uint32 height,
+                            const ossimPlanetTerrainTileId& tileId,
+                            const ossimPlanetGrid& theGrid);
+
+    virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                      ossim_uint32 height,
+                                                      const ossimPlanetTerrainTileId& tileId,
+                                                      const ossimPlanetGrid& theGrid,
+                                                      ossim_int32 padding=0);
+     virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                      ossim_uint64 row,
+                                                      ossim_uint64 col,
+                                                      const ossimPlanetGridUtility& utility);
+
+     virtual const osg::ref_ptr<ossimPlanetLookAt> getLookAt()const;
+     virtual void setLookAt(osg::ref_ptr<ossimPlanetLookAt> lookAt);
+
+     virtual void getDateRange(ossimDate& minDate,
+                               ossimDate& maxDate)const;
+     /**
+      * Approximate length in meters of the hypotneus.  Just uses the getExtents
+      * and ten approximates a meter gsd from the degree bounds.
+      */
+     virtual double getApproximateHypotneusLength()const;
+
+     /**
+      * Will return the center lat lon and the approximate hypotneus length in meters.
+      */
+     virtual void getCenterLatLonLength(double& centerLat,
+                                        double& centerLon,
+                                        double& length)const;
+     virtual void setEnableFlag(bool flag);
+     virtual void setFilterType(const ossimString& filterType);
+     virtual void getMetadata(ossimRefPtr<ossimXmlNode> metadata)const;
+     virtual ossimRefPtr<ossimXmlNode> saveXml(bool recurseFlag=true)const;
+     virtual bool loadXml(ossimRefPtr<ossimXmlNode> node);
+     virtual void resetLookAt();
+
+      virtual ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                       bool recurseFlag=false);
+      virtual const ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                             bool recurseFlag=false)const;
+
+      virtual ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                            const ossimString& layerId);
+      virtual const ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                                  const ossimString& layerId)const;
+
+      virtual ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                     bool recurseFlag=false);
+      virtual const ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                           bool recurseFlag=false)const;
+protected:
+    osg::ref_ptr<ossimPlanetTextureLayer> m_textureLayer;
+    osg::ref_ptr<ossimPlanetImageCache>   m_cache;
+
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCallback.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCallback.h
new file mode 100644
index 0000000..cdb64d7
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCallback.h
@@ -0,0 +1,110 @@
+#ifndef ossimPlanetCallback_HEADER
+#define ossimPlanetCallback_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <OpenThreads/ScopedLock>
+#include <vector>
+class  OSSIMPLANET_DLL ossimPlanetCallback : public osg::Referenced
+{
+public:
+   ossimPlanetCallback()
+   :theEnableFlag(true)
+   {}
+   void setEnableFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackMutex);
+      theEnableFlag = flag;
+   }
+   bool enableFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackMutex);
+      return theEnableFlag;
+   }
+protected:
+   mutable ossimPlanetReentrantMutex theCallbackMutex;
+   bool theEnableFlag;
+};
+
+template <class T>
+class ossimPlanetCallbackListInterface
+   {
+   public:
+      typedef std::vector<osg::ref_ptr<T> > CallbackListType;
+      ossimPlanetCallbackListInterface()
+      :theBlockCallbacksFlag(false)
+      {
+         
+      }
+      virtual ~ ossimPlanetCallbackListInterface(){}
+      virtual void addCallback(T* callback)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+         if(!hasCallbackNoMutex(callback))
+         {
+            theCallbackList.push_back(callback);
+         }
+      }
+	  virtual void addCallback(osg::ref_ptr<T> callback)
+      {
+			addCallback(callback.get());
+      }
+      virtual void removeCallback(T* callback);
+	  virtual void removeCallback(osg::ref_ptr<T> callback)
+		{
+			removeCallback(callback.get());
+		}
+      virtual void blockCallbacks(bool flag)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+         theBlockCallbacksFlag = flag;
+      }
+      bool hasCallback(const T* callback)const;
+   protected:
+      bool hasCallbackNoMutex(const T* callback)const;
+      
+      mutable ossimPlanetReentrantMutex theCallbackListMutex;
+      CallbackListType theCallbackList;
+      bool theBlockCallbacksFlag;
+      
+   };
+template <class T>
+void ossimPlanetCallbackListInterface<T>::removeCallback(T* callback)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   unsigned int idx;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx] == callback)
+      {
+         theCallbackList.erase(theCallbackList.begin() + idx);
+         break;
+      }
+   }
+}
+
+template <class T>
+bool ossimPlanetCallbackListInterface<T>::hasCallback(const T* callback)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   return hasCallbackNoMutex(callback);
+}
+
+template <class T>
+bool ossimPlanetCallbackListInterface<T>::hasCallbackNoMutex(const T* callback)const
+{
+   unsigned int idx;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx] == callback)
+      {
+         return true;
+      }
+   }
+   
+   return false;
+}
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetClientThread.h b/ossimPlanet/include/ossimPlanet/ossimPlanetClientThread.h
new file mode 100644
index 0000000..f826dc4
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetClientThread.h
@@ -0,0 +1,94 @@
+#ifndef ossimPlanetClientThread_HEADER
+#define ossimPlanetClientThread_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossimPlanet/sg_socket.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include "ossimPlanetRefBlock.h"
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/sg_socket.h>
+#include <queue>
+#include <map>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+class OSSIMPLANET_DLL ossimPlanetClientConnection : public osg::Referenced
+{
+public:
+   ossimPlanetClientConnection(SGSocket* socket,
+                               ossim_uint32 queueSize=1024);
+   ossimPlanetClientConnection();
+   virtual ~ossimPlanetClientConnection();
+   
+   ossimString getHost()const;
+   ossimString getPortString()const;
+   ossimString getPortType()const;
+   void getConnection(ossimString& host,
+                      ossimString& port,
+                      ossimString& portType);
+   bool setConnection(const ossimString& host,
+                      const ossimString& port,
+                      const ossimString& portType);
+   
+   void addMessage(const ossimString& message);
+   void sendNextMessage();
+   bool hasMessages()const;
+   void clearQueue();
+   
+   SGSocket* getSocket();
+   void setSocket(SGSocket* socket);
+
+protected:
+   ossimString popMessage();
+   mutable ossimPlanetReentrantMutex theMutex;
+   mutable ossimPlanetReentrantMutex theMessageQueueMutex;
+   SGSocket*                  theSocket;
+   ossim_uint32               theMaxQueueSize;
+   std::deque<ossimString>    theMessageQueue; 
+};
+
+class OSSIMPLANET_DLL ossimPlanetClientThread : public osg::Referenced,
+                                                public OpenThreads::Thread
+{
+
+public:
+   
+   ossimPlanetClientThread();
+   virtual ~ossimPlanetClientThread();
+   virtual void run();
+   virtual int cancel();
+
+   /**
+    * creates a conneciton and returns the id
+    */ 
+   osg::ref_ptr<ossimPlanetClientConnection> newConnection(const ossimString& host,
+                                                           const ossimString& port,
+                                                           const ossimString& portType);
+   bool setConnection(ossim_uint32 idx,
+                      const ossimString& host,
+                      const ossimString& port,
+                      const ossimString& portType);
+   
+   void removeConnection(osg::ref_ptr<ossimPlanetClientConnection> connection);
+   osg::ref_ptr<ossimPlanetClientConnection> removeConnection(ossim_uint32 idx);
+   const osg::ref_ptr<ossimPlanetClientConnection> getConnection(ossim_uint32 idx)const;
+
+   void sendMessage(ossim_uint32 idx,
+                    const ossimString& message);
+   void broadcastMessage(const ossimString& message);
+   ossim_uint32 getNumberOfConnections()const;
+
+   
+   void updateClientThreadBlock();
+protected:
+   void protectedSendMessage(ossim_uint32 idx,
+                             const ossimString& message);
+   void protectedUpdateClientThreadBlock();
+   
+   typedef std::vector<osg::ref_ptr<ossimPlanetClientConnection> > ossimPlanetClientThreadConnectionList;
+   mutable ossimPlanetReentrantMutex            theConnectionListMutex;
+   osg::ref_ptr<ossimPlanetRefBlock>  theBlock;
+   bool                                  theStartedFlag;
+   bool                                  theDoneFlag;
+   ossimPlanetClientThreadConnectionList theClientConnectionList;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCloudLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCloudLayer.h
new file mode 100644
index 0000000..e66b823
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCloudLayer.h
@@ -0,0 +1,231 @@
+#ifndef ossimPlanetCloudLayer_HEADER
+#define ossimPlanetCloudLayer_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimUnitConversionTool.h>
+#include <osg/NodeVisitor>
+#include <osg/TexMat>
+#include <osg/Geometry>
+#include <vector>
+#include <cstdlib>
+
+class OSSIMPLANET_DLL ossimPlanetCloudLayer : public ossimPlanetLayer
+{
+public:
+   typedef osg::ref_ptr<osg::Geometry> geometryPtr;
+   typedef std::vector<geometryPtr> geometryPtrArray;
+   
+   class OSSIMPLANET_DLL Patch : public ossimPlanetGrid
+   {
+   public:
+      Patch(double deltaLat=1.0, double deltaLon=1.0)
+      :ossimPlanetGrid(GEODETIC_MODEL),
+      theDeltaLat(deltaLat),
+      theDeltaLon(deltaLon)
+      {
+      }
+      virtual void getRootIds(TileIds &ids)const
+      {
+         ids.push_back(ossimPlanetTerrainTileId());
+      }
+      virtual void centerModel(const ossimPlanetTerrainTileId& /* tileId */,
+                               ModelPoint& modelPoint)
+      {
+         modelPoint = ModelPoint();
+      }
+      virtual void globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const
+      {
+         modelPoint.setX(-theDeltaLon*.5 + gridPoint.x()*theDeltaLon);
+         modelPoint.setY(-theDeltaLat*.5 + gridPoint.y()*theDeltaLat);
+         modelPoint.setZ(gridPoint.z());
+      }
+      virtual void modelToGlobalGrid(const ModelPoint& modelPoint, GridPoint& gridPoint)const
+      {
+         gridPoint.setX((modelPoint.x()+(theDeltaLon*.5))/theDeltaLon);
+         gridPoint.setY((modelPoint.y()+(theDeltaLat*.5))/theDeltaLat);
+         gridPoint.setZ(modelPoint.z());
+      }
+      virtual void widthHeightInModelSpace(const ossimPlanetTerrainTileId& /* tileId */,
+                                           osg::Vec2d& deltaXY)const
+      {
+         deltaXY[1] = theDeltaLat;
+         deltaXY[0] = theDeltaLon;
+      }
+      virtual ossim_uint32 numberOfFaces()const
+      {
+         return 1;
+      }
+      virtual bool findGridBound(ossim_uint32 face,
+                                 const ModelPoint& minPoint,
+                                 const ModelPoint& maxPoint,
+                                 GridBound& bound,
+                                 ossim_uint32 numberOfPoints=3)const
+      {
+         return false;
+      }
+      virtual bool isPolar(const ossimPlanetTerrainTileId& /* id */)const
+      {
+         return false;
+      }
+      /**
+       * 
+       */
+      virtual ossimPlanetGridUtility* newBackwardCompatableGrid(ossim_uint32 /* width */,
+                                                                ossim_uint32 /* height */)const
+      {
+         return 0;
+      }
+      
+      double theDeltaLat;
+      double theDeltaLon;
+   };
+   ossimPlanetCloudLayer();
+   virtual ~ossimPlanetCloudLayer()
+   {
+      theGeometryArray.clear();
+   }
+   void updateTexture(osg::Image* cloudTexture);
+   void updateTexture(ossim_int64 seed = 0,
+                      ossim_int32 coverage = 20,
+                      ossim_float64 sharpness = .95);
+   
+   virtual void computeMesh(double patchAltitude,
+                            ossim_uint32 patchWidth=9, 
+                            ossim_uint32 patchHeight=9, 
+                            ossim_uint32 level=3);
+   
+   /**
+    * This method allows for changing the opacity of the entire cloud layer
+    */
+   void setAlphaValue(float alpha);
+   
+   virtual void traverse(osg::NodeVisitor& nv);
+   void setHeading(ossim_float64 heading)
+   {
+      theHeading = heading;
+   }
+   /**
+    *  The speed is in units per hour.
+    */ 
+   void setSpeedPerHour(ossim_float64 speed, ossimUnitType unit=OSSIM_METERS)
+   {
+      // get it into units per second.
+      //
+      theSpeed = ossimUnitConversionTool(speed, unit).getMeters()/3600.0;
+   }
+   void setSpeedPerSecond(ossim_float64 speed, ossimUnitType unit=OSSIM_METERS)
+   {
+      // get it into units per second.
+      //
+      theSpeed = ossimUnitConversionTool(speed, unit).getMeters();
+   }
+   void setScale(ossim_float64 scale)
+   {
+      theTextureScale[0] = scale;
+      theTextureScale[1] = scale;
+      theTextureScale[2] = 1.0;
+      updateMetersPerPixelCoverage();
+   }
+   void setGrid(ossimPlanetGrid* g)
+   {
+      theGrid = g;
+   }
+   void setAutoUpdateTextureMatrixFlag(bool flag)
+   {
+      theAutoUpdateTextureMatrixFlag = flag;
+   }
+   bool autoUpdateTextureMatrixFlag()const
+   {
+      return theAutoUpdateTextureMatrixFlag;
+   }
+   void moveToLocationLatLonAltitude(const osg::Vec3d& llh);
+   
+   ossimPlanetGrid* grid()
+   {
+      return theGrid.get();
+   }
+   void setTextureMatrix(osg::TexMat* texMatrix);
+   osg::TexMat* textureMatrixAttribute()
+   {
+      return theTextureMatrixAttribute.get();
+   }
+   osg::Matrixd& textureMatrix()
+   {
+      return theTextureMatrix;
+   }
+   /**
+    *
+    */
+   void setMaxAltitudeToShowClouds(ossim_float64 maxAltitude);
+   ossim_float64 maxAltitudeToShowClouds()const;
+   
+private:
+   void init();
+   void splitTiles(ossimPlanetGrid::TileIds& tiles, ossim_uint32 levels)const;
+   void updateTextureMatrix(double timeScale=0.0);
+   void updateMetersPerPixelCoverage();
+  
+   osg::ref_ptr<ossimPlanetGrid>    theGrid;
+   osg::ref_ptr<osg::Geode>         theGeode;
+   osg::ref_ptr<osg::Image>         theImage;
+   osg::ref_ptr<osg::Texture2D>     theTexture;
+   
+   ossim_float64   theHeading;
+   ossim_float64   theSpeed;
+   osg::Vec3d      theTextureTranslation;
+   osg::Vec3d      theTextureScale;
+   osg::Matrixd    theTextureMatrix;
+   osg::ref_ptr<osg::TexMat> theTextureMatrixAttribute;
+   bool            theAutoUpdateTextureMatrixFlag;
+   ossim_uint32    theTextureWidth;
+   ossim_uint32    theTextureHeight;
+   ossim_int32     theMeshLevel;
+   
+   ossim_float64   theApproximateMetersPerPixelCoverage;
+   ossim_float64   theMaxAltitudeToShowClouds;
+   osg::Vec3d      theCenterLlh;
+   
+   geometryPtrArray theGeometryArray;
+};
+
+/**
+ * This perlin noise code was used from the GameDev site written by Huang
+ */ 
+class OSSIMPLANET_DLL ossimPlanetCloud : public osg::Referenced
+{
+public:
+   enum TextureSize
+   {
+      TEXTURE_SIZE_256_256 = 0,
+      TEXTURE_SIZE_512_512 = 1,
+      TEXTURE_SIZE_1024_1024 = 2,
+      TEXTURE_SIZE_2048_2048 = 3
+   };
+   ossimPlanetCloud(TextureSize=TEXTURE_SIZE_1024_1024);
+   void makeCloud(ossim_int64 seed, 
+                  ossim_int32 coverage=20, 
+                  ossim_float64 sharpness=.95);//,
+                  //TextureSize size=TEXTURE_SIZE_2048_2048);
+   osg::Image* image();
+
+protected:
+   void makeNoise(ossim_int64 seed);
+   ossim_float64 interpolate(ossim_float64 x, ossim_float64 y, ossim_float64  *map);
+   double noise(ossim_int32 x, ossim_int32 y, ossim_int32 random)const;
+   void overlapOctaves();
+   void expFilter();
+   ossim_int32 theNoiseDataWidth;
+   ossim_int32 theNoiseDataHeight;
+   ossim_int32 theCloudDataWidth;
+   ossim_int32 theCloudDataHeight;
+   std::vector<ossim_float64> theNoise;
+   std::vector<ossim_float64> theCloudData;
+   osg::ref_ptr<osg::Image>   theImage;
+   
+   ossim_int32   theCoverage;
+   ossim_float64 theSharpness;
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCompass.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCompass.h
new file mode 100644
index 0000000..324df01
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCompass.h
@@ -0,0 +1,103 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Copyright (c) 2007, Arizona State University
+//  All rights reserved.
+//  BSD License: http://www.opensource.org/licenses/bsd-license.html
+//  Created by: Jeff Conner
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef ossimPlanetCompass_HEADER
+#define ossimPlanetCompass_HEADER
+
+#include <osg/Group>
+#include <string>
+#include "ossimPlanet/ossimPlanetExport.h"
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossim/base/ossimString.h>
+
+
+namespace osg { class MatrixTransform; class Geode; }
+
+
+class OSSIMPLANET_EXPORT ossimPlanetCompass : public osg::Node
+{
+public:
+   ossimPlanetCompass( );
+   
+   
+   void setCompassTexture ( const ossimFilename& fn );
+//   void setInterior ( const ossimFilename& fn );
+//   void setCompassTexture(const ossimFilename& ring,
+//                          const ossimFilename& interior);
+/*    osg::Node* compassNode ( ); */
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+   bool isAnimating ( );
+   void setAnimation(bool state);
+   
+   float heading ( );
+   void setHeading ( float r );
+   void setHeadingRelativeToNorth(const osg::Vec2& north, const osg::Vec2& pos);
+   
+   float pitch ( );
+   void setPitch ( float p );
+
+   
+   float roll ( );
+   void setRoll(float r);
+   
+   void setRotateByViewMatrix ( bool m );
+   
+   const osg::Vec3& position ( );
+   void setPosition ( const osg::Vec3& p );
+   void setPositionByPercentage ( float width, float height );
+   
+   float scale ( );
+   void  setScale ( float s );
+   
+   bool isVisible ( );
+   
+   void buildCompass ( );
+   
+   
+   void updateCompass ( );
+   
+protected:
+        
+        virtual ~ossimPlanetCompass ( );
+        
+	osg::Node* buildCompassObject ( const ossimFilename& location);
+	osg::Group*  initCompass ( );
+	
+	void _showCompass ( );
+	void _hideCompass ( );
+	void _emptyCompass ( );
+        osg::Geode* buildTriangleFan ( const ossimFilename& tex,
+                                       float zoff,
+                                       unsigned int render_level,
+                                       const osg::Vec3& n );
+	
+private:
+        
+	osg::Vec3 _pos;
+	float _scale;
+   ossimFilename theCompassFilename;
+//	ossimFilename theRing;
+//	ossimFilename theInterior;
+	unsigned int _numslices;
+	float _radius;
+	osg::ref_ptr<osg::Group> theCompassGroup;
+	osg::ref_ptr<osg::Node> theCompassObject;
+//	osg::ref_ptr<osg::Node> theCompassInteriorObject;
+
+	bool _showOrHideCompass, _animating;
+	bool _rotateByView;
+	float _animationStart, _animationEnd, _animationStep;
+	
+	float _heading, _pitch, _roll;
+        osg::ref_ptr< osg::Vec4Array > theCommonColorArray;
+   };
+
+#endif // ossimPlanetCompass_HEADER
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetConstants.h b/ossimPlanet/include/ossimPlanet/ossimPlanetConstants.h
new file mode 100644
index 0000000..a6b9365
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetConstants.h
@@ -0,0 +1,111 @@
+#ifndef ossimPlanetConstants_HEADER
+#define ossimPlanetConstants_HEADER
+
+const double OSSIMPLANET_WGS_84_RADIUS_EQUATOR = 6378137.0;
+const double OSSIMPLANET_WGS_84_RADIUS_POLAR = 6356752.3142;
+
+enum ossimPlanetTimeUnit
+{
+   ossimPlanetTimeUnit_SECONDS = 0,
+   ossimPlanetTimeUnit_MINUTES,
+   ossimPlanetTimeUnit_HOURS,
+};
+
+enum ossimPlanetLandRefreshType
+{
+   ossimPlanetLandRefreshType_NONE    = 0,
+   ossimPlanetLandRefreshType_TEXTURE = 1,
+   ossimPlanetLandRefreshType_GEOM    = 2,
+   ossimPlanetLandRefreshType_PRUNE   = 4,
+};
+
+enum ossimPlanetLandType
+{
+   ossimPlanetLandType_NONE      = 0,
+   ossimPlanetLandType_FLAT      = 1,
+   ossimPlanetLandType_NORMALIZED_ELLIPSOID = 2,
+   ossimPlanetLandType_ELLIPSOID = 3,
+   ossimPlanetLandType_ORTHOFLAT = 4
+};
+
+enum ossimPlanetPriorityType
+{
+   ossimPlanetLandPriorityType_NONE                      = 0,
+   ossimPlanetLandPriorityType_LINE_OF_SITE_INTERSECTION = 1,
+   ossimPlanetLandPriorityType_EYE_POSITION              = 2 
+};
+
+enum ossimPlanetAltitudeMode
+{
+   ossimPlanetAltitudeMode_NONE               = 0,
+   ossimPlanetAltitudeMode_CLAMP_TO_GROUND    = 1,
+   ossimPlanetAltitudeMode_RELATIVE_TO_GROUND = 2,
+   ossimPlanetAltitudeMode_ABSOLUTE           = 3
+};
+
+enum ossimPlanetKmlUnits
+{
+   ossimPlanetKmlUnits_NONE           = 0,
+   ossimPlanetKmlUnits_FRACTION       = 1,
+   ossimPlanetKmlUnits_PIXELS         = 2,
+   ossimPlanetKmlUnits_INSET_PIXELS   = 3
+};
+
+enum ossimPlanetKmlStyleState
+{
+   ossimPlanetKmlStyleState_NONE        = 0,
+   ossimPlanetKmlStyleState_NORMAL      = 1,
+   ossimPlanetKmlStyleState_HIGHLIGHT   = 2,
+};
+
+enum ossimPlanetKmlRefreshMode
+{
+   ossimPlanetKmlRefreshMode_NONE        = 0,
+   ossimPlanetKmlRefreshMode_ON_CHANGE   = 1,
+   ossimPlanetKmlRefreshMode_ON_INTERVAL = 2,
+   ossimPlanetKmlRefreshMode_ON_EXPIRE   = 3
+};
+
+enum ossimPlanetKmlViewRefreshMode
+{
+   ossimPlanetKmlViewRefreshMode_NONE       = 0,
+   ossimPlanetKmlViewRefreshMode_NEVER      = 1,
+   ossimPlanetKmlViewRefreshMode_ON_REQUEST = 2,
+   ossimPlanetKmlViewRefreshMode_ON_STOP    = 3,
+   ossimPlanetKmlViewRefreshMode_ON_REGION  = 4
+};
+
+enum ossimPlanetKmlColorMode
+{
+   ossimPlanetKmlColorMode_NONE        = 0,
+   ossimPlanetKmlColorMode_NORMAL      = 1,
+   ossimPlanetKmlColorMode_RANDOM      = 2
+};
+
+enum ossimPlanetTextureLayerStateCode // bit vector
+{
+   ossimPlanetTextureLayer_VALID          = 0,
+   ossimPlanetTextureLayer_NO_SOURCE_DATA = 1,
+   ossimPlanetTextureLayer_NO_GEOM        = 2,
+   ossimPlanetTextureLayer_NO_OVERVIEWS   = 4,
+   ossimPlanetTextureLayer_NO_HISTOGRAMS  = 8,
+   ossimPlanetTextureLayer_NOT_OPENED     = 16,
+   ossimPlanetTextureLayer_ALL            = (ossimPlanetTextureLayer_NO_SOURCE_DATA|
+                                             ossimPlanetTextureLayer_NO_GEOM|
+                                             ossimPlanetTextureLayer_NO_OVERVIEWS|
+															ossimPlanetTextureLayer_NO_HISTOGRAMS|
+                                             ossimPlanetTextureLayer_NOT_OPENED)
+};
+
+enum ossimPlanetIoDirection
+{
+   ossimPlanetIoDirection_NONE = 0,
+   ossimPlanetIoDirection_IN   = 1,
+   ossimPlanetIoDirection_OUT  = 2,
+   ossimPlanetIoDirection_INOUT= 3
+};
+
+#include <cmath>
+
+#define OSSIMPLANET_NULL_HEIGHT ((ossim_float32)1.0/FLT_EPSILON)
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetCubeGrid.h b/ossimPlanet/include/ossimPlanet/ossimPlanetCubeGrid.h
new file mode 100644
index 0000000..2e74bce
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetCubeGrid.h
@@ -0,0 +1,37 @@
+#ifndef ossimPlanetCubeGrid_HEADER
+#define ossimPlanetCubeGrid_HEADER
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetCubeGrid : public ossimPlanetGridUtility
+{
+public:
+   ossimPlanetCubeGrid(ossim_uint32 tileWidth = 256,
+                        ossim_uint32 tileHeight = 256)
+      :ossimPlanetGridUtility(tileWidth, tileHeight)
+   {
+   }
+   virtual void getPixelScale(double& dx,
+                              double& dy,
+                              ossimUnitType& pixelScaleUnits,
+                              ossim_uint32 level,
+                              ossim_uint64 row,
+                              ossim_uint64 col)const;
+   virtual void getWidthHeightInDegrees(double& deltaX,
+                                        double& deltaY,
+                                        ossim_uint32 level,
+                                        ossim_uint64 row,
+                                        ossim_uint64 col)const;
+   // this is from GeoFusion SPEC
+   virtual void getLatLon(osg::Vec3d& latLon,
+                          const ossimPlanetGridUtility::GridPoint& gridPoint)const;
+
+   // this is from Geofusion SPEC
+   virtual void getGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                             const osg::Vec3d& latLon)const;
+   
+   virtual ossim_uint32 getNumberOfFaces()const;
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetDatabasePager.h b/ossimPlanet/include/ossimPlanet/ossimPlanetDatabasePager.h
new file mode 100644
index 0000000..e7679d6
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetDatabasePager.h
@@ -0,0 +1,67 @@
+#ifndef ossimPlanetDatabasePager_HEADER
+#define ossimPlanetDatabasePager_HEADER
+#include <osgDB/DatabasePager>
+#include <ossimPlanet/ossimPlanetExport.h>
+//#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+class OSSIMPLANET_DLL ossimPlanetDatabasePager : public osgDB::DatabasePager
+{
+public:
+   ossimPlanetDatabasePager();
+   virtual DatabasePager* clone() const { return new ossimPlanetDatabasePager(*this); }
+   #if 0
+   virtual bool isRunning() const;
+   
+   virtual void signalBeginFrame(const osg::FrameStamp* framestamp);
+   virtual void signalEndFrame();
+   virtual void updateSceneGraph(const osg::FrameStamp& frameStamp);
+   virtual void compileGLObjects(osg::State& state,double& availableTime);
+   virtual void compileAllGLObjects(osg::State& state);
+   
+   #endif
+#if 0
+   class Callback : public osg::Referenced
+   {
+     public:
+          Callback(){}
+          virtual void updateSceneGraph(){}
+          virtual void noMoreWork(){}
+          virtual void doingWork(){}
+   }; 
+   typedef std::vector<osg::ref_ptr<ossimPlanetDatabasePager::Callback> > CallbackListType;
+   ossimPlanetDatabasePager();
+   virtual DatabasePager* clone() const { return new ossimPlanetDatabasePager(*this); }
+   virtual ~ossimPlanetDatabasePager();
+   virtual void run();
+   virtual int cancel();
+   virtual void invalidateRequest(const std::string& requestString);
+   virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const osg::FrameStamp* framestamp);
+   bool listsAreEmpty()const;
+        
+   void addCallback(osg::ref_ptr<ossimPlanetDatabasePager::Callback> callback);
+   void removeCallback(osg::ref_ptr<ossimPlanetDatabasePager::Callback> callback);
+   void removeRequest(osg::Group* group);
+   void addToDeleteList(osg::Object* obj);
+   void clearRequests();
+   virtual void updateSceneGraph(double currentFrameTime);
+   
+   class  MyFindCompileableGLObjectsVisitor;
+   struct MySortFileRequestFunctor;
+   struct MyCompileOperation;
+   friend struct MyCompileOperation;
+   friend struct MySortFileRequestFunctor;
+   friend class MyFindCompileableGLObjectsVisitor;
+#endif
+
+protected:
+#if 0
+   void notifyDoingWork();
+   void notifyNoMoreWork();
+   void notifyUpdateSceneGraph();
+   ossimPlanetReentrantMutex theCallbackListMutex;
+   ossimPlanetDatabasePager::CallbackListType theCallbackList;
+//   SceneNotificationCallbackListType theCallbackList;
+#endif
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetDepthPartitionNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetDepthPartitionNode.h
new file mode 100644
index 0000000..c343805
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetDepthPartitionNode.h
@@ -0,0 +1,104 @@
+/* -*-c++-*- 
+*
+*  OpenSceneGraph example, osgdepthpartion.
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#ifndef _OF_DEPTHPARTITIONNODE_
+#define _OF_DEPTHPARTITIONNODE_
+#include <ossimPlanet/ossimPlanetExport.h>
+#include "ossimPlanetDistanceAccumulator.h"
+#include <osg/Group>
+#include <osg/Camera>
+
+/**********************************************************
+ * Ravi Mathur
+ * OpenFrames API, class DepthPartitionNode
+ * A type of osg::Group that analyzes a scene, then partitions it into
+ * several segments that can be rendered separately. Each segment
+ * is small enough in the z-direction to avoid depth buffer problems
+ * for very large scenes.
+**********************************************************/
+class OSSIMPLANET_DLL ossimPlanetDepthPartitionNode : public osg::Group
+{
+  public:
+	ossimPlanetDepthPartitionNode();
+	ossimPlanetDepthPartitionNode(const ossimPlanetDepthPartitionNode& dpn, 
+	              const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
+
+	META_Node( OpenFrames, ossimPlanetDepthPartitionNode ); // Common Node functions
+
+	/** Set the active state. If not active, this node will simply add the
+	    specified scene as it's child, without analyzing it at all. */
+	void setActive(bool active);
+	inline bool getActive() const { return _active; }
+
+	/** Specify whether the color buffer should be cleared before the first
+	    Camera draws it's scene. */
+	void setClearColorBuffer(bool clear);
+	inline bool getClearColorBuffer() const { return _clearColorBuffer; }
+
+	/** Specify the render order for each Camera */
+	void setRenderOrder(osg::Camera::RenderOrder order);
+	inline osg::Camera::RenderOrder getRenderOrder() const
+	{ return _renderOrder; }
+
+	/** Set/get the maximum depth that the scene will be traversed to.
+	    Defaults to UINT_MAX. */
+	void setMaxTraversalDepth(unsigned int depth) 
+	{ _distAccumulator->setMaxDepth(depth); }
+
+	inline unsigned int getMaxTraversalDepth() const
+	{ return _distAccumulator->getMaxDepth(); }
+
+	/** Override update and cull traversals */
+	virtual void traverse(osg::NodeVisitor &nv);
+
+	/** Catch child management functions so the Cameras can be informed
+	    of added or removed children. */
+	virtual bool addChild(osg::Node *child);
+	virtual bool insertChild(unsigned int index, osg::Node *child);
+	virtual bool removeChildren(unsigned int pos, unsigned int numRemove = 1);
+	virtual bool setChild(unsigned int i, osg::Node *node);
+
+  protected:
+	typedef std::vector< osg::ref_ptr<osg::Camera> > CameraList;
+
+	virtual ~ossimPlanetDepthPartitionNode();
+
+	void init();
+
+	// Creates a new Camera object with default settings
+	osg::Camera* createOrReuseCamera(const osg::Matrix& proj, 
+                                double znear, double zfar, 
+                                const unsigned int &camNum);
+
+	bool _active; // Whether partitioning is active on the scene
+
+	// The NodeVisitor that computes cameras for the scene
+	osg::ref_ptr<ossimPlanetDistanceAccumulator> _distAccumulator;
+
+	osg::Camera::RenderOrder _renderOrder;
+	bool _clearColorBuffer;
+
+	// Cameras that should be used to draw the scene.  These cameras
+	// will be reused on every frame in order to save time and memory.
+	CameraList _cameraList;
+	unsigned int _numCameras; // Number of Cameras actually being used
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetDestinationCommandAction.h b/ossimPlanet/include/ossimPlanet/ossimPlanetDestinationCommandAction.h
new file mode 100644
index 0000000..f42d44b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetDestinationCommandAction.h
@@ -0,0 +1,85 @@
+#ifndef ossimPlanetDestinationCommandAction_HEADER
+#define ossimPlanetDestinationCommandAction_HEADER
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossim/base/ossimString.h>
+
+class OSSIMPLANET_DLL ossimPlanetDestinationCommandAction : public ossimPlanetAction
+{
+public:
+	ossimPlanetDestinationCommandAction(const ossimString& sourcecode = ossimString(), 
+                                       const ossimString& originatingFederate = defaultOrigin());
+   ossimPlanetDestinationCommandAction(const ossimPlanetDestinationCommandAction& src)
+   :ossimPlanetAction(src),
+   theTokens(src.theTokens),
+	theArgCount(src.theArgCount)
+   {
+   }
+   virtual ossimPlanetDestinationCommandAction* toDestinationCommandAction()
+   {
+      return this;
+   }
+   virtual const ossimPlanetDestinationCommandAction* toDestinationCommandAction()const
+   {
+      return this;
+   }
+   virtual ossimPlanetAction* clone()const
+   {
+      return new ossimPlanetDestinationCommandAction(*this);
+   }
+   virtual ossimPlanetAction* cloneType()const
+   {
+      return new ossimPlanetDestinationCommandAction();
+   }
+   ossimString argListSourceCode() const;
+	virtual bool setSourceCode(const ossimString& code);
+  
+   virtual void setTarget(const ossimString& targetPath)
+   {
+      ossimPlanetAction::setTarget(targetPath);
+      if(theTokens.size())
+      {
+         theTokens[0] = targetPath.string();
+      }
+   }
+   
+   virtual void setCommand(const ossimString& value)
+   {
+      ossimPlanetAction::setCommand(value);
+      if(theTokens.size()>1)
+      {
+         theTokens[1] = value.string();
+      }
+   }
+	unsigned int argCount() const
+	{
+		return theArgCount;
+	}
+	
+	const std::string& arg(unsigned int i) const
+	{
+		assert(i >= 1 && i <= argCount());
+		return theTokens[i+1];
+	}
+   void setTargetCommandArg(const ossimString& target, 
+                            const ossimString& command, 
+                            const ossimString& arg)
+   {
+      theArgCount = 1;
+      theTokens.resize(3);
+      theTokens[0] = target.string();
+      theTokens[1] = command.string();
+      theTokens[2] = arg.string();
+   }
+	ossimString argListSource() const;
+	// source code of the argument list
+	virtual void print(std::ostream& out)const;
+   virtual void read(std::istream& in);
+   
+protected:
+	std::vector<std::string> theTokens;
+	unsigned int theArgCount;
+	
+	static const char theWhitespace[];
+	// characters considered to be whitespace
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetDistanceAccumulator.h b/ossimPlanet/include/ossimPlanet/ossimPlanetDistanceAccumulator.h
new file mode 100644
index 0000000..dfa8db3
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetDistanceAccumulator.h
@@ -0,0 +1,116 @@
+/* -*-c++-*- 
+*
+*  OpenSceneGraph example, osgdepthpartion.
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#ifndef _OF_DISTANCEACCUMULATOR_
+#define _OF_DISTANCEACCUMULATOR_
+
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Group>
+#include <osg/NodeVisitor>
+#include <osg/Polytope>
+#include <osg/fast_back_stack>
+
+#define CURRENT_CLASS ossimPlanetDistanceAccumulator
+/**********************************************************
+ * Ravi Mathur
+ * OpenFrames API, class DistanceAccumulator
+ * Class that traverses the scene and computes the distance to each
+ * visible drawable, and splits up the scene if the drawables are
+ * too far away (in the z direction) from each other. 
+**********************************************************/
+class OSSIMPLANET_DLL CURRENT_CLASS : public osg::NodeVisitor
+{
+  public:
+	typedef std::pair<double, double> DistancePair;
+	typedef std::vector<DistancePair> PairList;
+
+	CURRENT_CLASS();
+
+	virtual void apply(osg::Node &node);
+	virtual void apply(osg::Projection &proj);
+	virtual void apply(osg::Transform &transform);
+	virtual void apply(osg::Geode &geode);
+
+	// Specify the modelview & projection matrices
+	void setMatrices(const osg::Matrix &modelview,
+	                 const osg::Matrix &projection);
+
+	// Reset visitor before a new traversal
+	virtual void reset();
+
+	// Create a (near,far) distance pair for each camera of the specified
+	// distance pair list and distance limits.
+	void computeCameraPairs();
+
+	// Get info on the cameras that should be used for scene rendering
+	PairList& getCameraPairs() { return _cameraPairs; }
+
+	// Get info on the computed distance pairs
+	PairList& getDistancePairs() { return _distancePairs; }
+
+	// Get info on the computed nearest/farthest distances
+	DistancePair& getLimits() { return _limits; }
+
+	// Set/get the desired near/far ratio
+	void setNearFarRatio(double ratio);
+	inline double getNearFarRatio() const { return _nearFarRatio; }
+
+	inline void setMaxDepth(unsigned int depth) { _maxDepth = depth; }
+	inline unsigned int getMaxDepth() const { return _maxDepth; }
+
+  protected:
+	virtual ~CURRENT_CLASS();
+
+	void pushLocalFrustum();
+	void pushDistancePair(double zNear, double zFar);
+	bool shouldContinueTraversal(osg::Node &node);
+
+	// Stack of matrices accumulated during traversal
+	osg::fast_back_stack<osg::Matrix> _viewMatrices;
+	osg::fast_back_stack<osg::Matrix> _projectionMatrices;
+
+	// Main modelview/projection matrices
+	osg::Matrix _modelview, _projection;
+
+	// The view frusta in local coordinate space
+	osg::fast_back_stack<osg::Polytope> _localFrusta;
+
+	// Bounding box corners that should be used for cull computation
+	typedef std::pair<unsigned int, unsigned int> bbCornerPair;
+	osg::fast_back_stack<bbCornerPair> _bbCorners;
+
+	// Nar/far planes that should be used for each camera
+	PairList _cameraPairs;
+
+	// Accumulated pairs of min/max distances
+	PairList _distancePairs;
+
+	// The closest & farthest distances found while traversing
+	DistancePair _limits;
+
+	// Ratio of nearest/farthest clip plane for each section of the scene
+	double _nearFarRatio;
+
+	// Maximum depth to traverse to
+	unsigned int _maxDepth, _currentDepth;
+};
+#undef CURRENT_CLASS
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetDtedElevationDatabase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetDtedElevationDatabase.h
new file mode 100644
index 0000000..9730976
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetDtedElevationDatabase.h
@@ -0,0 +1,85 @@
+#ifndef ossimPlanetDtedElevationDatabase_HEADER
+#define ossimPlanetDtedElevationDatabase_HEADER
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <ossim/elevation/ossimDtedHandler.h>
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <OpenThreads/ReentrantMutex>
+
+class OSSIMPLANET_DLL ossimPlanetDtedElevationDatabase : public ossimPlanetElevationDatabase
+{
+public:
+   ossimPlanetDtedElevationDatabase();
+   ossimPlanetDtedElevationDatabase(const ossimPlanetDtedElevationDatabase& src);
+   virtual ~ossimPlanetDtedElevationDatabase();
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+
+   virtual ossimPlanetTextureLayerStateCode open(const std::string& location);
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& theGrid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& grid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+protected:
+    class DtedInfo : public osg::Referenced
+   {
+   public:
+      double                        theMinLat, theMinLon, theMaxLat, theMaxLon;
+      double                        theNumLatPoints;
+      double                        theNumLonLines;
+      double                        theLatSpacing;
+      double                        theLonSpacing;
+      ossimFilename                 theFilename;
+      ossimRefPtr<ossimDtedHandler> theHandler;
+      osg::Timer_t                  theTimeStamp;
+   };
+   
+   typedef std::map<std::string, osg::ref_ptr<DtedInfo> > DtedFilePointerList;
+
+
+   osg::ref_ptr<ossimPlanetDtedElevationDatabase::DtedInfo> getInfo(const std::string& name);
+   void shrinkFilePointers();
+   ossimFilename buildFilename(double lat, double lon)const;
+   osg::ref_ptr<ossimPlanetDtedElevationDatabase::DtedInfo> findDtedInfo(const std::string& name);
+   double getHeightAboveMSL(osg::ref_ptr<DtedInfo> info, double lat, double lon)const;
+   ossim_sint16 convertSignedMagnitude(ossim_uint16& s) const;
+  
+   std::string                            theLocation;
+   mutable bool                           theOpenFlag;
+   ossim_uint32                           theMaxOpenFiles;
+   ossim_uint32                           theMinOpenFiles;
+   DtedFilePointerList                    theFilePointers;
+   ossim_float32                          theNullHeightValue;
+   bool                                   theSwapBytesFlag;
+   mutable OpenThreads::ReentrantMutex    theDtedInfoMutex;
+
+};
+inline ossim_sint16 ossimPlanetDtedElevationDatabase::convertSignedMagnitude(ossim_uint16& s) const
+{
+   // DATA_VALUE_MASK 0x7fff = 0111 1111 1111 1111
+   // DATA_SIGN_MASK  0x8000 = 1000 0000 0000 0000
+   
+   // First check to see if the bytes need swapped.
+   s = (theSwapBytesFlag ? ( ((s & 0x00ff) << 8) | ((s & 0xff00) >> 8) ) : s);
+   
+   // If the sign bit is set, mask it out then multiply by negative one.
+   if (s & 0x8000)
+   {
+      return (static_cast<ossim_sint16>(s & 0x7fff) * -1);
+   }
+   
+   return static_cast<ossim_sint16>(s);
+}
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabase.h
new file mode 100644
index 0000000..2b98882
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabase.h
@@ -0,0 +1,69 @@
+#ifndef ossimPlanetElevationDatabase_HEADER
+#define ossimPlanetElevationDatabase_HEADER
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+#include <ossimPlanet/ossimPlanetExtents.h>
+#include <string>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+
+class OSSIMPLANET_DLL ossimPlanetElevationDatabase : public ossimPlanetTextureLayer
+{
+public:
+   ossimPlanetElevationDatabase()
+      :ossimPlanetTextureLayer(),
+   theFillNullWithGeoidOffsetFlag(false)
+   {}
+   ossimPlanetElevationDatabase(const ossimPlanetElevationDatabase& src)
+      :   ossimPlanetTextureLayer(src)
+   {
+   }
+   
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(const ossimPlanetTerrainTileId& tileId,
+                                                     osg::ref_ptr<ossimPlanetGrid> theGrid);
+      
+   virtual ossimPlanetTextureLayerStateCode open(const std::string& location)=0;
+   
+   virtual const std::string& getLocation()const
+   {
+      return theLocation;
+   }
+   bool fillNullWithGeoidOffsetFlag()const
+   {
+      return theFillNullWithGeoidOffsetFlag;
+   }
+   virtual void setFillNullWithGeoidOffsetFlag(bool flag)
+   {
+      theFillNullWithGeoidOffsetFlag = flag;
+   }
+   virtual void setGeoRefModel(osg::ref_ptr<ossimPlanetGeoRefModel> model)
+   {
+      theGeoRefModel = model.get();
+   }
+   ossimPlanetGeoRefModel* geoRefModel()const
+   {
+      return theGeoRefModel.get();
+   }
+   virtual void sortByGsd()
+   {
+      
+   }
+protected:
+   /**
+    * 
+    * destData is always assumed to be 1 band float and both buffers are of the same size.  It will make sure it's float before
+    * merging the src into the destination.  This function basically copys good pixels into
+    * non null regions of the destination.
+    * 
+    */ 
+   void mergeDataObjects(ossimRefPtr<ossimImageData> destData,
+                         ossimRefPtr<ossimImageData> srcData);
+   
+   std::string                      theLocation;
+   bool                             theFillNullWithGeoidOffsetFlag;
+   osg::ref_ptr<ossimPlanetGeoRefModel> theGeoRefModel;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabaseGroup.h b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabaseGroup.h
new file mode 100644
index 0000000..0d3b111
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationDatabaseGroup.h
@@ -0,0 +1,58 @@
+#ifndef ossimPlanetElevationDatabaseGroup_HEADER
+#define ossimPlanetElevationDatabaseGroup_HEADER
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetElevationDatabaseGroup : public ossimPlanetTextureLayerGroup
+{
+public:
+   ossimPlanetElevationDatabaseGroup();
+
+   ossimPlanetElevationDatabaseGroup(const ossimPlanetElevationDatabaseGroup& src);
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+
+   virtual bool replaceLayer(ossim_uint32 idx,
+                             osg::ref_ptr<ossimPlanetTextureLayer> layer);
+   
+   virtual bool addTop(osg::ref_ptr<ossimPlanetTextureLayer> layer);
+   virtual bool addBeforeIdx(ossim_uint32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer);
+   virtual bool addBeforeLayer(const osg::ref_ptr<ossimPlanetTextureLayer> beforeLayer,
+                       osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd);
+   virtual bool addAfterIdx(ossim_int32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer);
+   virtual bool addAfterLayer(const osg::ref_ptr<ossimPlanetTextureLayer> afterLayer,
+                      osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd);
+   virtual bool addBottom(osg::ref_ptr<ossimPlanetTextureLayer> layer);
+
+   virtual void setGeoRefModel(osg::ref_ptr<ossimPlanetGeoRefModel> model);
+   virtual void setFillNullWithGeoidOffsetFlag(bool flag);
+   bool fillNullWithGeoidOffsetFlag()const
+   {
+      return theFillNullWithGeoidOffsetFlag;
+   }
+
+protected:
+   /**
+    *
+    * Merging elevation cells are done differently.  We will override the base classes mergeImage.
+    * 
+    */ 
+   virtual void mergeImage(ossimPlanetImage* result,
+                           const ossimPlanetImage* source)const;   
+   void setPixelStatus(ossimPlanetImage* image);
+  
+   osg::ref_ptr<ossimPlanetGeoRefModel> theGeoRefModel;
+   bool                             theFillNullWithGeoidOffsetFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetElevationFactory.h b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationFactory.h
new file mode 100644
index 0000000..5f7530f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationFactory.h
@@ -0,0 +1,12 @@
+#ifndef ossimPlanetElevationFactory_HEADER
+#define ossimPlanetElevationFactory_HEADER
+#include <ossimPlanet/ossimPlanetElevationRegistry.h>
+class ossimPlanetElevationFactory : public ossimPlanetElevationRegistry::FactoryBase
+{
+public:
+   ossimPlanetElevationFactory();
+   virtual ossimPlanetElevationDatabase* openDatabase(const ossimString& location);
+   static ossimPlanetElevationFactory* instance();
+};
+
+#endif
\ No newline at end of file
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetElevationGrid.h b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationGrid.h
new file mode 100644
index 0000000..3fac884
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationGrid.h
@@ -0,0 +1,60 @@
+#ifndef ossimPlanetElevationGrid_HEADER
+#define ossimPlanetElevationGrid_HEADER
+#include <vector>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetElevationGrid : public osg::Referenced
+{
+public:
+   ossimPlanetElevationGrid(ossim_uint32 w=1,
+                          ossim_uint32 h=1);
+
+   float& operator[](ossim_uint32 idx)
+   {
+      return theGrid[idx];
+   }
+   const float& operator[](ossim_uint32 idx)const
+   {
+      return theGrid[idx];
+   }
+   float* row(ossim_uint32 rowIdx)
+   {
+      return &theGrid[rowIdx*theWidth];
+   }
+   ossim_uint32 getWidth()const
+   {
+      return theWidth;
+   }
+   ossim_uint32 getHeight()const
+   {
+      return theHeight;
+   }
+   
+   void resize(ossim_uint32 w,
+               ossim_uint32 h);
+
+   const ossim_float32* data()const
+   {
+      return theGrid;
+   }
+   ossim_float32* data()
+   {
+      return theGrid;
+   }
+   osg::ref_ptr<ossimPlanetElevationGrid>  scaleBy2Nearest()const;
+   osg::ref_ptr<ossimPlanetElevationGrid>  scaleBy2Bilinear()const;
+   void copyGrid(ossim_uint32 ulx,
+                 ossim_uint32 uly,
+                 osg::ref_ptr<ossimPlanetElevationGrid> output)const;
+   bool isEqualTo(osg::ref_ptr<ossimPlanetElevationGrid> grid)const;
+protected:
+   virtual ~ossimPlanetElevationGrid();
+   ossim_uint32 theWidth;
+   ossim_uint32 theHeight;
+   ossim_float32* theGrid;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetElevationRegistry.h b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationRegistry.h
new file mode 100644
index 0000000..c31dbf7
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetElevationRegistry.h
@@ -0,0 +1,36 @@
+#ifndef ossimPlanetElevationRegistry_HEADER
+#define ossimPlanetElevationRegistry_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+
+class OSSIMPLANET_DLL ossimPlanetElevationRegistry
+{
+public:
+   class OSSIMPLANET_DLL FactoryBase
+      {
+      public:
+         virtual ~FactoryBase(){}
+         virtual ossimPlanetElevationDatabase* openDatabase(const ossimString& location)=0;
+         
+         ossimString id(){return theId;}
+         void setId(const ossimString& value){theId = value;}
+      protected:
+         ossimString theId;
+      };
+   typedef std::vector<FactoryBase*> FactoryList;
+   
+   ossimPlanetElevationRegistry();
+   bool registerFactory(FactoryBase* factory);
+   void unregisterFactory(FactoryBase* factory);
+   ossimPlanetElevationDatabase* openDatabase(const ossimString& location);
+   
+   static ossimPlanetElevationRegistry* instance();
+   
+protected:
+   ossimPlanetReentrantMutex theMutex;
+   FactoryList theFactoryList;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetEphemeris.h b/ossimPlanet/include/ossimPlanet/ossimPlanetEphemeris.h
new file mode 100644
index 0000000..b884bb7
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetEphemeris.h
@@ -0,0 +1,392 @@
+#ifndef ossimPlanetEphemeris_HEADER
+#define ossimPlanetEphemeris_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Material>
+
+class ossimPlanet;
+class ossimPlanetCloudLayer;
+class OSSIMPLANET_DLL ossimPlanetEphemeris : public ossimPlanetLayer
+{
+public:
+   /**
+    * These are setting that will be used for display purposes.  The members
+    * can be ored together to formula the current active set of members to use.
+    *
+    * SUN_LIGHT enables sun lighting calculations. It will automatically set the sun directional
+    *           vector and positioning relative to the current ossimPlanet geospatial model.
+    * MOON_LIGHT enables moon lighting calculations. It will automatically set the moon directional
+    *           vector and positioning relative to the current ossimPlanet geospatial model.
+    */
+   enum Members
+   {
+      NO_MEMBERS    = 0,
+      SUN_LIGHT     = 1,  // Enable the default Sun lighting
+      MOON_LIGHT    = 2,  // Enable the default moon lighting
+      AMBIENT_LIGHT = 4,
+      SUN           = 8,      
+      MOON          = 16,   
+      SKY           = 32,   
+      FOG           = 64,
+      ALL_MEMBERS   = SKY|SUN_LIGHT|MOON_LIGHT|SUN|MOON|AMBIENT_LIGHT|FOG
+   };
+   
+   enum FogMode
+   {
+      LINEAR = 0, ///<Linear fog
+      EXP,        ///<Exponential fog
+      EXP2,       ///<Exponential squared fog
+      //ADV         ///<Advanced light scattering "fog" RESERVED FOR FUTURE
+   };
+   
+   typedef std::map<double, double> IntensityTableType; 
+   class LightingCallback : public osg::Referenced
+   {
+   public:
+      virtual void operator()(ossimPlanetEphemeris* /*ephemeris*/,
+                              osg::LightSource* /*light*/)
+      {
+      }
+   };
+   ossimPlanetEphemeris(ossim_uint64 membersBitMap=NO_MEMBERS);
+   virtual ~ossimPlanetEphemeris();
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   osg::Vec3d eyePositionXyz()const;
+   osg::Vec3d eyePositionLatLonHeight()const;
+   /**
+    * @brief Allows you to set what the current active members are.  See the 
+    *        enumeration Members for more detail.  This is an "ored" bit vector
+    *        of Members to use.
+    */
+   void setMembers(ossim_uint64 membersBitMap);
+   
+   /**
+    * @return The members bitmap describing the current members active in the
+    *         ephemeris model.  See the enumeration Members for more details
+    */
+   ossim_uint64 members()const;
+   
+   /**
+    * @param statest The root graph to use for light source settings.
+    */
+   void setRoot(osg::Group* group);
+   
+   
+   /**
+    * @brief Sets the index to use for the moonlight source.
+    *
+    * @param idxNumber The openGL Light index to use for the moon lighting
+    */
+   void setMoonLightIndex(ossim_uint32 idxNumber);
+   
+   /**
+    * @return the current moonlight index
+    */
+   ossim_uint32 moonLightIndex()const;
+   
+   void setMoonLightCallback(LightingCallback* callback);
+   
+   void setMoonCullCallback(osg::NodeCallback* callback);
+
+   osg::Vec3d moonPositionXyz()const;
+   osg::Vec3d moonPositionLatLonHeight()const;
+   
+   /**
+    * @brief Sets the index to use for the sunlight source.
+    *
+    * @param idxNumber The openGL Light index to use for the sun lighting
+    */
+   void setSunLightIndex(ossim_uint32 idxNumber);
+   
+   /**
+    * @return the current moonlight index
+    */
+   ossim_uint32 sunLightIndex()const;
+   
+   void setSunLightCallback(LightingCallback* callback);
+   
+   /**
+    * @brief Sets the cull call back to use for the sun model
+    *
+    * @param callback The call back function to use
+    */
+   void setSunCullCallback(osg::NodeCallback* callback);
+
+   osg::Vec3d sunPositionXyz()const;
+   osg::Vec3d sunPositionLatLonHeight()const;
+   /**
+    * Allows one to turn off auto update for sun color calculations. 
+    */
+   void setAutoUpdateSunColorFlag(bool flag);
+   
+   /**
+    * @brief OpenGL light index to use for the ambient lighting.
+    *
+    * @param idxNumber The openGL Light index to use for the sun lighting
+    */
+   void setGlobalAmbientLightIndex(ossim_uint32 idx);
+   
+   /**
+    * @brief returns the current ambient index.
+    *
+    * @return the ambient index.
+    */
+   ossim_uint32 globalAmbientLightIndex()const;
+   
+   /**
+    * Allows one to change the color value for the global ambient lighting.  The
+    * color is a normalized r,g,b value and range from 0..1
+    *
+    * @param ambient The normalized color vector ranging from 0..1 for each RGB component.
+    */
+   void setGlobalAmbientLight(const osg::Vec3d& ambient);
+   /**
+    * This will set the date to use.  If this is set then the 
+    * auto update of the current time is disabled and will use
+    * this date as a fixed shading.  When using this method we basically assume
+    * that you are driving the date and time.  To reset back to auto update just call
+    * the setAutoUpdateToCurrentTimeFlag.
+    *
+    * Note, for Ephermis calculations we normalize the date on the fly to GMT time
+    * so we will always hold onto the original date passed.
+    *
+    * @param time an ossimLocalTm object.
+    */
+   void setDate(const ossimLocalTm& date);
+   
+   /**
+    * This is to allow you to let the ephemeris updates continually 
+    * change based on the current time
+    */
+   void setAutoUpdateToCurrentTimeFlag(bool flag);
+   
+   /**
+    * This will disable the Auto update to current time setting and do a relative
+    * displacement of the current date settings to the sim time passed in the osg::NodeVisitor
+    *
+    * Currently the relative simulation time displacement units must be in seconds.
+    */
+   void setApplySimulationTimeOffsetFlag(bool flag);
+   
+   /**
+    * This is used by the ossimPlanetViewer to setup a slave camera for the drawing
+    * of the sun moon and dome.  We were having problems with large displacements being in 
+    * the same graph as the terrain.  The near and far planes were causing the terrain to
+    * get clipped at low altitudes.
+    *
+    * This might go away in the future, but for now I am playing with coupling to the viewer's master
+    * camera.
+    */
+   void setCamera(osg::Camera* camera);
+   
+   /**
+    * Will use the visibility to set the far plane and the density values of the fog.  The visibility is
+    * in meters.
+    *
+    * @param visibility Value specifies visibility in meter distance.
+    */
+   void setVisibility(ossim_float64 visibility);
+   
+   
+   /**
+    * This returns the internal representation of the visibility.
+    */
+   ossim_float64 visibility()const;
+   
+   /**
+    * Allows one to pass a texture in by file.  It uses this texture to show the position
+    * of the sun.
+    *
+    * @param texture Filename for the texture.  Typically a file format supported by OSG and has
+    *        an alpha channel.  Best is an RBA in png format.
+    */
+   void setSunTextureFromFile(const ossimFilename& texture);
+
+   /**
+    * Allows one to pass a texture by osg::Image.  It uses this texture to show the position
+    * of the sun.
+    *
+    * @param texture Image for the texture.  Should be an RGBA type image.
+    */
+   void setSunTextureFromImage(osg::Image* texture);
+
+   /**
+    * @brief Sets the scale to use for the sun model
+    *
+    * @param scale, The scale to use
+    */
+   void setSunScale(const osg::Vec3d& scale);
+
+   /**
+    * Allows one to pass a texture in by file.  It uses this texture to show the position
+    * of the moon.
+    *
+    * @param texture Filename for the texture.  Typically a file format supported by OSG and has
+    *        an alpha channel.  Best is an RBA in png format.
+    */
+   void setMoonTextureFromFile(const ossimFilename& texture);
+
+   /**
+    * Allows one to pass a texture by osg::Image.  It uses this texture to show the position
+    * of the moon.
+    *
+    * @param texture Image for the texture.  Should be an RGBA type image.
+    */
+   void setMoonTextureFromImage(osg::Image* texture);
+   
+   void setMoonScale(const osg::Vec3d& scale);
+   
+   void setSunMinMaxPixelSize(ossim_uint32 minPixelSize,
+                              ossim_uint32 maxPixelSize);
+
+   void setMaximumAltitudeToShowDomeInMeters(ossim_float64 maxAltitude);
+   void setMaximumAltitudeToShowFogInMeters(ossim_float64 maxAltitude);
+ 
+   /**
+    * This specifies the max altitude that you would like Sunlight adjustments to occur for
+    * sunrise and sunset calculations.
+    *
+    * @param maxAltitude The max altitude is specified in meters.
+    */
+   void setMaxAltitudeToDoSunriseSunsetColorAdjustment(ossim_float64 maxAltitude,
+                                                      bool useFading=true);
+   
+   /**
+    * @return the reference value used to identify when to use the eye's altitude to adjust the sun color
+    *          used for shading.
+    */
+   ossim_float64  maxAltitudeToDoSunriseSunsetColorAdjustment()const;
+   
+   /**
+    * This is an intensity/brightness factor multiplied by the sky color based on sun elevation angle
+    * with respect to the eye.  The table is a pair of values where the first value is the elevation angle
+    * and the second value is the intensity.  This table is used to do a bilinear interpolation of the brightness
+    * factor applied to the current sky color.
+    *
+    * skyColor*brightness
+    *
+    * where brightness is calculated form the passed in table.
+    *
+    * @param table a std::map of values that takes pairs elevation angle in degrees and brightness factor.
+    */
+   void setSkyColorAdjustmentTable(IntensityTableType& table);
+   
+   /**
+    * @return the adjustment table used to modify the sky color.  This is a table of elevation angles in degrees and
+    *         brightness factors used to attenuate the skycolor.
+    */
+   const IntensityTableType* skyColorAdjustmentTable()const;
+   
+   void setBaseSkyColor(const osg::Vec3d& color);
+   osg::Vec3d getBaseSkyColor()const;
+   
+   void setBaseFogColor(const osg::Vec3d& color);
+   osg::Vec3d getBaseFogColor()const;
+   
+   /**
+    *
+    * This mirrors the GL fog.  You can currently have LINEAR, EXP, and EXP2 fog affects.  @see Open gl for further information on
+    * the GL fog paramters.  LINEAR uses the near and far to set fog attenuation the others attenuate based on distance.
+    *
+    */
+   void setFogMode(FogMode mode);
+   
+   /**
+    * Sets the near plane where the fog begins.
+    *
+    * @param value the near plane in meters.
+    */
+   void setFogNear(ossim_float64 value);
+   
+   /**
+    * Set the far plane where the fog ends.  This is automatically set based on visibility.
+    *
+    * @param value The far plane value in meters.
+    */
+   void setFogFar(ossim_float64 value);
+   
+   /**
+    * Density is automatically calculated based on visibility.
+    *
+    * @param value The density value to use. This should e set after the visibility is set.
+    */
+   void setFogDensity(ossim_float64 value);
+   
+   /**
+    * Allows one to enable and disable fog in the scene.
+    *
+    * @param flag enables and disables the fog.  Pass in true to enable and false
+    *        to disable.
+    */
+   void setFogEnableFlag(bool flag);
+   
+   /**
+    * Resizes the list to the specified number of cloud layers.
+    *
+    * @param numberOfLayers The number of cloud layers to resize the list to.
+    */
+   void setNumberOfCloudLayers(ossim_uint32 numberOfLayers);
+   
+   void removeClouds(ossim_uint32 idx, ossim_uint32 count=1);
+   /**
+    * @param idx The index of the cloud layer to return.
+    * @return The cloud layer specified at idx.  If idx is out of
+    *         range then a value of null or 0 is returned.
+    */
+   ossimPlanetCloudLayer* cloudLayer(ossim_uint32 idx);
+   
+   /**
+    * @return the number of cloud layers
+    */
+   ossim_uint32 numberOfCloudLayers()const;
+   
+   /**
+    * This is a utility method that allows one to create a patch of clouds centered
+    * at the give lat lon height.  In short, we shift the creation of the patch to lat lon height
+    * to 0,0,0 so the patch is square and then use a Matrix transform to move it to a new location defined
+    * by the center lat lon height. The seed, coverange and sharpness are exposed to give you some
+    * control over the texture generated. The seed is used to initialize the random number generator so you should
+    * be able to give the same paramters and generate the same texture.  The coverage and sharpness are used to control
+    * how much clouds there are and how soft they appear.  For example coverage of say 20 and sharpness of .96 gives a nice
+    * look.  If you want them to be more overcast and softer, then increase the coverage to say 150 and the sharpness to around
+    * .99.
+    *
+    * @param cloudLayerIndex The cloud layer to create a patch for.
+    * @param theCenterLatLonHeight The center point to place the cloud patch.
+    * @param numberOfMeshSamples  This is square so a value of 128 will
+    *        create a mesh sample of 128x128.
+    * @param patchSizeInDegrees  Defines the patch size in depgrees.
+    * @param seed This is the seed value used to generate a cloud texture.
+    * @param coverage This is used to generate a texture.  This value is not a percentage
+    *         and is a value to controll the way the clouds look.
+    * @param sharpness  The closer the value is to 1.0 the softer the clouds and the closer you go to 
+    *        0 the harder the clouds look.
+    */
+   void createCloudPatch(ossim_uint32 cloudLayerIndex,
+                         const osg::Vec3d& theCenterLatLonHeight,
+                         ossim_float64 numberOfMeshSamples,
+                         ossim_float64 patchSizeInDegrees,
+                         ossim_uint64  seed,
+                         ossim_float64 coverage,
+                         ossim_float64 sharpness);
+   
+   void createGlobalCloud(ossim_uint32 cloudLayerIndex,
+                          ossim_float64 altitude,
+                          ossim_float64 numberOfMeshSamples,
+                          ossim_uint64  seed,
+                          ossim_float64 coverage,
+                          ossim_float64 sharpness);
+   
+   virtual osg::BoundingSphere computeBound() const;
+   
+protected:
+   class EphemerisData;
+   /**
+    * This is used to hide the gpstk library we are using.  This way we can conditionally compile
+    * out.
+    */
+   EphemerisData* theEphemerisData;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetExport.h b/ossimPlanet/include/ossimPlanet/ossimPlanetExport.h
new file mode 100644
index 0000000..7a03871
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetExport.h
@@ -0,0 +1,60 @@
+/* -*-c++-*- libwms - Copyright (C) since 2004 Garrett Potts 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the libwms Public License (WMSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * libwms Public License for more details.
+*/
+#ifndef ossimPlanetExport_HEADER
+#define ossimPlanetExport_HEADER
+// define used to include in API which is being fazed out
+// if you can compile your apps with this turned off you are
+// well placed for compatablity with future versions.
+#define USE_DEPRECATED_API
+
+#if defined(_MSC_VER)
+    #pragma warning( disable : 4244 )
+    #pragma warning( disable : 4251 )
+    #pragma warning( disable : 4267 )
+    #pragma warning( disable : 4275 )
+    #pragma warning( disable : 4290 )
+    #pragma warning( disable : 4786 )
+    #pragma warning( disable : 4305 )
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined( __BCPLUSPLUS__)  || defined( __MWERKS__)
+#    ifdef OSSIMPLANET_LIBRARY
+#        define OSSIMPLANET_EXPORT   __declspec(dllexport)
+#        define OSSIMPLANET_DLL   OSSIMPLANET_EXPORT
+#    else
+#        define OSSIMPLANET_EXPORT   __declspec(dllimport)
+#        define OSSIMPLANET_DLL   OSSIMPLANET_EXPORT
+#    endif /* OSSIMPLANET_LIBRARY */
+#else
+#    define OSSIMPLANET_EXPORT
+#    define OSSIMPLANET_DLL   OSSIMPLANET_EXPORT
+#endif  
+
+// set up define for whether member templates are supported by VisualStudio compilers.
+#ifdef _MSC_VER
+# if (_MSC_VER >= 1300)
+#  define __STL_MEMBER_TEMPLATES
+# endif
+#endif
+
+/* Define NULL pointer value */
+
+#ifndef NULL
+    #ifdef  __cplusplus
+        #define NULL    0
+    #else
+        #define NULL    ((void *)0)
+    #endif
+#endif
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetExtents.h b/ossimPlanet/include/ossimPlanet/ossimPlanetExtents.h
new file mode 100644
index 0000000..c213bb5
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetExtents.h
@@ -0,0 +1,351 @@
+#ifndef ossimPlanetExtents_HEADER
+#define ossimPlanetExtents_HEADER
+#include <osg/Referenced>
+#include <ossim/base/ossimDate.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/mkUtils.h>
+
+class OSSIMPLANET_DLL ossimPlanetExtents : public osg::Referenced
+{
+public:
+   ossimPlanetExtents()
+      :osg::Referenced(),
+      theMinLon(-180.0),
+      theMaxLon(180.0),
+      theMinLat(-90.0),
+      theMaxLat(90.0),
+      theMinScale(0.0),
+      theMaxScale(1.0/DBL_EPSILON),
+      theMinHeight(-(1.0/DBL_EPSILON)+1.0),
+      theMaxHeight(1.0/DBL_EPSILON),
+      theMinDate(1, 1, 1),
+      theMaxDate(12, 31, 9999)
+   {
+   }
+   ossimPlanetExtents(const ossimPlanetExtents& src)
+      :osg::Referenced(),
+      theMinLon(src.theMinLon),
+      theMaxLon(src.theMaxLon),
+      theMinLat(src.theMinLat),
+      theMaxLat(src.theMaxLat),
+      theMinScale(src.theMinScale),
+      theMaxScale(src.theMaxScale),
+      theMinHeight(src.theMinHeight),
+      theMaxHeight(src.theMaxHeight),
+      theMinDate(src.theMinDate),
+      theMaxDate(src.theMaxDate)
+   {
+   }
+   ossimPlanetExtents* clone()const
+   {
+      return new ossimPlanetExtents(*this);
+   }
+   void setMinLatLon(double lat,
+                     double lon)
+   {
+      theMinLat = lat;
+      theMinLon = lon;
+   }
+
+   void setMaxLatLon(double lat, double lon)
+   {
+      theMaxLat = lat;
+      theMaxLon = lon;
+   }
+   void setMinMaxLatLon(double minLat, double minLon,
+                        double maxLat, double maxLon)
+   {
+      theMinLat = ossim::min(minLat, maxLat);
+      theMaxLat = ossim::max(minLat, maxLat);
+      theMinLon = ossim::min(minLon, maxLon);
+      theMaxLon = ossim::max(minLon, maxLon);
+   }
+   void setMinMaxHeight(double minHeight, double maxHeight)
+   {
+      theMinHeight = ossim::min(minHeight, maxHeight);
+      theMaxHeight = ossim::max(minHeight, maxHeight);
+   }
+   void setMinMaxScale(double minScale,
+                       double maxScale)
+   {
+      theMinScale = ossim::min(minScale, maxScale);
+      theMaxScale = ossim::max(minScale, maxScale);
+   }
+   bool intersectsLatLon(const double& minLat, const double& minLon,
+                         const double& maxLat, const double& maxLon)const
+   {
+      double tempMinLon = ossim::max(theMinLon, minLon);
+      double tempMaxLon = ossim::min(theMaxLon, maxLon);
+      double tempMinLat = ossim::max(theMinLat, minLat);
+      double tempMaxLat = ossim::min(theMaxLat, maxLat);
+
+      return ((tempMinLon <= tempMaxLon)&&(tempMinLat<=tempMaxLat));
+      
+   }
+   bool intersectsLatLon(const ossimPlanetExtents& extents)const
+   {
+      return intersectsLatLon(extents.theMinLat, extents.theMinLon,
+                              extents.theMaxLat, extents.theMaxLon);
+   }
+
+   bool intersectsHeight(const double& minHeight, const double& maxHeight)const
+   {
+      return (ossim::max(minHeight,
+                       theMinHeight) <=
+              ossim::min(maxHeight,
+                       theMaxHeight));
+   }
+   bool intersectsHeight(const ossimPlanetExtents& extents)const
+   {
+      return intersectsHeight(extents.theMinHeight,
+                              extents.theMaxHeight);
+   }
+   bool intersectsScale(const double& minScale,
+                        const double& maxScale)const
+   {
+      return (ossim::max(minScale,
+                         theMinScale) <=
+              ossim::min(maxScale,
+                         theMaxScale));      
+   }
+   
+   bool intersectsScale(const ossimPlanetExtents& extents)const
+   {
+      return intersectsScale(extents.theMinScale,
+                             extents.theMaxScale);
+   }
+
+   bool intersectsModifiedJulianDate(const double& minDate,
+                                     const double& maxDate)const
+   {
+      return (ossim::max(minDate, theMinDate.getModifiedJulian()) <=
+              ossim::min(maxDate, theMaxDate.getModifiedJulian()));
+   }
+   bool intersectsDate(const ossimPlanetExtents& extents)const
+   {
+      return intersectsModifiedJulianDate(extents.theMinDate.getModifiedJulian(),
+                                          extents.theMaxDate.getModifiedJulian());
+   }
+
+   bool equal(osg::ref_ptr<ossimPlanetExtents> extents)const
+   {
+      if(extents.valid())
+      {
+         return equal(*extents.get());
+      }
+      return false;
+   }
+   bool equal(const ossimPlanetExtents& extents)const
+   {
+      return (ossim::almostEqual(theMinLon, extents.theMinLon, DBL_EPSILON)&&
+              ossim::almostEqual(theMaxLon, extents.theMaxLon, DBL_EPSILON)&&
+              ossim::almostEqual(theMinLat, extents.theMinLat, DBL_EPSILON)&&
+              ossim::almostEqual(theMaxLat, extents.theMaxLat, DBL_EPSILON)&&
+              ossim::almostEqual(theMinScale, extents.theMinScale, DBL_EPSILON)&&
+              ossim::almostEqual(theMaxScale, extents.theMaxScale, DBL_EPSILON)&&
+              ossim::almostEqual(theMinHeight, extents.theMinHeight, DBL_EPSILON)&&
+              ossim::almostEqual(theMaxHeight, extents.theMaxHeight, DBL_EPSILON)&&
+              (theMinDate == extents.theMinDate)&&
+              (theMaxDate == extents.theMaxDate));
+   }
+   bool intersects(const ossimPlanetExtents& extents)const
+   {
+      return (intersectsDate(extents)&&
+              intersectsScale(extents)&&
+              intersectsHeight(extents)&&
+              intersectsLatLon(extents));
+   }
+   double getMinLat()const
+   {
+      return theMinLat;
+   }
+   double getMinLon()const
+   {
+      return theMinLon;
+   }
+   double getMaxLat()const
+   {
+      return theMaxLat;
+   }
+   double getMaxLon()const
+   {
+      return theMaxLon;
+   }
+   double getMinScale()const
+   {
+      return theMinScale;
+   }
+   double getMaxScale()const
+   {
+      return theMaxScale;
+   }
+   double getMinHeight()const
+   {
+      return theMinHeight;
+   }
+   double getMaxHeight()const
+   {
+      return theMaxHeight;
+   }
+   const ossimDate& getMinDate()const
+   {
+      return theMinDate;
+   }
+   const ossimDate& getMaxDate()const
+   {
+      return theMaxDate;
+   }
+
+   void combineMinMaxLatLon(const double& minLat,
+                            const double& minLon,
+                            const double& maxLat,
+                            const double& maxLon)
+   {
+      theMinLat = ossim::min(minLat, theMinLat);
+      theMinLon = ossim::min(minLon, theMinLon);
+      theMaxLat = ossim::max(maxLat, theMaxLat);
+      theMaxLon = ossim::max(maxLon, theMaxLon);
+   }
+   void combineHeights(const double& minHeight,
+                       const double& maxHeight)
+   {
+      theMaxHeight = ossim::max(maxHeight, theMaxHeight);
+      theMinHeight = ossim::min(minHeight, theMinHeight);
+   }
+   void combineScale(const double& minScale,
+                     const double& maxScale)
+   {
+      theMinScale = ossim::min(theMinScale, minScale);
+      theMaxScale = ossim::max(theMaxScale, maxScale);
+   }
+   void combineDate(const ossimDate& minDate,
+                    const ossimDate& maxDate)
+   {
+      if(minDate.getModifiedJulian() < theMinDate.getModifiedJulian())
+      {
+         theMinDate = minDate;
+      }
+      if(maxDate.getModifiedJulian() > theMaxDate.getModifiedJulian())
+      {
+         theMaxDate = maxDate;
+      }
+      
+   }
+   void combine(const ossimPlanetExtents* extents)
+   {
+      if(!extents) return;
+      combineMinMaxLatLon(extents->theMinLat,
+                          extents->theMinLon,
+                          extents->theMaxLat,
+                          extents->theMaxLon);
+      combineHeights(extents->theMinHeight,
+                     extents->theMaxHeight);
+      combineScale(extents->theMinScale,
+                   extents->theMaxScale);
+      combineDate(extents->theMinDate,
+                  extents->theMaxDate);
+     
+   }
+   ossimRefPtr<ossimXmlNode> saveXml()const
+   {
+      ossimRefPtr<ossimXmlNode> result  = new ossimXmlNode();
+      result->setTag("ossimPlanetExtents");
+      ossimRefPtr<ossimXmlNode> minDate = new ossimXmlNode();
+      ossimRefPtr<ossimXmlNode> maxDate = new ossimXmlNode();
+      result->addChildNode("minLat", ossimString::toString(theMinLat));
+      result->addChildNode("maxLat", ossimString::toString(theMaxLat));
+      result->addChildNode("minLon", ossimString::toString(theMinLon));
+      result->addChildNode("maxLon", ossimString::toString(theMaxLon));
+      result->addChildNode("minScale", ossimString::toString(theMinScale));
+      result->addChildNode("maxScale", ossimString::toString(theMaxScale));
+      result->addChildNode("minHeight", ossimString::toString(theMinHeight));
+      result->addChildNode("maxHeight", ossimString::toString(theMaxHeight));
+
+      minDate->setTag("minDate");
+      maxDate->setTag("maxDate");
+      minDate->addChildNode(theMinDate.saveXml().get());
+      maxDate->addChildNode(theMaxDate.saveXml().get());
+      
+      result->addChildNode(minDate.get());
+      result->addChildNode(maxDate.get());
+      
+      return result.get();
+   }
+   bool loadXml(ossimRefPtr<ossimXmlNode> extentsNode)
+   {
+      if(!extentsNode.valid()) return false;
+      bool result = true;
+
+      ossimRefPtr<ossimXmlNode> minLat = extentsNode->findFirstNode("minLat");
+      ossimRefPtr<ossimXmlNode> maxLat = extentsNode->findFirstNode("maxLat");
+      ossimRefPtr<ossimXmlNode> minLon = extentsNode->findFirstNode("minLon");
+      ossimRefPtr<ossimXmlNode> maxLon = extentsNode->findFirstNode("maxLon");
+      ossimRefPtr<ossimXmlNode> minScale = extentsNode->findFirstNode("minScale");
+      ossimRefPtr<ossimXmlNode> maxScale = extentsNode->findFirstNode("maxScale");
+      ossimRefPtr<ossimXmlNode> minHeight = extentsNode->findFirstNode("minHeight");
+      ossimRefPtr<ossimXmlNode> maxHeight = extentsNode->findFirstNode("maxHeight");
+      ossimRefPtr<ossimXmlNode> minDate = extentsNode->findFirstNode("minDate");
+      ossimRefPtr<ossimXmlNode> maxDate = extentsNode->findFirstNode("maxDate");
+
+      if(minLat.valid()&&maxLat.valid()&&
+         minLon.valid()&&maxLon.valid()&&
+         minScale.valid()&&maxScale.valid()&&
+         minHeight.valid()&&maxHeight.valid()&&
+         minDate.valid()&&maxDate.valid())
+      {
+         theMinLat = minLat->getText().toDouble();
+         theMaxLat = maxLat->getText().toDouble();
+         theMinLon = minLon->getText().toDouble();
+         theMaxLon = maxLon->getText().toDouble();
+         theMinScale = minScale->getText().toDouble();
+         theMaxScale = maxScale->getText().toDouble();
+         theMinHeight = minHeight->getText().toDouble();
+         theMaxHeight = maxHeight->getText().toDouble();
+         if(!theMinDate.loadXml(minDate.get()))
+         {
+            result = false;
+         }
+         if(!theMaxDate.loadXml(maxDate.get()))
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+      
+      return result;
+   }
+   ossimString toString()const
+   {
+      ossimString result;
+      
+      result += "theMinLon: " + ossimString::toString(theMinLon) + "\n";
+      result += "theMaxLon: " + ossimString::toString(theMaxLon) + "\n";
+      result += "theMinLat: " + ossimString::toString(theMinLat) + "\n";
+      result += "theMaxLat: " + ossimString::toString(theMaxLat) + "\n";
+      result += "theMinScale: " + ossimString::toString(theMinScale) + "\n";
+      result += "theMaxScale: " + ossimString::toString(theMaxScale) + "\n";
+      result += "theMinHeight: " + ossimString::toString(theMinHeight) + "\n";
+      result += "theMaxHeight: " + ossimString::toString(theMaxHeight);
+      return result;
+   }
+protected:
+   ~ossimPlanetExtents()
+   {
+   }
+   double    theMinLon;
+   double    theMaxLon;
+   double    theMinLat;
+   double    theMaxLat;
+   double    theMinScale;
+   double    theMaxScale;
+   double    theMinHeight;
+   double    theMaxHeight;
+   ossimDate theMinDate;
+   ossimDate theMaxDate;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetFadeText.h b/ossimPlanet/include/ossimPlanet/ossimPlanetFadeText.h
new file mode 100644
index 0000000..2aa9d08
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetFadeText.h
@@ -0,0 +1,77 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * OpenSceneGraph Public License for more details.
+*/
+
+#ifndef ossimPlanetFadeText_HEADER
+#define ossimPlanetFadeText_HEADER 1
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osgText/Text>
+#include <ossim/base/ossimConstants.h>
+#include <osg/ClusterCullingCallback>
+
+class OSSIMPLANET_DLL ossimPlanetFadeText : public osgText::Text
+{
+public:
+   ossimPlanetFadeText();
+   ossimPlanetFadeText(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   
+   META_Object(osgText, ossimPlanetFadeText)
+      
+      
+   /**
+    * Set the speed that the alpha value changes as the text is occluded or becomes visible.
+    *
+    */
+   void setFadeSpeed(float speed) { theFadeSpeed = speed; }
+   float fadeSpeed()const{return theFadeSpeed;}
+   void setVisibleFlag(bool visible){theVisibleFlag = visible;}
+   bool visibleFlag()const{return theVisibleFlag;}
+ 	float opacity()const{return theCurrentOpacity;}
+	void setOpacity(float value){theCurrentOpacity = value;}
+	void setClusterCullingCallback(osg::ref_ptr<osg::ClusterCullingCallback> callback)
+      {
+         theClusterCull = callback;
+      }
+   osg::ref_ptr<osg::ClusterCullingCallback> clusterCullingCallback()
+      {
+         return theClusterCull;
+      }
+   const osg::ref_ptr<osg::ClusterCullingCallback> clusterCullingCallback()const
+      {
+         return theClusterCull;
+      }
+   /** Draw the text.*/
+   virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
+
+protected:
+
+   virtual ~ossimPlanetFadeText() {}
+   
+   void init();
+   
+   struct FadeTextUpdateCallback;
+   struct FadeTextCullCallback;
+   friend struct FadeTextUpdateCallback;
+   friend struct FadeTextCullCallback;
+   
+   float theFadeSpeed;
+   float theCurrentOpacity;
+   bool  theVisibleFlag;
+   ossim_uint32 theFrameNumber;
+   osg::ref_ptr<osg::ClusterCullingCallback> theClusterCull;
+   
+   osg::Vec4d theForegroundColor;
+   osg::Vec4d theBackgroundColor;
+   //    mutable ViewBlendColourMap _viewBlendColourMap;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h
new file mode 100644
index 0000000..4ac6ca3
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h
@@ -0,0 +1,63 @@
+#ifndef ossimPlanetGeneralRasterElevationDatabase_HEADER
+#define ossimPlanetGeneralRasterElevationDatabase_HEADER
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <osg/Timer>
+#include <ossim/elevation/ossimGeneralRasterElevHandler.h>
+class OSSIMPLANET_DLL ossimPlanetGeneralRasterElevationDatabase : public ossimPlanetElevationDatabase
+{
+public:
+   ossimPlanetGeneralRasterElevationDatabase();
+   ossimPlanetGeneralRasterElevationDatabase(const ossimPlanetGeneralRasterElevationDatabase& src);
+   virtual ~ossimPlanetGeneralRasterElevationDatabase();
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+   virtual ossimPlanetTextureLayerStateCode open(const std::string& location);
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& theGrid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+   
+protected:
+   class GeneralRasterInfo : public osg::Referenced
+   {
+   public:
+      double                        theMinLat, theMinLon, theMaxLat, theMaxLon;
+      std::string                   theFilename;
+      ossimRefPtr<ossimGeneralRasterElevHandler> theGeneralRasterHandler;
+      bool                          theOpenFlag;
+      osg::Timer_t                  theTimeStamp;
+   };
+   typedef std::vector<osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> > GeneralRasterFilePointerList;
+
+   osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> getHandlerInfo(const double& lat,
+                                                                                             const double& lon);
+   //void shrinkFilePointers();
+/*    ossimFilename buildFilename(double lat, double lon)const; */
+/*    osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::SrtmInfo> findSrtmInfo(const std::string& srtmName); */
+   
+   std::string                            theLocation;
+   mutable bool                           theOpenFlag;
+   ossim_uint32                           theMaxOpenFiles;
+   ossim_uint32                           theMinOpenFiles;
+   GeneralRasterFilePointerList           theFilePointers;
+   mutable ossim_int32                    theCurrentInfoIdx;
+/*    ossimRefPtr<ossimMapProjection>        theProjection; */
+/*    ossimRefPtr<ossimImageRenderer>        theRenderer; */
+/*    ossimRefPtr<ossimOrthoImageMosaic>     theMosaic; */
+/*    ossim_float32                          theNullHeightValue; */
+    
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetGeoRefModel.h b/ossimPlanet/include/ossimPlanet/ossimPlanetGeoRefModel.h
new file mode 100644
index 0000000..2539328
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetGeoRefModel.h
@@ -0,0 +1,370 @@
+#ifndef ossimPlanetGeoRefModel_HEADER
+#define ossimPlanetGeoRefModel_HEADER
+#include <osg/Referenced>
+#include <osg/Vec3d>
+#include <osg/CoordinateSystemNode>
+#include <ossim/base/ossimLsrSpace.h>
+#include <ossim/base/ossimMatrix4x4.h>
+#include <ossim/base/ossimEllipsoid.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimGeoid.h>
+#include <ossim/base/ossimEcefPoint.h>
+#include <ossim/base/ossimEcefVector.h>
+#include <ossim/base/ossimGeoidManager.h>
+#include <ossim/elevation/ossimElevManager.h>
+
+class OSSIMPLANET_DLL ossimPlanetGeoRefModel : public osg::Referenced
+{
+public:
+   ossimPlanetGeoRefModel()
+      :theGeoid(ossimGeoidManager::instance()->findGeoidByShortName("geoid1996", false))
+   {
+   }
+   virtual void latLonHeightToXyz(const osg::Vec3d& input,
+                                  osg::Vec3d& output)const=0;
+   virtual void xyzToLatLonHeight(const osg::Vec3d& input,
+                                  osg::Vec3d& output)const=0;
+   virtual void latLonHeightMslToXyz(const osg::Vec3d& input,
+                                  osg::Vec3d& output)
+   {
+      osg::Vec3d llh(input);
+      mslToEllipsoidal(llh);
+      latLonHeightToXyz(llh, output);
+   }
+   virtual void xyzToLatLonHeightMsl(const osg::Vec3d& input,
+                                     osg::Vec3d& output)
+   {
+      xyzToLatLonHeight(input, output);
+      ellipsoidalToMsl(output);
+   }
+   virtual void forward(const osg::Vec3d& input,
+                        osg::Vec3d& output)const
+   {
+      latLonHeightToXyz(input, output);
+   }
+   virtual void inverse(const osg::Vec3d& input,
+                        osg::Vec3d& output)const
+   {
+      xyzToLatLonHeight(input, output);
+   }
+   virtual void normal(const osg::Vec3d& input,
+                       osg::Vec3d& output)const
+   {
+      output = input;
+      output.normalize();
+   }
+
+   /**
+    * This will take a lat lon height and shift the height to the ellipsoid
+    */ 
+   virtual void mslToEllipsoidal(osg::Vec3d& llh)
+   {
+      llh[2] += getGeoidOffset(llh[0],llh[1]);
+   }
+   
+   /**
+    * This will take a lat lon height and shift the height to the Mean Sea Level.
+    * This assumes the height you passed in was Ellipsoidal
+    */ 
+   virtual void ellipsoidalToMsl(osg::Vec3d& llh)
+   {
+      llh[2] -= getGeoidOffset(llh[0],llh[1]);
+   }
+   virtual double getHeightAboveMsl(const double& lat, const double& lon)
+   {
+      double result = ossimElevManager::instance()->getHeightAboveMSL(ossimGpt(lat, lon));
+      if(ossim::isnan(result))
+      {
+         result = 0.0;
+      }
+      return result;
+   }
+   virtual double getGeoidOffset(const double& lat, const double& lon)
+   {
+      double result = 0.0;
+      if(theGeoid.valid())
+      {
+         result = theGeoid->offsetFromEllipsoid(ossimGpt(lat,lon));
+         if(ossim::isnan(result))
+         {
+            result = 0.0;
+         }
+      }
+      return result;
+   }
+   virtual double getHeightAboveEllipsoid(const double& lat, const double& lon)
+   {
+      double result =  ossimElevManager::instance()->getHeightAboveEllipsoid(ossimGpt(lat, lon));
+      if(ossim::isnan(result))
+      {
+         if(theGeoid.valid())
+         {
+            result = theGeoid->offsetFromEllipsoid(ossimGpt(lat,lon));
+            if(ossim::isnan(result))
+            {
+               result = 0.0;
+            }
+         }
+         else
+         {
+            result = 0.0;
+         }
+      }
+
+      return result;
+   }
+   virtual void lsrMatrix(const osg::Vec3d& /*latLonHeight*/,
+                          osg::Matrixd& output,
+                          double /*heading*/=0.0,
+                          bool /*rotationOnlyFlag*/=false)const
+   {
+      output = osg::Matrixd();
+   }
+   virtual void orientationLsrMatrix(osg::Matrixd& result,
+                                     const osg::Vec3d& llh,
+                                     double h, double p, double r)const
+   {
+      lsrMatrix(llh, result, 0.0);
+      
+      NEWMAT::Matrix orien = ossimMatrix4x4::createRotationZMatrix(h, OSSIM_RIGHT_HANDED)*
+      ossimMatrix4x4::createRotationXMatrix(p, OSSIM_LEFT_HANDED)*
+      ossimMatrix4x4::createRotationYMatrix(r, OSSIM_LEFT_HANDED);
+      osg::Matrixd tempM(orien[0][0], orien[1][0], orien[2][0], 0.0,
+                         orien[0][1], orien[1][1], orien[2][1], 0.0,
+                         orien[0][2], orien[1][2], orien[2][2], 0.0,
+                         0.0, 0.0, 0.0, 1.0);
+      
+      result = tempM*result;
+   }
+/*    virtual void computeLocalToWorldTransform(const osg::Vec3d& input, */
+/*                                              osg::Matrixd& output)const=0; */
+   virtual double calculateUnnormalizedLengthXyz(const osg::Vec3d& p1,
+                                                 const osg::Vec3d& p2)const
+   {
+      return calculateUnnormalizedLength((p1-p2).length());
+   }
+   virtual double calculateUnnormalizedLength(double delta)const
+   {
+      return getNormalizationScale()*delta;
+   }
+   virtual double getNormalizationScale()const
+   {
+      return 1.0;
+   }
+   virtual double getInvNormalizationScale()const
+   {
+      return 1.0;
+   }
+   const ossimRefPtr<ossimGeoid> geoid()const
+   {
+      return theGeoid;
+   }
+   void setGeoid(ossimRefPtr<ossimGeoid> geoid)
+   {
+      theGeoid = geoid.get();
+   }
+protected:
+   ossimRefPtr<ossimGeoid> theGeoid;
+   
+};
+
+
+class ossimPlanetEllipsoidModel : public ossimPlanetGeoRefModel
+{
+public:
+   ossimPlanetEllipsoidModel(double radiusEquator = osg::WGS_84_RADIUS_EQUATOR,
+                             double radiusPolar   = osg::WGS_84_RADIUS_POLAR)
+      :theModel(radiusEquator, radiusPolar)
+   {
+   }
+
+
+   virtual void lsrMatrix(const osg::Vec3d& latLonHeight,
+                          osg::Matrixd& output,
+                          double heading=0.0,
+                          bool rotationOnlyFlag=false)const
+   {
+      osg::Vec3d xyz;
+      ossimLsrSpace lsrSpace;
+      lsrSpace = ossimLsrSpace(ossimGpt(latLonHeight[0],
+                                        latLonHeight[1],
+                                        latLonHeight[2]),
+                               heading);//,
+      if(!rotationOnlyFlag)
+      {
+         latLonHeightToXyz(latLonHeight, xyz);
+      }
+      ossimMatrix4x4 lsrMatrix(lsrSpace.lsrToEcefRotMatrix());
+      NEWMAT::Matrix compositeMatrix = lsrMatrix.getData();
+/*       compositeMatrix = compositeMatrix.t(); */
+      output = osg::Matrixd(compositeMatrix[0][0], compositeMatrix[1][0], compositeMatrix[2][0], 0.0,
+                            compositeMatrix[0][1], compositeMatrix[1][1], compositeMatrix[2][1], 0.0,
+                            compositeMatrix[0][2], compositeMatrix[1][2], compositeMatrix[2][2], 0.0,
+                            xyz[0], xyz[1], xyz[2], 1.0);
+   }
+   virtual void latLonHeightToXyz(const osg::Vec3d& input,
+                                  osg::Vec3d& output)const
+   {
+      theModel.latLonHeightToXYZ(input[0],
+                                 input[1],
+                                 input[2],
+                                 output[0],
+                                 output[1],
+                                 output[2]);
+   }
+   virtual void xyzToLatLonHeight(const osg::Vec3d& input,
+                        osg::Vec3d& output)const
+   {
+      theModel.XYZToLatLonHeight(input[0],
+                                 input[1],
+                                 input[2],
+                                 output[0],
+                                 output[1],
+                                 output[2]);
+   }
+   virtual void normal(const osg::Vec3d& input,
+                       osg::Vec3d& output)const
+   {
+      ossimEcefPoint location(input[0], input[1], input[2]);
+      ossimEcefVector gradient;
+      theModel.gradient(location, gradient);
+      output[0] = gradient.x();
+      output[1] = gradient.y();
+      output[2] = gradient.z();
+   }
+protected:
+   ossimEllipsoid theModel;
+/*    osg::ref_ptr<osg::EllipsoidModel> theModel; */
+};
+
+class ossimPlanetNormalizedEllipsoidModel : public ossimPlanetEllipsoidModel
+{
+public:
+   ossimPlanetNormalizedEllipsoidModel(double radiusEquator = osg::WGS_84_RADIUS_EQUATOR,
+                                           double radiusPolar   = osg::WGS_84_RADIUS_POLAR)
+      :ossimPlanetEllipsoidModel(radiusEquator, radiusPolar)
+   {
+      theNormalizationScale    = osg::WGS_84_RADIUS_EQUATOR;
+      theInvNormalizationScale = 1.0/osg::WGS_84_RADIUS_EQUATOR;
+   }
+      
+   virtual void latLonHeightToXyz(const osg::Vec3d& input,
+                                  osg::Vec3d& output)const
+   {
+      theModel.latLonHeightToXYZ(input[0],
+                                 input[1],
+                                 input[2],
+                                 output[0],
+                                 output[1],
+                                 output[2]);
+      output[0]*=theInvNormalizationScale;
+      output[1]*=theInvNormalizationScale;
+      output[2]*=theInvNormalizationScale;
+      
+   }
+   virtual void xyzToLatLonHeight(const osg::Vec3d& input,
+                        osg::Vec3d& output)const
+   {
+      
+      theModel.XYZToLatLonHeight(input[0]*theNormalizationScale,
+                                 input[1]*theNormalizationScale,
+                                 input[2]*theNormalizationScale,
+                                 output[0],
+                                 output[1],
+                                 output[2]);
+   }
+   virtual void lsrMatrix(const osg::Vec3d& latLonHeight,
+                          osg::Matrixd& output,
+                          bool rotationOnlyFlag=false)const
+   {
+      osg::Vec3d xyz;
+      ossimLsrSpace lsrSpace;
+      lsrSpace = ossimLsrSpace(ossimGpt(latLonHeight[0],
+                                        latLonHeight[1],
+                                        latLonHeight[2]),
+                               0.0);//,
+      if(!rotationOnlyFlag)
+      {// make sure that the x,y,z are normalized.
+         latLonHeightToXyz(latLonHeight, xyz);
+         xyz[0] *= theNormalizationScale;
+         xyz[1] *= theNormalizationScale;
+         xyz[2] *= theNormalizationScale;
+      }
+      ossimMatrix4x4 lsrMatrix(lsrSpace.lsrToEcefRotMatrix());
+      NEWMAT::Matrix compositeMatrix = lsrMatrix.getData();
+/*       compositeMatrix = compositeMatrix.t(); */
+      output = osg::Matrixd(compositeMatrix[0][0], compositeMatrix[1][0], compositeMatrix[2][0], 0.0,
+                            compositeMatrix[0][1], compositeMatrix[1][1], compositeMatrix[2][1], 0.0,
+                            compositeMatrix[0][2], compositeMatrix[1][2], compositeMatrix[2][2], 0.0,
+                            xyz[0], xyz[1], xyz[2], 1.0);
+   }
+   virtual double getNormalizationScale()const
+   {
+      return theNormalizationScale;
+   }
+   virtual double getInvNormalizationScale()const
+   {
+      return theInvNormalizationScale;
+   }
+
+protected:
+   double theNormalizationScale;
+   double theInvNormalizationScale;
+};
+
+#if 0
+class ossimPlanetFlatLandModel : public ossimPlanetLandModel
+{
+public:
+   ossimPlanetFlatLandModel(){}
+   virtual void latLonHeightToXyz(const osg::Vec3d& input,
+                        osg::Vec3d& output)const
+   {
+      output[0] = input[1];
+      output[1] = input[0];
+      output[2] = input[2];
+   }
+   virtual void computeLocalToWorldTransform(const osg::Vec3d& /* input */,
+                                             osg::Matrixd& /* output */)const
+   {
+      // left blank for now so the matrix will not change
+   }
+   virtual void xyzToLatLonHeight(const osg::Vec3d& input,
+                                  osg::Vec3d& output)const
+   {
+      output[0] = input[1];
+      output[1] = input[0];
+      output[2] = input[2];
+   }
+   virtual void normal(const osg::Vec3d& input,
+                       osg::Vec3d& output)const
+   {
+      if(theNormalModel.valid())
+      {
+         osg::Vec3d tempVec;
+         osg::Vec3d tempVec2;
+         xyzToLatLonHeight(input, tempVec);
+         theNormalModel->forward(tempVec, tempVec2);
+         theNormalModel->normal(tempVec2,
+                                output);
+         output[0] *=-1.0;
+         output[1] *=-1.0;
+         output[2] *=-1.0;
+      }
+      else
+      {
+         output[0] = 0.0;
+         output[1] = 0.0;
+         output[2] = -1.0;
+      }
+   }
+   virtual void changeNormalModel(osg::ref_ptr<ossimPlanetLandModel> normalModel)
+   {
+      theNormalModel = normalModel;
+   }
+   
+   osg::ref_ptr<ossimPlanetLandModel> theNormalModel;
+};
+#endif
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetGeocoder.h b/ossimPlanet/include/ossimPlanet/ossimPlanetGeocoder.h
new file mode 100644
index 0000000..f411b05
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetGeocoder.h
@@ -0,0 +1,82 @@
+#ifndef ossimPlanetGeocoder_HEADER
+#define ossimPlanetGeocoder_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimString.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetGoecoder : public osg::Referenced
+{
+public:
+   class OSSIMPLANET_DLL ossimPlanetGeocoderLocation : public osg::Referenced
+   {
+   public:
+      ossimPlanetGeocoderLocation();
+
+      void setLocation(const ossimGpt& location);
+      ossimGpt getLocation()const;
+      void setName(const ossimString& name);
+      ossimString getName()const;
+      void setAddress(const ossimString& address);
+      ossimString getAddress()const;
+      
+   protected:      
+      ossimRefPtr<ossimXmlNode> theMetaInformation; // modeled after the GOOGLE KML
+      ossimRefPtr<ossimXmlNode> theNameNode;
+      ossimRefPtr<ossimXmlNode> thePlacemarkNode;
+      ossimRefPtr<ossimXmlNode> theAddressNode;
+      ossimRefPtr<ossimXmlNode> thePointNode;
+      ossimRefPtr<ossimXmlNode> theCoordinatesNode;
+   };
+   virtual void getLocationFromAddress(std::vector<osg::ref_ptr<ossimPlanetGeocoderLocation> >& result,
+                                       const ossimString& address,
+                                       const ossimString& city,
+                                       const ossimString& state,
+                                       const ossimString& zip,
+                                       const ossimString& /*country*/)const
+   {
+      ossimString location;
+      if(!address.trim().empty())
+      {
+         location += address;
+      }
+
+      if(!city.trim().empty())
+      {
+         if(!location.empty())
+         {
+            location += ",";
+         }
+         location += city;
+      }
+
+      if(!state.trim().empty())
+      {
+         if(!location.empty())
+         {
+            location += ",";
+         }
+         location += state;
+      }
+
+      if(!zip.trim().empty())
+      {
+         if(!location.empty())
+         {
+            location += ",";
+         }
+         location += zip;
+      }
+      
+      getLocationFromAddress(result, location);
+      
+   }
+   virtual void getLocationFromAddress(std::vector<osg::ref_ptr<ossimPlanetGeocoderLocation> >& result,
+                                       const ossimString& location)const=0;   
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetGrid.h b/ossimPlanet/include/ossimPlanet/ossimPlanetGrid.h
new file mode 100644
index 0000000..8f8e761
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetGrid.h
@@ -0,0 +1,310 @@
+#ifndef ossimPlanetGrid_HEADER
+#define ossimPlanetGrid_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetTerrainTileId.h>
+#include <ossimPlanet/ossimPlanetExtents.h>
+#include <osg/Referenced>
+#include <osg/Vec3d>
+#include <osg/Vec2d>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimDrect.h>
+#include <vector>
+#include <iostream>
+
+// this is here temporarily until everyone uses the new grid interface.  This will be used to
+// crate a backward comapatable grid type
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+
+class OSSIMPLANET_DLL ossimPlanetGrid : public osg::Referenced
+{
+public:
+   enum IndexValues
+   {
+      LAT_IDX = 0,
+      LON_IDX = 1,
+      HGT_IDX = 2,
+      X_IDX = 0,
+      Y_IDX = 1,
+      Z_IDX = 2
+   };
+   enum ModelType
+   {
+      UNKNOWN        = 0,
+      GEODETIC_MODEL = 1
+   };
+   class LocalNdcPoint
+      {
+      public:
+         LocalNdcPoint(ossim_float64 xValue=0.0,
+                       ossim_float64 yValue=0.0,
+                       ossim_float64 zValue=0.0)
+         {
+            setX(xValue);
+            setY(yValue);
+            setZ(zValue);
+         }
+         void setX(ossim_float64 value){theXYZ[ossimPlanetGrid::X_IDX] = value;}
+         void setY(ossim_float64 value){theXYZ[ossimPlanetGrid::Y_IDX] = value;}
+         void setZ(ossim_float64 value){theXYZ[ossimPlanetGrid::Z_IDX] = value;}
+         ossim_float64 x()const{return theXYZ[ossimPlanetGrid::X_IDX];}
+         ossim_float64 y()const{return theXYZ[ossimPlanetGrid::Y_IDX];}
+         ossim_float64 z()const{return theXYZ[ossimPlanetGrid::Z_IDX];}
+         osg::Vec3d theXYZ;
+      };
+   class GridPoint
+      {
+      public:
+         friend std::ostream& operator <<(std::ostream& out, const ossimPlanetGrid::GridPoint& point)
+         {
+            return out << "<" << point.theFace << ", " << point.theXYZ[ossimPlanetGrid::X_IDX] << ", " << point.theXYZ[ossimPlanetGrid::Y_IDX] << ", " << point.theXYZ[ossimPlanetGrid::Z_IDX] << ">";
+         }
+         GridPoint()
+         :theFace(0)
+         {
+            theXYZ[0]=0.0;
+            theXYZ[1]=0.0;
+            theXYZ[2]=0.0;
+         }
+         GridPoint(ossim_uint32 face,
+                   ossim_float64 x, ossim_float64 y, ossim_float64 z=0.0)
+         :theFace(face)
+         {
+            theXYZ[ossimPlanetGrid::X_IDX]=x;
+            theXYZ[ossimPlanetGrid::Y_IDX]=y;
+            theXYZ[ossimPlanetGrid::Z_IDX]=z;
+         }
+         GridPoint(ossim_uint32 face,
+                   osg::Vec3d& xyz)
+         :theFace(face),
+         theXYZ(xyz)
+         {
+         }
+         void setX(ossim_float64 value){theXYZ[ossimPlanetGrid::X_IDX] = value;}
+         void setY(ossim_float64 value){theXYZ[ossimPlanetGrid::Y_IDX] = value;}
+         void setZ(ossim_float64 value){theXYZ[ossimPlanetGrid::Z_IDX] = value;}
+         ossim_float64 x()const{return theXYZ[ossimPlanetGrid::X_IDX];}
+         ossim_float64 y()const{return theXYZ[ossimPlanetGrid::Y_IDX];}
+         ossim_float64 z()const{return theXYZ[ossimPlanetGrid::Z_IDX];}
+         ossim_uint32 face()const{return theFace;}
+         void setFace(ossim_uint32 face){theFace = face;}
+       
+         ossim_uint32 theFace;
+         osg::Vec3d theXYZ;
+      };
+   class GridBound
+      {
+      public:
+         friend std::ostream& operator <<(std::ostream& out, const ossimPlanetGrid::GridBound& bound)
+         {
+            return out << "<" << bound.face() << "," 
+                       << bound.minx() << ", " 
+                       << bound.miny() << ", " 
+                       << bound.maxx() << ","
+                       << bound.maxy() << ">";
+         }
+         ossim_float64 minx()const{return theMinx;}
+         ossim_float64 miny()const{return theMiny;}
+         ossim_float64 maxx()const{return theMinx+theWidth;}
+         ossim_float64 maxy()const{return theMiny+theHeight;}
+         ossim_float64 width()const{return theWidth;}
+         ossim_float64 height()const{return theHeight;}
+         void setFace(ossim_uint32 face){theFace = face;}
+         ossim_uint32 face()const{return theFace;}
+         ossimDrect toDrect()const
+         {
+            return ossimDrect(theMinx, 
+                              theMiny+theHeight, 
+                              theMinx+theWidth, 
+                              theMiny, OSSIM_RIGHT_HANDED);
+         }
+         ossim_uint32  theFace;
+         ossim_float64 theMinx;
+         ossim_float64 theMiny;
+         ossim_float64 theWidth;
+         ossim_float64 theHeight;
+      };
+   class ModelPoint
+      {
+      public:
+         friend std::ostream& operator <<(std::ostream& out, const ossimPlanetGrid::ModelPoint& point)
+         {
+            return out << "<" << point.theXYZ[ossimPlanetGrid::X_IDX] << ", " << point.theXYZ[ossimPlanetGrid::Y_IDX] << ", " << point.theXYZ[ossimPlanetGrid::Z_IDX] << ">";
+         }
+         ModelPoint()
+         {
+            theXYZ[0]=0.0;
+            theXYZ[1]=0.0;
+            theXYZ[2]=0.0;
+         }
+         ModelPoint(double x, double y, double z=0)
+         {
+            theXYZ[0] = x;
+            theXYZ[1] = y;
+            theXYZ[2] = z;
+         }
+         void setX(ossim_float64 value){theXYZ[ossimPlanetGrid::X_IDX] = value;}
+         void setY(ossim_float64 value){theXYZ[ossimPlanetGrid::Y_IDX] = value;}
+         void setZ(ossim_float64 value){theXYZ[ossimPlanetGrid::Z_IDX] = value;}
+         ossim_float64 x()const{return theXYZ[ossimPlanetGrid::X_IDX];}
+         ossim_float64 y()const{return theXYZ[ossimPlanetGrid::Y_IDX];}
+         ossim_float64 z()const{return theXYZ[ossimPlanetGrid::Z_IDX];}
+         
+         osg::Vec3d theXYZ;
+      };
+   typedef std::vector<ossimPlanetTerrainTileId> TileIds;
+   typedef std::vector<ModelPoint> ModelPoints;
+   typedef std::vector<GridPoint> GridPoints;
+   typedef std::vector<GridBound> GridBounds;
+   
+   ossimPlanetGrid(ossimPlanetGrid::ModelType type)
+   :theModelType(type)
+   {
+   }
+   ossimPlanetGrid::ModelType modelType()const
+   {
+      return theModelType;
+   }
+   virtual void getRootIds(TileIds &ids) const=0;
+   void getInternationalDateLineCrossings(const ossimPlanetTerrainTileId& tileid,
+                                          std::vector<osg::Vec2d>& minMaxPairs)const;
+   virtual bool crossesInternationalDateLine(const ossimPlanetTerrainTileId& tileId)const;
+   virtual void createModelPoints(const ossimPlanetTerrainTileId& tileId,
+                                  ossim_uint32 w,
+                                  ossim_uint32 h,
+                                  ModelPoints& modelPoints,
+                                  ossim_uint32 padding=0)const;
+   virtual void globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const=0;
+   virtual void modelToGlobalGrid(const ModelPoint& modelPoint, GridPoint& gridPoint)const=0;
+   virtual void modelBound(const ossimPlanetTerrainTileId& tileId, 
+                           ModelPoint& minPoint, ModelPoint& maxPoint)const;
+   virtual void localNdcToGlobalGrid(const ossimPlanetTerrainTileId& tileId, const LocalNdcPoint& localNdc, GridPoint& globalGrid)const;
+   virtual void localNdcToModel(const ossimPlanetTerrainTileId& tileId, const LocalNdcPoint& localNdc, ModelPoint& model)const;
+   virtual void numberOfTilesPerFace(ossim_uint32 lod, ossim_uint64& tilesWide, ossim_uint64& tilesHigh) const;
+   virtual void bounds(const ossimPlanetTerrainTileId& tileId, GridBound& bound)const;
+   virtual void boundsToModel(const ossimPlanetTerrainTileId& tileId, 
+                              ModelPoint& p0, 
+                              ModelPoint& p1, 
+                              ModelPoint& p2,
+                              ModelPoint& p3)const;
+   virtual void centerGrid(const ossimPlanetTerrainTileId& tileId, GridPoint& gridPoint);
+   virtual void centerModel(const ossimPlanetTerrainTileId& tileId, ModelPoint& modelPoint);
+   virtual void widthHeight(const ossimPlanetTerrainTileId& tileId, ossim_float64& width, ossim_float64& height)const;
+   virtual void origin(const ossimPlanetTerrainTileId& tileId, GridPoint& gridPoint)const;
+   
+   virtual void getUnitsPerPixel(osg::Vec2d& unitsPerPixel,
+                                 const ossimPlanetTerrainTileId& tileId, ossim_uint32 w, ossim_uint32 h,
+                                 const ossimUnitType unitType=OSSIM_METERS)const;
+   virtual bool convertToGeographicExtents(const ossimPlanetTerrainTileId& tileId,
+                                           ossimPlanetExtents& extents, 
+                                           ossim_uint32 w, ossim_uint32 h)const;
+   virtual void widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, osg::Vec2d& deltaXY)const=0;
+   virtual ossim_uint32 numberOfFaces()const=0;
+   virtual bool findGridBound(ossim_uint32 face,
+                              const ModelPoint& minPoint,
+                              const ModelPoint& maxPoint,
+                              GridBound& bound,
+                              ossim_uint32 numberOfPoints=3)const=0;
+   virtual bool isPolar(const ossimPlanetTerrainTileId& id)const=0;
+   /**
+    * 
+    */
+   virtual ossimPlanetGridUtility* newBackwardCompatableGrid(ossim_uint32 width,
+                                                             ossim_uint32 height)const=0;
+protected:
+   ModelType theModelType;
+};
+
+class OSSIMPLANET_DLL ossimPlanetCubeGrid2 : public ossimPlanetGrid
+{
+public:
+   ossimPlanetCubeGrid2()
+   :ossimPlanetGrid(ossimPlanetGrid::GEODETIC_MODEL),
+   theEquatorialCols(4),
+   theEquatorialRows(1) // will specify the number of bands
+   {
+   }
+   virtual void getRootIds(TileIds &ids) const;
+   virtual void globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const;
+   virtual void modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                  GridPoint& gridPoint)const;
+   virtual void widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, osg::Vec2d& deltaXY)const;
+   virtual bool findGridBound(ossim_uint32 face,
+                              const ModelPoint& minPoint,
+                              const ModelPoint& maxPoint,
+                              GridBound& bound,
+                              ossim_uint32 numberOfPoints=3)const;
+   virtual ossim_uint32 numberOfFaces()const;
+   virtual ossimPlanetGridUtility* newBackwardCompatableGrid(ossim_uint32 width,
+                                                             ossim_uint32 height)const;
+   virtual bool isPolar(const ossimPlanetTerrainTileId& id)const;
+   
+protected:
+   virtual void globalGridToModelLat45(const GridPoint& gridPoint, ModelPoint& modelPoint)const;
+   virtual void globalGridToModelLat67_5(const GridPoint& gridPoint, ModelPoint& modelPoint)const;
+   
+   ossim_uint32 theEquatorialCols;
+   ossim_uint32 theEquatorialRows;
+};
+
+class OSSIMPLANET_DLL ossimPlanetPlaneGrid2 : public ossimPlanetGrid
+{
+public:
+   ossimPlanetPlaneGrid2()
+   :ossimPlanetGrid(ossimPlanetGrid::GEODETIC_MODEL)
+   {
+   }
+   virtual void getRootIds(TileIds &ids) const;
+   virtual void globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const;
+   virtual void modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                  GridPoint& gridPoint)const;
+   virtual void widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, osg::Vec2d& deltaXY)const;
+   virtual bool findGridBound(ossim_uint32 face,
+                              const ModelPoint& minPoint,
+                              const ModelPoint& maxPoint,
+                              GridBound& bound,
+                              ossim_uint32 numberOfPoints=3)const;
+   virtual ossim_uint32 numberOfFaces()const;
+   virtual ossimPlanetGridUtility* newBackwardCompatableGrid(ossim_uint32 width,
+                                                             ossim_uint32 height)const;
+   virtual bool isPolar(const ossimPlanetTerrainTileId& /*id*/)const
+   {
+      return false;
+   }
+  
+};
+
+class OSSIMPLANET_DLL ossimPlanetAdjustableCubeGrid : public ossimPlanetCubeGrid2
+{
+public:
+   enum CapLocation
+   {
+      LOW_CAP = 0,     // 45 degree lat, default to Cube map 
+      MEDIUM_LOW_CAP,  // 67.5 degree lat
+      MEDIUM_CAP,      // 78.75 degree lat
+      MEDIUM_HIGH_CAP, // 84.375 degree lat
+      HIGH_CAP // 87.1875 degree lat
+   };
+   
+   ossimPlanetAdjustableCubeGrid(CapLocation location = MEDIUM_CAP);
+   virtual void setCapLocation(CapLocation location);
+   virtual void getRootIds(TileIds &ids) const;
+   virtual void globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const;
+   virtual void modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                  GridPoint& gridPoint)const;
+   virtual void widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, osg::Vec2d& deltaXY)const;
+   virtual bool findGridBound(ossim_uint32 face,
+                              const ModelPoint& minPoint,
+                              const ModelPoint& maxPoint,
+                              GridBound& bound,
+                              ossim_uint32 numberOfPoints=3)const;
+   virtual ossim_uint32 numberOfFaces()const;
+   virtual bool isPolar(const ossimPlanetTerrainTileId& id)const;
+   
+protected:
+   CapLocation theCapLocation;
+   ossim_float64 thePolarLat;
+   ossim_float64 theUpperEquatorialBandLatDelta;
+   ossim_float64 thePolarWidth;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetGridUtility.h b/ossimPlanet/include/ossimPlanet/ossimPlanetGridUtility.h
new file mode 100644
index 0000000..3278f45
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetGridUtility.h
@@ -0,0 +1,166 @@
+#ifndef ossimPlanetGridUtility_HEADER
+#define ossimPlanetGridUtility_HEADER
+#include <ossim/base/ossimConstants.h>
+#include <osg/Referenced>
+#include "ossimPlanetExport.h"
+#include <osg/Vec3d>
+#include <vector>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimCommon.h>
+
+class OSSIMPLANET_DLL ossimPlanetGridUtility : public osg::Referenced
+{
+public:
+   enum ossimPlanetGridUtilityIndices
+   {
+      LAT = 0,
+      LON = 1,
+      HGT = 2,
+      GRIDX = 0,
+      GRIDY = 1,
+      GRIDZ = 2
+   };
+   class GridPoint
+   {
+   public:
+      //  the global is a 0 to 1 for the entire face.
+      osg::Vec3d   theGlobalGridPoint;
+      
+      // the local is a 0 to 1 for the local row col patch.  This value could be used
+      // for the texture coordinate
+      osg::Vec3d   theLocalGridPoint;
+
+      // theFace this grid point corresponds to
+      ossim_uint32 theFace;
+   };
+   
+   ossimPlanetGridUtility(ossim_uint32 tileWidth = 256,
+                          ossim_uint32 tileHeight = 256)
+   {
+      theTileWidth  = tileWidth;
+      theTileHeight = tileHeight;
+   }
+   void getGeographicLonCrossings(std::vector<osg::Vec2d>& minMaxPairs,
+                                  ossim_uint32 level,
+                                  ossim_uint64 row,
+                                  ossim_uint64 col)const;
+   virtual bool crossesGeographicBounds(ossim_uint32 level,
+                                        ossim_uint64 row,
+                                        ossim_uint64 col)const;
+   virtual void getWidthHeightInDegrees(double& deltaX,
+                                        double& deltaY,
+                                        ossim_uint32 level,
+                                        ossim_uint64 row,
+                                        ossim_uint64 col)const;
+   virtual void getGridSpacing(double& xSpacing,
+                               double& ySpacing,
+                               ossim_uint32 level,
+                               ossim_uint64 row,
+                               ossim_uint64 col)const;
+
+   virtual void getPixelScaleAsDegrees(double& dx,
+                                       double& dy,
+                                       ossim_uint32 level,
+                                       ossim_uint64 row,
+                                       ossim_uint64 col)const;
+   virtual void getPixelScaleAsMeters(double& dx,
+                                      double& dy,
+                                      ossim_uint32 level,
+                                      ossim_uint64 row,
+                                      ossim_uint64 col)const;
+   virtual void getPixelScale(double& dx,
+                              double& dy,
+                              ossimUnitType& pixelScaleUnits,
+                              ossim_uint32 level,
+                              ossim_uint64 row,
+                              ossim_uint64 col)const=0;
+   
+   virtual void getLocalRowColumn(ossim_uint64& localRow,
+                                  ossim_uint64& localCol,
+                                  ossim_uint32 level,
+                                  ossim_uint64 row,
+                                  ossim_uint64 col)const;
+   virtual void mapToRowCol(ossim_uint64& targetRow,
+                            ossim_uint64& targetCol,
+                            ossim_uint32  targetLevel,
+                            ossim_uint32  srcLevel,
+                            ossim_uint64  srcRow,
+                            ossim_uint64  srcCol)const;
+
+   virtual ossim_uint32 getFace(ossim_uint32 level,
+                                ossim_uint64 row,
+                                ossim_uint64 col)const;
+
+
+   virtual void getNumberOfTilesWideHighPerFace(ossim_uint64 &wide,
+                                                ossim_uint64 &high,
+                                                ossim_uint32 level)const;
+   
+  
+   virtual ossim_uint32 getNumberOfFaces()const=0;
+
+   virtual void getCenterGridPoint(ossimPlanetGridUtility::GridPoint& point,
+                                   ossim_uint32 level,
+                                   ossim_uint32 row,
+                                   ossim_uint32 col)const;
+
+   virtual void getCenterGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                                   ossim_uint32 level,
+                                   const osg::Vec3d& latLon)const;
+   
+   virtual void createGridPoints(std::vector<ossimPlanetGridUtility::GridPoint>& points,
+                                 ossim_uint32 level,
+                                 ossim_uint64 row,
+                                 ossim_uint64 col,
+                                 ossim_uint32 rows,
+                                 ossim_uint32 cols)const;
+   
+   
+   virtual void getLatLon(osg::Vec3d& latLon,
+                          const ossimPlanetGridUtility::GridPoint& gridPoint)const=0;
+   virtual void getGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                             const osg::Vec3d& latLon)const=0;
+   virtual void getLatLonCorners(osg::Vec3d& ul,
+                                 osg::Vec3d& ur,
+                                 osg::Vec3d& lr,
+                                 osg::Vec3d& ll,
+                                 ossim_uint32 level,
+                                 ossim_uint32 row,
+                                 ossim_uint32 col)const;
+   virtual void getCenterLatLon(osg::Vec3d& center,
+                                ossim_uint32 level,
+                                ossim_uint32 row,
+                                ossim_uint32 col)const;
+   virtual void getLatLonBounds(double& minLat,
+                                double& minLon,
+                                double& maxLat,
+                                double& maxLon,
+                                ossim_uint32 level,
+                                ossim_uint64 row,
+                                ossim_uint64 col)const;
+   
+   virtual void getNumberOfTilesWideHigh(ossim_uint64 &wide,
+                                         ossim_uint64 &high,
+                                         ossim_uint32 level)const;
+   
+   virtual ossim_uint64 getNumberOfTiles(ossim_uint32 level)const;
+   virtual ossim_uint64 getTotalNumberOfTiles(ossim_uint32 level)const;
+
+   virtual ossim_uint64 getId(ossim_uint32 level,
+                              ossim_uint64 row,
+                              ossim_uint64 col)const;
+
+   ossim_uint32 getTileWidth()const;
+   ossim_uint32 getTileHeight()const;
+
+   void setTileWidthHeight(ossim_uint32 tileWidth,
+                           ossim_uint32 tileHeight);
+
+                            
+protected:
+   ossim_uint32 theTileWidth;
+   ossim_uint32 theTileHeight;
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIconGeom.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIconGeom.h
new file mode 100644
index 0000000..5ac8ee4
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIconGeom.h
@@ -0,0 +1,44 @@
+#ifndef ossimPlanetIconGeom_HEADER
+#define ossimPlanetIconGeom_HEADER
+#include <osg/Geometry>
+#include <osg/Vec3d>
+#include <osg/Texture2D>
+#include <ossim/base/ossimConstants.h>
+
+class ossimPlanetIconGeom : public osg::Geometry
+{
+public:
+   /**
+    *  We will setup a unit geometry for the icon.  
+    */ 
+   ossimPlanetIconGeom( const osg::Vec3d& corner=osg::Vec3d(-.5,
+                                                            0.0,
+                                                            -.5),
+                        const osg::Vec3d& width=osg::Vec3d(1.0,0.0,0.0),
+                        const osg::Vec3d& height=osg::Vec3d(0.0,0.0,1.0));
+   void setTexture(osg::ref_ptr<osg::Image> img);
+   void setTexture(osg::ref_ptr<osg::Texture2D> texture);
+   void resetToUnitGeometry();
+   void setGeometry(const osg::Vec3d& corner,
+                    const osg::Vec3d& width,
+                    const osg::Vec3d& height);
+   void setTextureCoordinatesGivenPixels(int originX,
+                                         int originY,
+                                         int pixelWidth,
+                                         int pixelHeight);
+   virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
+   ossim_uint32 width()const;
+   ossim_uint32 height()const;
+   osg::ref_ptr<osg::Texture2D> texture();
+   const osg::ref_ptr<osg::Texture2D> texture()const;
+protected:
+   void setupGeom(const osg::Vec3d& corner,
+                  const osg::Vec3d& width,
+                  const osg::Vec3d& height);
+   osg::ref_ptr<osg::Texture2D> theTexture;
+   mutable osg::ref_ptr<osg::Vec4dArray> theColorArray;
+   float theAlpha;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetId.h b/ossimPlanet/include/ossimPlanet/ossimPlanetId.h
new file mode 100644
index 0000000..26defcd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetId.h
@@ -0,0 +1,79 @@
+#ifndef ossimPlanetId_HEADER
+#define ossimPlanetId_HEADER
+#include <ossim/base/ossimConstants.h>
+#include "ossimPlanetExport.h"
+
+class OSSIMPLANET_DLL ossimPlanetId
+{
+public:
+   ossimPlanetId(ossim_int64 value = theInvalidId)
+      :theId(value)
+   {
+   }
+   ossim_int64 id()const
+   {
+      return theId;
+   }
+   ossimPlanetId& operator ++()
+   {
+      ++theId;
+      return *this;
+   }
+   ossimPlanetId operator ++(int)
+   {
+      ossimPlanetId id(theId);
+      ++theId;
+      return id;
+   }
+   bool operator()()const
+   {
+      return (theId != theInvalidId);
+   }
+   bool operator <(const ossimPlanetId& id)const
+   {
+      return (theId < id.theId);
+   }
+   bool operator <(ossim_int64 id)const
+   {
+      return (theId < id);
+   }
+   bool operator >(const ossimPlanetId& id)const
+   {
+      return (theId > id.theId);
+   }
+   bool operator >(ossim_int64 id)const
+   {
+      return (theId > id);
+   }
+   bool operator <=(const ossimPlanetId& id)const
+   {
+      return (theId <= id.theId);
+   }
+   bool operator <=(ossim_int64 id)const
+   {
+      return (theId <= id);
+   }
+   bool operator >=(const ossimPlanetId& id)const
+   {
+      return (theId >= id.theId);
+   }
+   bool operator >=(ossim_int64 id)const
+   {
+      return (theId >= id);
+   }
+   bool operator ==(const ossimPlanetId& id)const
+   {
+      return (theId == id.theId);
+   }
+   bool operator ==(ossim_int64 id)const
+   {
+      return (theId == id);
+   }
+   static ossim_int64 invalidId();
+protected:
+   ossim_int64 theId;
+
+   static ossim_int64 theInvalidId;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIdManager.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIdManager.h
new file mode 100644
index 0000000..16cae52
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIdManager.h
@@ -0,0 +1,15 @@
+#ifndef ossimPlanetIdManager_HEADER
+#define ossimPlanetIdManager_HEADER
+#include "ossimPlanetId.h"
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include "ossimPlanetExport.h"
+class OSSIMPLANET_DLL ossimPlanetIdManager
+{
+public:
+   static ossimPlanetId nextId();
+   
+protected:
+   static ossimPlanetId theCurrentId;
+   static ossimPlanetReentrantMutex theMutex;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIdolBridge.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIdolBridge.h
new file mode 100644
index 0000000..5d681f3
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIdolBridge.h
@@ -0,0 +1,105 @@
+// Written by Patrick Melody @ NRL
+
+#ifndef ossimPlanetIdolBridge_HEADER
+#define ossimPlanetIdolBridge_HEADER
+
+#include <map>
+#include <osg/Group>
+#include "ossimPlanet/ossimPlanetActionReceiver.h"
+#include "ossimPlanet/ossimPlanetIdolLayer.h"
+
+class ossimPlanetIdolBridge : public ossimPlanetActionReceiver {
+public:
+    ossimPlanetIdolBridge() :
+        layerGroup_(new osg::Group)
+        {
+            setPathnameAndRegister(":idolbridge");
+        }
+    
+    ~ossimPlanetIdolBridge() 
+        {
+            for (std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.begin(); i != layers_.end(); i++) {
+                layerGroup_->removeChild(i->second->layerRoot());
+                delete i->second;
+            }
+        }
+    
+    void execute(const ossimPlanetAction &a)
+        {
+            if (a.command() == "gotolatlonelev") {
+                // this action updates our current position to idol.
+                // we do nothing. this action is being broadcast so all
+                // idol data servers see it, and it is intended for them.
+            
+	    } else if (a.command() == "movechild") {
+                if (a.argCount() == 5) {
+                    std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.find(a.arg(1));
+                    if (i != layers_.end())
+                        i->second->moveChild(a);
+                    else
+                        a.printError("no such layer");
+		} else
+                    a.printError("bad arg count, need layername,childname,lat,lon,elev");
+                    
+            } else if (a.command() == "addchild") {
+                if (a.argCount() == 6) {
+                    std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.find(a.arg(1));
+                    if (i != layers_.end())
+                        i->second->addChild(a);
+                    else
+                        a.printError("no such layer");
+                } else
+                    a.printError("bad arg count, need layername,childname,lat,lon,elev,modeldata");
+
+	    } else if (a.command() == "removechild") {
+                if (a.argCount() == 2) {
+                    std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.find(a.arg(1));
+                    if (i != layers_.end())
+                        i->second->removeChild(a);
+                    else
+                        a.printError("no such layer");
+                } else 
+                    a.printError("bad arg count, need layername,childname");
+                    
+            } else if (a.command() == "createlayer") {
+                if (a.argCount() == 1) {
+                    std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.find(a.arg(1));
+                    if (i == layers_.end()) {
+                        layers_[a.arg(1)] = new ossimPlanetIdolLayer(a.arg(1));
+                        layerGroup_->addChild(layers_[a.arg(1)]->layerRoot());
+                    } else
+                        a.printError("layer already exists");
+                } else
+                    a.printError("bad arg count");
+                    
+            } else if (a.command() == "deletelayer") {
+                if (a.argCount() == 1) {
+                    std::map<std::string, ossimPlanetIdolLayer*>::iterator i = layers_.find(a.arg(1));
+                    if (i != layers_.end()) {
+                        layerGroup_->removeChild(i->second->layerRoot());
+                        delete i->second;
+                        layers_.erase(i);
+                    } else
+                        a.printError("no such layer");
+                } else
+                    a.printError("bad arg count");
+                    
+            } else
+                a.printError("bad command");
+        }
+    
+    osg::ref_ptr<osg::Group> layerGroup() const
+        // this group is attached to the scenegraph by class ossimPlanet.  idol layer groups live under it.
+        { return layerGroup_; }
+    
+protected:
+    osg::ref_ptr<osg::Group> layerGroup_;
+        // this group is attached to the scenegraph by class ossimPlanet.  idol layer groups live under it.
+    
+    std::map<std::string, ossimPlanetIdolLayer*> layers_;
+	// all our current layers indexed by layer name
+    
+};
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIdolLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIdolLayer.h
new file mode 100644
index 0000000..db2cb32
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIdolLayer.h
@@ -0,0 +1,140 @@
+// a data layer loaded by idol, controlled by an ossimPlanetIdolBridge
+
+// Written by Patrick Melody @ NRL
+
+#ifndef ossimPlanetIdolLayer_HEADER
+#define ossimPlanetIdolLayer_HEADER
+
+#include <vector>
+#include <map>
+#include <string>
+#include <osg/MatrixTransform>
+#include <osg/Group>
+#include <osg/Geode>
+#include <osgText/Text>
+#include <osgDB/ReadFile> 
+#include "ossimPlanet/ossimPlanetAction.h"
+#include "ossimPlanet/mkUtils.h"
+
+class ossimPlanetIdolLayer {
+public:
+    ossimPlanetIdolLayer(const std::string& name) :
+	name_(name),
+	layerRoot_(new osg::Group)
+	{ }
+    
+    ~ossimPlanetIdolLayer()
+	{
+	    for (std::map<std::string, osg::MatrixTransform*>::iterator i = children_.begin(); i != children_.end(); i++)
+		i->second->unref();
+	}
+    	
+    void addChild(const ossimPlanetAction &a)
+	// create and add a child;  args are layername childname lat lon elev modeldescription
+	{
+	    if (children_.find(a.arg(2)) == children_.end()) {
+                osg::Node* model = createModelFromDescription(a.arg(6));
+                if (model != NULL) {
+                    osg::MatrixTransform* xform = new osg::MatrixTransform; 
+                    xform->ref();
+                    setTransform(xform, mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)), mkUtils::asDouble(a.arg(5)));
+                    xform->addChild(model);            
+                    layerRoot_->addChild(xform);
+                    children_[a.arg(2)] = xform;
+                } else
+                    a.printError("could not create model from model description");
+	    } else
+                a.printError("already have a child with that name");
+	}
+	
+    void moveChild(const ossimPlanetAction &a)
+	// move a child;  args are layername childname lat lon elev
+	{
+	    std::map<std::string, osg::MatrixTransform*>::iterator i = children_.find(a.arg(2));
+	    if (i != children_.end())
+                setTransform(i->second, mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)), mkUtils::asDouble(a.arg(5)));
+	    else
+                a.printError("no such child");
+	}
+	
+    void removeChild(const ossimPlanetAction &a)
+	// remove a child
+	{
+	    std::map<std::string, osg::MatrixTransform*>::iterator i = children_.find(a.arg(2));
+	    if (i != children_.end()) {
+		layerRoot_->removeChild(i->second);
+		i->second->unref();
+		children_.erase(i);
+	    } else
+                a.printError("no such child");
+	}
+	
+    const std::string& name() const 
+	// name of this layer
+	{ return name_; }
+	
+    osg::Group* layerRoot() const
+	// root of this layer's scene subgraph 
+	{ return layerRoot_.get(); }  
+
+protected:
+    std::string name_;
+	// layer name
+
+    osg::ref_ptr<osg::Group> layerRoot_;
+	// root of this layer's scene subgraph 
+	
+    std::map<std::string, osg::MatrixTransform*> children_;
+	// collection of current children indexed by childname
+    
+    osg::Node* createModelFromDescription(const std::string& modelDescription) const
+	// create model
+        // modeldescription := (text labeltext r g b a scale) | (model filename scale)
+	{
+            osg::Node* result = NULL;
+            
+	    std::vector<std::string> tokens;
+            bool unbalancedBraces;
+	    mkUtils::lexBraceQuotedTokens(modelDescription, 0, " \t", &tokens, &unbalancedBraces);
+	    
+            if (!unbalancedBraces && tokens.size() > 0) {
+                if (tokens[0] == "text" && tokens.size() == 7) {
+                    osgText::Text* t = new osgText::Text;
+                    t->setFont();
+                    t->setCharacterSize(6.0f*mkUtils::asDouble(tokens[6]));
+                    t->setColor(osg::Vec4f(mkUtils::asDouble(tokens[2]), mkUtils::asDouble(tokens[3]), mkUtils::asDouble(tokens[4]), mkUtils::asDouble(tokens[5])));
+                    t->setAlignment(osgText::Text::CENTER_CENTER);
+                    t->setText(tokens[1]);
+                    osg::Geode* geode = new osg::Geode;
+                    geode->addDrawable(t);
+                    result = geode;
+                    
+                } else if (tokens[0] == "model" && tokens.size() == 3) {
+                    osg::Node* model = osgDB::readNodeFile(tokens[1].c_str());
+                    if (model != NULL) {
+                        double scale = mkUtils::asDouble(tokens[2]);
+                        osg::MatrixTransform* scaleNode = new osg::MatrixTransform(osg::Matrixf::scale(scale,scale,scale)); 
+                        scaleNode->addChild(model);
+                        result = scaleNode;
+                    }
+                }
+            }
+            
+            return result;
+        }
+        
+    void setTransform(osg::MatrixTransform* transform, double lat, double lon, double elev) const
+	// set transform to place geometry at lat,lon,elev
+	{
+            const osg::Vec3d zAxis(0.0, 0.0, 1.0);
+            
+            double planetRadius = 6378137.0; // XXX should really compute current planet's radius at lat/lon
+            osg::Vec3d v = mkUtils::modsphere2xyz(1.0 + elev/planetRadius, osg::DegreesToRadians(lon), osg::DegreesToRadians(lat));
+            
+            transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(lon + 90.0), zAxis));
+            transform->postMult(osg::Matrixd::rotate(zAxis, v));
+            transform->postMult(osg::Matrixd::translate(v));
+        }
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetImage.h b/ossimPlanet/include/ossimPlanet/ossimPlanetImage.h
new file mode 100644
index 0000000..9e57fca
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetImage.h
@@ -0,0 +1,186 @@
+#ifndef ossimPlanetImage_HEADER
+#define ossimPlanetImage_HEADER
+#include "ossimPlanetExport.h"
+#include <ossim/base/ossimConstants.h>
+#include <ossim/imaging/ossimImageData.h>
+#include <osg/Image>
+#include <osg/Vec2>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetTerrainTileId.h>
+
+class OSSIMPLANET_DLL ossimPlanetImage :public osg::Image
+{
+public:
+   enum ossimPlanetImageStateType 
+   {
+      ossimPlanetImageStateType_NONE = 0,
+      ossimPlanetImageStateType_LOADED = 1,
+      ossimPlanetImageStateType_NEEDS_LOADING     = 2
+   };
+   enum ossimPlanetImagePixelStatus
+   {
+      ossimPlanetImagePixelStatus_EMPTY    = 0,
+      ossimPlanetImagePixelStatus_FULL     = 1,
+      ossimPlanetImagePixelStatus_PARTIAL  = 2
+   };
+   virtual osg::Object* cloneType() const
+   {
+      return new ossimPlanetImage();
+   }
+   virtual osg::Object* clone(const osg::CopyOp& copyop) const
+   {
+      return new ossimPlanetImage(*this,copyop);
+   }
+   virtual const char* className() const
+   {
+      return "ossimPlanetImage";
+   }
+   ossimPlanetImage();
+   ossimPlanetImage(const osg::Image& image);
+   ossimPlanetImage(const ossimPlanetTerrainTileId& id); 
+   ossimPlanetImage(const ossimPlanetImage& image,
+                    const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   
+   virtual ~ossimPlanetImage();
+   void stripPadding();
+   int getNumberOfComponents()const; 
+   int getHeight()const; 
+   int getWidth()const;
+
+   ossimPlanetImageStateType getState()const;
+      
+   void setId(const ossimPlanetTerrainTileId& id);
+   const ossimPlanetTerrainTileId& tileId()const;
+   void setState(ossimPlanetImageStateType stateType);
+   void setPixelStatus();
+   void setPixelStatus(ossimPlanetImagePixelStatus pixelStatus);
+   ossimPlanetImagePixelStatus getPixelStatus()const;
+   ossimRefPtr<ossimImageData> toOssimImage()const;
+   void fromOssimImage(ossimRefPtr<ossimImageData> data,
+                       bool reassignNullFlag = true,
+                       double nullValue = 0.0);
+   void fromOssimImageNoAlpha(ossimRefPtr<ossimImageData> data,
+                              bool reassignNullFlag = true,
+                              double nullValue = 0.0);
+   OpenThreads::Mutex& mutex()const;
+
+   bool hasMinMax()const
+   {
+      return ((theMinValue.size()!=0)&&
+              (theMaxValue.size()!=0));
+   }
+   void setMinMax(double minValue,
+                  double maxValue)
+   {
+      theMinValue.resize(1);
+      theMaxValue.resize(1);
+
+      theMinValue[0] = minValue;
+      theMaxValue[0] = maxValue;
+   }
+   void setMin(ossim_uint32 idx,
+               double value)
+   {
+      if(idx < theMinValue.size())
+      {
+         theMinValue[idx] = value;
+      }
+   }
+   void setMax(ossim_uint32 idx,
+               double value)
+   {
+      if(idx < theMaxValue.size())
+      {
+         theMaxValue[idx] = value;
+      }
+   }
+   void setMinMax(const std::vector<double>& minValue,
+                  const std::vector<double>& maxValue)
+   {
+      theMinValue = minValue;
+      theMaxValue = maxValue;
+   }
+   const std::vector<double>& minValue()const
+   {
+      return theMinValue;
+   }
+   const std::vector<double>& maxValue()const
+   {
+      return theMaxValue;
+   }
+   static osg::Image*       readNewOsgImage(const ossimFilename& src,
+                                            bool flipVerticalFlag = true,
+                                            bool insertAlphaFlag = true);
+   static osg::Image*       readNewOsgImageNoAlpha(const ossimFilename& src,
+                                                   bool flipVerticalFlag = true);
+   ossimPlanetImage* scaleImagePowerOf2()const;
+               
+   void copyTo(ossim_uint32 x, ossim_uint32 y, ossimPlanetImage* destination)const;
+   
+   /**
+    * We will only support RGBA or RGB, or single band elevation in 32 bit float
+    */
+   void copySubImageAndInsertPointsPowerOf2(int x, // starting x 
+                                            int y, // starting y
+                                            ossim_uint32 lengthx, // length x
+                                            ossim_uint32 lengthy, // length y
+                                            ossimPlanetImage* source);  
+   virtual ossim_uint64 sizeInBytes()const;
+   virtual osg::Vec2 deltas(ossim_int32 x,
+                            ossim_int32 y)const;
+   
+   ossim_int32 widthWithoutPadding()const
+   {
+      return _s-(thePadding*2);
+   }
+   ossim_int32 heightWithoutPadding()const
+   {
+      return _t-(thePadding*2);
+   }
+   ossim_int32 width()const{return _s;}
+   ossim_int32 height()const{return _t;}
+   
+   ossim_int32 padding()const
+   {
+      return thePadding;
+   }
+   void setPadding(ossim_int32 value)
+   {
+      thePadding = value;
+   }
+   ossim_float32 elevationValue(ossim_int32 x, ossim_int32 y)const
+   {
+      return reinterpret_cast<const ossim_float32*>(_data)[_s*y+x];
+   }
+   ossim_float32 elevationValueNoPaddingOffset(ossim_int32 x, ossim_int32 y)const
+   {
+      return reinterpret_cast<const ossim_float32*>(_data)[_s*(y+thePadding)+(x+thePadding)];
+   }
+   void applyBrightnessContrast(ossim_float32 brightness, ossim_float32 contrast);
+
+protected:
+   template <class T>
+   void copySubImageAndInsertPointsPowerOf2(T dummy, // for casting to proper buffer type                                    
+                                    int x,
+                                    int y, // starting y
+                                    ossim_uint32 lengthx, // length x
+                                    ossim_uint32 lengthy, // length y
+                                    ossimPlanetImage* source); // 
+   template <class T>
+   ossimPlanetImage* scaleImagePowerOf2(T dummy)const;
+   
+   template <class T>
+   void copyTo(T dummy, ossim_uint32 x, ossim_uint32 y, ossimPlanetImage* destination)const;
+   
+   mutable ossimPlanetImageStateType theState;
+   ossimPlanetTerrainTileId theTileId;
+   ossimPlanetImagePixelStatus thePixelStatus;
+   mutable ossimPlanetReentrantMutex theMutex;
+   std::vector<double> theMinValue;
+   std::vector<double> theMaxValue;
+   
+   ossim_int32 thePadding;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetInputDevice.h b/ossimPlanet/include/ossimPlanet/ossimPlanetInputDevice.h
new file mode 100644
index 0000000..9d99efa
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetInputDevice.h
@@ -0,0 +1,20 @@
+#ifndef ossimPlanetInputDevice_HEADER
+#define ossimPlanetInputDevice_HEADER
+
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Referenced>
+// device driver interface for user input devices
+
+class OSSIMPLANET_DLL ossimPlanetInputDevice :public osg::Referenced
+{
+public:
+    ossimPlanetInputDevice() {}
+    virtual ~ossimPlanetInputDevice() {}
+    
+    virtual void processInput() = 0;
+    // update interaction valuators and execute actions
+    
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetInteractionController.h b/ossimPlanet/include/ossimPlanet/ossimPlanetInteractionController.h
new file mode 100644
index 0000000..0b5e49b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetInteractionController.h
@@ -0,0 +1,154 @@
+#ifndef ossimPlanetInteractionController_HEADER
+#define ossimPlanetInteractionController_HEADER
+
+// Control mapping configuration, notify sim of user input.
+// Events are discrete inputs, eg button presses, bound to actions. 
+// Events beginning with a '-' are reserved for commandline arguments.
+// Device valuators are continuous inputs, eg mouse position, tied    
+// to interaction valuators.  
+
+#include <assert.h>
+#include <iostream>
+#include <map>
+#include <vector>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanetInputDevice.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+#include <osg/ref_ptr>
+
+class OSSIMPLANET_DLL ossimPlanetInteractionController : public ossimPlanetActionReceiver
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetInputDevice> > DeviceList;
+   
+   // singleton routines
+   static ossimPlanetInteractionController* instance();
+	// pointer to the lazy initialized InteractionController singleton
+	// assert(instance() != NULL)
+   
+   static void shutdown();
+	// clean up the singleton
+   
+   // input management
+   void registerDevice(ossimPlanetInputDevice* d);
+	// add an input device to the list of devices we watch
+	// assert(d != NULL)
+	
+   void unregisterDevice(ossimPlanetInputDevice* d);
+	// remove an input device from the list of devices we watch
+	// assert(d != NULL)
+   
+   void processPendingInputs();
+	// generate all actions and update all variables required  
+	//    by any user input to a registered device that occured  
+	//    since last call.
+   
+   void defineInteractionValuator(const std::string& name, double minValue, double maxValue);
+	// define an interaction valuator
+	// assert(!name.empty());
+	// assert(!ossim::isnan(minValue));
+	// assert(!ossim::isnan(maxValue));
+   
+   float interactionValuatorValue(const std::string& interactionValuator) const;
+	// value of an interaction valuator, or NAN if undefined valuator
+	
+   // user control configuration
+   void bind(const std::string& event, const ossimPlanetAction& a);
+	// bind an event to an action
+	// assert(!event.empty())    // reserve empty event name for noops
+	
+   void unbind(const std::string& event);
+	// unbind event
+	
+   void unbindAll();
+	// unbind all events
+	
+   void tie(const std::string& valuatorList);
+	// given a brace quoted token list, treat the first token as a device valuator name,
+	//    and the rest of the tokens as virtual interaction valuator names.  untie the
+	//    device valuator from any previous ties and then tie it to all the listed 
+	//    interaction valuators that are currently defined.
+	
+   void untie(const std::string& deviceValuator);
+	// untie a device valuator from all its virtual interaction valuators
+	
+   void untieAll();
+	// untie all device valuators from all their virtual interaction valuators
+   
+   void writeConfiguration(std::ostream& stream) const;
+	// output an action script that will restore the current bindings/ties
+   
+   // routines called by InputDevice objects
+   void executeBoundAction(const std::string& event);
+	// execute the action bound to event, no op if no binding
+   
+   void updateInteractionValuators(const std::string& deviceValuator, float normalizedValue);
+	// update value of all interaction valuators tied to deviceValuator
+	// assert(mkUtils::inInterval(normalizedValue, 0.0f, 1.0f))
+   
+   // ActionReceiver routines
+   void execute(const ossimPlanetAction& a);
+	// execute the given action
+   
+protected:
+   ossimPlanetInteractionController();
+   ossimPlanetInteractionController(const ossimPlanetInteractionController& src):ossimPlanetActionReceiver(src) {}
+   ~ossimPlanetInteractionController();
+   ossimPlanetInteractionController& operator=(ossimPlanetInteractionController& ) {assert(false); return *this;}
+   
+   void xmlExecute(const ossimPlanetXmlAction& a);
+   void destinationCommandExecute(const ossimPlanetDestinationCommandAction& a);
+   static ossimPlanetInteractionController* instance_;
+	// our singleton
+   
+   DeviceList deviceList_;
+	// registered input devices 
+   
+   mutable ossimPlanetReentrantMutex theBoundActionsMutex;
+   std::map<std::string, osg::ref_ptr<ossimPlanetAction> > boundActions_;
+	// current event to action bindings
+   
+   class ossimPlanetInteractionValuatorData 
+      {
+      public:
+         double min;
+         double maxMinusMin;
+         double value;
+         ossimPlanetInteractionValuatorData() : min(0.0), maxMinusMin(1.0), value(0.0) {}
+         ossimPlanetInteractionValuatorData(float minVal, float maxVal) : min(minVal), maxMinusMin(maxVal-minVal), value(minVal) {}
+      };
+   // valuator data tuple
+	
+   std::map<std::string, ossimPlanetInteractionValuatorData> valuators_;
+   // all defined interaction valuators
+   
+   std::map<std::string, std::vector<std::string> > deviceTies_;
+	// device valuators and the interaction valuators they're tied to
+};
+
+inline ossimPlanetInteractionController* ossimPlanetInteractionController::instance()
+{
+   if (ossimPlanetInteractionController::instance_ == 0)
+   {
+      ossimPlanetInteractionController::instance_ = new ossimPlanetInteractionController();
+   }
+   assert(ossimPlanetInteractionController::instance_ != NULL);
+   return ossimPlanetInteractionController::instance_;
+}
+
+inline void ossimPlanetInteractionController::shutdown()
+{
+   if(ossimPlanetInteractionController::instance_)
+   {
+      delete ossimPlanetInteractionController::instance_;
+      ossimPlanetInteractionController::instance_ = 0;
+   }
+}
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIntersectUserData.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIntersectUserData.h
new file mode 100644
index 0000000..8d3142d
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIntersectUserData.h
@@ -0,0 +1,27 @@
+#ifndef ossimPlanetIntersectUserData_HEADER
+#define ossimPlanetIntersectUserData_HEADER
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetIntersectUserData : public osg::Referenced
+{
+public:
+   ossimPlanetIntersectUserData(int maxLevel=9999999)
+      :theMaxLevelToIntersect(maxLevel)
+   {
+   }
+
+      void setMaxLevelToIntersect(int maxLevel)
+      {
+         theMaxLevelToIntersect = maxLevel;
+      }
+   int getMaxLevelToIntersect()const
+   {
+      return theMaxLevelToIntersect;
+   }
+protected:
+   virtual ~ossimPlanetIntersectUserData(){}
+
+   int theMaxLevelToIntersect;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIo.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIo.h
new file mode 100644
index 0000000..62f285f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIo.h
@@ -0,0 +1,156 @@
+#ifndef ossimPlanetIo_HEADER
+#define ossimPlanetIo_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetMessage.h>
+#include <vector>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+
+class OSSIMPLANET_DLL ossimPlanetIo : public osg::Referenced
+{
+public:
+   typedef char BufferType;
+   typedef std::vector<char> ByteBufferType;
+   enum IoResultType
+   {
+      IO_SUCCESS = 0,
+      IO_NO_DATA = 1,
+      IO_FAIL    = 2
+   };
+   ossimPlanetIo(const ossimString& name="",
+                 char terminator='\0')
+      :theName(name),
+      theTerminator(terminator),
+      theFinishedFlag(false),
+      theEnableFlag(true)
+      {
+      }
+   
+   virtual ~ossimPlanetIo()
+   {
+   }
+   
+   virtual void performIo()=0;
+   
+   /**
+    * This is a general interface into Io for reading data.
+    *
+    * @param buffer is a fixed size buffer that we read data and put into it.
+    * @param bufferSize Size of the buffer.
+    * @result The amount of bytes read into the buffer.
+    */
+   virtual ossim_uint32 read(char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult)=0;
+   
+   /**
+    * This is a general interface into Io for writing data.
+    *
+    * @param buffer is a buffer that we either read data and put into it.
+    * @param bufferSize Size of the buffer.
+    * @param ioResult Specifies if the IO was succesful or if no data was present or if it failed. On failure derived IO
+    *                 can deterimine the action they want to take.
+    * @result The amount of bytes writen into the buffer.
+    */
+   virtual ossim_uint32 write(const char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult)=0;
+   
+   virtual bool pushMessage(osg::ref_ptr<ossimPlanetMessage> /*message*/, bool /*forcePushFlag*/)
+   {
+      return false;
+   }
+   virtual osg::ref_ptr<ossimPlanetMessage> popMessage()
+   {
+      return 0;
+   }
+   virtual void setConnectionHeader(osg::ref_ptr<ossimPlanetMessage> value)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+      theConnectionHeader = value;
+   }
+   void setFinishedFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+      theFinishedFlag = flag;
+   }
+   bool finishedFlag()const
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         return theFinishedFlag;
+      }
+   const ossimString& name()const
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         return theName;
+      }
+   void setName(const ossimString& name)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         theName = name;
+      }
+   virtual void searchName(ossimString& searchNameResult)const
+      {
+         // by default we will return the name.  Derived classes should return
+         // a full ID name.  For example, sockets will return <name>:<port>
+         searchNameResult = name();
+      }
+   char terminator()const
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         return theTerminator;
+      }
+   void setTerminator(char terminator)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         theTerminator = terminator;
+      }
+   virtual void setEnableFlag(bool flag)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         theEnableFlag = flag;
+      }
+   bool enableFlag()const
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+         return theEnableFlag;
+      }
+   void setIoDirection(ossimPlanetIoDirection direction)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+      theIoDirection = direction;
+   }
+   ossimPlanetIoDirection ioDirection()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+      return theIoDirection;
+   }
+   virtual void pushConnectionHeader() 
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetIoPropertyMutex);
+      if(theConnectionHeader.valid())
+      {
+         if(theConnectionHeader->dataSize() > 0)
+         {
+            pushMessage(theConnectionHeader, true);
+         }
+      }
+   }
+   virtual void closeIo()=0;
+   virtual bool openIo()=0;
+   
+private:
+   ossimString                  theName;
+   char                         theTerminator;
+   bool                         theFinishedFlag;
+   bool                         theEnableFlag;
+   ossimPlanetIoDirection       theIoDirection;
+   osg::ref_ptr<ossimPlanetMessage>      theConnectionHeader;
+   mutable ossimPlanetReentrantMutex   thePlanetIoPropertyMutex;
+protected:
+  mutable ossimPlanetReentrantMutex   theIoMutex;
+
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIoMessageHandler.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIoMessageHandler.h
new file mode 100644
index 0000000..78c0f0f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIoMessageHandler.h
@@ -0,0 +1,40 @@
+#ifndef ossimPlanetIoMessageHandler_HEADER
+#define ossimPlanetIoMessageHandler_HEADER
+#include <ossim/base/ossimString.h>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <vector>
+#include <ossimPlanet/ossimPlanetMessage.h>
+
+class ossimPlanetIoMessageHandler : public osg::Referenced
+{
+public:
+   ossimPlanetIoMessageHandler()
+      :theName(""),
+       theEnableFlag(true)
+      {}
+   virtual bool handleMessage(osg::ref_ptr<ossimPlanetMessage> message)=0;
+   void setEnableFlag(bool flag)
+      {
+         theEnableFlag = flag;
+      }
+   bool enableFlag()const
+      {
+         return theEnableFlag;
+      }
+
+   void setName(const ossimString& name)
+      {
+         theName = name;
+      }
+   const ossimString& name()const
+      {
+         return theName;
+      }
+protected:
+   ossimString  theName;
+   bool theEnableFlag;
+};
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIoRoutableMessageHandler.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIoRoutableMessageHandler.h
new file mode 100644
index 0000000..f220f34
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIoRoutableMessageHandler.h
@@ -0,0 +1,15 @@
+#ifndef ossimPlanetIoRoutableMessageHandler_HEADER
+#define ossimPlanetIoRoutableMessageHandler_HEADER
+#include <ossimPlanet/ossimPlanetIoMessageHandler.h>
+
+class ossimPlanetIoRoutableMessageHandler : public ossimPlanetIoMessageHandler
+{
+public:
+   ossimPlanetIoRoutableMessageHandler()
+   {
+         theName = "Routable Message Handler";
+   }
+   virtual bool handleMessage(osg::ref_ptr<ossimPlanetMessage> message);
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocket.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocket.h
new file mode 100644
index 0000000..b87ddd2
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocket.h
@@ -0,0 +1,125 @@
+#ifndef ossimPlanetIoSocket_HEADER
+#define ossimPlanetIoSocket_HEADER
+#include <ossimPlanet/ossimPlanetIo.h>
+#include <ossimPlanet/netSocket.h>
+#include <queue>
+#include <deque>
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <OpenThreads/Mutex>
+
+class OSSIMPLANET_DLL ossimPlanetIoSocket : public ossimPlanetIo
+{
+public:
+   typedef std::deque<osg::ref_ptr<ossimPlanetMessage> > OutQueueType;
+   ossimPlanetIoSocket();
+   virtual ~ossimPlanetIoSocket();
+
+   void setHandle(int handle);
+	void setSocketInfo(const ossimString& host,
+							 int port,
+							 const ossimString& ioType);
+   virtual void searchName(ossimString& searchNameResult)const;
+   bool setSocket(const ossimString& host,
+                  int port,
+                  const ossimString& ioType);
+   int handle()
+   {
+      if(theSocket) return theSocket->getHandle();
+      return -1;
+   }
+   virtual ossim_uint32 read(char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult);
+   virtual ossim_uint32 write(const char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult);
+   
+   bool nonblock();
+	bool setBlockingFlag(bool flag);
+   virtual void setEnableFlag(bool flag);
+   const ossimString& host()const;
+   int port()const;
+   const ossimString& ioType()const;
+   virtual void performIo();
+   virtual bool pushMessage(osg::ref_ptr<ossimPlanetMessage> message, bool forcePushFlag);
+   virtual osg::ref_ptr<ossimPlanetMessage> popMessage();
+   virtual void clearAllBuffers();
+   //void setAutoCloseOnPeerShutdownFlag(bool flag);
+   //bool autoCloseOnPeerShutdownFlag()const;
+   void setAutoReconnectFlag(bool flag);
+   bool autoReconnectFlag()const;
+   void setAutoReconnectInterval(ossim_uint32 milliseconds);
+   ossim_uint32 autoReconnectInterval()const;
+   void setMaxOutputBacklogInBytes(ossim_uint32 bytes);
+   ossim_uint32 maxOutputBacklogInBytes()const;
+   virtual void closeIo();
+   virtual bool openIo();
+   
+   void setMaxBytesToSendPerIo(ossim_uint32 byte);
+   ossim_uint32 maxBytesToSendPerIo()const;
+protected:   
+   bool makeClientSocket();
+   bool protectedSetSocket(const ossimString& host,
+                           int port,
+                           const ossimString& ioType);
+   void addToOutputBufferIfNeeded();
+   
+   netSocket*                theSocket;
+   ossimString               theHost;
+   int                       thePort;
+   ossimString               theIoType; // can be udp or tcp
+	bool                      theStreamingFlag;
+   ossimPlanetIo::ByteBufferType theTempBuffer;
+   ossimPlanetIo::ByteBufferType theInBuffer;
+   
+   // The In queue is where incoming messages are stored and will be popped and handled in the thread
+   //
+   ossimPlanetReentrantMutex      theInQueueMutex;
+   std::queue<osg::ref_ptr<ossimPlanetMessage> >   theInQueue;
+
+   // The out queue will hold all outgoing messages
+   ossimPlanetReentrantMutex      theOutQueueMutex;
+   OutQueueType                     theOutQueue;
+   ossimPlanetReentrantMutex      theOutBufferMutex;
+   std::vector<char>                theOutBuffer;
+
+   /**
+    *  If this flag is true then it will auto shutdown the client socket if a server shutdown is
+    *  detected.  So if a client socket is communicating and it gets a bad send or receive that indicates
+    *  a server shutdown it will set its finished flag if this flag is true.
+    */ 
+   //bool                           theAutoCloseOnPeerShutdownFlag;
+
+   /**
+    * This specifies if the client socket is disconnected it should try to reconnect
+    */ 
+   bool                           theAutoReconnectFlag;
+
+   /**
+    * if the AutoReconnectFlag is true then it will try to reconnect at the specified
+    * interval.  The interval is in Milleseconds.  So if you want a reconnect attempt
+    * to happen approximately every second then the value should be set to 1000.  This
+    * is the default value.
+    */ 
+   ossim_uint32                   theAutoReconnectInterval; // specified in milliseconds
+
+   mutable ossimPlanetReentrantMutex     theMaxBytesToSendPerIoMutex;
+   ossim_uint32                   theMaxBytesToSendPerIo;
+
+   ossim_uint32                   theMaxOutgoingBacklogInBytes;
+
+   ossim_int32                    theTotalBytesToSend;
+   /**
+    * Used in the reconnect interval  This is reset to 0 for identification that an initial
+    * tick needs to be set.  once set the delta milliseconds is used to determine
+    * when to do another reconnect.
+    */ 
+   osg::Timer_t                   theLastTick;
+
+   ossimPlanetReentrantMutex    theSocketMutex;
+	
+	bool                           theFirstReadFlag;
+   
+   /**
+    * Bytes to auto send on connection
+    */
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocketServerChannel.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocketServerChannel.h
new file mode 100644
index 0000000..9859558
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIoSocketServerChannel.h
@@ -0,0 +1,98 @@
+#ifndef ossimPlanetIoSocketServerChannel_HEADER
+#define ossimPlanetIoSocketServerChannel_HEADER
+#include <ossimPlanet/netChannel.h>
+#include <ossimPlanet/ossimPlanetIo.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <osg/ref_ptr>
+#include <queue>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Timer>
+#include <iostream>
+
+class OSSIMPLANET_DLL ossimPlanetIoSocketServerChannel : public ossimPlanetIo,
+                                                         public netChannel
+{
+public:
+   ossimPlanetIoSocketServerChannel();
+   virtual ~ossimPlanetIoSocketServerChannel();
+   virtual void searchName(ossimString& searchNameResult)const;
+   bool setSocket(const std::string& host,
+                  int port,
+                  const std::string& ioType);
+   virtual void setEnableFlag(bool flag);
+   virtual void clearAllBuffers();
+   const std::string& host()const;
+   const std::string& ioType()const;
+   int port()const;
+   bool isTcp()const;
+   virtual ossim_uint32 read(char* /* buffer */, ossim_uint32 /* bufferSize */,
+                             ossimPlanetIo::IoResultType& ioResult)
+   {
+      ioResult = IO_NO_DATA;
+      return 0;
+   }
+   virtual ossim_uint32 write(const char* /* buffer */, ossim_uint32 /* bufferSize */,
+                              ossimPlanetIo::IoResultType& ioResult)
+   {
+      ioResult = IO_NO_DATA;
+      return 0;
+   }
+   virtual void performIo();
+   virtual osg::ref_ptr<ossimPlanetMessage> popMessage();
+   int handle()
+   {
+      return getHandle();
+   }
+   virtual void closeIo()
+   {
+      netChannel::close();
+   }
+   virtual bool openIo()
+   {
+      closeIo();
+      return setSocket(theHost, thePort, theIoType);
+   }
+   void setAutoReconnectFlag(bool flag);
+   bool autoReconnectFlag()const;
+   void setAutoReconnectInterval(ossim_uint32 milliseconds);
+   ossim_uint32 autoReconnectInterval()const;
+   
+   // these are the callback handlers and we can create new Sockets with the given handle and add it to the thread.
+   
+   virtual void handleClose (void)
+       {
+//          ulSetError(UL_WARNING,"Network: %d: unhandled close",getHandle());
+       }
+   virtual void handleRead (void); // for udp servers we can read
+   virtual void handleWrite (void);
+//       {
+//          ulSetError(UL_WARNING,"Network: %d: unhandled write",getHandle());
+//       }
+   virtual void handleAccept (void);// for tcp servers we can accept
+    virtual void handleError (int error)
+       {
+			 std::cout << "ossimPlanetIoSocketServerChannel::handleError() = " << error << std::endl;
+//          ulSetError(UL_WARNING,"Network: %d: errno: %s(%d)",getHandle(),strerror(errno),errno);
+       }
+protected:
+   bool protectedFindHandle(int h)const;
+   bool protectedSetSocket(const std::string& host,
+                           int port,
+                           const std::string& ioType);
+   std::string theHost;
+   int  thePort;
+   std::string theIoType;
+   bool theIsTcp;
+   ossimPlanetReentrantMutex theIoListMutex;
+   std::vector<osg::ref_ptr<ossimPlanetIo> > theIoList;
+   ossimPlanetReentrantMutex        theInQueueMutex;
+   std::queue<osg::ref_ptr<ossimPlanetMessage> >   theInQueue;
+   bool                           theAutoReconnectFlag;
+   ossim_uint32                   theAutoReconnectInterval; // specified in milliseconds
+   osg::Timer_t                   theLastTick;
+   ossimPlanetReentrantMutex        theSocketMutex;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetIoThread.h b/ossimPlanet/include/ossimPlanet/ossimPlanetIoThread.h
new file mode 100644
index 0000000..b5808e0
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetIoThread.h
@@ -0,0 +1,76 @@
+#ifndef ossimPlanetIoThread_HEADER
+#define ossimPlanetIoThread_HEADER
+#include <OpenThreads/Thread>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetIoMessageHandler.h>
+#include <osg/ref_ptr>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetIo.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <queue>
+
+class OSSIMPLANET_DLL ossimPlanetIoThread : public OpenThreads::Thread,
+   public osg::Referenced,
+   public ossimPlanetActionReceiver
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetIoMessageHandler> > MessageHandlerListType;
+   ossimPlanetIoThread();
+   void addIo(osg::ref_ptr<ossimPlanetIo> io,
+              bool autoStartFlag = true);
+   virtual void execute(const ossimPlanetAction &a);
+   osg::ref_ptr<ossimPlanetIo> findIo(const ossimString& searchString);
+   const osg::ref_ptr<ossimPlanetIo> findIo(const ossimString& searchString)const;
+   /**
+    * broadcast to all outgoing sockets the passed in message
+    */ 
+   void sendMessage(osg::ref_ptr<ossimPlanetMessage> message, bool forceSendFlag=false);
+   
+   /**
+    * push message onto the named object
+    */ 
+   bool sendMessage(const ossimString& searchName,
+                    osg::ref_ptr<ossimPlanetMessage> message,
+                    bool forceSendFlag=false);
+   osg::ref_ptr<ossimPlanetIo> removeIoGivenSearchString(const ossimString& searchString);
+   osg::ref_ptr<ossimPlanetIo> ioGivenSearchName(const ossimString& sarchString);
+   bool removeIo(osg::ref_ptr<ossimPlanetIo> io);
+   virtual void run();
+   int cancel();
+   bool addMessageHandler(osg::ref_ptr<ossimPlanetIoMessageHandler> handler);
+   bool removeMessageHandler(osg::ref_ptr<ossimPlanetIoMessageHandler> handler);
+   bool removeMessageHandler(const ossimString& handlerName);
+   ossim_uint32 ioCount()const;
+   void clearIo();
+   bool startedFlag()const;
+   void setStartedFlag(bool flag);
+   bool doneFlag()const;
+   void setDoneFlag(bool flag);
+   virtual void setPauseFlag(bool flag, bool waitTilPaused=true);
+   bool pauseFlag()const;
+   bool startCalledFlag()const;
+   void setStartCalledFlag(bool flag);
+   virtual void start();
+protected:
+   void handleMessage(osg::ref_ptr<ossimPlanetMessage> msg);
+   void delayedExecute(const ossimPlanetAction &a);
+   void delayedXmlExecute(const ossimPlanetXmlAction &a);
+   
+   mutable ossimPlanetReentrantMutex thePropertyMutex;
+   mutable ossimPlanetReentrantMutex theIoListMutex;
+   std::vector<osg::ref_ptr<ossimPlanetIo> > theIoList;
+   mutable ossimPlanetReentrantMutex theMessageHandlerListMutex;
+   ossimPlanetIoThread::MessageHandlerListType theMessageHandlerList;
+   bool theDoneFlag;
+   bool theStartedFlag;
+   
+   bool theStartCalledFlag;
+   bool thePauseFlag;
+   mutable ossimPlanetReentrantMutex theDelayedExecutionMutex;
+   std::queue<osg::ref_ptr<ossimPlanetAction> > theDelayedExecution;
+   
+   ossimPlanetReentrantMutex theLoopMutex;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetJpegImage.h b/ossimPlanet/include/ossimPlanet/ossimPlanetJpegImage.h
new file mode 100644
index 0000000..bc47653
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetJpegImage.h
@@ -0,0 +1,24 @@
+#ifndef ossimPlanetJpegImage_HEADER
+#define ossimPlanetJpegImage_HEADER
+#include <iostream>
+#include "ossimPlanetExport.h"
+
+class ossimPlanetImage;
+class OSSIMPLANET_DLL ossimPlanetJpegImage
+{
+public:
+   ossimPlanetJpegImage();
+   virtual ~ossimPlanetJpegImage();
+   bool loadFile(std::string& inputFile,
+                 ossimPlanetImage& image);
+   bool saveFile(std::string& outputFile,
+                 ossimPlanetImage& image);
+                 
+   bool loadFile(std::istream& inputStream,
+                 ossimPlanetImage& image);
+   bool saveFile( std::ostream& stream,
+                  ossimPlanetImage &image,
+                  bool verbose=false);
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKml.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKml.h
new file mode 100644
index 0000000..1ecdc2f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKml.h
@@ -0,0 +1,2553 @@
+#ifndef ossimPlanetKml_HEADER
+#define ossimPlanetKml_HEADER
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <osg/Vec3d>
+#include <ossim/base/ossimXmlNode.h>
+#include <ossim/base/ossimHexString.h>
+#include <ossim/base/ossimXmlDocument.h>
+#include <ossim/base/ossimDpt3d.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/BoundingSphere>
+
+inline OSSIMPLANET_DLL ossimPlanetKmlColorMode ossimPlanetKmlConvertColorMode(const ossimString& value)
+{
+   if(value == "normal")
+   {
+      return ossimPlanetKmlColorMode_NORMAL;
+   }
+   else if(value == "random")
+   {
+      return ossimPlanetKmlColorMode_RANDOM;      
+   }
+
+   return ossimPlanetKmlColorMode_NONE;
+}
+
+inline OSSIMPLANET_DLL ossimPlanetKmlUnits ossimPlanetKmlConvertUnits(const ossimString& value)
+{
+   if(value == "fraction")
+   {
+      return ossimPlanetKmlUnits_FRACTION;
+   }
+   else if(value == "pixels")
+   {
+      return ossimPlanetKmlUnits_PIXELS;      
+   }
+   else if(value == "insetPixels")
+   {
+      return ossimPlanetKmlUnits_INSET_PIXELS;
+   }
+   
+   return ossimPlanetKmlUnits_NONE;
+}
+
+inline OSSIMPLANET_DLL ossimString ossimPlanetKmlConvertUnits(ossimPlanetKmlUnits value)
+{
+   switch(value)
+   {
+      case ossimPlanetKmlUnits_FRACTION:
+      {
+         return "fraction";
+      }
+      case ossimPlanetKmlUnits_PIXELS:
+      {
+         return "pixels";
+      }
+      case ossimPlanetKmlUnits_INSET_PIXELS:
+      {
+         return "insetPixels";
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   return "";
+}
+
+inline OSSIMPLANET_DLL ossimPlanetAltitudeMode ossimPlanetKmlConvertAltitudeMode(const ossimString& value)
+{
+   if((value == "clampToGround")||
+      (value == "clampedToGround"))
+   {
+      return ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+   }
+   else if(value == "relativeToGround")
+   {
+      return ossimPlanetAltitudeMode_RELATIVE_TO_GROUND;      
+   }
+   else if(value == "absolute")
+   {
+      return ossimPlanetAltitudeMode_ABSOLUTE;
+   }
+   
+   return ossimPlanetAltitudeMode_NONE;
+}
+
+inline OSSIMPLANET_DLL ossimString ossimPlanetKmlConvertAltitudeMode(const ossimPlanetAltitudeMode& value)
+{
+   switch(value)
+   {
+      case  ossimPlanetAltitudeMode_CLAMP_TO_GROUND:
+      {
+         return "clampToGround";
+      }
+      case ossimPlanetAltitudeMode_RELATIVE_TO_GROUND:
+      {
+         return "relativeToGround";
+      }
+      case ossimPlanetAltitudeMode_ABSOLUTE:
+      {
+         return "absolute";
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   return "";
+}
+
+inline OSSIMPLANET_DLL ossimPlanetKmlRefreshMode ossimPlanetKmlConvertRefreshMode(const ossimString& value)
+{
+   ossimString temp(value);
+   temp = temp.downcase();
+   
+   if(temp == "onchange")
+   {
+      return ossimPlanetKmlRefreshMode_ON_CHANGE;
+   }
+   else if(temp == "oninterval")
+   {
+      return ossimPlanetKmlRefreshMode_ON_INTERVAL;
+   }
+   else if(temp == "onexpire")
+   {
+      return ossimPlanetKmlRefreshMode_ON_EXPIRE;
+   }
+
+   return ossimPlanetKmlRefreshMode_NONE;
+}
+
+inline OSSIMPLANET_DLL ossimString ossimPlanetKmlConvertRefreshMode(ossimPlanetKmlViewRefreshMode value)
+{
+   switch(value)
+   {
+      case ossimPlanetKmlRefreshMode_ON_CHANGE:
+      {
+         return "onChange";
+      }
+      case ossimPlanetKmlRefreshMode_ON_INTERVAL:
+      {
+         return "onInterval";
+      }
+      case ossimPlanetKmlRefreshMode_ON_EXPIRE:
+      {
+         return "onExpire";
+      }
+      default:
+      {
+         break;
+      }
+   }
+
+   return "";
+}
+
+inline OSSIMPLANET_DLL ossimPlanetKmlViewRefreshMode ossimPlanetKmlConvertViewRefreshMode(const ossimString& value)
+{
+   ossimString temp(value);
+   temp = temp.downcase();
+   
+   if(temp == "never")
+   {
+      return ossimPlanetKmlViewRefreshMode_NEVER;
+   }
+   else if(temp == "onrequest")
+   {
+      return ossimPlanetKmlViewRefreshMode_ON_REQUEST;
+   }
+   else if(temp == "onstop")
+   {
+      return ossimPlanetKmlViewRefreshMode_ON_STOP;
+   }
+   else if(temp == "onregion")
+   {
+      return ossimPlanetKmlViewRefreshMode_ON_REGION;
+   }
+
+   return ossimPlanetKmlViewRefreshMode_NONE;
+}
+
+inline OSSIMPLANET_DLL ossimString ossimPlanetKmlConvertViewRefreshMode(ossimPlanetKmlViewRefreshMode value)
+{
+   switch(value)
+   {
+      case ossimPlanetKmlViewRefreshMode_NEVER:
+      {
+         return "never";
+      }
+      case ossimPlanetKmlViewRefreshMode_ON_REQUEST:
+      {
+         return "onRequest";
+      }
+      case ossimPlanetKmlViewRefreshMode_ON_STOP:
+      {
+         return "onStop";
+      }
+      case ossimPlanetKmlViewRefreshMode_ON_REGION:
+      {
+         return "onRegion";
+      }
+      default:
+      {
+         break;
+      }
+   }
+
+   return "never";
+}
+
+inline OSSIMPLANET_DLL void ossimPlanetKmlColorToRGBA(ossim_uint8& r,
+                                                      ossim_uint8& g,
+                                                      ossim_uint8& b,
+                                                      ossim_uint8& a,
+                                                      const ossimString& colorString)
+{
+   r = 255;
+   g = 255;
+   b = 255;
+   a = 255;
+   if(colorString.size() == 8)
+   {
+      a = ossimHexString(colorString.begin(),
+                         colorString.begin()+2).toUchar();
+      b = ossimHexString(colorString.begin()+2,
+                         colorString.begin()+4).toUchar();
+      g = ossimHexString(colorString.begin()+4,
+                         colorString.begin()+6).toUchar();
+      r = ossimHexString(colorString.begin()+6,
+                         colorString.begin()+8).toUchar();
+   }
+   else if(colorString.size() == 6)
+   {
+      b = ossimHexString(colorString.begin(),
+                         colorString.begin()+2).toUchar();
+      g = ossimHexString(colorString.begin()+2,
+                         colorString.begin()+4).toUchar();
+      r = ossimHexString(colorString.begin()+4,
+                         colorString.begin()+6).toUchar();
+      a = 255;
+   }
+}
+
+class ossimPlanetKmlPoint;
+class ossimPlanetKmlLineString;
+class ossimPlanetKmlLinearRing;
+class ossimPlanetKmlPolygon;
+class ossimPlanetKmlMultiGeometry;
+class ossimPlanetKmlModel;
+class ossimPlanetKmlFeature;
+
+/**
+ * This is an abstract base class and cannot be used directly in a KML file.
+ * It provides the id attribute, which allows unique identification of a KML element,
+ * and the targetId attribute, which is used to reference objects that have already
+ * been loaded into Planet. The id attribute must be assigned if the <Update> mechanism is to be used.
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlObject : public osg::Referenced
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetKmlObject> > ObjectList;
+   ossimPlanetKmlObject()
+   {
+      theId       = "";
+      theTargetId = "";
+      theParent = 0;
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode)=0;
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const=0;
+   void setId(const ossimString& id)
+   {
+      theId = id;
+   }
+   const ossimString& id()
+   {
+      return theId;
+   }
+
+   void setTargetId(const ossimString& targetId)
+   {
+      theTargetId = targetId;
+   }
+   
+   const ossimString& targetId()const
+   {
+      return theTargetId;
+   }
+   ossimPlanetKmlObject::ObjectList& getObjectList()
+   {
+      return theObjectList;
+   }
+   const ossimPlanetKmlObject::ObjectList& getObjectList()const
+   {
+      return theObjectList;
+   }
+   void setParent(ossimPlanetKmlObject* parent)
+   {
+      theParent = parent;
+   }
+   ossimPlanetKmlObject* getParent()
+   {
+      return theParent;
+   }
+   const ossimPlanetKmlObject* getParent()const
+   {
+      return theParent;
+   }
+   static ossimPlanetKmlObject* getRoot(ossimPlanetKmlObject* start);
+   static const ossimPlanetKmlObject* getRoot(const ossimPlanetKmlObject* start);
+   ossimFilename getCacheLocation(bool sharedLocationFlag = false)const;
+   virtual ossimFilename getKmlFile()const;
+protected:
+   ossimPlanetKmlObject* theParent;
+   ossimPlanetKmlObject::ObjectList theObjectList;
+   ossimString theId;
+   ossimString theTargetId;
+};
+
+/**
+ * Lod is an abbreviation for Level of Detail. <Lod> describes the size of the projected
+ * region on the screen that is required in order for the region to be considered
+ * "active." Also specifies the size of the pixel ramp used for fading in
+ * (from transparent to opaque) and fading out (from opaque to transparent).
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlLod: public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlLod()
+      :theMinLodPixels(0),
+      theMaxLodPixels(-1),
+      theMinFadeExtent(0),
+      theMaxFadeExtent(0)
+      {
+      }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+
+   ossim_int32 minLodPixels()const
+   {
+      return theMinLodPixels;
+   }
+   void setMinLodPixels(ossim_int32 minLod)
+   {
+      theMinLodPixels = minLod;
+   }
+   ossim_int32 maxLodPixels()const
+   {
+      return theMaxLodPixels;
+   }
+   ossim_int32 minFadeExtent()const
+   {
+      return theMinFadeExtent;
+   }
+   void setMinFadeExtent(ossim_int32 minFade)
+   {
+      theMinFadeExtent = minFade;
+   }
+   ossim_int32 maxFadeExtent()const
+   {
+      return theMaxFadeExtent;
+   }
+   void setMaxFadeExtent(ossim_int32 maxFade)
+   {
+      theMaxFadeExtent = maxFade;
+   }
+protected:
+   void clearFields()
+   {
+      theMinLodPixels  = 0;
+      theMaxLodPixels  = -1;
+      theMinFadeExtent = 0;
+      theMaxFadeExtent = 0;
+   }
+   /**
+    *<minLodPixels> (default = 0) Measurement in screen pixels
+    * that represents the minimum limit of the visibility range for a
+    * given Region. Google Earth calculates the size of the Region when
+    * projected onto screen space. Then it computes the square root of
+    * the Region's area (if, for example, the Region is square and the
+    * viewpoint is directly above the Region, and the Region is not tilted,
+    * this measurement is equal to the width of the projected Region).
+    * If this measurement falls within the limits defined by
+    * <minLodPixels> and <maxLodPixels> (and if the <LatLonAltBox> is in view),
+    * the Region is active. If this limit is not reached, the associated geometry
+    * is considered to be too far from the user's viewpoint to be drawn.
+    */ 
+   ossim_int32 theMinLodPixels;
+
+   /**
+    *
+    * <maxLodPixels> (default = -1) Measurement in screen pixels that
+    * represents the maximum limit of the visibility range for a given Region.
+    * A value of -1, the default, indicates "active to infinite size."
+    */
+   ossim_int32 theMaxLodPixels;
+
+   /**
+    * <minFadeExtent> (default = 0) Distance over which the geometry fades,
+    * from fully opaque to fully transparent. This ramp value,
+    * expressed in screen pixels, is applied at the minimum end of the LOD (visibility) limits.
+    */
+   ossim_int32 theMinFadeExtent;
+
+   /**
+    * <maxFadeExtent> (default = 0) Distance over which the geometry fades,
+    * from fully transparent to fully opaque. This ramp value, expressed in
+    * screen pixels, is applied at the maximum end of the LOD (visibility) limits.
+    */ 
+   ossim_int32 theMaxFadeExtent;
+};
+
+/**
+ * Scales a model along the x, y, and z axes in the model's coordinate space.
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlScale: public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlScale()
+      :ossimPlanetKmlObject(),
+      theX(1.0),
+      theY(1.0),
+      theZ(1.0)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void setX(double x)
+   {
+      theX = x;
+   }
+   double x()const
+   {
+      return theX;
+   }
+
+   void setY(double y)
+   {
+      theY = y;
+   }
+   double y()const
+   {
+      return theY;
+   }
+
+   void setZ(double z)
+   {
+      theZ = z;
+   }
+   double z()const
+   {
+      return theZ;
+   }
+protected:
+   void clearFields()
+   {
+      theX = 1.0;
+      theY = 1.0;
+      theZ = 1.0;
+   }
+   
+   double theX;
+   double theY;
+   double theZ;
+};
+
+/**
+ * Specifies the exact coordinates of the Model's origin in latitude, longitude,
+ * and altitude. Latitude and longitude measurements are standard lat-lon projection
+ * with WGS84 datum.
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlLocation: public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlLocation()
+      :ossimPlanetKmlObject(),
+      theLongitude(0.0),
+      theLatitude(0.0),
+      theAltitude(0.0)
+   {
+   }
+   ossimPlanetKmlLocation(const ossimPlanetKmlLocation& src)
+      :ossimPlanetKmlObject(src),
+      theLongitude(src.theLongitude),
+      theLatitude(src.theLatitude),
+      theAltitude(src.theAltitude)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void setLongitude(double lon)
+   {
+      theLongitude = lon;
+   }
+   double longitude()const
+   {
+      return theLongitude;
+   }
+
+   void setLatitude(double lat)
+   {
+      theLatitude = lat;
+   }
+   double latitude()const
+   {
+      return theLatitude;
+   }
+
+   void setAltitude(double altitude)
+   {
+      theAltitude = altitude;
+   }
+   double altitude()const
+   {
+      return theAltitude;
+   }
+protected:
+    void clearFields()
+    {
+       theLongitude = 0.0;
+       theLatitude  = 0.0;
+       theAltitude  = 0.0;
+    }
+    double theLongitude;
+    double theLatitude;
+    double theAltitude;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlOrientation : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlOrientation()
+      :ossimPlanetKmlObject(),
+      theHeading(0.0),
+      thePitch(0.0),
+      theRoll(0.0)
+   {
+   }
+   ossimPlanetKmlOrientation(const ossimPlanetKmlOrientation& src)
+      :ossimPlanetKmlObject(src),
+      theHeading(src.theHeading),
+      thePitch(src.thePitch),
+      theRoll(src.theRoll)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void setHeading(double h)
+   {
+      theHeading = h;
+   }
+   double heading()const
+   {
+      return theHeading;
+   }
+   void setPitch(double p)
+   {
+      thePitch = p;
+   }
+   double pitch()const
+   {
+      return thePitch;
+   }
+   void setRoll(double r)
+   {
+      theRoll = r;
+   }
+   double roll()const
+   {
+      return theRoll;
+   }
+protected:
+   void clearFields()
+   {
+      theHeading = 0.0;
+      thePitch   = 0.0;
+      theRoll    = 0.0;
+   }
+   double theHeading;
+   double thePitch;
+   double theRoll;
+};
+
+
+/**
+ * Specifies where the top, bottom, right, and left sides of a bounding box for the
+ * ground overlay are aligned. The <north>, <south>, <east>, and <west> elements are required.
+ * <north> (required) Specifies the latitude of the north edge of the bounding box,
+ * in decimal degrees from 0 to ±90.
+ * <south> (required) Specifies the latitude of the south edge of the bounding box,
+ * in decimal degrees from 0 to ±90.
+ * <east> (required) Specifies the longitude of the east edge of the bounding box,
+ * in decimal degrees from 0 to ±180. (For overlays that overlap the meridian of 180 longitude, values can extend beyond that range.)
+ * <west> (required) Specifies the longitude of the west edge of the bounding box,
+ * in decimal degrees from 0 to ±180. (For overlays that overlap the meridian of 180 longitude,
+ * values can extend beyond that range.)
+ * <rotation> (optional) specifies a rotation of the overlay about its center,
+ * in degrees. Values can be ±180. The default is 0 (north). Rotations are specified in a clockwise direction.
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlLatLonBox : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlLatLonBox()
+      :ossimPlanetKmlObject()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theNorth    = 0.0;
+      theSouth    = 0.0;
+      theEast     = 0.0;
+      theWest     = 0.0;
+      theRotation = 0.0;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      alt = 0.0;
+      lat = (theNorth+theSouth)*0.5;
+      lon = (theEast+theWest)*0.5;
+
+      return true;
+   }
+   void setBounds(double north, double south,
+                  double east, double west)
+   {
+      theNorth = north;
+      theSouth = south;
+      theEast  = east;
+      theWest  = west;
+   }
+   void setNorth(double n)
+   {
+      theNorth = n;
+   }
+   double north()const
+   {
+      return theNorth;
+   }
+   void setSouth(double s)
+   {
+      theSouth = s;
+   }
+   double south()const
+   {
+      return theSouth;
+   }
+   void setEast(double e)
+   {
+      theEast = e;
+   }
+   double east()const
+   {
+      return theEast;
+   }
+   
+   void setRotation(double rotation)
+   {
+      theRotation = rotation;
+   }
+   double rotation()const
+   {
+      return theRotation;
+   }
+protected:
+   
+   double theNorth;
+   double theSouth;
+   double theEast;
+   double theWest;
+   double theRotation;
+};
+
+
+/**
+ * <LatLonAltBox>
+ *
+ * A bounding box that describes an area of interest
+ * defined by geographic coordinates and altitudes.
+ * Default values and required fields are as follows:
+ *
+ * Adds the following tags to LatLonBox:
+ * 
+ * <altitudeMode> (defaults to clampToGround).
+ *                Possible values are clampToGround, relativeToGround, and absolute.
+ * <minAltitude> Defaults to 0; specified in meters above sea level (and is affected by
+ *               the <altitudeMode> specification).
+ * <maxAltitude> Defaults to 0; specified in meters above sea level
+ *                (and is affected by the <altitudeMode> specification).
+ */ 
+class OSSIMPLANET_DLL ossimPlanetKmlLatLonAltBox : public ossimPlanetKmlLatLonBox
+{
+public:
+   ossimPlanetKmlLatLonAltBox()
+      :ossimPlanetKmlLatLonBox()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theMinAltitude = 0.0;
+      theMaxAltitude = 0.0;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      alt = (theMinAltitude+theMaxAltitude)*0.5;
+      lat = (theNorth+theSouth)*0.5;
+      lon = (theEast+theWest)*0.5;
+      
+      return true;
+   }
+   void setBounds(double north, double south,
+                  double east, double west,
+                  double minAlt=0.0, double maxAlt=0.0)
+   {
+      ossimPlanetKmlLatLonBox::setBounds(north, south, east, west);
+      theMinAltitude = minAlt;
+      theMaxAltitude = maxAlt;
+   }
+   void setMinAltitude(double minAlt)
+   {
+      theMinAltitude = minAlt;
+   }
+   double minAltitude()const
+   {
+      return theMinAltitude;
+   }
+   void setMaxAltitude(double maxAlt)
+   {
+      theMaxAltitude = maxAlt;
+   }
+   double maxAltitude()const
+   {
+      return theMaxAltitude;
+   }
+   ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+   
+protected:
+   double      theMinAltitude;
+   double      theMaxAltitude;
+   ossimPlanetAltitudeMode theAltitudeMode;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLink : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlLink()
+      :ossimPlanetKmlObject()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   
+   void clearFields()
+   {
+      theHref            = "";
+      theRefreshMode     = ossimPlanetKmlRefreshMode_ON_CHANGE;
+      theRefreshInterval = 4.0;
+      theViewRefreshMode = ossimPlanetKmlViewRefreshMode_NEVER;
+      theViewRefreshTime = 4.0;
+      theViewBoundScale  = 1.0;
+      theViewFormat      = "";
+      theHttpQuery       = "";
+   }
+   void setHref(const ossimString& ref)
+   {
+      theHref = ref;
+   }
+   const ossimString href()const
+   {
+      return theHref;
+   }
+
+   void setRefreshMode(ossimPlanetKmlRefreshMode refreshMode)
+   {
+      theRefreshMode = refreshMode;
+   }
+   ossimPlanetKmlRefreshMode refreshMode()const
+   {
+      return theRefreshMode;
+   }
+
+   double refreshInterval()const
+   {
+      return theRefreshInterval;
+   }
+   void setRefreshInterval(double interval)
+   {
+      theRefreshInterval = interval; 
+   }
+
+   void setViewRefreshMode(ossimPlanetKmlViewRefreshMode mode)
+   {
+      theViewRefreshMode = mode;
+   }
+   ossimPlanetKmlViewRefreshMode viewRefreshMode()const
+   {
+      return theViewRefreshMode;
+   }
+
+   void setViewRefreshTime(double time)
+   {
+      theViewRefreshTime = time;
+   }
+   double viewRefreshTime()const
+   {
+      return theViewRefreshTime;
+   }
+
+   void setViewBoundScale(double scale)
+   {
+      theViewBoundScale = scale;
+   }
+   double viewBoundScale()const
+   {
+      return theViewBoundScale;
+   }
+
+   void setViewFormat(const ossimString& value)
+   {
+      theViewFormat = value;
+   }
+   const ossimString& viewFormat()const
+   {
+      return theViewFormat;
+   }
+   void setHttpQuery(const ossimString& value)
+   {
+      theHttpQuery = value;
+   }
+   const ossimString& httpQuery()const
+   {
+      return theHttpQuery;
+   }
+   virtual ossimFilename download(bool forceOverwrite=false,
+                                  const ossimFilename& locationOverride=ossimFilename(""))const;
+   
+protected:
+   
+   ossimString theHref;
+   ossimPlanetKmlRefreshMode theRefreshMode;
+   double      theRefreshInterval;
+   ossimPlanetKmlViewRefreshMode theViewRefreshMode;
+   double      theViewRefreshTime;
+   double      theViewBoundScale;
+   ossimString theViewFormat;
+   ossimString theHttpQuery;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlIcon : public ossimPlanetKmlLink
+{
+public:
+   ossimPlanetKmlIcon()
+      :ossimPlanetKmlLink()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+ 
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlRegion : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlRegion()
+      :ossimPlanetKmlObject()
+   {
+      
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      lat = 0.0;
+      lon = 0.0;
+      alt = 0.0;
+      if(theBox.valid())
+      {
+         return theBox->getCenter(lat, lon, alt);
+      }
+      return false;
+   }
+   void setBounds(double north, double south,
+                  double east, double west,
+                  double minAlt=0.0, double maxAlt=0.0)
+   {
+      if(!theBox.valid())
+      {
+         theBox = new ossimPlanetKmlLatLonAltBox;
+      }
+      theBox->setBounds(north, south, east, west, minAlt, maxAlt);
+   }
+   void setBox(osg::ref_ptr<ossimPlanetKmlLatLonAltBox> box)
+   {
+      theBox = box.get();
+   }
+   const osg::ref_ptr<ossimPlanetKmlLatLonAltBox> box()const
+   {
+      return theBox.get();
+   }
+   void setLod(osg::ref_ptr<ossimPlanetKmlLod> lod)
+   {
+      theLod = lod.get();
+   }
+   const osg::ref_ptr<ossimPlanetKmlLod> lod()const
+   {
+      return theLod.get();
+   }
+protected:
+   void clearFields()
+   {
+      theLod = 0;
+      theBox = 0;
+   }
+   osg::ref_ptr<ossimPlanetKmlLod>          theLod;
+   osg::ref_ptr<ossimPlanetKmlLatLonAltBox> theBox;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLookAt : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlLookAt()
+      :ossimPlanetKmlObject()
+   {
+      theLookAt = new ossimPlanetLookAt();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void setAll(double lat, double lon, double altitude,
+               double heading,  double pitch, double range,
+               const ossimString& mode="clampToGround")
+   {
+      theLookAt->setAll(lat, lon, altitude, heading, pitch, 0.0, range,
+                        ossimPlanetLookAt::modeFromString(mode));
+   }
+
+
+   osg::ref_ptr<ossimPlanetLookAt> lookAt()
+   {
+      return theLookAt;
+   }
+   const osg::ref_ptr<ossimPlanetLookAt> lookAt()const
+   {
+      return theLookAt;
+   }
+   
+   void clearFields()
+   {
+      setAll(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, "clampToGround");
+   }
+   double latitude()const
+   {
+      return theLookAt->lat();
+   }
+   double longitude()const
+   {
+      return theLookAt->lon();
+   }
+   double altitude()const
+   {
+      return theLookAt->altitude();
+   }
+   double heading()const
+   {
+      return theLookAt->heading();
+   }
+   double pitch()const
+   {
+      return theLookAt->pitch();
+   }
+   double roll()const
+   {
+      return theLookAt->roll();
+   }
+   double range()const
+   {
+      return theLookAt->range();
+   }
+   void setAlititudeMode(ossimPlanetAltitudeMode mode)
+   {
+      theLookAt->setAltitudeMode(mode);
+   }
+   ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theLookAt->altitudeMode();
+   }
+protected:
+   osg::ref_ptr<ossimPlanetLookAt> theLookAt;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlTimePrimitive : public ossimPlanetKmlObject
+{
+public:
+/*    static ossimData toDate(const ossimString& formatString); */
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlTimeSpan : public ossimPlanetKmlTimePrimitive
+{
+public:
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void clearFields()
+   {
+      theBegin = "";
+      theEnd  = "";
+   }
+protected:
+   ossimString theBegin;
+   ossimString theEnd;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlTimeStamp : public ossimPlanetKmlTimePrimitive
+{
+public:
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void clearFields()
+   {
+      theWhen = "";
+   }
+protected:
+   ossimString theWhen;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlColorStyle : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlColorStyle()
+      :ossimPlanetKmlObject(),
+      theColor("ffffffff"),
+      theColorMode(ossimPlanetKmlColorMode_NORMAL)
+   {
+   }
+
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theColor     = "";
+      theColorMode = ossimPlanetKmlColorMode_NORMAL;
+   }
+
+   const ossimString& color()const
+   {
+      return theColor;
+   }
+
+   ossimPlanetKmlColorMode colorMode()const
+   {
+      return theColorMode;
+   }
+   
+public:
+   ossimString             theColor;
+   ossimPlanetKmlColorMode theColorMode;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLineStyle : public ossimPlanetKmlColorStyle
+{
+public:
+   ossimPlanetKmlLineStyle()
+      :ossimPlanetKmlColorStyle(),
+      theWidth(1)
+   {
+   }
+
+   bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   ossim_float32 width()const
+   {
+      return theWidth;
+   }
+   void clearFields()
+   {
+      theWidth = 1.0;
+   }
+   
+protected:
+   ossim_float32 theWidth;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlPolyStyle : public ossimPlanetKmlColorStyle
+{
+public:
+   ossimPlanetKmlPolyStyle()
+      :ossimPlanetKmlColorStyle(),
+      theFillFlag(true),
+      theOutlineFlag(true)
+   {
+   }
+
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   bool getFillFlag()const
+   {
+      return theFillFlag;
+   }
+   bool getOutlineFlag()const
+   {
+      return theOutlineFlag;
+   }
+   void clearFields()
+   {
+      theFillFlag    = true;
+      theOutlineFlag = true;
+   }
+protected:
+   bool theFillFlag;
+   bool theOutlineFlag;
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetKmlIconStyle : public ossimPlanetKmlColorStyle
+{
+public:
+   ossimPlanetKmlIconStyle()
+      :ossimPlanetKmlColorStyle(),
+      theScale(1.0),
+      theHeading(0.0),
+      theXHotspot(.5),
+      theYHotspot(.5),
+      theXUnits(ossimPlanetKmlUnits_FRACTION),
+      theYUnits(ossimPlanetKmlUnits_FRACTION)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theScale    = 1.0;
+      theHeading  = 1.0;
+      theIcon     = 0;
+      theXHotspot = .5;
+      theYHotspot = .5;
+      theXUnits   = ossimPlanetKmlUnits_FRACTION;
+   }
+   osg::ref_ptr<ossimPlanetKmlIcon> icon()
+   {
+      return theIcon;
+   }
+   const osg::ref_ptr<ossimPlanetKmlIcon> icon()const
+   {
+      return theIcon;
+   }
+   
+   double xHotSpot()const
+   {
+      return theXHotspot;
+   }
+   double yHotspot()const
+   {
+      return theYHotspot;
+   }
+   double heading()const
+   {
+      return theHeading;
+   }
+   double scale()const
+   {
+      return theScale;
+   }
+   ossimPlanetKmlUnits xUnits()const
+   {
+      return theXUnits;
+   }
+   ossimPlanetKmlUnits yUnits()const
+   {
+      return theYUnits;
+   }
+   
+protected:
+   float theScale;
+   float theHeading;
+   osg::ref_ptr<ossimPlanetKmlIcon> theIcon;
+   float theXHotspot;
+   float theYHotspot;
+   ossimPlanetKmlUnits theXUnits;
+   ossimPlanetKmlUnits theYUnits;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLabelStyle : public ossimPlanetKmlColorStyle
+{
+public:
+   ossimPlanetKmlLabelStyle()
+      :ossimPlanetKmlColorStyle(),
+      theScale(1.0)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void setScale(float scale)
+   {
+      theScale = scale;
+   }
+   float scale()const
+   {
+      return theScale;
+   }
+   void clearFields()
+   {
+      theScale = 1.0;
+   }
+protected:
+   float theScale;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlBalloonStyle : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlBalloonStyle()
+      :ossimPlanetKmlObject(),
+      theBackgroundColor("ffffffff"),
+      theTextColor("ff000000"),
+      theText("")
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   const ossimString& backgroundColor()const
+   {
+      return theBackgroundColor;
+   }
+   const ossimString& textColor()const
+   {
+      return theTextColor;
+   }
+   const ossimString& text()const
+   {
+      return theText;
+   }
+   void clearFields()
+   {
+      theBackgroundColor = "ffffffff";
+      theTextColor       = "ff000000";
+      theText            = "";
+   }
+protected:
+   ossimString theBackgroundColor;
+   ossimString theTextColor;
+   ossimString theText;
+};
+
+class ossimPlanetKmlStyle;
+class ossimPlanetKmlStyleMap;
+class OSSIMPLANET_DLL ossimPlanetKmlStyleSelector : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlStyleSelector()
+      :ossimPlanetKmlObject()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+   {
+      return ossimPlanetKmlObject::parse(xmlNode);
+   }
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const
+   {
+      ossimPlanetKmlObject::write(xmlNode);
+   }
+   virtual const ossimPlanetKmlStyle* toStyle()const
+   {
+      return 0;
+   }
+   virtual ossimPlanetKmlStyle* toStyle()
+   {
+      return 0;
+   }
+   virtual const ossimPlanetKmlStyleMap* toStyleMap()const
+   {
+      return 0;
+   }
+   virtual ossimPlanetKmlStyleMap* toStyleMap()
+   {
+      return 0;
+   }
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlStyle : public ossimPlanetKmlStyleSelector
+{
+public:
+   ossimPlanetKmlStyle()
+      :ossimPlanetKmlStyleSelector()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual const ossimPlanetKmlStyle* toStyle()const
+   {
+      return this;
+   }
+   virtual ossimPlanetKmlStyle* toStyle()
+   {
+      return this;
+   }
+   
+   void clearFields()
+   {
+      theIconStyle  = 0;
+      theLabelStyle = 0;
+      theLineStyle  = 0;
+      thePolyStyle  = 0;
+   }
+   void setIconStyle(osg::ref_ptr<ossimPlanetKmlIconStyle> value)
+   {
+      theIconStyle = value;
+   }
+   const osg::ref_ptr<ossimPlanetKmlIconStyle> iconStyle()const
+   {
+      return theIconStyle.get();
+   }
+   void setLabelStyle(osg::ref_ptr<ossimPlanetKmlLabelStyle> value)
+   {
+      theLabelStyle = value;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLabelStyle> labelStyle()const
+   {
+      return theLabelStyle.get();
+   }
+   void setLineStyle(osg::ref_ptr<ossimPlanetKmlLineStyle> value)
+   {
+      theLineStyle = value;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLineStyle> lineStyle()const
+   {
+      return theLineStyle.get();
+   }
+   void setPolyStyle(osg::ref_ptr<ossimPlanetKmlPolyStyle> value)
+   {
+      thePolyStyle = value;
+   }
+   const osg::ref_ptr<ossimPlanetKmlPolyStyle> polyStyle()const
+   {
+      return thePolyStyle.get();
+   }
+   void setBalloonStyle(osg::ref_ptr<ossimPlanetKmlBalloonStyle> value)
+   {
+      theBalloonStyle = value;
+   }
+   const osg::ref_ptr<ossimPlanetKmlBalloonStyle> balloonStyle()const
+   {
+      return theBalloonStyle.get();
+   }
+
+protected:
+   osg::ref_ptr<ossimPlanetKmlIconStyle>  theIconStyle;
+   osg::ref_ptr<ossimPlanetKmlLabelStyle> theLabelStyle;
+   osg::ref_ptr<ossimPlanetKmlLineStyle>  theLineStyle;
+   osg::ref_ptr<ossimPlanetKmlPolyStyle>  thePolyStyle;
+   osg::ref_ptr<ossimPlanetKmlBalloonStyle>  theBalloonStyle;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlStyleMap : public ossimPlanetKmlStyleSelector
+{
+public:
+   typedef std::map<std::string, std::string> MapType;
+   
+   ossimPlanetKmlStyleMap()
+      :ossimPlanetKmlStyleSelector()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void clearFields()
+   {
+      theStyleMap.clear();
+   }
+   virtual const ossimPlanetKmlStyleMap* toStyleMap()const
+   {
+      return this;
+   }
+   virtual ossimPlanetKmlStyleMap* toStyleMap()
+   {
+      return this;
+   }
+   void styles(std::vector<ossimString>& styleNames)const
+   {
+      MapType::const_iterator i = theStyleMap.begin();
+      while(i!=theStyleMap.end())
+      {
+         styleNames.push_back(i->first);
+         ++i;
+      }
+   }
+   ossimString findStyle(const ossimString& styleName)const
+   {
+      MapType::const_iterator i = theStyleMap.find(styleName);
+      if(i != theStyleMap.end())
+      {
+         return i->second;
+      }
+      return "";
+   }
+   ossimString normalUrl()const
+   {
+      return findStyle("normal");
+   }
+   ossimString highlightUrl()const
+   {
+      return findStyle("highlight");
+   }
+protected:
+/*    ossimString theNormalUrl; */
+/*    ossimString theHighlightUrl; */
+   MapType theStyleMap;
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetKmlFeature : public ossimPlanetKmlObject
+{
+public:
+   ossimPlanetKmlFeature()
+      :ossimPlanetKmlObject()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theName           = "";
+      theVisibilityFlag = true;
+      theOpenFlag       = true;
+      theAddress        = "";
+      thePhoneNumber    = "";
+      theDescription    = "";
+      theCDataDescriptionFlag = false;
+      theLookAt         = 0;
+      theStyleUrl       = "";
+      theStyleSelector  = 0;
+      theRegion         = 0;
+      theExtendedData   = 0;
+   }
+   void setName(const ossimString& name)
+   {
+      theName = name;
+   }
+   const ossimString& name()const
+   {
+      return theName;
+   }
+   bool visibilityFlag()const
+   {
+      return theVisibilityFlag;
+   }
+   void setVisibilityFlag(bool flag)
+   {
+      theVisibilityFlag = flag;
+   }
+   void setOpenFlag(bool flag)
+   {
+      theOpenFlag = flag;
+   }
+   bool openFlag()const
+   {
+      return theOpenFlag;
+   }
+   void setAddress(const ossimString& address)
+   {
+      theAddress = address;
+   }
+   const ossimString& address()const
+   {
+      return theAddress;
+   }
+   void setPhoneNumber(const ossimString& phoneNumber)
+   {
+      thePhoneNumber = phoneNumber;
+   }
+   const ossimString& phoneNumber()const
+   {
+      return thePhoneNumber;
+   }
+   void setDescription(const ossimString& description)
+   {
+      theDescription = description;
+   }
+   const ossimString& description()const
+   {
+      return theDescription;
+   }
+   void setLookAt(osg::ref_ptr<ossimPlanetKmlLookAt> lookAt)
+   {
+      theLookAt = lookAt.get();
+   }
+   const osg::ref_ptr<ossimPlanetKmlLookAt>  lookAt()const
+   {
+      return theLookAt;
+   }
+   void setSyleUrl(const ossimString& styleUrl)
+   {
+      theStyleUrl = styleUrl;
+   }
+   const ossimString& styleUrl()const
+   {
+      return theStyleUrl;
+   }
+   void setRegion(osg::ref_ptr<ossimPlanetKmlRegion> region)
+   {
+      theRegion = region.get();
+   }
+   osg::ref_ptr<ossimPlanetKmlRegion> region()const
+   {
+      return theRegion;
+   }
+   void setExtendedData(ossimRefPtr<ossimXmlNode> value)
+   {
+      theExtendedData = value;
+   }
+   const ossimXmlNode* extendedData()const
+   {
+      return theExtendedData.get();
+   }
+   ossimXmlNode* extendedData()
+   {
+      return theExtendedData.get();
+   }
+
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      lat = 0.0;
+      lon = 0.0;
+      alt = 0.0;
+
+      if(theRegion.valid())
+      {
+         return theRegion->getCenter(lat, lon, alt);
+      }
+      return false;
+   }
+   
+   const osg::ref_ptr<ossimPlanetKmlStyleSelector> getStyleSelector()const
+   {
+      return theStyleSelector;
+   }
+protected:
+   ossimString theName;
+   bool        theVisibilityFlag;
+   bool        theOpenFlag;
+   ossimString theAddress;
+   // there is an Address details field.  Need to look at it later.
+
+   // End details field
+
+   ossimString thePhoneNumber;
+   ossimString theSnippet;
+   ossimString theSnippetMaxLines;
+   ossimString theDescription;
+   bool        theCDataDescriptionFlag;
+   osg::ref_ptr<ossimPlanetKmlLookAt> theLookAt;
+   osg::ref_ptr<ossimPlanetKmlTimePrimitive> theTimePrimitive;
+   ossimString theStyleUrl;
+   osg::ref_ptr<ossimPlanetKmlStyleSelector> theStyleSelector;
+   osg::ref_ptr<ossimPlanetKmlRegion> theRegion;
+   ossimRefPtr<ossimXmlNode> theExtendedData;
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetKmlGeometry : public ossimPlanetKmlObject
+{
+public:
+   typedef std::vector<osg::Vec3d> PointListType;
+   
+   ossimPlanetKmlGeometry()
+      :ossimPlanetKmlObject()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual bool getCenter(double& lat, double& lon, double& alt)const=0;
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return ossimPlanetAltitudeMode_NONE;
+   }
+
+   virtual ossimPlanetKmlPoint* toPoint(){return 0;}
+   virtual const ossimPlanetKmlPoint* toPoint()const{return 0;}
+   virtual ossimPlanetKmlLineString* toLineString(){return 0;}
+   virtual const ossimPlanetKmlLineString* toLineString()const{return 0;}
+   virtual ossimPlanetKmlLinearRing* toLinearRing(){return 0;}
+   virtual const ossimPlanetKmlLinearRing* toLinearRing()const{return 0;}
+   virtual ossimPlanetKmlPolygon* toPolygon(){return 0;}
+   virtual const ossimPlanetKmlPolygon* toPolygon()const{return 0;}
+   virtual ossimPlanetKmlMultiGeometry* toMultiGeometry(){return 0;}
+   virtual const ossimPlanetKmlMultiGeometry* toMultiGeometry()const{return 0;}
+   virtual ossimPlanetKmlModel* toModel(){return 0;}
+   virtual const ossimPlanetKmlModel* toModel()const{return 0;}
+
+   static void computeCenter(osg::Vec3d& result,
+                             const PointListType& pointList);
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlPoint : public ossimPlanetKmlGeometry
+{
+public:
+   ossimPlanetKmlPoint()
+      :ossimPlanetKmlGeometry()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      if(thePointList.size() > 0)
+      {
+         lat = theCenter[1];
+         lon = theCenter[0];
+         alt = theCenter[2];
+      }
+
+      return (thePointList.size()>0);
+   }
+   virtual ossimPlanetKmlPoint* toPoint(){return this;}
+   virtual const ossimPlanetKmlPoint* toPoint()const{return this;}
+
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+
+   void setExtrudeFlag(bool flag)
+   {
+      theExtrudeFlag = flag;
+   }
+   bool extrudeFlag()const
+   {
+      return theExtrudeFlag;
+   }
+
+   void setTesselateFlag(bool flag)
+   {
+      theTesselateFlag = flag;
+   }
+   bool tesselateFlag()const
+   {
+      return theTesselateFlag;
+   }
+
+   const ossimPlanetKmlGeometry::PointListType& pointList()const
+   {
+      return thePointList;
+   }
+   ossimPlanetKmlGeometry::PointListType& pointList()
+   {
+      return thePointList;
+   }
+   
+protected:
+   void clearFields()
+   {
+      theExtrudeFlag = false;
+      theTesselateFlag = false;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      thePointList.clear();
+      theCenter = osg::Vec3d(0.0,0.0,0.0);
+   }
+   
+   bool                    theExtrudeFlag;
+   bool                    theTesselateFlag;
+   ossimPlanetAltitudeMode theAltitudeMode;
+   ossimPlanetKmlGeometry::PointListType thePointList;
+   osg::Vec3d theCenter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLineString : public ossimPlanetKmlGeometry
+{
+public:
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual ossimPlanetKmlLineString* toLineString(){return this;}
+   virtual const ossimPlanetKmlLineString* toLineString()const{return this;}
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+
+   void setExtrudeFlag(bool flag)
+   {
+      theExtrudeFlag = flag;
+   }
+   bool extrudeFlag()const
+   {
+      return theExtrudeFlag;
+   }
+
+   void setTesselateFlag(bool flag)
+   {
+      theTesselateFlag = flag;
+   }
+   bool tesselateFlag()const
+   {
+      return theTesselateFlag;
+   }
+
+   const ossimPlanetKmlGeometry::PointListType& pointList()const
+   {
+      return thePointList;
+   }
+   ossimPlanetKmlGeometry::PointListType& pointList()
+   {
+      return thePointList;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      if(thePointList.size() > 0)
+      {
+         lat = theCenter[1];
+         lon = theCenter[0];
+         alt = theCenter[2];
+      }
+
+      return (thePointList.size()>0);
+   }
+   
+protected:
+   void clearFields()
+   {
+      theExtrudeFlag = false;
+      theTesselateFlag = false;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      thePointList.clear();
+      theCenter = osg::Vec3d(0.0,0.0,0.0);
+   }
+   bool        theExtrudeFlag;
+   bool        theTesselateFlag;
+   ossimPlanetAltitudeMode theAltitudeMode;
+   ossimPlanetKmlGeometry::PointListType thePointList;
+   osg::Vec3d theCenter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLinearRing : public ossimPlanetKmlGeometry
+{
+public:
+   ossimPlanetKmlLinearRing()
+      :ossimPlanetKmlGeometry()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+
+   void setExtrudeFlag(bool flag)
+   {
+      theExtrudeFlag = flag;
+   }
+   bool extrudeFlag()const
+   {
+      return theExtrudeFlag;
+   }
+
+   void setTesselateFlag(bool flag)
+   {
+      theTesselateFlag = flag;
+   }
+   bool tesselateFlag()const
+   {
+      return theTesselateFlag;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      if(thePointList.size() > 0)
+      {
+         lat = theCenter[1];
+         lon = theCenter[0];
+         alt = theCenter[2];
+      }
+
+      return (thePointList.size()>0);
+   }
+   virtual ossimPlanetKmlLinearRing* toLinearRing(){return this;}
+   virtual const ossimPlanetKmlLinearRing* toLinearRing()const{return this;}
+   const ossimPlanetKmlGeometry::PointListType& pointList()const
+   {
+      return thePointList;
+   }
+   ossimPlanetKmlGeometry::PointListType& pointList()
+   {
+      return thePointList;
+   }
+
+protected:
+   void clearFields()
+   {
+      theExtrudeFlag = false;
+      theTesselateFlag = false;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      thePointList.clear();
+      theCenter = osg::Vec3d(0.0,0.0,0.0);
+   }
+   bool        theExtrudeFlag;
+   bool        theTesselateFlag;
+   ossimPlanetAltitudeMode theAltitudeMode;
+   ossimPlanetKmlGeometry::PointListType thePointList;
+   osg::Vec3d theCenter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlPolygon : public ossimPlanetKmlGeometry
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetKmlLinearRing> > InnerBoundaryList;
+   
+   ossimPlanetKmlPolygon()
+      :ossimPlanetKmlGeometry()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+
+   void setExtrudeFlag(bool flag)
+   {
+      theExtrudeFlag = flag;
+   }
+   bool extrudeFlag()const
+   {
+      return theExtrudeFlag;
+   }
+
+   void setTesselateFlag(bool flag)
+   {
+      theTesselateFlag = flag;
+   }
+   bool tesselateFlag()const
+   {
+      return theTesselateFlag;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      if(theOuterBoundary.valid())
+      {
+         return theOuterBoundary->getCenter(lat, lon, alt);
+      }
+
+      return false;
+   }
+   virtual ossimPlanetKmlPolygon* toPolygon(){return this;}
+   virtual const ossimPlanetKmlPolygon* toPolygon()const{return this;}
+
+
+   osg::ref_ptr<ossimPlanetKmlLinearRing> outerBoundary()
+   {
+      return theOuterBoundary;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLinearRing> outerBoundary()const
+   {
+      return theOuterBoundary;
+   }
+
+   ossimPlanetKmlPolygon::InnerBoundaryList& innerBoundaryList()
+   {
+      return theInnerBoundaryList;
+   }
+
+   const ossimPlanetKmlPolygon::InnerBoundaryList& innerBoundaryList()const
+   {
+      return theInnerBoundaryList;
+   }
+   
+protected:
+   void clearFields()
+   {
+      theExtrudeFlag = false;
+      theTesselateFlag = false;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      theOuterBoundary = 0;
+      theInnerBoundaryList.clear();
+      theCenter = osg::Vec3d(0.0,0.0,0.0);
+   }
+   bool        theExtrudeFlag;
+   bool        theTesselateFlag;
+   ossimPlanetAltitudeMode theAltitudeMode;
+   osg::ref_ptr<ossimPlanetKmlLinearRing>   theOuterBoundary;
+   ossimPlanetKmlPolygon::InnerBoundaryList  theInnerBoundaryList;
+   osg::Vec3d theCenter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlMultiGeometry : public ossimPlanetKmlGeometry
+{
+public:
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      if(theGeometryList.size()>0)
+      {
+         theGeometryList[0]->getCenter(lat, lon, alt);
+      }
+/*       if(theGeometryList.size() > 0) */
+/*       { */
+/*          double tempLat=0.0, tempLon=0.0, tempAlt=0.0; */
+/*          theGeometryList[0]->getCenter(tempLat, tempLon, tempAlt); */
+/*          ossim_uint32 idx = 1; */
+/*          for(;idx < theGeometryList.size(); ++idx) */
+/*          { */
+/*             if(theGeometryList[idx]->getCenter(lat, lon, alt)) */
+/*             { */
+/*                tempLat += lat; */
+/*                tempLon += lon; */
+/*                tempAlt += alt; */
+/*             } */
+/*          } */
+/*          lat = tempLat/(double)theGeometryList.size(); */
+/*          lon = tempLon/(double)theGeometryList.size(); */
+/*          alt = tempAlt/(double)theGeometryList.size(); */
+         
+/*       } */
+      return (theGeometryList.size() > 0);
+   }   
+   virtual ossimPlanetKmlMultiGeometry* toMultiGeometry(){return this;}
+   virtual const ossimPlanetKmlMultiGeometry* toMultiGeometry()const{return this;}
+
+   std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> >& geomtryList()
+   {
+      return theGeometryList;
+   }
+   const std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> >& geomtryList()const
+   {
+      return theGeometryList;
+   }
+protected:
+   void clearFields()
+   {
+      theGeometryList.clear();
+      theCenter = osg::Vec3d(0.0,0.0,0.0);
+   }
+   std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> > theGeometryList;
+   osg::Vec3d theCenter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlModel : public ossimPlanetKmlGeometry
+{
+public:
+   ossimPlanetKmlModel()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      lat = theLocation->latitude();
+      lon = theLocation->longitude();
+      alt = theLocation->altitude();
+
+      return true;
+   }   
+   virtual ossimPlanetKmlModel* toModel(){return this;}
+   virtual const ossimPlanetKmlModel* toModel()const{return this;}
+
+   osg::ref_ptr<ossimPlanetKmlLocation> location()
+   {
+      return theLocation;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLocation> location()const
+   {
+      return theLocation;
+   }
+   osg::ref_ptr<ossimPlanetKmlOrientation> orientation()
+   {
+      return theOrientation;
+   }
+   const osg::ref_ptr<ossimPlanetKmlOrientation> orientation()const
+   {
+      return theOrientation;
+   }
+   osg::ref_ptr<ossimPlanetKmlScale> scale()
+   {
+      return theScale;
+   }
+   
+   const osg::ref_ptr<ossimPlanetKmlScale> scale()const
+   {
+      return theScale;
+   }
+   osg::ref_ptr<ossimPlanetKmlLink> link()
+   {
+      return theLink;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLink> link()const
+   {
+      return theLink;
+   }
+   virtual ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+   void setAltitudeMode(ossimPlanetAltitudeMode mode)
+   {
+      theAltitudeMode = mode;
+   }
+   
+protected:
+   void clearFields()
+   {
+      theLocation    = new ossimPlanetKmlLocation;
+      theOrientation = new ossimPlanetKmlOrientation;
+      theScale       = new ossimPlanetKmlScale;
+      theLocation->setParent(this);
+      theOrientation->setParent(this);
+      theScale->setParent(this);
+      theLink = 0;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+   }
+
+   osg::ref_ptr<ossimPlanetKmlLocation>    theLocation;
+   osg::ref_ptr<ossimPlanetKmlOrientation> theOrientation;
+   osg::ref_ptr<ossimPlanetKmlScale>       theScale; 
+   osg::ref_ptr<ossimPlanetKmlLink>        theLink;
+   ossimPlanetAltitudeMode                 theAltitudeMode;
+ 
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlOverlay : public ossimPlanetKmlFeature
+{
+public:
+   ossimPlanetKmlOverlay()
+      :ossimPlanetKmlFeature()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void setColor(const ossimString& value)
+   {
+      theColor = value;
+   }
+   const ossimString& color()const
+   {
+      return theColor;
+   }
+   void setDrawOrder(ossim_int32 value)
+   {
+      theDrawOrder = value;
+   }
+   ossim_int32 drawOrder()const
+   {
+      return theDrawOrder;
+   }
+   void clearFields()
+   {
+      theColor     = "ffffffff";
+      theDrawOrder = 0;
+      theIcon      = 0;
+   }
+   osg::ref_ptr<ossimPlanetKmlIcon> icon()
+   {
+      return theIcon;
+   }
+   const osg::ref_ptr<ossimPlanetKmlIcon> icon()const
+   {
+      return theIcon;
+   }
+   
+protected:
+   ossimString theColor;
+   ossim_int32 theDrawOrder;
+   osg::ref_ptr<ossimPlanetKmlIcon> theIcon;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlScreenOverlay : public ossimPlanetKmlOverlay
+{
+public:
+   ossimPlanetKmlScreenOverlay()
+      :ossimPlanetKmlOverlay()
+   {
+      clearFields();
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   void setOverlayPosition(double x, double y)
+   {
+      theOverlayX = x;
+      theOverlayY = y;
+   }
+   void setOverlayUnits(ossimPlanetKmlUnits units)
+   {
+      theOverlayXUnits = units;
+      theOverlayYUnits = units;
+   }
+   void setOverlayXUnits(ossimPlanetKmlUnits units)
+   {
+      theOverlayXUnits = units;
+   }
+   void setOverlayYUnits(ossimPlanetKmlUnits units)
+   {
+      theOverlayYUnits = units;
+   }
+   double overlayX()const
+   {
+      return theOverlayX;
+   }
+   double overlayY()const
+   {
+      return theOverlayY;
+   }
+   ossimPlanetKmlUnits overlayXUnits()const
+   {
+      return theOverlayXUnits;
+   }
+   ossimPlanetKmlUnits overlayYUnits()const
+   {
+      return theOverlayYUnits;
+   }
+   
+   void setScreenPosition(double x, double y)
+   {
+      theScreenX = x;
+      theScreenY = y;
+   }
+   void setScreenUnits(ossimPlanetKmlUnits units)
+   {
+      theScreenXUnits = units;
+      theScreenYUnits = units;
+   }
+   void setScreenXUnits(ossimPlanetKmlUnits units)
+   {
+      theScreenXUnits = units;      
+   }
+   void setScreenYUnits(ossimPlanetKmlUnits units)
+   {
+      theScreenYUnits = units;      
+   }
+   double screenX()const
+   {
+      return theScreenX;
+   }
+   double screenY()const
+   {
+      return theScreenY;
+   }
+   ossimPlanetKmlUnits screenXUnits()const
+   {
+      return theScreenXUnits;
+   }
+   ossimPlanetKmlUnits screenYUnits()const
+   {
+      return theScreenYUnits;
+   }
+   void setRotationXY(double xRotate, double yRotate)
+   {
+      theRotationX = xRotate;
+      theRotationY = yRotate;
+   }
+   void setRotationXYUnits(ossimPlanetKmlUnits units)
+   {
+      theRotationXUnits = units;
+      theRotationYUnits = units;
+   }
+   void setRotationXUnits(ossimPlanetKmlUnits units)
+   {
+      theRotationXUnits = units;
+   }
+   void setRotationYUnits(ossimPlanetKmlUnits units)
+   {
+      theRotationYUnits = units;
+   }
+   double rotationX()const
+   {
+      return theRotationX;
+   }
+   double rotationY()const
+   {
+      return theRotationY;
+   }
+   
+   ossimPlanetKmlUnits rotationXUnits()const
+   {
+      return theRotationXUnits;
+   }
+   ossimPlanetKmlUnits rotationYUnits()const
+   {
+      return theRotationYUnits;
+   }
+   void setSize(double x, double y)
+   {
+      theSizeX = x;
+      theSizeY = y;
+   }
+   void setSizeX(double x)
+   {
+      theSizeX = x;
+   }
+   void setSizeY(double y)
+   {
+      theSizeY = y;
+   }
+   void setSizeUnits(ossimPlanetKmlUnits units)
+   {
+      theSizeXUnits = units;
+      theSizeYUnits = units;
+   }
+   double sizeX()const
+   {
+      return theSizeX;
+   }
+   double sizeY()const
+   {
+      return theSizeY;
+   }
+   ossimPlanetKmlUnits sizeXUnits()const
+   {
+      return theSizeXUnits;
+   }
+   ossimPlanetKmlUnits sizeYUnits()const
+   {
+      return theSizeYUnits;
+   }
+   
+   void setRotation(float value)
+   {
+      theRotation = value;
+   }
+   float rotation()const
+   {
+      return theRotation;
+   }
+   void clearFields()
+   {
+      theOverlayX= 0.0;
+      theOverlayY= 0.0;
+      theOverlayXUnits = ossimPlanetKmlUnits_FRACTION;
+      theOverlayYUnits = ossimPlanetKmlUnits_FRACTION;
+      theScreenX= 0.0;
+      theScreenY= 0.0;
+      theScreenXUnits = ossimPlanetKmlUnits_FRACTION;
+      theScreenYUnits = ossimPlanetKmlUnits_FRACTION;
+      theRotationX = 0.0;
+      theRotationY = 0.0;
+      theRotationXUnits = ossimPlanetKmlUnits_FRACTION;
+      theRotationYUnits = ossimPlanetKmlUnits_FRACTION;
+      theSizeX = 0.0;
+      theSizeY = 0.0;
+      theSizeXUnits = ossimPlanetKmlUnits_FRACTION;
+      theSizeYUnits = ossimPlanetKmlUnits_FRACTION;
+      theRotation = 0.0;
+   }
+                    
+protected:
+   double theOverlayX;
+   double theOverlayY;
+   ossimPlanetKmlUnits theOverlayXUnits;
+   ossimPlanetKmlUnits theOverlayYUnits;
+   double theScreenX;
+   double theScreenY;
+   ossimPlanetKmlUnits theScreenXUnits;
+   ossimPlanetKmlUnits theScreenYUnits;
+   double theRotationX;
+   double theRotationY;
+   ossimPlanetKmlUnits theRotationXUnits;
+   ossimPlanetKmlUnits theRotationYUnits;
+   double theSizeX;
+   double theSizeY;
+   ossimPlanetKmlUnits theSizeXUnits;
+   ossimPlanetKmlUnits theSizeYUnits;
+   float theRotation;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlGroundOverlay : public ossimPlanetKmlOverlay
+{
+public:
+   ossimPlanetKmlGroundOverlay()
+      :ossimPlanetKmlOverlay(),
+      theAltitude(0.0),
+      theAltitudeMode(ossimPlanetAltitudeMode_CLAMP_TO_GROUND),
+      theLatLonBox(0)
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   double altitude()const
+   {
+      return theAltitude;
+   }
+   void setAltitude(double value)
+   {
+      theAltitude = value;
+   }
+   ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theAltitudeMode;
+   }
+   void setAltitudeMode(ossimPlanetAltitudeMode mode)
+   {
+      theAltitudeMode = mode;
+   }
+   const osg::ref_ptr<ossimPlanetKmlLatLonBox> latLonBox()const
+   {
+      return theLatLonBox;
+   }
+   void setLatLonBox(osg::ref_ptr<ossimPlanetKmlLatLonBox> value)
+   {
+      theLatLonBox = value;
+   }
+   void clearFields()
+   {
+      theAltitude = 0.0;
+      theAltitudeMode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      theLatLonBox = 0;
+   }
+protected:
+   double                                theAltitude;
+   ossimPlanetAltitudeMode               theAltitudeMode;
+   osg::ref_ptr<ossimPlanetKmlLatLonBox> theLatLonBox;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlNetworkLink : public ossimPlanetKmlFeature
+{
+public:
+   ossimPlanetKmlNetworkLink()
+      :ossimPlanetKmlFeature()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   const ossimPlanetKmlLink* link()const
+   {
+      return theLink.get();
+   }
+   ossimPlanetKmlLink* link()
+   {
+      return theLink.get();
+   }
+   void setLink(osg::ref_ptr<ossimPlanetKmlLink> value)
+   {
+      theLink = value;
+   }
+   bool refreshVisibilityFlag()const
+   {
+      return theRefreshVisibilityFlag;
+   }
+   void setRefreshVisibilityFlag(bool value)
+   {
+      theRefreshVisibilityFlag = value;
+   }
+   bool flyToViewFlag()const
+   {
+      return theFlyToViewFlag;
+   }
+   void setFlyToViewFlag(bool value)
+   {
+      theFlyToViewFlag = value;
+   }
+   void clearFields()
+   {
+      theLink                  = 0;
+      theRefreshVisibilityFlag = false;
+      theFlyToViewFlag         = false;
+   }
+   
+protected:
+   
+   osg::ref_ptr<ossimPlanetKmlLink> theLink;
+
+   bool                             theRefreshVisibilityFlag;
+   bool                             theFlyToViewFlag;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlPlacemark : public ossimPlanetKmlFeature
+{
+public:
+   ossimPlanetKmlPlacemark()
+      :ossimPlanetKmlFeature()
+   {}
+   bool parse(const ossimRefPtr<ossimXmlNode> node);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+
+   void clearFields()
+   {
+      theGeometry = 0;
+   }
+   osg::ref_ptr<ossimPlanetKmlGeometry> getGeometry()
+   {
+      return theGeometry;
+   }
+   const osg::ref_ptr<ossimPlanetKmlGeometry> getGeometry()const
+   {
+      return theGeometry;
+   }
+   virtual bool getCenter(double& lat, double& lon, double& alt)const
+   {
+      bool result = ossimPlanetKmlFeature::getCenter(lat, lon, alt);
+
+      if(!result)
+      {
+         if(theGeometry.valid())
+         {
+            result = theGeometry->getCenter(lat, lon, alt);
+         }
+      }      
+      return result;
+   }
+
+ void setColor(std::string color)
+ {
+    thePColor = color;    
+ }
+ const std::string& getPColor()const
+ {
+   return thePColor;
+ }  
+ 
+protected:
+    std::string thePColor;
+   osg::ref_ptr<ossimPlanetKmlGeometry> theGeometry;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlContainer : public ossimPlanetKmlFeature
+{
+public:
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlFolder : public ossimPlanetKmlContainer
+{
+public:
+   ossimPlanetKmlFolder()
+      :ossimPlanetKmlContainer()
+   {
+   }
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> xmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlDocument : public ossimPlanetKmlContainer
+{
+public:
+   ossimPlanetKmlDocument();
+   bool parse(const ossimRefPtr<ossimXmlNode> node);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+};
+
+class OSSIMPLANET_DLL ossimPlanetKml : public ossimPlanetKmlObject
+{
+public:
+   typedef std::map<std::string, osg::ref_ptr<ossimPlanetKmlObject> > IdMapType;
+   ossimPlanetKml();
+
+   virtual bool parse(const ossimFilename& file);
+   virtual bool parse(std::istream& in, bool fullDocumentFlag=true);
+   virtual bool parse(const ossimRefPtr<ossimXmlDocument> document);
+
+/*    const ossimPlanetKmlObject::ObjectList& getObjectList()const */
+/*    { */
+/*       return theObjectList; */
+/*    } */
+
+   virtual bool parse(const ossimRefPtr<ossimXmlNode> kmlNode);
+   virtual void write(ossimRefPtr<ossimXmlNode> xmlNode)const;
+   virtual ossimRefPtr<ossimXmlDocument> writeDocument()const;
+   bool getAllFeatures(ossimPlanetKmlObject::ObjectList& placemarks);
+   void createIdMap()const;
+   osg::ref_ptr<ossimPlanetKmlObject> findById(const ossimString& id);
+   const osg::ref_ptr<ossimPlanetKmlObject> findById(const ossimString& id)const;
+
+   const ossimFilename& filename()const
+   {
+      return theFilename;
+   }
+   virtual bool isCompressed()const
+   {
+      return false;
+   }
+   
+   ossimFilename getCacheLocation(bool sharedLocationFlag = false)const;
+   virtual ossimFilename getKmlFile()const
+   {
+      return theFilename;
+   }
+protected:
+   ossimFilename                    theFilename;
+   mutable ossimFilename            theCacheLocation;
+   mutable bool                     theIdMapGeneratedFlag;
+   mutable IdMapType theIdMap;
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetKmz : public ossimPlanetKml
+{
+public:
+
+   ossimPlanetKmz();
+   virtual ~ossimPlanetKmz();
+   virtual bool parse(std::istream& in);
+   virtual bool parse(const ossimFilename& file);
+   virtual bool isCompressed()const
+   {
+      return true;
+   }
+protected:
+   void extractFiles();
+   void deleteExtractedFiles();
+   void* thePrivateData;  
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetKmlObjectRegistry
+{
+public:
+   static ossimPlanetKmlObjectRegistry* instance();
+   ossimPlanetKmlObject* newObject(const ossimXmlNode* tag)const;
+   ossimPlanetKmlObject* newObject(const ossimString& tag)const;
+   ossimPlanetKmlObject* newGeometry(const ossimString& tag)const;
+   ossimPlanetKmlObject* newTimePrimitive(const ossimString& tag)const;
+   ossimPlanetKmlObject* newColorStyle(const ossimString& tag)const;
+    
+protected:
+   ossimPlanetKmlObjectRegistry();
+   ossimPlanetKmlObjectRegistry(const ossimPlanetKmlObjectRegistry&){}
+   
+   static ossimPlanetKmlObjectRegistry* theInstance;
+   
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayer.h
new file mode 100644
index 0000000..d0d0be6
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayer.h
@@ -0,0 +1,201 @@
+#ifndef ossimPlanetKmlLayer_HEADER
+#define ossimPlanetKmlLayer_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetKmlLayerNode.h>
+#include <ossimPlanet/ossimPlanetKml.h>
+#include <OpenThreads/Mutex>
+#include <osgDB/ReaderWriter>
+#include <osg/Texture2D>
+#include <osg/FrameStamp>
+#include <osgUtil/IntersectVisitor>
+#include <queue>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <time.h>
+#include <ossimPlanet/ossimPlanetIconGeom.h>
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+
+class ossimPlanet;
+class OSSIMPLANET_DLL ossimPlanetKmlLayerReaderWriter : public osgDB::ReaderWriter
+{
+public:
+   ossimPlanetKmlLayerReaderWriter(ossimPlanetKmlLayer* layer=0)
+      :theLayer(layer)
+      {
+         theRecurseFlag = false;
+         srand(time(0));
+      }
+   void setLayer(ossimPlanetKmlLayer* layer)
+      {
+         theLayer = layer;
+      }
+   virtual ReadResult readNode(const std::string& fileName, const Options*)const;
+   void setKmlCacheLocation(const ossimFilename& location)
+   {
+      theKmlCacheLocation = location;
+   }
+   virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) const;
+   void setId(const ossimString& id)
+   {
+	theIdString = id;
+   }
+protected:
+   
+   mutable ossimPlanetKmlLayer*                  theLayer; 
+   ossimFilename                                 theKmlCacheLocation;
+   mutable ossimFilename                         theCurrentPlwLocation;
+   mutable bool                                  theRecurseFlag;
+   ossimString                                   theIdString;
+};
+
+
+
+// theis is teporary testing for ground annotations.  We will initially be testing
+// grouping of Placemark Icons into common/shared draws
+//
+class ossimPlanetKmlLayerTile : public osg::Referenced
+{
+public:
+
+protected:
+   // will hold the tile location
+   ossim_uint32 theRow;
+   ossim_uint32 theCol;
+   ossim_uint32 theLevel;
+   ossim_uint32 theFace;
+
+   // will hold the local space transform for this cell.
+   // used to convert common points to the local space.
+   // Entities will be added to this graph after transformation
+   //
+   osg::ref_ptr<osg::MatrixTransform> theLocalToWorldTransform;
+   
+};
+
+class OSSIMPLANET_DLL ossimPlanetKmlLayer : public ossimPlanetLayer
+{
+   friend class ossimPlanetKmlLayerReaderWriter;
+public:
+   class FindNodeVisitor : public osg::NodeVisitor
+   {
+   public:
+      typedef std::vector<osg::ref_ptr<ossimPlanetKmlLayerNode> > LayerNodeList;
+      FindNodeVisitor(const ossimString& id)
+         :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+         theId(id)
+         {
+         }
+      virtual void apply(osg::Node& node)
+      {
+         ossimPlanetKmlLayerNode* n = dynamic_cast<ossimPlanetKmlLayerNode*>(&node);
+         if(n)
+         {
+            if(n->id() == theId)
+            {
+               theLayerNodeList.push_back(n);
+            }
+         }
+         
+         traverse(node);
+      }
+      FindNodeVisitor::LayerNodeList& layerList()
+      {
+         return theLayerNodeList;
+      }
+      const FindNodeVisitor::LayerNodeList& layerList()const
+      {
+         return theLayerNodeList;
+      }
+      
+   protected:
+      FindNodeVisitor::LayerNodeList theLayerNodeList;
+      ossimString theId;
+   };
+   typedef std::map<std::string, osg::ref_ptr<ossimPlanetIconGeom> > IconMap;
+   class OSSIMPLANET_DLL ossimPlanetKmlLayerCallback : public osg::Referenced
+   {
+   public:
+      ossimPlanetKmlLayerCallback()
+         :osg::Referenced(),
+         theEnableFlag(true)
+      {
+      }
+      virtual void nodeAdded(osg::Node* /*node*/){}
+      virtual void nodeDeleted(osg::Node* /*node*/){}
+      bool enableFlag()const
+      {
+         return theEnableFlag;
+      }
+      void setEnableFlag(bool flag)
+      {
+         theEnableFlag = flag;
+      }
+   protected:
+      bool theEnableFlag;
+   };
+   ossimPlanetKmlLayer();
+   virtual osg::Object* cloneType() const { return new ossimPlanetKmlLayer(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanetKmlLayer *>(obj)!=0; }
+   virtual const char* className() const { return "ossimPlanetKmlLayer"; } 
+   virtual const char* libraryName() const { return "ossimPlanet"; }
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual void addKml(const ossimFilename& kmlFile);
+   virtual void addKml(osg::ref_ptr<ossimPlanetKmlObject> kml);
+   virtual void addKml(osg::ref_ptr<osg::Group> parent,
+                       osg::ref_ptr<ossimPlanetKmlObject> kml);
+
+   virtual bool addChild( Node *child );
+
+   osg::ref_ptr<ossimPlanetIconGeom> getOrCreateIconEntry(const ossimString& src);
+   osg::ref_ptr<ossimPlanetIconGeom> getIconEntry(const ossimString& src);
+   void deleteNode(const ossimString& id);
+   
+   const ossimPlanet* planet()const;
+   const ossimPlanetGeoRefModel* landModel()const;
+   ossimPlanet* planet();
+   ossimPlanetGeoRefModel* landModel();
+   
+   void readyToAddNode(osg::Group* parent,
+                       osg::Node* node);
+   
+protected:
+   
+   class NodeToAddInfo
+   {
+   public:
+      NodeToAddInfo(osg::Group* parent,
+                     osg::Node* node)
+      :theParent(parent),
+      theNode(node)
+      {
+      }
+      osg::ref_ptr<osg::Group> theParent;
+      osg::ref_ptr<osg::Node> theNode;
+   };
+   bool hasCallback(const ossimPlanetKmlLayerCallback* callback)const;
+   void initializePalettes();
+   mutable ossimPlanetReentrantMutex theGraphMutex;                                           
+   mutable ossimPlanetReentrantMutex theReadyToAddListMutex;                                           
+   mutable ossimPlanetReentrantMutex theReadyToProcessKmlListMutex;
+   std::vector<osg::ref_ptr<ossimPlanetKmlLayerNode> > theNodeList;
+
+
+   std::queue<ossimFilename>                        theReadyToProcessKmlFileList;
+   std::queue<osg::ref_ptr<ossimPlanetKmlObject> >  theReadyToProcessKmlList;
+   osg::ref_ptr<ossimPlanetKmlLayerReaderWriter>    theReaderWriter;
+   ossimFilename                                    theKmlCacheLocation;
+   ossimPlanetKmlLayer::IconMap                     theIconMap;
+   osg::ref_ptr<osg::FrameStamp>                    theFudgeStamp;
+//   osg::ref_ptr<ossimPlanetDatabasePager>           theDatabasePager;
+   bool theNodesAddedFlag;
+   osg::ref_ptr<ossimPlanetOperationThreadQueue> theOperationQueue;
+//   osg::ref_ptr<ossimPlanetKmlLayer::PagerCallback> thePagerCallback; 
+   
+   OpenThreads::Mutex theNodesToAddListMutex;
+   std::vector<NodeToAddInfo> theNodesToAddList;
+   osg::ref_ptr<osg::Referenced> theRequestRef;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayerNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayerNode.h
new file mode 100644
index 0000000..d6fe33b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlLayerNode.h
@@ -0,0 +1,49 @@
+#ifndef ossimPlanetKmlLayerNode_HEADER
+#define ossimPlanetKmlLayerNode_HEADER
+#include <osg/Group>
+#include <ossimPlanet/ossimPlanetKml.h>
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <osg/Image>
+class ossimPlanetKmlLayer;
+
+class OSSIMPLANET_DLL ossimPlanetKmlLayerNode : public ossimPlanetNode
+{
+public:
+   ossimPlanetKmlLayerNode(ossimPlanetKmlLayer* layer = 0,
+                           ossimPlanetKmlObject* obj  = 0);
+   void setKmlLayer(ossimPlanetKmlLayer* layer)
+   {
+      theLayer = layer;
+   }
+   void setLayer(ossimPlanetKmlLayer* layer);
+   void setKmlObject(ossimPlanetKmlObject* obj);
+   ossimPlanetKmlLayer* layer();
+   
+   osg::ref_ptr<ossimPlanetKmlObject> kmlObject()
+   {
+      return theKmlObject.get();
+   }
+
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+   /**
+    * This is a convenient method for interactive GUIs to call to allow a KML node to change its state
+    * in the scene graph.
+    */ 
+   virtual void doNormalStyle(){}
+
+   /**
+    * This is a convenient method for interactive GUIs to call to allow the KML node to change its state
+    * in the scene graph.
+    */ 
+   virtual void doHighlightStyle(){}
+   
+   virtual bool init();
+   
+protected:
+   ossimPlanetKmlLayer*               theLayer;
+   osg::ref_ptr<ossimPlanetKmlObject> theKmlObject;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlNetworkLinkNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlNetworkLinkNode.h
new file mode 100644
index 0000000..91ab760
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlNetworkLinkNode.h
@@ -0,0 +1,18 @@
+#ifndef ossimPlanetKmlNetworkLinkNode_HEADER
+#define ossimPlanetKmlNetworkLinkNode_HEADER
+#include <ossimPlanet/ossimPlanetKmlLayerNode.h>
+
+class OSSIMPLANET_DLL ossimPlanetKmlNetworkLinkNode : public ossimPlanetKmlLayerNode
+{
+public:
+   ossimPlanetKmlNetworkLinkNode(ossimPlanetKmlLayer* layer = 0,
+                                 ossimPlanetKmlObject* obj  = 0);
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual bool init();
+   
+protected:
+   osg::ref_ptr<ossimPlanetKml> theKmlData;
+   bool theScheduledFlag;
+
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlPlacemarkNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlPlacemarkNode.h
new file mode 100644
index 0000000..55c9aae
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlPlacemarkNode.h
@@ -0,0 +1,72 @@
+#ifndef ossimPlanetKmlPlacemarkNode_HEADER
+#define ossimPlanetKmlPlacemarkNode_HEADER
+#include <ossimPlanet/ossimPlanetKmlLayerNode.h>
+#include <ossimPlanet/ossimPlanetLabelGeom.h>
+#include <osg/MatrixTransform>
+#include <ossimPlanet/ossimPlanetBillboardIcon.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetFadeText.h>
+#include <osg/ClusterCullingCallback>
+#include <ossimPlanet/ossimPlanetKml.h>
+
+class ossimPlanetKmlPlacemarkNode : public ossimPlanetKmlLayerNode
+{
+public:
+   ossimPlanetKmlPlacemarkNode(ossimPlanetKmlLayer* layer = 0,
+                               ossimPlanetKmlObject* obj  = 0);
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   virtual bool init();
+   
+protected:
+   class PlacemarkGeometryDraw : public osg::Drawable::DrawCallback
+   {
+   public:
+      PlacemarkGeometryDraw()
+         :theOpacity(1.0)
+      {
+         
+      }
+      virtual void drawImplementation(osg::RenderInfo& /*renderInfo*/,
+                                      const osg::Drawable* /*drawable*/)const;
+   public:
+      float theOpacity;
+   };
+   double convertHeight(const osg::Vec3d& kmlWorldPoint,
+                        ossimPlanetAltitudeMode altMode,
+                        ossimPlanetGeoRefModel* landModel)const;
+                        
+   void convertPointsToLocalCoordinates(osg::Vec3Array* result,
+                                        const ossimPlanetKmlGeometry::PointListType& pointList,
+                                        const osg::Matrixd& worldToLocalTransform,
+                                        ossimPlanetGeoRefModel* landModel,
+                                        ossimPlanetAltitudeMode altMode,
+                                        double& minHeight,
+                                        double& maxHeight)const;
+
+   void extrude(osg::ref_ptr<osg::Geometry> result,
+                osg::Vec3Array* verts,
+                osg::Vec3Array* extrusionVerts,
+                const std::vector<std::pair<ossim_uint32, ossim_uint32> >& extrusionGroups)const;
+
+
+
+   double                              theNormalizationScale;
+   osg::ref_ptr<osg::Group>            theKmlGeometries;
+   osg::ref_ptr<osg::Group>            theKmlPickableGeometries;
+   bool                                theCulledFlag;
+
+   // we will shift the center of the bounds to the ground level
+   // and use this for determining pixel coverage
+   //
+   ossim_float64                       theRadius;
+   osg::Vec3d                          theCenter;
+
+   ossim_float32                       theFadeAlpha;
+   osg::ref_ptr<PlacemarkGeometryDraw> theDraw;
+   osg::ref_ptr<ossimPlanetKmlRegion> theRegion;
+   osg::ref_ptr<ossimPlanetKmlLod>    theLod;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlReaderWriter.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlReaderWriter.h
new file mode 100644
index 0000000..4c2c8c0
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlReaderWriter.h
@@ -0,0 +1,16 @@
+#ifndef ossimPlanetKmlReaderWriter_HEADER
+#define ossimPlanetKmlReaderWriter_HEADER
+#include <osgDB/ReaderWriter>
+
+class ossimPlanetKmlReaderWriter : : public osgDB::ReaderWriter
+{
+public:
+   ossimPlanetKmlReaderWriter();
+   
+   virtual ReadResult readNode(const std::string& /*fileName*/, const Options* =NULL) const;
+
+protected:
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetKmlScreenOverlayNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlScreenOverlayNode.h
new file mode 100644
index 0000000..14a2be2
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetKmlScreenOverlayNode.h
@@ -0,0 +1,49 @@
+#ifndef ossimPlanetKmlScreenOverlayNode_HEADER
+#define ossimPlanetKmlScreenOverlayNode_HEADER
+#include <ossimPlanet/ossimPlanetKml.h>
+#include <ossimPlanet/ossimPlanetKmlLayerNode.h>
+#include <osg/Group>
+#include <osg/CameraNode>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetIconGeom.h>
+
+class ossimPlanetKmlScreenOverlayNode : public ossimPlanetKmlLayerNode
+{
+public:
+   ossimPlanetKmlScreenOverlayNode(ossimPlanetKmlLayer* layer = 0,
+                                   ossimPlanetKmlObject* obj  = 0);
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual bool init();
+
+protected:
+   void update();
+   void computeOverlayXY(osg::Vec3d& position);
+   void computeScreenXY(osg::Vec3d& position);
+   void computeSize(osg::Vec3d& size);
+   
+   osg::ref_ptr<osg::CameraNode> theCameraNode;
+   osg::ref_ptr<osg::Group> theGroup;
+   osg::ref_ptr<osg::Viewport> theViewport;
+   osg::ref_ptr<osg::Geode> theIconGeode; 
+   osg::ref_ptr<ossimPlanetIconGeom> theIconGeom; 
+   bool theViewportChangedFlag;
+   bool theNeedsUpdateFlag;
+
+   osg::Vec2d theOverlayOrigin;
+   ossimPlanetKmlUnits theOverlayXUnits;
+   ossimPlanetKmlUnits theOverlayYUnits;
+   osg::Vec2d theScreenOrigin;
+   ossimPlanetKmlUnits theScreenXUnits;
+   ossimPlanetKmlUnits theScreenYUnits;
+   
+   osg::Vec2d theRotationOrigin;
+   ossimPlanetKmlUnits theRotationXUnits;
+   ossimPlanetKmlUnits theRotationYUnits;
+   osg::Vec2d theSize;
+   ossimPlanetKmlUnits theSizeXUnits;
+   ossimPlanetKmlUnits theSizeYUnits;   
+   float theRotation;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLabelGeom.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLabelGeom.h
new file mode 100644
index 0000000..4a08365
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLabelGeom.h
@@ -0,0 +1,77 @@
+#ifndef ossimPlanetLabelGeom_HEADER
+#define ossimPlanetLabelGeom_HEADER
+#include <osg/Node>
+#include <osg/CoordinateSystemNode>
+#include <osg/MatrixTransform>
+#include <osg/Billboard>
+#include <osgText/Text>
+#include <osg/Matrixd>
+#include <osg/Vec4f>
+#include <ossim/base/ossimString.h>
+
+class ossimPlanetLabelGeom : public osg::Node
+{
+public:
+   enum ShowState
+   {
+      SHOW_NO_STATE      = 0,
+      SHOW_WHEN_FULL_RES = 1, // default
+      SHOW_ALWAYS        = 2
+   };
+   class ossimPlanetLabelGeomUpdateCallback : public osg::NodeCallback
+   {
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+         {
+            ossimPlanetLabelGeom* n = dynamic_cast<ossimPlanetLabelGeom*>(node);
+            if(n)
+            {
+               n->traverse(*nv);
+            }
+         }
+   };
+   ossimPlanetLabelGeom(const ossimString& label="",
+                        double characterSizeInObjectSpace=1.0/osg::WGS_84_RADIUS_EQUATOR);
+   virtual ~ossimPlanetLabelGeom();
+   void setAlignment(osgText::Text::AlignmentType alignment);
+   void setCharacterSizeInObjectSpace(double objectSize);
+   osg::ref_ptr<osgText::Text> getLabel();
+   void setLabel(const ossimString& label);
+   /**
+    * Setting to 0 or negative says there is no max height.
+    */ 
+   void setMaxHeightInPixels(double pixelHeight);
+   /**
+    * Setting to 0 or negative value says there is no minimum height.
+    */ 
+   void setMinHeightInPixels(double pixelHeight);
+   
+   void setColor(float r, float g, float b, float a=1.0);
+   void setEnableFlag(bool enableFlag);
+   void setShowFlag(bool show);
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual osg::BoundingSphere computeBound() const;
+protected:
+   /**
+    * Specifies how the label should be shown.  You can show it once it reaches full resolution of the pixel
+    * identified by the .
+    */ 
+   ossimPlanetLabelGeom::ShowState     theShowState;
+   mutable bool                        theShowFlag;
+   mutable bool                        theUpdateTransformFlag;
+   bool                                theEnableFlag;
+   double                              theMaxHeightInPixels;
+   double                              theMinHeightInPixels;
+
+   /**
+    * used to make sure the font is at desired size in pixel if the
+    * max or min font heights are specified.
+    */ 
+   osg::ref_ptr<osg::MatrixTransform>  theTransform;  
+   osg::ref_ptr<osg::Billboard>        theBillboard;
+   osg::ref_ptr<osgText::Text>         theLabel;
+   osg::Matrixd                        theMatrix;
+   osg::Vec4f                          theColor;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLand.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLand.h
new file mode 100644
index 0000000..244a41f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLand.h
@@ -0,0 +1,181 @@
+#ifndef ossimPlanetLand_HEADER
+#define ossimPlanetLand_HEADER
+#include <osg/Group>
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <osgDB/DatabasePager>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetLandNormalType.h>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetExtents.h>
+#include <ossimPlanet/ossimPlanetShaderProgramSetup.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossimPlanet/ossimPlanetLandCache.h>
+#include <ossimPlanet/ossimPlanetElevationDatabaseGroup.h>
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetLandCullCallback.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <osg/GL2Extensions>
+
+class ossimPlanetGeoRefModel;
+class ossimPlanetLandReaderWriter;
+
+class OSSIMPLANET_DLL ossimPlanetLand : public ossimPlanetLayer 
+{
+public:
+   friend class ossimPlanetLandUpdateCallback;
+   friend class ossimPlanetLandRefreshVisitor;
+   ossimPlanetLand();
+
+   virtual osg::Object* cloneType() const { return new ossimPlanetLand(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanetLand *>(obj)!=NULL; }
+   virtual const char* className() const { return "ossimPlanetLand"; } 
+   virtual const char* libraryName() const { return "ossimPlanet"; }
+   virtual void accept(osg::NodeVisitor& nv);
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   virtual void setModel(ossimPlanetGeoRefModel* model);
+   void setLineOfSiteIntersection(const osg::Vec3d& pt);
+   
+   void setElevationEnabledFlag(bool elevationEnabledFlag);
+   bool getElevationEnabledFlag()const;
+   
+   ossim_float64 getHeightExag()const;
+   void setHeightExag(ossim_float64 heightExag);
+   ossim_uint32 getElevationPatchSize()const;
+   void setElevationPatchSize(ossim_uint32 patchSize);
+   void setReaderWriter(ossimPlanetLandReaderWriter* readerWriter);
+ 	ossimPlanetLandReaderWriter* getReaderWriter();
+	const ossimPlanetLandReaderWriter* getReaderWriter()const;
+	ossim_uint32 getMaxLevelDetail()const;
+   void setMaxLevelDetail(ossim_uint32 maxLevelDetail);
+   ossimFilename getElevationCacheDir()const;
+   void setElevationCacheDir(const ossimFilename& cacheDir);
+   void resetGraph(osg::ref_ptr<ossimPlanetExtents> extents=0,
+                   ossimPlanetLandRefreshType refreshType=ossimPlanetLandRefreshType_PRUNE);
+   virtual bool addChild( Node *child );
+   const osg::ref_ptr<ossimPlanetGeoRefModel> model()const;
+
+   ossim_uint32 getNumberOfOverlayLayers()const;
+   void setReferenceLayer(osg::ref_ptr<ossimPlanetTextureLayerGroup> reference);
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> referenceLayer();
+   const osg::ref_ptr<ossimPlanetTextureLayerGroup> referenceLayer()const;
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> overlayLayers();
+   const osg::ref_ptr<ossimPlanetTextureLayerGroup> overlayLayers()const;
+   osg::ref_ptr<ossimPlanetTextureLayer> overlayLayer(ossim_uint32 layerIdx);
+   const osg::ref_ptr<ossimPlanetTextureLayer> overlayLayer(ossim_uint32 layerIdx)const;
+   osg::ref_ptr<ossimPlanetTextureLayer> removeOverlayLayer(ossim_uint32 layerIdx);
+   void addOverlayLayer(osg::ref_ptr<ossimPlanetTextureLayerGroup> overlay);
+   void setOverlayLayer(ossim_uint32 idx,
+                        osg::ref_ptr<ossimPlanetTextureLayerGroup> overlay);
+   osg::ref_ptr<ossimPlanetShaderProgramSetup> getCurrentShader();
+   void setCurrentFragmentShaderType(ossimPlanetShaderProgramSetup::ossimPlanetFragmentShaderType fragType);
+   /**
+    * Setting to 0 will disable caching.  The second argument dictates how far to shrink the cache when it exceeds
+    * the maxSize allowed.  Maybe a good value is .85*maxSize.  This will allow about a 15% reduction in cache size
+    */ 
+   void setCacheSize(ossim_uint64 maxSize, ossim_uint64 minSize);
+   ossim_uint64 getCacheSize()const;
+
+   /**
+    * This is a ratio distance from the eye versus to radial bounds of
+    * a patch.  By default this is set to 3.  So this means that once the eye
+    * is within 3 times the radial distance of the patch the patch will split.  So the affect is
+    * increasing this number will cause the land to tesselate faster as the eye approaches.
+    */ 
+   void setSplitMetricRatio(double ratio);
+   double getSplitMetricRatio()const;
+
+   void setSplitPriorityType(ossimPlanetPriorityType priorityType);
+   ossimPlanetPriorityType getSplitPrioirtyType()const;
+
+   void setCullingFlag(bool flag);
+   bool getCullingFlag()const;
+
+   void setFreezeRequestFlag(bool flag);
+   bool getFreezRequestFlag()const;
+
+   bool getMipMappingFlag()const;
+   void setMipMappingFlag(bool flag);
+   
+   void addElevationDirectory(const ossimFilename& file, bool sortFlag=false);
+   void addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag=false);
+   bool shadersInitialized()const;
+   
+   void clearElevation();
+   
+   
+   /**
+    * Will add callbacks to the textures layers and automatically refresh the scene graph as needed if the passed in
+    * flag is true.  If you want to control refreshing then set the flag to false.
+    */ 
+/*    void setAutoRefreshFlag(bool flag); */
+/*    bool getAutoRefreshFlag(bool flag)const; */
+
+   void pagedLodAdded(osg::Node* parent, osg::Node* child);
+   void pagedLodRemoved(osg::Node* node);
+	void pagedLodModified(osg::Node* node);
+
+   /**
+    * Executes receiver command actions:
+    * <pre>
+    *
+    * </pre>
+    */ 
+   virtual void execute(const ossimPlanetAction &a);
+   
+protected:
+   struct refreshInfo : public osg::Referenced
+   {
+      osg::ref_ptr<ossimPlanetExtents> theExtents;
+      ossimPlanetLandRefreshType theRefreshType;
+   };
+   virtual ~ossimPlanetLand();
+	void xmlExecute(const ossimPlanetXmlAction& a);
+   void resetGraphLocal();
+   void initShaders();
+   void initElevation();
+   
+   void add(const ossimPlanetAction& a);
+   void remove(const ossimPlanetAction& a);
+   void resetGraph(const ossimPlanetAction& a);
+   void addImageObject(const ossimString& objectName, const ossimString& objectArg);
+   
+   osg::ref_ptr<ossimPlanetLandReaderWriter>    theReaderWriter;
+   static ossim_uint32                          theLandReaderWriterId;
+   mutable ossimPlanetReentrantMutex                   theMutex;
+   mutable ossimPlanetReentrantMutex                   theRefreshMutex;
+   osg::ref_ptr<ossimPlanetTextureLayerGroup>   theReferenceLayer;
+   osg::ref_ptr<ossimPlanetTextureLayerGroup>   theOverlayLayers;
+   mutable std::vector<osg::ref_ptr<refreshInfo> > theExtentRefreshList;
+   osg::ref_ptr<ossimPlanetShaderProgramSetup>  theCurrentShaderProgram;
+   osg::ref_ptr<osg::Uniform>                   theReferenceTexture;
+   osg::ref_ptr<osg::Uniform>                   theTopTexture;
+   osg::ref_ptr<osg::Program>                   theLandShaderProgram;
+   osg::ref_ptr<osg::Program>                   theNoShaderProgram;
+   osg::ref_ptr<osg::Shader>                    theVertexShader;
+   osg::ref_ptr<osg::Shader>                    theFragShader;
+   std::string                                  theTopSource;
+   std::string                                  theReferenceSource;
+   std::string                                  theOpacitySource;
+   std::string                                  theSwipeSource;
+   std::string                                  theFalseColorReplacementSource;
+   std::string                                  theAbsoluteDifferenceSource;
+   bool                                         theAutoRefreshFlag;
+   osg::ref_ptr<osg::StateSet>                  theStateSet;
+   osg::ref_ptr<osg::GL2Extensions>             theGL2Extensions;
+   osg::ref_ptr<ossimPlanetLandCache>           theLandCache;
+   osg::ref_ptr<ossimPlanetElevationDatabaseGroup> theElevationDatabase;
+   osg::ref_ptr<ossimPlanetLandCullCallback>    theCullCallback;
+   osg::ref_ptr<ossimPlanetTextureLayerCallback> theTextureLayerCallback;   
+   osg::ref_ptr<ossimPlanetTextureLayerCallback> theElevationLayerCallback;   
+   
+   bool theShadersInitializedFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandCache.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandCache.h
new file mode 100644
index 0000000..7cab3bd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandCache.h
@@ -0,0 +1,114 @@
+#ifndef ossimPlanetLandCache_HEADER
+#define ossimPlanetLandCache_HEADER
+
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetExtents.h>
+#include <osg/Referenced>
+#include <osg/Geometry>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class ossimPlanetLandCache;
+class OSSIMPLANET_DLL ossimPlanetLandCacheNode : public osg::Referenced
+{
+public:
+   friend class ossimPlanetLandCache;
+   ossimPlanetLandCacheNode(ossimPlanetLandCache* landCache=0,
+                            ossim_uint64 id=0)
+      :theTimeStamp(osg::Timer::instance()->tick()),
+      theLandCache(landCache),
+      theId(id)
+   {
+      estimateSize();
+   }
+   ossim_uint64 getId()const
+   {
+      return theId;
+   }
+   void access();
+   
+   void setExtents(osg::ref_ptr<ossimPlanetExtents> extents);   
+   void setTexture(ossim_uint32 idx, osg::ref_ptr<ossimPlanetImage> texture);
+   void setElevation(osg::ref_ptr<ossimPlanetImage> elevation);
+
+   void setLandCache(ossimPlanetLandCache* landCache);
+   const ossimPlanetExtents* getExtents()const
+   {
+      return theExtents.get();
+   }
+   
+   void clearTextures();
+   ossimPlanetImage* getTexture(ossim_uint32 idx)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      if(idx < theTextureList.size())
+      {
+         return theTextureList[idx].get();
+      }
+
+      return 0;
+   }
+   ossimPlanetImage* getElevation()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+      return theElevation.get();
+   }
+   ossim_uint32 getTextureListSize()const
+   {
+      return theTextureList.size();
+   }
+   ossim_uint64 getNodeSizeInBytes()const;
+   osg::Timer_t timeStamp()const
+   {
+      return theTimeStamp;
+   }
+protected:
+   void protectedAccess();
+   void estimateSize();
+   /**
+    * Handles auto communicating the changed size to the cache that owns this node.
+    */ 
+   void adjustSize();
+   mutable osg::Timer_t                          theTimeStamp;
+   ossimPlanetReentrantMutex                            theMutex;
+   ossimPlanetLandCache*                         theLandCache;
+   ossim_uint64                                  theId;
+   ossim_uint32                                  theNodeSizeInBytes;
+   osg::ref_ptr<ossimPlanetExtents>              theExtents;
+   std::vector<osg::ref_ptr<ossimPlanetImage> >  theTextureList;
+   osg::ref_ptr<ossimPlanetImage>                theElevation;
+};
+
+class ossimPlanetLandCache : public osg::Referenced
+{
+public:
+   friend class ossimPlanetLandCacheNode;
+   typedef std::map<ossim_uint64, osg::ref_ptr<ossimPlanetLandCacheNode> > ossimPlanetLandCacheType;
+   ossimPlanetLandCache(ossim_uint64 maxCacheSize=0, ossim_uint64 minCacheSize=0);
+
+   bool addNode(ossimPlanetLandCacheNode* node);
+   ossimPlanetLandCacheNode* getNode(ossim_uint64 id, bool allocateNewNodeIfNotPresent=true);
+   osg::ref_ptr<ossimPlanetLandCacheNode> removeNode(ossim_uint64 id);
+   void setCacheSize(ossim_uint64 maxCacheSize, ossim_uint64 minCacheSize);
+   ossim_uint64 getCacheSize()const;
+   
+   void shrinkCache();
+   void clearCache();
+
+   void clearTexturesWithinExtents(osg::ref_ptr<ossimPlanetExtents> extents);
+   void clearAllWithinExtents(osg::ref_ptr<ossimPlanetExtents> extents);
+   
+protected:
+   /**
+    * Will check to see if the cache exceeds max and if so shrinks until doesn't exceed min.
+    */ 
+   void protectedShrinkCache();
+   
+   ossimPlanetReentrantMutex       theMutex; 
+   ossim_uint64             theMaxCacheSize;
+   ossim_uint64             theMinCacheSize; // used in shrinking the cache if exceeds the max
+   ossim_uint64             theCurrentCacheSize;
+   ossimPlanetLandCacheType theCacheMap;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandCullCallback.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandCullCallback.h
new file mode 100644
index 0000000..63de2ae
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandCullCallback.h
@@ -0,0 +1,55 @@
+#ifndef ossimPlanetLandCullCallback_HEADER
+#define ossimPlanetLandCullCallback_HEADER
+#include <osg/Node>
+#include <osg/Vec3d>
+#include <osg/NodeCallback>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+class ossimPlanetPagedLandLod;
+
+class OSSIMPLANET_DLL ossimPlanetLandCullCallback :  public osg::NodeCallback
+{
+public:
+   ossimPlanetLandCullCallback();
+   ossimPlanetLandCullCallback(const ossimPlanetLandCullCallback& src)
+      :osg::NodeCallback(src),
+      theFreezeRequestFlag(src.theFreezeRequestFlag),
+      theCullingFlag(src.theCullingFlag),
+      theSplitMetric(src.theSplitMetric),
+      theSplitPriorityType(src.theSplitPriorityType),
+      theLineOfSiteValidFlag(src.theLineOfSiteValidFlag),
+      theLineOfSite(src.theLineOfSite)
+   {
+   }
+   ossimPlanetLandCullCallback* clone()const
+   {
+      return new ossimPlanetLandCullCallback(*this);
+   }
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+   void setLineOfSite(const osg::Vec3d& lineOfSite);
+   void setLineOfSiteValidFlag(bool flag);
+   bool isLineOfSiteValid()const;
+
+   void setSplitMetricRatio(double ratio);
+   double getSplitMetricRatio()const;
+
+   void setSplitPriorityType(ossimPlanetPriorityType priorityType);
+   ossimPlanetPriorityType getSplitPriorityType()const;
+
+   void setCullingFlag(bool flag);
+   bool getCullingFlag()const;
+
+   void setFreezeRequestFlag(bool flag);
+   bool getFreezRequestFlag()const;
+protected:
+   void applyStandardCull(ossimPlanetPagedLandLod* n, osg::NodeVisitor* nv);
+ //  void applyOrthoCull(ossimPlanetPagedLandLod* n, osg::NodeVisitor* nv);
+
+   bool                    theFreezeRequestFlag;
+   bool                    theCullingFlag;
+   double                  theSplitMetric;
+   ossimPlanetPriorityType theSplitPriorityType;
+   bool                    theLineOfSiteValidFlag;
+   osg::Vec3d              theLineOfSite;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandNode.h
new file mode 100644
index 0000000..8c2530e
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandNode.h
@@ -0,0 +1,115 @@
+#ifndef ossimPlanetLandNode_HEADER
+#define ossimPlanetLandNode_HEADER
+#include <osg/PagedLOD>
+#include <osg/Texture2D>
+#include <osg/CoordinateSystemNode>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetLandGridNode.h>
+#include <ossimPlanet/ossimPlanetPagedRequestNode.h>
+#include <osg/Array>
+#include <osg/ref_ptr>
+#include <osg/Geometry>
+#include <osg/Texture2D>
+#include <ossim/base/ossimConstants.h>
+#include "ossimPlanetExport.h"
+#include "ossimPlanetLandSettings.h"
+#include "ossimPlanetBoundingBox.h"
+#include <ossimPlanet/ossimPlanetExport.h>
+
+namespace osgUtil
+{
+   class CullVisitor;
+}
+class OSSIMPLANET_DLL ossimPlanetLandNode : public osg::Group
+{
+public:
+   friend class ossimPlanetLand;
+   friend class ossimPlanetLandNodeDrawableCallback;
+   ossimPlanetLandNode(ossim_uint32 level = 0,
+                     ossim_uint32 row   = 0,
+                     ossim_uint32 col   = 0);
+   ossimPlanetLandNode(const ossimPlanetLandNode& plod,const osg::CopyOp& copyop);
+   virtual ~ossimPlanetLandNode();
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanetLandNode *>(obj)!=NULL; }
+   virtual const char* className() const { return "PlanetLandNode"; } 
+   virtual const char* libraryName() const { return ""; }
+
+   void setLandSettings(const osg::ref_ptr<ossimPlanetLandSettings>& settings);
+   void setTextureRequest(osg::ref_ptr<ossimPlanetPagedRequestNode> texture);
+   osg::ref_ptr<osg::Texture2D> getTexture();
+
+   ossim_uint32 getLevel()const;
+   ossim_uint32 getRow()const;
+   ossim_uint32 getCol()const;
+   bool getRemoveAllChildrenFlag()const
+   {
+      return theRemoveAllChildrenFlag;
+   }
+   void setRemoveAllChildrenFlag(bool flag)
+   {
+      theRemoveAllChildrenFlag = flag;
+   }
+   void createPatchGeometry();
+   void setPatchLocation(ossim_uint32 level,
+                         ossim_uint32 row,
+                         ossim_uint32 col,
+                         bool createPatchGeometryFlag=true);
+  
+   virtual bool isLeaf()const;
+   virtual bool areAllChildrenLeaves()const;
+   virtual bool isCulled()const;
+   virtual bool areAllChildrenCulled()const;
+protected:
+   friend class ossimPlanetLandNodeUpdateCallback;
+   unsigned int theLevel;
+   unsigned int theRow;
+   unsigned int theCol;
+   osg::ref_ptr<ossimPlanetPagedRequestNode> theTextureRequest;
+   
+   bool                                    theTextureChangedFlag;
+   bool                                    theElevationChangedFlag;
+   osg::ref_ptr<ossimPlanetLandSettings>     theLandSettings;
+   
+   mutable ossimPlanetReentrantMutex theMutex;
+   mutable osg::ref_ptr<osg::Geometry> theGeometry;
+
+   mutable bool theAddAllChildrenFlag;
+   mutable bool theRemoveAllChildrenFlag;
+   mutable bool theCulledFlag;
+   mutable bool thePreviousCulledFlag;
+   osg::Vec3d theCenterNormal;
+   osg::Vec3d theUlNormal;
+   osg::Vec3d theUrNormal;
+   osg::Vec3d theLrNormal;
+   osg::Vec3d theLlNormal;
+
+   osg::Vec3d theCenterPoint;
+   osg::Vec3d theUlPoint;
+   osg::Vec3d theUrPoint;
+   osg::Vec3d theLrPoint;
+   osg::Vec3d theLlPoint;
+   osg::ref_ptr<ossimPlanetBoundingBox> theBoundingBox;
+   osg::ref_ptr<ossimPlanetElevationGrid> theElevation;
+   
+   virtual void createPoints(osg::Vec3Array *verts,
+                             osg::Vec3Array *norms,
+                             osg::Vec2Array *tcoords)=0;
+   virtual void handleUpdateTraversal(osg::NodeVisitor& nv);
+   virtual void handleCullTraversal(osg::NodeVisitor& nv);
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual void setupBoundaryNormals()=0;
+   virtual void applyElevation()=0;
+   virtual void adjustTexCoordinates();
+
+//   void computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const;
+//   osg::Vec3d computeLocalPosition(const osg::Matrixd& worldToLocal, double X, double Y, double Z)const;
+
+   virtual bool addChild(Node *child);
+   virtual std::string createDbName()const;
+   virtual std::string createLevel0DbName()const;
+   const osg::ref_ptr<osg::Geometry> getParentGeometry()const;
+   osg::ref_ptr<osg::Geometry> getParentGeometry();
+   ossim_uint32 distanceToLeaf()const;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandNormalType.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandNormalType.h
new file mode 100644
index 0000000..5d06752
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandNormalType.h
@@ -0,0 +1,10 @@
+#ifndef ossimPlanetLandNormalType_HEADER
+#define ossimPlanetLandNormalType_HEADER
+
+enum ossimPlanetLandNormalType
+{
+   ossimPlanetLandNormalType_ELLIPSOIDAL = 0,
+   ossimPlanetLandNormalType_FLAT        = 0
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandReaderWriter.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandReaderWriter.h
new file mode 100644
index 0000000..f73e10d
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandReaderWriter.h
@@ -0,0 +1,202 @@
+#ifndef ossimPlanetLandReaderWriter_HEADER
+#define ossimPlanetLandReaderWriter_HEADER
+#include <string>
+#include <ossim/base/ossimKeywordlist.h>
+#include <osgDB/ReaderWriter>
+#include <osg/MatrixTransform>
+#include <osg/Geometry>
+#include <osg/Texture2D>
+#include "ossimPlanetGridUtility.h"
+#include <ossim/base/ossimString.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetLandNormalType.h>
+/* #include <ossimPlanet/ossimPlanetElevationGrid.h> */
+#include <ossimPlanet/ossimPlanetBoundingBox.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetLandCache.h>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossimPlanet/ossimPlanetShaderProgramSetup.h>
+#include <ossimPlanet/ossimPlanetElevationDatabaseGroup.h>
+#include <ossimPlanet/ossimPlanetLandCullCallback.h>
+class ossimPlanetLand;
+class ossimPlanetPagedLandLod;
+class ossimPlanetPagedLandLodCullCallback;
+class ossimPlanetTexture2D;
+class ossimPlanetLandReaderWriter : public osgDB::ReaderWriter
+{
+public:
+   typedef std::map<std::string, char> requestStringMapType;
+   ossimPlanetLandReaderWriter();
+   
+   virtual const char* className()const;
+   virtual ReadResult readNode(const std::string& fileName, const Options*)const;
+
+   ossim_uint32 getId()const
+   {
+      return theId;
+   }
+   
+   std::string createDbString(ossim_uint32 level,
+                              ossim_uint64 row,
+                              ossim_uint64 col)const;
+
+   void setModel(ossimPlanetGeoRefModel* geoModel);
+   const ossimPlanetGeoRefModel* model()const{return theModel.get();};
+   ossimPlanetGeoRefModel* model(){return theModel.get();};
+   void setLandNodeCullCallback(ossimPlanetLandCullCallback* callback);
+   bool getElevationEnabledFlag()const;
+   void setElevationEnabledFlag(bool elevationFlag);
+
+   ossim_float64 getHeightExag()const;
+   void setHeightExag(ossim_float64 exag);
+
+   ossim_uint32 getElevationPatchSize()const;
+   void setElevationPatchSize(ossim_uint32 densityLevel);
+
+   ossim_uint32 getMaxLevelDetail()const;
+   void setMaxLevelDetail(ossim_uint32 maxLevelDetail);
+
+   ossimFilename getElevationCacheDir()const;
+   void setElevationCacheDir(const ossimFilename& cacheDir);
+
+   const ossimPlanetGridUtility* gridUtility()const;
+   void setGridUtility(ossimPlanetGridUtility* utility);
+   
+//   void setMultiTextureLayers(osg::ref_ptr<ossimPlanetTextureLayerGroup> textureLayers);
+   void setReferenceLayer(osg::ref_ptr<ossimPlanetTextureLayerGroup> reference);
+   void setOverlayLayers(osg::ref_ptr<ossimPlanetTextureLayerGroup> overlays);
+   void setMipMappingFlag(bool flag);
+   bool getMipMappingFlag()const;
+
+   void setMultiTextureEnableFlag(bool flag);
+   bool getMultiTextureEnableFlag()const;
+
+   void setLandCache(osg::ref_ptr<ossimPlanetLandCache> landCache);
+
+   void setElevationDatabase(osg::ref_ptr<ossimPlanetElevationDatabaseGroup> databaseGroup);
+   osg::ref_ptr<ossimPlanetElevationDatabaseGroup> getElevationGroup();
+   const osg::ref_ptr<ossimPlanetElevationDatabaseGroup> getElevationGroup()const;
+   
+protected:
+   enum ossimPlanetLandReaderWriterGeomType
+   {
+      ossimPlanetLandReaderWriterGeomType_NONE    = 0,
+      ossimPlanetLandReaderWriterGeomType_TEXTURE = 1,
+      ossimPlanetLandReaderWriterGeomType_GEOM    = 2,
+      ossimPlanetLandReaderWriterGeomType_LOD     = 4
+   };
+   mutable ossimPlanetReentrantMutex theMutex;
+   ossim_uint32 theId;
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+   ossimPlanetLandType theLandType;
+   ossim_uint32 theMaxLevelDetail;
+   double theHeightExag;
+/*    ossim_uint32 theElevationDensityLevel; */
+   ossim_uint32 theElevationPatchSize;
+   bool theElevationEnabledFlag;
+   ossimFilename theElevationCacheDir;
+   bool          theMipMappingFlag;
+   osg::ref_ptr<ossimPlanetGridUtility>  theGrid;
+   osg::ref_ptr<ossimPlanetGridUtility>  theElevationGrid;
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> theReferenceLayer;
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> theOverlayLayers;
+/*    osg::ref_ptr<ossimPlanetTextureLayer> theTextureLayer; */
+   osg::ref_ptr<ossimPlanetElevationDatabaseGroup> theElevationDatabase;
+   bool                                        theMultiTextureEnableFlag;
+   osg::ref_ptr<ossimPlanetLandCache> theLandCache;
+   osg::ref_ptr<ossimPlanetLandCullCallback> theCullNodeCallback;
+   mutable osg::ref_ptr<osg::Texture2D> theBlankTexture;
+   /*    virtual osgDB::ReaderWriter::ReadResult local_readNode(const std::string& filename, */
+/*                                                           const Options* options)const; */
+   
+   virtual bool extractValues(const std::string& filename,
+                              ossim_uint32 &level,
+                              ossim_uint32 &row,
+                              ossim_uint32 &col,
+                              ossim_uint32 &id,
+                              ossimPlanetLandReaderWriterGeomType &geomType)const;
+   
+   void newTexture(std::vector<osg::ref_ptr<osg::Texture2D> >& textures,
+                   ossim_uint32 level,
+                   ossim_uint32 row,
+                   ossim_uint32 col,
+                   ossimPlanetImage::ossimPlanetImageStateType& textureState)const;
+   
+   osg::ref_ptr<osg::MatrixTransform> newGeometry(ossim_uint32 level,
+                                                  ossim_uint32 row,
+                                                  ossim_uint32 col,
+                                                  std::vector<osg::ref_ptr<osg::Texture2D> >& textures,
+                                                  osg::ref_ptr<ossimPlanetImage> elevationGrid,
+/*                                                   osg::ref_ptr<ossimPlanetElevationGrid> elevationGrid, */
+                                                  ossimPlanetBoundingBox& box,
+                                                  bool& useClusterCullingCallback,
+                                                  osg::Vec3d& clusterControlPoint,
+                                                  osg::Vec3d& clusterCenterNormal,
+                                                  double& minDotProduct,
+                                                  double& maxClusterCullingRadius)const;
+   virtual void createPoints(ossim_uint32 level,
+                             ossim_uint32 row,
+                             ossim_uint32 col,
+                             osg::ref_ptr<ossimPlanetImage> elevationGrid,
+/*                              osg::ref_ptr<ossimPlanetElevationGrid> elevationGrid, */
+                             osg::Vec3Array *verts,
+                             osg::Vec3Array *norms,
+                             osg::Vec2Array *tcoords,
+                             osg::Matrixd& localToWorld,
+                             ossimPlanetBoundingBox& box,
+                             bool& useClusterCullingCallback,
+                             osg::Vec3d& clusterControlPoint,
+                             osg::Vec3d& clusterCenterNormal,
+                             double& minDotProduct,
+                             double& maxClusterCullingRadius)const;
+
+  
+   void initSupportAttributes(ossim_uint32 level,
+                              ossim_uint32 row,
+                              ossim_uint32 col,
+                              osg::Vec3d& centerPoint,
+                              osg::Vec3d& ulPoint,
+                              osg::Vec3d& urPoint,
+                              osg::Vec3d& lrPoint,
+                              osg::Vec3d& llPoint,
+                              osg::Vec3d& centerNormal,
+                              osg::Vec3d& ulNormal,
+                              osg::Vec3d& urNormal,
+                              osg::Vec3d& lrNormal,
+                              osg::Vec3d& llNormal,
+                              ossimPlanetBoundingBox& box,
+                              std::vector<ossimPlanetBoundingBox>& childrenBounds,
+                              const osg::MatrixTransform& transform)const;
+   void createBounds(ossim_uint32 level,
+                     ossim_uint32 row,
+                     ossim_uint32 col,
+                     ossimPlanetBoundingBox& bounds,
+                     const osg::MatrixTransform& transform)const;
+   osg::Vec3d normal(double x, double y, double z)const;
+   
+/*    osg::ref_ptr<ossimPlanetElevationGrid> newElevation(ossim_uint32 level, */
+/*                                                      ossim_uint32 row, */
+/*                                                      ossim_uint32 col)const; */
+/*    osg::ref_ptr<ossimPlanetElevationGrid> getCachedElevation(ossim_uint32 level, */
+/*                                                            ossim_uint32 row, */
+/*                                                            ossim_uint32 col)const; */
+   osg::ref_ptr<ossimPlanetImage> newElevation(ossim_uint32 level,
+                                               ossim_uint32 row,
+                                               ossim_uint32 col)const;
+   osg::ref_ptr<ossimPlanetImage> getCachedElevation(ossim_uint32 level,
+                                                     ossim_uint32 row,
+                                                     ossim_uint32 col)const;
+/*    void writeElevationToCache(ossim_uint32 level, */
+/*                               ossim_uint32 row, */
+/*                               ossim_uint32 col, */
+/*                               osg::ref_ptr<ossimPlanetElevationGrid> elevation)const; */
+   void writeElevationToCache(ossim_uint32 level,
+                              ossim_uint32 row,
+                              ossim_uint32 col,
+                              osg::ref_ptr<ossimPlanetImage> elevation)const;
+   
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandTextureRequest.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandTextureRequest.h
new file mode 100644
index 0000000..7671766
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandTextureRequest.h
@@ -0,0 +1,226 @@
+#ifndef ossimPlanetLandTextureRequest_HEADER
+#define ossimPlanetLandTextureRequest_HEADER
+#include <vector>
+#include <osg/Node>
+#include <osg/ref_ptr>
+#include <osg/Texture2D>
+#include <osg/NodeCallback>
+#include <osg/MatrixTransform>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetBoundingBox.h>
+#include <iostream>
+#include <ossimPlanet/ossimPlanetTexture2D.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+
+class ossimPlanetLandTextureRequest : public osg::Node
+{
+public:
+   ossimPlanetLandTextureRequest(ossim_uint32 level=0,
+                                 ossim_uint32 row=0,
+                                 ossim_uint32 col=0,
+                                 const std::vector<osg::ref_ptr<osg::Texture2D> >& textures=std::vector<osg::ref_ptr<osg::Texture2D> >())
+      :osg::Node(),
+      theLevel(level),
+      theRow(row),
+      theCol(col),
+      theTextures(textures)/* , */
+/*       theClusterParametersSet(false) */
+      {
+      }
+   virtual ~ossimPlanetLandTextureRequest()
+      {
+      }
+   void setTextures(const std::vector<osg::ref_ptr<osg::Texture2D> >& textures)
+      {
+         theTextures = textures;
+      }
+   void setTransform(osg::ref_ptr<osg::Node> transform)
+      {
+         theTransform = transform;
+      }
+   void setCullCallback(osg::ref_ptr<osg::NodeCallback> callback)
+   {
+      theCullCallback = callback;
+   }
+   osg::ref_ptr<osg::Node> getTransform()
+   {
+      return theTransform;
+   }
+   std::vector<osg::ref_ptr<osg::Texture2D> >& getTextures()
+   {
+      return theTextures;
+   }
+   osg::ref_ptr<osg::NodeCallback> getCullCallback()
+   {
+      return theCullCallback;
+   }
+   ossim_uint32 getLevel()const
+      {
+         return theLevel;
+      }
+   ossim_uint32 getRow()const
+      {
+         return theRow;
+      }
+   ossim_uint32 getCol()const
+      {
+         return theCol;
+      }
+
+   void setCenterPoint(osg::Vec3d& centerPoint)
+   {
+      theCenterPoint = centerPoint;
+   }
+   void setUlPoint(osg::Vec3d& ulPoint)
+   {
+      theUlPoint = ulPoint;
+   }
+   void setUrPoint(osg::Vec3d& urPoint)
+   {
+      theUrPoint = urPoint;
+   }
+   void setLrPoint(osg::Vec3d& lrPoint)
+   {
+      theLrPoint = lrPoint;
+   }
+   void setLlPoint(osg::Vec3d& llPoint)
+   {
+      theLlPoint = llPoint;
+   }
+   void setCenterNormal(osg::Vec3d& centerNormal)
+   {
+      theCenterNormal = centerNormal;
+   }
+   void setUlNormal(osg::Vec3d& ulNormal)
+   {
+      theUlNormal = ulNormal;
+   }
+   void setUrNormal(osg::Vec3d& urNormal)
+   {
+      theUrNormal = urNormal;
+   }
+   void setLrNormal(osg::Vec3d& lrNormal)
+   {
+      theLrNormal = lrNormal;
+   }
+   void setLlNormal(osg::Vec3d& llNormal)
+   {
+      theLlNormal = llNormal;
+   }
+   osg::Vec3d centerPoint()const
+   {
+      return theCenterPoint;
+   }
+   osg::Vec3d ulPoint()const
+   {
+      return theUlPoint;
+   }
+   osg::Vec3d urPoint()const
+   {
+      return theUrPoint;
+   }
+   osg::Vec3d lrPoint()const
+   {
+      return theLrPoint;
+   }
+   osg::Vec3d llPoint()const
+   {
+      return theLlPoint;
+   }
+   osg::Vec3d centerNormal()const
+   {
+      return theCenterNormal;
+   }
+   osg::Vec3d ulNormal()const
+   {
+      return theUlPoint;
+   }
+   osg::Vec3d urNormal()const
+   {
+      return theUrNormal;
+   }
+   osg::Vec3d lrNormal()const
+   {
+      return theLrNormal;
+   }
+   osg::Vec3d llNormal()const
+   {
+      return theLlNormal;
+   }
+
+   void setBoundingBox(osg::ref_ptr<ossimPlanetBoundingBox> bounds)
+   {
+      theBoundingBox = bounds;
+   }
+   osg::ref_ptr<ossimPlanetBoundingBox> boundingBox()
+   {
+      return theBoundingBox;
+   }
+   const osg::ref_ptr<ossimPlanetBoundingBox> boundingBox()const
+   {
+      return theBoundingBox;
+   }
+   void setChildrenBounds(const std::vector<ossimPlanetBoundingBox>& childrenBounds)
+   {
+      theChildrenBounds = childrenBounds;
+   }
+   const std::vector<ossimPlanetBoundingBox>& childrenBounds()const
+   {
+      return theChildrenBounds;
+   }
+   ossimPlanetImage::ossimPlanetImageStateType getTextureState()const
+   {
+      return theTextureState;
+   }
+   void setTextureState(ossimPlanetImage::ossimPlanetImageStateType state)
+   {
+      theTextureState = state;
+   }
+
+/*    void setClusterCullValues(bool useClusterCulling, */
+/*                              const osg::Vec3& controlPoint, */
+/*                              const osg::Vec3& normal, */
+/*                              double deviation, */
+/*                              double radius) */
+/*    { */
+/*       theClusterParametersSet = true; */
+/*       theUseClusterCulling    = useClusterCulling; */
+/*       theClusterCullingControlPoint = controlPoint; */
+/*       theClusterCullingNormal = normal; */
+/*       theClusterCullingDeviation = deviation; */
+/*       theClusterCullingRadius = radius; */
+/*    } */
+   
+protected:
+   ossim_uint32 theLevel;
+   ossim_uint32 theRow;
+   ossim_uint32 theCol;
+   std::vector<osg::ref_ptr<osg::Texture2D> > theTextures;
+   osg::ref_ptr<osg::Node> theTransform;
+   osg::ref_ptr<osg::NodeCallback> theCullCallback;
+   
+   osg::Vec3d theCenterPoint;
+   osg::Vec3d theUlPoint;
+   osg::Vec3d theUrPoint;
+   osg::Vec3d theLrPoint;
+   osg::Vec3d theLlPoint;
+   osg::Vec3d theCenterNormal;
+   osg::Vec3d theUlNormal;
+   osg::Vec3d theUrNormal;
+   osg::Vec3d theLrNormal;
+   osg::Vec3d theLlNormal;
+   osg::ref_ptr<ossimPlanetBoundingBox> theBoundingBox;
+   std::vector<ossimPlanetBoundingBox>  theChildrenBounds;
+   ossimPlanetImage::ossimPlanetImageStateType theTextureState;
+
+
+/*    bool theClusterParametersSet; */
+/*    bool theUseClusterCulling; */
+/*    osg::Vec3d theClusterCullingControlPoint; */
+/*    osg::Vec3d theClusterCullingNormal; */
+/*    double theClusterCullingDeviation; */
+/*    double theClusterCullingRadius; */
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLandTreeNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLandTreeNode.h
new file mode 100644
index 0000000..58cb53b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLandTreeNode.h
@@ -0,0 +1,26 @@
+#ifndef ossimPlanetLandTreeNode_HEADER
+#define ossimPlanetLandTreeNode_HEADER
+#include <osg/Node>
+
+class ossimPlanetLandTreeNode : public osg::Node
+{
+public:
+   ossimPlanetLandTreeNode(ossim_uint32 level,
+                           ossim_uint64 row,
+                           ossim_uint64 col);
+
+protected:
+   ossim_uint32 theLevel;
+   ossim_uint32 theRow;
+   ossim_uint32 theCol;
+   ossimPlanetLandTreeNode* theParent;
+   ossimPlanetLandTreeNode* theRightNeighbor;
+   ossimPlanetLandTreeNode* theLeftNeighbor;
+   ossimPlanetLandTreeNode* theTopNeighbor;
+   ossimPlanetLandTreeNode* theBottomNeighbor;
+   ossimRefPtr<ossimPlanetLandTreeNode> theChildren[4];
+   
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLatLonHud.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLatLonHud.h
new file mode 100644
index 0000000..1fc17d1
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLatLonHud.h
@@ -0,0 +1,86 @@
+#ifndef ossimPlanetLatLonHud_HEADER
+#define ossimPlanetLatLonHud_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <osgText/Text>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/LineWidth>
+#include <osg/Projection>
+#include <osg/CameraNode>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetCompass.h>
+class ossimPlanet;
+namespace osg
+{
+   class LineWidth;
+}
+class OSSIMPLANET_EXPORT ossimPlanetLatLonHud : public ossimPlanetLayer
+{
+public:
+   ossimPlanetLatLonHud();
+   virtual void traverse(osg::NodeVisitor& nv);
+   osg::Vec4 getCrossHairColor()const;
+   osg::Vec4 getTextColor()const;
+   void setCrosshairColor(const osg::Vec4& color);
+   void setTextColor(const osg::Vec4& color);
+   void setFont(const ossimString& fontFile);
+   void setLatDisplayString(const ossimString& latDisplayString);
+   void setLonDisplayString(const ossimString& lonDisplayString);
+   void setCharacterSize(float size);
+   void setViewport(osg::ref_ptr<osg::Viewport> viewport);
+   void setAutoUpdateFlag(bool flag);
+   void setCompassTexture(const ossimFilename& compass);
+//   void setCompassTexture(const ossimFilename& ring,
+//                          const ossimFilename& interior);
+  
+   virtual void execute(const ossimPlanetAction& action);
+   
+protected:
+   void initialize();
+   void updatePosition();
+   osg::ref_ptr<osg::CameraNode> theCameraNode;
+/*    osg::ref_ptr<osg::Projection> theProjection; */
+   osg::ref_ptr<osgText::Text> thePositionText;
+   
+   osg::ref_ptr<osgText::Text> theLookText;
+   osg::ref_ptr<osgText::Text> theEyeText;
+   osg::ref_ptr<osgText::Text> theRangeText;
+   
+   osg::ref_ptr<osg::Geode> theGeode;
+   osg::ref_ptr<osg::Viewport> theViewport;
+   osg::ref_ptr<osg::Geometry> theCrosshair;
+   osg::Vec3d theLineOfSiteLatLon;
+   osg::Vec3d theNadirLatLon;
+   double     theRange;
+   double     theAltitude;
+   osg::Vec4 theTextColor;
+   osg::Vec4 theShadowTextColor;
+   osg::Vec4 theCrosshairColor;
+   osg::ref_ptr<osg::LineWidth> theCrosshairLineWidth;
+   bool theAutoUpdateFlag;
+   mutable bool theFontChanged;
+   float theCharacterSize;
+   bool theCharacterSizeDirtyFlag;
+   ossimString theFontName;
+   osg::ref_ptr<osgText::Font> theFont;
+
+   
+   ossimString theLookLabel;
+   ossimString theEyeLabel;
+   ossimString theRangeLabel;
+   ossimString theLookDisplayString;
+   ossimString theEyeDisplayString;
+   
+   ossimString theLatDisplayString;
+   ossimString theLonDisplayString;
+   
+   
+   bool theInitializedFlag;
+   mutable OpenThreads::ReentrantMutex theMutex;
+   bool theViewportChangedFlag;
+   osg::ref_ptr<ossimPlanetCompass> theCompass;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLayer.h
new file mode 100644
index 0000000..bfa119a
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLayer.h
@@ -0,0 +1,58 @@
+#ifndef ossimPlanetLayer_HEADER
+#define ossimPlanetLayer_HEADER
+#include <osg/Group>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+
+class ossimPlanet;
+
+class OSSIMPLANET_DLL ossimPlanetLayer :public ossimPlanetNode
+{
+public:
+   friend class ossimPlanetLayerUpdateCallback;
+   
+   ossimPlanetLayer();
+   virtual ~ossimPlanetLayer();   
+   
+   virtual void execute(const ossimPlanetAction& action);
+   
+   virtual void setModel(ossimPlanetGeoRefModel* model)
+   {
+      theModel = model;
+   }
+   const ossimPlanetGeoRefModel* model()const
+   {
+      return theModel.get();
+   }
+   ossimPlanetGeoRefModel* model()
+   {
+      return theModel.get();
+   }
+   virtual void setPlanet(ossimPlanet* planet)
+   {
+      thePlanet = planet;
+   }
+   ossimPlanet* planet()
+   {
+      return thePlanet;
+   }
+   const ossimPlanet* planet()const
+   {
+      return thePlanet;
+   }
+	virtual void needsRemoving(osg::Node* /*node*/){}
+   static ossimPlanetLayer* findLayer(osg::Node* startNode);
+   static ossimPlanetLayer* findLayer(osg::NodePath& currentNodePath);
+   
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+protected:
+   ossimPlanet* thePlanet;   
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactory.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactory.h
new file mode 100644
index 0000000..131f139
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactory.h
@@ -0,0 +1,21 @@
+#ifndef ossimPlanetLayerFactory_HEADER
+#define ossimPlanetLayerFactory_HEADER
+#include "ossimPlanetLayerFactoryBase.h"
+#include <osg/ref_ptr>
+
+class ossimPlanetLayerFactory : public ossimPlanetLayerFactoryBase
+{
+public:
+   ossimPlanetLayerFactory();
+   virtual ~ossimPlanetLayerFactory();
+   
+   static ossimPlanetLayerFactory* instance();
+   
+   virtual ossimPlanetLayer* create(const ossimString& type)const;
+protected:
+   static ossimPlanetLayerFactory* theInstance;
+   
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactoryBase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactoryBase.h
new file mode 100644
index 0000000..5a0b521
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerFactoryBase.h
@@ -0,0 +1,15 @@
+#ifndef ossimPlanetLayerFactoryBase_HEADER
+#define ossimPlanetLayerFactoryBase_HEADER
+#include <osg/Referenced>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+class ossimPlanetLayer;
+class OSSIMPLANET_DLL ossimPlanetLayerFactoryBase : public osg::Referenced
+{
+public:
+   ossimPlanetLayerFactoryBase(){}
+   
+   virtual ossimPlanetLayer* create(const ossimString& type)const=0;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLayerRegistry.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerRegistry.h
new file mode 100644
index 0000000..fa04363
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLayerRegistry.h
@@ -0,0 +1,39 @@
+#ifndef ossimPlanetLayerRegistry_HEADER
+#define ossimPlanetLayerRegistry_HEADER
+#include "ossimPlanetExport.h"
+#include <OpenThreads/ReadWriteMutex>
+#include <OpenThreads/ScopedLock>
+#include <vector>
+#include <ossim/base/ossimString.h>
+#include "ossimPlanetLayerFactoryBase.h"
+#include <osg/ref_ptr>
+
+class ossimPlanetLayer;
+class ossimPlanetLayerRegistry
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetLayerFactoryBase> > FactoryListType;
+   
+   ossimPlanetLayerRegistry();
+   ~ossimPlanetLayerRegistry();
+   static ossimPlanetLayerRegistry* instance();
+   void finalize();
+	
+   /**
+	 * @param type is the type name of the layer to create
+    */
+   ossimPlanetLayer* create(const ossimString& type)const;
+   
+   void registerFactory(ossimPlanetLayerFactoryBase* factory,
+								bool insertFrontFlag=false);
+   void unregisterFactory(const ossimPlanetLayerFactoryBase* factory);
+   
+protected:
+   bool hasFactory(const ossimPlanetLayerFactoryBase* factory)const;
+   
+   mutable OpenThreads::ReadWriteMutex       theFactoryListMutex;
+   static ossimPlanetLayerRegistry* theInstance;
+   FactoryListType                  theFactoryList;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLookAt.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLookAt.h
new file mode 100644
index 0000000..765b4cd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLookAt.h
@@ -0,0 +1,230 @@
+#ifndef ossimPlanetLookAt_HEADER
+#define ossimPlanetLookAt_HEADER
+#include <osg/Referenced>
+#include <ossim/base/ossimString.h>
+#include <sstream>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <iostream>
+#include <iomanip>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/base/ossimXmlNode.h>
+
+class OSSIMPLANET_DLL ossimPlanetLookAt : public osg::Referenced
+{
+public:
+   ossimPlanetLookAt()
+      :osg::Referenced(),
+      theLat(0.0),
+      theLon(0.0),
+      theAltitude(0.0),
+      theHeading(0.0),
+      thePitch(0.0),
+      theRoll(0.0),
+      theRange(0.0),
+      theMode(ossimPlanetAltitudeMode_CLAMP_TO_GROUND)
+   {
+   }
+   ossimPlanetLookAt(const ossimPlanetLookAt& src)
+      :osg::Referenced(),
+      theLat(src.theLat),
+      theLon(src.theLon),
+      theAltitude(src.theAltitude),
+      theHeading(src.theHeading),
+      thePitch(src.thePitch),
+      theRoll(src.theRoll),
+      theRange(src.theRange),
+      theMode(src.theMode)
+   {
+   }
+	ossimPlanetLookAt(double lat, double lon, double altitude,
+							double heading, double pitch, double roll,
+							double range, ossimPlanetAltitudeMode mode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND)
+	{
+		setAll(lat, lon, altitude, heading, pitch, roll, range, mode);
+	}
+   virtual ossimPlanetLookAt* clone()const
+   {
+      return new ossimPlanetLookAt(*this);
+   }
+   
+   void setAll(double lat, double lon, double altitude,
+               double heading, double pitch, double roll,
+               double range, ossimPlanetAltitudeMode mode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND)
+   {
+      theLat      = lat;
+      theLon      = lon;
+      theAltitude = altitude;
+      theHeading  = heading;
+      thePitch    = pitch;
+      theRoll     = roll;
+      theRange    = range;
+      theMode     = mode;
+   }
+   void setLat(double value)
+   {
+      theLat = value;
+   }
+   double lat()const
+   {
+      return theLat;
+   }
+   void setLon(double value)
+   {
+      theLon = value;
+   }
+   double lon()const
+   {
+      return theLon;
+   }
+   void setAltitude(double value)
+   {
+      theAltitude = value;
+   }
+   double altitude()const
+   {
+      return theAltitude;
+   }
+   void setHeading(double value)
+   {
+      theHeading = value;
+   }
+   double heading()const
+   {
+      return theHeading;
+   }
+   void setPitch(double value)
+   {
+      thePitch = value;
+   }
+   double pitch()const
+   {
+      return thePitch;
+   }
+   void setRoll(double value)
+   {
+      theRoll = value;
+   }
+   double roll()const
+   {
+      return theRoll;
+   }
+   void setRange(double value)
+   {
+      theRange = value;
+   }
+   double range()const
+   {
+      return theRange;
+   }
+   void setAltitudeMode(ossimPlanetAltitudeMode mode)
+   {
+      theMode = mode;
+   }
+   ossimPlanetAltitudeMode altitudeMode()const
+   {
+      return theMode;
+   }
+   ossimString toNavigationString()const
+   {
+      std::ostringstream out;
+
+      out << std::setprecision(15)
+          << ":navigator gotolookat "
+          << theLat << " "
+          << theLon << " "
+          << theAltitude << " "
+          << theHeading << " "
+          << thePitch   << " "
+          << theRoll    << " "
+          << theRange   << " "
+          << modeToString(theMode);
+      
+      return ossimString(out.str().c_str());
+   }
+   ossimString toKml()const
+   {
+      std::ostringstream out;
+      out << std::setprecision(15) << "<LookAt>"
+          << "<latitude>"     << theLat << "</latitude>"
+          << "<longitude>"    << theLon << "</longitude>"
+          << "<altitude>"     << theAltitude << "</altitude>"
+          << "<range>"        << theRange << "</range>"
+          << "<tilt>"         << thePitch << "</tilt>"
+          << "<heading>"      << theHeading << "</heading>"
+          << "<altitudeMode>" << modeToString(theMode) << "</altitudeMode>"
+          << "</LookAt>";
+      return ossimString(out.str().c_str());
+   }
+   ossimRefPtr<ossimXmlNode> saveXml()const
+   {
+      ossimXmlNode* node = new ossimXmlNode();
+      
+      node->setTag("ossimPlanetLookAt");
+      node->addChildNode("latitude", ossimString::toString(theLat));
+      node->addChildNode("longitude", ossimString::toString(theLon));
+      node->addChildNode("altitude", ossimString::toString(theAltitude));
+      node->addChildNode("range", ossimString::toString(theRange));
+      node->addChildNode("roll", ossimString::toString(theRoll));
+      node->addChildNode("tilt", ossimString::toString(thePitch));
+      node->addChildNode("heading", ossimString::toString(theHeading));
+      node->addChildNode("altitudeMode", modeToString(theMode));
+
+      return node;
+   }
+   
+   bool loadXml(ossimRefPtr<ossimXmlNode> xmlNode);
+   
+   static ossimString modeToString(ossimPlanetAltitudeMode mode)
+   {
+      ossimString altitudeMode = "clampToGround";
+      
+      switch(mode)
+      {
+         case ossimPlanetAltitudeMode_RELATIVE_TO_GROUND:
+         {
+            altitudeMode = "relativeToGround";
+            break;
+         }
+         case ossimPlanetAltitudeMode_ABSOLUTE:
+         {
+            altitudeMode = "absolute";
+            break;
+         }
+         default:
+         {
+            break;
+         }
+      }
+      return altitudeMode;
+   }
+   static ossimPlanetAltitudeMode modeFromString(const ossimString& mode)
+   {
+      ossimPlanetAltitudeMode result = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+      ossimString testString = mode;
+      testString = testString.downcase();
+      if(testString == "relativeToGround")
+      {
+         result = ossimPlanetAltitudeMode_RELATIVE_TO_GROUND;
+      }
+      else if(testString == "absolute")
+      {
+         result = ossimPlanetAltitudeMode_ABSOLUTE;
+      }
+
+      return result;
+   }
+
+   
+protected:
+   double theLat;
+   double theLon;
+   double theAltitude;
+   double theHeading;
+   double thePitch;
+   double theRoll;
+   double theRange;
+   ossimPlanetAltitudeMode theMode;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetLsrSpaceTransform.h b/ossimPlanet/include/ossimPlanet/ossimPlanetLsrSpaceTransform.h
new file mode 100644
index 0000000..837f3a6
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetLsrSpaceTransform.h
@@ -0,0 +1,363 @@
+#ifndef ossimPlanetLsrSpaceTransform_HEADER
+#define ossimPlanetLsrSpaceTransform_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <osg/MatrixTransform>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+
+class ossimPlanetLsrSpaceTransform;
+class OSSIMPLANET_DLL ossimPlanetLsrSpaceTransformCallback : public ossimPlanetCallback
+   {
+   public:
+      virtual void lsrSpaceChanged(ossimPlanetLsrSpaceTransform* lsrSpace)=0;
+   };
+
+/**
+ * ossimPlanetLsrSpaceTransform allows one to talk to osg::Transform in the form of Euler angles and
+ * lat lon altitude where altitude is in meters.  The Lsr stands for Local Space Reference.  This manages
+ * a local space axis at te given <lat,lon,altitude> point.
+ */
+class OSSIMPLANET_DLL ossimPlanetLsrSpaceTransform : public osg::Transform,
+                                     public ossimPlanetCallbackListInterface<ossimPlanetLsrSpaceTransformCallback>
+{
+public:
+   /**
+    * Constructs a LsrSpace with a given geo ref model and orientation type.
+    * @param model The Geo Reference Model to use.
+    */
+   ossimPlanetLsrSpaceTransform(ossimPlanetGeoRefModel* model=0);
+   
+   /**
+    * Copy contructor.
+    */ 
+   ossimPlanetLsrSpaceTransform(const ossimPlanetLsrSpaceTransform& lsrTransform,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   
+   /**
+    * Allows one to change the geo reference model.  Will apply the new model to the coordinates
+    * and dirty the bound.
+    * 
+    * @param model  The model to use to generates the lsrMatrix.
+    */
+   void setModel(ossimPlanetGeoRefModel* model);
+   
+   
+   /**
+    * Will copy the parameters only form one transform to the next.
+    *
+    * @param src This is the source to copy from.
+    */
+   void copyParametersOnly(const ossimPlanetLsrSpaceTransform& src)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      dirtyBound();
+      if(!theModel.valid())
+      {
+         theModel = src.theModel;
+      }
+      setHeadingPitchRoll(src.headingPitchRoll());
+      setLatLonAltitude(src.latLonAltitude());
+      setScale(src.scale());
+      theOrientationMode = src.theOrientationMode;
+   }
+   /**
+    * @return the pointer to the active model used by the transform.
+    */
+   const ossimPlanetGeoRefModel* model()const
+   {      
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theModel.get();
+   }
+   
+   /**
+    * @return the pointer to the active model used by the transform.
+    */
+   ossimPlanetGeoRefModel* model()
+   {      
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theModel.get();
+   }
+   
+   /**
+    * This is the local to world  transform matrix.  It will extract out the translation, scale
+    * and orientation from the past in matrix and set the Lsr parameters.
+    *
+    * @param m The matrix to copy and extract the Lsr space parameters.
+    */
+   void setMatrix(const osg::Matrix& m);
+   
+   /**
+    * @return the latitude position in degrees.
+    */
+   double lat()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theLatLonAltitude[0];
+   }
+   
+   /**
+    * @return the longitutde position in degrees.
+    */
+   double lon()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theLatLonAltitude[1];
+   }
+   
+   /**
+    * @return the altitdude in meters.
+    */
+   double altitude()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theLatLonAltitude[2];
+   }
+   
+   /**
+    * @return latLonAltitude as a vector.
+    */
+   const osg::Vec3d& latLonAltitude()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theLatLonAltitude;
+   }
+   
+   /**
+    * @return the model X coordinate of the model that was fromed from the inverse
+    *  of the lat lon altitude.
+    */
+   double x()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theXYZ[0];
+   }
+   
+   /**
+    * @return the model Y coordinate of the model that was fromed from the inverse
+    *  of the lat lon altitude.
+    */
+   double y()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theXYZ[1];
+   }
+   
+   /**
+    * @return the model Z coordinate of the model that was fromed from the inverse
+    *  of the lat lon altitude.
+    */   
+   double z()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theXYZ[2];
+   }
+   
+   /**
+    * @return the model XYZ coordinate of the model that was fromed from the inverse
+    *  of the lat lon altitude.
+    */   
+   const osg::Vec3d& xyz()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theXYZ;
+   }
+   
+   /**
+    * @return the heading orientation in degrees. indicates the rotation about the
+    * Nadir axis
+    */
+   double heading()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theHpr[0];
+   }
+   
+   /**
+    * @return the pitch orientation in degrees.  Indicates the rotation about the
+    * x-axis.
+    */
+   double pitch()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theHpr[1];
+   }
+   
+   /**
+    * @return the roll orientation in degrees. Indicates the rotation about the
+    * y-axis.
+    */
+   double roll()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theHpr[2];
+   }
+   
+   /**
+    * @return all values for heading pitch and roll.
+    */
+   const osg::Vec3d& headingPitchRoll()const{return theHpr;}
+   
+   /**
+    * @return the x scale factor.
+    */
+   double scalex()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theScale[0];
+   }
+   
+   /**
+    * @return the y scale factor
+    */
+   double scaley()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theScale[1];
+   }
+   
+   /**
+    * @return the z-scale factor.
+    */
+   double scalez()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theScale[2];
+   }
+   
+   /**
+    * @return the scale for x,y,z as a vector
+    */
+   const osg::Vec3d& scale()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theScale;
+   }
+   
+   /**
+    * @param hpr contains the heading pitch and roll in that order for the orientation.
+    */
+   void setHeadingPitchRoll(const osg::Vec3d& hpr);
+   
+   /**
+    * @param value contains the position lat lon and altitude where lat and lon
+    *               are in degrees and altitude is in meters relative to the ellipsoid.
+    */
+   void setLatLonAltitude(const osg::Vec3d& value);
+   
+   
+   /**
+    * @param value contains the position lat lon altitude where lat lon are in degrees
+    *              and altitude is in meters relative to the curren geoid contained in the
+    *              ossimPlanetGeoRefModel.
+    */
+   void setLatLonAltitudeMeanSeaLevel(const osg::Vec3d& value);
+   
+   /**
+    * @param value contains the values for the x-scale, y-scale, z-scale
+    *              components.
+    */
+   void setScale(const osg::Vec3d& value);
+   
+   /**
+    * @param xyz is the x,y,z values resulting from the conversion of lat,lon,altitude using the
+    *            ossimPlanetGeoRefModel.  
+    */
+   void setXYZ(const osg::Vec3d& xyz);
+   
+   /**
+    * Override the base class Transform localToWorldMatrix.
+    */
+   virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+   
+   /**
+    * Override the base class world to local transforms
+    */
+   virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+   
+   /**
+    * Override the traverse to make sure that the model pointer is set and if the redraw flag is
+    * set then pass it up.
+    */
+   virtual void traverse(osg::NodeVisitor& nv);
+
+protected:
+   /**
+    * Will take the parameters such as lat,lon,altitude, heading, pitch, and roll, and scales
+    * and convert to it's localToWorld matrix form.
+    *
+    * @return true if successfull and flase otherwise.
+    */
+   bool parametersToMatrix();
+   
+   /**
+    * Will take the matrix and extract out the parameters such as lat, lon, altitude, and
+    * heading pitch and roll and scales.
+    *
+    * param inputM the input matrix to decompose the parameters from.  It will decompose to 
+    * a local space reference axis.
+    */
+   void matrixToParameters(const osg::Matrix& inputM);
+   
+   /**
+    * Will call the callbacks in the callback list and notify the listeners that 
+    * the Lsr space transform changed.
+    */
+   void notifyLsrSpaceChanged();
+   
+   /**
+    * thePropertyMutex is used to synchronize access to any property value.
+    */ 
+   mutable ossimPlanetReentrantMutex thePropertyMutex;
+   
+   /**
+    * theOrientationMode specifies how to construct the matrix
+    * transform.  This can be in OSSIM_LEFT_HANDED or OSSIM_RIGHT_HANDED.
+    */
+   ossimCoordSysOrientMode theOrientationMode;
+   
+   /**
+    *  Convenient pointer to hold direct access to the current GeoRefModel.
+    */
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+   
+   /**
+    * The position in lat lon altitude where lat and lon are degrees and Altitude is
+    * meters.
+    */
+   osg::Vec3d theLatLonAltitude;
+   
+   /**
+    * theXYZ holds the ossimlanetGeoRefModel result of going form lat, lon, altitude to the current
+    * x,y,z representation.
+    */
+   osg::Vec3d theXYZ;
+   
+   /**
+    * theHpr holds the orientation parameters for heading, pitch and roll in degrees.
+    */
+   osg::Vec3d theHpr;
+   
+   /**
+    * theScale holds the x,y,z, scale factors
+    */
+   osg::Vec3d theScale;
+   
+   /**
+    * Convenient values for holding the theLocalToWorld transform.  
+    */
+   mutable osg::Matrixd theLocalToWorld;
+   
+   /**
+    * Convenient values for holding the inverse of theLocalToWorld transform.  
+    */
+   mutable osg::Matrixd theInvLocalToWorld;
+   
+   /**
+    * theRedrawFlag holds the value to specify if redraw is needed.  Will be comunicated to
+    * the parent if needed.
+    */
+   bool theRedrawFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.back b/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.back
new file mode 100644
index 0000000..ef31e24
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.back
@@ -0,0 +1,125 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * OpenSceneGraph Public License for more details.
+*/
+
+#ifndef OSSIM_PLANETMANIPULATOR
+#define OSSIM_PLANETMANIPULATOR 1
+
+#include <osgGA/MatrixManipulator>
+#include <osg/Quat>
+#include <ossim/base/ossimGpt.h>
+#include "ossimPlanetExport.h"
+
+class OSSIMPLANET_EXPORT ossimPlanetManipulator : public osgGA::MatrixManipulator
+{
+public:
+   
+   ossimPlanetManipulator();
+   
+   virtual const char* className() const { return "ossimPlanetManipulator"; }
+   
+   /** set the minimum distance (as ratio) the eye point can be zoomed in towards the
+       center before the center is pushed forward.*/        
+   void setMinimumDistance(float minimumDistance) { theMinimumAltitude=minimumDistance; }
+   
+   /** get the minimum distance (as ratio) the eye point can be zoomed in */
+   float getMinimumDistance() const { return theMinimumAltitude; }
+   
+   
+   /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+   virtual void setByMatrix(const osg::Matrixd& matrix);
+   
+   /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+   virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+   
+   /** get the position of the manipulator as 4x4 Matrix.*/
+   virtual osg::Matrixd getMatrix() const;
+   
+   /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+   virtual osg::Matrixd getInverseMatrix() const;
+   
+   /** Get the FusionDistanceMode. Used by SceneView for setting up setereo convergence.*/
+   virtual osgUtil::SceneView::FusionDistanceMode getFusionDistanceMode() const { return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; }
+   
+   /** Get the FusionDistanceValue. Used by SceneView for setting up setereo convergence.*/
+   virtual float getFusionDistanceValue() const { return _distance; }
+   
+   /** Attach a node to the manipulator. 
+       Automatically detaches previously attached node.
+       setNode(NULL) detaches previously nodes.
+       Is ignored by manipulators which do not require a reference model.*/
+   virtual void setNode(osg::Node*);
+   
+   /** Return node if attached.*/
+   virtual const osg::Node* getNode() const;
+   
+   /** Return node if attached.*/
+   virtual osg::Node* getNode();
+   
+   /** Move the camera to the default position. 
+       May be ignored by manipulators if home functionality is not appropriate.*/
+   virtual void home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   
+   /** Start/restart the manipulator.*/
+   virtual void init(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   
+   /** handle events, return true if handled, false otherwise.*/
+   virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   
+   /** Get the keyboard and mouse usage of this manipulator.*/
+   virtual void getUsage(osg::ApplicationUsage& usage) const;
+   
+protected:
+   
+   virtual ~ossimPlanetManipulator();
+   
+   /** Reset the internal GUIEvent stack.*/
+   void flushMouseEventStack();
+   /** Add the current mouse GUIEvent to internal stack.*/
+   void addMouseEvent(const osgGA::GUIEventAdapter& ea);
+   
+   void computePosition(const osg::Vec3d& eye,const osg::Vec3d& lv,const osg::Vec3d& up);
+   
+   /** For the give mouse movement calculate the movement of the camera.
+       Return true is camera has moved and a redraw is required.*/
+   bool calcMovement();
+   
+   void trackball(osg::Vec3& axis,double& angle, double p1x, double p1y, double p2x, double p2y, double r);
+   double tb_project_to_sphere(double r, double x, double y);
+   
+   /** Check the speed at which the mouse is moving.
+       If speed is below a threshold then return false, otherwise return true.*/
+   bool isMouseMoving();
+   bool computeIntersectionPoint(osg::Vec3d& intersection,
+                                 const osg::Vec3d& startPt = osg::Vec3d(0,0,0),
+                                 const osg::Vec3d& endPt=osg::Vec3d(0,0,0));
+   osg::Vec3d eyePosition()const;
+   // Internal event stack comprising last three mouse events.
+   osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t1;
+   osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t0;
+   
+   osg::ref_ptr<osg::Node> _node;
+   
+   double                  theMinimumAltitude;
+   
+   bool                    _thrown;
+   
+   osg::Vec3d              _center;
+   osg::Quat               _rotation;
+   double                  _distance;
+   double                  theCurrentAltitude;
+   double                  theMaxAltitude;
+};
+
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.h b/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.h
new file mode 100644
index 0000000..6433c4c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetManipulator.h
@@ -0,0 +1,309 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
+ *
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * OpenSceneGraph Public License for more details.
+ */
+
+#ifndef OSSIM_PLANETMANIPULATOR
+#define OSSIM_PLANETMANIPULATOR 1
+
+//#include <osgGA/MatrixManipulator>
+#include <osgGA/CameraManipulator>
+#include <osg/Quat>
+#include <ossim/base/ossimGpt.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetNavigator.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetViewMatrixBuilder.h>
+#include <osg/observer_ptr>
+#include <osg/Node>
+
+class ossimPlanet;
+
+//class OSSIMPLANET_DLL ossimPlanetManipulator : public osgGA::MatrixManipulator,
+class OSSIMPLANET_DLL ossimPlanetManipulator : public osgGA::CameraManipulator,
+public ossimPlanetActionReceiver
+{
+public:
+   ossimPlanetManipulator();
+
+   // osgGA::MatrixManipulator methods
+
+   virtual const char* className() const { return "ossimPlanetManipulator"; }
+
+   virtual void setByMatrix(const osg::Matrixd& matrix);
+   /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+
+   virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+   /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+
+   virtual osg::Matrixd getMatrix() const;
+   /** get the position of the manipulator as 4x4 Matrix.*/
+
+   virtual osg::Matrixd getInverseMatrix() const;
+   /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+
+   virtual void setNode(osg::Node*);
+   /** Get the FusionDistanceMode. Used by SceneView for setting up stereo convergence.*/
+   virtual osgUtil::SceneView::FusionDistanceMode getFusionDistanceMode() const { return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; }
+
+   /** Get the FusionDistanceValue. Used by SceneView for setting up stereo convergence.*/
+   virtual float getFusionDistanceValue() const { return theFusionDistance; }
+
+   /** Attach a node to the manipulator.
+    Automatically detaches previously attached node.
+    setNode(NULL) detaches previously nodes.
+    Is ignored by manipulators which do not require a reference model.*/
+
+   virtual const osg::Node* getNode() const;
+   /** Return node if attached.*/
+
+   virtual osg::Node* getNode();
+   /** Return node if attached.*/
+
+   virtual void home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   /** Move the camera to the default position.
+    May be ignored by manipulators if home functionality is not appropriate.*/
+
+   virtual void init(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   /** Start/restart the manipulator.*/
+
+   virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
+   /** handle events, return true if handled, false otherwise.*/
+
+   virtual void getUsage(osg::ApplicationUsage& usage) const;
+   /** Get the keyboard and mouse usage of this manipulator.*/
+
+
+   virtual void setLockToNode(osg::Node* node);
+   // new methods
+
+   virtual void getLatLonHgtHPR(double& lat, double& lon, double& hgt, double& heading, double& pitch, double& roll)const;
+
+   virtual void solveLookAt(double losLat, double losLon, double losHeight, double& heading, double& pitch, double& roll, double& range)const;
+
+   void playRecording();
+   void startRecording();
+   void stopRecording();
+   void saveRecording(std::ostream& out);
+   bool loadRecording(std::istream& in);
+
+	void extractLookFromParameters(ossimXmlNode* node,
+                                 double& lat,
+                                 double& lon,
+                                 double& alt,
+                                 double& h,
+                                 double& p,
+                                 double& r);
+
+
+
+   void setEventHandlingFlag(bool flag);
+   void setUseFrameEventForUpdateFlag(bool flag);
+   void setAutoCalculateIntersectionFlag(bool flag);
+   void setLosXYZ(const osg::Vec3d& losXYZ);
+
+   void updateNavigator();
+   // call theNavigator->update()
+   // Cocoa version temporarily needs this for now
+   ossimPlanetNavigator* navigator()
+   {
+      return theNavigator.get();
+   }
+
+   /**
+    * Will set the latitude for the view matrix.
+    *
+    * @param value is the latitude position of the view in degrees.
+    */
+   void setLatitude(double value);
+
+   /**
+    * Will set the longitude for the view matrix.
+    *
+    * @param value is the longitude position of the view in degrees.
+    */
+   void setLongitude(double value);
+
+   /**
+    * Will set the altitude for the view matrix.
+    *
+    * @param value is the altitude position of the view in meters.
+    *              Currently this is absolute position on the ellipsoid.
+    */
+   void setAltitude(double value);
+
+
+   /**
+    * Will allow you to set the latitude, longitude and altitude in a single operation
+    *
+    * @param lat is the latitude position of the view in degrees.
+    * @param lon is the longitude position of the view in degrees.
+    * @param alt is the altitude position of the view in meters.
+    *                 Currently this is absolute position on the ellipsoid.
+    */
+   void setLatitudeLongitudeAltitude(double lat, double lon, double alt);
+
+   /**
+    * This is a convenience method that allows one to put the positional information
+    * in a single osg::Vec3d data type.
+    *
+    * @param pos is the is the latitude, longitude, altitude where the latitude is in
+    *            pos[0] and longitude is in pos[1] and altitude is in pos[2].  the lat and lon
+    *            values are in degrees where the altitude is in meters.
+    */
+   void setPosition(const osg::Vec3d& pos);
+
+   /**
+    * sets the heading orientation for the view.  Note this indicates a rotation about the
+    * Z-axis.
+    *
+    * @param value indicates the heading in degrees to rotate around the Z axis.
+    */
+   void setHeading(double value);
+
+   /**
+    * Sets the pitch orientation for the view.  Note this indicates a rotation about the
+    * X-axis.
+    *
+    * @param value indicates the pitch in degrees to rotate around the X-axis.
+    */
+   void setPitch(double value);
+
+   /**
+    * Set the roll orietation for the view.  Note this indicates a rotation about the
+    * Y-axis.
+    */
+   void setRoll(double value);
+
+   /**
+    * sets the heading pitch and rool as a single operation.
+    *
+    * @param h indicates the heading in degrees to rotate around the Z axis.
+    * @param p indicates the pitch in degrees to rotate around the X axis.
+    * @param r indicates the roll in degrees to rotate around the y axis.
+    */
+   void setHeadingPitchRoll(double h, double p, double r);
+
+   /**
+    * This is a convenience method that allows one to put the positional information
+    * in a single osg::Vec3d data type.
+    *
+    * @param orien is the heading, pitch, and roll orientation of the view in degrees.
+    *              the heading is in orien[0] and pitch is in orien[1] and the roll is in
+    *              orien[2].
+    */
+    void setOrientation(const osg::Vec3d& orien);
+
+   /**
+    * Allows one to set the position and orientation as a single operation.
+    *
+    * @param lat is the latitude position of the view in degrees.
+    * @param lon is the longitude position of the view in degrees.
+    * @param alt is the altitude position of the view in meters.
+    *                 Currently this is absolute position on the ellipsoid.
+    * @param h indicates the heading in degrees to rotate around the Z axis.
+    * @param p indicates the pitch in degrees to rotate around the X axis.
+    * @param r indicates the roll in degrees to rotate around the y axis.
+    *
+    */
+   void setPositionAndOrientation(double lat, double lon, double altitude,
+                                  double h, double p, double r);
+
+   /**
+    * This is an added convenience method to take 2 3-d vectors as position
+    * and orientation
+    *
+    * @param pos is the is the latitude, longitude, altitude where the latitude is in
+    *            pos[0] and longitude is in pos[1] and altitude is in pos[2].  the lat and lon
+    *            values are in degrees where the altitude is in meters.
+    * @param orien is the heading, pitch, and roll orientation of the view in degrees.
+    *              the heading is in orien[0] and pitch is in orien[1] and the roll is in
+    *              orien[2].
+    *
+    */
+   void setPositionAndOrientation(const osg::Vec3d& pos,
+                                  const osg::Vec3d& orien);
+
+   ossimPlanetViewMatrixBuilder* viewMatrixBuilder(){return theViewMatrixBuilder.get();}
+   const ossimPlanetViewMatrixBuilder* viewMatrixBuilder()const{return theViewMatrixBuilder.get();}
+   virtual void execute(const ossimPlanetAction& a);
+
+   void initializeDefaultBindings(const ossimString& pathName=":navigator");
+   
+protected:
+
+   class FromNodeCallback : public ossimPlanetLsrSpaceTransformCallback
+      {
+      public:
+         FromNodeCallback(ossimPlanetViewMatrixBuilder* vb)
+         :theViewMatrixBuilder(vb)
+         {
+         }
+         virtual void lsrSpaceChanged(ossimPlanetLsrSpaceTransform* /*lsrSpace*/)
+         {
+            if(theViewMatrixBuilder)
+            {
+               theViewMatrixBuilder->setLookFromNodeOffset(theViewMatrixBuilder->fromNode(),
+                                                           theViewMatrixBuilder->fromRelativeHpr(),
+                                                           theViewMatrixBuilder->fromRange(),
+                                                           theViewMatrixBuilder->fromRelativeOrientationFlags());
+            }
+         }
+         ossimPlanetViewMatrixBuilder* theViewMatrixBuilder;
+      };
+
+   class ToNodeCallback : public ossimPlanetLsrSpaceTransformCallback
+      {
+      public:
+         ToNodeCallback(ossimPlanetViewMatrixBuilder* vb)
+         :theViewMatrixBuilder(vb)
+         {
+
+         }
+         virtual void lsrSpaceChanged(ossimPlanetLsrSpaceTransform* lsrSpace)
+         {
+            if(theViewMatrixBuilder)
+            {
+               theViewMatrixBuilder->setLookToNode(lsrSpace);
+            }
+         }
+         ossimPlanetViewMatrixBuilder* theViewMatrixBuilder;
+      };
+
+   virtual ~ossimPlanetManipulator();
+   virtual void updateViewMatrixNodes();
+
+   bool calculateLineOfSiteLatLonHeight(osg::Vec3d& latLonHeight);
+
+   osg::Vec3d eyePosition()const;
+
+   osg::ref_ptr<ossimPlanetNavigator> theNavigator;
+   mutable ossimPlanetReentrantMutex theMutex;
+   osg::ref_ptr<osg::Node> theNode;
+   bool theEventHandlingFlag;
+   bool theUseFrameEventForUpdateFlag;
+   bool theAutoCalculateIntersectionFlag;
+   ossimPlanet* thePlanet;
+   ossim_float32 theFusionDistance;
+
+   osg::ref_ptr<ossimPlanetViewMatrixBuilder> theViewMatrixBuilder;
+
+   osg::ref_ptr<osg::Node> theLockToNode;
+   osg::ref_ptr<osg::Node> theLockFromNode;
+
+   osg::ref_ptr<FromNodeCallback> theFromNodeCallback;
+   osg::ref_ptr<ToNodeCallback> theToNodeCallback;
+};
+
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetMessage.h b/ossimPlanet/include/ossimPlanet/ossimPlanetMessage.h
new file mode 100644
index 0000000..ede81c5
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetMessage.h
@@ -0,0 +1,48 @@
+#ifndef ossimPlanetMessage_HEADER
+#define ossimPlanetMessage_HEADER
+#include <ossim/base/ossimString.h>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <vector>
+
+class OSSIMPLANET_DLL ossimPlanetMessage : public osg::Referenced
+{
+public:
+   typedef unsigned char DataType;
+   typedef std::vector<ossimPlanetMessage::DataType> StorageType;
+   
+   ossimPlanetMessage(const ossimString& id=ossimString("") )
+   {
+	   setId(id);
+   }
+   ossimPlanetMessage(const ossimString& id, const ossimString& data )
+   {
+      setId(id);
+      setData(data);
+   }
+   ossimPlanetMessage(const ossimString& id, const std::vector<char>& byteBuffer):
+   theId(id),
+   theData(byteBuffer.begin(), byteBuffer.end())
+   {
+   }
+   ossimPlanetMessage(const ossimString& id, const StorageType& buf):
+   theId(id),
+   theData(buf)
+   {
+   }
+   ossimPlanetMessage(const ossimPlanetMessage& src)
+   :theId(src.theId),
+   theData(src.theData){}
+   ossimPlanetMessage* clone()const{return new ossimPlanetMessage(*this);}
+   const ossimString& id()const{return theId;}
+   void setId(const ossimString& id){theId = id;}
+   void setData(const ossimPlanetMessage::StorageType& data){theData = data;}
+   void setData(const ossimString& data){theData.clear();theData.insert(theData.begin(), data.begin(), data.end());}
+   ossim_uint32 dataSize()const{return (ossim_uint32)theData.size();}                                                                     
+   const ossimPlanetMessage::StorageType& data()const{return theData;}
+protected:
+   ossimString                     theId;
+   ossimPlanetMessage::StorageType theData;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNavigator.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNavigator.h
new file mode 100644
index 0000000..0563a2d
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNavigator.h
@@ -0,0 +1,277 @@
+#ifndef ossimPlanetNavigator_HEADER
+#define ossimPlanetNavigator_HEADER
+
+#include <assert.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetPrimaryBody.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <osg/Timer>
+#include <osg/AnimationPath>
+#include <osg/ref_ptr>
+#include <osg/Referenced>
+#include <osg/Matrixd>
+//#include <osgGA/MatrixManipulator>
+#include <osgGA/CameraManipulator>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+
+class ossimPlanet;
+class OSSIMPLANET_DLL ossimPlanetNavigator : public osg::Referenced//,
+	                                         //public ossimPlanetActionReceiver
+{
+public:
+    ossimPlanetNavigator(osg::ref_ptr<ossimPlanetPrimaryBody> p);
+        // assert(p);
+    ~ossimPlanetNavigator();
+
+    double lat() const
+        // latitude of eye in degrees
+        { return lat_; };
+    
+    double lon() const
+        // longitude of eye in degrees
+        { return lon_; };
+
+    double elev() const
+        // elevation of eye in meters
+        { return zoom2Elevation(eyexyz_.z()); }
+
+    const osg::Vec3d& orientation() const
+        // eyepoint orientation in euler angles: heading (yaw), pitch, roll
+        { return eyehpr_; };
+
+    double metersToCenter() const;
+        // distance from eye to center of primary
+
+   void setLatLonHeight(double lat, double lon, double height);
+   void setHpr(double h, double p, double r);
+        // set the lat, lon, elevation above planet
+
+    virtual osg::Vec3d centerOfInterest() const;
+        // lat/lon/elev of center of interest in degrees/degrees/meters for CacheEngine purposes
+    
+    virtual void update();
+        // update look/lat/lon/elev/navigation-quasimodes based on current navigation-quasimodes
+
+    void updateZoomParameters();
+        // update info needed to clamp/manage the eyepoint zoomin
+
+    const osg::ref_ptr<ossimPlanetPrimaryBody> primary() const
+        // the primary we are orbiting
+        { return primary_; }
+    
+    // ActionReceiver features
+
+    virtual void execute(const ossimPlanetAction &a);
+        // execute action
+
+
+    // uncommented mystery routines under here
+
+    osg::Matrixd orientationLsrMatrix() const
+        { return orientationLsrMatrix(lat_, lon_, elev(), eyehpr_[0], eyehpr_[1], eyehpr_[2]); }
+    
+    osg::Matrixd orientationLsrMatrix(double lat, double lon, double hgt, double h, double p, double r) const;
+
+    osg::Matrixd viewMatrix() const
+        { return viewMatrix(lat_, lon_, elev(), eyehpr_[0], eyehpr_[1], eyehpr_[2]); }
+    
+    osg::Matrixd viewMatrix(double lat, double lon, double hgt, double h, double p, double r) const;    
+
+    void setViewParameters(const osg::Matrixd& m);
+    
+    void setPlanet(ossimPlanet* planet)
+   { thePlanet = planet; }
+    
+    bool canSetLineOfSite() const
+    { return ((!zoominglos_ && !losLookingFlag_)||
+              (!losXYZValidFlag_||rotating_||looking_||flying_)); }
+        
+    double pitchOffset() const
+        { return pitchOffset_; }
+
+    void setLosXYZ(const osg::Vec3d& losXYZ)
+        {
+            losXYZ_ = losXYZ;
+            losXYZValidFlag_ = !ossim::isnan(losXYZ[0]) && !ossim::isnan(losXYZ[1]) && !ossim::isnan(losXYZ[2]);
+        }
+    
+    void setLosXYZValidFlag(bool flag)
+        { losXYZValidFlag_ = flag; }
+        
+    bool gotZoomingLosFlag() const
+        { return zoominglos_; }
+        
+    bool getLosLookingFlag() const
+        { return losLookingFlag_; }
+        
+    void setLosLookingFlag(bool flag)
+        { losLookingFlag_ = flag; }
+    
+    enum NavigatorAnimationMode { NAV_ANIMATION_NONE = 0, NAV_ANIMATION_RECORDING = 1, NAV_ANIMATION_PLAYBACK  = 2 };
+
+    void solveLookAt(double losLat, double losLon, double losHeight,
+                     double& heading, double& pitch, double& roll, double& range)const;
+    void solveEyeGivenLocalSpaceAndRange(osg::Vec3d& llh, // out lat lon height
+                                         osg::Vec3d& hpr,  // output orientation
+                                         const osg::Vec3d& localPt,
+                                         const osg::Vec3d& localHpr,
+                                         double rangeInMeters)const;
+   void playRecording();
+   void startRecording();
+   void stopRecording();
+   void saveRecording(std::ostream& out);
+   bool loadRecording(std::istream& in);
+
+   void setUseTimedUpdateFlag(bool flag);
+
+   bool needsContinuousUpdate()const
+   {
+      return ((theAnimationMode==NAV_ANIMATION_PLAYBACK)||
+              rotating_||
+              zooming_||
+              zoominglos_||
+              looking_||
+              gotoing_||
+              gotoingelev_||
+              gotoset_||
+              flying_||
+              losLookingFlag_);
+   }
+   void setRedrawFlag(bool flag)
+   {
+      theRedrawFlag = flag;
+   }
+   bool redrawFlag()const
+   {
+      return theRedrawFlag;
+   }
+   osg::ref_ptr<ossimPlanetGeoRefModel> landModel();
+   const osg::ref_ptr<ossimPlanetGeoRefModel> landModel()const;
+	void gotoLatLonElevHpr(const string& placeName, 
+                          double latitude, 
+                          double longitude, 
+                          double elevation, 
+                          double h, 
+                          double p, 
+                          double r,
+                          bool animateFlag=true);
+	void gotoLookAt(const ossimPlanetLookAt& lookInfo,bool animateFlag=true);
+protected:
+	void xmlExecute(const ossimPlanetXmlAction& action);
+	void destinationCommandExecute(const ossimPlanetDestinationCommandAction& action);
+	
+	void updateLatLon(float x, float y);
+	
+	
+	// update lon_ and lat_ based on user input x,y in [-1,1] and elev()
+	void extractCameraParameters(ossimRefPtr<ossimXmlNode> node,
+                                double& lat,
+                                double& lon,
+                                double& alt,
+                                double& h,
+                                double& p,
+                                double& r)const;
+	void extractLookAtParameters(ossimRefPtr<ossimXmlNode> node,
+                                ossimPlanetLookAt& look)const;
+	inline double zoom2Elevation(double zoomParameter) const
+	{ return (-zoomParameter - 1.0)*primary_->radius(lat()); }
+
+    double pitchOffset_;
+
+    double lat_;
+    double lon_;
+        // current latitude and longitude of eye in degrees
+
+    osg::Vec3d eyexyz_;
+        // eyepoint position (z for zooming, xy unused)
+
+    osg::Vec3d eyehpr_; 
+        // eyepoint orientation (heading/pitch/roll)
+
+    double zoomMin_;
+    double zoomMax_;
+        // min and max distances to zoom in and out
+
+    double fov_;
+        // GraphicsSystem::instance()->camera()->fov()
+
+    ossimPlanet* thePlanet;
+
+    osg::ref_ptr<ossimPlanetPrimaryBody> primary_;
+        // the primary we are observing (ie, the celestial body we orbit, ie probably the earth)
+
+    bool rotating_;
+    bool zooming_;
+    bool zoominglos_;
+    bool looking_;
+    bool endLooking_;
+    bool gotoing_;
+    bool gotoingelev_;
+    bool gotoset_;
+    bool flying_;
+    bool losLookingFlag_;
+        // current user navigation quasimodes
+
+    double targetLat_;
+    double targetLon_;
+    double targetLookZ_;
+    double targetStartLookZ_;
+    double targetStartLat_;
+    double targetStartLon_;
+    double targetStartLookH_;
+    double targetStartLookP_;
+    double targetStartLookR_;
+    double targetMidpointLookZ_;
+    double targetLookH_;
+    double targetLookP_;
+    double targetLookR_;
+    
+    osg::Vec3d losXYZ_;
+    bool losXYZValidFlag_;
+
+    double updateRatePerSecond_;
+    osg::Timer_t lastUpdateTime_;
+    
+    osg::Timer_t gotoStartTime_;
+        // data for going to a target location
+
+    double gotoLookDuration_;
+        // duration in seconds of movement in a gotolatlon and a look view snapback
+
+    osg::Timer_t endLookingStartTime_;
+        // time when user stopped looking around
+
+    double zoomScaleBaseline_;
+        // pfUnits elevation height of maximum user input sensitivity 
+
+    double zoomScaleInput(float input) const;
+        // scale user input based on current zoom level and zoomScaleBaseline_
+
+    double baseInputLon_, baseInputLat_, baseInputZoom_, baseInputYaw_, baseInputPitch_;
+        // initial values for device input, so we can use relative device movement
+
+    double xFly_, yFly_;
+        // values specified by last flying action (which may be still active; flying_ will tell you)
+        
+    struct LastAnimationParameter
+    {
+       osg::Quat  quat;
+       osg::Vec3d orientation;
+       osg::Vec3d eye;
+    };
+    NavigatorAnimationMode theAnimationMode;
+    osg::ref_ptr<osg::AnimationPath> theAnimationPath;
+    LastAnimationParameter theLastAnimationParameter;
+    osg::Timer_t theAnimationStartTime;
+
+    mutable ossimPlanetReentrantMutex theMutex;
+    bool theUseTimedUpdateFlag;
+    bool theRedrawFlag;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNetworkConnection.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNetworkConnection.h
new file mode 100644
index 0000000..375ac3f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNetworkConnection.h
@@ -0,0 +1,41 @@
+#ifndef ossimPlanetNetworkConnection_HEADER
+#define ossimPlanetNetworkConnection_HEADER
+
+// abstract interface to network.
+
+#include <string>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+
+class OSSIMPLANET_DLL ossimPlanetNetworkConnection
+{
+public:
+   ossimPlanetNetworkConnection(const std::string& name) : name_(name) {}
+    virtual ~ossimPlanetNetworkConnection() {}
+
+    const std::string& name() const
+        // name of the connection
+        { return name_; }
+
+    const std::string& error() const
+        // current error status, empty if no error.
+        { return error_; }
+
+    virtual void send(const ossimPlanetAction& a, const std::string& destination) = 0;
+        // send action to the specified destination host.
+
+    virtual void receive() = 0;
+        // read any pending incoming actions and execute them.
+        // should discard any incoming sent by me where destination is me or all
+
+protected:
+    std::string name_;
+        // name of the connection
+
+    std::string error_;
+        // current error status, empty if no error.
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNode.h
new file mode 100644
index 0000000..cc7c397
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNode.h
@@ -0,0 +1,255 @@
+#ifndef ossimPlanetNode_HEADER
+#define ossimPlanetNode_HEADER
+#include <osg/Group>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ReadWriteMutex>
+
+class ossimPlanetNode;
+class OSSIMPLANET_DLL ossimPlanetNodeCallback : public ossimPlanetCallback
+{
+public:
+   virtual void propertyChanged(ossimPlanetNode* /*node*/,
+                                const ossimString& /*name*/){}
+   virtual void destructingNode(ossimPlanetNode* /*node*/){}
+   virtual void needsRedraw(ossimPlanetNode* /*node*/){}
+   virtual void nodeAdded(osg::Node* /*node*/){}
+   virtual void nodeRemoved(osg::Node* /*node*/){}
+   
+protected:
+};
+
+
+class ossimPlanetLayer;
+class OSSIMPLANET_DLL ossimPlanetNode : public osg::Group,
+                                        public ossimPlanetCallbackListInterface<ossimPlanetNodeCallback>,
+													 public ossimPlanetActionReceiver
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetNode> > NodeListType;
+
+   ossimPlanetNode();
+   virtual ~ossimPlanetNode();
+	static void remove(osg::Node* node);
+	virtual void setLayer(ossimPlanetLayer* layer)
+	{
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+		theLayer = layer;
+	}
+	ossimPlanetLayer* layer()
+	{
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+		return theLayer;
+	}
+	const ossimPlanetLayer* layer()const
+	{
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+		return theLayer;
+	}
+   virtual bool addChild( Node *child );
+   virtual bool insertChild( unsigned int index, Node *child );
+   virtual bool replaceChild( Node *origChild, Node* newChild );
+   bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove);
+   bool enableFlag()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theEnableFlag;
+   }
+   virtual void setEnableFlag(bool flag)
+   {
+      bool changed = flag!=enableFlag();
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+         theEnableFlag = flag;
+      }
+      if(changed) setRedrawFlag(true);
+      notifyPropertyChanged(this, "enableFlag");
+   }
+   bool intersectFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      
+      return theIntersectableFlag;
+   }
+   virtual void setIntersectFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      theIntersectableFlag = flag;
+   }
+   virtual void setRedrawFlag(bool flag);
+   bool redrawFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodeRedrawPropertyMutex);
+      return theRedrawFlag;
+   }
+   const ossimString& id()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theId;
+   }
+   virtual void setId(const ossimString& id)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+         theId = id;
+      }
+      notifyPropertyChanged(this, "id");
+   }
+   virtual void setName(const ossimString& value)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+         theName = value;
+      }
+      notifyPropertyChanged(this, "name");
+   }
+   const ossimString& name()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theName;
+   }
+   void name(ossimString& value)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      value = theName;
+   }
+   virtual void setDescription(const ossimString& value)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+         theDescription = value;
+      }
+      notifyPropertyChanged(this, "description");
+   }
+   const ossimString& description()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theDescription;
+   }
+   void description(ossimString& value)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      value = theDescription;
+   }
+   virtual osg::ref_ptr<ossimPlanetLookAt> lookAt()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theLookAt;
+   }
+   virtual const osg::ref_ptr<ossimPlanetLookAt> lookAt()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      return theLookAt;
+   }
+   virtual void lookAt(ossimPlanetLookAt& result)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+      if(theLookAt.valid())
+      {
+         result = *theLookAt;
+      }
+   }
+   virtual void setLookAt(osg::ref_ptr<ossimPlanetLookAt> value)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodePropertyMutex);
+         theLookAt = value;
+      }
+      notifyPropertyChanged(this, "LookAt");
+   }
+   virtual void traverse(osg::NodeVisitor& nv);
+   virtual void execute(const ossimPlanetAction& action);
+   
+   static ossimPlanetNode* findNode(osg::NodePath& currentNodePath);
+
+   
+   virtual void notifyPropertyChanged(ossimPlanetNode* node, const ossimString& name);
+   virtual void notifyDestructing(ossimPlanetNode* node);
+   virtual void notifyNeedsRedraw();
+   virtual void notifyAddChild(osg::ref_ptr<osg::Node>    node);
+   virtual void notifyRemoveChild(osg::ref_ptr<osg::Node> node);
+	
+protected:
+   virtual void nodeAdded(osg::Node* /*node*/){}
+	virtual void nodeRemoved(osg::Node* /*node*/){}
+   mutable OpenThreads::ReentrantMutex thePlanetNodeRedrawPropertyMutex;
+   mutable OpenThreads::ReentrantMutex thePlanetNodePropertyMutex;
+   
+   bool        theEnableFlag;
+   bool        theIntersectableFlag;
+   ossimString theId;
+   ossimString theName;
+   ossimString theDescription;
+   bool        theRedrawFlag;
+   osg::ref_ptr<ossimPlanetLookAt> theLookAt;
+	ossimPlanetLayer* theLayer;
+};
+
+class OSSIMPLANET_DLL ossimPlanetNodeReraiseCallback : public ossimPlanetNodeCallback
+{
+public:
+	ossimPlanetNodeReraiseCallback(ossimPlanetNode* node)
+	:theNode(node)
+	{
+	}
+	void setNode(ossimPlanetNode* node)
+	{
+		theNode = node;
+	}
+	ossimPlanetNode* node()
+	{
+		return theNode;
+	}
+	const ossimPlanetNode* node()const
+	{
+		return theNode;
+	}
+   virtual void propertyChanged(ossimPlanetNode* node,
+                                const ossimString& name)
+	{
+		if(theNode)
+		{
+			theNode->notifyPropertyChanged(node, name);
+		}
+	}
+   virtual void destructingNode(ossimPlanetNode* node)
+	{
+		if(theNode)
+		{
+			theNode->notifyDestructing(node);
+		}
+	}
+   virtual void needsRedraw(ossimPlanetNode* /*node*/)
+	{
+		if(theNode)
+		{
+			theNode->notifyNeedsRedraw();
+		}
+	}
+   virtual void nodeAdded(osg::Node* node)
+	{
+		if(theNode)
+		{
+			theNode->notifyAddChild(node);
+		}
+	}
+   virtual void nodeRemoved(osg::Node* node)
+	{
+		if(theNode)
+		{
+			theNode->notifyRemoveChild(node);
+		}
+	}
+protected:
+	ossimPlanetNode* theNode;
+	osg::ref_ptr<ossimPlanetLookAt> theLookAt;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactory.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactory.h
new file mode 100644
index 0000000..9e4f162
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactory.h
@@ -0,0 +1,17 @@
+#ifndef ossimPlanetNodeFactory_HEADER
+#define ossimPlanetNodeFactory_HEADER
+#include "ossimPlanetNodeFactoryBase.h"
+
+class OSSIMPLANET_DLL ossimPlanetNodeFactory : public ossimPlanetNodeFactoryBase
+{
+public:
+	ossimPlanetNodeFactory();
+	virtual ~ossimPlanetNodeFactory();
+	static ossimPlanetNodeFactory* instance();
+   virtual ossimPlanetNode* create(const ossimString& type)const;
+	
+protected:
+		static ossimPlanetNodeFactory* theInstance;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactoryBase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactoryBase.h
new file mode 100644
index 0000000..fbdaac5
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeFactoryBase.h
@@ -0,0 +1,18 @@
+#ifndef ossimPlanetNodeFactoryBase_HEADER
+#define ossimPlanetNodeFactoryBase_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+class ossimPlanetNode;
+class OSSIMPLANET_DLL ossimPlanetNodeFactoryBase : public osg::Referenced
+{
+public:
+   ossimPlanetNodeFactoryBase(){}
+   virtual ~ossimPlanetNodeFactoryBase()
+	{
+	}
+   virtual ossimPlanetNode* create(const ossimString& type)const=0;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetNodeRegistry.h b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeRegistry.h
new file mode 100644
index 0000000..48fccc8
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetNodeRegistry.h
@@ -0,0 +1,30 @@
+#ifndef ossimPlanetNodeRegistry_HEADER
+#define ossimPlanetNodeRegistry_HEADER
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetNodeFactoryBase.h>
+#include <OpenThreads/ReadWriteMutex>
+#include <OpenThreads/ScopedLock>
+
+class ossimPlanetNodeRegistry  
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetNodeFactoryBase> > FactoryListType;
+   ossimPlanetNodeRegistry();
+   ~ossimPlanetNodeRegistry();
+	static ossimPlanetNodeRegistry* instance();
+   void finalize();
+   ossimPlanetNode* create(const ossimString& type)const;
+	void registerFactory(ossimPlanetNodeFactoryBase* factory,
+								bool insertFrontFlag=false);
+   void unregisterFactory(const ossimPlanetNodeFactoryBase* factory);
+	
+protected:
+	bool hasFactory(const ossimPlanetNodeFactoryBase* factory)const;
+	
+	static ossimPlanetNodeRegistry* theInstance;
+	static ossim_uint32 theInitializeCount;
+	mutable OpenThreads::ReadWriteMutex theFactoryListMutex;
+	FactoryListType theFactoryList;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetOperation.h b/ossimPlanet/include/ossimPlanet/ossimPlanetOperation.h
new file mode 100644
index 0000000..2dc68c0
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetOperation.h
@@ -0,0 +1,422 @@
+#ifndef ossimPlanetOperation_HEADER
+#define ossimPlanetOperation_HEADER
+#include <OpenThreads/Thread>
+#include <OpenThreads/ScopedLock>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <ossimPlanet/ossimPlanetRefBlock.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimString.h>
+#include <iostream>
+
+
+class ossimPlanetOperation;
+class ossimPlanetOperationThreadQueue;
+class ossimPlanetOperationMultiThreadQueue;
+class ossimPlanetOperationQueue;
+class OSSIMPLANET_DLL ossimPlanetOperationCallback : public ossimPlanetCallback
+{
+public:
+	ossimPlanetOperationCallback(){}
+	virtual void ready(ossimPlanetOperation* /*operation*/){}
+	virtual void started(ossimPlanetOperation* /*operation*/){}
+	virtual void finished(ossimPlanetOperation* /*operation*/){}
+	virtual void canceled(ossimPlanetOperation* /*operation*/){}
+   virtual void priorityChanged(ossimPlanetOperation* /*operation*/){}
+   virtual void propertyChanged(const ossimString& /*name*/,
+                                ossimPlanetOperation* /*operation*/){}
+	
+};
+
+
+class OSSIMPLANET_DLL ossimPlanetOperation : public osg::Referenced,
+                                             public ossimPlanetCallbackListInterface<ossimPlanetOperationCallback>
+{
+public:
+	friend class ossimPlanetOperationThreadQueue;
+	friend class ossimPlanetOperationMultiThreadQueue;
+	friend class ossimPlanetOperationQueue;
+   typedef double Priority;
+
+   enum StateType
+	{
+		READY_STATE = 0, // Specifies that the operation is ready to run
+		RUN_STATE = 1,   // Specifies that the operation is currently running
+		CANCELED_STATE = 4, // Specifies that the operation was canceled
+		FINISHED_STATE = 8 // The operation ran through to completion
+	};
+   static const ossimPlanetOperation::Priority PRIORITY_HIGHEST;
+   static const ossimPlanetOperation::Priority PRIORITY_LOWEST;
+   typedef std::list<osg::ref_ptr<ossimPlanetOperation> > List;
+   ossimPlanetOperation(const ossimString& name="", const ossimString id="", ossimPlanetOperation::Priority queuePriority=0)
+   :theName(name),
+   theId(id),
+	thePriority(queuePriority),
+	theState(READY_STATE)
+   {
+      setThreadSafeRefUnref(true);
+   }
+   virtual ~ossimPlanetOperation()
+   {
+#if 0
+		if((state() == RUN_STATE)||
+         (state() == READY_STATE))
+		{
+			cancel();
+		}
+#endif
+   }
+   bool operator < (const ossimPlanetOperation& rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority < rhs.thePriority);
+   }
+   bool operator < (const osg::ref_ptr<ossimPlanetOperation> rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority < rhs->thePriority);
+   }
+   bool operator < (const ossimPlanetOperation* rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority < rhs->thePriority);
+   }
+   bool operator > (const ossimPlanetOperation& rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority > rhs.thePriority);
+   }
+   bool operator > (const ossimPlanetOperation* rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority > rhs->thePriority);
+   }
+   bool operator > (const osg::ref_ptr<ossimPlanetOperation> rhs)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return (thePriority > rhs->thePriority);
+   }
+   void setName(const ossimString& name)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         theName = name;
+      }
+      notifyPropertyChanged("name");
+   }
+	
+   const ossimString& name()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theName;
+   }
+   void setId(const ossimString& id)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         theId = id;
+      }
+      notifyPropertyChanged("id");
+   }
+	const ossimString& id()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theId;
+   }
+	void setState(StateType state)
+	{
+		{
+			OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+			theState = state;
+		}
+		switch(state)
+		{
+			case READY_STATE:
+			{
+            notifyReady();
+				break;
+			}
+			case RUN_STATE:
+			{
+				notifyStarted();
+				break;
+			}
+			case CANCELED_STATE:
+			{
+				notifyCanceled();
+				break;
+			}
+			case FINISHED_STATE:
+			{
+				notifyFinished();
+				break;
+			}
+		}
+	}
+   bool isStopped()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return ((theState == CANCELED_STATE)||
+              (theState == FINISHED_STATE));
+   }
+	virtual StateType state()const
+	{
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+		return theState;
+	}
+   virtual void release(){}
+   void addDependency(ossimPlanetOperation* operation)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDependencyListMutex);
+      List::iterator iter = std::find(theDependencyList.begin(),
+                                      theDependencyList.end(),
+                                      operation);
+      if(iter==theDependencyList.end())
+      {
+         theDependencyList.push_back(operation);
+      }
+   }
+   void removeDependency(ossimPlanetOperation* operation)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDependencyListMutex);
+      List::iterator iter = std::find(theDependencyList.begin(),
+                                      theDependencyList.end(),
+                                      operation);
+      if(iter!=theDependencyList.end())
+      {
+         theDependencyList.erase(iter);
+      }
+   }
+   bool hasDependency()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDependencyListMutex);
+      return (theDependencyList.size() > 0);
+   }
+   ossimPlanetOperation::List& dependencyList()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theDependencyList;
+   }
+   const ossimPlanetOperation::List& dependencyList()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theDependencyList;
+   }
+   void setPriority(ossimPlanetOperation::Priority priority)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         thePriority = priority;
+      }
+      notifyPriorityChanged();
+   }
+   virtual ossimPlanetOperation::Priority priority()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return thePriority;
+   }
+   virtual void status(ossimString& result)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      result = theStatus;
+   }
+   virtual void setStatus(const ossimString& value)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         theStatus = value;
+      }
+      notifyPropertyChanged("status");
+   }
+   /**
+    * Since you can have nested dependencies it will go until no more dependencies depend
+    * on other dependencies if the recures flag is true.  If false it will just return the 
+    * first one in the list.
+    */
+   osg::ref_ptr<ossimPlanetOperation> nextDependency(bool recurseFlag=true);
+	virtual void cancel()
+	{
+		setState(CANCELED_STATE);
+	}
+   OpenThreads::Mutex& runMutex(){return theRunMutex;}
+   virtual void reset()
+   {
+		setState(READY_STATE);
+   }
+	virtual void start()
+	{
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRunMutex);
+		setState(RUN_STATE);
+		run();
+		if(state() == RUN_STATE) // if it wasn't canceled or set to some other state then say it has finished
+		{
+			setState(FINISHED_STATE);
+		}
+	}
+protected:
+	void notifyReady();
+	void notifyStarted();
+	void notifyFinished();
+	void notifyCanceled();
+	void notifyPriorityChanged();
+	void notifyPropertyChanged(const ossimString& name);
+   virtual void run()=0;
+	
+   //mutable ossimPlanetReentrantMutex theRunMutex;
+   //mutable ossimPlanetReentrantMutex thePropertyMutex;
+   mutable OpenThreads::Mutex theRunMutex;
+   mutable OpenThreads::Mutex thePropertyMutex;
+   bool theFinishedFlag;
+   bool theCanceledFlag;
+   //mutable ossimPlanetReentrantMutex theDependencyListMutex;
+   mutable OpenThreads::Mutex theDependencyListMutex;
+   ossimPlanetOperation::List theDependencyList;
+   ossimString theName;
+   ossimString theId;
+   ossimString theStatus;
+   ossimPlanetOperation::Priority thePriority;
+	StateType theState;
+};
+
+                                        
+class OSSIMPLANET_DLL ossimPlanetOperationQueue : public osg::Referenced
+{
+public:
+   ossimPlanetOperationQueue();
+   virtual ~ossimPlanetOperationQueue();
+   virtual void add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag=true);
+   osg::ref_ptr<ossimPlanetOperation> removeByName(const ossimString& name);
+   osg::ref_ptr<ossimPlanetOperation> removeById(const ossimString& id);
+   void remove(const ossimPlanetOperation* operation);
+   void removeStoppedOperations();
+   void removeAllOperations();
+   
+   virtual osg::ref_ptr<ossimPlanetOperation> nextOperation(bool blockIfEmptyFlag=true);
+   void releaseOperationsBlock();
+   bool empty()const;
+   ossim_uint32 size()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+      return theOperationQueue.size();
+   }
+protected:
+   ossimPlanetOperation::List::iterator findById(const ossimString& name);
+   ossimPlanetOperation::List::iterator findByName(const ossimString& name);
+   ossimPlanetOperation::List::iterator findByPointer(const ossimPlanetOperation* operation);
+   ossimPlanetOperation::List::iterator findByNameOrPointer(const ossimPlanetOperation* operation);
+   bool hasOperation(ossimPlanetOperation* operation);
+   osg::ref_ptr<ossimPlanetRefBlock> theBlock;
+  
+  // mutable ossimPlanetReentrantMutex theOperationQueueMutex;
+   mutable OpenThreads::Mutex theOperationQueueMutex;
+   ossimPlanetOperation::List theOperationQueue;
+};
+
+class OSSIMPLANET_DLL ossimPlanetOperationPriorityQueue : public ossimPlanetOperationQueue
+{
+public:
+   ossimPlanetOperationPriorityQueue();
+   virtual ~ossimPlanetOperationPriorityQueue();
+   
+   virtual osg::ref_ptr<ossimPlanetOperation> nextOperation(bool blockIfEmptyFlag=true);
+protected:
+   
+};
+
+class OSSIMPLANET_DLL ossimPlanetOperationThreadQueue : public osg::Referenced, 
+                                                        public OpenThreads::Thread
+{
+public:
+   ossimPlanetOperationThreadQueue(ossimPlanetOperationQueue* opq=0);
+   
+   /** Set the OperationQueue. */
+   void setOperationQueue(ossimPlanetOperationQueue* opq);
+   
+   /** Get the OperationQueue. */
+   ossimPlanetOperationQueue* operationQueue() { return theOperationQueue.get(); }
+   
+   /** Get the const OperationQueue. */
+   const ossimPlanetOperationQueue* operationQueue() const { return theOperationQueue.get(); }
+   
+   
+   /** Add operation to end of OperationQueue, this will be 
+    * executed by the graphics thread once this operation gets to the head of the queue.*/
+   void add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag=true);
+   
+   /** Remove operation from OperationQueue.*/
+   void remove(ossimPlanetOperation* operation);
+   
+   /** Remove named operation from OperationQueue.*/
+   osg::ref_ptr<ossimPlanetOperation> removeByName(const ossimString& name);
+   
+   /** Remove id operation from OperationQueue.*/
+   osg::ref_ptr<ossimPlanetOperation> removeById(const ossimString& id);
+   
+   /** Remove all operations from OperationQueue.*/
+   void removeAllOperations();
+   
+   
+   /** Get the operation currently being run.*/
+   osg::ref_ptr<ossimPlanetOperation> currentOperation() { return theCurrentOperation; }
+   
+	void cancelCurrentOperation();
+   /** Run does the opertion thread run loop.*/
+   virtual void run();
+   
+   void setDone(bool done);
+   
+   bool done() const { return theDoneFlag; }
+   
+   /** Cancel this graphics thread.*/        
+   virtual int cancel();
+   bool empty()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+      return theOperationQueue->empty();
+   }
+protected:
+   virtual ~ossimPlanetOperationThreadQueue();
+   virtual osg::ref_ptr<ossimPlanetOperation> nextOperation();
+   
+   bool                                    theDoneFlag;
+   mutable ossimPlanetReentrantMutex       theThreadMutex;
+   osg::ref_ptr<ossimPlanetOperationQueue> theOperationQueue;
+   osg::ref_ptr<ossimPlanetOperation>      theCurrentOperation;
+   
+};
+
+class OSSIMPLANET_DLL ossimPlanetOperationMultiThreadQueue : public osg::Referenced
+{
+public:
+	typedef std::vector<osg::ref_ptr<ossimPlanetOperationThreadQueue> > ThreadQueueList;
+	
+	ossimPlanetOperationMultiThreadQueue(ossim_uint32 numberOfThreads=1);
+	virtual ~ossimPlanetOperationMultiThreadQueue();
+	/** Get the OperationQueue. */
+   ossimPlanetOperationQueue* operationQueue();
+   
+   /** Get the const OperationQueue. */
+   const ossimPlanetOperationQueue* operationQueue() const;	
+   void add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag=true);
+   
+   /** Remove operation from OperationQueue.*/
+   void remove(ossimPlanetOperation* operation);
+   
+   /** Remove named operation from OperationQueue.*/
+   osg::ref_ptr<ossimPlanetOperation> removeByName(const ossimString& name);
+   osg::ref_ptr<ossimPlanetOperation> removeById(const ossimString& id);
+   
+   /** Remove all operations from OperationQueue.*/
+   void removeAllOperations();
+	void cancelCurrentOperation();
+protected:
+   ossimPlanetReentrantMutex             theThreadMutex;
+   osg::ref_ptr<ossimPlanetOperationQueue> theOperationQueue;
+	ThreadQueueList theThreadQueueList;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetOrthoFlatLandNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetOrthoFlatLandNode.h
new file mode 100644
index 0000000..f253bca
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetOrthoFlatLandNode.h
@@ -0,0 +1,26 @@
+#ifndef ossimPlanetOrthoFlatLandNode_HEADER
+#define ossimPlanetOrthoFlatLandNode_HEADER
+#include "ossimPlanetFlatLandNode.h"
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetOrthoFlatLandNode : public ossimPlanetFlatLandNode
+{
+public:
+   ossimPlanetOrthoFlatLandNode(ossim_uint32 level = 0,
+                     ossim_uint32 row   = 0,
+                     ossim_uint32 col   = 0);
+   ossimPlanetOrthoFlatLandNode(const ossimPlanetFlatLandNode& plod,const osg::CopyOp& copyop);
+   virtual ~ossimPlanetOrthoFlatLandNode();
+   virtual osg::Object* cloneType() const { return new ossimPlanetOrthoFlatLandNode(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const
+   {
+      return dynamic_cast<const ossimPlanetOrthoFlatLandNode *>(obj)!=NULL;
+   }
+   virtual const char* className() const { return "OrthoFlatLandNode"; } 
+   virtual const char* libraryName() const { return ""; }
+   virtual void handleCullTraversal(osg::NodeVisitor& nv);
+
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetOssimElevationDatabase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimElevationDatabase.h
new file mode 100644
index 0000000..cde59d3
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimElevationDatabase.h
@@ -0,0 +1,56 @@
+#ifndef ossimPlanetDtedElevationDatabase_HEADER
+#define ossimPlanetDtedElevationDatabase_HEADER
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <ossim/elevation/ossimGeneralRasterElevationDatabase.h>
+#include <ossim/elevation/ossimImageElevationDatabase.h>
+#include <osg/Timer>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/elevation/ossimElevationDatabase.h>
+
+class OSSIMPLANET_DLL ossimPlanetOssimElevationDatabase : public ossimPlanetElevationDatabase
+{
+public:
+   ossimPlanetOssimElevationDatabase();
+   ossimPlanetOssimElevationDatabase(const ossimPlanetOssimElevationDatabase& src);
+   virtual ~ossimPlanetOssimElevationDatabase();
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+   
+   virtual ossimPlanetTextureLayerStateCode open(const std::string& location);
+   virtual void setDatabase(ossimElevationDatabase* database)
+   {
+      m_database = database;
+      m_cellDatabaseFlag = ((!dynamic_cast<ossimGeneralRasterElevationDatabase*>(database) &&
+                             !dynamic_cast<ossimImageElevationDatabase*>(database))&&
+                            ((dynamic_cast<ossimElevationCellDatabase*>(database) != 0)));
+      updateExtents();
+   }
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& grid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& grid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 /* level */,
+                                                     ossim_uint64 /* row */,
+                                                     ossim_uint64 /* col */,
+                                                     const ossimPlanetGridUtility& /* utility */)
+   {
+      return 0;
+   }
+protected:
+   virtual osg::ref_ptr<ossimPlanetImage> getTextureCellDatabase(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& grid,
+                                                     ossim_int32 padding=0);
+   bool                                m_cellDatabaseFlag;
+   ossimRefPtr<ossimElevationDatabase> m_database;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImage.h b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImage.h
new file mode 100644
index 0000000..e5aadfd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImage.h
@@ -0,0 +1,21 @@
+#ifndef ossimPlanetOssimImage_HEADER
+#define ossimPlanetOssimImage_HEADER
+#include <iostream>
+#include "ossimPlanetExport.h"
+#include <osg/Referenced>
+#include <ossim/imaging/ossimImageHandler.h>
+
+class ossimPlanetImage;
+class OSSIMPLANET_DLL ossimPlanetOssimImage : public osg::Referenced
+{
+public:
+   ossimPlanetOssimImage();
+   virtual ~ossimPlanetOssimImage();
+   bool loadFile(const std::string& inputFile,
+                 ossimPlanetImage& image);
+
+protected:
+   ossimRefPtr<ossimImageHandler> theHandler;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImageLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImageLayer.h
new file mode 100644
index 0000000..a5fe5c8
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetOssimImageLayer.h
@@ -0,0 +1,370 @@
+#ifndef ossimPlanetOssimImageLayer_HEADER
+#define ossimPlanetOssimImageLayer_HEADER
+#include "ossimPlanetTextureLayer.h"
+#include <osg/Referenced>
+#include "ossimPlanetId.h"
+#include "ossimPlanetExport.h"
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/imaging/ossimImageRenderer.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/projection/ossimEquDistCylProjection.h>
+#include <ossim/imaging/ossimGeoAnnotationSource.h>
+#include <ossim/imaging/ossimGeoAnnotationPolyObject.h>
+#include <ossim/imaging/ossimHistogramRemapper.h>
+#include <ossim/imaging/ossimRectangleCutFilter.h>
+#include <ossim/elevation/ossimElevManager.h>
+#include <ossim/projection/ossimLlxyProjection.h>
+#include <queue>
+class OSSIMPLANET_DLL ossimPlanetOssimImageLayer : public ossimPlanetTextureLayer
+{
+public:
+   ossimPlanetOssimImageLayer();
+   ossimPlanetOssimImageLayer(const ossimPlanetOssimImageLayer& src);
+   ossimPlanetTextureLayerStateCode openImage(const ossimFilename& filename, ossim_int32 entryIdx = -1);
+   ossimPlanetTextureLayerStateCode setCurrentEntry(ossim_int32 idx);
+   ossim_uint32 getNumberOfEntries()const;
+   void setOverviewFile(const ossimFilename& overviewFile);
+   void setHistogramFile(const ossimFilename& histogram);
+   void setHistogramStretchMode(const ossimString& mode);
+   void setHistogramStretchEnableFlag(bool flag);
+   bool histogramStretchEnableFlag()const;
+   ossimString histogramStretchMode()const;
+   void getHistogramStretchModes(std::vector<ossimString>& modes);
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimString getClassName()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+   ossimScalarType scalarType()const;
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& grid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+  virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+   ossimPlanetTextureLayerStateCode setHandler(ossimRefPtr<ossimImageHandler> handler);
+   ossimRefPtr<ossimImageHandler> getHandler();
+   const ossimRefPtr<ossimImageHandler> getHandler()const;
+   
+   virtual double getApproximateHypotneusLength()const;
+   virtual void getCenterLatLonLength(double& centerLat,
+                                      double& centerLon,
+                                      double& length)const;
+   void setFilterType(const ossimString& filterType);
+
+   bool isMultiEntry()const;
+
+   virtual bool buildOverview();
+   
+   osg::ref_ptr<ossimPlanetTextureLayer> groupAllEntries();
+   virtual void getMetadata(ossimRefPtr<ossimXmlNode> metadata)const;
+
+   virtual ossimRefPtr<ossimXmlNode> saveXml(bool recurseFlag=true)const;
+   virtual bool loadXml(ossimRefPtr<ossimXmlNode> node);
+   
+protected:
+   struct ResamplePoint
+   {
+   public:
+      friend ostream& operator <<(ostream& out, const ResamplePoint& point)
+      {
+         out << point.theGlobalNdcPoint << "\n"
+         << point.theModelPoint << "\n"
+         << point.theImagePoint << "\n"
+         << point.theTileImagePoint << "\n"
+         << point.theDecimation << "\n"
+         << point.theResolutionLevel;
+         
+         return out;
+      }
+      ResamplePoint(){}
+      ResamplePoint(const ossimPlanetGrid::GridPoint& globalPoint,
+                    const ossimPlanetGrid::ModelPoint& modelPt,
+                    const ossimDpt& imgPt,
+                    const ossimDpt& tileImgPt,
+                    const ossimDpt& decimation,
+                    ossim_uint32 rLevel)
+      :theGlobalNdcPoint(globalPoint),
+      theModelPoint(modelPt),
+      theImagePoint(imgPt),
+      theTileImagePoint(tileImgPt),
+      theDecimation(decimation),
+      theResolutionLevel(rLevel)
+      {}
+      ossimPlanetGrid::GridPoint  theGlobalNdcPoint;
+      ossimPlanetGrid::ModelPoint theModelPoint;
+      ossimDpt                    theImagePoint;
+      ossimDpt                    theTileImagePoint;
+      ossimDpt                    theDecimation;
+      ossim_uint32                theResolutionLevel;
+   };
+   struct ResampleCorner
+   {
+   public:
+      friend std::ostream& operator <<(std::ostream& out, const ResampleCorner& corners)
+      {
+         out << corners.theP1 << "\n" << corners.theP2 << "\n" 
+             << corners.theP3 << "\n" << corners.theP4; 
+         
+         return out;
+      }
+     ResampleCorner(){}
+      ResampleCorner(const ResamplePoint& p1, 
+                     const ResamplePoint& p2,
+                     const ResamplePoint& p3,
+                     const ResamplePoint& p4)
+      :theP1(p1),
+      theP2(p2),
+      theP3(p3),
+      theP4(p4)
+      {}
+      bool canBilinearInterpolate(ossimProjection* proj,
+                                  const ossimPlanetGrid& grid)const
+      {
+         ossimPlanetGrid::GridPoint globalGridCenter(theP1.theGlobalNdcPoint.face(),
+                                                     (theP1.theGlobalNdcPoint.x()+
+                                                      theP2.theGlobalNdcPoint.x()+
+                                                      theP3.theGlobalNdcPoint.x()+
+                                                      theP4.theGlobalNdcPoint.x())*.25,
+                                                     (theP1.theGlobalNdcPoint.y()+
+                                                      theP2.theGlobalNdcPoint.y()+
+                                                      theP3.theGlobalNdcPoint.y()+
+                                                      theP4.theGlobalNdcPoint.y())*.25);
+         ossimDpt inputImageCenter((theP1.theImagePoint.x + 
+                                    theP2.theImagePoint.x +
+                                    theP3.theImagePoint.x +
+                                    theP4.theImagePoint.x)*.25,
+                                   (theP1.theImagePoint.y + 
+                                    theP2.theImagePoint.y +
+                                    theP3.theImagePoint.y +
+                                    theP4.theImagePoint.y)*.25);
+         
+              
+         ossimPlanetGrid::ModelPoint centerModel;
+         ossimDpt centerImageTest;
+         grid.globalGridToModel(globalGridCenter, centerModel);
+         ossimGpt gpt(centerModel.y(),
+                     centerModel.x());
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         proj->worldToLineSample(gpt, 
+                                 centerImageTest);
+         double errorMetric = (inputImageCenter-centerImageTest).length();
+         
+         //std::cout << "face == " << theP1.theGlobalNdcPoint.face() << std::endl;
+         //std::cout << "ERROR == " << errorMetric << std::endl;
+         return (errorMetric<1.0);
+      }
+      ossim_uint32 tileWidth()const
+      {
+         return (theP1.theTileImagePoint - theP2.theTileImagePoint).length();
+      }
+      ossim_uint32 tileHeight()const
+      {
+         return (theP1.theTileImagePoint - theP4.theTileImagePoint).length();
+      }
+      ossimDrect boundingInputImageRect()const
+      {
+         return ossimDrect(ossim::min(theP1.theImagePoint.x, 
+                                      ossim::min(theP2.theImagePoint.x, 
+                                                 ossim::min(theP3.theImagePoint.x, theP4.theImagePoint.x))),
+                           ossim::max(theP1.theImagePoint.y, 
+                                      ossim::max(theP2.theImagePoint.y, 
+                                                 ossim::max(theP3.theImagePoint.y, theP4.theImagePoint.y))),
+                           ossim::max(theP1.theImagePoint.x, 
+                                      ossim::max(theP2.theImagePoint.x, 
+                                                 ossim::max(theP3.theImagePoint.x, theP4.theImagePoint.x))),
+                           ossim::min(theP1.theImagePoint.y, 
+                                      ossim::min(theP2.theImagePoint.y, 
+                                                 ossim::min(theP3.theImagePoint.y, theP4.theImagePoint.y))),
+                           OSSIM_RIGHT_HANDED);
+      }
+
+     ossimDrect boundingInputImageRect(const ossimDpt& decimation)const
+      {
+         return boundingInputImageRect()*decimation;
+      }
+      void split(ossimProjection* proj,
+                 const ossimPlanetGrid& grid,
+                 ResampleCorner& bound1,
+                 ResampleCorner& bound2,
+                 ResampleCorner& bound3,
+                 ResampleCorner& bound4)
+      {
+         // use parametric to split along each line going in
+         // counter clockwise for the edges.
+         //
+         
+         //
+         ossimPlanetGrid::ModelPoint model;
+         ResamplePoint centerP1P2;
+         ResamplePoint centerP2P3;
+         ResamplePoint centerP3P4;
+         ResamplePoint centerP4P1;
+         ResamplePoint centerPt;
+         
+         centerP1P2.theGlobalNdcPoint.theFace = theP1.theGlobalNdcPoint.theFace;
+         centerP2P3.theGlobalNdcPoint.theFace = theP1.theGlobalNdcPoint.theFace;
+         centerP3P4.theGlobalNdcPoint.theFace = theP1.theGlobalNdcPoint.theFace;
+         centerP4P1.theGlobalNdcPoint.theFace = theP1.theGlobalNdcPoint.theFace;
+         centerPt.theGlobalNdcPoint.theFace   = theP1.theGlobalNdcPoint.theFace;
+         
+
+       
+         centerP1P2.theGlobalNdcPoint.setX((theP2.theGlobalNdcPoint.x()+theP1.theGlobalNdcPoint.x())*.5);
+         centerP1P2.theGlobalNdcPoint.setY(theP1.theGlobalNdcPoint.y());
+         centerP1P2.theTileImagePoint.x   = (ossim_int32)((theP2.theTileImagePoint.x+theP1.theTileImagePoint.x)*.5);
+         centerP1P2.theTileImagePoint.y   = (ossim_int32)theP2.theTileImagePoint.y;
+         centerP1P2.theDecimation = theP1.theDecimation;
+         centerP1P2.theResolutionLevel = theP1.theResolutionLevel;
+         grid.globalGridToModel(centerP1P2.theGlobalNdcPoint, model);
+         ossimGpt gpt(model.y(),
+                      model.x());
+         
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         //std::cout << "class = " << proj->getClassName() << std::endl;
+         //std::cout << "gpt = " << gpt << std::endl;
+         proj->worldToLineSample(gpt, 
+                                 centerP1P2.theImagePoint);
+         
+         centerP2P3.theGlobalNdcPoint.setX(theP2.theGlobalNdcPoint.x()); 
+         centerP2P3.theGlobalNdcPoint.setY((theP3.theGlobalNdcPoint.y()+theP2.theGlobalNdcPoint.y())*.5);
+         centerP2P3.theTileImagePoint.x   = theP2.theTileImagePoint.x;
+         centerP2P3.theTileImagePoint.y   = (ossim_int32)((theP2.theTileImagePoint.y+theP3.theTileImagePoint.y)*.5);
+         centerP2P3.theDecimation = theP2.theDecimation;
+         centerP2P3.theResolutionLevel = theP2.theResolutionLevel;
+         grid.globalGridToModel(centerP2P3.theGlobalNdcPoint, model);
+         gpt = ossimGpt(model.y(),
+                        model.x());
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         proj->worldToLineSample(gpt, 
+                                 centerP2P3.theImagePoint);
+         
+         
+         centerP3P4.theGlobalNdcPoint.setX((theP4.theGlobalNdcPoint.x()+theP3.theGlobalNdcPoint.x())*.5);
+         centerP3P4.theGlobalNdcPoint.setY(theP3.theGlobalNdcPoint.y());
+         centerP3P4.theTileImagePoint.x   = (ossim_int32)((theP3.theTileImagePoint.x+theP4.theTileImagePoint.x)*.5);
+         centerP3P4.theTileImagePoint.y   = theP3.theTileImagePoint.y;
+         centerP3P4.theDecimation = theP3.theDecimation;
+         centerP3P4.theResolutionLevel = theP3.theResolutionLevel;
+         grid.globalGridToModel(centerP3P4.theGlobalNdcPoint, model);
+         gpt = ossimGpt(model.y(),
+                        model.x());
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         proj->worldToLineSample(gpt, 
+                                 centerP3P4.theImagePoint);
+
+      
+         centerP4P1.theGlobalNdcPoint.setX(theP1.theGlobalNdcPoint.x());
+         centerP4P1.theGlobalNdcPoint.setY((theP1.theGlobalNdcPoint.y()+theP4.theGlobalNdcPoint.y())*.5);
+         centerP4P1.theTileImagePoint.x   = theP1.theTileImagePoint.x;
+         centerP4P1.theTileImagePoint.y   = (ossim_int32)((theP1.theTileImagePoint.y + theP4.theTileImagePoint.y)*.5);
+         centerP4P1.theDecimation = theP4.theDecimation;
+         centerP4P1.theResolutionLevel = theP4.theResolutionLevel;
+         grid.globalGridToModel(centerP4P1.theGlobalNdcPoint, model);
+         gpt = ossimGpt(model.y(),
+                        model.x());
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         proj->worldToLineSample(gpt, 
+                                 centerP4P1.theImagePoint);
+         
+         centerPt.theGlobalNdcPoint.setX(centerP1P2.theGlobalNdcPoint.x());         
+         centerPt.theGlobalNdcPoint.setY(centerP4P1.theGlobalNdcPoint.y());       
+         centerPt.theTileImagePoint.x = centerP1P2.theTileImagePoint.x;
+         centerPt.theTileImagePoint.y = centerP4P1.theTileImagePoint.y;
+         grid.globalGridToModel(centerPt.theGlobalNdcPoint, model);
+         gpt = ossimGpt(model.y(),
+                        model.x());
+         if(proj->isAffectedByElevation())
+         {
+            gpt.height(ossimElevManager::instance()->getHeightAboveEllipsoid(gpt));
+         }
+         proj->worldToLineSample(gpt, 
+                                 centerPt.theImagePoint);
+         centerPt.theDecimation      = theP4.theDecimation;
+         centerPt.theResolutionLevel = theP4.theResolutionLevel;
+        
+         bound1.theP1 = theP1;
+         bound1.theP2 = centerP1P2;
+         bound1.theP3 = centerPt;
+         bound1.theP4 = centerP4P1;
+         
+         bound2.theP1 = centerP1P2;
+         bound2.theP2 = theP2;
+         bound2.theP3 = centerP2P3;
+         bound2.theP4 = centerPt;
+         
+         bound3.theP1 = centerPt;
+         bound3.theP2 = centerP2P3;
+         bound3.theP3 = theP3;
+         bound3.theP4 = centerP3P4;
+         
+         bound4.theP1 = centerP4P1;
+         bound4.theP2 = centerPt;
+         bound4.theP3 = centerP3P4;
+         bound4.theP4 = theP4;
+      }
+      ResamplePoint theP1;
+      ResamplePoint theP2;
+      ResamplePoint theP3;
+      ResamplePoint theP4;
+   };
+   typedef std::queue<ResampleCorner> ResampleCorners;
+   virtual ~ossimPlanetOssimImageLayer();
+   void clearChains();
+   virtual ossimPlanetTextureLayerStateCode updateExtentsNoMutex();
+   ossimPlanetTextureLayerStateCode buildChain();
+   
+   void initializeResamplePoints(const ossimPlanetTerrainTileId& tileId,
+                                 const ossimPlanetGrid& grid,
+                                 ossim_uint32 tileWidth,
+                                 ossim_uint32 tileHeight,
+                                 ResampleCorners& corners);
+                                 
+   ossimFilename                               theFilename;
+   ossimFilename                               theOverviewFile;
+   ossimFilename                               theHistogramFile;
+   ossimRectangleCutFilter*                    theCut;
+   mutable ossimRefPtr<ossimImageHandler>      theSource;
+   ossimRefPtr<ossimImageRenderer>             theRenderer;
+   ossimViewInterface*                         theViewInterface;
+   ossimHistogramRemapper*                     theHistogramRemapper;
+   ossimHistogramRemapper::StretchMode         theHistogramStretchMode;
+   bool                                        theHistogramStretchEnableFlag;
+   std::vector<ossimRefPtr<ossimImageSource> > theChain;
+   std::vector<ossimRefPtr<ossimImageSource> > theImageSpaceChain;
+   //   ossimRefPtr<ossimEquDistCylProjection>      theProjection;
+   ossimRefPtr<ossimImageGeometry>  theImageGeometry;
+   ossimRefPtr<ossimMapProjection>      theProjection;
+   ossimRefPtr<ossimProjection>                theInputProjection;
+   mutable double theCenterLat;
+   mutable double theCenterLon;
+   mutable double theLength;                   // approximate length in meters of the diagonal image
+   mutable OpenThreads::Mutex         theOssimImageLayerMutex;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLod.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLod.h
new file mode 100644
index 0000000..395fa7f
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLod.h
@@ -0,0 +1,199 @@
+#ifndef ossimPlanetPagedLandLod_HEADER
+#define ossimPlanetPagedLandLod_HEADER
+#include <osg/NodeVisitor>
+#include <osg/Group>
+#include <osg/PagedLOD>
+#include <osg/MatrixTransform>
+#include <osg/Geometry>
+#include <OpenThreads/ScopedLock>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include "ossimPlanet/ossimPlanetBoundingBox.h"
+#include <ossimPlanet/ossimPlanetLandTextureRequest.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetPagedLandLodCullNode : public osg::MatrixTransform
+{
+public:
+   ossimPlanetPagedLandLodCullNode():
+      osg::MatrixTransform(),
+      theCulledFlag(false)
+   {}
+      ossimPlanetPagedLandLodCullNode(osg::ref_ptr<ossimPlanetBoundingBox> boundingBox,
+                                      bool useClusterCulling,
+                                      const osg::Vec3d& clusterCullingControlPoint,
+                                      const osg::Vec3d& clusterCullingNormal,
+                                      double clusterCullingDeviation,
+                                      double clusterCullingRadius):
+         osg::MatrixTransform(),
+         theCulledFlag(false),
+         theBoundingBox(boundingBox),
+         theUseClusterCulling(useClusterCulling),
+         theClusterCullingControlPoint(clusterCullingControlPoint),
+         theClusterCullingNormal(clusterCullingNormal),
+         theClusterCullingDeviation(clusterCullingDeviation),
+         theClusterCullingRadius(clusterCullingRadius)
+   {}
+   ossimPlanetPagedLandLodCullNode(const ossimPlanetPagedLandLodCullNode& src):
+      osg::MatrixTransform(src),
+      theCulledFlag(src.theCulledFlag),
+      theBoundingBox(new ossimPlanetBoundingBox(*src.theBoundingBox)),
+      theUseClusterCulling(src.theUseClusterCulling),
+      theClusterCullingControlPoint(src.theClusterCullingControlPoint),
+      theClusterCullingNormal(src.theClusterCullingNormal),
+      theClusterCullingDeviation(src.theClusterCullingDeviation),
+      theClusterCullingRadius(src.theClusterCullingRadius)
+   {
+   }
+   void setBoundingBox(osg::ref_ptr<ossimPlanetBoundingBox> box)
+   {
+      theBoundingBox = box.get();
+   }
+   
+   const ossimPlanetBoundingBox* boundingBox()const
+   {
+      return theBoundingBox.get();
+   }
+   double eyeDistance()const
+   {
+      return theEyeDistance;
+   }
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   bool isCulled()const
+   {
+      return theCulledFlag;
+   }
+  
+protected:
+   bool theCulledFlag;
+   osg::ref_ptr<ossimPlanetBoundingBox> theBoundingBox;
+   bool theUseClusterCulling;
+   osg::Vec3d theClusterCullingControlPoint;
+   osg::Vec3d theClusterCullingNormal;
+   double theClusterCullingDeviation;
+   double theClusterCullingRadius;
+
+   double theEyeDistance;
+};
+
+class ossimPlanetLandCullCallback;
+class ossimPlanetLand;
+class OSSIMPLANET_EXPORT ossimPlanetPagedLandLod : public osg::Group//public osg::PagedLOD
+{
+public:
+
+   friend class ossimPlanetLandCullCallback;
+   friend class ossimPlanetPagedLandLodUpdateCallback;
+   friend class ossimPlanetLandReaderWriter;
+   friend class ossimPlanetPagedLandLodClearPointers;
+
+   virtual osg::Object* cloneType() const { return new ossimPlanetPagedLandLod(); }
+   virtual osg::Object* clone(const osg::CopyOp& copyop) const
+   {
+      return new ossimPlanetPagedLandLod(*this,copyop);
+   }
+   virtual bool isSameKindAs(const osg::Object* obj) const
+   {
+      return dynamic_cast<const ossimPlanetPagedLandLod *>(obj)!=0;
+   }
+   virtual const char* className() const { return "PlanetPagedLandLod"; }
+   virtual const char* libraryName() const { return ""; }
+   ossimPlanetPagedLandLod(ossim_uint32 level=0,
+                         ossim_uint32 row=0,
+                         ossim_uint32 col=0,
+                         const std::string& requestName="");
+   ossimPlanetPagedLandLod(const ossimPlanetPagedLandLod& src,
+                         const osg::CopyOp& copyop);
+    virtual ~ossimPlanetPagedLandLod();
+    void setRequestName(ossim_uint32 idx,
+                          const std::string& name)
+    {
+      theRequestNameList[idx] = name;
+   }
+   std::string getRequestName(ossim_uint32 idx)const
+   {
+      return theRequestNameList[idx];
+   }
+   bool getRemoveChildrenFlag()const
+   {
+      return theRemoveChildrenFlag;
+   }
+   bool getCulledFlag()const
+   {
+      return theCulledFlag;
+   }
+
+   virtual bool addChild( Node *child );
+
+   ossim_uint32 getLevel()const
+      {
+         return theLevel;
+      }
+   ossim_uint32 getRow()const
+      {
+         return theRow;
+      }
+   ossim_uint32 getCol()const
+      {
+         return theCol;
+      }
+   bool isLeaf()const
+   {
+      return (getNumChildren() != 5);
+   }
+   bool hasCulledChildren()const;
+   bool areAllChildrenCulled(bool applyToAddedChildrenOnly=false)const;
+   bool areAllChildrenLeaves()const;
+   OpenThreads::Mutex& mutex()const
+   {
+      return theMutex;
+   }
+
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   void setRefreshType(ossimPlanetLandRefreshType refreshType);
+   ossimPlanetLandRefreshType refreshType()const;
+protected:
+   ossimPlanetLand* landLayer();
+   const ossimPlanetLand* landLayer()const;
+
+   osg::ref_ptr<osg::Geode> theGeode;
+   ossim_uint32 theLevel;
+   ossim_uint32 theRow;
+   ossim_uint32 theCol;
+/*    osg::ref_ptr<ossimPlanetBoundingBox> theBoundingBox; */
+   std::vector<std::string> theRequestNameList;
+   osg::ref_ptr<osg::Referenced> theRequestRefChildList[4];
+   osg::ref_ptr<osg::Referenced> theRequestRef;
+   bool theCulledFlag;
+   bool theRemoveChildrenFlag;
+   ossimPlanetLandRefreshType theRefreshType;
+   mutable ossimPlanetReentrantMutex theMutex;
+   mutable ossimPlanetReentrantMutex thePagedLodListMutex;
+   mutable ossimPlanetReentrantMutex theChildCullNodeListMutex;
+   mutable ossimPlanetReentrantMutex theTextureRequestMutex;
+   osg::ref_ptr<ossimPlanetPagedLandLodCullNode> theCullNode;
+      
+/*    osg::Node* theTransform; */
+   ossim_uint32 theMaxLevel;
+   osg::Vec3d theCenterPoint;
+   osg::Vec3d theUlPoint;
+   osg::Vec3d theUrPoint;
+   osg::Vec3d theLrPoint;
+   osg::Vec3d theLlPoint;
+   osg::Vec3d theCenterNormal;
+   osg::Vec3d theUlNormal;
+   osg::Vec3d theUrNormal;
+   osg::Vec3d theLrNormal;
+   osg::Vec3d theLlNormal;
+
+   
+// lists to add during update calls
+   //
+   std::vector<osg::ref_ptr<ossimPlanetPagedLandLod> >          thePagedLodList;
+   std::vector<osg::ref_ptr<ossimPlanetPagedLandLodCullNode> >  theChildCullNodeList;
+   osg::ref_ptr<ossimPlanetLandTextureRequest>                  theTextureRequest;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLodRefreshType.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLodRefreshType.h
new file mode 100644
index 0000000..615953b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedLandLodRefreshType.h
@@ -0,0 +1,16 @@
+#ifndef ossimPlanetPagedLandLodRefreshType_HEADER
+#define ossimPlanetPagedLandLodRefreshType_HEADER
+
+// Been moved to ossimPlanetConstants.h
+// This file is deprecated
+#error File header depcricated, plaese use ossimPlanet/ossimPlanetConstants.h
+
+/* enum ossimPlanetPagedLandLodRefreshType */
+/* { */
+/*    ossimPlanetPagedLandLodRefreshType_NONE    = 0, */
+/*    ossimPlanetPagedLandLodRefreshType_TEXTURE = 1, */
+/*    ossimPlanetPagedLandLodRefreshType_GEOM    = 2, */
+/*    ossimPlanetPagedLandLodRefreshType_PRUNE   = 3, */
+/* }; */
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPagedRequestNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedRequestNode.h
new file mode 100644
index 0000000..365e7f1
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPagedRequestNode.h
@@ -0,0 +1,70 @@
+#ifndef ossimPlanetPagedRequestNode_HEADER
+#define ossimPlanetPagedRequestNode_HEADER
+#include <osg/Node>
+#include <osg/ref_ptr>
+#include <osg/Texture2D>
+#include <ossim/base/ossimConstants.h>
+#include <iostream>
+#include "ossimPlanetElevationGrid.h"
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetPagedRequestNode : public osg::Node
+{
+public:
+   ossimPlanetPagedRequestNode(ossim_uint32 level=0,
+                             ossim_uint32 row=0,
+                             ossim_uint32 col=0,
+                             osg::ref_ptr<osg::Texture2D> texture=0)
+      :osg::Node(),
+      theLevel(level),
+      theRow(row),
+      theCol(col),
+      theTexture(texture)
+      {
+      }
+   virtual ~ossimPlanetPagedRequestNode()
+      {
+      }
+   osg::ref_ptr<osg::Texture2D> getTexture()
+      {
+         return theTexture;
+      }
+   osg::ref_ptr<ossimPlanetElevationGrid> getElevation()
+   {
+      return theElevationGrid;
+   }
+   const osg::ref_ptr<ossimPlanetElevationGrid> getElevation()const
+   {
+      return theElevationGrid;
+   }
+   void setElevation(osg::ref_ptr<ossimPlanetElevationGrid> elevationGrid)
+   {
+      theElevationGrid = elevationGrid;
+   }
+   void setTexture(osg::ref_ptr<osg::Texture2D> texture)
+      {
+         theTexture = texture;
+      }
+   ossim_uint32 getLevel()const
+      {
+         return theLevel;
+      }
+   ossim_uint32 getRow()const
+      {
+         return theRow;
+      }
+   ossim_uint32 getCol()const
+      {
+         return theCol;
+      }
+   
+   
+protected:
+   ossim_uint32 theLevel;
+   ossim_uint32 theRow;
+   ossim_uint32 theCol;
+   osg::ref_ptr<osg::Texture2D> theTexture;
+   osg::ref_ptr<ossimPlanetElevationGrid> theElevationGrid;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPlaneGrid.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPlaneGrid.h
new file mode 100644
index 0000000..582ce21
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPlaneGrid.h
@@ -0,0 +1,28 @@
+#ifndef ossimPlanetPlaneGrid_HEADER
+#define ossimPlanetPlaneGrid_HEADER
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+
+class OSSIMPLANET_DLL ossimPlanetPlaneGrid : public ossimPlanetGridUtility
+{
+public:
+   ossimPlanetPlaneGrid(ossim_uint32 tileWidth = 256,
+                        ossim_uint32 tileHeight = 256)
+      :ossimPlanetGridUtility(tileWidth, tileHeight)
+   {
+   }
+   virtual ossim_uint32 getNumberOfFaces()const;
+   virtual void getPixelScale(double& dx,
+                              double& dy,
+                              ossimUnitType& pixelScaleUnits,
+                              ossim_uint32 level,
+                              ossim_uint64 row,
+                              ossim_uint64 col)const;
+
+   virtual void getGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                             const osg::Vec3d& latLon)const;
+
+   virtual void getLatLon(osg::Vec3d& latLon,
+                          const ossimPlanetGridUtility::GridPoint& gridPoint)const;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPointModel.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPointModel.h
new file mode 100644
index 0000000..0435068
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPointModel.h
@@ -0,0 +1,150 @@
+#ifndef ossimPlanetPointModel_HEADER
+#define ossimPlanetPointModel_HEADER
+#include <ossimPlanet/ossimPlanetAnnotationLayerNode.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetLsrSpaceTransform.h>
+
+/**
+ * This will be the root class to handle all point based models.  
+ * Typically this may pertain to buildings or other 3-D
+ * point models.  This will also own an ossimLsrSpaceTransform that 
+ * allows one to talk to the Matrix transform in a common Euler orientation
+ * and lat lon altitude placement and scale settings.  The Lsr stands for Local Space
+ * Reference and mirrors the conepts in the ossim core engine.
+ *
+ * Caveat:  If the setMatrix is called on a MatrixTransform which is a base of
+ *          ossimPlanetLsrSpaceTransform then it will not sync the euler and lat lon paramters
+ *          until the next call to computeBound.  Note setMatrix will dirty the bound.  So if you want immediate
+ *          sync to occurr then you must manually say getBound immediately after a setMatrix.  This should
+ *          force a recompute.
+ *
+ *
+ * <pre>
+ *  EXAMPLE USAGE:
+ *  We will assume we have an annotation layer defined in ossimPlanetViewer and will access through the Viewer
+ *  
+ *  osg::ref_ptr<ossimPlanetPointModel> pointModel = new ossimPlanetPointModel;
+ *  // adding the object should automatically setup the pointers for model and layer on the Node.
+ *  viewer->addAnnotation(pointModel.get());
+ *
+ *  // node is some local 3-D comdel that you wish to posistion.
+ *  pointModel->setNode(node);
+ * 
+ * // set the point at 25 degrees lat, -120 degrees lon and 5000 meters above the ellipsoid.  Note this call
+ * // assumes ellipsoidal height.  Use mean sea level call for heights above the geoidal egm grid.
+ *  pointModel->lsrSpace()->setLatLonAltitude(osg::Vec3d(25.0, -120, 5000));
+ * 
+ *
+ * </pre>
+ */
+class OSSIMPLANET_DLL ossimPlanetPointModel : public ossimPlanetAnnotationLayerNode
+{
+public:
+   class LsrSpaceCallback : public ossimPlanetLsrSpaceTransformCallback
+   {
+   public:
+      LsrSpaceCallback(ossimPlanetPointModel* model)
+      :thePointModel(model)
+      {
+      }
+      virtual void lsrSpaceChanged(ossimPlanetLsrSpaceTransform* /*lsrSpace*/)
+      {
+         if(thePointModel)
+         {
+            thePointModel->dirtyBound();
+            thePointModel->setRedrawFlag(true);
+         }
+      }
+   protected:
+      ossimPlanetPointModel* thePointModel;
+   };
+   ossimPlanetPointModel();
+   virtual ~ossimPlanetPointModel();
+   
+   /**
+    * For now we will do nothing for the update.  This is reserved for future background operations on a node
+    * to update itself.  It iwll be up to the node's responsibility to update only its dirty components.  Note
+    *  this is not synched to the Update Visitor but this virtual method is an interface to an UpdateOperation.
+    */
+   virtual void update(){}
+   
+   
+   /**
+    * It will keep in sync during the update stage the node this point model is 
+    * controlling with a LsrSpace transform.
+    *
+    * @param nv Node visitor base for all visitors.
+    */
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+   /**
+    * This will be the point model controlled by this class.  
+    * During the update traversal it will be aded to the ossimPlanetLsrSpaceTransform
+    *
+    * @param node This node is assumed to be relative values from the LsrSpaceTransform
+    */
+   void setNode(osg::Node* node);
+   
+   /**
+    * @return Returns a constant reference to a Local Space Reference for this point model.
+    */
+   const ossimPlanetLsrSpaceTransform* lsrSpace()const{return theLsrSpaceTransform.get();}
+   
+   /**
+    * @return Returns a reference to a Local Space Reference for this point model.
+    */
+   ossimPlanetLsrSpaceTransform* lsrSpace(){return theLsrSpaceTransform.get();}
+   
+   /**
+    * This Will copy the LSR parameters.
+    *
+    * @param lsr  The Local Space Reference to copy the parameters from.
+    */
+   void copyLsrSpaceParameters(const ossimPlanetLsrSpaceTransform& lsr);
+   
+   /**
+    * overrides set layer so we can pass the model immediatley to the Local Space Reference
+    * transform.
+    *
+    * @param layer The ossimPlanetLayer we are part of.
+    */
+   virtual void setLayer(ossimPlanetLayer* layer);
+   
+   virtual osg::BoundingSphere computeBound()const
+   {
+      if(theLsrSpaceTransform.valid())
+      {
+         return theLsrSpaceTransform->computeBound();
+      }
+      return osg::BoundingSphere(osg::Vec3d(0.0,0.0,0.0), -1);
+   }
+protected:
+   /**
+    * Checks if the required pointers are set.  Will see if layer and model exist.
+    */
+   bool checkPointers();
+   
+   /**
+    * General mutex to sync access to the parameters with other threads.
+    */
+   ossimPlanetReentrantMutex thePointModelPropertyMutex;
+   
+   /**
+    * The Local space node will be added to the LsrSpace transform.
+    */
+   osg::ref_ptr<ossimPlanetLsrSpaceTransform> theLsrSpaceTransform;
+   
+   /**
+    * Indication that we need to update the matrix transform to encapsulate the node.
+    */
+   bool                    theNodeChangedFlag;
+   
+   /**
+    * Direct access to the node that is a child of MatrixTransform.
+    */
+   osg::ref_ptr<osg::Node> theNode;
+   
+   osg::ref_ptr<LsrSpaceCallback> theLsrSpaceCallback;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPredatorVideoLayerNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPredatorVideoLayerNode.h
new file mode 100644
index 0000000..c403e4c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPredatorVideoLayerNode.h
@@ -0,0 +1,264 @@
+#ifndef ossimPlanetPredatorVideoLayerNode_HEADER
+#define ossimPlanetPredatorVideoLayerNode_HEADER
+#include "ossimPlanetVideoLayerNode.h"
+#include "ossimPlanetIconGeom.h"
+#include "ossimPlanetRefBlock.h"
+#include <ossimPredator/ossimPredatorVideo.h>
+#include "ossimPlanetBillboardIcon.h"
+#include "ossimPlanetGeoRefModel.h"
+#include <osg/ImageStream>
+#include <osg/Timer>
+#include <osg/Viewport>
+#include <osg/CameraNode>
+#include <osg/MatrixTransform>
+#include <osg/Geode>
+#include <OpenThreads/Thread>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <OpenThreads/ScopedLock>
+#include <OpenThreads/Block>
+#include <osg/Switch>
+
+class OSSIMPLANET_DLL ossimPlanetFFMpegImageStream :  public osg::ImageStream, public OpenThreads::Thread
+{
+public:
+   
+   class  OSSIMPLANET_DLL CoordinateInfo : public osg::Referenced
+   {
+   public:
+      CoordinateInfo()
+      :theFrameCenterLlhValidFlag(true),
+      theSensorPositionLlhValidFlag(true),
+      theOrientationMatrixValidFlag(true),
+      theTargetWidthInMetersValidFlag(true),
+      theTargetWidthInMeters(0.0),
+      theSlantRangeValidFlag(true),
+      theSlantRange(0.0),
+      theReferenceTime(0.0),
+      theClock(0.0)
+      {
+      }
+      CoordinateInfo(const CoordinateInfo& src)
+         :theFrameCenterLlhValidFlag(src.theFrameCenterLlhValidFlag),
+          theFrameCenterLlh(src.theFrameCenterLlh),
+          theSensorPositionLlhValidFlag(src.theSensorPositionLlhValidFlag),
+          theSensorPositionLlh(src.theSensorPositionLlh),
+          theOrientationMatrixValidFlag(src.theOrientationMatrixValidFlag),
+          theOrientationMatrix(src.theOrientationMatrix),
+          theTargetWidthInMetersValidFlag(src.theTargetWidthInMetersValidFlag),
+          theTargetWidthInMeters(src.theTargetWidthInMeters),
+          theSlantRangeValidFlag(src.theSlantRangeValidFlag),
+          theSlantRange(src.theSlantRange),
+          theCornerPoints(src.theCornerPoints),
+      theKlvTable(src.theKlvTable.valid()?src.theKlvTable->dup():(ossimPredatorKlvTable*)0),
+      theReferenceTime(src.theReferenceTime),
+      theClock(src.theClock),
+      theDescription(src.theDescription)
+      {}
+      CoordinateInfo* dup()const
+      {
+         return new CoordinateInfo(*this);
+      }
+      void setDescriptionToKlvMetadata();
+      
+      bool theFrameCenterLlhValidFlag;
+      osg::Vec3d theFrameCenterLlh;
+      bool theSensorPositionLlhValidFlag;
+      osg::Vec3d theSensorPositionLlh;
+      bool theOrientationMatrixValidFlag;
+      osg::Matrixd theOrientationMatrix;
+      bool theTargetWidthInMetersValidFlag;
+      ossim_float64 theTargetWidthInMeters;
+      bool theSlantRangeValidFlag;
+      ossim_float64 theSlantRange;
+      std::vector<osg::Vec3d> theCornerPoints;
+      ossimRefPtr<ossimPredatorKlvTable> theKlvTable;
+      double theReferenceTime;
+      double theClock;
+      ossimString theDescription; // html or text formatted description field.  
+   };
+   class OSSIMPLANET_DLL Callback : public osg::Referenced
+   {
+   public:
+      // will add callbacks for when the geometry changed so we can update the drawables position
+      //
+      virtual void coordinatesChanged(ossimRefPtr<ossimPredatorKlvTable> /* originalTable */,
+                                      osg::ref_ptr<CoordinateInfo> /* transformedInfo*/ ){}
+
+      virtual void referenceTimeChanged(ossim_float64 /* reference */){}
+   };
+   ossimPlanetFFMpegImageStream();
+   virtual ~ossimPlanetFFMpegImageStream();
+   void setModel(osg::ref_ptr<ossimPlanetGeoRefModel> model)
+   {
+      theModel = model;
+   }
+   const osg::ref_ptr<ossimPlanetGeoRefModel> model()const
+   {
+      return theModel.get();
+   }
+   void setVideo(ossimRefPtr<ossimPredatorVideo> video);
+   virtual int cancel();
+
+   virtual void run();
+   virtual void play();
+   virtual void pause();
+   virtual void rewind();
+   virtual void quit(bool /*waitForThreadToExit*/ = true);
+   virtual double getLength() const;
+        
+   virtual void setReferenceTime(double);
+   virtual double getReferenceTime();
+                
+   virtual void setTimeMultiplier(double);
+   virtual double getTimeMultiplier();
+        
+   virtual void setVolume(float);
+   virtual float getVolume();
+   void updateThreadBlock()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+         
+         // setting true will release the block
+      theBlock->set((theVideo.valid())&&
+                    ((!theVideo->firstFrameFlag()||theVideo->seekingFlag())||
+                     (theEnableFlag&&(_status == osg::ImageStream::PLAYING))));
+   }
+   void setEnableFlag(bool flag)
+   {
+      theMutex.lock();
+      theEnableFlag = flag;
+      theMutex.unlock();
+      updateThreadBlock();
+   }
+   void setCallback( osg::ref_ptr<ossimPlanetFFMpegImageStream::Callback> callback)
+   {
+      theCallback = callback;
+   }
+   void setNeedFirstFrameFlag(bool flag)
+   {
+      theMutex.lock();
+      theNeedFirstFrameFlag = flag;
+      theMutex.unlock();
+      updateThreadBlock();
+   }
+protected:
+   ossimPlanetReentrantMutex                 theMutex;
+   osg::ref_ptr<ossimPlanetRefBlock> theBlock;
+   ossimRefPtr<ossimPredatorVideo>    theVideo;
+   ossim_float64                      theFrameRate;
+   ossim_float64                      theSecondsToUpdate;
+   bool                               theDoneFlag;
+   bool                               theEnableFlag;
+   bool                               theNeedFirstFrameFlag;
+   osg::ref_ptr<ossimPlanetFFMpegImageStream::Callback> theCallback;
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+};
+
+class OSSIMPLANET_DLL ossimPlanetPredatorVideoLayerNode : public ossimPlanetVideoLayerNode
+{
+public:
+   class ImageStreamCallback : public ossimPlanetFFMpegImageStream::Callback
+   {
+   public:
+      ImageStreamCallback(ossimPlanetPredatorVideoLayerNode* layer)
+         :theLayer(layer)
+      {}
+      virtual void coordinatesChanged(ossimRefPtr<ossimPredatorKlvTable> /* originalTable */,
+                                      osg::ref_ptr<ossimPlanetFFMpegImageStream::CoordinateInfo> transformedInfo)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theLayer->theCoordinateMutex);
+         theLayer->notifyPropertyChanged(theLayer, "coordinates");
+         theLayer->theCoordinates = transformedInfo->dup();
+         theLayer->setDescription(transformedInfo->theDescription);
+      }
+      virtual void referenceTimeChanged(ossim_float64 /* reference */)
+      {
+         theLayer->notifyPropertyChanged(theLayer, "referenceTime");
+         theLayer->setRedrawFlag(true);
+      }
+   protected:
+      ossimPlanetPredatorVideoLayerNode* theLayer;
+   };
+   friend class ImageStreamCallback;
+   ossimPlanetPredatorVideoLayerNode(ossimPlanetVideoLayer* layer=0);
+   virtual ~ossimPlanetPredatorVideoLayerNode();
+   virtual bool open(const ossimFilename& file);
+   virtual void setVideo(ossimPredatorVideo* video);
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   virtual void pause();
+   virtual void rewind();
+   virtual void play();
+   virtual ossim_float64 duration()const;
+   ossimPlanetVideoLayerNode::Status status()const;
+   virtual void setReferenceTime(ossim_float64 reference);
+   virtual ossim_float64 referenceTime()const;
+   virtual void setRenderMode(ossimPlanetVideoLayerNode::RenderMode mode);
+	virtual void stage()
+	{
+		setStagedFlag(true);
+	}
+	virtual void update()
+	{
+	}
+	
+   virtual void setEnableFlag(bool flag)
+   {
+      if(theCurrentFrame.valid())
+      {
+         theCurrentFrame->setEnableFlag(flag);
+      }
+      ossimPlanetVideoLayerNode::setEnableFlag(flag);
+   }
+  
+protected:
+   void updateIconGeometry();
+
+   ossimRefPtr<ossimPredatorVideo>            theVideo;
+   ossim_float64                               theFrameRate;
+   ossim_float64                               theSecondsToUpdate;
+   osg::ref_ptr<ossimPlanetFFMpegImageStream>  theCurrentFrame;
+   osg::Timer_t                                theCurrentTime;
+
+   osg::ref_ptr<osg::Switch> theSwitchNode;
+
+   ossim_float64 theAspect;
+   ossim_float64 theInvAspect;
+   bool          theGeometryFlag;
+   bool          theCullFlag;
+   osg::ref_ptr<ossimPlanetFFMpegImageStream::CoordinateInfo> theCoordinates;
+   ossim_float64 theCullDistance;
+   osg::Vec3d    theFrameCenter;
+   
+   /**
+    * This is the base drawable for all draw modes
+    */
+   osg::ref_ptr<osg::Texture2D>      theSharedTexture;
+   osg::ref_ptr<ossimPlanetIconGeom> theIcon;
+   ossimPlanetReentrantMutex                thePredatorTraverseMutex;
+
+   
+   /**
+    * Used by the 2-D HUD mode drawing for setting the ortho matrix of the camera
+    */ 
+   bool theViewportChangedFlag;
+   
+   osg::ref_ptr<osg::Geode> theSharedGeode;
+
+   /**
+   * Used by the 2-D display mode
+   */
+   osg::ref_ptr<osg::CameraNode> theCameraNode; 
+   osg::ref_ptr<osg::Viewport>   theViewport;
+   osg::ref_ptr<osg::MatrixTransform> the2DMatrixTransform;
+
+   /**
+    * Used by the Billboard display mode.
+    */
+   osg::ref_ptr<ossimPlanetBillboardIcon> theBillboard;
+   osg::ref_ptr<osg::MatrixTransform>     theBillboardMatrixTransform;
+   osg::ref_ptr<ossimPlanetPredatorVideoLayerNode::ImageStreamCallback> theCallback;
+   ossimPlanetReentrantMutex                     theCoordinateMutex;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetPrimaryBody.h b/ossimPlanet/include/ossimPlanet/ossimPlanetPrimaryBody.h
new file mode 100644
index 0000000..1f358cc
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetPrimaryBody.h
@@ -0,0 +1,130 @@
+#ifndef ossimPlanetPrimaryBody_HEADER
+#define ossimPlanetPrimaryBody_HEADER
+#include <osg/Referenced>
+// data associated with astronomical bodies (see bottom for earth and moon values)
+
+#include <math.h>
+#include <ossimPlanet/mkUtils.h>
+#include <string>
+/* #include "eassert.h" */
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetPrimaryBody : public osg::Referenced
+{
+public:
+    ossimPlanetPrimaryBody(const std::string& name, double equatorialRadius, double polarRadius, double signedSecondsPerDay, double mass, double minLon, double maxLon) :
+	name_(name), 
+	equatorialRadius_(equatorialRadius), 
+	polarRadius_(polarRadius),
+	rotationSpeed_(360.0/signedSecondsPerDay), 
+	secondsPerDay_(fabs(signedSecondsPerDay)), 
+	mass_(mass), 
+	mu_(mass*6.67259e-20), // mass * newton's universal gravitational constant in km not meters
+	minLon_(minLon), 
+	maxLon_(maxLon)
+	{
+/* 	    require(!name.empty()); */
+/* 	    require(equatorialRadius > 0.0); */
+/* 	    require(polarRadius > 0.0); */
+/* 	    require(mass > 0.0); */
+/* 	    require(minLon < maxLon); */
+	    
+	    if (secondsPerDay_ == 0.0)
+		rotationSpeed_ = 0.0;
+	}
+    
+    const std::string& name() const
+	// name of the body
+	{ return name_; }
+    
+    double equatorialRadius() const
+	// equatorial radius in meters  (aka a)
+	{ return equatorialRadius_; }
+    
+    double polarRadius() const
+	// polar radius in meters  (aka b)
+	{ return polarRadius_; }
+	
+    double meanRadius() const
+	// mean of equatorialRadius() and polarRadius()
+	{ return (equatorialRadius_ + polarRadius_)/2.0; }
+	
+    double radius(double latitudeDeg) const
+	// distance from center of primary to mean sea level (?) at given latitude
+	{
+           double c  = cos(osg::DegreesToRadians(latitudeDeg)) / equatorialRadius_;
+           double s = sin(osg::DegreesToRadians(latitudeDeg)) / polarRadius_;
+           return sqrt(1.0/(c*c + s*s));
+	}
+
+    double rotationSpeed() const
+	// rotation speed in degrees per second, anticlockwise from north pole
+	{ return rotationSpeed_; }
+
+    double secondsPerDay() const
+	// number of seconds in a day
+	{ return secondsPerDay_; }
+
+    double mass() const
+	// mass in kg
+	{ return mass_; }
+
+    double mu() const
+	// mass * newton universal gravitational constant in km^3/s^2
+	{ return mu_; }
+
+    double minLon() const
+	// min longitude
+	{ return minLon_; }
+
+    double maxLon() const
+	// max longitude
+	{ return maxLon_; }
+
+
+protected:
+    std::string name_;
+	// primary name
+    
+    double equatorialRadius_;
+	// equatorial radius in meters  (aka a)
+    
+    double polarRadius_;
+	// polar radius in meters  (aka b)
+	
+    double rotationSpeed_;
+	// rotation speed in degrees per second 
+
+    double secondsPerDay_;
+	// number of seconds in a day
+
+    double mass_;
+	// mass in kg
+
+    double mu_;
+	// mass * newton universal gravitational constant in km^3/s^2
+
+    double minLon_;
+	// min longitude
+
+    double maxLon_;
+	// max longitude
+
+};
+
+#endif
+
+
+/*
+    # arglist values are:
+    #   primary name
+    #   equatorial radius in meters
+    #   polar radius in meters
+    #   seconds per day (negative if rotates clockwise from north pole, 0 if no rotation)
+    #   mass in kg
+    #   min longitude
+    #   max longitude
+    
+    earth_wgs84   6378137.0    6356752.3142  86400  5.9742e24   -180  180  
+    moon          1737400.0    1737400.0     0      7.3483e22   0     360     
+ */
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetReentrantMutex.h b/ossimPlanet/include/ossimPlanet/ossimPlanetReentrantMutex.h
new file mode 100644
index 0000000..95cc633
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetReentrantMutex.h
@@ -0,0 +1,110 @@
+#ifndef ossimPlanetReentrantMutex_HEADER
+#define ossimPlanetReentrantMutex_HEADER
+#include <OpenThreads/Thread>
+#include <OpenThreads/Mutex>
+#include <OpenThreads/ScopedLock>
+
+/**
+ * This is out of SVN for the nex 2.8.1 release of OSG.  There was a bug in the lock and unlock
+ * I will use this until the new 2.8.1 comes out.
+ */
+class ossimPlanetReentrantMutex : public OpenThreads::Mutex
+{
+public:
+   
+   ossimPlanetReentrantMutex():
+   _threadHoldingMutex(0),
+   _lockCount(0) {}
+   
+   virtual ~ossimPlanetReentrantMutex() {}
+   
+   virtual int lock()
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
+         if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
+         {
+            ++_lockCount;
+            return 0;
+         }
+      }
+      
+      int result = Mutex::lock();
+      if (result==0)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
+         
+         _threadHoldingMutex = OpenThreads::Thread::CurrentThread();
+         _lockCount = 1;
+      }
+      return result;
+   }
+   
+   
+   virtual int unlock()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
+#if 0
+      if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
+      {
+         --_lockCount;
+         if (_lockCount<=0)
+         {
+            _threadHoldingMutex = 0;
+            return Mutex::unlock();
+         }
+      }
+      else
+      {
+         osg::notify(osg::NOTICE)<<"Error: ReentrantMutex::unlock() - unlocking from the wrong thread."<<std::endl;
+      }
+#else
+      if (_lockCount>0)
+      {
+         --_lockCount;
+         if (_lockCount<=0)
+         {
+            _threadHoldingMutex = 0;
+            return Mutex::unlock();
+         }
+      }
+#endif    
+      return 0;
+   }
+   
+   
+   virtual int trylock()
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
+         if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
+         {
+            ++_lockCount;
+            return 0;
+         }
+      }
+      
+      int result = Mutex::trylock();
+      if (result==0)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
+         
+         _threadHoldingMutex = OpenThreads::Thread::CurrentThread();
+         _lockCount = 1;
+      }
+      return result;
+   }
+   
+private:
+   
+   ossimPlanetReentrantMutex(const ossimPlanetReentrantMutex&):OpenThreads::Mutex() {}
+   
+   ossimPlanetReentrantMutex& operator =(const ossimPlanetReentrantMutex&) { return *(this); }
+   
+   OpenThreads::Thread* _threadHoldingMutex;
+   
+   OpenThreads::Mutex  _lockCountMutex;
+   unsigned int        _lockCount;
+   
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetRefBlock.h b/ossimPlanet/include/ossimPlanet/ossimPlanetRefBlock.h
new file mode 100644
index 0000000..4f42083
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetRefBlock.h
@@ -0,0 +1,15 @@
+#ifndef ossimPlanetRefBlock_HEADER
+#define ossimPlanetRefBlock_HEADER
+#include <osg/Referenced>
+#include <OpenThreads/Block>
+#include "ossimPlanetExport.h"
+
+class OSSIMPLANET_DLL ossimPlanetRefBlock : virtual public osg::Referenced,
+                                            public OpenThreads::Block
+{
+public:
+   ossimPlanetRefBlock()
+   {}
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetSceneView.h b/ossimPlanet/include/ossimPlanet/ossimPlanetSceneView.h
new file mode 100644
index 0000000..ff7728e
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetSceneView.h
@@ -0,0 +1,37 @@
+#ifndef ossimPlanetSceneView_HEADER
+#define ossimPlanetSceneView_HEADER
+#include<osgUtil/SceneView>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osgUtil/IntersectVisitor>
+
+class OSSIMPLANET_DLL ossimPlanetSceneView : public osgUtil::SceneView
+{
+public:
+   ossimPlanetSceneView();
+   virtual bool pickObjects(osgUtil::IntersectVisitor::HitList& hits,
+                            osg::Node* startNode,
+                            double vx, double vy,
+                            double startPointShift);
+   
+/*    virtual bool intersectScene(osg::Node* startNode, */
+/*                                osg::Vec3d& intersection, */
+/*                                const osg::Vec3d& startPt, */
+/*                                const osg::Vec3d& endPt); */
+   virtual bool intersectScene(osg::Node* startNode,
+                               osg::Vec3d& intersectionPoint,
+                               double vx, double vy,
+                               double startPointShift=0.0);
+/*    virtual bool computeNadirIntersection(osg::Vec3d& intersectionPoint, */
+/*                                          double startPointShift=0.0); */
+   virtual bool computeLineOfSiteIntersection(osg::Vec3d& intersectionPoint,
+                                              double startPointShift=0.0);
+   void getEyePosition(osg::Vec3d& eye)const;
+   void getLookDirection(osg::Vec3d& direction)const;
+/*    bool makeRay(osg::Vec3d& origin, */
+/*                 osg::Vec3d& ray, */
+/*                 double vx, double vy); */
+   
+protected:
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetServerMessageHandler.h b/ossimPlanet/include/ossimPlanet/ossimPlanetServerMessageHandler.h
new file mode 100644
index 0000000..86ea8ef
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetServerMessageHandler.h
@@ -0,0 +1,30 @@
+#ifndef ossimPlanetServerMessageHandler_HEADER
+#define ossimPlanetServerMessageHandler_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/sg_socket.h>
+
+class ossimPlanetServerMessageHandler : public osg::Referenced
+{
+public:
+   ossimPlanetServerMessageHandler()
+      :theEnableFlag(true)
+   {
+   }
+   virtual bool handleMessage(const ossimString& message,
+                              osg::ref_ptr<SGIOChannel> iochannel)=0;
+   void setEnableFlag(bool flag)
+   {
+      theEnableFlag = flag;
+   }
+   bool getEnableFalg()const
+   {
+      return theEnableFlag;
+   }
+   
+protected:
+      bool theEnableFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetServerThread.h b/ossimPlanet/include/ossimPlanet/ossimPlanetServerThread.h
new file mode 100644
index 0000000..e29ec37
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetServerThread.h
@@ -0,0 +1,75 @@
+#ifndef ossimPlanetServerThread_HEADER
+#define ossimPlanetServerThread_HEADER
+#include <queue>
+#include "ossimPlanetExport.h"
+#include <ossimPlanet/sg_socket.h>
+#include <ossimPlanet/ossimPlanetServerMessageHandler.h>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include <OpenThreads/Thread>
+#include<ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimString.h>
+
+
+class OSSIMPLANET_DLL ossimPlanetServerThread : public osg::Referenced,
+                                                public OpenThreads::Thread
+{
+public:
+   ossimPlanetServerThread(ossim_uint32 maxQueueSize = 2048);
+   virtual ~ossimPlanetServerThread();
+   virtual void run();
+   virtual int cancel();
+
+   void setQueueMessagesFlag(bool flag);
+   bool getQueueMessagesFlag()const;
+   /**
+    * Adds a port listener.
+    *
+    * @param host  The host ip address.  Usually will be localhost or empty string
+    * @param port  The port number.
+    * @param portType The port type can be udp or tcp listener
+    */ 
+   osg::ref_ptr<SGSocket> addServer(const ossimString& host,
+                                    const ossimString& port,
+                                    const ossimString& portType,
+                                    char delimiter='\n');
+
+   osg::ref_ptr<SGSocket> removeServer(ossim_uint32 idx);
+   osg::ref_ptr<SGSocket> removeServer(const ossimString& host,
+                                       const ossimString& port);
+   
+   ossim_uint32 getNumberOfServers()const;
+
+   bool setServer(ossim_uint32 idx,
+                  const ossimString& host,
+                  const ossimString& port,
+                  const ossimString& portType);
+                  
+   ossimString getPort(ossim_uint32 idx)const;
+   ossimString getServer(ossim_uint32 idx)const;
+   ossimString getPortType(ossim_uint32 idx)const;
+
+   bool nextMessage(ossimString& msg);
+
+   void addMessageHandler(osg::ref_ptr<ossimPlanetServerMessageHandler> messageHandler);
+   void removeMessageHandler(osg::ref_ptr<ossimPlanetServerMessageHandler> messageHandler);
+   ossim_uint32 getNumberOfMessageHandlers()const;
+   
+protected:
+   int findMessageHandler(ossimPlanetServerMessageHandler* handler)const;
+   
+   mutable ossimPlanetReentrantMutex theMessageQueueMutex;
+   mutable ossimPlanetReentrantMutex theChannelListMutex;
+   mutable ossimPlanetReentrantMutex theMessageHandlerMutex;
+   ossim_uint32               thePollingRatePerSecond;
+   ossim_uint32               theMaxQueueSize;
+   std::queue<ossimString>    theMessageQueue;
+   std::vector<osg::ref_ptr<SGSocket> >    theChannelList;
+   bool                       theDoneFlag;
+   bool                       theStartedFlag;
+   bool                       theQueueMessagesFlag;
+   std::vector<osg::ref_ptr<ossimPlanetServerMessageHandler> > theMessageHandlerList;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetSetup.h b/ossimPlanet/include/ossimPlanet/ossimPlanetSetup.h
new file mode 100644
index 0000000..53bd339
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetSetup.h
@@ -0,0 +1,8 @@
+#ifndef ossimPlanetSetup_HEADER
+#define ossimPlanetSetup_HEADER
+
+// Comment this out if you want to build without ephemeris support
+// On by default
+#define OSSIMPLANET_HAS_LIBZ
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetShaderProgramSetup.h b/ossimPlanet/include/ossimPlanet/ossimPlanetShaderProgramSetup.h
new file mode 100644
index 0000000..7c8ec29
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetShaderProgramSetup.h
@@ -0,0 +1,86 @@
+#ifndef ossimPlanetShaderProgramSetup_HEADER
+#define ossimPlanetShaderProgramSetup_HEADER
+#include <osg/Referenced>
+#include <osg/Program>
+#include <osg/Shader>
+#include <osg/Uniform>
+#include <vector>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetShaderProgramSetup : public osg::Referenced
+{
+public:
+   enum ossimPlanetFragmentShaderType
+   {
+      NO_SHADER = 0,
+      TOP,
+      REFERENCE,
+      OPACITY,
+      HORIZONTAL_SWIPE,
+      VERTICAL_SWIPE,
+      BOX_SWIPE,
+      CIRCLE_SWIPE,
+      ABSOLUTE_DIFFERENCE,
+      FALSE_COLOR_REPLACEMENT
+   };
+   ossimPlanetShaderProgramSetup(ossim_uint32 minNumberOfTextureArguments=2)
+      :theMinNumberOfTextureArguments(minNumberOfTextureArguments),
+	  theFragmentShaderType(NO_SHADER)
+   {
+   }
+   void setProgram(osg::Program* program)
+   {
+      theProgram = program;
+   }
+   osg::Program* getProgram()
+   {
+      return theProgram.get();
+   }
+   const osg::Program* getProgram()const
+   {
+      return theProgram.get();
+   }
+   ossim_uint32 getNumberOfUniforms()const
+   {
+      return theUniformList.size();
+   }
+   osg::ref_ptr<osg::Uniform> getUniform(const ossimString& name);
+   osg::ref_ptr<osg::Uniform> getUniform(ossim_uint32 idx)
+   {
+      if(idx < theUniformList.size())
+      {
+         return theUniformList[idx].get();
+      }
+      
+      return 0;
+   }
+   void clearUniformList()
+   {
+      theUniformList.clear();
+   }
+
+   void addUniform(osg::Uniform* uniform)
+   {
+      theUniformList.push_back(uniform);
+   }
+   ossim_uint32 minNumberOfTextureArguments()const
+   {
+      return theMinNumberOfTextureArguments;
+   }
+   void setFragmentType(ossimPlanetFragmentShaderType fragType)
+   {
+      theFragmentShaderType = fragType;
+   }
+   ossimPlanetFragmentShaderType fragmentType()const
+   {
+      return theFragmentShaderType;
+   }
+protected:
+   ossim_uint32                             theMinNumberOfTextureArguments;
+   osg::ref_ptr<osg::Program>               theProgram;
+   std::vector<osg::ref_ptr<osg::Uniform> > theUniformList;
+   ossimPlanetFragmentShaderType            theFragmentShaderType;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetSocketNetworkConnection.h b/ossimPlanet/include/ossimPlanet/ossimPlanetSocketNetworkConnection.h
new file mode 100644
index 0000000..2f2eefd
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetSocketNetworkConnection.h
@@ -0,0 +1,68 @@
+class ossimPlanetSocketNetworkConnection;
+#ifndef ossimPlanetSocketNetworkConnection_H
+#define ossimPlanetSocketNetworkConnection_H
+
+#include <ossimPlanet/sg_socket.h>
+#include <ossimPlanet/netBuffer.h>
+#include <osg/ref_ptr>
+// point to point socket connection.
+// XXX see bugs below
+
+#include <string>
+/* #include <sys/time.h>  */
+#include "ossimPlanet/ossimPlanetNetworkConnection.h"
+
+class ossimPlanetSocketNetworkConnection : public ossimPlanetNetworkConnection
+{
+public:
+   class ossimPlanetNetSocketRef : public netSocket,
+                                   public osg::Referenced
+   {
+   public:
+      ossimPlanetNetSocketRef(){}
+      virtual ~ossimPlanetNetSocketRef(){}
+   };
+    ossimPlanetSocketNetworkConnection(const std::string& hostname, int port, char delimiter = '\0');
+    ~ossimPlanetSocketNetworkConnection();
+
+    void send(const ossimPlanetAction& a, const std::string& destination);
+        // XXX doesn't really handle destination correctly
+        //     we don't encode the destination (or the origin) of the sent Action.
+        //     so the remote receiver has to infer origin from which socket he got it off of.
+        //     also the remote receiver can't know the intended destination, since we don't
+        //     encode it and broadcast it to all NetworkConnections.  
+	
+    void receive();
+        // XXX doesn't yet handle broadcast semantics or destination correctly.  
+        // XXX our protocol here doesn't support origin names, so we just use 
+        //     the NetworkConnection name as the originating federate name.
+
+protected:
+    void attemptToFlushOutBuffer();
+        // if outBuffer_ is not empty, write() as much of it as possible and remove the written part from outBuffer_
+        // assert(socket_ >= 0)
+
+//    osg::ref_ptr<SGSocket> theSocket;
+    osg::ref_ptr<ossimPlanetNetSocketRef> theSocket;
+    char actionDelimiter_;
+        // character that marks end of action. usually \n or \0
+
+    std::string inBuffer_;
+	// buffer for accumulating incoming Actions
+        
+    std::string outBuffer_;
+        // buffer for accumulating outgoing Actions, in the case of write() failing somehow.
+    
+
+#if 0
+    int socket_;
+	// socket descriptor
+    
+    struct timeval timeout_;
+	// select() timeout structure
+        
+#endif
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetSousaLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetSousaLayer.h
new file mode 100644
index 0000000..a2bf2c9
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetSousaLayer.h
@@ -0,0 +1,97 @@
+#ifndef ossimPlanetSousaLayer_HEADER
+#define ossimPlanetSousaLayer_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossimPlanet/ossimPlanetAnnotationLayer.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <OpenThreads/Mutex>
+#include <map>
+#include <ossimPlanet/ossimPlanetArchive.h>
+
+
+class ossimPlanet;
+class ossimPlanetKmlLayer;
+class OSSIMPLANET_DLL ossimPlanetSousaLayer : public ossimPlanetLayer
+{
+public:
+   ossimPlanetSousaLayer();
+   virtual ~ossimPlanetSousaLayer();
+	
+   /**
+    * For now this will remove any current connection and then replace with the passed in
+    * connection.  All previous entities are cleared from the scene graph.
+    */ 
+   void setConnection(const ossimString& name,
+                      const ossimString& ip,
+                      const ossimString& port,
+                      const ossimString& portType);
+   
+   /**
+    * add <object definition>
+    *
+    * for annotation adds see the ossimPlanetAnnotationLayer execute.
+    *
+    */
+   virtual void execute(const ossimPlanetAction &a);
+   void closeConnections();
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   // added by russc 5/5/08
+   void setArchive(osg::ref_ptr<ossimPlanetArchive> archive);
+   
+	void setIdentity(const ossimString& tempUserName, 
+						  const ossimString& tempDomain);
+	const ossimString& username()const;
+	const ossimString& domain()const;
+	
+protected:
+   class ossimPlanetSousaXmlActionOperation;
+   friend class ossimPlanetSousaXmlActionOperation;
+   virtual void xmlExecute(const ossimPlanetXmlAction &a);
+   virtual void threadedXmlExecute(const ossimPlanetXmlAction &a);
+	void removeImage(const ossimString& name, 
+						  const ossimString& id);
+	void removeAnnotation(const ossimString& name, 
+						       const ossimString& id);
+	void addImageLayer(const ossimXmlNode* imageObject);
+	void addImageToGroup(ossimPlanetTextureLayerGroup* group, const ossimXmlNode* imageObject);
+   void setClientSocket(const ossimXmlNode* node);
+   void sendViewMessage();
+   void sendIdentityMessage();
+	
+   ossimString          theConnectionName;
+   ossimString          theConnectionIp;
+   ossimString          theConnectionPort;
+   ossimString          theConnectionPortType;
+   ossimString          theIoThreadReceiverName;
+
+	ossimString          theUserName;
+	ossimString          theDomain;
+	
+   bool                 theZuiInitializedFlag;
+	bool                 theViewChangedFlag;
+	double               theViewMessageRate;
+	osg::Timer_t         theViewChangeStart;
+   osg::Vec3d           theEyePosition;
+   osg::Vec3d           theEyeOrientation;
+	
+	
+   osg::ref_ptr<ossimPlanetAnnotationLayer>   theAnnotationLayer;
+   osg::ref_ptr<ossimPlanetArchive>           theArchive;
+   
+	ossimPlanetReentrantMutex theCameraTestDelayMutex;
+   ossim_int32 theCameraTestDelay;
+   mutable ossimPlanetReentrantMutex theUpdateMutex;
+   
+   mutable ossimPlanetReentrantMutex theXmlActionThreadQueueMutex;
+	
+   osg::ref_ptr<ossimPlanetOperationThreadQueue> theXmlActionThreadQueue;
+   
+	osg::ref_ptr<ossimPlanetNodeReraiseCallback> theNodeCallback;
+   
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> theSousaImageGroup;
+   bool theNeedToAddImageGroupFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetSrtmElevationDatabase.h b/ossimPlanet/include/ossimPlanet/ossimPlanetSrtmElevationDatabase.h
new file mode 100644
index 0000000..1448e90
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetSrtmElevationDatabase.h
@@ -0,0 +1,65 @@
+#ifndef ossimPlanetSrtmElevationDatabase_HEADER
+#define ossimPlanetSrtmElevationDatabase_HEADER
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <osg/Timer>
+#include <ossim/imaging/ossimImageRenderer.h>
+#include <ossim/imaging/ossimOrthoImageMosaic.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/projection/ossimEquDistCylProjection.h>
+#include <ossim/elevation/ossimSrtmHandler.h>
+class OSSIMPLANET_DLL ossimPlanetSrtmElevationDatabase : public ossimPlanetElevationDatabase
+{
+public:
+   ossimPlanetSrtmElevationDatabase();
+   ossimPlanetSrtmElevationDatabase(const ossimPlanetSrtmElevationDatabase& src);
+   virtual ~ossimPlanetSrtmElevationDatabase();
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+   virtual ossimPlanetTextureLayerStateCode open(const std::string& location);
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& grid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+   
+protected:
+   class SrtmInfo : public osg::Referenced
+   {
+   public:
+      double                        theMinLat, theMinLon, theMaxLat, theMaxLon;
+      std::string                   theFilename;
+      ossimRefPtr<ossimSrtmHandler> theSrtmHandler;
+      osg::Timer_t                  theTimeStamp;
+   };
+   typedef std::map<std::string, osg::ref_ptr<SrtmInfo> > SrtmFilePointerList;
+
+
+   osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> getInfo(const std::string& srtmName);
+   void shrinkFilePointers();
+   ossimFilename buildFilename(double lat, double lon)const;
+   osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> findSrtmInfo(const std::string& srtmName);
+   
+   std::string                            theLocation;
+   mutable bool                           theOpenFlag;
+   ossim_uint32                           theMaxOpenFiles;
+   ossim_uint32                           theMinOpenFiles;
+   SrtmFilePointerList                    theFilePointers;
+/*    ossimRefPtr<ossimMapProjection>        theProjection; */
+/*    ossimRefPtr<ossimImageRenderer>        theRenderer; */
+/*    ossimRefPtr<ossimOrthoImageMosaic>     theMosaic; */
+/*    ossim_float32                          theNullHeightValue; */
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetStandardTextureLayerFactory.h b/ossimPlanet/include/ossimPlanet/ossimPlanetStandardTextureLayerFactory.h
new file mode 100644
index 0000000..e651de9
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetStandardTextureLayerFactory.h
@@ -0,0 +1,30 @@
+#ifndef ossimPlanetStandardTextureLayerFactory_HEADER
+#define ossimPlanetStandardTextureLayerFactory_HEADER
+#include <OpenThreads/Mutex>
+#include <ossimPlanet/ossimPlanetTextureLayerFactory.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimKeywordlist.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetStandardTextureLayerFactory : public ossimPlanetTextureLayerFactory
+{
+public:
+   ossimPlanetStandardTextureLayerFactory();
+
+   static ossimPlanetStandardTextureLayerFactory* instance();
+   virtual osg::ref_ptr<ossimPlanetTextureLayer> createLayer(const ossimString& name, bool openAllEntriesFlag)const;
+
+protected:
+   ossimPlanetStandardTextureLayerFactory(const ossimPlanetStandardTextureLayerFactory& src):ossimPlanetTextureLayerFactory(src) { } 
+   const ossimPlanetStandardTextureLayerFactory& operator =(const ossimPlanetStandardTextureLayerFactory& ) { return *this;}
+      
+   osg::ref_ptr<ossimPlanetTextureLayer> createLayerFromFilename(const ossimFilename& name, bool openAllEntriesFlag)const;
+   osg::ref_ptr<ossimPlanetTextureLayer> createLayerFromKwl(const ossimKeywordlist& kwl,
+                                                            const ossimString& prefix=ossimString())const;
+   osg::ref_ptr<ossimPlanetTextureLayer> createLayerFromOldKwl(const ossimKeywordlist& kwl,
+                                                               const ossimString& prefix=ossimString())const;
+   static ossimPlanetStandardTextureLayerFactory* theInstance;
+   mutable ossimPlanetReentrantMutex theMutex;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrain.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrain.h
new file mode 100644
index 0000000..821711c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrain.h
@@ -0,0 +1,435 @@
+#ifndef ossimPlanetTerrain_HEADER
+#define ossimPlanetTerrain_HEADER
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <ossimPlanet/ossimPlanetTerrainTile.h>
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetElevationDatabaseGroup.h>
+#include <osg/TexMat>
+#include <osg/Timer>
+#include <osg/GraphicsContext>
+#include <osg/Geometry>
+#include <osg/BufferObject>
+#include <osgDB/DatabasePager>
+#include <osgUtil/UpdateVisitor>
+#include <osgUtil/CullVisitor>
+#include <ossimPlanet/ossimPlanetElevationDatabaseGroup.h>
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetTileRequest.h>
+#include <ossimPlanet/ossimPlanetCache.h>
+#include <set>
+#include <map>
+#include <queue>
+
+/**
+ *
+ */
+class OSSIMPLANET_DLL ossimPlanetTerrain : public ossimPlanetLayer
+{
+public:   
+   class TextureCallback;
+   class OSSIMPLANET_DLL UpdateTileCallback : public osg::NodeCallback
+   {
+   public:
+      UpdateTileCallback(ossimPlanetTerrain* terrain)
+      :theTerrain(terrain){}
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+      virtual void update(ossimPlanetTerrainTile* tile, osg::NodeVisitor* nv);
+   protected:
+      ossimPlanetTerrain* theTerrain;
+   };   
+   class OSSIMPLANET_DLL CullTileCallback : public osg::NodeCallback
+   {
+   public:
+      CullTileCallback(ossimPlanetTerrain* terrain)
+      :theTerrain(terrain){}
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+      virtual void cull(ossimPlanetTerrainTile* tile, osg::NodeVisitor* nv);
+   protected:
+      ossimPlanetTerrain* theTerrain;
+   };
+
+   enum CullAmountType
+   {
+      NO_CULL  = 0,
+      LOW_CULL,
+      MEDIUM_LOW_CULL,
+      MEDIUM_CULL,
+      MEDIUM_HIGH_CULL,
+      HIGH_CULL
+   };
+   enum TextureDensityType
+   {
+      LOW_TEXTURE_DENSITY = 0, 
+      MEDIUM_LOW_TEXTURE_DENSITY, 
+      MEDIUM_TEXTURE_DENSITY, 
+      MEDIUM_HIGH_TEXTURE_DENSITY, 
+      HIGH_TEXTURE_DENSITY    
+   };
+   enum ElevationDensityType
+   {
+      LOW_ELEVATION_DENSITY = 0,
+      MEDIUM_LOW_ELEVATION_DENSITY,
+      MEDIUM_ELEVATION_DENSITY,
+      MEDIUM_HIGH_ELEVATION_DENSITY,
+      HIGH_ELEVATION_DENSITY
+   };
+   enum SplitMergeSpeedType
+   {
+      LOW_SPEED = 0,
+      MEDIUM_LOW_SPEED,
+      MEDIUM_SPEED,
+      MEDIUM_HIGH_SPEED,
+      HIGH_SPEED
+   };
+   enum SplitMergeMetricType
+   {
+       DISTANCE_METRIC = 0,
+       PIXEL_METRIC
+   };
+   class FindCompileableGLObjectsVisitor;
+   friend class UpdateTileCallback;
+   friend class CullTileCallback;
+   friend class TextureCallback;
+   
+   typedef std::list<osg::ref_ptr<ossimPlanetExtents> > RefreshImageExtentsList;
+   typedef std::list<osg::ref_ptr<ossimPlanetExtents> > RefreshElevationExtentsList;
+   typedef std::list<osg::ref_ptr<ossimPlanetTerrainTile> > RemoveChildrenList;
+   typedef std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > TextureLayers;
+   typedef std::map<ossimPlanetTerrainTileId, ossimPlanetTerrainTile* > TileSetMap; 
+   typedef std::set<ossimPlanetTerrainTile*> TileSet; 
+
+   
+   ossimPlanetTerrain();
+   ossimPlanetTerrain(ossimPlanetGrid* grid);
+   virtual ~ossimPlanetTerrain();
+   void setDatabasePager(osgDB::DatabasePager* pager);
+   osgDB::DatabasePager* getDatabasePager(){return thePager.get();}
+   void setTerrainTechnique(ossimPlanetTerrainTechnique* technique);
+   ossimPlanetTerrainTechnique* newTechnique();
+   
+   void setGrid(ossimPlanetGrid* grid);
+   const ossimPlanetGrid* grid()const;
+   ossimPlanetGrid* grid();
+   void removeTerrainTileFromGraph(ossimPlanetTerrainTile* tile);
+   void removeTerrainChildren(ossimPlanetTerrainTile* tile);
+   
+   void requestSplit(ossimPlanetTerrainTile* tile,
+                     ossim_float64 priority,
+                     const osg::FrameStamp* framestamp,
+                     ossimPlanetOperation* request);
+   void requestMerge(ossimPlanetTerrainTile* tile,
+                     ossim_float64 priority,
+                     const osg::FrameStamp* framestamp,
+                     ossimPlanetOperation* request);
+   void requestTexture(ossimPlanetTerrainTile* tile,
+                       ossim_float64 priority,
+                       const osg::FrameStamp* framestamp,
+                       const std::vector<ossim_uint32>& indices,
+                       ossimPlanetOperation* request);
+   void requestElevation(ossimPlanetTerrainTile* tile,
+                         ossim_float64 priority,
+                         const osg::FrameStamp* framestamp,
+                         ossimPlanetOperation* request);
+   void compileGLObjects(osg::State& state, double compileTime);
+  
+   // Helper functions for determining if objects need to be
+   // compiled.
+   inline static bool isCompiled(const osg::Texture* texture,
+                                 unsigned int contextID)
+   {
+      return( texture->getTextureObject(contextID) != NULL );
+   }
+   inline static bool isCompiled(const osg::StateSet* stateSet,
+                                 unsigned int contextID)
+   {
+      for (unsigned i = 0;
+           i < stateSet->getTextureAttributeList().size();
+           ++i)
+      {
+         const osg::Texture* texture
+         = dynamic_cast<const osg::Texture*>(stateSet->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
+         if (texture && !isCompiled(texture, contextID))
+            return false;
+      }
+      return true;
+   }
+   inline static bool isCompiled(const osg::Drawable* drawable,
+                                 unsigned int contextID)
+   {
+      // Worry about vbos later
+      if (drawable->getUseDisplayList())
+      {
+         return drawable->getDisplayList(contextID) != 0;
+      }
+      else if(drawable->getUseVertexBufferObjects())
+      {
+         const osg::Geometry* geometry = drawable->asGeometry();
+         if(geometry)
+         { 
+            osg::Geometry::ArrayList arrayList;
+            geometry->getArrayList(arrayList);
+            ossim_uint32 idx = 0;
+            for(idx = 0; idx < arrayList.size();++idx)
+            {
+               if(arrayList[idx]->getVertexBufferObject())
+               {
+//                  if(arrayList[idx]->getVertexBufferObject()->isDirty(contextID))
+                  {
+                     return false;
+                  }
+               }
+            }
+         }
+      }
+      return true;
+     }
+   bool addElevation(const ossimFilename& file, bool sortFlag=false);
+   bool addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag=false);
+   
+   /**
+    * Will do a non destructive expand or shrink
+    */
+   void setNumberOfTextureLayers(ossim_uint32 size);
+   
+   ossim_uint32 numberOfTextureLayers()const;
+   ossimPlanetTextureLayer* textureLayer(ossim_uint32 idx);
+   bool setTextureLayer(ossim_uint32 idx, ossimPlanetTextureLayer* layer);
+   
+   ossimPlanetElevationDatabaseGroup* elevationLayer();
+   const ossimPlanetElevationDatabaseGroup* elevationLayer()const;
+   
+   virtual void traverse(osg::NodeVisitor &nv);
+   static ossimPlanetTerrain* findTerrain(osg::NodePath& currentNodePath);
+   
+   double maxTimeToSplit()const;
+   double maxTimeToMerge()const;
+   
+   void registerTile(ossimPlanetTerrainTile* tile);
+   void unregisterTile(ossimPlanetTerrainTile* tile);
+   ossimPlanetTerrainTile* findTile(const ossimPlanetTerrainTileId& id);
+   const ossimPlanetTerrainTile* findTile(const ossimPlanetTerrainTileId& id)const;
+   
+   void refreshImageLayers(ossimPlanetExtents* extents = 0);
+   void refreshElevationLayers(ossimPlanetExtents* extents = 0);
+   void refreshImageAndElevationLayers(ossimPlanetExtents* extents = 0);
+   
+   void resetImageLayers();
+   void resetGraph();
+   virtual void setModel(ossimPlanetGeoRefModel* model);
+   void addRequestToReadyToApplyQueue(ossimPlanetTileRequest* request);
+   void addRequestToNeedToCompileQueue(ossimPlanetTileRequest* request);
+   
+   void setMaxNumberOfOperationsToApplyToGraphPerFrame(ossim_uint32 value);
+   
+   /**
+    * @brief set the cull amount used for the terrain.
+    */
+   virtual void setCullAmountType(CullAmountType cullAmount);
+   virtual void setTextureTileSize(ossim_uint32 width,
+                                   ossim_uint32 height);
+   ossim_uint32 textureTileWidth()const;
+   ossim_uint32 textureTileHeight()const;
+   
+   virtual void setElevationTileSize(ossim_uint32 width,
+                                     ossim_uint32 height);
+   ossim_uint32 elevationTileWidth()const;
+   ossim_uint32 elevationTileHeight()const;
+   
+   virtual void setElevationDensityType(ElevationDensityType type);
+   virtual void setTextureDensityType(TextureDensityType type);
+   
+   ElevationDensityType elevationDensityType()const;
+   TextureDensityType textureDensityType()const;
+   
+   void setSplitMergeMetricType(SplitMergeMetricType type);
+   SplitMergeMetricType splitMergeMetricType()const;
+   /**
+    * Split merge speed determines how fast or basically how soon the patch should split.
+    * Currently our algorithm is based solely on distance which means if you set the split
+    * merge speed type to a LOW_SPEED setting you have to move your eye closer to a patch 
+    * before it is further refined.  If you set the speed to a higher speed that low it 
+    * progressively refines the graph sooner.  So the eye can be further away and still refine without
+    * having to be close so the higher the speed the more detail you see from further away.
+    */
+   virtual void setSplitMergeSpeedType(SplitMergeSpeedType type);
+
+   /**
+    *  The metric is based on a scale multiplier of the pixel dimensions of the texture.
+    *  If the patch is smaller in projective scale than the mergeMetric*patchRadiusInPixels then it will
+    *  merge the graph.  If its larger than the splitMetric*patchRadiusInpixels then split.
+    */
+   virtual void setSplitMergePixelMetricParameters(ossim_float64 mergeMetric,
+                                                  ossim_float64 splitMetric);
+   ossim_float64 splitPixelMetric()const;
+   ossim_float64 mergePixelMetric()const;
+
+   virtual void setSplitMergeLodScale(ossim_float64 ratio);
+   ossim_float64 splitMergeLodScale()const; 
+   virtual void setElevationExaggeration(ossim_float64 exaggeration);
+   ossim_float64 elevationExaggeration()const;
+   void setMinimumTimeToCompilePerFrameInSeconds(double timeInSeconds);
+   ossim_float64 minimumTimeToCompilePerFrame()const;
+   void setPrecompileEnabledFlag(bool flag);
+   bool precompileEnabledFlag()const;
+   void setElevationEnabledFlag(bool flag);
+   bool elevationEnabledFlag()const;
+   void initElevation();
+   
+   void setElevationMemoryCache(ossimPlanetMemoryImageCache* cache)
+   {
+      thePropertyMutex.lock();
+      theElevationCache = cache;
+      thePropertyMutex.unlock();
+   }
+   ossimPlanetImageCache* elevationCache()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theElevationCache.get();
+   }
+   const ossimPlanetImageCache* elevationCache()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theElevationCache.get();
+   }
+   
+   bool priorityPointFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return thePriorityPointFlag;
+   }
+   void setPriorityPointFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      thePriorityPointFlag = flag;
+   }
+   void setPriorityPointXyz(const osg::Vec3d& pt)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      thePriorityPoint = pt;
+   }
+   const osg::Vec3d& priorityPoint()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return thePriorityPoint;
+   }
+
+   
+   bool falseEyeFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFalseEyeFlag;
+   }
+   void setFalseEyeFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFalseEyeFlag = flag;
+   }
+   void setFalseEyeXyz(const osg::Vec3d& eye)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFalseEye = eye;
+   }
+   const osg::Vec3d& falseEye()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFalseEye;
+   }
+   
+protected:
+   void buildRoot();
+   bool resetRootsFlag()const;
+   void applyRequestsToGraph(double maxTime);
+   void compileRequests(double maxTime);
+   void pruneNeedToCompileAndAddToGraphThreadQueues();
+   void removeTerrainChildren(double maxTime = 2.0);
+   void refreshExtents();
+   osg::ref_ptr<ossimPlanetTerrainTechnique> theTerrainTechnique;
+   ossim_int64 theLastApplyToGraphFrameNumber;
+   ossim_uint32 theMaxNumberOfOperationsToApplyToGraphPerFrame;
+   mutable OpenThreads::Mutex          thePropertyMutex;
+   mutable OpenThreads::ReentrantMutex theRootLayersMutex;
+   mutable OpenThreads::ReentrantMutex theTextureQueueMutex;
+   mutable OpenThreads::ReentrantMutex theElevationQueueMutex;
+   mutable OpenThreads::ReentrantMutex theSplitQueueMutex;
+   mutable OpenThreads::ReentrantMutex theMergeQueueMutex;
+   
+   mutable OpenThreads::ReentrantMutex theChildrenToRemoveMutex;
+   RemoveChildrenList theChildrenToRemove;
+   
+   bool theResetRootsFlag;
+   osg::ref_ptr<ossimPlanetGrid> theGrid;
+   
+   std::vector<osg::ref_ptr<ossimPlanetTerrainTile> > theRootLayers;
+   
+   TextureLayers      theTextureLayers;
+   osg::ref_ptr<ossimPlanetElevationDatabaseGroup> theElevationLayer;
+   
+   
+   osg::ref_ptr<ossimPlanetTileRequestThreadQueue> theElevationQueue;
+   osg::ref_ptr<ossimPlanetTileRequestThreadQueue> theTextureQueue;
+   
+   
+   /**
+    *
+    */
+   osg::ref_ptr<ossimPlanetTileRequestThreadQueue> theSplitQueue;
+   osg::ref_ptr<ossimPlanetTileRequestQueue> theMergeQueue;
+   
+   OpenThreads::ReentrantMutex    theReadyToApplyToGraphQueueMutex;
+   ossimPlanetTileRequest::List   theReadyToApplyToGraphQueue;
+   ossimPlanetTileRequest::List   theReadyToApplyToGraphNewNodesQueue;
+   OpenThreads::ReentrantMutex    theNeedToCompileQueueMutex;
+   ossimPlanetTileRequest::List   theNeedToCompileQueue;
+      
+   double theMaxTimeToSplit;
+   double theMaxTimeToMerge;
+   mutable OpenThreads::ReentrantMutex theTileSetMutex;
+   mutable OpenThreads::ReentrantMutex theTileSetMapMutex;
+   TileSet theTileSet;
+   TileSetMap theTileSetMap;
+   
+   osg::Vec3d theLastEyePosition;
+   
+   osg::ref_ptr<TextureCallback> theTextureCallback;
+   
+   ossim_int64 theLastFrameNumber;
+   
+   osg::ref_ptr<ossimPlanetMemoryImageCache> theElevationCache;
+   osg::ref_ptr<ossimPlanetImageCacheShrinkOperation> theElevationCacheShrinkOperation;
+   osg::ref_ptr<ossimPlanetOperationThreadQueue> theCacheShrinkThreadQueue;
+   
+   mutable OpenThreads::ReentrantMutex theRefreshExtentsMutex;
+   osg::ref_ptr<ossimPlanetExtents> theRefreshImageExtent;
+   osg::ref_ptr<ossimPlanetExtents> theRefreshElevationExtent;
+//   RefreshImageExtentsList     theRefreshImageExtentsList;
+//   RefreshElevationExtentsList theRefreshElevationExtentsList;
+   
+   /************************** Scene Parameters ****************/
+   osg::CullSettings::CullingModeValues theCullSettings;
+   SplitMergeMetricType                 theSplitMergeMetricType;
+   ossim_uint32                         theTextureTileWidth;
+   ossim_uint32                         theTextureTileHeight;
+   ossim_uint32                         theElevationTileWidth;
+   ossim_uint32                         theElevationTileHeight;
+   ossim_float64                        theSplitMergeLodScale;
+   ossim_float64                        theSplitPixelMetric;
+   ossim_float64                        theMergePixelMetric;
+   ossim_float64                        theElevationExaggeration;
+   double                               theMinimumTimeToCompilePerFrame;
+   bool                                 thePrecompileEnabledFlag;
+   bool                                 theElevationEnabledFlag;
+   
+   bool                                 theFalseEyeFlag;
+   osg::Vec3d                           theFalseEye;
+   bool                                 thePriorityPointFlag;
+   osg::Vec3d                           thePriorityPoint;
+
+   osg::ref_ptr<osgDB::DatabasePager>          thePager;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainGeometryTechnique.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainGeometryTechnique.h
new file mode 100644
index 0000000..03b4bed
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainGeometryTechnique.h
@@ -0,0 +1,255 @@
+#ifndef ossimPlanetTerrainGeometryTechnique_HEADER
+#define ossimPlanetTerrainGeometryTechnique_HEADER
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <osg/MatrixTransform>
+#include <osgUtil/CullVisitor>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/ClusterCullingCallback>
+#include <ossimPlanet/ossimPlanetBoundingBox.h>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+
+class ossimPlanetTerrainTile;
+class ossimPlanetTexture2D;
+class OSSIMPLANET_DLL ossimPlanetTerrainGeometryTechnique : public ossimPlanetTerrainTechnique
+{
+public:
+   META_Object(ossimPlanet, ossimPlanetTerrainGeometryTechnique);
+     
+   class UpdateChildTextureVisitor : public osg::NodeVisitor
+      {
+      public:
+         UpdateChildTextureVisitor(ossimPlanetTexture2D* texture,
+                                   ossim_uint32 idx)
+         : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+         theTexture(texture),
+         theIdx(idx)
+         {
+         }
+         virtual void apply(osg::Node& node);
+      protected:
+         osg::ref_ptr<ossimPlanetTexture2D> theTexture;
+         ossim_uint32 theIdx;
+      };
+   /**
+    * Local space cull node
+    */ 
+   class OSSIMPLANET_DLL CullNode : public osg::MatrixTransform
+   {
+   public:
+      CullNode(const ossimPlanetTerrainTileId& tileId):
+      osg::MatrixTransform(),
+      theTileId(tileId),
+      theCulledFlag(false),
+      theWithinFrustumFlag(true),
+      theEyeDistance(0.0),
+      theEyeToVolumeDistance(0.0),
+      thePixelSize(0.0)
+      {
+         setCullingActive(false);
+      }
+      CullNode(const ossimPlanetTerrainTileId& tileId,
+               osg::ref_ptr<ossimPlanetBoundingBox> boundingBox,
+               const osg::Vec3d& clusterCullingControlPoint,
+               const osg::Vec3d& clusterCullingNormal,
+               double clusterCullingDeviation,
+               double clusterCullingRadius):
+      osg::MatrixTransform(),
+      theTileId(tileId),
+      theCulledFlag(false),
+      theWithinFrustumFlag(true),
+      theBoundingBox(boundingBox),
+      theClusterCullingControlPoint(clusterCullingControlPoint),
+      theClusterCullingNormal(clusterCullingNormal),
+      theClusterCullingDeviation(clusterCullingDeviation),
+      theClusterCullingRadius(clusterCullingRadius),
+      theEyeDistance(0.0),
+      theEyeToVolumeDistance(0.0),
+      thePixelSize(0.0)
+      {
+         setCullingActive(false);
+      }
+      CullNode(const CullNode& src, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
+      :osg::MatrixTransform(src, copyop),
+      theTileId(src.theTileId),
+      theCulledFlag(src.theCulledFlag),
+      theWithinFrustumFlag(src.theWithinFrustumFlag),
+      theBoundingBox(new ossimPlanetBoundingBox(*src.theBoundingBox)),
+      theClusterCullingControlPoint(src.theClusterCullingControlPoint),
+      theClusterCullingNormal(src.theClusterCullingNormal),
+      theClusterCullingDeviation(src.theClusterCullingDeviation),
+      theClusterCullingRadius(src.theClusterCullingRadius),
+      theEyeDistance(0.0),
+      theEyeToVolumeDistance(0.0),
+      thePixelSize(0.0)
+     {
+         setCullingActive(false);
+      }
+      const ossimPlanetTerrainTileId& tileId()const
+      {
+         return theTileId;
+      }
+      void setTileId(const ossimPlanetTerrainTileId& id)
+      {
+         theTileId = id;
+      }
+      void setBoundingBox(osg::ref_ptr<ossimPlanetBoundingBox> box)
+      {
+         theBoundingBox = box.get();
+      }
+      
+      const ossimPlanetBoundingBox* boundingBox()const
+      {
+         return theBoundingBox.get();
+      }
+      double eyeDistance()const
+      {
+         return theEyeDistance;
+      }
+      double eyeToVolumeDistance()const
+      {
+         return theEyeToVolumeDistance;
+      }
+      virtual void traverse(osg::NodeVisitor& nv);
+      
+      void setCulledFlag(bool flag)
+      {
+         theCulledFlag = flag;
+      }
+      bool isCulled()const
+      {
+         return theCulledFlag;
+      }
+      virtual osg::BoundingSphere computeBound() const;
+      
+      double pixelSize()const
+      {
+         return thePixelSize;
+      }
+      bool withinFrustumFlag()const
+      {
+         return theWithinFrustumFlag;
+      }
+   protected:
+      ossimPlanetTerrainTileId theTileId;
+      bool theCulledFlag;
+      bool theWithinFrustumFlag;
+      osg::ref_ptr<ossimPlanetBoundingBox> theBoundingBox;
+      osg::Vec3d theClusterCullingControlPoint;
+      osg::Vec3d theClusterCullingNormal;
+      double theClusterCullingDeviation;
+      double theClusterCullingRadius;
+      double theEyeDistance;
+      double theEyeToVolumeDistance;
+      double thePixelSize;
+  };
+   friend class CullCallback;
+   ossimPlanetTerrainGeometryTechnique();
+   ossimPlanetTerrainGeometryTechnique(const ossimPlanetTerrainGeometryTechnique& src,
+                                       const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+  virtual ~ossimPlanetTerrainGeometryTechnique();
+   virtual void setTerrainTile(ossimPlanetTerrainTile* tile);
+   virtual void update(osgUtil::UpdateVisitor* nv);
+   
+   virtual void cull(osgUtil::CullVisitor* nv);
+   virtual void traverse(osg::NodeVisitor& nv);
+  
+   virtual void buildMesh(ossimPlanetTerrainTile* optionalParent=0);
+   
+   virtual void applyColorLayers(ossimPlanetTerrainTile* optionalParent=0);
+   
+   virtual void applyTransparency(ossimPlanetTerrainTile* optionalParent=0);
+   
+   virtual void smoothGeometry();
+   virtual void init(ossimPlanetTerrainTile* optionalParent=0);
+   //void split(bool recurse, double availableTime=2.5);
+   
+   virtual void childAdded(ossim_uint32 pos);
+   
+   virtual void merge();
+   virtual void removeCulledChildren();
+   bool hasCulledChildren()const;
+   bool isChildCulled(ossim_uint32 childIdx)const;
+
+   virtual double elevationPriority()const;
+   virtual double texturePriority()const;
+   virtual double mergePriority()const;
+   virtual double splitPriority()const;
+   virtual osg::BoundingSphere computeBound() const;
+
+   virtual void updateElevationMesh();
+   
+   virtual ossimPlanetTexture2D* newImageLayerTexture(ossim_uint32 imageLayerIdx);
+   virtual void setChildCullParameters(ossimPlanetTerrainTile* child,
+                                       osg::ref_ptr<CullNode> cullNode);
+   virtual void compileGlObjects(osg::State* state);
+   virtual void setImageLayerTexture(ossimPlanetTexture2D* texture, 
+                                     ossim_uint32 imageLayerIdx);
+   virtual void setElevationMeshFrom(ossimPlanetTerrainTile* tile);
+   virtual void vacantChildIds(TileIdList& ids)const;
+
+   
+   // setup parameters
+   //
+   
+   
+   virtual void releaseGLObjects(osg::State* state=0);
+   
+protected:
+   struct BufferData
+   {
+      osg::ref_ptr<osg::MatrixTransform>   theTransform;
+      osg::ref_ptr<osg::Geode>             theGeode;
+      osg::ref_ptr<osg::Geometry>          theGeometry;
+      osg::Vec3d                           theCenterPatch;
+      osg::ref_ptr<osg::ClusterCullingCallback> theClusterCullingCallback;
+      osg::ref_ptr<CullNode>               theCullNode;
+   };
+   enum ChildLocation
+   {
+      BOTTOM_LEFT  = 0,
+      BOTTOM_RIGHT = 1,
+      TOP_LEFT     = 2,
+      TOP_RIGHT    = 3
+   };
+   enum SkirtFlags
+   {
+      NO_SKIRT     = 0,
+      BOTTOM_SKIRT = 1,
+      RIGHT_SKIRT  = 2,
+      TOP_SKIRT    = 4,
+      LEFT_SKIRT   = 8
+  };
+   ossimPlanetTexture2D* findNearestActiveParentTexture(ossim_uint32 idx, ossimPlanetTerrainTile* optionalParent=0);
+   void swapBuffers();
+   inline BufferData& readOnlyBuffer() { return theBufferData;}//theBufferData[theCurrentReadOnlyBuffer]; }
+   inline const BufferData& readOnlyBuffer()const { return theBufferData;}//[theCurrentReadOnlyBuffer]; }
+   inline BufferData& writeBuffer() { return theBufferData;}//theBufferData[theCurrentWriteBuffer]; }
+   void updateTextureMatrix(osg::StateSet* stateset, 
+                            ossim_uint32 imageLayerIdx,
+                            const ossimPlanetTerrainTileId& startId,
+                            const ossimPlanetTerrainTileId& endId);
+   bool isCulled(BufferData& buffer, osgUtil::CullVisitor* cv)const;
+   void updateChildCullSettings(osgUtil::CullVisitor* cv);
+   void markOnlyNeededChildImageLayersDirty();
+   ossim_uint32 computeSkirtFlags(const ossimPlanetTerrainTileId& childId)const;
+   void updateRequests(osg::NodeVisitor& nv);
+   
+//   unsigned int                        theCurrentReadOnlyBuffer;
+//   unsigned int                        theCurrentWriteBuffer;
+   BufferData                            theBufferData;
+   ossimPlanetReentrantMutex theUpdateMutex;
+   
+   ossimPlanetReentrantMutex            theChildNodeCullParametersMutex;
+   std::vector<osg::ref_ptr<CullNode> > theChildNodeCullParameters;
+   
+   OpenThreads::Mutex                   theInitMutex;
+   
+   osg::Vec3d                           theAdjustedEye;
+   osg::Vec3d                           thePriorityPoint;
+   osg::BoundingSphere                  thePatchBound;
+   osg::Vec3d                           theCenterGrid;
+};
+
+#endif
+   
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainLayer.h
new file mode 100644
index 0000000..5f2132a
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainLayer.h
@@ -0,0 +1,191 @@
+#ifndef ossimPlanetTerrainLayer_HEADER
+#define ossimPlanetTerrainLayer_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <osg/Object>
+#include <osg/Texture>
+
+class OSSIMPLANET_DLL ossimPlanetTerrainLayer : public osg::Object
+{
+public:
+   ossimPlanetTerrainLayer()
+   :theDirtyFlag(false),
+   theMinLevel(0),
+   theMaxLevel(99999),
+   theMinFilter(osg::Texture::LINEAR),
+   theMagFilter(osg::Texture::LINEAR)
+   {
+      setThreadSafeRefUnref(true);
+   }
+   
+   /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
+   ossimPlanetTerrainLayer(const ossimPlanetTerrainLayer& src,
+                           const osg::CopyOp& copyValue=osg::CopyOp::SHALLOW_COPY)
+   :osg::Object(src, copyValue),
+   theDirtyFlag(src.theDirtyFlag),
+   theMinLevel(src.theMinLevel),
+   theMaxLevel(src.theMaxLevel),
+   theMinFilter(src.theMinFilter),
+   theMagFilter(src.theMagFilter)
+   {
+      setThreadSafeRefUnref(true);
+      theMinLevel = src.theMinLevel;
+      theMaxLevel = src.theMaxLevel;
+   }
+   
+   META_Object(ossimPlanet, ossimPlanetTerrainLayer);  
+   
+   virtual void dirty()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theDirtyFlag = true;
+   }
+   virtual bool isDirty()const
+   {      
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theDirtyFlag;
+   }
+   virtual void setDirtyFlag(bool flag)
+   {
+      if(flag)
+      {
+         dirty();
+      }
+      else
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         theDirtyFlag = flag;
+      }
+   }
+   
+   virtual void setMinMaxLevel(ossim_uint32 minLevel, 
+                               ossim_uint32 maxLevel)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theMinLevel = minLevel;
+      theMaxLevel = maxLevel;
+   }
+   ossim_uint32 minLevel()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theMinLevel;
+   }
+   ossim_uint32 maxLevel()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theMaxLevel;
+   }
+   osg::Texture::FilterMode minFilter()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theMinFilter;
+   }
+   osg::Texture::FilterMode magFilter()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theMagFilter;
+   }
+   OpenThreads::Mutex& propertyMutex(){return thePropertyMutex;}
+   virtual void setRefreshFlag(bool flag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theRefreshFlag = flag;
+   }
+   virtual bool refreshFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theRefreshFlag;
+   }
+   
+protected:
+   mutable OpenThreads::Mutex thePropertyMutex;
+   bool theDirtyFlag;
+   bool theRefreshFlag;
+   ossim_uint32 theMinLevel;
+   ossim_uint32 theMaxLevel;
+   osg::Texture::FilterMode        theMinFilter;
+   osg::Texture::FilterMode        theMagFilter;
+};
+
+class OSSIMPLANET_DLL ossimPlanetTerrainImageLayer : public ossimPlanetTerrainLayer
+{
+public:
+   ossimPlanetTerrainImageLayer()
+   :theNoMoreDataFlag(false)
+   {
+   }
+   /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
+   ossimPlanetTerrainImageLayer(const ossimPlanetTerrainImageLayer& src,
+                                const osg::CopyOp& copyValue=osg::CopyOp::SHALLOW_COPY)
+   :ossimPlanetTerrainLayer(src, copyValue),
+   theNoMoreDataFlag(src.theNoMoreDataFlag)
+   {
+      if(src.theImage.valid())
+      {
+         theImage = new ossimPlanetImage(*src.theImage, 
+                                         osg::CopyOp::DEEP_COPY_ALL);
+      }
+  }
+   
+   
+   META_Object(ossimPlanet, ossimPlanetTerrainImageLayer);  
+   
+   virtual void setImage(ossimPlanetImage* image)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theImage = image;
+      if(theImage.valid())
+      {
+         theImage->dirty();
+      }
+      theDirtyFlag = true;
+   }
+   ossimPlanetImage* cloneImage()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      if(theImage.valid())
+      {
+         return new ossimPlanetImage(*theImage.get());
+      }
+      return 0;
+   }
+   ossimPlanetImage* image()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theImage.get();
+   }
+   const ossimPlanetImage* image()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theImage.get();
+   }
+   virtual void dirty()
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+         if(theImage.valid())
+         {
+            theImage->dirty();
+         }
+      }
+      ossimPlanetTerrainLayer::dirty();
+   }
+   ossim_uint32 modifiedCount()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      if(!theImage) return 0;
+      return theImage->getModifiedCount();
+   }
+   void setNoMoreDataFlag(bool flag)
+   {
+      theNoMoreDataFlag = flag;
+   }
+   bool noMoreDataFlag()const
+   {
+      return theNoMoreDataFlag;
+   }
+protected:
+   bool                           theNoMoreDataFlag;
+   osg::ref_ptr<ossimPlanetImage> theImage;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTechnique.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTechnique.h
new file mode 100644
index 0000000..eb1b871
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTechnique.h
@@ -0,0 +1,170 @@
+#ifndef ossimPlanetTerrainTechnique_HEADER
+#define ossimPlanetTerrainTechnique_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Referenced>
+#include <osgUtil/UpdateVisitor>
+#include <osgUtil/CullVisitor>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetTexture2D.h>
+#include <osgUtil/GLObjectsVisitor>
+
+class ossimPlanetTerrainTile;
+class OSSIMPLANET_DLL ossimPlanetTerrainTechnique : public osg::Object
+{
+public:
+   META_Object(ossimPlanet, ossimPlanetTerrainTechnique);
+   class OSSIMPLANET_DLL CompileObjects : public osgUtil::GLObjectsVisitor
+   {
+   public:
+      CompileObjects()
+      : osgUtil::GLObjectsVisitor(COMPILE_STATE_ATTRIBUTES|COMPILE_DISPLAY_LISTS|CHECK_BLACK_LISTED_MODES)
+      {
+         
+      }
+      virtual void apply(osg::Node& node);
+      virtual void apply(osg::Geode& node);
+      virtual void apply(osg::Drawable& drawable);
+      virtual void apply(osg::StateSet& stateset);
+   };
+   
+   class CullCallback : public osg::NodeCallback
+   {
+   public: 
+      CullCallback(){}
+      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         ossimPlanetTerrainTechnique* technique = dynamic_cast<ossimPlanetTerrainTechnique*>(node);
+         osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
+         if(technique&&cv)
+         {
+            technique->cull(cv);
+         }
+         else if(node)
+         {
+            node->traverse(*nv);
+         }
+      }
+   };
+   friend class ossimPlanetTerrainTile;
+   typedef std::vector<ossimPlanetTerrainTileId> TileIdList;
+   ossimPlanetTerrainTechnique();
+   ossimPlanetTerrainTechnique(const ossimPlanetTerrainTechnique& src,
+                               const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   
+   virtual void setTerrainTile(ossimPlanetTerrainTile* tile);
+   ossimPlanetTerrainTile* terrainTile() 
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTerrainTileMutex);
+      return theTerrainTile; 
+   }
+   const ossimPlanetTerrainTile* terrainTile() const 
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTerrainTileMutex);
+      return theTerrainTile; 
+   }
+   
+   void setGrid(ossimPlanetGrid* grid){theGrid = grid;}
+   void setModel(ossimPlanetGeoRefModel* model){theModel = model;}
+   
+   const ossimPlanetGrid* grid()const
+   {
+      return theGrid.get();
+   }
+   const ossimPlanetGeoRefModel* model()const{return theModel.get();}
+   
+   virtual bool isLeaf()const;
+   virtual bool areAllChildrenLeaves()const;
+   virtual void init(ossimPlanetTerrainTile* optionalParent=0);
+   
+//   virtual void applyImageLayer(ossim_int32 idx=-1)=0;
+//   virtual void applyElevation()=0;
+   
+   virtual void update(osgUtil::UpdateVisitor* nv);
+   
+   virtual void cull(osgUtil::CullVisitor* nv);
+   
+   /** Traverse the terrain subgraph.*/
+   virtual void traverse(osg::NodeVisitor& nv);
+   
+//   virtual void split(bool recurse, double availableTime=2.5);
+   virtual void childAdded(ossim_uint32 /*pos*/)
+   {
+      
+   }
+
+   virtual void merge();
+ 
+   virtual double texturePriority()const
+   {
+      return 0.0;
+   }
+
+   virtual double elevationPriority()const
+   {
+      return texturePriority();
+   }
+
+   virtual double splitPriority()const
+   {
+      return texturePriority();
+   }
+   virtual double mergePriority()const
+   {
+      return texturePriority();
+   }
+  
+   /**
+    *
+    */
+   virtual void solveTextureMatrixMappingToParent(const ossimPlanetTerrainTileId& tileId,
+                                                  osg::Matrixd& m)const;
+   virtual void solveTextureMatrixMappingToParent(const ossimPlanetTerrainTileId& startId,
+                                                  const ossimPlanetTerrainTileId& endId,
+                                                  osg::Matrixd& m)const;
+   
+   virtual osg::BoundingSphere computeBound() const
+   {
+      return osg::BoundingSphere(osg::Vec3d(0.0,0.0,0.0), -1);
+   }
+   
+   virtual void compileGlObjects(osg::State* /*state*/)
+   {
+      // intentianally left blank
+   }
+   virtual void setImageLayerTexture(ossimPlanetTexture2D* /*texture*/, 
+                                     ossim_uint32 /*imageLayerIdx*/)
+   {
+      // intentianally left blank
+   }
+   virtual void setElevationMeshFrom(ossimPlanetTerrainTile* /*tile*/)
+   {
+      // intentianally left blank
+   }
+   virtual ossimPlanetTexture2D* newImageLayerTexture(ossim_uint32 /*imageLayerIdx*/)
+   {
+      return 0;
+   }
+   virtual ossim_uint32 childIndex(const ossimPlanetTerrainTileId& tileId)const;
+   virtual void childTreePosition(const ossimPlanetTerrainTileId& tileId,
+                                  ossim_uint32& x, ossim_uint32& y)const;
+   virtual void vacantChildIds(TileIdList& ids)const;
+   virtual void releaseGLObjects(osg::State* /*state*/=0)
+   {
+      
+   }
+protected:
+   virtual ~ossimPlanetTerrainTechnique();
+   mutable OpenThreads::Mutex theTerrainTileMutex;
+   /**
+    * this ossimPlanetGeoRefModel will be replaced soon with a general
+    * GeoRefModel
+    */
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+   
+   osg::ref_ptr<ossimPlanetGrid> theGrid;
+   ossimPlanetTerrainTile*    theTerrainTile;
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTile.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTile.h
new file mode 100644
index 0000000..427a6fb
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTile.h
@@ -0,0 +1,223 @@
+#ifndef ossimPlanetTerrainTile_HEADER
+#define ossimPlanetTerrainTile_HEADER
+#include <osg/Group>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <ossimPlanet/ossimPlanetTerrainTileId.h>
+#include <ossimPlanet/ossimPlanetTerrainLayer.h>
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <osg/observer_ptr>
+#include <OpenThreads/ReadWriteMutex>
+
+class ossimPlanetTerrain;
+class OSSIMPLANET_DLL ossimPlanetTerrainTile : public osg::Group
+{
+public:
+   friend class ossimPlanetTerrain;
+   
+   class MergeTestVisitor : public osg::NodeVisitor
+   {
+   public:
+      MergeTestVisitor(bool cancelScheduledTasksFlag=true)
+      :NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+      theCancelScheduledTasksFlag(cancelScheduledTasksFlag),
+      theCanMergeFlag(true)
+      {
+      }
+      virtual void reset()
+      {
+         theCanMergeFlag = true;
+      }
+      virtual void apply(osg::Node& node)
+      {
+         ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+         if(tile)
+         {
+            if(theCancelScheduledTasksFlag)
+            {
+               tile->splitRequest()->cancel();
+               tile->elevationRequest()->cancel();
+               tile->textureRequest()->cancel();
+            }
+            if((tile->splitRequest()->referenceCount() >1)||
+               (tile->elevationRequest()->referenceCount() > 1)||
+               (tile->textureRequest()->referenceCount()>1))
+            {
+               theCanMergeFlag = false;
+            }
+         }
+         
+         traverse(node);
+      }
+      bool canMerge()const{return theCanMergeFlag;}
+   protected:
+      bool theCancelScheduledTasksFlag;
+      bool theCanMergeFlag;
+   };
+   typedef std::vector<osg::ref_ptr<ossimPlanetTerrainImageLayer> > ImageLayers;
+   typedef osg::ref_ptr<ossimPlanetTerrainImageLayer> ElevationLayer;
+   typedef std::vector<osg::ref_ptr<ossimPlanetTerrainTile> > TileList;
+   ossimPlanetTerrainTile();
+   ossimPlanetTerrainTile(const ossimPlanetTerrainTileId& value);
+   virtual ~ossimPlanetTerrainTile();
+
+   virtual void init(ossimPlanetTerrainTile* optionalParentOverride=0);
+   void traverse(osg::NodeVisitor& nv);
+   
+   void setTerrainTechnique(ossimPlanetTerrainTechnique* terrainTechnique);
+   
+   /** Get the TerrainTechnique*/
+   ossimPlanetTerrainTechnique* terrainTechnique() { return theTerrainTechnique.get(); }
+   
+   /** Get the const TerrainTechnique*/
+   const ossimPlanetTerrainTechnique* terrainTechnique() const
+   { 
+      return theTerrainTechnique.get(); 
+   }
+   void copyCommonParameters(ossimPlanetTerrainTile* src);
+   const ossimPlanetTerrainTileId& tileId()const{return theId;}
+   void setTileId(const ossimPlanetTerrainTileId& value);
+   void setTerrain(ossimPlanetTerrain* value);
+   ossimPlanetTerrain* terrain();
+   const ossimPlanetTerrain* terrain()const;
+   ossimPlanetGrid* grid(){return theGrid.get();}
+   const ossimPlanetGrid* grid()const{return theGrid.get();}
+   
+   virtual void cancelAllOperations();
+   virtual bool hasActiveOperations()const;
+   
+   virtual void resetImageLayers();
+   virtual void resetElevationLayer();
+/**
+    * Will be non destructive set.
+    */
+   void setNumberOfImageLayers(ossim_uint32 n);
+   ossim_uint32 numberOfImageLayers()const;
+   bool imageLayersDirty()const;
+   ossimPlanetTerrainImageLayer* imageLayer(ossim_uint32 idx=0);
+   ossimPlanetTerrainImageLayer* elevationLayer();
+   
+   ossim_int32 indexOfChild(const ossimPlanetTerrainTileId& id);
+   ossimPlanetTerrainTile* child(const ossimPlanetTerrainTileId& id);
+
+   ossimPlanetTerrainTile* parentTile();
+   const ossimPlanetTerrainTile* parentTile()const;
+   
+   virtual void vacantChildIds(ossimPlanetTerrainTechnique::TileIdList& ids)const;
+   //virtual void split(bool recurse=true, double availableTime=2.5);
+   virtual void merge();
+
+   void setCulledFlag(bool culled);
+   bool culledFlag()const;
+   
+   virtual osg::BoundingSphere computeBound() const;
+   
+   ossimPlanetOperation* splitRequest()
+   {
+      return theSplitRequest.get();
+   }
+   const ossimPlanetOperation* splitRequest()const
+   {
+      return theSplitRequest.get();
+   }
+   
+   ossimPlanetOperation* elevationRequest()
+   {
+      return theElevationRequest.get();
+   }
+   
+   ossimPlanetOperation* textureRequest()
+   {
+      return theTextureRequest.get();
+   }
+   virtual void releaseGLObjects(osg::State* state=0);
+   
+   /**
+    * @return the last cull time stamp.
+    */
+   ossim_float64 simTimeStamp()const
+   {
+      return theSimTimeStamp;
+   }
+   
+   
+   /**
+    * @return the last cull time stamp.
+    */
+   ossim_float64 timeStamp()const
+   {
+      return theTimeStamp;
+   }
+   
+   /**
+    * @return the last cull frame stamp
+    */
+   ossim_int64 frameNumber()const
+   {
+      return theFrameNumber;
+   }
+   
+   void updateFrameAndTimeStamps(const osg::FrameStamp* stamp)
+   {
+      if(stamp)
+      {
+         theFrameNumber = stamp->getFrameNumber();
+         theTimeStamp = stamp->getReferenceTime();
+         theSimTimeStamp = stamp->getSimulationTime();
+      }
+   }
+protected:
+   virtual void childInserted(unsigned int /*pos*/);
+   
+   mutable ossimPlanetReentrantMutex thePropertyMutex; 
+   ossimPlanetTerrainTileId theId;
+
+   osg::ref_ptr<ossimPlanetGrid> theGrid;
+   ossimPlanetTerrain* theTerrain;
+   osg::ref_ptr<ossimPlanetTerrainTechnique> theTerrainTechnique;
+   
+   ImageLayers    theImageLayers;
+   ElevationLayer theElevationLayer;
+   
+   bool theCulledFlag;
+
+   /**
+    * Job interface to the split queue
+    */
+   osg::ref_ptr<ossimPlanetOperation> theSplitRequest;
+
+   /**
+    * Job interface to the texture queue
+    */
+   osg::ref_ptr<ossimPlanetOperation> theTextureRequest;
+
+   /**
+    * Job interface to the elevation queue
+    */
+   osg::ref_ptr<ossimPlanetOperation> theElevationRequest;
+   
+   /**
+    * Will hold the frame stamp of the last culled visit.  If it get's culled it should not update
+    * it's frame stamp
+    */
+   ossim_int64   theFrameNumber;
+
+   
+   /**
+    * Will hold the time stamp of the last culled visit.  If it get's culled it should not update
+    * it's time stamp
+    */
+   ossim_float64 theTimeStamp;
+   
+   /**
+    * Will hold the simulation time stamp of the last culled visit.  If it get's culled it should not update
+    * it's time stamp
+    */
+   ossim_float64 theSimTimeStamp;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTileId.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTileId.h
new file mode 100644
index 0000000..7aa5fb2
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTerrainTileId.h
@@ -0,0 +1,76 @@
+#ifndef ossimPlanetTerrainTileId_HEADER
+#define ossimPlanetTerrainTileId_HEADER
+#include <ossim/base/ossimConstants.h>
+#include <iostream>
+
+class OSSIMPLANET_DLL ossimPlanetTerrainTileId
+{
+public:
+   friend std::ostream& operator <<(std::ostream& out, const ossimPlanetTerrainTileId& tileid)
+   {
+      return out << "<" << tileid.theFace <<", " << tileid.theLevel << ", " << tileid.theX << ", " << tileid.theY << ">";
+   }
+   ossimPlanetTerrainTileId()
+   :theFace(0),
+   theLevel(0),
+   theX(0),
+   theY(0)
+   {
+      setId(0,0,0,0);
+   }
+   ossimPlanetTerrainTileId(ossim_uint32 face, ossim_uint32 level, ossim_uint64 x, ossim_uint64 y)
+   {
+      setId(face, level, x, y);
+   }
+   bool operator == (const ossimPlanetTerrainTileId& rhs) const        
+   {
+      return (theLevel==rhs.theLevel) && (theX==rhs.theX) && (theY==rhs.theY) && (theFace == rhs.theFace);
+   }
+   
+   bool operator != (const ossimPlanetTerrainTileId& rhs) const        
+   {
+      return (theLevel!=rhs.theLevel) || (theX!=rhs.theX) || (theY!=rhs.theY) || (theFace != rhs.theFace);
+   }
+   
+   bool operator < (const ossimPlanetTerrainTileId& rhs) const
+   {
+      if (theLevel<rhs.theLevel) return true;
+      if (theLevel>rhs.theLevel) return false;
+      if (theX<rhs.theX) return true;
+      if (theX>rhs.theX) return false;
+      if (theY<rhs.theY) return true;
+      if (theY>rhs.theY) return false;
+      return theFace<rhs.theFace;
+   }
+   
+   void setId(ossim_uint32 face, ossim_uint32 level, ossim_uint64 x, ossim_uint64 y)
+   {
+      theFace  = face;
+      theLevel = level;
+      theX     = x;
+      theY     = y;
+   }
+   void splitQuad(ossimPlanetTerrainTileId& quad00, 
+                  ossimPlanetTerrainTileId& quad10,
+                  ossimPlanetTerrainTileId& quad11,
+                  ossimPlanetTerrainTileId& quad01)
+   {
+      ossim_uint32 xOrigin=theX<<1;
+      ossim_uint32 yOrigin=theY<<1;
+
+      quad00.setId(theFace, theLevel+1, xOrigin, yOrigin);
+      quad10.setId(theFace, theLevel+1, xOrigin+1, yOrigin);
+      quad11.setId(theFace, theLevel+1, xOrigin+1, yOrigin+1);
+      quad01.setId(theFace, theLevel+1, xOrigin, yOrigin+1);
+   }
+   const ossim_uint32& level()const{return theLevel;}
+   const ossim_uint64& x()const{return theX;}
+   const ossim_uint64& y()const{return theY;}
+   const ossim_uint32& face()const{return theFace;}
+   ossim_uint32 theFace;
+   ossim_uint32 theLevel;
+   ossim_uint64 theX;
+   ossim_uint64 theY;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTexture2D.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTexture2D.h
new file mode 100644
index 0000000..5a6428c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTexture2D.h
@@ -0,0 +1,34 @@
+#ifndef ossimPlanetTexture2D_HEADER
+#define ossimPlanetTexture2D_HEADER
+#include <osg/Texture2D>
+#include <osg/State>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossim/base/ossimConstants.h>
+#include <ossimPlanet/ossimPlanetTerrainTileId.h>
+
+class ossimPlanetImage;
+class OSSIMPLANET_DLL ossimPlanetTexture2D : public osg::Texture2D
+{
+public:
+   ossimPlanetTexture2D(const ossimPlanetTerrainTileId& id=ossimPlanetTerrainTileId(0,0,0,0));
+   ossimPlanetTexture2D(osg::Image* image, 
+                        const ossimPlanetTerrainTileId& id=ossimPlanetTerrainTileId(0,0,0,0));
+   ossimPlanetTexture2D(ossimPlanetImage* image);
+
+   /** Copy constructor using CopyOp to manage deep vs shallow copy. */
+   ossimPlanetTexture2D(const ossimPlanetTexture2D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   virtual ~ossimPlanetTexture2D();
+
+   void setImage(ossimPlanetImage* image);
+   const ossimPlanetTerrainTileId& tileId()const;
+   void setId(const ossimPlanetTerrainTileId& id);
+
+protected:
+   ossimPlanetTerrainTileId theTileId;
+   ossim_uint32 theFace;
+   ossim_uint32 theLevel;
+   ossim_uint64 theRow;
+   ossim_uint64 theCol;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayer.h
new file mode 100644
index 0000000..b585eff
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayer.h
@@ -0,0 +1,380 @@
+#ifndef ossimPlanetTextureLayer_HEADER
+#define ossimPlanetTextureLayer_HEADER
+#include <osg/Referenced>
+#include <ossim/base/ossimString.h>
+#include <ossim/base/ossimId.h>
+#include "ossimPlanetExport.h"
+#include "ossimPlanetImage.h"
+#include "ossimPlanetGridUtility.h"
+#include <ossimPlanet/ossimPlanetId.h>
+#include <ossim/base/ossimDate.h>
+#include <ossim/imaging/ossimImageData.h>
+#include <ossimPlanet/ossimPlanetExtents.h>
+#include <ossimPlanet/ossimPlanetConstants.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <vector>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+
+class ossimPlanetTextureLayerGroup;
+
+class ossimPlanetTextureLayer;
+class OSSIMPLANET_DLL ossimPlanetTextureLayerCallback : public ossimPlanetCallback
+{
+public:
+   ossimPlanetTextureLayerCallback(){}
+   
+   virtual void layerAdded(osg::ref_ptr<ossimPlanetTextureLayer> /*layer*/)
+   {
+   }
+   virtual void layerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> /*layer*/,
+                             osg::ref_ptr<ossimPlanetTextureLayer> /*parent*/)
+   {
+   }
+   virtual void refreshExtent(osg::ref_ptr<ossimPlanetExtents> /*extent*/)
+   {
+   }
+   virtual void propertyChanged(const ossimString& /*name*/,
+                                const ossimPlanetTextureLayer* /*object*/){}
+   
+};
+
+class ossimPlanetTextureLayerRaiseCallback;
+
+class OSSIMPLANET_DLL ossimPlanetTextureLayer : public osg::Referenced,
+   public ossimPlanetCallbackListInterface<ossimPlanetTextureLayerCallback>
+{
+public:
+	friend class ossimPlanetTextureLayerRaiseCallback;
+   class OSSIMPLANET_DLL Stats : public osg::Referenced
+   {
+   public:
+      Stats()
+         :osg::Referenced(),
+         theTotalTextureSize(0),
+         theBytesTransferred(0)
+      {
+      }
+      Stats(const Stats& src)
+         :osg::Referenced(),
+         theTotalTextureSize(src.theTotalTextureSize),
+         theBytesTransferred(src.theBytesTransferred)
+      {
+         
+      }
+         
+      Stats* clone()const
+      {
+         return new Stats(*this);
+      }
+      
+      const ossim_uint64& totalTextureSize()const
+      {
+         return theTotalTextureSize;         
+      }
+      void setTotalTextureSize(const ossim_uint64& size)
+      {
+         theTotalTextureSize = size;
+      }
+      
+      const ossim_uint64& bytesTransferred()const
+      {
+         return theBytesTransferred;
+      }
+      void setBytesTransferred(ossim_uint64 amountTransferred)
+      {
+         theBytesTransferred = amountTransferred;
+      }
+   protected:
+      
+      ossim_uint64 theTotalTextureSize;
+      ossim_uint64 theBytesTransferred;
+   };
+/*    typedef std::vector<osg::ref_ptr<ossimPlanetTextureLayer::Callback> > CallbackList; */
+   typedef std::vector<ossimPlanetTextureLayerGroup*> ossimPlanetTextureLayerParentList;
+   typedef std::vector<unsigned char> TransparentColorType;
+   
+
+   ossimPlanetTextureLayer();
+   ossimPlanetTextureLayer(const ossimPlanetTextureLayer& src);
+   virtual ~ossimPlanetTextureLayer();
+   virtual ossimPlanetTextureLayer* dup()const=0;
+   virtual ossimPlanetTextureLayer* dupType()const=0;
+   virtual ossimString getClassName()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents()=0;
+   
+   void addBytesTransferredStat(ossim_uint64 bytesTransferred)const;
+   virtual void updateStats()const=0;
+   /**
+    *  Since theStateCode is a utility / mutable variable and is updated during
+    *  constant and non constant access we will make this a const on ll other non mutable
+    *  variables.
+    */
+   void clearState(ossimPlanetTextureLayerStateCode stateCode=ossimPlanetTextureLayer_ALL)const;
+
+   /**
+    *  Since theStateCode is a utility / mutable variable and is updated during
+    *  constant and non constant access we will make this a const on ll other non mutable
+    *  variables.
+    */
+   void setState(ossimPlanetTextureLayerStateCode stateCode)const;
+
+   ossimPlanetTextureLayerStateCode getStateCode()const;
+   bool isStateSet(ossimPlanetTextureLayerStateCode)const;
+   
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& theGrid)=0;
+   
+   /**
+    * We will supply an optional padding value.  This is a request and if the request occured successfully
+    * then the padding variable will be set in the resulting image result.
+    *
+    * 
+    */
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0)=0;
+   /**
+    * Deprecated.  Will be replaced with the new tiling grid interface
+    */
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility)=0;
+   
+   void dirtyExtents();
+   void dirtyStats();
+   void setDirtyExtentsFlag(bool flag);
+   const osg::ref_ptr<ossimPlanetTextureLayer::Stats> getStats()const;
+   osg::ref_ptr<ossimPlanetTextureLayer::Stats>  getStats();
+   const osg::ref_ptr<ossimPlanetExtents> getExtents()const;
+   osg::ref_ptr<ossimPlanetExtents> getExtents();
+   virtual void setExtents (osg::ref_ptr<ossimPlanetExtents> extents);
+
+   virtual const osg::ref_ptr<ossimPlanetLookAt> getLookAt()const;
+   virtual void setLookAt(osg::ref_ptr<ossimPlanetLookAt> lookAt);
+
+   virtual void getDateRange(ossimDate& minDate,
+                             ossimDate& maxDate)const;
+   /**   
+    * Approximate length in meters of the hypotneus.  Just uses the getExtents
+    * and ten approximates a meter gsd from the degree bounds.
+    */ 
+   virtual double getApproximateHypotneusLength()const;
+
+   /**
+    * Will return the center lat lon and the approximate hypotneus length in meters.
+    */ 
+   virtual void getCenterLatLonLength(double& centerLat,
+                                      double& centerLon,
+                                      double& length)const;
+   virtual ossimPlanetTextureLayerGroup* asGroup();
+   virtual const ossimPlanetTextureLayerGroup* asGroup()const;
+   ossimPlanetTextureLayerGroup* getParent(ossim_uint32 idx);
+   const ossimPlanetTextureLayerGroup* getParent(ossim_uint32 idx)const;
+   ossimPlanetTextureLayerGroup* parent(ossim_uint32 idx);
+   const ossimPlanetTextureLayerGroup* parent(ossim_uint32 idx)const;
+   ossim_uint32 getNumberOfParents();
+   bool hasParent(ossimPlanetTextureLayerGroup* parent)const;
+   void setParent(ossimPlanetTextureLayer* parent);
+   const ossimString& id()const;
+   void setId(const ossimString& id);
+   virtual void setEnableFlag(bool flag);
+	bool enableFlag()const;
+   bool getEnableFlag()const;
+
+   void setName(const ossimString& name);
+   const ossimString& getName()const;
+   const ossimString& name()const;
+
+   void setDescription(const ossimString& description);
+   const ossimString& getDescription()const;
+   const ossimString& description()const;
+
+   void setTransparentColorFlag(bool flag);
+   bool getTransparentColorFlag()const;
+   const TransparentColorType& getTransparentColor()const;
+   void setTransparentColor(unsigned int r,
+                            unsigned int g,
+                            unsigned int b);
+   
+   bool insertAlpha(osg::ref_ptr<ossimPlanetImage> texture)const;
+   bool insertAlpha(osg::ref_ptr<ossimPlanetImage> texture,
+                    float initialAlphaValue)const;
+   void addTransparent(osg::ref_ptr<ossimPlanetImage> texture)const;
+
+   void detachFromParents();
+   void addParent(ossimPlanetTextureLayerGroup* parent);
+   void removeParent(ossimPlanetTextureLayerGroup* parent);
+   
+   virtual void setFilterType(const ossimString& filterType);
+   virtual const ossimString& getFilterTypeAsString()const;
+/*    void addCallback(osg::ref_ptr<ossimPlanetTextureLayer::Callback> callback); */
+/*    void removeCallback(osg::ref_ptr<ossimPlanetTextureLayer::Callback> callback); */
+
+   OpenThreads::Mutex& mutex();
+   
+   virtual void getMetadata(ossimRefPtr<ossimXmlNode> metadata)const;
+   virtual ossimRefPtr<ossimXmlNode> saveXml(bool recurseFlag=true)const;
+   virtual bool loadXml(ossimRefPtr<ossimXmlNode> node);
+
+
+   // all notification methods are propagated if parent texture layers are listening to child layers.
+   //
+   void notifyRefreshExtent(osg::ref_ptr<ossimPlanetExtents> extent);
+   void notifyLayerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer);
+   void notifyLayerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                           osg::ref_ptr<ossimPlanetTextureLayer> parent);
+   void notifyPropertyChanged(const ossimString& name,
+                              const ossimPlanetTextureLayer* layer)const;
+
+   virtual void resetLookAt();
+
+   virtual ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                    bool recurseFlag=false);
+   virtual const ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                          bool recurseFlag=false)const;
+   
+   virtual ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                         const ossimString& layerId);
+   virtual const ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                               const ossimString& layerId)const;
+   
+   virtual ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                  bool recurseFlag=false);
+   virtual const ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                        bool recurseFlag=false)const;
+
+   void remove();
+   
+
+   ossim_float32 brightness()const;
+   ossim_float32 contrast()const;
+   ossim_float32 opacity()const;
+
+   /**
+     * Allows one to enable brightness contrast settings.
+     */
+    void setBrightnessContrast(ossim_float32 brightnessValue,
+                               ossim_float32 contrastValue,
+                               bool notifyFlag = true);
+    /**
+      * Allows one to enable brightness  settings.
+      */
+     void setBrightness(ossim_float32 brightnessValue, bool notifyFlag=true);
+     /**
+       * Allows one to enable contrast settings.
+       */
+     void setContrast(ossim_float32 contrastValue, bool notifyFlag = true);
+
+   /**
+    * Allows one to set the opacity.
+    *
+    * @param opacityValue value of 1.0 is fully opaque and a value of 0 is fully transparent
+    */
+   void setOpacity(ossim_float32 opacityValue, bool notifyFlag = true);
+   
+protected:
+   ossimPlanetImage* applyBrightnessContrast(ossimPlanetImage* image, bool duplicateFlag=true)const;
+   virtual void mergeImage(ossimPlanetImage* result,
+                           const ossimPlanetImage* source,
+                           ossim_float32 sourceOpacity=1.0)const;
+   
+   void convertToOsg(ossimImageData* data,
+                     ossimPlanetImage* image)const;
+   void convertToOsg(ossimImageData* data,
+                     ossimPlanetImage* image,
+                     const osg::Vec2d& ulInput,
+                     const osg::Vec2d& /*urInput*/,
+                     const osg::Vec2d& lrInput,
+                     const osg::Vec2d& /*llInput*/,
+                     ossimPlanetGrid::ModelPoints& outputGridPoints,
+                     ossim_uint32 outputWidth,
+                     ossim_uint32 outputHeight)const;
+   
+   void convertToOsg(ossimImageData* data,
+                     ossimPlanetImage* image,
+                     const osg::Vec2d& ulInput,
+                     const osg::Vec2d& urInput,
+                     const osg::Vec2d& lrInput,
+                     const osg::Vec2d& llInput,
+                     std::vector<ossimPlanetGridUtility::GridPoint>& outputGridPoints,
+                     const ossimPlanetGridUtility& utility,
+                     ossim_uint32 outputWidth,
+                     ossim_uint32 outputHeight)const;
+   
+   ossimString                            theName;
+   ossimString                            theDescription;
+   ossimString                            theId;
+   ossimPlanetTextureLayerParentList      theParentList;
+   mutable osg::ref_ptr<ossimPlanetExtents>   theExtents;
+   mutable osg::ref_ptr<ossimPlanetLookAt>    theLookAt;
+   
+   bool                                   theEnableFlag;
+   bool                                   theTransparentColorFlag;
+   TransparentColorType                   theTransparentColorVector; // [0] = r, [1] = g, [2] = b
+   ossimString                            theFilterType;
+   mutable ossimPlanetReentrantMutex    thePropertyMutex;
+   mutable ossimPlanetReentrantMutex    theMutex;
+/*    mutable OpenThreads::Mutex             theCallbackMutex; */
+   mutable bool                           theDirtyExtentsFlag;
+   mutable bool                           theDirtyStatsFlag;
+   mutable osg::ref_ptr<Stats>            theStats;
+   mutable ossimPlanetTextureLayerStateCode theStateCode;
+   
+   ossim_float32                          theBrightness;
+   ossim_float32                          theContrast;
+
+   ossim_float32                          theOpacity;
+/*    ossimPlanetTextureLayer::CallbackList    theCallbackList; */
+   
+};
+
+class OSSIMPLANET_DLL ossimPlanetTextureLayerRaiseCallback : public ossimPlanetTextureLayerCallback
+{
+public:
+	ossimPlanetTextureLayerRaiseCallback(ossimPlanetTextureLayer* parentLayer):theLayer(parentLayer){}
+	ossimPlanetTextureLayer* layer(){return theLayer;}
+	void setLayer(ossimPlanetTextureLayer* l){theLayer = l;}
+	
+   virtual void layerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+   {
+		if(theLayer)
+		{
+			theLayer->notifyLayerAdded(layer.get());
+		}
+   }
+   virtual void layerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                             osg::ref_ptr<ossimPlanetTextureLayer> parent)
+   {
+		if(theLayer)
+		{
+			theLayer->notifyLayerRemoved(layer, parent);
+		}
+   }
+   virtual void refreshExtent(osg::ref_ptr<ossimPlanetExtents> extent)
+   {
+		if(theLayer)
+		{
+			theLayer->notifyRefreshExtent(extent);
+		}
+   }
+   virtual void propertyChanged(const ossimString& name,
+                                const ossimPlanetTextureLayer* object)
+	{
+		if(theLayer)
+		{
+			theLayer->notifyPropertyChanged(name, object);
+		}
+	}
+   
+protected:
+	ossimPlanetTextureLayer* theLayer;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerFactory.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerFactory.h
new file mode 100644
index 0000000..7007e43
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerFactory.h
@@ -0,0 +1,19 @@
+#ifndef ossimPlanetTextureLayerFactory_HEADER
+#define ossimPlanetTextureLayerFactory_HEADER
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetTextureLayerFactory : public osg::Referenced
+{
+public:
+   virtual osg::ref_ptr<ossimPlanetTextureLayer> createLayer(const ossimString& name, bool openAllEntriesFlag=true)const=0;
+    
+protected:
+   ossimPlanetTextureLayerFactory(){}
+   ossimPlanetTextureLayerFactory(const ossimPlanetTextureLayerFactory&):osg::Referenced(){}
+   const ossimPlanetTextureLayerFactory& operator = (const ossimPlanetTextureLayerFactory& /*src*/){return *this;}
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerGroup.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerGroup.h
new file mode 100644
index 0000000..2053af8
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerGroup.h
@@ -0,0 +1,115 @@
+#ifndef ossimPlanetTextureLayerGroup_HEADER
+#define ossimPlanetTextureLayerGroup_HEADER
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <vector>
+#include <OpenThreads/ScopedLock>
+#include <OpenThreads/ReentrantMutex>
+
+class OSSIMPLANET_DLL ossimPlanetTextureLayerGroup : public ossimPlanetTextureLayer
+{
+public:
+   ossimPlanetTextureLayerGroup();
+   ossimPlanetTextureLayerGroup(const ossimPlanetTextureLayerGroup& src);
+   ~ossimPlanetTextureLayerGroup();
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimString getClassName()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void resetStats()const;
+   virtual void updateStats()const;
+   
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& grid);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+   
+   virtual ossimPlanetTextureLayerGroup* asGroup();
+   virtual const ossimPlanetTextureLayerGroup* asGroup()const;
+   virtual bool swapLayers(ossim_uint32 idx1, ossim_uint32 idx2, bool notifyFlag=true);
+   virtual bool swapLayers(osg::ref_ptr<ossimPlanetTextureLayer> layer1, 
+                           osg::ref_ptr<ossimPlanetTextureLayer> layer2,
+                           bool notifyFlag=true);
+   virtual bool replaceLayer(ossim_uint32 idx,
+                             osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                             bool notifyFlag = true);
+   
+   virtual bool addTop(osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag=true);
+   virtual bool addBeforeIdx(ossim_uint32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag=true);
+   virtual bool addBeforeLayer(const osg::ref_ptr<ossimPlanetTextureLayer> beforeLayer,
+                               osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd, bool notifyFlag=true);
+   virtual bool addAfterIdx(ossim_int32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag=true);
+   virtual bool addAfterLayer(const osg::ref_ptr<ossimPlanetTextureLayer> afterLayer,
+                              osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd, bool notifyFlag=true);
+   virtual bool addBottom(osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag=true);
+   osg::ref_ptr<ossimPlanetTextureLayer> removeLayer(ossim_uint32 idx, bool notifyFlag=true);
+   void removeLayers(ossim_uint32 idx, ossim_uint32 length=1, bool notifyFlag=true);
+   bool removeLayer(osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag=true);
+   
+   ossim_int32 findLayerIndex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const;
+   bool containsLayer(osg::ref_ptr<ossimPlanetTextureLayer> layer)const;
+   
+   ossim_uint32 numberOfLayers()const;
+   const osg::ref_ptr<ossimPlanetTextureLayer> layer(ossim_uint32 idx)const;
+   osg::ref_ptr<ossimPlanetTextureLayer> layer(ossim_uint32 idx);
+   
+   virtual ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                    bool recurseFlag=false);
+   virtual const ossimPlanetTextureLayer* findLayerByName(const ossimString& layerName,
+                                                          bool recurseFlag=false)const;
+   
+   virtual ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                         const ossimString& layerId);
+   virtual const ossimPlanetTextureLayer* findLayerByNameAndId(const ossimString& layerName,
+                                                               const ossimString& layerId)const;
+   virtual ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                  bool recurseFlag=false);
+   virtual const ossimPlanetTextureLayer* findLayerById(const ossimString& layerId,
+                                                        bool recurseFlag=false)const;
+   
+   /**
+    * The empty tile color is used to return a tile that has color if there is 
+    * no texture in the group.  The color is a normalized float vector and the normal
+    * use is to pass in (osg::Vec4f(1.0,1.0,1.0,1.0),0).  This will enable the color if
+    * the level passed in is >= 0.
+    */
+   void setFillNullOrEmptyTileMaxLevel(ossim_int32 maxLevel=0);
+   
+   /**
+    * Set background fill color for partial tiles.  If a tile is partial it 
+    * will fill any invalid color with this value.
+    */
+   void setBackgroundColor(const osg::Vec4f& color);
+   void setFillTranslucentPixelsWithBackground(bool on=true);
+   
+   virtual void sortByGsd();
+   virtual ossimRefPtr<ossimXmlNode> saveXml(bool recurseFlag=true)const;
+   virtual bool loadXml(ossimRefPtr<ossimXmlNode> node);
+   
+protected:
+   bool containsLayerNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const;
+   bool removeLayerNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag);
+   osg::ref_ptr<ossimPlanetTextureLayer> removeLayerNoMutex(ossim_uint32 idx, bool notifyFlag);
+   std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > removeLayersNoMutex(ossim_uint32 idx, ossim_uint32 length=1, bool notifyFlag=true);
+   ossim_int32 findLayerIndexNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const;
+   
+   mutable OpenThreads::Mutex theChildrenListMutex;
+   std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > theChildrenList;
+   osg::ref_ptr<ossimPlanetTextureLayerCallback>    theChildListener;
+   
+   osg::Vec4f  theBackgroundColor;
+   ossim_int32 theFillEmptyNullTileMaxLevel;
+   bool        theFillTranslucentPixelsWithBackgroundEnabled;
+   
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerRegistry.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerRegistry.h
new file mode 100644
index 0000000..1dd3e3e
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTextureLayerRegistry.h
@@ -0,0 +1,40 @@
+#ifndef ossimPlanetTextureLayerRegistry_HEADER
+#define ossimPlanetTextureLayerRegistry_HEADER
+#include <OpenThreads/ReadWriteMutex>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetTextureLayerFactory.h>
+
+class OSSIMPLANET_DLL ossimPlanetTextureLayerRegistry : public osg::Referenced
+{
+public:
+   ossimPlanetTextureLayerRegistry();
+   virtual ~ossimPlanetTextureLayerRegistry();
+   static ossimPlanetTextureLayerRegistry* instance();
+
+   void registerFactory(ossimPlanetTextureLayerFactory* factory);
+   void registerFactoryToFront(ossimPlanetTextureLayerFactory* factory);
+   void unregisterFactory(ossimPlanetTextureLayerFactory* factory);
+   /**
+    * The passed in string could be a WMS http string, keyword list
+    * describing archives or a local image file, .. etc.  A layer will be returned.
+    *
+    * Note this layer could be a grouped layer.  For instance.  An image may have multiple
+    * handlers and will return a group of all images.
+    *
+    */ 
+   osg::ref_ptr<ossimPlanetTextureLayer> createLayer(const ossimString& name, bool openAllEntriesFlag=true)const;
+
+   
+protected:
+   ossimPlanetTextureLayerRegistry(const ossimPlanetTextureLayerRegistry& /*src*/):osg::Referenced(){}
+   const ossimPlanetTextureLayerRegistry& operator = (const ossimPlanetTextureLayerRegistry& /*src*/){return *this;}
+   bool containsFactory(ossimPlanetTextureLayerFactory* factory)const;
+   
+   static ossimPlanetTextureLayerRegistry* theInstance;
+   std::vector<ossimPlanetTextureLayerFactory* > theFactoryList;
+   mutable OpenThreads::ReadWriteMutex theFactoryListMutex;
+   mutable bool destroyingFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetThread.h b/ossimPlanet/include/ossimPlanet/ossimPlanetThread.h
new file mode 100644
index 0000000..dec043b
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetThread.h
@@ -0,0 +1,30 @@
+#ifndef ossimPlanetThread_HEADER
+#define ossimPlanetThread_HEADER
+#include <OpenThreads/Thread>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include "ossimPlanetThreadImp.h"
+#include "ossimPlanetExport.h"
+
+class ossimPlanetThreadPool;
+class OSSIMPLANET_DLL ossimPlanetThread : public osg::Referenced,
+                                         public OpenThreads::Thread
+{
+public:
+   ossimPlanetThread();
+   virtual void run();
+   virtual int cancel();
+   virtual void updateThreadBlock();
+   void setImplementation(ossimPlanetThreadImp* implementation);
+   void setThreadPool(ossimPlanetThreadPool* threadPool);
+   ossimPlanetThreadImp* implementation();
+   const ossimPlanetThreadImp* implementation()const;
+   void setRetainThreadFlag(bool flag);
+protected:
+   ossimPlanetThreadImp*  theImplementation;
+   ossimPlanetThreadPool*              theThreadPool;
+   bool                                theRetainThreadFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetThreadImp.h b/ossimPlanet/include/ossimPlanet/ossimPlanetThreadImp.h
new file mode 100644
index 0000000..8d44006
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetThreadImp.h
@@ -0,0 +1,38 @@
+#ifndef ossimPlanetThreadImp_HEADER
+#define ossimPlanetThreadImp_HEADER
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include "ossimPlanetExport.h"
+#include "ossimPlanetRefBlock.h"
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+class ossimPlanetThread;
+class OSSIMPLANET_DLL ossimPlanetThreadImp
+{
+public:
+   ossimPlanetThreadImp()
+      :theThread(0),
+       theDoneFlag(false) 
+   {
+   }
+   virtual ~ossimPlanetThreadImp();
+   virtual void setThread(ossimPlanetThread* thread)
+   {
+      theThread = thread;
+   }
+   ossimPlanetThread* thread()
+   {
+      return theThread;
+   }
+   virtual void run()=0;
+   virtual int cancel();
+   virtual void threadPooled();
+   virtual void setDoneFlag(bool flag);
+   virtual bool doneFlag()const;
+   virtual void updateThreadBlock();
+protected:
+   mutable ossimPlanetReentrantMutex theImpMutex;
+   ossimPlanetThread* theThread;
+   bool theDoneFlag;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetThreadPool.h b/ossimPlanet/include/ossimPlanet/ossimPlanetThreadPool.h
new file mode 100644
index 0000000..6ee458c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetThreadPool.h
@@ -0,0 +1,32 @@
+#ifndef ossimPlanetThreadPool_HEADER
+#define ossimPlanetThreadPool_HEADER
+#include <vector>
+#include <OpenThreads/Thread>
+#include <ossimPlanet/ossimPlanetReentrantMutex.h>
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+#include "ossimPlanetExport.h"
+
+class ossimPlanetThread;
+
+class OSSIMPLANET_DLL ossimPlanetThreadPool : public osg::Referenced
+{
+public:
+   static osg::ref_ptr<ossimPlanetThreadPool> instance();
+   void makeAvailable(osg::ref_ptr<ossimPlanetThread> thread);
+   osg::ref_ptr<ossimPlanetThread> nextAvailable();
+   static void setMaxThread(int maxThreads);
+   
+protected:
+   ossimPlanetThreadPool();
+
+   unsigned int totalThreads()const;
+   std::vector<osg::ref_ptr<ossimPlanetThread> > theAvailableList;
+   std::vector<osg::ref_ptr<ossimPlanetThread> > theUnavailableList;
+   ossimPlanetReentrantMutex            theListMutex;
+   static unsigned int theMaxThreads;
+   static osg::ref_ptr<ossimPlanetThreadPool> theInstance;
+
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetTileRequest.h b/ossimPlanet/include/ossimPlanet/ossimPlanetTileRequest.h
new file mode 100644
index 0000000..7604a12
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetTileRequest.h
@@ -0,0 +1,256 @@
+#ifndef ossimPlanetTileRequest_HEADER
+#define ossimPlanetTileRequest_HEADER
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <queue>
+#include <osg/observer_ptr>
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <osgUtil/IncrementalCompileOperation>
+class ossimPlanetTerrainTile;
+class ossimPlanetTerrain;
+
+class OSSIMPLANET_DLL ossimPlanetTileRequest : public ossimPlanetOperation
+{
+public:
+   struct SortFunctor
+   {
+      bool operator() (const osg::ref_ptr<ossimPlanetOperation>& lhs,
+                       const osg::ref_ptr<ossimPlanetOperation>& rhs) const
+      {
+         return (lhs->priority()>rhs->priority());
+      }
+      bool operator() (const osg::ref_ptr<ossimPlanetTileRequest>& lhs,
+                       const osg::ref_ptr<ossimPlanetTileRequest>& rhs) const
+      {
+         return (lhs->priority()>rhs->priority());
+      }
+   };
+   typedef std::queue<osg::ref_ptr<ossimPlanetTileRequest> > Queue;
+   typedef std::list<osg::ref_ptr<ossimPlanetTileRequest> > List;
+   typedef std::vector<osg::ref_ptr<ossimPlanetTileRequest> > Vector;
+   typedef std::set< osg::ref_ptr<osg::Texture> >               TextureSetList;
+   typedef std::set< osg::ref_ptr<osg::Drawable> >              DrawableList;
+   typedef std::set< osg::ref_ptr<osg::VertexBufferObject> >    VertexBufferList;
+   struct DataToCompile
+   {
+      TextureSetList   textures;
+      VertexBufferList vbos;
+   };
+   
+   class FindCompileableGLObjectsVisitor : public osg::NodeVisitor
+   {
+   public:
+      FindCompileableGLObjectsVisitor(DataToCompile& dataToCompile, 
+                                      ossimPlanetTerrain* terrain,
+                                      ossim_uint32 context):
+      osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+      theDataToCompile(dataToCompile),
+      theTerrain(terrain),
+      theContextId(context)
+      {
+      }
+      virtual void apply(osg::Node& node);
+      virtual void apply(osg::Geode& geode);
+      inline void apply(osg::StateSet* stateset);
+      inline void apply(osg::Drawable* drawable);
+      
+   protected:
+      ossimPlanetTileRequest::DataToCompile&      theDataToCompile;
+      const ossimPlanetTerrain*               theTerrain;
+      std::set<osg::ref_ptr<osg::Texture> >   theTextureSet;
+      std::set<osg::ref_ptr<osg::Drawable> >  theDrawableSet;
+      ossim_uint32                            theContextId;
+   };
+
+   ossimPlanetTileRequest()
+   {
+      setThreadSafeRefUnref(true);
+   }
+   ossimPlanetTileRequest(ossimPlanetTerrainTile* tile);
+   virtual void setTile(ossimPlanetTerrainTile* tile);
+   ossimPlanetTerrainTile* tile();
+   const ossimPlanetTerrainTile* tile()const;
+   bool needsToCompile()const
+   {
+      return true;
+   }
+   ossim_int32 frameNumberOfLastRequest()const{return theFrameNumberLastRequest;}
+   void setFrameNumberOfLastRequest(ossim_int32 num)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFrameNumberLastRequest = num;
+   }
+   bool isRequestCurrent(ossim_int32 frameNumber)const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return ((frameNumber-theFrameNumberLastRequest)<=1);
+   }
+   void setTimestampFirstRequest(double timeStamp)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theTimestampFirstRequest = timeStamp;
+      theTimestampLastRequest  = timeStamp;
+   }
+   double timeStampFirstRequest()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theTimestampFirstRequest;
+   }
+   void setTimestampLastRequest(double timeStamp)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theTimestampLastRequest = timeStamp;
+   }
+   double timestampLastRequest()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theTimestampLastRequest;
+   }
+   virtual void applyToGraph()
+   {
+      
+   }
+   virtual bool compileObjects(osg::RenderInfo& renderInfo,//osg::State* s, 
+                               double availableTimeInSeconds=9999999);
+   virtual bool populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                   osgUtil::IncrementalCompileOperation::CompileSet& compileSet);
+protected:
+   mutable OpenThreads::Mutex thePropertyMutex;
+   ossim_int32                theFrameNumberFirstRequest;
+   double                     theTimestampFirstRequest;
+   ossim_int32                theFrameNumberLastRequest;
+   ossim_float64              theTimestampLastRequest;
+   ossimPlanetTerrainTileId                  theTileId;
+   osg::observer_ptr<ossimPlanetTerrainTile> theTile;
+   osg::observer_ptr<ossimPlanetTerrain>     theTerrain;
+   DataToCompile theDataToCompile;
+};
+
+class OSSIMPLANET_DLL ossimPlanetSplitRequest : public ossimPlanetTileRequest
+{
+public:
+   ossimPlanetSplitRequest(){}
+   ossimPlanetSplitRequest(ossimPlanetTerrainTile* tile);
+   
+   virtual void run();
+   virtual void applyToGraph();
+   virtual bool compileObjects(osg::RenderInfo& renderInfo,//osg::State* s, 
+                               double availableTimeInSeconds=9999999);
+   virtual bool populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                   osgUtil::IncrementalCompileOperation::CompileSet& compileSet);
+   virtual void setTile(ossimPlanetTerrainTile* tile);
+protected:
+   ossimPlanetTerrainTechnique::TileIdList theNeededChildrenList;
+   std::vector<osg::ref_ptr<ossimPlanetTerrainTile> > theNewTiles;
+};
+
+class OSSIMPLANET_DLL ossimPlanetTextureRequest : public ossimPlanetTileRequest
+{
+public:
+   ossimPlanetTextureRequest();
+   ossimPlanetTextureRequest(ossimPlanetTerrainTile* tile, 
+                             ossim_uint32 imageLayerIdx);
+   virtual void run();
+   virtual void applyToGraph();
+   void setImageLayerIdx(ossim_uint32 idx)
+   {
+      std::vector<ossim_uint32> idxValues;
+      idxValues.push_back(idx);
+      setTextureLayerIndices(idxValues);
+   }
+   void setTextureLayerIndices(const std::vector<ossim_uint32>& values);
+   
+   virtual bool compileObjects(osg::RenderInfo& renderInfo,//osg::State* s, 
+                               double availableTimeInSeconds=9999999);
+   virtual bool populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                   osgUtil::IncrementalCompileOperation::CompileSet& compileSet);
+protected:
+   class Result
+   {
+   public:
+      osg::ref_ptr<ossimPlanetTexture2D> theTexture;
+      osg::ref_ptr<ossimPlanetImage> theImage;
+   };
+   typedef std::map<ossim_uint32, Result>  TextureResultMap;
+   TextureResultMap theResultList;
+};
+
+class OSSIMPLANET_DLL ossimPlanetElevationRequest : public ossimPlanetTileRequest
+{
+public:
+   ossimPlanetElevationRequest();
+   ossimPlanetElevationRequest(ossimPlanetTerrainTile* tile,
+                               ossim_uint32 width,
+                               ossim_uint32 height);
+   virtual void run();
+   virtual bool compileObjects(osg::RenderInfo& renderInfo,//osg::State* s, 
+                               double availableTimeInSeconds=9999999);
+    virtual bool populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                   osgUtil::IncrementalCompileOperation::CompileSet& compileSet);
+  virtual void applyToGraph();
+protected:
+   osg::ref_ptr<ossimPlanetTerrainTile> theNewMesh;
+   osg::ref_ptr<ossimPlanetImage> theImage;
+};
+
+class OSSIMPLANET_DLL ossimPlanetTileRequestQueue : public ossimPlanetOperationQueue
+{
+public:
+   ossimPlanetTileRequestQueue(bool sortFlag=true);
+   void sort();
+   virtual void add(ossimPlanetTileRequest* request);
+   virtual osg::ref_ptr<ossimPlanetOperation> nextOperation(bool blockIfEmptyFlag=true);
+   void setCurrentFrameNumber(ossim_int32 num)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRequestQueueMutex);
+      theCurrentFrameNumber = num;
+   }
+   void setSortFlag(bool flag)
+   {
+      theSortFlag = flag;
+   }
+   bool sortFlag()const
+   {
+      return theSortFlag;
+   }
+protected:
+   OpenThreads::Mutex theRequestQueueMutex;
+   ossim_int32 theCurrentFrameNumber;
+   bool theSortFlag;
+};
+
+class OSSIMPLANET_DLL ossimPlanetTileRequestThreadQueue : public ossimPlanetOperationThreadQueue
+{
+public:
+   ossimPlanetTileRequestThreadQueue ()
+   :ossimPlanetOperationThreadQueue()
+   {
+      setOperationQueue(new ossimPlanetTileRequestQueue());
+   }
+   virtual ~ossimPlanetTileRequestThreadQueue(){}
+   virtual void add(ossimPlanetTileRequest* request);
+   virtual void run();
+   void setCurrentFrameNumber(ossim_int32 num)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRequestThreadQueueMutex);
+      theCurrentFrameNumber = num;
+      ossimPlanetTileRequestQueue* tileQueue = dynamic_cast<ossimPlanetTileRequestQueue*>(operationQueue());
+      if(tileQueue)
+      {
+         tileQueue->setCurrentFrameNumber(num);
+      }
+   }
+   ossim_int32 currentFrameNumber()const
+   {
+      return theCurrentFrameNumber;
+   }
+   //void applyToGraph(double availableTime=2.5);
+protected:
+   OpenThreads::Mutex theRequestThreadQueueMutex;
+   ossim_int32 theCurrentFrameNumber;
+};
+
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetUtility.h b/ossimPlanet/include/ossimPlanet/ossimPlanetUtility.h
new file mode 100644
index 0000000..9f1abed
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetUtility.h
@@ -0,0 +1,29 @@
+#ifndef ossimPlanetUtility_HEADER
+#define ossimPlanetUtility_HEADER
+#include <osg/CoordinateSystemNode>
+#include <osg/Vec3d>
+#include "ossimPlanetExport.h"
+
+class OSSIMPLANET_DLL ossimPlanetUtility
+{
+public:
+   static double getMaxDistance()
+      {
+         return 1.0e10;
+      }
+   static osg::Vec3d normal(const osg::EllipsoidModel& model,
+                            double x, double y, double z);
+   static void ellipsoidToXYZ( const osg::EllipsoidModel& model,
+                               double latitude, double longitude, double height,
+                               double &x, double &y, double &z);
+   static void XYZToEllipsoid( const osg::EllipsoidModel& model,
+                               double x, double y, double z,
+                               double& latitude, double& longitude, double& height);
+
+   static bool intersectsEllipsoid(const osg::EllipsoidModel& model,
+                                   osg::Vec3d& intersection,
+                                   const osg::Vec3d& start,
+                                   const osg::Vec3d& end);
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayer.h
new file mode 100644
index 0000000..fcb1b5d
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayer.h
@@ -0,0 +1,61 @@
+#ifndef ossimPlanetVideoLayer_HEADER
+#define ossimPlanetVideoLayer_HEADER
+#include "ossimPlanetLayer.h"
+#include <ossim/base/ossimFilename.h>
+#include <ossimPlanet/ossimPlanetVideoLayerNode.h>
+
+class ossimPlanet;
+class OSSIMPLANET_DLL ossimPlanetVideoLayer : public ossimPlanetLayer
+{
+public:
+   ossimPlanetVideoLayer()
+   {
+   }
+   virtual osg::Object* cloneType() const { return new ossimPlanetVideoLayer(); }
+   virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ossimPlanetVideoLayer *>(obj)!=0; }
+   virtual const char* className() const { return "ossimPlanetVideoLayer"; } 
+   virtual const char* libraryName() const { return ""; }
+   
+   virtual void traverse(osg::NodeVisitor& nv);
+
+   virtual bool add(const ossimFilename& file);
+
+   
+   virtual bool addChild( Node *child )
+   {
+      if(dynamic_cast<ossimPlanetVideoLayerNode*>(child))
+      {
+         return ossimPlanetLayer::addChild(child);
+      }
+      return false;
+   }
+   virtual bool insertChild( unsigned int index, Node *child )
+   {
+      if(dynamic_cast<ossimPlanetVideoLayerNode*>(child))
+      {
+         return ossimPlanetLayer::insertChild(index, child);
+      }
+      return false;
+      
+   }
+   virtual bool replaceChild( Node *origChild, Node* newChild )
+   {
+      if(dynamic_cast<ossimPlanetVideoLayerNode*>(newChild))
+      {
+         return ossimPlanetLayer::replaceChild(origChild, newChild);
+      }
+      return false;
+   }
+   virtual bool setChild( unsigned  int i, Node* node )
+   {
+      if(dynamic_cast<ossimPlanetVideoLayerNode*>(node))
+      {
+         return ossimPlanetLayer::setChild(i, node);
+      }
+      return false;
+   }
+
+   
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayerNode.h b/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayerNode.h
new file mode 100644
index 0000000..c01eca7
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetVideoLayerNode.h
@@ -0,0 +1,72 @@
+#ifndef ossimPlanetVideoLayerNode_HEADER
+#define ossimPlanetVideoLayerNode_HEADER
+#include <ossimPlanet/ossimPlanetAnnotationLayerNode.h>
+#include <ossim/base/ossimFilename.h>
+
+class ossimPlanetVideoLayer;
+/**
+ * 
+ * I will eventually have this do the drawing and let the derived classes just populate the geometries.
+ * For now,  I will put the implementation in ossimPlanetPredatorVideoLayerNode and move implementations out
+ * as we finish and test them.
+ * 
+ */ 
+class OSSIMPLANET_DLL ossimPlanetVideoLayerNode : public ossimPlanetAnnotationLayerNode
+{
+public:
+   enum Status
+   {
+      STATUS_NONE = 0,
+      STATUS_PLAYING,
+      STATUS_PAUSED
+   };
+   enum RenderMode
+   {
+      RENDER_SCREEN   = 0,
+      RENDER_BILLBOARD = 1,
+      RENDER_OVERLAY  = 2 
+   };
+   ossimPlanetVideoLayerNode(ossimPlanetVideoLayer* layer):theLayer(layer){}
+   virtual ~ossimPlanetVideoLayerNode(){}
+   virtual bool open(const ossimFilename& file)=0;
+	
+   virtual void pause()=0;
+   virtual void rewind()=0;
+   virtual void play()=0;
+   virtual ossim_float64 duration()const=0;
+   virtual ossimPlanetVideoLayerNode::Status status()const = 0;
+   virtual void setReferenceTime(ossim_float64 reference)=0;
+   virtual ossim_float64 referenceTime()const=0;
+   virtual ossimPlanetVideoLayerNode::RenderMode renderMode()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theVideoLayerNodeMutex);
+      return theRenderMode;
+   }
+   virtual void setRenderMode(ossimPlanetVideoLayerNode::RenderMode mode)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theVideoLayerNodeMutex);
+      theRenderMode = mode;
+   }
+   
+   void setVideoLayer(ossimPlanetVideoLayer* layer)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theVideoLayerNodeMutex);
+      theLayer = layer;
+   }
+   ossimPlanetVideoLayer* videoLayer()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theVideoLayerNodeMutex);
+      return theLayer;
+   }
+   const ossimPlanetVideoLayer* videoLayer()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theVideoLayerNodeMutex);
+      return theLayer;
+   }
+	
+protected:
+   mutable ossimPlanetReentrantMutex   theVideoLayerNodeMutex;
+   ossimPlanetVideoLayer*                theLayer;
+   ossimPlanetVideoLayerNode::RenderMode theRenderMode;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetViewMatrixBuilder.h b/ossimPlanet/include/ossimPlanet/ossimPlanetViewMatrixBuilder.h
new file mode 100644
index 0000000..57b036c
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetViewMatrixBuilder.h
@@ -0,0 +1,680 @@
+#ifndef ossimPlanetViewMatrixBuilder_HEADER
+#define ossimPlanetViewMatrixBuilder_HEADER
+#include <osg/Matrix>
+#include <osg/Node>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetPointModel.h>
+#include <ossimPlanet/ossimPlanetLsrSpaceTransform.h>
+#include <osg/ref_ptr>
+
+/**
+ * The view matrix builder serves several purposes. It can be used to allow one to do free form manipulation of the scene
+ * based on position and euler heading pitch roll orientation.  Also, one can use the class to "track" another node whether
+ * you are a fixed point looking at a moving object or a moving object looking at another moving object or a moving object
+ * looking at a fixed point or looking from a fixed point to a fixed point.  To support all these scenarios we have decomposed
+ * the stages internally to build the matrix into self contained paramters where each can be adjusted by a maniopulator.
+ * Tracking in the true since of the word is really done by the ossimPlanetManipulator which owns a ViewMatrixBuilder and listens
+ * for changes in nodes that either we are looking from or looking to and adjusts the paramters of the view matrix accordingly.
+ *
+ *
+ * Each parameter updates the matrix at it's defined stage.  The multiplication or building up the final view matrix is done  
+ * in the following steps:
+ * <pre>
+ *  Step 1 - Compute a Lsr Matrix with the current "from" Lat lon height position and a composited orientation
+ *           created based on the "from" Heading Pitch and Roll and the Relative Heading Pitch and Roll and relative flags.
+ *  Step 2 - Apply the From displacement to the current oriented axis.  The from displacement will shift the
+ *           "from" eye position to a displacement relative to the position and orientation of the matrix from Step 1.  Each
+ *           X, Y, Z value in the displacement vector is multiplied by the axis of the rotational matrix and added to 
+ *           the Step 1's origin defined by the from Lat lon height in world  X, Y, Z space.
+ *  Step 3 - Calculate a look vector at this point based on the Look vector alignment.  The default alignment is
+ *           to position the look direction along the positive Y-Axis.  We will use this vector for other calculations
+ *           in later steps.
+ *  Step 4 - Displacement along the look axis calculated in Step 3 a "from range" distance.
+ *  Step 5 - If there is no "to" information set then we create a lookAt view matrix using OSG's make look at by using the 
+ *           look vector calculated in Step 3.  If there is a look "to" information set then goto Step 8.
+ *  Step 6 - If the "to" information is set then first redefine a look vector that looks along the axis to the point you
+ *           are looking at.
+ *  Step 7 - Now apply 2 displacments.  The "ToRange" is a convenient displacement that could be achieved by using just
+ *           the z component of the to displacment. The "to range" is added to the Z component of the "to displacement".
+ *           the displacement is then applied to the axis created by using the look vector calculated in Step 6 and the makeLookAt 
+ *           utility supplied to us by OSG.  This will create an orientation axis and we display the current displaced eye point
+ *           calculated in the from stage along the new axis.
+ * Step 8 - Apply the final Attitude to allow one to look around.
+ * </pre>
+ *
+ * How to use the view matrix builder.
+ * 
+ * - Free form manipulation where you are just wanting to move the eye around. the paramters typically used are the 
+ *   "from Lat lon Height" and the from Heading pitch and roll.  The from Realtive flags should be set to ALL and the relative
+ *   heading pitch roll and all other values should be zeroed out.  The to information should be invalidated and not set.
+ * 
+ * - fixed point. you can set the from information to a fixed location and allow yourself to spin around the fixed point
+ *   by adjusting the from range and look axis and the from heading pitch and roll.  I would default the relative orientation to 0's 
+ *   and the relative orientation flags to ALL.
+ *
+ * - fixed point to fixed point.  There are 2 ways to implement this type of situation.  The little bit harder one to setup
+ *   is to use it all as a from point with a range displacement.  So you could orient the From HPR axis and do a negative
+ *   range displacement along the look direction for the from orientation.  The easier to control and setup is to treat the point
+ *   to point type implementation as a "from to" setting.  So we set the from position Lat Lon Height and the point you are looking
+ *   at Lat Lon Height.  We then set the orientaiton information for the from axis to all 0 and relative to all.  This will use the 
+ *   normal of the local tangent axis at the from position for the calculation of a "make look at".  This will also keep the horizon 
+ *   level.
+ *
+ * - fixed point to a node.  Currently we only support orientation and positional lookups for nodes that are or contain a node of 
+ *   type ossimPlanetPointModel or of type ossimPlanetLsrSpace.  We will later add some of OSG's position attitude models.  The 
+ *   view matrix does not auto track but auto tracking is done outside the class (@see ossimPlanetManipulator). Since the node is
+ *   the "to" node the orientation information is not used from the passed in node.  We only use the transform to get the global 
+ *   position of the node in Lat Lon Height.  The from position is fixed and should use te set routines that do not take a from node.
+ *   to keep the horizon pretty much level you can set the "from fixed point" orientation to all 0 for from HPR and from Relative HPR
+ *   and make relative flags set to all relative.  This will use the normal to the tangent plane as the up axis used in the calculation 
+ *   of the makeLookAt call.
+ *
+ * - node to fixed point. How the look to the fixed point is oriented will depend on the settings of the relative orientation flags.
+ *   the from point is created from the nodes location and then the orientation is grabbed from the node.  We currently only support
+ *   locating an ossimPlanetLsrSpace somewhere as a child of node and we also can detect ossimPlanetPointModel.  
+ *   The orientation of the lsr space and the location of the point model is used to populate the from information.  
+ *   The relative flags used will dtermine how the eye tilts when doing a lookat vector to the fixed point.  If you want it to 
+ *   not allow the horizon to move but stay level then I would do a NOR ORIENTATION FLAG and the relative HPR values are actually
+ *   used in the orientation and so giving them the value of all 0 should keep the horizon level.
+ *
+ * - node to node. Node to node is nothing different than the node to fixed point but in the ossimPlanetManipulator it just keeps
+ *   tracking the "to" node.  The tilting that occurs depends on how you set up the from information orientation and relative 
+ *   orientation and the relative orientation flags.
+ */
+class OSSIMPLANET_DLL ossimPlanetViewMatrixBuilder : public osg::Referenced
+
+{
+public:
+   class OSSIMPLANET_DLL Visitor : public osg::NodeVisitor
+   {
+   public:
+      Visitor();
+      virtual void apply(osg::Node& node);
+      virtual void reset()
+      {
+         thePointModel = 0;
+         theLsrSpaceTransform = 0;
+      }
+      osg::ref_ptr<ossimPlanetPointModel> thePointModel;
+      osg::ref_ptr<ossimPlanetLsrSpaceTransform> theLsrSpaceTransform;
+   };
+   /**
+    * These are used as flags for defining relative orientation axis for passed in
+    * heading, pitch, and roll.
+    */
+   enum OrientationFlags
+   {
+      NO_ORIENTATION = 0,
+      HEADING        = 1,
+      PITCH          = 2,
+      ROLL           = 4,
+      ALL_ORIENTATION = (HEADING|PITCH|ROLL)
+   };
+
+   /**
+    * Look axis.  Once a defined orientation is created you have the option to define a LOOK axis.
+    */
+   enum LookAxis
+   {
+      LOOK_AXIS_X = 0,
+      LOOK_AXIS_NEGATIVE_X,
+      LOOK_AXIS_Y,
+      LOOK_AXIS_NEGATIVE_Y,
+      LOOK_AXIS_Z,
+      LOOK_AXIS_NEGATIVE_Z
+   };
+   /**
+    * Allow one to construct an empty geo ref model.  We need it to have this option
+    * For some nodes in a graph that use this will not know about a model until it's added
+    * to a graph.
+    *
+    * @param geoRefModel Pass in an optional geo ref model during construction time.  If not
+    *                    set here you need to set it with the setGeoRefModel before calling
+    *                    the viewMatrix and inverseViewMatrix methods.
+    */
+   ossimPlanetViewMatrixBuilder(ossimPlanetGeoRefModel* geoRefModel=0);
+
+   ossimPlanetViewMatrixBuilder(const osg::Matrixd& m, ossimPlanetGeoRefModel* geoRefModel);
+   /**
+    * Copy constructor
+    */
+   ossimPlanetViewMatrixBuilder(const ossimPlanetViewMatrixBuilder& src);
+
+   /**
+    * clone method.  Will return an allocated copy of this object.
+    */
+   virtual ossimPlanetViewMatrixBuilder* clone(){return new ossimPlanetViewMatrixBuilder(*this);}
+
+   /**
+    * Standard destructor
+    */
+   virtual ~ossimPlanetViewMatrixBuilder();
+
+   /**
+    * Sets the GeoRefModel used for coordinate transformations.
+    *
+    * @param geoRefModel the current model used for coordinate transformations
+    *
+    */
+   void setGeoRefModel(ossimPlanetGeoRefModel* geoRefModel);
+
+   /**
+    * Basic access method.
+    *
+    * @return the stored geo ref model
+    */
+   const ossimPlanetGeoRefModel* geoRefModel()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theModel.get();
+   }
+   ossimPlanetGeoRefModel* geoRefModel()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theModel.get();
+   }
+   
+   /**
+    * This method allows you to define a view that tracks a node.  You can eather sit
+    * at the node's defined center of mass or displace a distance "range" along line of site and/or 3d vector displacement.
+    * the relative orientation flag defines how the heading pitch roll argument is to be used
+    * to calculate the final orientation.  if any flag is set for Heading, Pitch, and/or roll then
+    * that orientation parameter is relative to that orientation defined in the axis of the node.  If
+    * any flag is not set then it is relative to the East North Up axis.  So if you want a camera to
+    * always say rotate with the heading of that node then you will just set the HEADING flag in
+    * the relativeOrientationFlag.
+    *
+    * @param node  This is the node you wish this ViewMatrixBuilder to Lock to.
+    * @param hpr   The passed in Heading Pitch and Roll to apply in angular degrees.
+    * @param range The meter distance along the look axis.
+    * @param relativeOrientationFlag Which orientation parameter(s) do you wish to be relative
+    *                                to the Node's Axes.  A value of ALL_ORIENTATION and a hpr
+    *                                parameter of all 0's will allow you to rotate with the object.
+    */
+   void setLookFromNodeOffset(osg::Node* node,
+                              const osg::Vec3d& hpr,
+                              double range,
+                              int relativeOrientationFlag);
+
+   /**
+    * This allows for a look from displacement.  So for instance if you want to
+    * position the camera truly in the cockpit and not the center of mass used for the local
+    * space transform you can do so.  Currently this displacment will follow the local point
+    * center of mass relative to the orientation axis of the plane.
+    *
+    * @param displacement This takes a local space displacement in meters and positions along
+    *                     the orientation of the node or current relative axis the amount to
+    *                     displace to the new center.
+    */
+   void setLookFromLocalDisplacement(const osg::Vec3d& displacement)
+   {
+      updateFromLocalDisplacement(displacement);
+   }
+   
+   /**
+    * This was added to keep a name consistency problem.
+    */
+   void updateFromLocalDisplacement(const osg::Vec3d& displacement);
+   
+   void updateFromPositionLlh(const osg::Vec3d& llh)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFromNode        = 0;
+      theFromPositionLLH = llh;
+   }
+   void updateFromRange(double range)
+   {
+     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+     theFromRange = range;
+     setComputeViewMatrixFlag(true);
+   }
+   void updateFromRelativeHpr(const osg::Vec3d& hpr)
+   {
+     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+     theFromRelativeHpr = hpr;
+     setComputeViewMatrixFlag(true);
+   }
+   void updateFromHpr(const osg::Vec3d& hpr)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFromHpr = hpr;
+      setComputeViewMatrixFlag(true);
+   }
+   void updateFromRelativeOrientationFlag(int relativeOrientationFlag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFromRelativeOrientationFlags = (OrientationFlags)relativeOrientationFlag;
+      setComputeViewMatrixFlag(true);
+   }
+   void updateFromNode(osg::Node* node)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFromNode = node;
+      setComputeViewMatrixFlag(true);
+   }
+   /**
+    * @return The current from node.
+    */
+   osg::Node* fromNode()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromNode.get();
+   }
+   const osg::Vec3d& fromLocalDisplacement()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromDisplacement;
+   }
+   
+   /**
+    * This is the starting from position in lat lon height form.  This does not
+    * include the displacement information or range information.
+    *
+    * @return the from position in lat lon height.
+    */
+   const osg::Vec3d& fromPositionLlh()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromPositionLLH;
+   }
+   
+   /**
+    * This is for the relative heading pitch and roll setting done in the set
+    * relative to a Node call.  Also,  the internal matrix builder will set
+    * the relative positioning if setting using the fixed point method.
+    *
+    * @return the realtive Hpr setting.
+    */
+   const osg::Vec3d& fromRelativeHpr()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromRelativeHpr;
+   }
+   
+   /**
+    * @return the current setting for the relative orientation flags.
+    */
+   OrientationFlags fromRelativeOrientationFlags()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromRelativeOrientationFlags;
+   }
+   
+   /**
+    * This will give a composited from orientation based on the Relative flags.  Internally the source orientation could
+    * be changing each frame and the rleative orientation offsets the source orientation vector based on the orientation flags.
+    * this is a utility function to allow one to call this in a single call.
+    *
+    * @return the composited orientation vector for heading pitch and roll in degrees.
+    */
+   osg::Vec3d computeFromOrientation()const;
+   
+   /**
+    * This is the from source orietation vector.
+    *
+    * @return the from Heading pitch ad roll as a vec3d.
+    */
+   const osg::Vec3d& fromHpr()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromHpr;
+   }
+   
+   /**
+    * @return the from range value in meters.
+    */
+   double fromRange()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromRange;
+   }
+   
+   /**
+    * @return The current from node as a constant value
+    */
+   const osg::Node* fromNode()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theFromNode.get();
+   }
+   
+   /**
+    * This method allow you to set fixed point to look from with a defined orientation and
+    * a displacement along the look as defined by the "range" parameter.
+    *
+    * @param llh This is the <lattitude, longitude, height> where the lat and lon are expressed
+    *            in angular degrees and the height is in meters.
+    *
+    * @param hpr This is the <Heading, Pitch, Roll> parameters for the orietation axis relative
+    *            to the local tangent plane defined by the point llh.  The values are in
+    *            angular degrees.
+    *
+    * @param range This indicates the displacement from the axis origin along the line of site or look
+    *              vector.  Negative value displaces backwards from the look and positive displaces
+    *              along the direction of the resulting look.
+    */
+   void setLookFrom(const osg::Vec3d& llh,
+                    const osg::Vec3d& hpr,
+                    double range);
+
+   /**
+    * If a look to node is specified some of the look from parameters are overriden since the orientation
+    * is dictated by the resulting look vector to the "look to" node that is passed in here.
+    *
+    * @param node The node you wish to look to.  It will take the node passed in and use it's
+    *             center point information to define to help define a look direction as a vector
+    *             going from the "from" location to the "to" node.
+    *
+    */
+   void setLookToNode(osg::Node* node);
+
+   /**
+    * This is a method to define a fixed look to point.
+    *
+    * @param llh This is a <lattitude, longitude, height> vector and the lat and lon are in
+    *            angular degrees and the height is in meters.
+    */
+   void setLookTo(const osg::Vec3d& llh);
+
+
+   /**
+    * This allows for a look to displacement. This displaces along the look axis the amount along
+    * the x, y, and z.  This is applied after the from axis orientation and positioning is performed
+    *
+    * @param displacement This takes a local space displacement in meters and positions along
+    *                     the orientation of the node or current relative axis the amount to
+    *                     displace to the new center.
+    */
+   void setLookToLocalDisplacement(const osg::Vec3d& dispalcement);
+
+   /**
+    *  This allows one to specify a displacement along the look axis to the point you are looking.
+    *  This is applied after the look to local displacement.
+    */
+   void setLookToRange(double range);
+
+   /**
+    * Sets the global range.  This is applied in the direction of the view matrix look.
+    *
+    * @param range The range is in meters.
+    */
+   void setRange(double range);
+   
+   /**
+    * Returns the range
+    */
+   double range()const;
+   /**
+    * This is the last applied transform and will generate the final orientation matrix for
+    * the view.  This is done after a look from and to calculations and allows one to move the
+    * head around.
+    *
+    * @param hpr  This is the relative heading pitch and roll about the final orientation axis.
+    *
+    */
+   void setAttitudeHpr(const osg::Vec3d& hpr)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theAttitudeHpr = hpr;
+      setComputeViewMatrixFlag(true);
+
+   }
+
+   /**
+    * @return The attitude of the final look position.  This is the Heading pitch and roll
+    *         relative to the final orientation axes.
+    */
+   const osg::Vec3d& attitudeHpr()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theAttitudeHpr;
+   }
+
+    /**
+    * @return The to information set flag.  A value of true specifies that
+    *         the look to information was set
+    */
+   bool toInformationSetFlag()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToInformationSetFlag;
+   }
+   /**
+    *  @return The current to node.
+    */
+   osg::Node* toNode()
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToNode.get();
+   }
+
+   /**
+    *  @return The current to node as a constant value.
+    */
+   const osg::Node* toNode()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToNode.get();
+   }
+
+   /**
+    * This should only be called if a look to was set.
+    *
+    * @return the Look to position lat lon height as a Vec3d.
+    */
+   const osg::Vec3d& toPositionLlh()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToPositionLLH;
+   }
+   
+   /**
+    * This is a displacement along the current Rotational axis.
+    */
+   const osg::Vec3d& toDisplacement()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToDisplacement;
+   }
+   
+   /**
+    */
+   double toRange()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theToRange;
+   }
+
+   /**
+    * This allows one to change the look axis you wish to look down.
+    * After the orientation is applied you can set the look axis you wish
+    * to use.  This is not used if you are looking at another node or a fixed point
+    * for the look direction is already known.  This is used only when you are in a
+    * from location only and will allow you to swap between axis to look down.  So you
+    * can easily look up, down, left, right, ... etc
+    *
+    * @param LookAxis The axis to look down,  see LookAxis enumeration for possible
+    *                  values.
+    */
+   void setLookAxis(LookAxis axis)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theLookAxis = axis;
+      setComputeViewMatrixFlag(true);
+   }
+   /**
+    * @return The current look axis.
+    */
+   LookAxis lookAxis()const
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      return theLookAxis;
+   }
+
+   /**
+    * This matrix you can think of as placing objects out into the scene.
+    * Basically a local to world transform.
+    * @return the composited view Matrix as defined by the look to and from parameter settings.
+    */
+   const osg::Matrixd& viewMatrix()const;
+
+   /**
+    * This takes world coordinates and puts it into this local orientation.  This is typically
+    * used to set a Camera Matrix.  Call this to set a osg::Camera matrix or to set a manipulators
+    * setByMatrix.
+    *
+    * @return The inverse of the view matrix.
+    */
+   const osg::Matrixd& inverseViewMatrix()const;
+
+   /**
+    * Returns true or false if there is enough information to compute a matrix.  We will need the
+    * geoRefModel for coodrinate transformations and at least the From point information
+    * needs to be set.
+    *
+    * @return true if a call to viewMatrix would be valid or false otherwise.
+    */
+   bool isValid()const{return (theModel.valid()&&theFromInformationSetFlag);}
+
+   void setFromInformationSetFlag(bool flag)
+    {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theFromInformationSetFlag = flag;
+    }
+   void setToInformationSetFlag(bool flag)
+    {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theToInformationSetFlag = flag;
+    }
+   
+   /**
+    * @see setParametersByMatrix.
+    *
+    * This just wraps the call to the setParamtersByMatrix to invert the 
+    * passed in matrix.
+    *
+    * @param m Inverted matrix.
+    */
+   void setParametersByInverseMatrix(const osg::Matrixd& m)
+   {
+      osg::Matrixd newM(osg::Matrixd::inverse(m));
+      setParametersByMatrix(newM);
+   }
+   
+   /**
+    *
+    * Allows one to extract the absolute position and orientation of the composited
+    * view matrix.  We still have a problem if the viewMatrix has a roll component influencing
+    * the solution.  We don't get an exact inverse.
+    *
+    */
+   virtual bool extractCompositedLlhHprParameters(osg::Vec3d& llh,
+                                                 osg::Vec3d& hpr)const;
+   
+   /**
+    * This will take a matrix and flatten the parameters of the ViewMatrixBuilder to be purely a from
+    * unlocked type ViewMatrixBuilder.  It will take the matrix passed in and extract out the eye position
+    * and orientation hpr.  All other values such as range any to values will be zeroed out.  All nodes
+    * that we were locked to will be nulled out.
+    *
+    * @param m The matrix to use to convert the ViewMatrixBuilder to.
+    *
+    */
+   virtual void setParametersByMatrix(const osg::Matrixd& m);
+   
+   /**
+    * Converts the paramters to a from only.  If the range is to be preserved by setting
+    * the flatten range flag to false and there is a to point that we are looking at then 
+    * it will preserve the distance in the from range and setup a from only paramter ViewMAtrixBuilder.
+    *
+    * When using this call the Attitude orientation is not taken into account since this is used as a final 
+    * displacement.  So,  the Attitude values are preserved but are removed from the orientation calculation
+    * for the new from HPR.
+    *
+    */
+   virtual void convertToAFromViewMatrix(bool flattenRangeFlag = false);
+   void invalidateFrom()
+   {
+     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+     theFromInformationSetFlag = false;
+     theFromNode = 0;
+   }
+   void invalidateTo()
+   {
+     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theToInformationSetFlag = false;
+      theToNode = 0;
+   }
+   void invalidate()
+   {
+     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+     theFromInformationSetFlag = false;
+      theFromNode = 0;
+      theToNode   = 0;
+   }
+protected:
+   /**
+    * Sets an internal flag to say that the view matrix needs to be recomputed.
+    *
+    * @param flag a true value will have the next call to viewMatrix or viewInverseMatrix
+    *        recalculate the matrices.
+    */
+   void setComputeViewMatrixFlag(bool flag)
+   {
+      theComputeViewMatrixFlag = flag;
+   }
+
+   /**
+    * Returns the view matrix flag
+    */
+   bool computeViewMatrixFlag()const
+   {
+      return theComputeViewMatrixFlag;
+   }
+
+   /**
+    * Recomputes the view matrix based on all the from and to paraemters.
+    */
+   virtual void computeMatrices()const;
+
+   /**
+    * Thread sync mutex for multiple threads hitting the object.
+    */
+   mutable OpenThreads::ReentrantMutex thePropertyMutex;
+
+   /**
+    * A referenced pointer to the current Model in planet.
+    */
+   osg::ref_ptr<ossimPlanetGeoRefModel> theModel;
+
+   /**
+    * The look axis for defining whihc axis to look down when in
+    * view mode only.
+    */
+   LookAxis                theLookAxis;
+
+   bool                    theFromInformationSetFlag;
+   osg::ref_ptr<osg::Node> theFromNode;
+   osg::Vec3d              theFromPositionLLH;
+   osg::Vec3d              theFromRelativeHpr;
+   OrientationFlags        theFromRelativeOrientationFlags;
+   osg::Vec3d              theFromHpr;
+   double                  theFromRange;
+   osg::Vec3d              theFromDisplacement;
+
+   bool                    theToInformationSetFlag;
+   osg::ref_ptr<osg::Node> theToNode;
+   osg::Vec3d              theToPositionLLH;
+   osg::Vec3d              theToDisplacement;
+   double                  theToRange;
+   
+   osg::Vec3d              theAttitudeHpr;
+   double                  theRange;
+   mutable osg::Matrix     theViewMatrix;
+   mutable osg::Matrix     theInverseViewMatrix;
+   mutable bool            theComputeViewMatrixFlag;
+};
+
+#endif // OSSIMPLANETVIEWMATRIXBUILDER_H_
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetViewer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetViewer.h
new file mode 100644
index 0000000..04e2f27
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetViewer.h
@@ -0,0 +1,487 @@
+#ifndef ossimPlanetViewer_HEADER
+#define ossimPlanetViewer_HEADER
+#include <osgDB/DatabasePager>
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetCallback.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <osgViewer/Viewer>
+//#include <osgViewer/Renderer>
+#include <ossimPlanet/ossimPlanet.h>
+#include <osg/ref_ptr>
+#include <osg/Node>
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <osgUtil/LineSegmentIntersector>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetAnnotationLayer.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+#include <OpenThreads/Mutex>
+
+class ossimPlanetManipulator;
+class ossimPlanetViewer;
+class OSSIMPLANET_DLL ossimPlanetViewerCallback : public ossimPlanetCallback
+{
+public:
+   virtual void viewChanged(ossimPlanetViewer* /*viewer*/){}
+};
+
+/**
+ *
+ * ossimPlanetViewer will serve as a higher level interface to most of the ossimPlanet's inner workings.  During the update phase it will determine if
+ * the scnee graph is in a static state ad will notify the user through a virtual method callback.  At the time of this documentation we have not written then API
+ * to auto setup the planet node.  This is an example to setup the planet node and then set it to the Viewer.  Note, this code will eventually be moved into 
+ * a single setup routine on ossimPlanetViewer.
+ *
+ * <pre>
+ *    viwer->addEventHandler( new osgGA::StateSetManipulator(theCanvas->getCamera()->getOrCreateStateSet()));
+ *    viewer->addEventHandler(new osgViewer::StatsHandler());
+ *    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
+ *    osg::ref_ptr<ossimPlanet> planet = new ossimPlanet;
+ *    planet->setupDefaults();
+ *    planet->land()->setCurrentFragementShaderType(ossimPlanetShaderProgramSetup::NO_SHADER);
+ *    viewer->setSceneData(planet.get());
+ *    viewer->addImageTexture("/data/earth/earth.jpg");
+ *
+ *    viewer->setCameraManipulator(new ossimPlanetManipulator());
+ * </pre>
+ *
+ * this example sets some GUI action handlers supported by OSG.  We allocate a planet and then call planets setupDefaults().
+ * I then set the scene to the viewer and then add an image to the earth.  The last thing we did was setup the manipulator that will
+ * manipulate the eye matrix of OSG.  We have our own manipulator called ossimPlanetManipulator.
+ */
+class OSSIMPLANET_DLL ossimPlanetViewer : public osgViewer::Viewer, 
+                                          public ossimPlanetCallbackListInterface<ossimPlanetViewerCallback>,
+                                          public ossimPlanetActionReceiver
+
+{
+public:
+   class InitializePointersVisitor;
+   friend class InitializePointersVisitor;
+
+   /**
+    * PickObject is used to hold the node path information when picking objects
+    * in the scene.  For each object intersected a complete node path is stored.  
+    * A higher level api is placed on PickObject to give access to the most common attributes.
+    *
+    * <pre>
+    * Exmaple usage:
+    *  assume we have a pointer to ossimPlanetViewer called viewer and we have variables wx and wy at the window location
+    *  to pick.
+    *
+    *  std::vector<osg::ref_ptr<PickObject> > pickResult,
+    *  viewer->pickAtWindowCoordinate(pickResult, wx,wy);
+    *
+    *  if(pickResult.size() > 0)
+    *  {
+    *    // now access the Picked objects.
+    *  }
+    * </pre>
+    */
+   class OSSIMPLANET_DLL PickObject : public osg::Referenced
+   {
+   public:
+      typedef std::vector<osg::ref_ptr<osg::Node> > Path;
+      /**
+       * Used by the intersection routines to construct all the default values for the object.
+       */
+      PickObject(const osg::NodePath& nodePath, 
+                 const osg::Vec3d& localPoint,
+                 const osg::Vec3d& worldPoint,
+                 const osg::Vec3d& llh)
+      :theNodePath(nodePath.begin(), nodePath.end()),
+       theLocalPoint(localPoint),
+       theWorldPoint(worldPoint),
+       theLatLonHeightPoint(llh)
+      {}
+      
+      /**
+       * @return the objects local point
+       */
+      const osg::Vec3d& localPoint()const{return theLocalPoint;}
+      
+      /**
+       * @param value local point
+       */
+      void setLocalPoint(osg::Vec3d& value){theLocalPoint = value;}
+      
+      /**
+       * This will return the objects world point.  Note this is in the space that the x,y,z coordinates are in
+       * So if normalized ellipsoidalmode then values are in normalized ellipsoid. 
+       */
+      const osg::Vec3d& worldPoint()const{return theWorldPoint;}
+      
+      /**
+       * @param value world point
+       */
+      void setWorldPoint(osg::Vec3d& value){theWorldPoint = value;}
+      
+      /**
+       * This returns the lat, lon, height in the mode of the model.  By default the model uses wgs84 horizontal
+       * datum.  The height is currently not shifted relative to any geoid so it is an ellipsoidal height at this point.
+       */
+      const osg::Vec3d& llh()const{return theLatLonHeightPoint;}
+      void setllh(const osg::Vec3d& value){theLatLonHeightPoint = value;}
+      
+      /**
+       * Will search the node path and return a pointer to the ossimPlanetNode that is first encountered. If
+       * no ossimPlanetNode is encountered then null is returned
+       */
+      ossimPlanetNode* firstPlanetNode();
+      
+   protected:
+      ossimPlanetViewer::PickObject::Path theNodePath;
+      osg::Vec3d theLocalPoint;
+      osg::Vec3d theWorldPoint;
+      osg::Vec3d theLatLonHeightPoint;
+   };
+   
+   /**
+    * The NodeListener is used internally to ossimPlanetViewer to listen to things in the graph so it can effectively 
+    * determine if a graph is at a static state.
+    */
+   class OSSIMPLANET_DLL NodeListener: public ossimPlanetNodeCallback
+      {
+      public:
+         NodeListener(ossimPlanetViewer* viewer)
+         :theViewer(viewer)
+         {
+            
+         }
+         virtual void nodeAdded(osg::Node* /*node*/);
+         virtual void nodeRemoved(osg::Node* /*node*/);
+         virtual void needsRedraw(ossimPlanetNode* node);
+         
+      protected:
+         ossimPlanetViewer* theViewer;
+      };
+   friend class NodeListener;
+   
+   
+   /**
+    * Shorthand typedef of a list of Pick objects.
+    */
+   typedef std::vector<osg::ref_ptr<PickObject> > PickList;
+   /**
+    * Shorthand typedef of a PlanetNode list.
+    */
+   typedef std::vector<osg::ref_ptr<ossimPlanetNode> > PlanetNodeList;
+   /**
+    * Shorthand typedef to hold a list of hud nodes.
+    */
+   typedef std::vector<osg::ref_ptr<osg::Node> > HudList;
+   
+   /**
+    * constructor for ossimPlanetViewer.  Initializing internal pointers and sets up the Update visitor
+    * that will be used to determine if the graph needs refreshing.  
+    */
+   ossimPlanetViewer();
+   /**
+    * Constructs with arguments.  Note this is bridged for osgViewer since ossimPlanetViewer derives from it.
+    */
+   ossimPlanetViewer(osg::ArgumentParser& arguments);
+   
+   /**
+    * Copy constructor.  Currently ossimPlanetViewer ignores this and passes on up to osgViewer.
+    */
+   ossimPlanetViewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
+   
+   /**
+    * destorys and allocated data and removes callbacks form any internal nodes in the scene graph that ossim
+    * PlanetViewer was listneeing to
+    */
+   virtual ~ossimPlanetViewer();
+   
+   /**
+    *
+    * Note only 1 ossimPlanet should exist in a graph.  ossimPlanetViewer searches for the ossimPlanet node and
+    * will unset any previous setup pointers to the newly found ossimPlanet object.
+    *
+    */
+   virtual void setSceneData(osg::Node* node);
+ 
+   void initializeIncrementalCompile();
+
+   /**
+    * Gives acdcess to any allocated ossimPlanet object found in the setSceneData call.
+    */
+   ossimPlanet* planet();
+   
+   /**
+    * Gives acdcess to any allocated ossimPlanet object found in the setSceneData call.
+    */
+   const ossimPlanet* planet()const;
+   
+   /**
+    * Override this to mark the start of the framing
+    */
+   virtual void advance(double simulationTime=USE_REFERENCE_TIME);
+
+   /**
+    * virtual method override form base class.  We check the ossimPlanetUpdte visitor to see if any need refresh flags were found 
+    * in the scnee graph.
+    */
+   virtual void updateTraversal();
+      
+   virtual void eventTraversal();
+   /**
+    * Utility method to give you access to the continuous equation model used for the ellipsoidal tesselation.
+    */
+   const ossimPlanetGeoRefModel* model()const;
+   ossimPlanetGeoRefModel* model();
+   
+   /**
+    * This will be reserved for executing messages routed to the view object.  No implementation yet for this method.
+    */
+   virtual void execute(const ossimPlanetAction& action);
+
+   /**
+    * This will return the eye origin and a normalized ray direction given a window coordinate.  This is unnormalized
+    * window coordinate and assumes Y is up.  So if you are in a GUI where Y is down (left handed) then you must flip and make Y up
+    * using some formula like: height() - Y.
+    */
+   virtual bool makeRayAtWindowCoordinate(osg::Vec3d& origin,
+                                          osg::Vec3d& ray,
+                                          double wx, double wy);
+   
+   
+   /**
+    * This is a utility method for picking objects.  The passed in wx and wy are in unnormalized window coordinates.  Assumed that
+    * the passed in coordinates are right handed where Y is up.  So if you are in a GUI where Y is down (left haded) then you must flip and make Y up
+    * using some formula like: height() - Y.
+    */
+   virtual bool pickAtWindowCoordinate(PickList& result,
+                                       double wx, double wy, 
+                                       osg::Node::NodeMask traversalMask = 0xffffffff);
+   /**
+    * This is a utility method for picking objects.  The passed in wx and wy are in unnormalized window coordinates.  Assumed that
+    * the passed in coordinates are right handed where Y is up.  So if you are in a GUI where Y is down (left haded) then you must flip and make Y up
+    * using some formula like: height() - Y.
+    */
+   virtual bool getLatLonHeightAtWindowCoordinate(osg::Vec3d& llh,
+                                                  double wx, double wy,
+                                                  osg::Node::NodeMask traversalMask=0xffffffff);
+
+   /**
+    * will add and manage the hud.
+    */
+//   bool AddHudOverlay(osg::ref_ptr<osg::Node> hudNode);
+//   ossim_uint32 getNumberOfHudOverlays()const;
+   
+   /**
+    * This will take the passed in anotation node and add it to the annotation layer in planet.
+    *
+    * @param annotation Annotation node to add to planet.
+    */
+   bool addAnnotation(osg::ref_ptr<ossimPlanetAnnotationLayerNode> annotation);
+   
+   /**
+    *
+    * This will take a texture layer and add it to the top of the reference layer.
+    *
+    * @param imageLayer Texture layer to be added.
+    * @return true if the layer was added successfully.
+    *
+    */
+   bool addImageTexture(osg::ref_ptr<ossimPlanetTextureLayer> imageTexture);
+   
+   /**
+    * Will open all entries and return as a root image layer.  If this image file only contains a single
+    * image then that layer is returned.  If multipl images are found then it will open each image and 
+    * create a Layer group and return the images all grouped together.
+    *
+    * @param file The file to open adn add to the graph
+    *
+    * @return the Root layer node.
+    */
+   osg::ref_ptr<ossimPlanetTextureLayer> addImageTexture(const ossimString& file);
+   
+   /**
+    * Allows one to add elevation database.
+    *
+    * @param the elevation database to add.
+    * @param sortFlag will specify if you want to re-sort the database based on resolution.
+    *
+    */
+   bool addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag=false);
+   
+   /**
+    * Allows one to add a kml resource to the kml layer
+    *
+    **/
+   void addKml(const ossimFilename& file);
+   
+   /**
+    * This will take the current active camera and calculate ossimPlanetLookAt representations
+    * for the eye and the lookat point.   
+    *
+    * You should not have to call this for it is already called after each update traversal.
+    */
+   void computeCurrentCameraInfo();
+   
+   /**
+    * Utility to search the scene graph for objects of type ossimPlanetNode that are in the scene graph and has
+    * the passed in id
+    */
+   void findNodesWithId(ossimPlanetViewer::PlanetNodeList& nodeList,
+                        const ossimString& id);
+   /**
+    * Utility to search the scene graph for objects of type ossimPlanetNode that are in the scene graph and has
+    * the passed in id
+    */
+   osg::ref_ptr<ossimPlanetNode> findFirstNodeWithId(const ossimString& id);
+   
+   
+   /**
+    * Lookat object is maintained at any view change within the ossimPlanetViewer.  You can at anytime obtain
+    * the current lookat.
+    */
+   const ossimPlanetLookAt* currentLookAt()const{return theCurrentLookAt.get();}
+   
+   /**
+    * Camera object is stored in the format of a lookat object where the range value is 0.  The Eye position and oritentation is
+    * a special case of a look at object.  This is maintained at any view change automatically by ossimPlanetViewer
+    * and can be queried at any time.
+    *
+    * @return Eye position and orientation in the form of a LookAt object.
+    */
+   const ossimPlanetLookAt* currentCamera()const{return theCurrentCamera.get();}
+   
+   /**
+    * This currently may change.  We are exposing some control of how fast objects are added to the graph
+    * at runtime.  This in particular is an interface added for ossimPlanetTerrain engine.  It will pass
+    * the value on to the terrain and will indicate how many tile request operation to apply to the graph 
+    * per frame.  So the higher the number the more requests that are finalized will be applied to the graph.
+    *
+    * Note:  Requests can be a split, update a mesh, or update a texture.  Each of these adds content to the 
+    *        scene and how fast it's added can be controlled by this variable.
+    */
+   void setTerrainMaxNumberOfOperationsToApplyToGraphPerFrame(ossim_uint32 value);
+   
+   ossimPlanetManipulator* planetManipulator();
+   ossimPlanetTerrain* terrainLayer();
+   ossimPlanetAnnotationLayer* annotationLayer();
+   ossimPlanetKmlLayer* kmlLayer();
+   void addEphemeris(ossim_uint32 memberBitMask);
+   void removeEphemeris();
+   ossimPlanetEphemeris* ephemeris();
+   
+   /**
+    * We will bridge the GUI action adapter so these values can be poled
+    */
+   virtual void requestRedraw();
+   virtual void requestContinuousUpdate(bool needed=true);
+   virtual void requestWarpPointer(float x,float y);
+   
+   
+   /**
+    * This is an atomic operation so if another request redraw comes in while you are querying
+    * they will be in synch.  Instead of doing a separate query of the redraw flag and then 
+    * a set on it for a new request could come in while in between those 2 calls and therefore you will
+    * miss a frame.
+    */
+   bool getAndSetRedrawFlag(bool newValue);
+   bool getRedrawFlag();
+   void setRedrawFlag(bool flag);
+   bool redrawFlag()const;
+   void setContinuousUpdateFlag(bool flag);
+   bool continuousUpdateFlag()const;
+   bool warpPointerFlag()const;
+   void getWarpPoints(float& x, float& y)const;
+
+   /** 
+    * All code contained in here was copied from OSG.  We will be adding fudge factor shifts
+    * for close to earth intersections.
+    *
+    * Compute intersections between a ray through the specified master cameras window/eye coords and a specified node.
+    * Note, when a master cameras has slaves and no viewport itself its coordinate frame will be in clip space i.e. -1,-1 to 1,1,
+    * while if its has a viewport the coordintates will be relative to its viewport dimensions. 
+    * Mouse events handled by the view will automatically be attached into the master camera window/clip coords so can be passed
+    * directly on to the computeIntersections method. */
+   bool computeIntersections(float x,
+                             float y, 
+                             osgUtil::LineSegmentIntersector::Intersections& intersections,
+                             osg::Node::NodeMask traversalMask = 0xffffffff);
+   
+   /** 
+    * All code contained in here was copied from OSG.  We will be adding fudge factor shifts
+    * for close to earth intersections.
+    *
+    * Compute intersections between a ray through the specified master cameras 
+    * window/eye coords and a specified nodePath's subgraph. 
+    **/
+   bool computeIntersections(float x,
+                             float y, 
+                             const osg::NodePath& nodePath, 
+                             osgUtil::LineSegmentIntersector::Intersections& intersections,
+                             osg::Node::NodeMask traversalMask = 0xffffffff);
+   /**
+    * This will return the eye origin and a normalized ray direction given a window coordinate.  This is unnormalized
+    * window coordinate and assumes Y is up.  So if you are in a GUI where Y is down (left haded) then you must flip and make Y up
+    * using some formula like: height() - Y.
+    */
+   virtual bool makeRayAtWindowCoordinate(osg::Vec3d& origin,
+                                          osg::Vec3d& ray,
+                                          osg::Camera* camera,
+                                          double wx, double wy);
+   
+   void setIntersectWithMasterIfNotWithinAnyViewFlag(bool flag)
+   {
+      theIntersectWithMasterIfNotWithinAnyViewFlag = flag;
+   }
+   bool intersectWithMasterIfNotWithinAnyViewFlag()const
+   {
+      return theIntersectWithMasterIfNotWithinAnyViewFlag;
+   }
+   void setCalculateNearFarRatioFlag(bool flag)
+   {
+      theCalculateNearFarRatioFlag = flag;
+   }
+   bool calculateNearFarRatioFlag()const
+   {
+      return theCalculateNearFarRatioFlag;
+   }
+protected:
+   friend class DrawCallback;
+   const osg::Camera* forceAdjustToMasterCamera(float x, float y, float& local_x, float& local_y) const;
+   
+   void init();
+   void notifyViewChanged();
+
+   HudList theHudOverlayList;
+   osg::ref_ptr<NodeListener> theCallback;
+   osg::ref_ptr<ossimPlanet> thePlanet;
+   osg::ref_ptr<ossimPlanetUpdateVisitor> theUpdateVisitor;
+   
+   osg::Matrixd theCurrentViewMatrix;
+   osg::Matrixd theCurrentViewMatrixInverse;
+   osg::ref_ptr<ossimPlanetLookAt> theCurrentCamera;
+   osg::ref_ptr<ossimPlanetLookAt> theCurrentLookAt;
+   osg::ref_ptr<ossimPlanetAnnotationLayer> theAnnotationLayer;
+   osg::ref_ptr<ossimPlanetKmlLayer>  theKmlLayer;
+   osg::ref_ptr<ossimPlanetLayer>     theTerrainLayer;
+   osg::ref_ptr<ossimPlanetEphemeris> theEphemerisLayer;
+   osg::ref_ptr<osg::Camera>          theEphemerisCamera;
+   osg::ref_ptr<osg::Node>            theEphemerisRoot;
+  
+   osg::ref_ptr<osg::Group> theRootNode;
+   osg::ref_ptr<osg::Light> theSavedLight;
+   osg::Timer_t theFrameStartTimeStamp;
+   /***  These are Gui Action adapter bridge ****/
+   mutable OpenThreads::Mutex theActionAdapterMutex;
+   bool theContinousUpdateFlag;
+   bool theRedrawFlag;
+   bool theWarpPointerFlag;
+   float theWarpX, theWarpY;
+   /*** Done with GUI Action adapter bridge ****/
+   
+   bool theIntersectWithMasterIfNotWithinAnyViewFlag;
+   bool theCalculateNearFarRatioFlag;
+   
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetVisitors.h b/ossimPlanet/include/ossimPlanet/ossimPlanetVisitors.h
new file mode 100644
index 0000000..998d4b9
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetVisitors.h
@@ -0,0 +1,140 @@
+#ifndef ossimPlanetVisitors_HEADER
+#define ossimPlanetVisitors_HEADER
+#include <ossimPlanet/ossimPlanetExport.h>
+#include <osg/Texture>
+#include <osg/Texture2D>
+#include <osg/StateSet>
+#include <osg/Node>
+#include <iostream>
+#include <osg/NodeVisitor>
+#include <ossim/base/ossimString.h>
+#include <osgUtil/UpdateVisitor>
+
+class OSSIMPLANET_DLL ossimSetNonPowerOfTwoTextureVisitor : public osg::NodeVisitor
+{
+public:
+   ossimSetNonPowerOfTwoTextureVisitor()
+      :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+   {
+      theResizePowerOfTwoHint = false;
+      theMinFilterMode = osg::Texture2D::LINEAR;
+      theMagFilterMode = osg::Texture2D::LINEAR;
+      theSWrapMode     = osg::Texture2D::CLAMP_TO_EDGE;
+      theTWrapMode     = osg::Texture2D::CLAMP_TO_EDGE;
+      theRWrapMode     = osg::Texture2D::CLAMP_TO_EDGE;
+      theDataVariance  = osg::Object::STATIC;
+   }
+   virtual void apply(osg::Node& node)
+   {
+      osg::StateSet* set = node.getStateSet();
+      if(set)
+      {
+         osg::Texture* texture = dynamic_cast<osg::Texture*>(set->getTextureAttribute(0,
+                                                                                      osg::StateAttribute::TEXTURE));
+         if(texture)
+         {
+/*             std::cout << GL_CLAMP <<", " << GL_CLAMP_TO_EDGE <<", " << GL_CLAMP_TO_BORDER_ARB << ", " << GL_REPEAT << "\n"; */
+/*             std::cout <<"<" << texture->getWrap(osg::Texture2D::WRAP_S) <<", " */
+/*                       <<texture->getWrap(osg::Texture2D::WRAP_T) << ">\n"; */
+            texture->setFilter(osg::Texture::MIN_FILTER, theMinFilterMode);
+            texture->setFilter(osg::Texture::MAG_FILTER, theMagFilterMode);
+            texture->setWrap(osg::Texture2D::WRAP_S, theSWrapMode);
+            texture->setWrap(osg::Texture2D::WRAP_T, theTWrapMode);
+            texture->setWrap(osg::Texture2D::WRAP_R, theRWrapMode);
+            texture->setDataVariance(theDataVariance);
+            texture->setResizeNonPowerOfTwoHint(theResizePowerOfTwoHint);
+         }
+      }
+      traverse(node);
+   }
+protected:
+   bool theResizePowerOfTwoHint;
+   osg::Texture::FilterMode theMinFilterMode;
+   osg::Texture::FilterMode theMagFilterMode;
+   osg::Texture::WrapMode   theSWrapMode;
+   osg::Texture::WrapMode   theTWrapMode;
+   osg::Texture::WrapMode   theRWrapMode;
+   osg::Object::DataVariance theDataVariance;
+};
+
+class OSSIMPLANET_DLL ossimPlanetLayerNameIdSearchVisitor : public osg::NodeVisitor
+{
+public:
+   ossimPlanetLayerNameIdSearchVisitor()
+   :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+   {
+   }
+   ossimPlanetLayerNameIdSearchVisitor(const ossimString& name, const ossimString& id)
+   :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+   theName(name),
+   theId(id)
+   {
+   }
+   void setName(const ossimString& value)
+   {
+      theName = value;
+   }
+   const ossimString& name()const
+   {
+      return theName;
+   }
+   void setId(const ossimString& value)
+   {
+      theId = value;
+   }
+   const ossimString& id()const
+   {
+      return theId;
+   }
+   osg::ref_ptr<osg::Node> node()
+   {
+      return theNode.get();
+   }
+   const osg::ref_ptr<osg::Node> node()const
+   {
+      return theNode.get();
+   }
+   virtual void apply(osg::Node& node);
+protected:
+   ossimString theName;
+   ossimString theId;
+   osg::ref_ptr<osg::Node> theNode;
+};
+
+class OSSIMPLANET_DLL ossimPlanetTraverseCallback : public osg::NodeCallback
+{
+	virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+	{
+		if(node)
+		{
+			node->traverse(*nv);
+		}
+	}
+};
+
+
+/**
+ * Used to determine if a node in the graph needs refreshing.  It will query the refresh flag while its
+ * going through the update phase and set an internal flag.  Note, ossimPlanetViewer's updateTraversal
+ * method override uses this information to help determine if it's in a static state
+ */
+class OSSIMPLANET_DLL ossimPlanetUpdateVisitor :  public osgUtil::UpdateVisitor
+{
+public:
+   ossimPlanetUpdateVisitor();
+   /**
+    * Virtual method override that calls the base implementation but also sets/clears the RedrawFlag
+    * for next traversal
+    */
+   virtual void reset();
+   
+   /**
+    * @return the value of the redraw flag.  True means we need to redraw
+    */
+   bool redrawFlag()const;
+protected:
+   virtual void apply(osg::Node& node);       
+   virtual void apply(osg::Group& node);      
+   bool theRedrawFlag;
+};
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetWmsClient.h b/ossimPlanet/include/ossimPlanet/ossimPlanetWmsClient.h
new file mode 100644
index 0000000..e3bdbe2
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetWmsClient.h
@@ -0,0 +1,99 @@
+#ifndef OSSIMPLANET_WITHOUT_WMS
+#ifndef ossimPlanetWmsClient_HEADER
+#define ossimPlanetWmsClient_HEADER
+#include <vector>
+#include <string>
+#include "ossimPlanetExport.h"
+#include <ossim/base/ossimFilename.h>
+#include <ossim/imaging/ossimImageData.h>
+#include <ossim/base/ossimConstants.h>
+#include <wms/wmsClient.h>
+#include <wms/wmsRefPtr.h>
+#include <osg/ref_ptr>
+#include <osg/Referenced>
+#include <ossimPlanet/ossimPlanetOssimImage.h>
+
+class wmsClient;
+class ossimPlanetImage;
+namespace osg
+{
+   class Image;
+}
+
+class OSSIMPLANET_DLL ossimPlanetWmsClient : public osg::Referenced
+{
+ public:
+   ossimPlanetWmsClient(const std::string& server=std::string(""),
+                      const std::string& path=std::string(""));
+   ossimPlanetWmsClient(const ossimPlanetWmsClient& src);
+
+   virtual ~ossimPlanetWmsClient();
+
+   void setServer(const std::string& server);
+   void setPath(const std::string& path);
+
+   virtual osg::ref_ptr<ossimPlanetImage> createImage(ossim_uint32 width,
+                                                    ossim_uint32 height,
+                                                    const double& minLat,
+                                                    const double& minLon,
+                                                    const double& maxLat,
+                                                    const double& maxLon,
+                                                    const std::string& filename = std::string(""));
+
+   virtual osg::ref_ptr<ossimPlanetImage> readLocalImage(const std::string& filename)const;
+   
+   void setImageType(const std::string& imageType);
+   std::string getImageType()const;
+   std::string getServer()const;
+   std::string getPath()const;
+   void setVersion(const ossimString& version);
+   void setAdditionalParameters(const ossimString& additionalParameters);
+   void setTransparentFlag(bool flag);
+   void setBackgroundColor(const std::string& color);
+   void setProxyHost(const std::string& host)
+   {
+      theWmsClient->setProxyHost(host);
+   }
+   void setProxyPort(const std::string& port)
+   {
+      theWmsClient->setProxyPort(port);
+   }
+   void setProxyUser(const std::string& userName)
+   {
+      theWmsClient->setProxyUser(userName);
+   }
+   void setProxyPassword(const std::string& password)
+   {
+      theWmsClient->setProxyPassword(password);
+   }
+   const std::string& proxyHost()const
+   {
+      return theWmsClient->proxyHost();
+   }
+   const std::string& proxyPort()const
+   {
+      return theWmsClient->proxyPort();
+   }
+   const std::string& proxyUser()const
+   {
+      return theWmsClient->proxyUser();
+   }
+   const std::string& proxyPassword()const
+   {
+      return theWmsClient->proxyPassword();
+   }
+protected:
+   wmsRefPtr<wmsClient> theWmsClient; 
+   std::string theServer;
+   std::string thePath;
+   std::string theImageFormats;
+   std::string theImageType;
+   std::string theVersion;
+   std::string theAdditionalParameters;
+   std::string theBackgroundColor;
+   bool theTransparentFlag;
+   osg::ref_ptr<ossimPlanetOssimImage> theImageReader;
+};
+
+#endif
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetWmsImageLayer.h b/ossimPlanet/include/ossimPlanet/ossimPlanetWmsImageLayer.h
new file mode 100644
index 0000000..9dc80a8
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetWmsImageLayer.h
@@ -0,0 +1,128 @@
+#ifndef ossimPlanetWmsImageLayer_HEADER
+#define ossimPlanetWmsImageLayer_HEADER
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossim/imaging/ossimImageFileWriter.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossimPlanet/ossimPlanetWmsClient.h>
+class OSSIMPLANET_DLL ossimPlanetWmsImageLayer : public ossimPlanetTextureLayer
+{
+public:
+   ossimPlanetWmsImageLayer();
+   ossimPlanetWmsImageLayer(const ossimPlanetWmsImageLayer& src);
+   virtual ossimPlanetTextureLayer* dup()const;
+   virtual ossimPlanetTextureLayer* dupType()const;
+   virtual ossimString getClassName()const;
+   virtual ossimPlanetTextureLayerStateCode updateExtents();
+   virtual void updateStats()const;
+   virtual void resetStats()const;
+
+   virtual bool hasTexture(ossim_uint32 width,
+                           ossim_uint32 height,
+                           const ossimPlanetTerrainTileId& tileId,
+                           const ossimPlanetGrid& grid);
+   
+   virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 width,
+                                                     ossim_uint32 height,
+                                                     const ossimPlanetTerrainTileId& tileId,
+                                                     const ossimPlanetGrid& theGrid,
+                                                     ossim_int32 padding=0);
+  virtual osg::ref_ptr<ossimPlanetImage> getTexture(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col,
+                                                     const ossimPlanetGridUtility& utility);
+   
+   void setServer(const std::string& serverString);
+   const std::string& getServer()const;
+   const std::string& getImageType()const;
+   void setImageType(const std::string& imageType);
+
+   void setCacheDirectory(const ossimFilename& cacheDir);
+   const ossimFilename& getCacheDirectory()const;
+   const ossimFilename& getCompleteCacheDirectory()const;
+
+   void setRawCapabilities(const ossimString& rawCapabilities);
+   const ossimString& getRawCapabilities()const;
+
+   void setCapabilitiesUrl(const std::string& url);
+   const std::string& getCapabilitiesUrl()const;
+
+   void setBackgroundColor(const ossimString& color);
+   const ossimString& getBackgroundColor()const;
+
+   void setTransparentFlag(bool flag);
+   bool getTransparentFlag()const;
+
+   void setAdditionalParameters(const ossimString& additionalParameters);
+   const ossimString& getAdditionalParameters()const;
+
+   void setAutoCreateCacheFlag(bool value);
+   bool getAutoCreateCacheFlag()const;
+
+   void clearDiskCache();
+
+   virtual ossimRefPtr<ossimXmlNode> saveXml(bool recurse=true)const;
+   bool loadXml(ossimRefPtr<ossimXmlNode> node);
+
+   void setProxyHost(const std::string& host)
+   {
+      theProxyHost = host;
+      theWmsClient->setProxyHost(host);
+   }
+   void setProxyPort(const std::string& port)
+   {
+      theProxyPort = port;
+      theWmsClient->setProxyPort(port);
+   }
+   void setProxyUser(const std::string& user)
+   {
+      theProxyUser = user;
+      theWmsClient->setProxyUser(user);
+   }
+   void setProxyPassword(const std::string& password)
+   {
+      theProxyPassword = password;
+      theWmsClient->setProxyPassword(password);
+   }
+   const std::string& proxyHost()const
+   {
+      return theProxyHost;
+   }
+   const std::string& proxyPort()const
+   {
+      return theProxyPort;
+   }
+   const std::string& proxyUser()const
+   {
+      return theProxyUser;
+   }
+   const std::string& proxyPassword()const
+   {
+      return theProxyPassword;
+   }
+   
+protected:
+   void adjustServerString();
+   
+   ossimFilename              theCacheDirectory;
+   ossimFilename              theCompleteCacheDirectory;
+   ossimString                theServer;
+   ossimString                theAdjustedServer;
+   ossimString                theImageType;
+   ossimString                theRawCapabilities;
+   ossimString                theCapabilitiesUrl;
+   ossimString                theBackgroundColor;
+   bool                       theTransparentFlag;
+   ossimString                theAdditionalParameters;
+   std::string theProxyHost;
+   std::string theProxyPort;
+   std::string theProxyUser;
+   std::string theProxyPassword;
+   mutable ossimPlanetReentrantMutex theWmsArchiveMutex;
+   std::vector<ossimString>   theLayers;
+   std::vector<ossimString>   theStyles;
+   bool                       theAutoCreateCacheFlag;
+   ossimRefPtr<ossimImageFileWriter> theWriter;
+   osg::ref_ptr<ossimPlanetWmsClient> theWmsClient;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetXmlAction.h b/ossimPlanet/include/ossimPlanet/ossimPlanetXmlAction.h
new file mode 100644
index 0000000..4b4765e
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetXmlAction.h
@@ -0,0 +1,81 @@
+#ifndef ossimPlanetXmlAction_HEADER
+#define ossimPlanetXmlAction_HEADER
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <osg/ref_ptr>
+
+class OSSIMPLANET_DLL ossimPlanetXmlAction : public ossimPlanetAction
+{
+public:
+   ossimPlanetXmlAction(const ossimString& code = ossimString(), 
+                        const ossimString& originatingFederate = defaultOrigin());
+	ossimPlanetXmlAction(ossimRefPtr<ossimXmlNode> node,
+								const ossimString& originatingFederate = defaultOrigin());
+   ossimPlanetXmlAction(const ossimPlanetXmlAction& src)
+   :ossimPlanetAction(src),
+   theXmlNode(src.theXmlNode.valid()?(ossimXmlNode*)src.theXmlNode->dup():(ossimXmlNode*)0)
+   {
+      
+   }
+   virtual ossimPlanetAction* clone()const
+   {
+      return new ossimPlanetXmlAction(*this);
+   }
+   virtual ossimPlanetAction* cloneType()const
+   {
+      return new ossimPlanetXmlAction();
+   }
+   virtual ossimPlanetXmlAction* toXmlAction()
+   {
+      return this;
+   }
+   virtual const ossimPlanetXmlAction* toXmlAction()const
+   {
+      return this;
+   }
+   virtual void setTarget(const ossimString& value);
+   virtual void setCommand(const ossimString& value);
+	
+   /**
+    * Will allow one to set the source code for the derived actions
+    *
+    */
+	virtual bool setSourceCode(const ossimString& code);
+   ossimRefPtr<ossimXmlNode> xmlNode()
+   {
+      return theXmlNode;
+   }
+   const ossimRefPtr<ossimXmlNode> xmlNode()const
+   {
+      return theXmlNode;
+   }
+   void setXmlNode(ossimRefPtr<ossimXmlNode> code);
+	
+	/**
+	 * Utility method for accessing the attribute id of the Action.
+	 */
+	ossimString id()const;
+	ossimString name()const;
+   
+   	/**
+	 * Utility method to duplicte a child of the action and maintain the same action parameters
+	 */
+	osg::ref_ptr<ossimPlanetXmlAction> duplicateChildAndMaintainAction(ossim_uint32 childIdx)const;
+	
+	/**
+	 * Utility method to duplicate the child properties and promote them as the children of the Action.
+	 * This is typically used when doing a set Action on a node.  The properties are promoted for the set actions
+	 *
+	 */
+	osg::ref_ptr<ossimPlanetXmlAction> duplicateChildPropertiesAndMaintainAction(ossim_uint32 childIdx)const;
+	
+	bool hasChildren()const;
+	virtual void print(std::ostream& out)const;
+   virtual void read(std::istream& in);
+   
+protected:
+   ossimRefPtr<ossimXmlNode> theXmlNode;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/ossimPlanetYahooGeocoder.h b/ossimPlanet/include/ossimPlanet/ossimPlanetYahooGeocoder.h
new file mode 100644
index 0000000..17aa476
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ossimPlanetYahooGeocoder.h
@@ -0,0 +1,23 @@
+#ifndef ossimPlanetYahooGeocoder_HEADER
+#define ossimPlanetYahooGeocoder_HEADER
+#include <ossimPlanet/ossimPlanetGeocoder.h>
+#include <ossimPlanet/ossimPlanetExport.h>
+
+class OSSIMPLANET_DLL ossimPlanetYahooGeocoder : public ossimPlanetGoecoder
+{
+public:
+   ossimPlanetYahooGeocoder(const ossimString url = "http://api.local.yahoo.com/MapsService/V1/geocode?",
+                            const ossimString yahooAppId = "YahooDemo")
+      :theUrl(url),
+      theAppId(yahooAppId)
+   {
+   }
+      virtual void getLocationFromAddress(std::vector<osg::ref_ptr<ossimPlanetGeocoderLocation> >& result,
+                                       const ossimString& location)const;   
+
+protected:
+   ossimString theUrl;
+   ossimString theAppId;
+};
+
+#endif
diff --git a/ossimPlanet/include/ossimPlanet/sg_file.h b/ossimPlanet/include/ossimPlanet/sg_file.h
new file mode 100644
index 0000000..1755a9a
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/sg_file.h
@@ -0,0 +1,101 @@
+/** \file sg_file.hxx
+ * File I/O routines.
+ */
+
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_file.h 10524 2007-02-26 18:27:24Z gpotts $
+
+
+#ifndef _SG_FILE_HXX
+#define _SG_FILE_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include <ossimPlanet/compiler.h>
+
+#include <string>
+
+#include <sys/types.h>		// for open(), read(), write(), close()
+#include <sys/stat.h>		// for open(), read(), write(), close()
+#include <fcntl.h>		// for open(), read(), write(), close()
+#if !defined( _MSC_VER )
+#  include <unistd.h>		// for open(), read(), write(), close()
+#endif
+
+#include "iochannel.h"
+
+SG_USING_STD(string);
+
+
+/**
+ * A file I/O class based on SGIOChannel.
+ */
+class SGFile : public SGIOChannel {
+
+    string file_name;
+    int fp;
+    bool eof_flag;
+
+public:
+
+    /**
+     * Create an instance of SGFile.
+     * When calling the constructor you need to provide a file
+     * name. This file is not opened immediately, but instead will be
+     * opened when the open() method is called.
+     * @param file name of file to open
+     */
+    SGFile( const string& file );
+
+    /** Destructor */
+    ~SGFile();
+
+    // open the file based on specified direction
+    bool open( const SGProtocolDir dir );
+
+    // read a block of data of specified size
+    int read( char *buf, int length );
+
+    // read a line of data, length is max size of input buffer
+    int readline( char *buf, int length );
+
+    // write data to a file
+    int write( const char *buf, const int length );
+
+    // write null terminated string to a file
+    int writestring( const char *str );
+
+    // close file
+    bool close();
+
+    /** @return the name of the file being manipulated. */
+    inline string get_file_name() const { return file_name; }
+
+    /** @return true of eof conditions exists */
+    inline bool eof() const { return eof_flag; };
+};
+
+
+#endif // _SG_FILE_HXX
+
+
diff --git a/ossimPlanet/include/ossimPlanet/sg_socket.h b/ossimPlanet/include/ossimPlanet/sg_socket.h
new file mode 100644
index 0000000..b6bbc05
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/sg_socket.h
@@ -0,0 +1,181 @@
+/**
+ * \file sg_socket.hxx
+ * Socket I/O routines.
+ */
+
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_socket.h 10927 2007-05-16 13:22:06Z gpotts $
+
+
+#ifndef _SG_SOCKET_HXX
+#define _SG_SOCKET_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+#include <vector>
+
+#include <ossimPlanet/compiler.h>
+
+#include STL_STRING
+
+#include "iochannel.h"
+
+#include "netSocket.h"
+
+SG_USING_STD(string);
+
+#include <vector>
+#define SG_MAX_SOCKET_QUEUE 32
+
+
+/**
+ * A socket I/O class based on SGIOChannel.
+ */
+class SGSocket : public SGIOChannel {
+public:
+private:
+    string hostname;
+    string port_str;
+
+    std::vector<char> save_buf;
+/*     char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ]; */
+    int save_len;
+
+    netSocket sock;
+    netSocket* client;
+    unsigned short port;
+    bool is_tcp;
+    bool is_server;
+    bool first_read;
+    int timeout;
+
+    /**
+     * Not used yet.  Will allow the buffer to grow instead of stay fixed.
+     */ 
+    bool theAutoGrowFlag;
+    
+    static bool init;
+
+    // make a server (master listening) socket
+    bool make_server_socket();
+
+    // make a client socket
+    bool  make_client_socket();
+
+    // Poll for new connections or data to read.
+    int poll();
+
+public:
+
+    /**
+     * Create an instance of SGSocket.
+     *
+     * When calling the constructor you need to provide a host name, a
+     * port number, and a socket style. The convention used by the
+     * SGSocket class is that the server side listens and the client
+     * side sends. For a server socket, the host name should be
+     * empty. For a server, the port number is optional, if you do not
+     * specify a port, the system will assign one. For a client
+     * socket, you need to specify both a destination host and
+     * destination port. For both client and server sockets you must
+     * specify the socket type. Type must be either udp or tcp. Here's
+     * a quick breakdown of the major differences between UDP and TCP
+     * type sockets.
+     *
+     * TCP sockets are the type where you establish a connection and
+     * then can read and write to the socket from both ends. If one
+     * end of TCP socket connect quits, the other end will likely
+     * segfault if it doesn't take special precautions.  But, the nice
+     * thing about TCP connections is that the underlying protocol
+     * guarantees that your message will get through. This imposes a
+     * certain performance overhead though on the communication
+     * because the protocol must resend failed messages. TCP sockets
+     * are good for sending periodic command/response type messages
+     * where performance isn't a big issues, but reliability is.
+     *
+     * UDP sockets on the other hand are a lower level protocol and
+     * don't have the same sort of connection as TCP sockets. With UDP
+     * sockets, the server end just sits and listens for incoming
+     * packets from anywhere. The client end sends it's message and
+     * forgets about it. It doesn't care if there isn't even a server
+     * out there listening and all the packets are getting
+     * lost. Although systems/networks usually do a pretty good job
+     * (statistically) of getting your UDP packets to their
+     * destination, there is no guarantee that any particular packet
+     * will make it. But, because of this low level implementation and
+     * lack of error checking, UDP packets are much faster and
+     * efficient. UDP packets are good for sending positional
+     * information to synchronize two applications. In this case, you
+     * want the information to arrive as quickly as possible, and if
+     * you lose a packet, you'd rather get new updated information
+     * rather than have the system waste time resending a packet that
+     * is becoming older and older with every retry.
+     * @param host name of host if direction is SG_IO_OUT or SG_IO_BI
+     * @param port port number if we care to choose one.
+     * @param style specify "udp" or "tcp"
+     */
+    SGSocket( const string& host, const string& port, const string& style );
+    SGSocket();
+    /** Destructor */
+    ~SGSocket();
+
+    virtual void setSocket(const string& host, const string& port, const string& style);
+    virtual void setSocket(const string& host, int port, const string& style);
+    // If specified as a server (in direction for now) open the master
+    // listening socket.  If specified as a client (out direction),
+    // open a connection to a server.
+    bool open( const SGProtocolDir d );
+
+    // read data from socket
+    int read( char *buf, int length );
+
+    // read data from socket
+    int readline( char *buf, int length );
+
+    // write data to a socket
+    int write( const char *buf, const int length );
+
+    // write null terminated string to a socket
+    int writestring( const char *str );
+
+    // close file
+    bool close();
+
+    /**
+     * Enable non-blocking mode.
+     * @return success/failure
+     */
+    bool nonblock();
+
+    // set timeout (default: 0)
+    inline void set_timeout(int i) { timeout = i; }
+
+    /** @return the remote host name */
+    inline string get_hostname() const { return hostname; }
+
+    /** @return the port number (in string form) */
+    inline string get_port_str() const { return port_str; }
+    inline std::string get_port_style()const { return is_tcp?"tcp":"udp";}
+};
+
+
+#endif // _SG_SOCKET_HXX
diff --git a/ossimPlanet/include/ossimPlanet/sg_socket_udp.h b/ossimPlanet/include/ossimPlanet/sg_socket_udp.h
new file mode 100644
index 0000000..cfd8271
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/sg_socket_udp.h
@@ -0,0 +1,137 @@
+/**
+ * \file sg_socket_udp.hxx
+ * UDP Socket I/O routines.
+ */
+
+// Written by Curtis Olson, started November 2001.
+//
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_socket_udp.h 10524 2007-02-26 18:27:24Z gpotts $
+
+
+#ifndef _SG_SOCKET_UDP_HXX
+#define _SG_SOCKET_UDP_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include "netSocket.h"
+
+#include <ossimPlanet/compiler.h>
+
+#include STL_STRING
+
+#include <ossimPlanet/iochannel.h>
+
+SG_USING_STD(string);
+
+/**
+ * A UDP socket I/O class based on SGIOChannel and plib/net.
+ */
+class SGSocketUDP : public SGIOChannel {
+
+private:
+
+    netSocket sock;
+
+    string hostname;
+    string port_str;
+
+    char save_buf[ 2 * SG_IO_MAX_MSG_SIZE ];
+    int save_len;
+
+    short unsigned int port;
+
+public:
+
+    /**
+     * Create an instance of SGSocketUDP.
+     *
+     * When calling the constructor you need to provide a host name, and a
+     * port number. The convention used by the
+     * SGSocketUDP class is that the server side listens and the client
+     * side sends. For a server socket, the host name should be
+     * empty. For a server, the port number is optional, if you do not
+     * specify a port, the system will assign one. For a client
+     * socket, you need to specify both a destination host and
+     * destination port.
+     *
+     * UDP sockets are a lower level protocol than TCP sockets and are
+     * "connectionless" in the sense that either client or server can
+     * exist, or not exist, startup, quit, etc. in any order and
+     * whenever both ends are alive, the communication succeeds. With
+     * UDP sockets, the server end just sits and listens for incoming
+     * packets from anywhere. The client end sends it's message and
+     * forgets about it. It doesn't care if there isn't even a server
+     * out there listening and all the packets are getting
+     * lost. Although systems/networks usually do a pretty good job
+     * (statistically) of getting your UDP packets to their
+     * destination, there is no guarantee that any particular packet
+     * will make it. But, because of this low level implementation and
+     * lack of error checking, UDP packets are much faster and
+     * efficient. UDP packets are good for sending positional
+     * information to synchronize two applications. In this case, you
+     * want the information to arrive as quickly as possible, and if
+     * you lose a packet, you'd rather get new updated information
+     * rather than have the system waste time resending a packet that
+     * is becoming older and older with every retry.
+     * @param host name of host if direction is SG_IO_OUT or SG_IO_BI
+     * @param port port number if we care to choose one.
+     * @param style specify "udp" or "tcp" */
+    SGSocketUDP( const string& host, const string& port );
+
+    /** Destructor */
+    ~SGSocketUDP();
+
+    // If specified as a server (in direction for now) open the master
+    // listening socket.  If specified as a client (out direction),
+    // open a connection to a server.
+    bool open( const SGProtocolDir d );
+
+    // read data from socket
+    int read( char *buf, int length );
+
+    // read data from socket
+    int readline( char *buf, int length );
+
+    // write data to a socket
+    int write( const char *buf, const int length );
+
+    // write null terminated string to a socket
+    int writestring( const char *str );
+
+    // close file
+    bool close();
+
+    /**
+     * Set blocking true or false
+     * @return success/failure
+     */
+    bool setBlocking( bool value );
+
+    /** @return the remote host name */
+    inline string get_hostname() const { return hostname; }
+
+    /** @return the port number (in string form) */
+    inline string get_port_str() const { return port_str; }
+};
+
+
+#endif // _SG_SOCKET_UDP_HXX
diff --git a/ossimPlanet/include/ossimPlanet/ul.h b/ossimPlanet/include/ossimPlanet/ul.h
new file mode 100644
index 0000000..26d3cf3
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ul.h
@@ -0,0 +1,868 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ul.h 2117 2007-09-13 23:21:09Z fayjf $
+*/
+
+//
+//  UL - utility library
+//
+//  Contains:
+//  - necessary system includes
+//  - basic types
+//  - error message routines
+//  - high performance clocks
+//  - ulList
+//  - ulLinkedList
+//  - more to come (endian support, version ID)
+//
+
+#ifndef _INCLUDED_UL_H_
+#define _INCLUDED_UL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+/**********************\
+*                      *
+*  Determine OS type   *
+*                      *
+\**********************/
+
+#if defined(__CYGWIN__)
+
+#define UL_WIN32     1
+#define UL_CYGWIN    1    /* Windoze AND Cygwin. */
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(_MSC_VER)
+
+#define UL_WIN32     1
+#define UL_MSVC      1    /* Windoze AND MSVC. */
+
+#elif defined(__BEOS__)
+
+#define UL_BEOS      1
+
+#elif defined( macintosh )
+
+#define UL_MACINTOSH 1
+
+#elif defined(__APPLE__)
+
+#define UL_MAC_OSX   1 
+
+#elif defined(__linux__)
+
+#define UL_LINUX     1
+
+#elif defined(__sgi)
+
+#define UL_IRIX      1
+
+#elif defined(_AIX)
+
+#define UL_AIX       1
+
+#elif defined(SOLARIS) || defined(sun)
+
+#define UL_SOLARIS   1
+
+#elif defined(hpux)
+
+#define UL_HPUX      1
+
+#elif (defined(__unix__) || defined(unix)) && !defined(USG)
+
+#define UL_BSD       1
+
+#endif
+
+
+/*
+  Add specialised includes/defines...
+*/
+
+#ifdef UL_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <mmsystem.h>
+#include <regstr.h>
+#define  UL_WGL     1
+#endif
+
+#ifdef UL_CYGWIN
+#include <unistd.h>
+#define  UL_WGL     1
+#endif
+
+#ifdef UL_BEOS
+#include <be/kernel/image.h>
+#define  UL_GLX     1
+#endif
+
+#ifdef UL_MACINTOSH
+#include <CodeFragments.h>
+#include <unistd.h>
+#define  UL_AGL     1
+#endif
+
+#ifdef UL_MAC_OSX
+#include <unistd.h>
+#define  UL_CGL     1
+#endif
+
+#if defined(UL_LINUX) || defined(UL_BSD) || defined(UL_IRIX) || defined(UL_SOLARIS) || defined(UL_AIX)
+#include <unistd.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#define  UL_GLX     1
+#endif
+
+#if defined(UL_BSD)
+#include <sys/param.h>
+#define  UL_GLX     1
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <math.h>
+#include <float.h>
+#include <errno.h>
+
+/* PLIB version macros */
+
+#define PLIB_MAJOR_VERSION 1
+#define PLIB_MINOR_VERSION 8
+#define PLIB_TINY_VERSION  5
+
+#define PLIB_VERSION (PLIB_MAJOR_VERSION*100 \
+                     +PLIB_MINOR_VERSION*10 \
+                     +PLIB_TINY_VERSION)
+
+/* SGI machines seem to suffer from a lack of FLT_EPSILON so... */
+
+#ifndef FLT_EPSILON
+#define FLT_EPSILON 1.19209290e-07f        
+#endif
+
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 1.19209290e-07f
+#endif
+
+#ifndef TRUE
+#define TRUE  1
+#define FALSE 0
+#endif
+
+/* SUNWspro 4.2 and earlier need bool to be defined */
+
+#if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500
+typedef int bool ;
+const   int true  = 1 ;
+const   int false = 0 ;
+#endif
+
+/* Let's define our own "min" and "max" so that different operating systems
+ * don't complain
+ */
+#define ulMax(a,b)	((a)>(b)?(a):(b))
+#define ulMin(a,b)	((a)<(b)?(a):(b))
+
+
+/*
+  Basic Types
+*/
+
+
+/*
+  High precision clocks.
+*/
+
+class ulClock
+{
+  double start ;
+  double now   ;
+  double delta ;
+  double last_time ;
+  double max_delta ;
+  
+#ifdef UL_WIN32
+  static double res ;
+  static int perf_timer ;
+  void initPerformanceTimer () ;
+#endif
+
+  double getRawTime () const ;
+
+public:
+
+  ulClock () { reset () ; }
+
+  void reset ()
+  {
+#ifdef UL_WIN32
+    initPerformanceTimer () ;
+#endif
+    start     = getRawTime () ;
+    now       = 0.0 ;
+    max_delta = 0.2 ; 
+    delta     = 0.0000001 ;  /* Faked so stoopid programs won't div0 */
+    last_time = 0.0 ;
+  }
+
+  void   setMaxDelta  ( double maxDelta ) { max_delta = maxDelta ; }
+  double getMaxDelta  () const { return max_delta ; }
+  void   update       () ;
+  double getAbsTime   () const { return now   ; }
+  double getDeltaTime () const { return delta ; }
+  double getFrameRate () const { return 1.0 / delta ; }
+} ;
+
+
+inline void ulSleep ( int seconds )
+{
+  if ( seconds >= 0 )
+  {
+#ifdef UL_WIN32
+    Sleep ( 1000 * seconds ) ;
+#else
+    sleep ( seconds ) ;
+#endif
+  }
+}
+
+
+inline void ulMilliSecondSleep ( int milliseconds )
+{
+	if ( milliseconds >= 0 )
+	{
+#ifdef UL_WIN32
+		Sleep ( milliseconds ) ;
+#else
+		usleep ( milliseconds * 1000 ) ;
+#endif
+	}
+}
+
+inline void ulMicroSecondSleep ( int microseconds )
+{
+	if ( microseconds >= 0 )
+	{
+#ifdef UL_WIN32
+		Sleep ( microseconds/1000 ) ;
+#else
+		usleep ( microseconds) ;
+#endif
+	}
+}
+
+
+/*
+  This is extern C to enable 'configure.in' to
+  find it with a C-coded probe.
+*/
+
+extern "C" void ulInit () ;
+
+/*
+  Error handler.
+*/
+
+enum ulSeverity
+{
+  UL_DEBUG,    // Messages that can safely be ignored.
+  UL_WARNING,  // Messages that are important.
+  UL_FATAL,    // Errors that we cannot recover from.
+  UL_MAX_SEVERITY
+} ;
+
+
+typedef void (*ulErrorCallback) ( enum ulSeverity severity, char* msg ) ;
+
+void            ulSetError         ( enum ulSeverity severity, const char *fmt, ... ) ;
+char*           ulGetError         ( void ) ;
+void            ulClearError       ( void ) ;
+ulErrorCallback ulGetErrorCallback ( void ) ;
+void            ulSetErrorCallback ( ulErrorCallback cb ) ;
+
+/*
+  Directory Reading
+*/
+
+#define UL_NAME_MAX 256
+typedef struct _ulDir ulDir ;
+struct ulDirEnt
+{
+  char d_name [ UL_NAME_MAX+1 ];
+  bool d_isdir ;
+} ;
+
+int ulIsAbsolutePathName ( const char *pathname ) ;
+char *ulGetCWD ( char *result, int maxlength ) ;
+
+ulDir* ulOpenDir ( const char* dirname ) ;
+ulDirEnt* ulReadDir ( ulDir* dir ) ;
+void ulCloseDir ( ulDir* dir ) ;
+
+// file handling
+
+char* ulMakePath( char* path, const char* dir, const char* fname );
+
+bool ulFileExists ( const char *fileName ) ;
+
+void ulFindFile( char *filenameOutput, const char *path, 
+											  const char * tfnameInput, const char *sAPOM ) ;
+
+
+/*
+  Endian handling
+*/
+
+static const int _ulEndianTest = 1;
+#define ulIsLittleEndian (*((char *) &_ulEndianTest ) != 0)
+#define ulIsBigEndian    (*((char *) &_ulEndianTest ) == 0)
+
+inline void ulEndianSwap(unsigned int *x)
+{
+  *x = (( *x >> 24 ) & 0x000000FF ) | 
+       (( *x >>  8 ) & 0x0000FF00 ) | 
+       (( *x <<  8 ) & 0x00FF0000 ) | 
+       (( *x << 24 ) & 0xFF000000 ) ;
+}
+
+  
+inline void ulEndianSwap(unsigned short *x)
+{
+  *x = (( *x >>  8 ) & 0x00FF ) | 
+       (( *x <<  8 ) & 0xFF00 ) ;
+}
+  
+
+inline void ulEndianSwap(float *x) { ulEndianSwap((unsigned int   *)x); }
+inline void ulEndianSwap(int   *x) { ulEndianSwap((unsigned int   *)x); }
+inline void ulEndianSwap(short *x) { ulEndianSwap((unsigned short *)x); }
+
+
+inline unsigned short ulEndianLittle16(unsigned short x) {
+  if (ulIsLittleEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline unsigned int ulEndianLittle32(unsigned int x) {
+  if (ulIsLittleEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline float ulEndianLittleFloat(float x) {
+  if (ulIsLittleEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline void ulEndianLittleArray16(unsigned short *x, int length) {
+  if (ulIsLittleEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline void ulEndianLittleArray32(unsigned int *x, int length) {
+  if (ulIsLittleEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline void ulEndianLittleArrayFloat(float *x, int length) {
+  if (ulIsLittleEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline void ulEndianBigArray16(unsigned short *x, int length) {
+  if (ulIsBigEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline void ulEndianBigArray32(unsigned int *x, int length) {
+  if (ulIsBigEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline void ulEndianBigArrayFloat(float *x, int length) {
+  if (ulIsBigEndian) {
+    return;
+  } else {
+    for (int i = 0; i < length; i++) {
+      ulEndianSwap(x++);
+    }
+  }
+}
+
+inline unsigned short ulEndianBig16(unsigned short x) {
+  if (ulIsBigEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline unsigned int ulEndianBig32(unsigned int x) {
+  if (ulIsBigEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline float ulEndianBigFloat(float x) {
+  if (ulIsBigEndian) {
+    return x;
+  } else {
+    ulEndianSwap(&x);
+    return x;
+  }
+}
+
+inline unsigned short ulEndianReadLittle16(FILE *f) {
+  unsigned short x;
+  fread(&x, 2, 1, f);
+  return ulEndianLittle16(x);
+}
+
+inline unsigned int ulEndianReadLittle32(FILE *f) {
+  unsigned int x;
+  fread(&x, 4, 1, f);
+  return ulEndianLittle32(x);
+}
+
+inline float ulEndianReadLittleFloat(FILE *f) {
+  float x;
+  fread(&x, 4, 1, f);
+  return ulEndianLittleFloat(x);
+}
+
+inline unsigned short ulEndianReadBig16(FILE *f) {
+  unsigned short x;
+  fread(&x, 2, 1, f);
+  return ulEndianBig16(x);
+}
+
+inline unsigned int ulEndianReadBig32(FILE *f) {
+  unsigned int x;
+  fread(&x, 4, 1, f);
+  return ulEndianBig32(x);
+}
+
+inline float ulEndianReadBigFloat(FILE *f) {
+  float x;
+  fread(&x, 4, 1, f);
+  return ulEndianBigFloat(x);
+}
+
+inline size_t ulEndianWriteLittle16(FILE *f, unsigned short x) {
+  x = ulEndianLittle16(x);
+  return fwrite( &x, 2, 1, f );
+}
+
+inline size_t ulEndianWriteLittle32(FILE *f, unsigned int x) {
+  x = ulEndianLittle32(x);
+  return fwrite( &x, 4, 1, f );
+}
+
+inline size_t ulEndianWriteLittleFloat(FILE *f, float x) {
+  x = ulEndianLittleFloat(x);
+  return fwrite( &x, 4, 1, f );
+}
+
+inline size_t ulEndianWriteBig16(FILE *f, unsigned short x) {
+  x = ulEndianBig16(x);
+  return fwrite( &x, 2, 1, f );
+}
+
+inline size_t ulEndianWriteBig32(FILE *f, unsigned int x) {
+  x = ulEndianBig32(x);
+  return fwrite( &x, 4, 1, f );
+}
+
+inline size_t ulEndianWriteBigFloat(FILE *f, float x) {
+  x = ulEndianBigFloat(x);
+  return fwrite( &x, 4, 1, f );
+}
+
+
+/*
+  Windoze/BEOS code based on contribution from Sean L. Palmer 
+*/
+
+
+#ifdef UL_WIN32
+
+class ulDynamicLibrary
+{
+  HMODULE handle ;
+
+public:
+
+  ulDynamicLibrary ( const char *libname )
+  {
+    char dllname[1024];
+    strcpy ( dllname, libname ) ;
+    strcat ( dllname, ".dll"  ) ;
+#ifdef UL_WIN32
+    handle = (HMODULE) LoadLibraryA ( (char*)dllname ) ;
+#else
+    handle = (HMODULE) LoadLibrary ( (char*)dllname ) ;
+
+#endif
+  }
+
+  void *getFuncAddress ( const char *funcname )
+  {
+    return (void *) GetProcAddress ( handle, funcname ) ; //lint !e611
+  }
+
+  ~ulDynamicLibrary ()
+  {
+    if ( handle != NULL )
+      FreeLibrary ( handle ) ;
+  }
+} ;
+
+#elif defined (UL_MACINTOSH)
+
+class ulDynamicLibrary
+{
+    CFragConnectionID connection;
+    OSStatus          error;
+
+public:
+
+    ulDynamicLibrary ( const char *libname )
+    {
+        Str63    pstr;
+        int        sz;
+
+        sz = strlen (libname);
+
+        if (sz < 64) {
+
+            pstr[0] = sz;
+            memcpy (pstr+1, libname, sz);
+
+            error = GetSharedLibrary (pstr, kPowerPCCFragArch, kReferenceCFrag,
+                                      &connection, NULL, NULL);
+        }
+        else
+            error = 1;
+    }
+
+    ~ulDynamicLibrary ()
+    {
+        if ( ! error )
+            CloseConnection (&connection);
+    }
+
+    void* getFuncAddress ( const char *funcname )
+    {
+        if ( ! error ) {
+
+            char*  addr;
+            Str255 sym;
+            int    sz;
+
+            sz = strlen (funcname);
+            if (sz < 256) {
+
+                sym[0] = sz;
+                memcpy (sym+1, funcname, sz);
+
+                error = FindSymbol (connection, sym, &addr, 0);
+                if ( ! error )
+                    return addr;
+            }
+        }
+
+        return NULL;
+    }
+};
+
+#elif defined (UL_MAC_OSX)
+
+
+class ulDynamicLibrary
+{
+
+ public:
+
+    ulDynamicLibrary ( const char *libname )
+    {
+    }
+
+    ~ulDynamicLibrary ()
+    {
+    }
+
+    void* getFuncAddress ( const char *funcname )
+    {
+      ulSetError ( UL_WARNING, "ulDynamicLibrary unsuppored on Mac OS X" );
+      return NULL;
+    }
+};
+
+#elif defined (__BEOS__)
+
+class ulDynamicLibrary
+{
+  image_id *handle ;
+
+public:
+
+  ulDynamicLibrary ( const char *libname )
+  {
+    char addonname[1024] ;
+    strcpy ( addonname, libname ) ;
+    strcat ( addonname, ".so" ) ;
+    handle = new image_id ;
+
+    *handle = load_add_on ( addonname ) ;
+
+    if ( *handle == B_ERROR )
+    {
+      delete handle ;
+      handle = NULL ;
+    }
+  }
+
+  void *getFuncAddress ( const char *funcname )
+  {
+    void *sym = NULL ;
+
+    if ( handle &&
+         get_image_symbol ( handle, "funcname",
+                            B_SYMBOL_TYPE_TEXT, &sym ) == B_NO_ERROR )
+      return sym ;
+
+    return NULL ;
+  }
+
+  ~ulDynamicLibrary ()
+  {
+    if ( handle != NULL )
+      unload_add_on ( handle ) ;
+
+    delete handle ;
+  }
+} ;
+
+#  else
+
+/*
+  Linux/UNIX
+*/
+
+class ulDynamicLibrary
+{
+  void *handle ;
+
+public:
+
+  ulDynamicLibrary ( const char *libname )
+  {
+    char dsoname [ 1024 ] ;
+    strcpy ( dsoname, libname ) ;
+    strcat ( dsoname, ".so"  ) ;
+    handle = (void *) dlopen ( dsoname, RTLD_NOW | RTLD_GLOBAL ) ;
+
+    if ( handle == NULL )
+      ulSetError ( UL_WARNING, "ulDynamicLibrary: %s\n", dlerror() ) ;
+  }
+
+  void *getFuncAddress ( const char *funcname )
+  {
+    return (handle==NULL) ? NULL : dlsym ( handle, funcname ) ;
+  }
+
+  ~ulDynamicLibrary ()
+  {
+    if ( handle != NULL )
+      dlclose ( handle ) ;
+  }
+} ;
+
+#endif
+
+
+class ulList
+{
+protected:
+  unsigned int total ;  /* The total number of entities in the list */
+  unsigned int limit ;  /* The current limit on number of entities  */
+  unsigned int next  ;  /* The next entity when we are doing getNext ops */
+ 
+  void **entity_list ;  /* The list. */
+ 
+  void sizeChk (void) ;
+ 
+public:
+ 
+  ulList ( int init_max = 1 ) ;
+  virtual ~ulList (void) ;
+ 
+  void *getEntity ( unsigned int n )
+  {
+    next = n + 1 ;
+    return ( n >= total ) ? (void *) NULL : entity_list [ n ] ;
+  }
+ 
+  virtual void addEntity ( void *entity ) ;
+  virtual void addEntityBefore ( int n, void *entity ) ;
+  virtual void removeEntity ( unsigned int n ) ;
+ 
+  void removeAllEntities () ;
+ 
+  void removeEntity ( void *entity )
+  {
+    removeEntity ( searchForEntity ( entity ) ) ;
+  }
+ 
+  virtual void replaceEntity ( unsigned int n, void *new_entity ) ;
+ 
+  void replaceEntity ( void *old_entity, void *new_entity )
+  {
+    replaceEntity ( searchForEntity ( old_entity ), new_entity ) ;
+  }
+ 
+  void *getNextEntity   (void) { return getEntity ( next ) ; }
+
+  int   getNumEntities  (void) const { return total ; }
+  int   searchForEntity ( void *entity ) const ;
+} ;
+
+
+typedef bool (*ulIterateFunc)( const void *data, void *user_data ) ;
+typedef int  (*ulCompareFunc)( const void *data1, const void *data2 ) ;
+
+/*
+  Linked list.
+*/
+
+class ulListNode ;
+
+class ulLinkedList
+{
+protected:
+
+  ulListNode *head ;
+  ulListNode *tail ;
+
+  int nnodes ;
+  bool sorted ;
+
+  void unlinkNode ( ulListNode *prev, ulListNode *node ) ;
+
+  bool isValidPosition ( int pos ) const
+  {
+    if ( ( pos < 0 ) || ( pos >= nnodes ) )
+    {
+      ulSetError ( UL_WARNING, "ulLinkedList: Invalid 'pos' %u", pos ) ;
+      return false ;
+    }
+    return true ;
+  }
+
+public:
+
+  ulLinkedList ()
+  {
+    head = tail = NULL ;
+    nnodes = 0 ;
+    sorted = true ;
+  }
+
+  ~ulLinkedList () { empty () ; }
+
+  int  getNumNodes ( void ) const { return nnodes ; }
+  bool isSorted    ( void ) const { return sorted ; }
+
+  int  getNodePosition ( void *data ) const ;
+
+  void insertNode ( void *data, int pos ) ;
+  void prependNode ( void *data ) { insertNode ( data, 0 ) ; }
+  void appendNode ( void *data ) ;
+
+  int  insertSorted ( void *data, ulCompareFunc comparefn ) ;
+
+  void removeNode ( void *data ) ;
+  void * removeNode ( int pos ) ;
+
+  void * getNodeData ( int pos ) const ;
+
+  void * forEach ( ulIterateFunc fn, void *user_data = NULL ) const ;
+
+  void empty ( ulIterateFunc destroyfn = NULL, void *user_data = NULL ) ;
+} ;
+
+
+extern char *ulStrDup ( const char *s ) ;
+extern int ulStrNEqual ( const char *s1, const char *s2, int len );
+extern int ulStrEqual ( const char *s1, const char *s2 );
+
+//lint -restore
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ulLocal.h b/ossimPlanet/include/ossimPlanet/ulLocal.h
new file mode 100644
index 0000000..e7e7cea
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ulLocal.h
@@ -0,0 +1,52 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ulLocal.h 1568 2002-09-02 06:05:49Z sjbaker $
+*/
+
+#ifndef _UL_LOCAL_H_
+#define _UL_LOCAL_H_ 1
+
+#include "ul.h"
+
+class ulListNode
+{
+protected:
+
+  ulListNode *next ;
+  void *data ;
+
+public:
+
+  ulListNode ( void *dt, ulListNode *next_node )
+  {
+    data = dt ;
+    next = next_node ;
+  }
+
+  void * getData ( void ) const { return data ; }
+  void   setData ( void *d )    { data = d    ; }
+
+  ulListNode * getNext ( void ) const { return next ; }
+  void setNext ( ulListNode *n )      { next = n    ; }
+} ;
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/ulRTTI.h b/ossimPlanet/include/ossimPlanet/ulRTTI.h
new file mode 100644
index 0000000..e8c5216
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/ulRTTI.h
@@ -0,0 +1,420 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+     For further information visit http://plib.sourceforge.net                  */
+
+
+/*
+  Originally written by: Alexandru C. Telea <alext at win.tue.nl>
+*/
+
+/*
+  This file provides support for RTTI and generalized (virtual-base to derived
+  and separate hierarchy branches) casting. There is also support for RT obj
+  creation from type names.
+
+  In order to enable these features for a class, two things should be done:
+
+  1)	insert the text UL_TYPE_DATA (without ';') in the class-decl.
+  2)	in the .C file where the class's implementation resides, insert the
+	following (without';'):
+
+	UL_RTTI_DEF(classname)
+	if the class has no bases with RTTI
+
+	UL_RTTI_DEFn(classname,b1,...bn)
+	if the class has bases b1,...bn with RTTI
+
+	Use UL_RTTI_DEF_INST instead of UL_RTTI_DEF if you want to enable RT
+	obj creation for classname. You should provide then a public default
+	ctor.
+
+  RTTI is used via a class called ulRTTItypeid. A typeid describes a type of a
+  class. [..] They should provide all necessary support for any kind of
+  RTTI/casting [..].
+
+  [..]
+
+  REMARK:	There are two classes related to RTTI: ulRTTItypeid and
+  =======	ulRTTITypeinfo. A ulRTTItypeid is, as it says, an 'id for a
+		type'. It actually wraps a ulRTTITypeinfo*, where a
+		ulRTTITypeinfo contains the actual encoding of a class type.
+		You can freely create/copy/destroy/manipulate ulRTTItypeid's,
+		but you should NEVER deal directly with ulRTTITypeinfo. A
+		ulRTTITypeinfo should actually be created ONLY by the
+		UL_TYPE_DATA macros, as part of a class definition, since the
+		ulRTTITypeinfo encodes a type info for an EXISTING class [..].
+		All type-related stuff should be therefore handled via
+		ulRTTItypeid's.
+*/
+
+#ifndef _UL_RTTI_H_
+#define _UL_RTTI_H_
+
+#include <string.h>
+#include "ul.h"
+
+
+class ulRTTITypeinfo
+/* Implementation of type-related info */
+{
+private:
+
+  char *n ; /* type name */
+
+  /*
+    base types (NULL-ended array of ulRTTITypeinfo's for this's direct bases)
+  */
+  const ulRTTITypeinfo** b ;
+
+  int ns ;  /* #subtypes of this type */
+  const ulRTTITypeinfo **subtypes ; /* types derived from this type */
+
+  /* convenience type info for a 'null' type */
+  static const ulRTTITypeinfo null_type ;
+
+  void* (*new_obj)() ;       /* func to create a new obj of this type */
+  void* (*cast)(int,void*) ; /*
+                               func to cast an obj of this type to ith
+                               baseclass of it or to itself
+                             */
+
+  /* adds a subtype to this's subtypes[] */
+  void add_subtype ( const ulRTTITypeinfo * ) ;
+
+  /* dels a subtype from this's subtypes[] */
+  void del_subtype ( const ulRTTITypeinfo* ) ;
+
+  friend class ulRTTItypeid ; /* for null_type */
+
+public:
+
+  ulRTTITypeinfo ( const char* name, const ulRTTITypeinfo* bb[],
+                   void* (*)(int,void*),void* (*)() ) ;
+  ~ulRTTITypeinfo () ;
+
+  /* Returns name of this ulRTTITypeinfo */
+  const char* getname () const { return n ; }
+
+  /* Compares 2 ulRTTITypeinfo objs */
+  bool same ( const ulRTTITypeinfo *p ) const
+  {
+    /*
+      First, try to see if it's the same 'physical' ulRTTITypeinfo (which
+      should be the case, since we create them per-class and not per-obj).
+    */
+    return ( this == p ) || !strcmp ( n, p->n ) ;
+  }
+
+  /* true if the arg can be cast to this, else false */
+  bool can_cast ( const ulRTTITypeinfo *p ) const
+  {
+    return same ( p ) || p->has_base ( this ) ;
+  }
+
+  /* true if this has the arg as some base, else false */
+  bool has_base ( const ulRTTITypeinfo *p ) const
+  {
+    for ( int i = 0 ; b[i] != NULL ; i++ ) /* for all bases of this... */
+      /* match found, return 1 or no match, search deeper */
+      if ( p->same ( b[i] ) || b[i]->has_base ( p ) ) return true ;
+    return false ; /* no match at all, return false */
+  }
+
+  /* get i-th subclass of this, if any, else NULL */
+  const ulRTTITypeinfo * subclass ( int i = 0 ) const
+  {
+    return ( i >= 0 && i < ns ) ? subtypes[i] : NULL ;
+  }
+
+  int num_subclasses () const { return ns ; } /* get # subclasses of this */
+
+  /*
+    search for a subclass named char*, create obj of it and return it cast to
+    the ulRTTITypeinfo* type, which is either this or a direct base of this.
+  */
+  void * create ( const ulRTTITypeinfo *, const char * ) const ;
+
+  /* Returns true if this type has a default ctor, else false */
+  bool can_create () const { return new_obj != NULL ; }
+} ;
+
+
+class ulRTTItypeid	
+/* Main class for RTTI interface */
+{
+protected:
+
+  /* ulRTTItypeid implementation (the only data-member) */
+  const ulRTTITypeinfo* id ;
+
+public:
+
+  /* Not for application use ! */
+  const ulRTTITypeinfo* get_info () const { return id ; }
+
+  ulRTTItypeid ( const ulRTTITypeinfo* p ) : id ( p ) { }
+  ulRTTItypeid () : id ( &ulRTTITypeinfo::null_type ) { }
+
+  /* Compares 2 ulRTTItypeid objs */
+  bool isSame ( ulRTTItypeid i ) const { return id->same ( i.id ) ; }
+
+  /* true if the arg can be cast to this, else false */
+  bool canCast ( ulRTTItypeid i ) const { return id->can_cast ( i.id ) ; }
+
+  const char * getName () const { return id->getname () ; }
+
+  /* Return # subclasses of this  */
+  int getNumSubclasses  () const { return id->num_subclasses () ; }
+
+  /* Return ith subclass of this */
+  ulRTTItypeid getSubclass ( int i ) const { return id->subclass ( i ) ; }
+
+  /* Return # baseclasses of this */
+  int getNumBaseclasses () const
+  {
+    int i ; for ( i = 0 ; id->b[i] != NULL ; i++ ) ;
+    return i ;
+  }
+
+  /* Return ith baseclass of this */
+  ulRTTItypeid getBaseclass ( int i ) const { return id->b[i] ; }
+
+  /*
+    Tries to create an instance of a subclass of this having of type given
+    by the ulRTTItypeid arg. If ok, it returns it casted to the class-type of
+    this and then to void*
+  */
+  void * create ( ulRTTItypeid t ) const
+  {
+    return id->create ( id, t.getName () ) ; 
+  }
+
+  /* Returns true if this type is instantiable, else false */
+  bool canCreate () const { return id->can_create () ; }
+} ;
+
+
+class ulRTTIdyntypeid : public ulRTTItypeid
+/*
+  Class for dynamic type creation from user strings. Useful for creating
+  typeids at RT for comparison purposes.
+*/
+{
+private:
+
+  static const ulRTTITypeinfo *a[] ;
+
+public:
+
+  ulRTTIdyntypeid ( const char *c ) :
+     /* create a dummy ulRTTITypeinfo */
+     ulRTTItypeid ( new ulRTTITypeinfo ( c, a, NULL, NULL ) ) { }
+
+  ~ulRTTIdyntypeid () { delete id ; /* delete the dummy ulRTTITypeinfo */ }
+} ;
+
+
+
+/*
+  Macros
+*/
+
+/*
+  'ulRTTItypeid'
+  UL_STATIC_TYPE_INFO(T)	T=RTTI-class name.
+				Returns a ulRTTItypeid with T's type. If T
+				hasn't RTTI, a compile-time error occurs.
+*/
+
+#define UL_STATIC_TYPE_INFO(T) T::RTTI_sinfo()
+
+
+/*
+  'T*'
+  UL_PTR_CAST(T,p)	T=RTTI-class, p=RTTI-class ptr.
+			Returns p cast to the type T as a T*, if cast is
+			possible, else returns NULL. If *p or T have no RTTI,
+			a compile-time error occurs. Note that p can point to
+			virtual base classes. Casting between separat branches
+			of a class hierarchy is also supported, as long as all
+			classes have RTTI. Therefore UL_PTR_CAST is a fully
+			general and safe operator. If p==NULL, the operator
+			returns NULL.
+*/
+
+#define UL_PTR_CAST(T,p)   ((p != NULL)? (T*)((p)->RTTI_cast(UL_STATIC_TYPE_INFO(T))) : NULL)
+
+
+/* 'T*'
+   UL_TYPE_NEW(T,t)	T=RTTI-class, t=ulRTTItypeid
+			Returns a new object of type t cast to the type T as
+			a T*. t must represent a type identical to or derived
+			from T. If t is not a type derived from T or not an
+                        instantiable type having a default constructor, NULL is
+                        returned. */
+
+#define UL_TYPE_NEW(T,t)   ((T*)t.create(T))
+
+
+
+/*
+  Definition of TYPE_DATA for a RTTI-class: introduces one static
+  ulRTTITypeinfo data-member and a couple of virtuals.
+*/
+
+#define UL_TYPE_DATA			 		          \
+	protected:					          \
+	   static  const  ulRTTITypeinfo RTTI_obj; 		  \
+	   static  void*  RTTI_scast(int,void*);	          \
+	   static  void*  RTTI_new();			          \
+	   virtual ulRTTItypeid RTTI_vinfo() const { return &RTTI_obj; }\
+	public:						          \
+	   static  ulRTTItypeid RTTI_sinfo()	 { return &RTTI_obj; }\
+	   virtual void*  RTTI_cast(ulRTTItypeid);
+
+
+
+/*
+  Definition of auxiliary data-structs supporting RTTI for a class: defines
+  the static ulRTTITypeinfo object of that class and its associated virtuals.
+*/
+
+/* Auxiliary definition of the construction method: */
+#define UL_RTTI_NEW(cls)     void* cls::RTTI_new() { return new cls; }	\
+			     const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,cls::RTTI_new);
+
+#define UL_RTTI_NO_NEW(cls)  const ulRTTITypeinfo cls::RTTI_obj(#cls,RTTI_base_ ## cls,cls::RTTI_scast,NULL);
+
+
+
+/*
+  Top-level macros:
+*/
+
+#define UL_RTTI_DEF_BASE(cls)						\
+	static const ulRTTITypeinfo* RTTI_base_ ## cls [] = { NULL };	\
+	void* cls::RTTI_cast(ulRTTItypeid t)				\
+	{								\
+	   if (t.isSame(&RTTI_obj)) return this;			\
+	   return NULL;							\
+	}								\
+	void* cls::RTTI_scast(int i,void* p)				\
+	{  cls* ptr = (cls*)p; return ptr; }			
+	
+
+#define UL_RTTI_DEF1_BASE(cls,b1)					\
+        static const ulRTTITypeinfo* RTTI_base_ ## cls [] = 		\
+	       { UL_STATIC_TYPE_INFO(b1).get_info(), NULL };		\
+  	void* cls::RTTI_cast(ulRTTItypeid t)				\
+	{								\
+	   if (t.isSame(&RTTI_obj)) return this;			\
+	   void* ptr;							\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;			\
+	   return NULL;							\
+	}								\
+	void* cls::RTTI_scast(int i,void* p)				\
+	{  cls* ptr = (cls*)p;						\
+	   switch(i)							\
+	   {  case  0: return (b1*)ptr;	 }				\
+	   return ptr;							\
+	}							
+									
+
+#define UL_RTTI_DEF2_BASE(cls,b1,b2)					\
+        static const ulRTTITypeinfo* RTTI_base_ ## cls [] = 		\
+	       { UL_STATIC_TYPE_INFO(b1).get_info(),			\
+		 UL_STATIC_TYPE_INFO(b2).get_info(), NULL };		\
+  	void* cls::RTTI_cast(ulRTTItypeid t)				\
+	{								\
+	   if (t.isSame(&RTTI_obj)) return this;			\
+	   void* ptr;							\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;			\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;			\
+	   return NULL;							\
+	}								\
+	void* cls::RTTI_scast(int i,void* p)				\
+	{  cls* ptr = (cls*)p;						\
+	   switch(i)							\
+	   {  case  0: return (b1*)ptr;					\
+	      case  1: return (b2*)ptr;					\
+	   }								\
+	   return ptr;							\
+	}							
+	
+#define UL_RTTI_DEF3_BASE(cls,b1,b2,b3)					\
+        static const ulRTTITypeinfo* RTTI_base_ ## cls [] = 		\
+	       { UL_STATIC_TYPE_INFO(b1).get_info(),			\
+		 UL_STATIC_TYPE_INFO(b2).get_info(),			\
+		 UL_STATIC_TYPE_INFO(b3).get_info(), NULL };		\
+  	void* cls::RTTI_cast(ulRTTItypeid t)				\
+	{								\
+	   if (t.isSame(&RTTI_obj)) return this;			\
+	   void* ptr;							\
+	   if ((ptr=b1::RTTI_cast(t))) return ptr;			\
+	   if ((ptr=b2::RTTI_cast(t))) return ptr;			\
+	   if ((ptr=b3::RTTI_cast(t))) return ptr;			\
+	   return NULL;							\
+	}								\
+	void* cls::RTTI_scast(int i,void* p)				\
+	{  cls* ptr = (cls*)p;						\
+	   switch(i)							\
+	   {  case  0: return (b1*)ptr;					\
+	      case  1: return (b2*)ptr;					\
+	      case  2: return (b3*)ptr;					\
+	   }								\
+	   return ptr;							\
+	}							
+
+
+
+#define UL_RTTI_DEF_INST(cls)		\
+	UL_RTTI_DEF_BASE(cls)		\
+	UL_RTTI_NEW(cls)
+
+#define UL_RTTI_DEF(cls)		\
+	UL_RTTI_DEF_BASE(cls)		\
+	UL_RTTI_NO_NEW(cls)
+
+#define UL_RTTI_DEF1_INST(cls,b1)	\
+	UL_RTTI_DEF1_BASE(cls,b1)	\
+	UL_RTTI_NEW(cls)
+
+#define UL_RTTI_DEF1(cls,b1)		\
+	UL_RTTI_DEF1_BASE(cls,b1)	\
+	UL_RTTI_NO_NEW(cls)
+	
+#define UL_RTTI_DEF2_INST(cls,b1,b2)	\
+	UL_RTTI_DEF2_BASE(cls,b1,b2)	\
+	UL_RTTI_NEW(cls)
+
+#define UL_RTTI_DEF2(cls,b1,b2)		\
+	UL_RTTI_DEF2_BASE(cls,b1,b2)	\
+	UL_RTTI_NO_NEW(cls)
+
+#define UL_RTTI_DEF3_INST(cls,b1,b2,b3)	\
+	UL_RTTI_DEF3_BASE(cls,b1,b2,b3)	\
+	UL_RTTI_NEW(cls)
+
+#define UL_RTTI_DEF3(cls,b1,b2,b3)	\
+	UL_RTTI_DEF3_BASE(cls,b1,b2,b3)	\
+	UL_RTTI_NO_NEW(cls)
+
+
+#endif
+
diff --git a/ossimPlanet/include/ossimPlanet/unzip.h b/ossimPlanet/include/ossimPlanet/unzip.h
new file mode 100644
index 0000000..3573be2
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/unzip.h
@@ -0,0 +1,354 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+
+   Multi volume ZipFile (span) are not supported.
+   Encryption compatible with pkzip 2.04g only supported
+   Old compressions used by old PKZip 1.x are not supported
+
+
+   I WAIT FEEDBACK at mail info at winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  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.
+
+
+*/
+
+/* for more info about .ZIP format, see
+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
+      http://www.info-zip.org/pub/infozip/doc/
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip
+*/
+
+#ifndef _unz_H
+#define _unz_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include <ossimPlanet/ioapi.h>
+#endif
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                          (0)
+#define UNZ_END_OF_LIST_OF_FILE         (-100)
+#define UNZ_ERRNO                       (Z_ERRNO)
+#define UNZ_EOF                         (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info_s
+{
+    uLong number_entry;         /* total number of entries in
+                       the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                 const char* fileName2,
+                                                 int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+    (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+     "zlib/zlib113.zip".
+     If the zipfile cannot be opened (file don't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+                                    zlib_filefunc_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unzOpen, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                        unz_global_info *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                           char *szComment,
+                                           uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+                     const char *szFileName,
+                     int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   /* offset in zip file directory */
+    uLong num_of_file;            /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+        the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+            (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+            (extraFieldBufferSize is the size of the buffer).
+            This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+            (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+                                                  const char* password));
+/*
+  Open for reading data the current file in the zipfile.
+  password is a crypting password
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw,
+                                           const char* password));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+                      voidp buf,
+                      unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                             voidp buf,
+                                             unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz_H */
diff --git a/ossimPlanet/include/ossimPlanet/zip.h b/ossimPlanet/include/ossimPlanet/zip.h
new file mode 100644
index 0000000..b0bcff4
--- /dev/null
+++ b/ossimPlanet/include/ossimPlanet/zip.h
@@ -0,0 +1,235 @@
+/* zip.h -- IO for compress .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+   Multi volume ZipFile (span) are not supported.
+   Encryption compatible with pkzip 2.04g only supported
+   Old compressions used by old PKZip 1.x are not supported
+
+  For uncompress .zip file, look at unzip.h
+
+
+   I WAIT FEEDBACK at mail info at winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  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.
+
+
+*/
+
+/* for more info about .ZIP format, see
+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
+      http://www.info-zip.org/pub/infozip/doc/
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip
+*/
+
+#ifndef _zip_H
+#define _zip_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include <ossimPlanet/ioapi.h>
+#endif
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK                          (0)
+#define ZIP_EOF                         (0)
+#define ZIP_ERRNO                       (Z_ERRNO)
+#define ZIP_PARAMERROR                  (-102)
+#define ZIP_BADZIPFILE                  (-103)
+#define ZIP_INTERNALERROR               (-104)
+
+#ifndef DEF_MEM_LEVEL
+#  if MAX_MEM_LEVEL >= 8
+#    define DEF_MEM_LEVEL 8
+#  else
+#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#  endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+    tm_zip      tmz_date;       /* date in understandable format           */
+    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
+/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
+
+    uLong       internal_fa;    /* internal file attributes        2 bytes */
+    uLong       external_fa;    /* external file attributes        4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE        (0)
+#define APPEND_STATUS_CREATEAFTER   (1)
+#define APPEND_STATUS_ADDINZIP      (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+/*
+  Create a zipfile.
+     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+       an Unix computer "zlib/zlib113.zip".
+     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+       will be created at the end of the file.
+         (useful if the file contain a self extractor code)
+     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+       add files in existing zip (be sure you don't add file that doesn't exist)
+     If the zipfile cannot be opened, the return value is NULL.
+     Else, the return value is a zipFile Handle, usable with other function
+       of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+   If you want delete file into a zipfile, you must open a zipfile, and create another
+   Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+                                   int append,
+                                   zipcharpc* globalcomment,
+                                   zlib_filefunc_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+                       const char* filename,
+                       const zip_fileinfo* zipfi,
+                       const void* extrafield_local,
+                       uInt size_extrafield_local,
+                       const void* extrafield_global,
+                       uInt size_extrafield_global,
+                       const char* comment,
+                       int method,
+                       int level));
+/*
+  Open a file in the ZIP for writing.
+  filename : the filename in zip (if NULL, '-' without quote will be used
+  *zipfi contain supplemental information
+  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+    contains the extrafield data the the local header
+  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+    contains the extrafield data the the local header
+  if comment != NULL, comment contain the comment string
+  method contain the compression method (0 for store, Z_DEFLATED for deflate)
+  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw));
+
+/*
+  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCtypting));
+
+/*
+  Same than zipOpenNewFileInZip2, except
+    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+    password : crypting password (NULL for no crypting)
+    crcForCtypting : crc of file to compress (needed for crypting)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+                       const void* buf,
+                       unsigned len));
+/*
+  Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+  Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+                                            uLong uncompressed_size,
+                                            uLong crc32));
+/*
+  Close the current file in the zipfile, for fiel opened with
+    parameter raw=1 in zipOpenNewFileInZip2
+  uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+                const char* global_comment));
+/*
+  Close the zipfile
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip_H */
diff --git a/ossimPlanet/projects/vs2005/ossimPlanet.sln b/ossimPlanet/projects/vs2005/ossimPlanet.sln
new file mode 100644
index 0000000..c60efb2
--- /dev/null
+++ b/ossimPlanet/projects/vs2005/ossimPlanet.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ossimPlanet", "ossimPlanet.vcproj", "{F042D695-C4DD-4282-B22F-A3041AB93623}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ossimplanetviewer", "..\..\examples\ossimplanetviewer\ossimplanetviewer.vcproj", "{982CDBCD-0217-4E0D-8870-338D101EB982}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F042D695-C4DD-4282-B22F-A3041AB93623} = {F042D695-C4DD-4282-B22F-A3041AB93623}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug using Release|Win32 = Debug using Release|Win32
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Debug using Release|Win32.ActiveCfg = Debug using Release|Win32
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Debug using Release|Win32.Build.0 = Debug using Release|Win32
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Debug|Win32.Build.0 = Debug|Win32
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Release|Win32.ActiveCfg = Release|Win32
+		{F042D695-C4DD-4282-B22F-A3041AB93623}.Release|Win32.Build.0 = Release|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Debug using Release|Win32.ActiveCfg = Release|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Debug using Release|Win32.Build.0 = Release|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Debug|Win32.ActiveCfg = Debug|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Debug|Win32.Build.0 = Debug|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Release|Win32.ActiveCfg = Release|Win32
+		{982CDBCD-0217-4E0D-8870-338D101EB982}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/ossimPlanet/projects/vs2005/ossimPlanet.vcproj b/ossimPlanet/projects/vs2005/ossimPlanet.vcproj
new file mode 100644
index 0000000..d75a184
--- /dev/null
+++ b/ossimPlanet/projects/vs2005/ossimPlanet.vcproj
@@ -0,0 +1,1381 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="ossimPlanet"
+	ProjectGUID="{F042D695-C4DD-4282-B22F-A3041AB93623}"
+	RootNamespace="ossimPlanet"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)\out\Debug"
+			IntermediateDirectory="$(OutDir)\work\$(ProjectName)\"
+			ConfigurationType="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\ossim_dependencies\src\3rdParty\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\zziplib-0.13.49";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph\include""
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;OSSIMPLANET_LIBRARY;ssize_t=int"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ossimd.lib OpenThreadsWin32d.lib Producerd.lib osgd.lib osgDBd.lib osgGAd.lib osgTextd.lib osgUtild.lib libwmsd.lib libjpegD.lib Ws2_32.lib Winmm.lib"
+				OutputFile="$(OutDir)\bin\$(ProjectName)d.dll"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=".\out\Release\lib;"$(OutDir)\lib";..\src\OpenSceneGraph\lib\win32"
+				GenerateDebugInformation="true"
+				SubSystem="0"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)\lib\ossimPlanetd.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir "$(SolutionDir)..\..\include\win32"&#x0D;&#x0A;xcopy /Y /S "$(SolutionDir)..\src\ossimPlanet\include" "$(SolutionDir)..\..\include\win32"&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\work\$(ProjectName)\"
+			ConfigurationType="2"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				WholeProgramOptimization="false"
+				AdditionalIncludeDirectories=""$(InputDir)..\..\include";"$(InputDir)..\..\..\libwms\include";"$(InputDir)..\..\..\ossim\include";"$(InputDir)..\..\..\ossimPredator\include";"$(InputDir)..\..\..\ossim_dependencies\include";"$(InputDir)..\..\..\ossim_dependencies\include\freetype";"$(InputDir)..\..\..\ossim_dependencies\src\ffmpeg""
+				PreprocessorDefinitions="WIN32;_LIB;NDEBUG;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;OSSIMPLANET_LIBRARY;ssize_t=int;OSSIMPLANET_ENABLE_PREDATOR;OSSIMPLANET_ENABLE_EPHEMERIS"
+				StringPooling="false"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="zlib1.lib OpenThreads.lib osg.lib osgDB.lib osgGA.lib osgText.lib osgUtil.lib osgViewer.lib libjpeg.lib Ws2_32.lib Winmm.lib opengl32.lib gpstk.lib"
+				OutputFile="$(OutDir)\bin\$(ProjectName).dll"
+				AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph-2.8.1\build\lib";"$(ProjectDir)..\..\..\ossim_dependencies\lib""
+				IgnoreDefaultLibraryNames="LIBCMT.lib"
+				GenerateDebugInformation="true"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)\lib\$(ProjectName).lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug using Release|Win32"
+			OutputDirectory="$(SolutionDir)\out\Debug"
+			IntermediateDirectory="$(OutDir)\work\$(ProjectName)\"
+			ConfigurationType="2"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=""$(ProjectDir)..\..\..\ossim_dependencies\src\3rdParty\include";"$(ProjectDir)..\..\..\ossim\include";"$(ProjectDir)..\..\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\zziplib-0.13.49";"$(ProjectDir)..\..\..\libwms\include";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph\include""
+				PreprocessorDefinitions="WIN32;_LIB;_CRT_SECURE_NO_DEPRECATE;OSSIMPLANET_LIBRARY;ssize_t=int"
+				StringPooling="true"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ossim.lib OpenThreadsWin32.lib Producer.lib osg.lib osgDB.lib osgGA.lib osgText.lib osgUtil.lib libwms.lib libjpeg.lib Ws2_32.lib Winmm.lib zzlib.lib"
+				OutputFile="$(OutDir)\bin\$(ProjectName)d.dll"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""$(ProjectDir)..\..\..\ossim\projects\vs2005\bin\Release";.\out\Release\lib;"$(OutDir)\lib";"$(ProjectDir)..\..\..\ossim_dependencies\src\OpenSceneGraph\lib\win32""
+				GenerateDebugInformation="true"
+				SubSystem="0"
+				OptimizeForWindows98="0"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)\lib\ossimPlanetd.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="mkdir "$(SolutionDir)..\..\include\win32"&#x0D;&#x0A;xcopy /Y /S "$(SolutionDir)..\src\ossimPlanet\include" "$(SolutionDir)..\..\include\win32"&#x0D;&#x0A;pushlib.bat "$(OutDir)\lib\ossimPlanetd.lib" "$(OutDir)\bin\ossimPlanetd.dll"&#x0D;&#x0A;"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ioapi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\iochannel.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\iowin32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\mkUtils.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netBuffer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netChannel.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netChat.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netMessage.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netMonitor.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\netSocket.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanet.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetAction.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetActionReceiver.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetActionRouter.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetAnimatedPointModel.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetAnimationPath.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetAnnotationLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetAnnotationLayerNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetApi.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetArchive.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetArchiveMapping.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetBillboardIcon.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetBoundingBox.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetCache.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetClientThread.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetCloudLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetCompass.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetCubeGrid.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetDatabasePager.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetDestinationCommandAction.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetDtedElevationDatabase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetElevationDatabase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetElevationDatabaseGroup.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetElevationFactory.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetElevationGrid.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetElevationRegistry.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetEphemeris.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetFadeText.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetGeneralRasterElevationDatabase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetGeocoder.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetGrid.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetGridUtility.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIconGeom.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetId.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIdManager.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetImage.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetInteractionController.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIoRoutableMessageHandler.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIoSocket.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIoSocketServerChannel.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetIoThread.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetJpegImage.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKml.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKmlLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKmlLayerNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKmlNetworkLinkNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKmlPlacemarkNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetKmlScreenOverlayNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLabelGeom.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLand.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLandCache.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLandCullCallback.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLandReaderWriter.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLatLonHud.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLayerFactory.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLayerRegistry.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLookAt.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetLsrSpaceTransform.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetManipulator.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetNavigator.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetNodeFactory.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetNodeRegistry.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetOperation.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetOssimElevationDatabase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetOssimImage.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetOssimImageLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetPagedLandLod.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetPlaneGrid.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetPointModel.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetPredatorVideoLayerNode.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetSceneView.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetServerThread.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetShaderProgramSetup.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetSocketNetworkConnection.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetSousaLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetSrtmElevationDatabase.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetStandardTextureLayerFactory.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTerrain.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTerrainGeometryTechnique.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTerrainLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTerrainTechnique.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTerrainTile.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTexture2D.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTextureLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTextureLayerGroup.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTextureLayerRegistry.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetThread.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetThreadImp.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetThreadPool.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetTileRequest.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetUtility.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetVideoLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetViewer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetViewMatrixBuilder.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetVisitors.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetWmsClient.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetWmsImageLayer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetXmlAction.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ossimPlanetYahooGeocoder.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\sg_file.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\sg_socket.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\sg_socket_udp.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ul.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ulClock.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ulError.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ulLinkedList.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ulList.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\ulRTTI.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\unzip.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ossimPlanet\zip.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<File
+			RelativePath="..\..\include\ossimPlanet\compiler.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\ossimPlanet\crypt.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ioapi.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\iochannel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\iowin32.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\mkUtils.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\net.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netBuffer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netChannel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netChat.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netMessage.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netMonitor.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\netSocket.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanet.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetAction.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetActionReceiver.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetActionRouter.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetAnimatedPointModel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetAnimationPath.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetAnnotationLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetAnnotationLayerNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetApi.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetArchive.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetArchiveMapping.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetBillboardIcon.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetBoundingBox.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetCache.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetCallback.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetClientThread.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetCloudLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetCompass.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetConstants.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetCubeGrid.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetDatabasePager.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetDestinationCommandAction.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetDtedElevationDatabase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetElevationDatabase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetElevationDatabaseGroup.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetElevationFactory.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetElevationGrid.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetElevationRegistry.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetEphemeris.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetExport.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetExtents.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetFadeText.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetGeneralRasterElevationDatabase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetGeocoder.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetGeoRefModel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetGrid.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetGridUtility.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIconGeom.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetId.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIdManager.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIdolBridge.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIdolLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetImage.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetInputDevice.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetInteractionController.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIntersectUserData.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIo.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIoMessageHandler.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIoRoutableMessageHandler.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIoSocket.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIoSocketServerChannel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetIoThread.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetJpegImage.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKml.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlLayerNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlNetworkLinkNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlPlacemarkNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlReaderWriter.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetKmlScreenOverlayNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLabelGeom.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLand.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandCache.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandCullCallback.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandNormalType.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandReaderWriter.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandTextureRequest.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLandTreeNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLatLonHud.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLayerFactory.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLayerFactoryBase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLayerRegistry.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLookAt.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetLsrSpaceTransform.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetManipulator.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetMessage.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNavigator.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNetworkConnection.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNodeFactory.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNodeFactoryBase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetNodeRegistry.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetOperation.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetOrthoFlatLandNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetOssimElevationDatabase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetOssimImage.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetOssimImageLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPagedLandLod.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPagedLandLodRefreshType.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPagedRequestNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPlaneGrid.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPointModel.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPredatorVideoLayerNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetPrimaryBody.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetReentrantMutex.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetRefBlock.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetSceneView.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetServerMessageHandler.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetServerThread.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetSetup.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetShaderProgramSetup.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetSocketNetworkConnection.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetSousaLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetSrtmElevationDatabase.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetStandardTextureLayerFactory.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrain.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrainGeometryTechnique.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrainLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrainTechnique.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrainTile.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTerrainTileId.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTexture2D.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTextureLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTextureLayerFactory.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTextureLayerGroup.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTextureLayerRegistry.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetThread.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetThreadImp.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetThreadPool.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetTileRequest.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetUtility.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetVideoLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetVideoLayerNode.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetViewer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetViewMatrixBuilder.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetVisitors.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetWmsClient.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetWmsImageLayer.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetXmlAction.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ossimPlanetYahooGeocoder.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\sg_file.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\sg_socket.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\sg_socket_udp.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ul.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ulLocal.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\ulRTTI.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\unzip.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\include\ossimPlanet\zip.h"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/ossimPlanet/schema/AnimationPath.xsd b/ossimPlanet/schema/AnimationPath.xsd
new file mode 100644
index 0000000..640a6ef
--- /dev/null
+++ b/ossimPlanet/schema/AnimationPath.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:simpleType name="pathCoordinatesType">
+        <xs:list itemType="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="orientationType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="lsrhpr"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="positionType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="latlonhgt"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="timeUnitEnumType" >
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="seconds"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:element name="GeospatialPath" type="GeospatialPathType"/>
+    <xs:complexType name="GeospatialPathType">
+        <xs:sequence>
+            <xs:element name="description" type="xs:string"/>
+            <xs:element name="coordinates" type="pathCoordinatesType" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" use="optional"/>
+        <xs:attribute name="id" use="optional"/>
+        <xs:attribute name="refId" use="optional"/>
+        <xs:attribute name="timeUnit" type="timeUnitEnumType" use="required"/>
+        <xs:attribute name="positionType" type="positionType" use="required"/>
+        <xs:attribute name="orientationType" type="orientationType" use="required"/>
+        <xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
+        <xs:attribute name="duration" type="xs:duration" use="optional"/>
+    </xs:complexType>
+    <xs:element name="AnimationPath" type="AnimationPathType" abstract="false"/>
+    <xs:complexType name="AnimationPathType" abstract="false">
+        <xs:sequence>
+            <xs:element name="name" type="xs:string" minOccurs="0" maxOccurs="1"/>            
+            <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>    
+            <xs:element ref="GeospatialPath" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="refId" type="xs:string" use="optional"/> 
+        <xs:attribute name="id" type="xs:string" use="optional"/> 
+        <xs:attribute name="parentId" type="xs:string" use="optional"/> 
+        <xs:attribute name="timeScale" type="xs:double" use="optional"/>
+        <xs:attribute name="timeOffset" type="xs:duration" use="optional"/>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
diff --git a/ossimPlanet/schema/ossimPlanet.xsd b/ossimPlanet/schema/ossimPlanet.xsd
new file mode 100644
index 0000000..efbd128
--- /dev/null
+++ b/ossimPlanet/schema/ossimPlanet.xsd
@@ -0,0 +1,447 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    
+    <xs:element name="AbstractObjectGroup" type="AbstractObjectType" abstract="true"/>
+    <xs:complexType name="AbstractObjectType" abstract="true">
+        <xs:sequence>
+            <xs:element name="id" type="xs:string" minOccurs="0" maxOccurs="1"> </xs:element>
+        </xs:sequence>
+        <xs:attribute name="id" type="xs:string" use="optional"> </xs:attribute>
+        <xs:attribute name="parentId" type="xs:string" use="optional"> </xs:attribute>
+    </xs:complexType>
+    <xs:element name="address" type="xs:string" default=""/>
+    <xs:element name="range" type="xs:double" default="0.0"/>
+    <xs:element name="longitude" type="angle180Type" default="0.0"/>
+    <xs:element name="latitude" type="angle90Type" default="0.0"/>
+    <xs:element name="altitude" type="xs:double" default="0.0"/>
+    <xs:attribute name="vref">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="wgs84"/>
+                <xs:enumeration value="msl"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="groupType">
+        <xs:simpleType>
+            <xs:restriction base="xs:string">
+                <xs:enumeration value="groundTexture"/>
+                <xs:enumeration value="feature"/>
+            </xs:restriction>
+        </xs:simpleType>
+    </xs:attribute>
+    <xs:simpleType name="objectType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="Placemark"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="heading" type="angle360Type" default="0.0"/>
+    <xs:element name="pitch" type="angle180Type" default="0.0"/>
+    <xs:element name="roll" type="angle180Type" default="0.0"/>
+    <xs:simpleType name="anglepos90Type">
+        <xs:restriction base="xs:double">
+            <xs:minInclusive value="0.0"/>
+            <xs:maxInclusive value="90.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="angle90Type">
+        <xs:restriction base="xs:double">
+            <xs:minInclusive value="-90"/>
+            <xs:maxInclusive value="90.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="anglepos180Type">
+        <xs:restriction base="xs:double">
+            <xs:minInclusive value="0.0"/>
+            <xs:maxInclusive value="180.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="angle180Type">
+        <xs:restriction base="xs:double">
+            <xs:minInclusive value="-180.0"/>
+            <xs:maxInclusive value="180.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="angle360Type">
+        <xs:restriction base="xs:double">
+            <xs:minInclusive value="-360.0"/>
+            <xs:maxInclusive value="360.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="metaKeyEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="shift"/>
+            <xs:enumeration value="ctrl"/>
+            <xs:enumeration value="alt"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="KeyType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value=".|space|delete|return|home|escape|right|left|up|down"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="mouseButtonType">
+        <xs:restriction base="xs:string">
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="mouseButtonStateEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="press"/>
+            <xs:enumeration value="release"/>
+            <xs:enumeration value="doubleClick"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="filename" type="xs:string"></xs:element>
+    <xs:element name="extrude" type="xs:boolean" default="0"/>
+    <xs:simpleType name="altitudeModeEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="clampToGround"/>
+            <xs:enumeration value="relativeToGround"/>
+            <xs:enumeration value="absolute"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="timeUnitEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="seconds"/>
+         </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="AbstractInputDeviceGroup" type="AbstractInputDeviceType" abstract="true"/>
+    <xs:complexType name="AbstractInputDeviceType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType">
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Link" type="LinkType" substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="LinkType">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType">
+                <xs:sequence>
+                </xs:sequence>
+                <xs:attribute name="href" type="xs:anyURI" use="required"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Keyboard" type="KeyboardType" abstract="false" final="#all"
+        substitutionGroup="AbstractInputDeviceGroup"/>
+    <xs:complexType name="KeyboardType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractInputDeviceType">
+                <xs:attribute name="key" type="KeyType" use="optional"/>    
+                <xs:attribute name="metaKey" type="metaKeyEnumType" use="optional"/>    
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="Mouse" type="MouseType" abstract="false" final="#all"
+        substitutionGroup="AbstractInputDeviceGroup"/>
+    <xs:complexType name="MouseType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractInputDeviceType">
+                <xs:attribute name="button" type="mouseButtonType" />    
+                <xs:attribute name="state" type="mouseButtonStateEnumType" />    
+                <xs:attribute name="metaKey" type="metaKeyEnumType" />    
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="AbstractActionObjectGroup" type="AbstractActionObjectType" abstract="true"/>
+    <xs:complexType name="AbstractActionObjectType" abstract="true">
+        <xs:attribute name="id" type="xs:ID" use="optional"> </xs:attribute>
+        <xs:attribute name="target" type="xs:string" use="optional"> </xs:attribute>
+        <xs:attribute name="origin" type="xs:string" use="optional"> </xs:attribute>
+    </xs:complexType>
+    
+     <xs:element name="Add" type="AbstractActionObjectContainerType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="Remove" type="AbstractActionObjectContainerType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="Set" type="AbstractActionObjectContainerType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="Get" type="AbstractActionObjectContainerType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="FlyTo" type="AbstractActionObjectFlyToType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="Bind" type="BindType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="Unbind" type="BindType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="UnbindAll" type="BindType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    <xs:element name="SendMessage" type="SendMessageType" abstract="false" final="#all"
+        substitutionGroup="AbstractActionObjectGroup"/>
+    
+    <xs:complexType name="AbstractActionObjectContainerType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractActionObjectType">
+                <xs:sequence>
+                    <xs:element ref="AbstractObjectGroup" minOccurs="0" maxOccurs="unbounded"></xs:element>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="BindType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractActionObjectType">
+                <xs:sequence>
+                    <xs:element ref="AbstractInputDeviceGroup" minOccurs="0" maxOccurs="1"></xs:element>
+                    <xs:element ref="AbstractActionObjectGroup" minOccurs="0" maxOccurs="unbounded"></xs:element>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="SendMessageType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractActionObjectType">
+                <xs:sequence>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:complexType name="AbstractActionObjectFlyToType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractActionObjectType">
+                <xs:sequence>
+                    <xs:element ref="Camera" minOccurs="0" maxOccurs="1"></xs:element>
+                    <xs:element ref="LookAt" minOccurs="0" maxOccurs="1"></xs:element>
+                    <xs:element ref="address" minOccurs="0" maxOccurs="1"></xs:element>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Message" type="MessageType"/>
+    <xs:complexType name="MessageType" final="#all">
+        <xs:sequence>
+            <xs:element ref="AbstractActionObjectGroup" minOccurs="0" maxOccurs="unbounded"></xs:element>        
+        </xs:sequence>
+        <xs:attribute name="id" type="xs:ID" use="optional"/>
+    </xs:complexType>
+   
+    <xs:element name="Identity" type="IdentityType" abstract="false" substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="IdentityType">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType">
+                <xs:sequence>
+                    <xs:element name="username" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="password" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="domain" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="AbstractExpireTimeGroup" type="AbstractExpireTime" abstract="true"
+        substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="AbstractExpireTime"> 
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="ExpireDuration" type="ExpireDurationType" abstract="false"
+    substitutionGroup="AbstractExpireTimeGroup"/>
+    <xs:complexType name="ExpireDurationType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractExpireTime">
+                <xs:attribute name="value" type="xs:double"></xs:attribute>
+                <xs:attribute name="unit" type="timeUnitEnumType"></xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="AbstractGeometryGroup" type="AbstractGeometryType" abstract="true"
+        substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="AbstractGeometryType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType"/>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="coordinates" type="coordinatesType"/>
+    <xs:simpleType name="coordinatesType">
+        <xs:list itemType="xs:string"/>
+    </xs:simpleType>
+
+    <xs:element name="altitudeModeGroup" abstract="false"/>
+    <xs:element name="altitudeMode" type="altitudeModeEnumType" default="clampToGround"
+        substitutionGroup="altitudeModeGroup"/>
+
+    <xs:element name="PointModel" type="PointModeType" substitutionGroup="AbstractGeometryGroup"/>
+    <xs:complexType name="PointModeType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractGeometryType">
+                <xs:sequence>
+                    <xs:element ref="Link"/>
+                    <xs:element ref="longitude" minOccurs="0"/>
+                    <xs:element ref="latitude" minOccurs="0"/>
+                    <xs:element ref="altitude" minOccurs="0"/>
+                    <xs:element ref="heading" minOccurs="0"/>
+                    <xs:element ref="pitch" minOccurs="0"/>
+                    <xs:element ref="roll" minOccurs="0"/>
+                    <xs:element ref="altitudeMode" minOccurs="0"/>
+                </xs:sequence>
+            </xs:extension>
+         </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Point" type="PointType" substitutionGroup="AbstractGeometryGroup"/>
+    <xs:complexType name="PointType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractGeometryType">
+                <xs:sequence>
+                    <xs:element ref="extrude" minOccurs="0" maxOccurs="1"/>
+                    <xs:element ref="altitudeMode" minOccurs="0" maxOccurs="1"/>
+                    <xs:element ref="coordinates" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="AbstractViewGroup" type="AbstractViewType" abstract="true"
+        substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="AbstractViewType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType"/>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="LookAt" type="LookAtType"
+        substitutionGroup="AbstractViewGroup"/>
+    <xs:complexType name="LookAtType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractViewType">
+                <xs:sequence>
+                    <xs:element ref="longitude" minOccurs="0"></xs:element>
+                    <xs:element ref="latitude" minOccurs="0"></xs:element>
+                    <xs:element ref="altitude" minOccurs="0"></xs:element>
+                    <xs:element ref="heading" minOccurs="0"/>
+                    <xs:element ref="pitch" minOccurs="0"/>
+                    <xs:element ref="roll" minOccurs="0"/>
+                    <xs:element ref="altitudeModeGroup" minOccurs="0"/>
+                    <xs:element ref="range" minOccurs="0"/>
+                </xs:sequence>
+                <xs:attribute ref="vref"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Camera" type="CameraType" abstract="false"
+    substitutionGroup="AbstractViewGroup"/>
+    <xs:complexType name="CameraType">
+        <xs:complexContent>
+            <xs:extension base="AbstractViewType">
+                <xs:sequence>
+                    <xs:element ref="longitude" minOccurs="0"></xs:element>
+                    <xs:element ref="latitude" minOccurs="0"></xs:element>
+                    <xs:element ref="altitude" minOccurs="0"></xs:element>
+                    <xs:element ref="heading" minOccurs="0"/>
+                    <xs:element ref="pitch" minOccurs="0"/>
+                    <xs:element ref="roll" minOccurs="0"/>
+                    <xs:element ref="altitudeModeGroup" minOccurs="0"/>
+                </xs:sequence>
+                <xs:attribute ref="vref"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="AbstractFeatureGroup" type="AbstractFeatureType" abstract="true"
+        substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="AbstractFeatureType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractObjectType">
+                <xs:sequence>
+                    <xs:element name="name" type="xs:string" minOccurs="0" maxOccurs="1"> </xs:element>
+                    <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"> </xs:element>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="AbstractWorldFeatureGroup" type="AbstractWorldFeatureType" abstract="true"
+        substitutionGroup="AbstractFeatureGroup"/>
+    <xs:complexType name="AbstractWorldFeatureType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractFeatureType"> 
+                <xs:sequence>
+                    <xs:element ref="LookAt" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="AbstractScreenFeatureGroup" type="AbstractScreenFeatureType" abstract="true"
+        substitutionGroup="AbstractFeatureGroup"/>
+    <xs:complexType name="AbstractScreenFeatureType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractFeatureType"> </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+     <xs:element name="Image" type="ImageType" substitutionGroup="AbstractFeatureGroup"/>
+    <xs:complexType name="ImageType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractWorldFeatureType">
+                <xs:sequence>
+                    <xs:element ref="filename" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="ImageGroup" type="ImageGroupType" substitutionGroup="AbstractContainerGroup"/>
+    <xs:complexType name="ImageGroupType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractContainerType">
+                <xs:sequence>
+                    <xs:element ref="Image" minOccurs="0" maxOccurs="unbounded"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="Placemark" type="PlacemarkType" substitutionGroup="AbstractWorldFeatureGroup"/>
+    <xs:complexType name="PlacemarkType" final="#all">
+        <xs:complexContent>
+            <xs:extension base="AbstractWorldFeatureType">
+                <xs:sequence>
+                    <xs:element ref="AbstractExpireTimeGroup" minOccurs="0" maxOccurs="1"/>
+                    <xs:element ref="AbstractGeometryGroup" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+
+    <xs:element name="AbstractContainerGroup" type="AbstractContainerType" abstract="true"
+        substitutionGroup="AbstractFeatureGroup"/>
+    <xs:complexType name="AbstractContainerType" abstract="true">
+        <xs:complexContent>
+            <xs:extension base="AbstractFeatureType"> </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name="Group" type="GroupType" abstract="false"
+        substitutionGroup="AbstractFeatureGroup"/>
+    <xs:complexType name="GroupType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractContainerType"> 
+                <xs:sequence>
+                    <xs:element ref="AbstractFeatureGroup" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+                <xs:attribute ref="groupType" use="optional"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    
+    <xs:element name = "Object" type="ObjectType" abstract="false" substitutionGroup="AbstractObjectGroup"/>
+    <xs:complexType name="ObjectType" abstract="false">
+        <xs:complexContent>
+            <xs:extension base="AbstractContainerType"> 
+                <xs:sequence>
+                    <xs:element ref="AbstractObjectGroup" minOccurs="0" maxOccurs="unbounded"/>
+                </xs:sequence>
+                <xs:attribute name="type" type="objectType" use="optional"/>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+</xs:schema>
+
diff --git a/ossimPlanet/src/GNUmakefile b/ossimPlanet/src/GNUmakefile
new file mode 100644
index 0000000..8d65fea
--- /dev/null
+++ b/ossimPlanet/src/GNUmakefile
@@ -0,0 +1,7 @@
+TOPDIR = ..
+include $(TOPDIR)/Make/makedefs
+include $(TOPDIR)/Make/makedirdefs
+
+DIRS = $(SRC_DIRS)
+
+include $(TOPDIR)/Make/makedirrules
diff --git a/ossimPlanet/src/ossimPlanet/GNUmakefile b/ossimPlanet/src/ossimPlanet/GNUmakefile
new file mode 100644
index 0000000..14efa34
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/GNUmakefile
@@ -0,0 +1,144 @@
+TOPDIR= ../..
+include $(TOPDIR)/Make/makedefs 
+
+CXXFILES = \
+iochannel.cpp \
+mkUtils.cpp\
+netBuffer.cpp\
+netChannel.cpp\
+netChat.cpp\
+netMessage.cpp\
+netMonitor.cpp\
+netSocket.cpp\
+ossimPlanet.cpp\
+ossimPlanetAction.cpp\
+ossimPlanetActionReceiver.cpp\
+ossimPlanetActionRouter.cpp\
+ossimPlanetAnimationPath.cpp \
+ossimPlanetAnimatedPointModel.cpp \
+ossimPlanetAnnotationLayer.cpp\
+ossimPlanetAnnotationLayerNode.cpp\
+ossimPlanetApi.cpp\
+ossimPlanetArchive.cpp\
+ossimPlanetArchiveMapping.cpp\
+ossimPlanetBillboardIcon.cpp\
+ossimPlanetBoundingBox.cpp \
+ossimPlanetCache.cpp \
+ossimPlanetCacheTextureLayer.cpp \
+ossimPlanetClientThread.cpp \
+ossimPlanetCloudLayer.cpp \
+ossimPlanetCompass.cpp \
+ossimPlanetCubeGrid.cpp \
+ossimPlanetDatabasePager.cpp \
+ossimPlanetDestinationCommandAction.cpp \
+ossimPlanetDtedElevationDatabase.cpp \
+ossimPlanetElevationDatabase.cpp \
+ossimPlanetElevationDatabaseGroup.cpp \
+ossimPlanetElevationGrid.cpp \
+ossimPlanetElevationFactory.cpp \
+ossimPlanetElevationRegistry.cpp \
+ossimPlanetEphemeris.cpp \
+ossimPlanetFadeText.cpp \
+ossimPlanetGeneralRasterElevationDatabase.cpp \
+ossimPlanetGeocoder.cpp \
+ossimPlanetGridUtility.cpp \
+ossimPlanetGrid.cpp \
+ossimPlanetIconGeom.cpp \
+ossimPlanetId.cpp \
+ossimPlanetIdManager.cpp \
+ossimPlanetImage.cpp \
+ossimPlanetInteractionController.cpp \
+ossimPlanetIoRoutableMessageHandler.cpp \
+ossimPlanetIoSocket.cpp \
+ossimPlanetIoSocketServerChannel.cpp \
+ossimPlanetIoThread.cpp \
+ossimPlanetJpegImage.cpp \
+ossimPlanetKml.cpp \
+ossimPlanetKmlLayer.cpp \
+ossimPlanetKmlLayerNode.cpp \
+ossimPlanetKmlNetworkLinkNode.cpp \
+ossimPlanetKmlPlacemarkNode.cpp \
+ossimPlanetKmlScreenOverlayNode.cpp \
+ossimPlanetLabelGeom.cpp \
+ossimPlanetLand.cpp \
+ossimPlanetLandCache.cpp \
+ossimPlanetLandCullCallback.cpp \
+ossimPlanetLandReaderWriter.cpp \
+ossimPlanetLatLonHud.cpp \
+ossimPlanetLayer.cpp \
+ossimPlanetLayerFactory.cpp \
+ossimPlanetLayerRegistry.cpp \
+ossimPlanetLookAt.cpp \
+ossimPlanetLsrSpaceTransform.cpp \
+ossimPlanetManipulator.cpp \
+ossimPlanetNavigator.cpp \
+ossimPlanetNode.cpp \
+ossimPlanetNodeFactory.cpp \
+ossimPlanetNodeRegistry.cpp \
+ossimPlanetOperation.cpp \
+ossimPlanetOssimElevationDatabase.cpp \
+ossimPlanetOssimImage.cpp \
+ossimPlanetOssimImageLayer.cpp \
+ossimPlanetPagedLandLod.cpp \
+ossimPlanetPlaneGrid.cpp \
+ossimPlanetPointModel.cpp \
+ossimPlanetViewer.cpp\
+ossimPlanetSceneView.cpp \
+ossimPlanetServerThread.cpp \
+ossimPlanetShaderProgramSetup.cpp \
+ossimPlanetSocketNetworkConnection.cpp \
+ossimPlanetSousaLayer.cpp \
+ossimPlanetSrtmElevationDatabase.cpp \
+ossimPlanetStandardTextureLayerFactory.cpp \
+ossimPlanetTerrain.cpp \
+ossimPlanetTerrainGeometryTechnique.cpp \
+ossimPlanetTerrainLayer.cpp \
+ossimPlanetTerrainTechnique.cpp \
+ossimPlanetTerrainTile.cpp \
+ossimPlanetTexture2D.cpp \
+ossimPlanetTextureLayer.cpp \
+ossimPlanetTextureLayerGroup.cpp \
+ossimPlanetTextureLayerRegistry.cpp \
+ossimPlanetThread.cpp \
+ossimPlanetThreadImp.cpp \
+ossimPlanetThreadPool.cpp \
+ossimPlanetTileRequest.cpp \
+ossimPlanetUtility.cpp \
+ossimPlanetVideoLayer.cpp \
+ossimPlanetViewMatrixBuilder.cpp \
+ossimPlanetVisitors.cpp \
+ossimPlanetWmsClient.cpp \
+ossimPlanetWmsImageLayer.cpp \
+ossimPlanetXmlAction.cpp \
+ossimPlanetYahooGeocoder.cpp \
+sg_file.cpp \
+sg_socket.cpp \
+sg_socket_udp.cpp \
+ul.cpp \
+ulClock.cpp \
+ulError.cpp \
+ulLinkedList.cpp \
+ulList.cpp \
+ulRTTI.cpp
+ 
+CFILES = \
+ioapi.c \
+unzip.c \
+zip.c
+
+ifneq ("$(OSSIMPLANET_ENABLE_PREDATOR)", "no")
+CXXFILES+=ossimPlanetPredatorVideoLayerNode.cpp
+endif
+
+ifeq ($(OS),MINGW)
+CFILES += iowin32.c
+endif
+
+DEF     += -DOSSIMPLANET_LIBRARY
+
+LIBS    +=  $(OSG_LIBS) $(OSSIM_LIBS) $(OTHER_LIBS)
+
+TARGET_BASENAME = ossimPlanet
+LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT)
+
+include $(TOPDIR)/Make/makerules 
diff --git a/ossimPlanet/src/ossimPlanet/crypt.h b/ossimPlanet/src/ossimPlanet/crypt.h
new file mode 100644
index 0000000..622f4bc
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/crypt.h
@@ -0,0 +1,132 @@
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This code is a modified version of crypting code in Infozip distribution
+
+   The encryption/decryption parts of this source code (as opposed to the
+   non-echoing password parts) were originally written in Europe.  The
+   whole source package can be freely distributed, including from the USA.
+   (Prior to January 2000, re-export from the US was a violation of US law.)
+
+   This encryption code is a direct transcription of the algorithm from
+   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+   file (appnote.txt) is distributed with the PKZIP program (even in the
+   version without encryption capabilities).
+
+   If you don't need crypting in your application, just define symbols
+   NOCRYPT and NOUNCRYPT.
+
+   This code support the "Traditional PKWARE Encryption".
+
+   The new AES encryption added on Zip format by Winzip (see the page
+   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+   Encryption is not supported.
+*/
+
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
+{
+    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
+                     * unpredictable manner on 16-bit systems; not a problem
+                     * with any known compiler so far, though */
+
+    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
+{
+    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+    {
+      register int keyshift = (int)((*(pkeys+1)) >> 24);
+      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+    }
+    return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
+{
+    *(pkeys+0) = 305419896L;
+    *(pkeys+1) = 591751049L;
+    *(pkeys+2) = 878082192L;
+    while (*passwd != '\0') {
+        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+        passwd++;
+    }
+}
+
+#define zdecode(pkeys,pcrc_32_tab,c) \
+    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+
+#define RAND_HEAD_LEN  12
+   /* "last resort" source for second part of crypt seed pattern */
+#  ifndef ZCR_SEED2
+#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
+#  endif
+
+static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
+    const char *passwd;         /* password string */
+    unsigned char *buf;         /* where to write header */
+    int bufSize;
+    unsigned long* pkeys;
+    const unsigned long* pcrc_32_tab;
+    unsigned long crcForCrypting;
+{
+    int n;                       /* index in random header */
+    int t;                       /* temporary */
+    int c;                       /* random byte */
+    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+    static unsigned calls = 0;   /* ensure different random header each time */
+
+    if (bufSize<RAND_HEAD_LEN)
+      return 0;
+
+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+     * output of rand() to get less predictability, since rand() is
+     * often poorly implemented.
+     */
+    if (++calls == 1)
+    {
+        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+    }
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        c = (rand() >> 7) & 0xff;
+        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+    }
+    /* Encrypt random header (last two bytes is high word of crc) */
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+    }
+    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+    return n;
+}
+
+#endif
diff --git a/ossimPlanet/src/ossimPlanet/ioapi.c b/ossimPlanet/src/ossimPlanet/ioapi.c
new file mode 100644
index 0000000..9626796
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ioapi.c
@@ -0,0 +1,177 @@
+/* ioapi.c -- IO base function header for compress/uncompress .zip
+   files using zlib + zip or unzip API
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "zlib.h"
+#include <ossimPlanet/ioapi.h>
+
+
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+voidpf ZCALLBACK fopen_file_func OF((
+   voidpf opaque,
+   const char* filename,
+   int mode));
+
+uLong ZCALLBACK fread_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   void* buf,
+   uLong size));
+
+uLong ZCALLBACK fwrite_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   const void* buf,
+   uLong size));
+
+long ZCALLBACK ftell_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+long ZCALLBACK fseek_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   uLong offset,
+   int origin));
+
+int ZCALLBACK fclose_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+int ZCALLBACK ferror_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+
+voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
+   voidpf opaque;
+   const char* filename;
+   int mode;
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen(filename, mode_fopen);
+    return file;
+}
+
+
+uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   void* buf;
+   uLong size;
+{
+    uLong ret;
+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+
+uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   const void* buf;
+   uLong size;
+{
+    uLong ret;
+    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+long ZCALLBACK ftell_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    long ret;
+    ret = ftell((FILE *)stream);
+    return ret;
+}
+
+long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
+   voidpf opaque;
+   voidpf stream;
+   uLong offset;
+   int origin;
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+    fseek((FILE *)stream, offset, fseek_origin);
+    return ret;
+}
+
+int ZCALLBACK fclose_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret;
+    ret = fclose((FILE *)stream);
+    return ret;
+}
+
+int ZCALLBACK ferror_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret;
+    ret = ferror((FILE *)stream);
+    return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = fopen_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell_file = ftell_file_func;
+    pzlib_filefunc_def->zseek_file = fseek_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/ossimPlanet/src/ossimPlanet/iochannel.cpp b/ossimPlanet/src/ossimPlanet/iochannel.cpp
new file mode 100644
index 0000000..7bd7796
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/iochannel.cpp
@@ -0,0 +1,84 @@
+// iochannel.cxx -- High level IO channel class
+//
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: iochannel.cpp 11616 2007-08-15 18:23:33Z gpotts $
+
+
+#include <ossimPlanet/iochannel.h>
+
+
+// constructor
+SGIOChannel::SGIOChannel()
+   :theReadlineDelimiter('\n')
+{
+}
+
+
+// destructor
+SGIOChannel::~SGIOChannel()
+{
+}
+
+
+// dummy configure routine
+bool SGIOChannel::open( const SGProtocolDir /*d*/ ) {
+    return false;
+}
+
+
+// dummy process routine
+int SGIOChannel::read( char * /*buf*/, int /*length*/ ) {
+    return 0;
+}
+
+
+// dummy process routine
+int SGIOChannel::readline( char * /*buf*/, int /*length*/ ) {
+    return 0;
+}
+
+void SGIOChannel::setReadlineDelimiter(char delimiter)
+{
+   theReadlineDelimiter = delimiter;
+}
+
+
+// dummy process routine
+int SGIOChannel::write( const char * /*buf*/, const int /*length*/ ) {
+    return false;
+}
+
+
+// dummy process routine
+int SGIOChannel::writestring( const char * /*str*/ ) {
+    return false;
+}
+
+
+// dummy close routine
+bool SGIOChannel::close() {
+    return false;
+}
+
+
+// dummy eof routine
+bool SGIOChannel::eof() {
+    return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/iowin32.c b/ossimPlanet/src/ossimPlanet/iowin32.c
new file mode 100644
index 0000000..ab153e8
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/iowin32.c
@@ -0,0 +1,270 @@
+/* iowin32.c -- IO base function header for compress/uncompress .zip
+   files using zlib + zip or unzip API
+   This IO API version uses the Win32 API (for Microsoft Windows)
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+*/
+
+#include <stdlib.h>
+
+#include "zlib.h"
+#include <ossimPlanet/ioapi.h>
+#include <ossimPlanet/iowin32.h>
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+voidpf ZCALLBACK win32_open_file_func OF((
+   voidpf opaque,
+   const char* filename,
+   int mode));
+
+uLong ZCALLBACK win32_read_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   void* buf,
+   uLong size));
+
+uLong ZCALLBACK win32_write_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   const void* buf,
+   uLong size));
+
+long ZCALLBACK win32_tell_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+long ZCALLBACK win32_seek_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   uLong offset,
+   int origin));
+
+int ZCALLBACK win32_close_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+int ZCALLBACK win32_error_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+typedef struct
+{
+    HANDLE hf;
+    int error;
+} WIN32FILE_IOWIN;
+
+voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
+   voidpf opaque;
+   const char* filename;
+   int mode;
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = 0;
+    voidpf ret=NULL;
+
+    dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
+
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+    {
+        dwDesiredAccess = GENERIC_READ;
+        dwCreationDisposition = OPEN_EXISTING;
+        dwShareMode = FILE_SHARE_READ;
+    }
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+    {
+        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        dwCreationDisposition = OPEN_EXISTING;
+    }
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+    {
+        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        dwCreationDisposition = CREATE_ALWAYS;
+    }
+
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
+                      dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+    if (hFile == INVALID_HANDLE_VALUE)
+        hFile = NULL;
+
+    if (hFile != NULL)
+    {
+        WIN32FILE_IOWIN w32fiow;
+        w32fiow.hf = hFile;
+        w32fiow.error = 0;
+        ret = malloc(sizeof(WIN32FILE_IOWIN));
+        if (ret==NULL)
+            CloseHandle(hFile);
+        else *((WIN32FILE_IOWIN*)ret) = w32fiow;
+    }
+    return ret;
+}
+
+
+uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   void* buf;
+   uLong size;
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    if (hFile != NULL)
+        if (!ReadFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+
+    return ret;
+}
+
+
+uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   const void* buf;
+   uLong size;
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+    if (hFile !=NULL)
+        if (!WriteFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+
+    return ret;
+}
+
+long ZCALLBACK win32_tell_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    long ret=-1;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    if (hFile != NULL)
+    {
+        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
+        if (dwSet == INVALID_SET_FILE_POINTER)
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=(long)dwSet;
+    }
+    return ret;
+}
+
+long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
+   voidpf opaque;
+   voidpf stream;
+   uLong offset;
+   int origin;
+{
+    DWORD dwMoveMethod=0xFFFFFFFF;
+    HANDLE hFile = NULL;
+
+    long ret=-1;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        dwMoveMethod = FILE_CURRENT;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        dwMoveMethod = FILE_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        dwMoveMethod = FILE_BEGIN;
+        break;
+    default: return -1;
+    }
+
+    if (hFile != NULL)
+    {
+        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
+        if (dwSet == INVALID_SET_FILE_POINTER)
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=0;
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_close_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret=-1;
+
+    if (stream!=NULL)
+    {
+        HANDLE hFile;
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+        if (hFile != NULL)
+        {
+            CloseHandle(hFile);
+            ret=0;
+        }
+        free(stream);
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_error_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret=-1;
+    if (stream!=NULL)
+    {
+        ret = ((WIN32FILE_IOWIN*)stream) -> error;
+    }
+    return ret;
+}
+
+void fill_win32_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = win32_open_file_func;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
+    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque=NULL;
+}
diff --git a/ossimPlanet/src/ossimPlanet/mkUtils.cpp b/ossimPlanet/src/ossimPlanet/mkUtils.cpp
new file mode 100644
index 0000000..c0c92eb
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/mkUtils.cpp
@@ -0,0 +1,471 @@
+#include <ossimPlanet/mkUtils.h>
+#include <ossim/base/ossimCommon.h>
+#include <osgDB/ReaderWriter>
+#include <osgDB/Registry>
+#include <ossim/base/ossimString.h>
+#include <ossim/base/ossimCommon.h>
+#include <iostream>
+#include <stack>
+
+std::istream& mkUtils::planetSkipws(std::istream& in)
+{
+   int c = in.peek();
+   while(!in.fail()&&
+         ((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n')||
+         (c == '\r')))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+bool mkUtils::writeOsgObjectToStream(std::ostream& out, const osg::Object* node, const std::string& extension)
+{
+    osg::ref_ptr<osgDB::ReaderWriter> writer = osgDB::Registry::instance()->getReaderWriterForExtension(extension);
+    return writer.valid() ? writer->writeObject(*node, out).success() : false;
+}
+
+bool mkUtils::isDouble(const std::string& s)
+{
+    char* end;
+    const char* start = s.c_str();
+    strtod(start, &end);
+    return start != end;
+}
+
+bool mkUtils::isInt(const std::string& s)
+{
+    char* end;
+    const char* start = s.c_str();
+    strtoul(start, &end, 0);
+    return start != end;
+}
+
+double mkUtils::asDouble(const std::string& s)
+{
+    char* end;
+    const char* start = s.c_str();
+    double x = strtod(start, &end);
+    return (start != end) ? x : ossim::nan();
+}
+
+bool mkUtils::hasSuffix(const std::string& s, const std::string& suffix)
+{
+    std::string::size_type sSize = s.size();
+    std::string::size_type suffixSize = suffix.size();
+    return (suffixSize <= sSize) ? suffix == s.substr(sSize - suffixSize, suffixSize) : false;
+}
+
+ossim_int64 mkUtils::factorial(int n)
+{
+    // only factorials for small n can fit in int64 so just use a 168 byte lookup table.
+    
+    const int tableLength = 21;
+    if((n < 0) || (n > tableLength)) return 0;
+//     assert(n >= 0 && n < tableLength);
+    
+    static const ossim_int64 table[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 
+        39916800, 479001600, 6227020800LL, 87178291200LL, 1307674368000LL, 20922789888000LL, 
+        355687428096000LL, 6402373705728000LL, 121645100408832000LL, 2432902008176640000LL };
+    // XXX add this back in later:  static_check(tableLength == sizeof(table)/sizeof(table[0]), tableLength_must_equal_actual_table_length);
+
+    return table[n];
+}
+
+void mkUtils::lexBraceQuotedTokens(const std::string& str, unsigned int startIdx, const char* whitespace, std::vector<std::string>* tokens, bool* unbalancedBraces)
+{
+   ossim::lexQuotedTokens(str, startIdx, whitespace, "{}", *tokens, *unbalancedBraces);
+#if 0
+   if(!whitespace||!tokens||!unbalancedBraces) return;
+//     assert(whitespace != NULL);
+//     assert(tokens != NULL);
+//     assert(unbalancedBraces != NULL);
+    
+    const char openQuote('{'), closeQuote('}');
+    
+    tokens->clear();
+    *unbalancedBraces = false;
+    
+    unsigned int endIdx;
+    while (startIdx < str.length())
+    {
+	if (str[startIdx] == openQuote)
+        {
+            int openBraceCount = 1;
+            
+            if (startIdx+1 < str.length())
+            {
+                startIdx++;
+                if (str[startIdx] != closeQuote)
+                {
+                    endIdx = startIdx+1;
+                    while (endIdx < str.length() && openBraceCount > 0)
+                    {
+                        if (str[endIdx] == openQuote)
+                            openBraceCount++;
+                        else if (str[endIdx] == closeQuote)
+                            openBraceCount--;
+                        endIdx++;
+                    }
+                }
+                else
+                {
+                    openBraceCount = 0;
+                    startIdx++;
+                    endIdx = startIdx+1;
+                }
+            }
+            
+            if (openBraceCount == 0)
+            {
+                tokens->push_back(str.substr(startIdx, endIdx-1-startIdx));
+            }
+            else
+            {
+                *unbalancedBraces = true;
+                endIdx = str.length();
+            }
+            
+	}
+        else if (str[startIdx] == closeQuote)
+        {
+            *unbalancedBraces = true;
+            endIdx = str.length();
+            
+	}
+        else
+        {
+            endIdx = str.find_first_of(whitespace, startIdx);
+            tokens->push_back(str.substr(startIdx, endIdx-startIdx));
+	}
+	
+	startIdx = str.find_first_not_of(whitespace, endIdx);
+    }
+#endif
+}
+
+void mkUtils::hprToQuat(osg::Quat& quat, const osg::Vec3d& hpr)
+{
+//   const double yaw(osg::DegreesToRadians(hpr[1]));
+//   const double pitch(osg::DegreesToRadians(hpr[2]));
+//   const double roll(osg::DegreesToRadians(-hpr[0]));
+   const double yaw(osg::DegreesToRadians(-hpr[0]));
+   const double pitch(osg::DegreesToRadians(hpr[1]));
+   const double roll(osg::DegreesToRadians(hpr[2]));
+   const double cy ( cos ( yaw * 0.5 ) );
+   const double cp ( cos ( pitch * 0.5 ) );
+   const double cr ( cos ( roll * 0.5 ) );
+   const double sy ( sin ( yaw * 0.5 ) );
+   const double sp ( sin ( pitch * 0.5 ) );
+   const double sr ( sin ( roll * 0.5 ) );
+   
+   const double qw ( cy*cp*cr + sy*sp*sr );
+   const double qx ( sy*cp*cr - cy*sp*sr );
+   const double qy ( cy*sp*cr + sy*cp*sr );
+   const double qz ( cy*cp*sr - sy*sp*cr );
+   
+   quat.set ( qx, qy, qz, qw );
+}
+
+void mkUtils::quatToHpr(osg::Vec3d& hpr, const osg::Quat& quat)
+{
+   // From the reference material the h p r is about
+   // Y, Z, and X
+   // our LSR axiz says Z, X, Y
+   const double q0 ( quat[3] );
+   const double q1 ( quat[0] );
+   const double q2 ( quat[1] );
+   const double q3 ( quat[2] );
+   const double sqx(q1*q1);
+   const double sqy(q2*q2);
+   const double sqz(q3*q3);
+   const double sqw(q0*q0);
+   
+   double h = atan2(2.0 * (q1*q2 + q3*q0),(sqx - sqy - sqz + sqw));
+   double p = atan2(2.0 * (q2*q3 + q1*q0),(-sqx - sqy + sqz + sqw));
+   double r = asin(-2.0 * (q1*q3 - q2*q0)/(sqx + sqy + sqz + sqw));
+//   const double h(atan2 ( 2 * (q2*q3 + q0*q1), (q0*q0 - q1*q1 - q2*q2 + q3*q3)));
+//   double p(asin ( -2 * (q1*q3 - q0*q2)));
+//   double r(atan2 ( 2 * (q1*q2 + q0*q3), (q0*q0 + q1*q1 - q2*q2 - q3*q3)));
+   //   hpr = osg::Vec3d(osg::RadiansToDegrees(-r),
+   //                    osg::RadiansToDegrees(h),
+   //                    osg::RadiansToDegrees(p));
+      hpr = osg::Vec3d(osg::RadiansToDegrees(-h),
+                       osg::RadiansToDegrees(p),
+                       osg::RadiansToDegrees(r));
+}
+
+bool mkUtils::matrixToHpr( osg::Vec3d& hpr, 
+                          const osg::Matrixd& rotation )
+{
+//   std::cout << "HEADING = " << ossim::radiansToDegrees(atan(rotation(0,1)/rotation(0,0))) << std::endl;
+//   std::cout << "PITCH   = " << ossim::radiansToDegrees(asin(-rotation(0,2))) << std::endl;
+//   std::cout << "ROLL    = " << ossim::radiansToDegrees(atan(rotation(1,2)/rotation(2,2))) << std::endl;
+   
+   osg::Quat q;
+   
+   q.set(rotation);
+   
+   quatToHpr(hpr, q);
+
+   return true;
+}
+
+bool mkUtils::matrixToHpr( osg::Vec3d& hpr,
+                           const osg::Matrixd& lsrMatrix,
+                           const osg::Matrixd& rotationalMatrix)
+{
+   bool result = false;
+   osg::Matrixd invertLsr;
+    
+    hpr[0] = 0.0;
+    hpr[1] = 0.0;
+    hpr[2] = 0.0;
+   osg::Matrixd m(lsrMatrix(0,0), lsrMatrix(0, 1), lsrMatrix(0,2), 0.0,
+                  lsrMatrix(1,0), lsrMatrix(1, 1), lsrMatrix(1,2), 0.0,
+                  lsrMatrix(2,0), lsrMatrix(2, 1), lsrMatrix(2,2), 0.0,
+                  0.0,0.0,0.0, 1.0);
+    if(invertLsr.invert(m))
+    {
+        result = matrixToHpr(hpr, rotationalMatrix*invertLsr);
+        if(std::abs(hpr[0]) < FLT_EPSILON)
+        {
+            hpr[0] = 0.0;
+        }
+        if(std::abs(hpr[1]) < FLT_EPSILON)
+        {
+            hpr[1] = 0.0;
+        }
+        if(std::abs(hpr[2]) < FLT_EPSILON)
+        {
+            hpr[2] = 0.0;
+        }
+    }
+    return result;
+}
+
+bool mkUtils::extractObjectAndArg(std::string& resultObject,
+                                  std::string& resultArg,
+                                  const std::string& inputValue,
+                                  const char quotes[2])
+{
+   const char openQuote(quotes[0]), closeQuote(quotes[1]);
+   std::vector<std::string> tokens;
+   bool unbalancedQuotes=false;
+   ossim_uint32 end = 1;
+   ossim_uint32 start=0;
+   ossim_uint32 totalOpenQuoteCount = 0;
+   const char* whitespace = " \t\n\r";
+   // while (start < inputValue.length() && start >= 0)
+   start = inputValue.find_first_not_of(whitespace, start);
+   end = start + 1;
+   if(inputValue[start] != openQuote)
+   {
+      while (start < inputValue.length())      
+      {
+         if (inputValue[start] == openQuote)
+         {
+            int openBraceCount = 1;
+            ++totalOpenQuoteCount;
+            if (start+1 < inputValue.length())
+            {
+               ++start;
+               // skip white space since this is the object portion and need te start of the first character
+               //
+               start = inputValue.find_first_not_of(whitespace, start);
+               if (inputValue[start] != closeQuote)
+               {
+                  end = start+1;
+                  while (static_cast<ossim_uint32>(end) < inputValue.length() &&
+                         openBraceCount > 0)
+                  {
+                     if (inputValue[end] == openQuote)
+                     {
+                        openBraceCount++;
+                        ++totalOpenQuoteCount;
+                     }
+                     else if (inputValue[end] == closeQuote)
+                        openBraceCount--;
+                     end++;
+                  }
+               }
+               else
+               {
+                  openBraceCount = 0;
+                  start++;
+                  end = start+1;
+               }
+            }
+            
+            if (openBraceCount == 0)
+            {
+               tokens.push_back(inputValue.substr(start, end-1-start));
+            }
+            else
+            {
+               unbalancedQuotes = true;
+               end = inputValue.length();
+            }
+            
+         }
+         else if (inputValue[start] == closeQuote)
+         {
+            unbalancedQuotes = true;
+            end = inputValue.length();
+            
+         }
+         else
+         {
+            end = inputValue.find_first_of(whitespace, start);
+            tokens.push_back(inputValue.substr(start, end-start));
+         }
+         
+         start = inputValue.find_first_not_of(whitespace, end);
+      }
+   }
+   else
+   {
+      end = inputValue.find_first_of(whitespace, start);
+      tokens.push_back(inputValue.substr(start, end-start));
+      tokens.push_back(inputValue.substr(end, inputValue.size()));
+   }
+   if(unbalancedQuotes) return false;
+   if(tokens.size() < 2) return false;
+   bool requoteArg = totalOpenQuoteCount >0;
+   resultObject = tokens[0];
+   resultArg = "";
+   ossim_uint32 maxSize = tokens.size()-1;
+   ossim_uint32 idx = 0;
+   for(idx =1; idx < maxSize; ++idx)
+   {
+      if(requoteArg)
+      {
+         resultArg    += (quotes[0] + tokens[idx]+quotes[1]);
+      }
+      else
+      {
+         resultArg    += tokens[idx];
+      }
+      resultArg += " ";
+   }
+   if(requoteArg)
+   {
+      resultArg    += (quotes[0] + tokens[idx]+quotes[1]);
+   }
+   else
+   {
+      resultArg    += tokens[idx];
+   }
+   
+   return true;
+}
+
+ossimRefPtr<ossimXmlNode> mkUtils::newNodeFromObjectMessageRoute(const ossimString& v,
+                                                                 const char quotes[2])
+{
+   std::istringstream in(v);
+   const char openQuote = quotes[0];
+   const char closeQuote = quotes[1];
+   std::stack<ossimRefPtr<ossimXmlNode> > xmlStack;
+   ossimRefPtr<ossimXmlNode> current;
+   in >> mkUtils::planetSkipws;
+   if(!in.good()) return current;
+   current = new ossimXmlNode;
+   xmlStack.push(current.get());
+   
+   if(in.peek() == openQuote)
+   {
+      in.ignore();
+   }
+   ossimString name;
+   ossimString value;
+   while(in.good()&&!xmlStack.empty())
+   {
+      in>>mkUtils::planetSkipws;
+      if(in.peek() == openQuote)
+      {
+         // create a new xml node
+         // add it to current and skip white space to parse out the name
+         //
+         ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+         name = "";
+         value = "";
+         current->addChildNode(node.get());
+         xmlStack.push(node.get());
+         current = node;
+         in.ignore();
+      }
+      else if(in.peek() == closeQuote)
+      {
+         xmlStack.pop();
+         if(xmlStack.size() > 0)
+         {
+            current = xmlStack.top();
+         }
+         in.ignore();
+      }
+      else
+      {
+         if(name.empty())
+         {
+            // read object name
+            //
+            while(in.good()&&(in.peek()!=' ')&&(in.peek()!=openQuote)&&(in.peek()!=closeQuote))
+            {
+               name += (char)in.get();
+            }
+            // on last pop there is a possibility that the name will be parsed to empty so don't overwrite.
+            // we are basically done at this point and the main loop should kick out
+            //
+            if(!name.empty())
+            {
+               current->setTag(name);
+            }
+         }
+         else if(value.empty())
+         {
+            while(in.good()&&(in.peek()!=closeQuote))
+            {
+               value += (char)in.get();
+            }
+            current->setText(value);
+            // reset name and value;
+            name  = "";
+            value = "";
+         }
+      }
+   }
+   // check for error
+   //
+   if(!in.good())
+   {
+      if(xmlStack.size() != 1)
+      {
+         current = 0;
+      }
+   }
+
+   return current;
+}
+
+ossimRefPtr<ossimXmlNode> mkUtils::newNodeFromObjectMessageRoute(const ossimString& receiverPath,
+                                                                 const ossimString& command,
+                                                                 const ossimString& v,
+                                                                 const char quotes[2])
+{
+   ossimRefPtr<ossimXmlNode> objectDefinition = newNodeFromObjectMessageRoute(v, quotes);
+   ossimRefPtr<ossimXmlNode> result;
+   if(objectDefinition.valid())
+   {
+      result = new ossimXmlNode;
+      result->setTag("Message");
+      result->addAttribute("receiver", receiverPath);
+      result->addAttribute("command", receiverPath);
+      
+   }
+   return result.get();
+}
diff --git a/ossimPlanet/src/ossimPlanet/netBuffer.cpp b/ossimPlanet/src/ossimPlanet/netBuffer.cpp
new file mode 100644
index 0000000..0885939
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netBuffer.cpp
@@ -0,0 +1,69 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netBuffer.cxx 1568 2002-09-02 06:05:49Z sjbaker $
+*/
+
+#include <ossimPlanet/netBuffer.h>
+
+void
+netBufferChannel::handleRead (void)
+{
+  int max_read = in_buffer.getMaxLength() - in_buffer.getLength() ;
+  if (max_read)
+  {
+    char* data = in_buffer.getData() + in_buffer.getLength() ;
+    int num_read = recv (data, max_read) ;
+    if (num_read > 0)
+    {
+      in_buffer.append (num_read) ;
+      //ulSetError ( UL_DEBUG, "netBufferChannel: %d read", num_read ) ;
+    }
+  }
+  if (in_buffer.getLength())
+  {
+    handleBufferRead (in_buffer);
+  }
+}
+
+void
+netBufferChannel::handleWrite (void)
+{
+  if (out_buffer.getLength())
+  {
+    if (isConnected())
+    {
+      int length = out_buffer.getLength() ;
+      if (length>512)
+        length=512;
+      int num_sent = netChannel::send (
+        out_buffer.getData(), length);
+      if (num_sent > 0)
+      {
+        out_buffer.remove (0, num_sent);
+        //ulSetError ( UL_DEBUG, "netBufferChannel: %d sent", num_sent ) ;
+      }
+    }
+  }
+  else if (should_close)
+  {
+    close();
+  }
+}
diff --git a/ossimPlanet/src/ossimPlanet/netChannel.cpp b/ossimPlanet/src/ossimPlanet/netChannel.cpp
new file mode 100644
index 0000000..677965b
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netChannel.cpp
@@ -0,0 +1,279 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netChannel.cxx 1906 2004-03-22 19:44:50Z sjbaker $
+*/
+
+// TODO:
+// have all socket-related functions assert that the socket has not
+// been closed.  [a read event may close it, and a write event may try
+// to write or something...]
+// Maybe assert valid handle, too?
+
+#include <ossimPlanet/netChannel.h>
+
+static netChannel* channels = 0 ;
+
+netChannel::netChannel ()
+{
+  closed = true ;
+  connected = false ;
+  accepting = false ;
+  write_blocked = false ;
+  should_delete = false ;
+
+  next_channel = channels ;
+  channels = this ;
+}
+  
+netChannel::~netChannel ()
+{
+  close();
+
+  netChannel* prev = NULL ;
+
+  for ( netChannel* ch = channels; ch != NULL;
+                    ch = ch -> next_channel )
+  {
+    if (ch == this)
+    {
+      ch = ch -> next_channel ;
+      if ( prev != NULL )
+        prev -> next_channel = ch ;
+      else
+        channels = ch ;
+      next_channel = 0 ;
+      break;
+    }
+    prev = ch ;
+  }
+}
+  
+void
+netChannel::setHandle (int handle, bool is_connected)
+{
+  close () ;
+  netSocket::setHandle ( handle ) ;
+  connected = is_connected ;
+  //if ( connected ) this->handleConnect();
+  closed = false ;
+}
+
+bool
+netChannel::open (bool streamFlag)
+{
+  close();
+  if (netSocket::open(streamFlag)) {
+    closed = false ;
+    setBlocking ( false ) ;
+    return true ;
+  }
+  return false ;
+}
+
+int
+netChannel::listen ( int backlog )
+{
+  accepting = true ;
+  return netSocket::listen ( backlog ) ;
+}
+
+int
+netChannel::connect ( const char* host, int port )
+{
+  int result = netSocket::connect ( host, port ) ;
+  if (result == 0) {
+    connected = true ;
+    //this->handleConnect();
+    return 0;
+  } else if (isNonBlockingError ()) {
+    return 0;
+  } else {
+    // some other error condition
+    this->handleError (result);
+    close();
+    return -1;
+  }
+}
+
+int
+netChannel::send (const void * buffer, int size, int flags)
+{
+  int result = netSocket::send (buffer, size, flags);
+  
+  if (result == (int)size) {
+    // everything was sent
+    write_blocked = false ;
+    return result;
+  } else if (result >= 0) {
+    // not all of it was sent, but no error
+    write_blocked = true ;
+    return result;
+  } else if (isNonBlockingError ()) {
+    write_blocked = true ;
+    return 0;
+  } else {
+    this->handleError (result);
+    close();
+    return -1;
+  }
+  
+}
+
+int
+netChannel::recv (void * buffer, int size, int flags)
+{
+  int result = netSocket::recv (buffer, size, flags);
+  
+  if (result > 0) {
+    return result;
+  } else if (result == 0) {
+    close();
+    return 0;
+  } else if (isNonBlockingError ()) {
+    return 0;
+  } else {
+    this->handleError (result);
+    close();
+    return -1;
+  }
+}
+
+void
+netChannel::close (void)
+{
+  if ( !closed )
+  {
+    this->handleClose();
+  
+    closed = true ;
+    connected = false ;
+    accepting = false ;
+    write_blocked = false ;
+  }
+
+  netSocket::close () ;
+}
+
+void
+netChannel::handleReadEvent (void)
+{
+  if (accepting) {
+    if (!connected) {
+      connected = true ;
+      //this->handleConnect();
+    }
+    this->handleAccept();
+  } else if (!connected) {
+    connected = true ;
+    //this->handleConnect();
+    this->handleRead();
+  } else {
+    this->handleRead();
+  }
+}
+
+void
+netChannel::handleWriteEvent (void)
+{
+  if (!connected) {
+    connected = true ;
+    //this->handleConnect();
+  }
+  write_blocked = false ;
+  this->handleWrite();
+}
+
+bool
+netChannel::poll (unsigned int timeout)
+{
+  if (!channels)
+    return false ;
+  
+  enum { MAX_SOCKETS = 256 } ;
+  netSocket* reads [ MAX_SOCKETS+1 ] ;
+  netSocket* writes [ MAX_SOCKETS+1 ] ;
+  netSocket* deletes [ MAX_SOCKETS+1 ] ;
+  int nreads = 0 ;
+  int nwrites = 0 ;
+  int ndeletes = 0 ;
+  int nopen = 0 ;
+  netChannel* ch;
+  for (  ch = channels; ch != NULL; ch = ch -> next_channel )
+  {
+    if ( ch -> should_delete )
+    {
+      assert(ndeletes<MAX_SOCKETS);
+      deletes[ndeletes++] = ch ;
+    }
+    else if ( ! ch -> closed )
+    {
+      nopen++ ;
+      if (ch -> readable()) {
+        assert(nreads<MAX_SOCKETS);
+        reads[nreads++] = ch ;
+      }
+      if (ch -> writable()) {
+        assert(nwrites<MAX_SOCKETS);
+        writes[nwrites++] = ch ;
+      }
+    }
+  }
+  reads[nreads] = NULL ;
+  writes[nwrites] = NULL ;
+  deletes[ndeletes] = NULL ;
+
+  int i ;
+  for ( i=0; deletes[i]; i++ )
+  {
+    ch = (netChannel*)deletes[i];
+    delete ch ;
+  }
+
+  if (!nopen)
+    return false ;
+  if (!nreads && !nwrites)
+    return true ; //hmmm- should we shutdown?
+
+  netSocket::select (reads, writes, timeout) ;
+
+  for ( i=0; reads[i]; i++ )
+  {
+    ch = (netChannel*)reads[i];
+    if ( ! ch -> closed )
+      ch -> handleReadEvent();
+  }
+
+  for ( i=0; writes[i]; i++ )
+  {
+    ch = (netChannel*)writes[i];
+    if ( ! ch -> closed )
+      ch -> handleWriteEvent();
+  }
+
+  return true ;
+}
+
+void
+netChannel::loop (unsigned int timeout)
+{
+  while ( poll (timeout) ) ;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/netChat.cpp b/ossimPlanet/src/ossimPlanet/netChat.cpp
new file mode 100644
index 0000000..804d1db
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netChat.cpp
@@ -0,0 +1,125 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netChat.cxx 2117 2007-09-13 23:21:09Z fayjf $
+*/
+
+#include <ossimPlanet/netChat.h>
+
+void
+netChat::setTerminator (const char* t)
+{
+  if (terminator) delete[] terminator;
+  terminator = ulStrDup(t);
+}
+
+const char*
+netChat::getTerminator (void)
+{
+  return terminator;
+}
+
+// return the size of the largest prefix of needle at the end
+// of haystack
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+static int
+find_prefix_at_end (const netBuffer& haystack, const char* needle)
+{
+  const char* hd = haystack.getData();
+  int hl = haystack.getLength();
+  int nl = strlen(needle);
+  
+  for (int i = MAX (nl-hl, 0); i < nl; i++) {
+    //if (haystack.compare (needle, hl-(nl-i), nl-i) == 0) {
+    if (memcmp(needle, &hd[hl-(nl-i)], nl-i) == 0) {
+      return (nl-i);
+    }
+  }
+  return 0;
+}
+
+static int
+find_terminator (const netBuffer& haystack, const char* needle)
+{
+  if (needle && *needle)
+  {
+    const char* data = haystack.getData();
+    const char* ptr = strstr(data,needle);
+    if (ptr != NULL)
+      return(ptr-data);
+  }
+  return -1;
+}
+
+
+void
+netChat::handleBufferRead (netBuffer& in_buffer)
+{
+  // Continue to search for terminator in in_buffer,
+  // while calling collect_incoming_data.  The while loop is
+  // necessary because we might read several data+terminator combos
+  // with a single recv().
+  
+  while (in_buffer.getLength()) {
+
+    // special case where we're not using a terminator
+    if (terminator == 0 || *terminator == 0) {
+      collectIncomingData (in_buffer.getData(),in_buffer.getLength());
+      in_buffer.remove ();
+      return;
+    }
+    
+    int terminator_len = strlen(terminator);
+    
+    int index = find_terminator ( in_buffer, terminator ) ;
+    
+    // 3 cases:
+    // 1) end of buffer matches terminator exactly:
+    //    collect data, transition
+    // 2) end of buffer matches some prefix:
+    //    collect data to the prefix
+    // 3) end of buffer does not match any prefix:
+    //    collect data
+    
+    if (index != -1) {
+      // we found the terminator
+      collectIncomingData ( in_buffer.getData(), index ) ;
+      in_buffer.remove (0, index + terminator_len);
+      foundTerminator();
+    } else {
+      // check for a prefix of the terminator
+      int num = find_prefix_at_end (in_buffer, terminator);
+      if (num) {
+        int bl = in_buffer.getLength();
+        // we found a prefix, collect up to the prefix
+        collectIncomingData ( in_buffer.getData(), bl - num ) ;
+        in_buffer.remove (0, bl - num);
+        break;
+      } else {
+        // no prefix, collect it all
+        collectIncomingData (in_buffer.getData(), in_buffer.getLength());
+        in_buffer.remove();
+      }
+    }
+  }
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/netMessage.cpp b/ossimPlanet/src/ossimPlanet/netMessage.cpp
new file mode 100644
index 0000000..5affa53
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netMessage.cpp
@@ -0,0 +1,50 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netMessage.cxx 1899 2004-03-21 17:41:07Z sjbaker $
+*/
+
+#include <ossimPlanet/netMessage.h>
+
+
+void
+netMessageChannel::handleBufferRead (netBuffer& in_buffer)
+{
+  int n = in_buffer.getLength () ;
+  while ( n >= 2 )
+  {
+    unsigned short msg_len = *( (unsigned short*)in_buffer.getData() ) ;
+    if ( n >= msg_len )
+    {
+      //we have a complete message; handle it
+      netMessage msg(in_buffer.getData(),msg_len);
+      in_buffer.remove(0,msg_len);
+      handleMessage ( msg );
+
+      //ulSetError ( UL_DEBUG, "netMessageChannel: %d read", msg_len ) ;
+      n -= msg_len ;
+    }
+    else
+    {
+      //ulSetError ( UL_DEBUG, "netMessageChannel: %d waiting", n ) ;
+      break ;
+    }
+  }
+}
diff --git a/ossimPlanet/src/ossimPlanet/netMonitor.cpp b/ossimPlanet/src/ossimPlanet/netMonitor.cpp
new file mode 100644
index 0000000..a6761fd
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netMonitor.cpp
@@ -0,0 +1,180 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netMonitor.cxx 1568 2002-09-02 06:05:49Z sjbaker $
+*/
+
+#include <ossimPlanet/netMonitor.h>
+
+
+class netMonitorChannel : public netChat
+{
+  netMonitorServer* server ;
+  bool authorized ;
+  netBuffer buffer;
+
+  void prompt () ;
+
+  virtual void collectIncomingData	(const char* s, int n) ;
+  virtual void foundTerminator (void) ;
+
+public:
+
+  netMonitorChannel ( netMonitorServer* server ) ;
+
+  virtual void handleClose (void)
+  {
+    ulSetError(UL_DEBUG, "%d: Client disconnected.",getHandle());
+    shouldDelete () ;
+    netChat::handleClose () ;
+    server -> active = 0 ;
+  }
+} ;
+
+		
+// for now, we ignore any telnet option stuff sent to
+// us, and we process the backspace key ourselves.
+// gee, it would be fun to write a full-blown line-editing
+// environment, etc...
+
+static void clean_line (char* line)
+{
+  char* dst = line ;
+  for ( char* src = line ; *src ; src ++ )
+  {
+    char ch = *src ;
+    if (ch==8 || ch==127)
+    {
+      // backspace
+      if (dst != line)
+        dst -- ;
+    }
+    else if (ch<127)
+    {
+      *dst++ = *src ;
+    }
+  }
+  *dst = 0 ;
+}
+
+
+netMonitorChannel::netMonitorChannel ( netMonitorServer* _server ) : buffer(512)
+{
+  server = _server ;
+  setTerminator("\r\n");
+  
+  if ( server -> password && server -> password [0] != 0 )
+  {
+    authorized = false ;
+    push ("Enter password: ") ;
+  }
+  else
+  {
+    authorized = true ;
+    push ( netFormat("Connected to \"%s\"... Welcome!\r\n", server -> name ) ) ;
+    prompt();
+  }
+}
+
+
+void netMonitorChannel::prompt ()
+{
+	push ( server -> prompt ) ;
+}
+
+
+void netMonitorChannel::collectIncomingData	(const char* s, int n)
+{
+  if ( !buffer.append(s,n) )
+  {
+    // denial of service.
+    push ("BCNU\r\n");
+    closeWhenDone();
+  }
+}
+
+void netMonitorChannel::foundTerminator (void)
+{
+  char* line = buffer.getData();
+  clean_line ( line ) ;
+  
+  if (!authorized)
+  {
+    if (strcmp(line,server -> password) == 0)
+    {
+      authorized = true ;
+      push ( netFormat("Connected to \"%s\"... Welcome!\r\n",server -> name) ) ;
+      prompt () ;
+    }
+    else
+    {
+      close();
+    }
+  }
+  else if (*line == 0)
+  {
+    prompt();
+  }
+  else if (*line == 4 || strcmp(line,"exit") == 0)
+  {
+    push ("BCNU\r\n");  //Be seein' you
+    closeWhenDone();
+  }
+  else
+  {
+    if ( server -> cmdfunc )
+    {
+      server -> cmdfunc ( line ) ;
+    }
+    else
+    {
+      ulSetError(UL_DEBUG,"echo: %s",line);
+
+      push(line);
+      push(getTerminator());
+    }
+    
+    prompt();
+  }
+  buffer.remove();
+}
+
+
+void netMonitorServer::handleAccept (void)
+{
+  if ( !active )
+  {
+    netAddress addr ;
+    int s = accept ( &addr ) ;
+
+    ulSetError(UL_DEBUG, "%d: Client %s:%d connected",s,addr.getHost(),addr.getPort());
+
+    active = new netMonitorChannel ( this ) ;
+    active -> setHandle (s);
+  }
+}
+
+
+bool netMonitorServer::push (const char* s)
+{
+  if ( active )
+    return active -> push ( s ) ;
+  return false ;
+}
diff --git a/ossimPlanet/src/ossimPlanet/netSocket.cpp b/ossimPlanet/src/ossimPlanet/netSocket.cpp
new file mode 100644
index 0000000..75a45a9
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/netSocket.cpp
@@ -0,0 +1,503 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: netSocket.cxx 2054 2005-11-16 15:20:57Z bram $
+*/
+
+#include <ossimPlanet/netSocket.h>
+
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+
+#if defined(UL_MAC_OSX)
+#  include <netinet/in.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <sys/time.h>    /* Need both for Mandrake 8.0!! */
+#include <unistd.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+#else
+
+#include <winsock.h>
+#include <stdarg.h>
+
+#endif
+
+#if defined(UL_MSVC) && !defined(socklen_t)
+#define socklen_t int
+#endif
+
+/* Paul Wiltsey says we need this for Solaris 2.8 */
+ 
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned long)-1)
+#endif
+                                                                                               
+netAddress::netAddress ( const char* host, int port )
+{
+  set ( host, port ) ;
+}
+
+
+void netAddress::set ( const char* host, int port )
+{
+  memset(this, 0, sizeof(netAddress));
+
+  sin_family = AF_INET ;
+  sin_port = htons (port);
+
+  /* Convert a string specifying a host name or one of a few symbolic
+  ** names to a numeric IP address.  This usually calls gethostbyname()
+  ** to do the work; the names "" and "<broadcast>" are special.
+  */
+
+  if (host[0] == '\0')
+    sin_addr = INADDR_ANY;
+  else
+  if (host[0] == '<' && strcmp(host, "<broadcast>") == 0)
+    sin_addr = INADDR_BROADCAST;
+  else
+  {
+    sin_addr = inet_addr ( host ) ;
+
+    if ( sin_addr == INADDR_NONE )
+    {
+      struct hostent *hp = gethostbyname ( host ) ;
+
+      if ( hp != NULL )
+      	memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ;
+      else
+      {
+        perror ( "netAddress::set" ) ;
+        sin_addr = INADDR_ANY ;
+      }
+    }
+  }
+}
+
+
+/* Create a string object representing an IP address.
+   This is always a string of the form 'dd.dd.dd.dd' (with variable
+   size numbers). */
+
+const char* netAddress::getHost () const
+{
+#if 0
+  const char* buf = inet_ntoa ( sin_addr ) ;
+#else
+  static char buf [32];
+	long x = ntohl(sin_addr);
+	sprintf(buf, "%d.%d.%d.%d",
+		(int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
+		(int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff );
+#endif
+  return buf;
+}
+
+unsigned int netAddress::getIP () const 
+{ 
+	return sin_addr; 
+}
+
+unsigned int netAddress::getPort() const
+{
+  return ntohs(sin_port);
+}
+
+unsigned int netAddress::getFamily () const 
+{ 
+	return sin_family; 
+}
+
+const char* netAddress::getLocalHost ()
+{
+  //gethostbyname(gethostname())
+
+  char buf[256];
+  memset(buf, 0, sizeof(buf));
+  gethostname(buf, sizeof(buf)-1);
+  const hostent *hp = gethostbyname(buf);
+
+  if (hp && *hp->h_addr_list)
+  {
+    in_addr     addr = *((in_addr*)*hp->h_addr_list);
+    const char* host = inet_ntoa(addr);
+
+    if ( host )
+      return host ;
+  }
+
+  return "127.0.0.1" ;
+}
+
+
+bool netAddress::getBroadcast () const
+{
+  return sin_addr == INADDR_BROADCAST;
+}
+
+
+netSocket::netSocket ()
+{
+  handle = -1 ;
+}
+
+
+netSocket::~netSocket ()
+{
+  close () ;
+}
+
+
+void netSocket::setHandle (int _handle)
+{
+  close () ;
+  handle = _handle ;
+}
+
+
+bool netSocket::open ( bool stream )
+{
+  close () ;
+  handle = ::socket ( AF_INET, (stream? SOCK_STREAM: SOCK_DGRAM), 0 ) ;
+  return (handle != -1);
+}
+
+
+void netSocket::setBlocking ( bool blocking )
+{
+  assert ( handle != -1 ) ;
+
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+
+  int delay_flag = ::fcntl (handle, F_GETFL, 0);
+
+  if (blocking)
+    delay_flag &= (~O_NDELAY);
+  else
+    delay_flag |= O_NDELAY;
+
+  ::fcntl (handle, F_SETFL, delay_flag);
+
+#else
+
+  u_long nblocking = blocking? 0: 1;
+  ::ioctlsocket(handle, FIONBIO, &nblocking);
+
+#endif
+}
+
+
+void netSocket::setBroadcast ( bool broadcast )
+{
+  assert ( handle != -1 ) ;
+  int result;
+  if ( broadcast ) {
+      int one = 1;
+#ifdef UL_WIN32
+      result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, (char*)&one, sizeof(one) );
+#else
+      result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one) );
+#endif
+  } else {
+      result = ::setsockopt( handle, SOL_SOCKET, SO_BROADCAST, NULL, 0 );
+  }
+  if ( result < 0 ) {
+      perror("set broadcast:");
+  }
+  assert ( result != -1 );
+}
+
+
+int netSocket::bind ( const char* host, int port )
+{
+  assert ( handle != -1 ) ;
+  netAddress addr ( host, port ) ;
+  return ::bind(handle,(const sockaddr*)&addr,sizeof(netAddress));
+}
+
+
+int netSocket::listen ( int backlog )
+{
+  assert ( handle != -1 ) ;
+  return ::listen(handle,backlog);
+}
+
+
+int netSocket::accept ( netAddress* addr )
+{
+  assert ( handle != -1 ) ;
+
+  if ( addr == NULL )
+  {
+    return ::accept(handle,NULL,NULL);
+  }
+  else
+  {
+    socklen_t addr_len = (socklen_t) sizeof(netAddress) ;
+    return ::accept(handle,(sockaddr*)addr,&addr_len);
+  }
+}
+
+
+int netSocket::connect ( const char* host, int port )
+{
+  assert ( handle != -1 ) ;
+  netAddress addr ( host, port ) ;
+  if ( addr.getBroadcast() ) {
+      setBroadcast( true );
+  }
+  return ::connect(handle,(const sockaddr*)&addr,sizeof(netAddress));
+}
+
+
+int netSocket::send (const void * buffer, int size, int flags)
+{
+  assert ( handle != -1 ) ;
+  return ::send (handle, (const char*)buffer, size, flags);
+}
+
+
+int netSocket::sendto ( const void * buffer, int size,
+                        int flags, const netAddress* to )
+{
+  assert ( handle != -1 ) ;
+  return ::sendto(handle,(const char*)buffer,size,flags,
+                         (const sockaddr*)to,sizeof(netAddress));
+}
+
+
+int netSocket::recv (void * buffer, int size, int flags)
+{
+  assert ( handle != -1 ) ;
+  return ::recv (handle, (char*)buffer, size, flags);
+}
+
+
+int netSocket::recvfrom ( void * buffer, int size,
+                          int flags, netAddress* from )
+{
+  assert ( handle != -1 ) ;
+  socklen_t fromlen = (socklen_t) sizeof(netAddress) ;
+  return ::recvfrom(handle,(char*)buffer,size,flags,(sockaddr*)from,&fromlen);
+}
+
+
+void netSocket::close (void)
+{
+  if ( handle != -1 )
+  {
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+    ::close( handle );
+#else
+    ::closesocket( handle );
+#endif
+    handle = -1 ;
+  }
+}
+
+
+bool netSocket::isNonBlockingError ()
+{
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+  switch (errno) {
+  case EWOULDBLOCK: // always == NET_EAGAIN?
+  case EALREADY:
+  case EINPROGRESS:
+    return true;
+  }
+  return false;
+#else
+  int wsa_errno = WSAGetLastError();
+  if ( wsa_errno != 0 )
+  {
+    WSASetLastError(0);
+    ulSetError(UL_WARNING,"WSAGetLastError() => %d",wsa_errno);
+    switch (wsa_errno) {
+    case WSAEWOULDBLOCK: // always == NET_EAGAIN?
+    case WSAEALREADY:
+    case WSAEINPROGRESS:
+      return true;
+    }
+  }
+  return false;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////
+//
+//	modified version by os
+//
+//////////////////////////////////////////////////////////////////////
+int netSocket::select ( netSocket** reads, netSocket** writes, int timeout )
+{
+  fd_set r,w;
+  int	retval;
+  
+  FD_ZERO (&r);
+  FD_ZERO (&w);
+
+  int i, k ;
+  int num = 0 ;
+
+  if ( reads )
+  {
+    for ( i=0; reads[i]; i++ )
+    {
+      int fd = reads[i]->getHandle();
+      FD_SET (fd, &r);
+      num++;
+    }
+  }
+
+  if ( writes )
+  {
+    for ( i=0; writes[i]; i++ )
+    {
+      int fd = writes[i]->getHandle();
+      FD_SET (fd, &w);
+      num++;
+    }
+  }
+
+  if (!num)
+    return num ;
+
+  /* Set up the timeout */
+  struct timeval tv ;
+  tv.tv_sec = timeout/1000;
+  tv.tv_usec = (timeout%1000)*1000;
+
+  // It bothers me that select()'s first argument does not appear to
+  // work as advertised... [it hangs like this if called with
+  // anything less than FD_SETSIZE, which seems wasteful?]
+  
+  // Note: we ignore the 'exception' fd_set - I have never had a
+  // need to use it.  The name is somewhat misleading - the only
+  // thing I have ever seen it used for is to detect urgent data -
+  // which is an unportable feature anyway.
+
+  retval = ::select (FD_SETSIZE, &r, &w, 0, &tv);
+
+  //remove sockets that had no activity
+
+  num = 0 ;
+
+  if ( reads )
+  {
+    for ( k=i=0; reads[i]; i++ )
+    {
+      int fd = reads[i]->getHandle();
+      if ( FD_ISSET (fd, &r) )
+      {
+        reads[k++] = reads[i];
+        num++;
+      }
+    }
+    reads[k] = NULL ;
+  }
+
+  if ( writes )
+  {
+    for ( k=i=0; writes[i]; i++ )
+    {
+      int fd = writes[i]->getHandle();
+      if ( FD_ISSET (fd, &w) )
+      {
+        writes[k++] = writes[i];
+        num++;
+      }
+    }
+    writes[k] = NULL ;
+  }
+
+  if (retval == 0) // timeout
+    return (-2);
+  if (retval == -1)// error
+    return (-1);
+
+  return num ;
+}
+
+
+/* Init/Exit functions */
+
+static void netExit ( void )
+{
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+#else
+	/* Clean up windows networking */
+	if ( WSACleanup() == SOCKET_ERROR ) {
+		if ( WSAGetLastError() == WSAEINPROGRESS ) {
+			WSACancelBlockingCall();
+			WSACleanup();
+		}
+	}
+#endif
+}
+
+
+int netInit ( int* argc, char** argv )
+{
+  /* Legacy */
+
+  return netInit () ;
+}
+
+
+int netInit ()
+{
+  assert ( sizeof(sockaddr_in) == sizeof(netAddress) ) ;
+
+#if defined(UL_CYGWIN) || !defined (UL_WIN32)
+#else
+	/* Start up the windows networking */
+	WORD version_wanted = MAKEWORD(1,1);
+	WSADATA wsaData;
+
+	if ( WSAStartup(version_wanted, &wsaData) != 0 ) {
+		ulSetError(UL_WARNING,"Couldn't initialize Winsock 1.1");
+		return(-1);
+	}
+#endif
+
+  atexit( netExit ) ;
+	return(0);
+}
+
+
+const char* netFormat ( const char* format, ... )
+{
+  static char buffer[ 256 ];
+  va_list argptr;
+  va_start(argptr, format);
+  vsprintf( buffer, format, argptr );
+  va_end(argptr);
+  return( buffer );
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanet.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanet.cpp
new file mode 100644
index 0000000..15b5a05
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanet.cpp
@@ -0,0 +1,507 @@
+#include <osg/Timer>
+#include <osg/BoundingSphere>
+#include <osg/CoordinateSystemNode>
+#include <osgDB/DatabasePager>
+#include <osgDB/Registry>
+#include <osgUtil/IntersectVisitor>
+#include <iostream>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossim/base/ossimEcefPoint.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossimPlanet/ossimPlanetLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <iostream>
+// #include <ossimPlanet/ossimPlanetUtility.h>
+
+// #include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+
+#include <OpenThreads/ScopedLock>
+ossimPlanet::LayerListener::LayerListener(ossimPlanet* planet)
+:thePlanet(planet)
+{
+}
+void ossimPlanet::LayerListener::needsRedraw(ossimPlanetNode* node)
+{
+   if(thePlanet)
+   {
+      thePlanet->setRedrawFlag(true);
+      thePlanet->notifyNeedsRedraw(node);
+   }
+}
+void ossimPlanet::LayerListener::setPlanet(ossimPlanet* planet)
+{
+   thePlanet = planet;
+}
+
+class ossimPlanetFinder : public osg::NodeVisitor
+{
+public:
+   ossimPlanetFinder()
+      :osg::NodeVisitor(NODE_VISITOR,
+                        TRAVERSE_ALL_CHILDREN)
+      {
+         thePlanet = 0;
+      }
+
+   virtual void apply(osg::Node& node)
+      {
+         if(!thePlanet)
+         {
+            thePlanet = dynamic_cast<ossimPlanet*>(&node);
+         }
+         else
+         {
+            return;
+         }
+         osg::NodeVisitor::apply(node);
+      }
+   
+   ossimPlanet* thePlanet;
+};
+
+class ossimPlanetResetRedrawFlag : public osg::NodeVisitor
+{
+public:
+	ossimPlanetResetRedrawFlag()
+	:osg::NodeVisitor(NODE_VISITOR,
+							TRAVERSE_ALL_CHILDREN)
+	{
+		
+	}
+   virtual void apply(osg::Node& node)
+	{
+		ossimPlanetLayer* layer = dynamic_cast<ossimPlanetLayer*>(&node);
+		if(layer)
+		{
+			layer->setRedrawFlag(false);
+		}
+		
+		osg::NodeVisitor::apply(node);		
+	}
+	
+};
+
+osg::BoundingSphere ossimPlanet::computeBound() const
+{
+   if(getNumChildren() == 0)
+   {
+      return osg::BoundingSphere(osg::Vec3(0.0,0.0,0.0),
+                                     1.0);
+   }
+   return osg::MatrixTransform::computeBound();
+
+}
+
+//bool ossimPlanet::computeBound() const
+//{
+//  if(getNumChildren() == 0)
+//  {
+//       _bsphere = osg::BoundingSphere(osg::Vec3(0.0,0.0,0.0),
+//                                      1.0);
+//    }
+//    else
+//    {
+//       return osg::MatrixTransform::computeBound();
+//    }
+//    return true;
+// }
+
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static ossim_uint32 allocated = 0;
+#endif
+ossimPlanet::ossimPlanet()
+   :osg::MatrixTransform()
+{
+   theNadirPoint                  = osg::Vec3d(0.0,0.0,ossim::nan());
+   theLineOfSitePoint             = osg::Vec3d(0.0,0.0,ossim::nan());
+   theNadirLatLonHeightPoint      = osg::Vec3d(0.0,0.0,ossim::nan());
+   theLineOfSiteLatLonHeightPoint = osg::Vec3d(0.0,0.0,ossim::nan());
+   theLayerListener = new ossimPlanet::LayerListener(this);
+   theRedrawFlag = false;
+   theComputeIntersectionFlag = true;
+   setUpdateCallback(new ossimPlanetTraverseCallback);
+   setEventCallback(new ossimPlanetTraverseCallback);
+   setCullCallback(new ossimPlanetTraverseCallback);
+
+   theModel = new ossimPlanetNormalizedEllipsoidModel;
+   
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++allocated;
+   std::cout << "ossimPlanet count: " << allocated << std::endl;
+#endif
+}
+
+ossimPlanet::~ossimPlanet()
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   --allocated;
+   std::cout << "ossimPlanet count: " << allocated << std::endl;
+#endif
+
+}
+void ossimPlanet::setupDefaults()
+{
+}
+
+
+void ossimPlanet::traverse(osg::NodeVisitor& nv)
+{
+//   osg::Timer_t tick = osg::Timer::instance()->tick();
+   switch(nv.getVisitorType())
+   {
+     case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osg::MatrixTransform::traverse(nv);
+         return;
+      }
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         // we are starting a redraw for the update,cull,draw sequence so reset the redraw flag for next frame
+         theLayersToAddListMutex.lock();
+         if(theLayersToAddList.size())
+         {
+            ossim_uint32 idx = 0;
+            for(idx = 0; idx < theLayersToAddList.size();++idx)
+            {
+               addChild(theLayersToAddList[idx].get());
+            }
+            theLayersToAddList.clear();
+         }
+         theLayersToAddListMutex.unlock();
+         
+         break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   osg::MatrixTransform::traverse(nv);
+#if 0
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         std::cout << "event TIME == " 
+         << osg::Timer::instance()->delta_m(tick, osg::Timer::instance()->tick()) << std::endl;
+         break;
+      }
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         std::cout << "update TIME == " 
+         << osg::Timer::instance()->delta_m(tick, osg::Timer::instance()->tick()) << std::endl;
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         std::cout << "CULLING TIME == " 
+         << osg::Timer::instance()->delta_m(tick, osg::Timer::instance()->tick()) << std::endl;
+         break;
+      }
+   }
+#endif
+}
+
+const osg::Vec3d& ossimPlanet::getEyePositionLatLonHeight()const
+{
+   return theEyePositionLatLonHeight;
+}
+
+osg::Vec3d ossimPlanet::getNadirPoint()const
+{
+   return theNadirPoint;
+}
+
+osg::Vec3d ossimPlanet::getLineOfSitePoint()const
+{
+   return theLineOfSitePoint;
+}
+
+
+osg::Vec3d ossimPlanet::getNadirLatLonHeightPoint()const
+{
+   return theNadirLatLonHeightPoint;
+}
+
+osg::Vec3d ossimPlanet::getLineOfSiteLatLonHeightPoint()const
+{
+   return theLineOfSiteLatLonHeightPoint;
+}
+
+const osg::Vec3d& ossimPlanet::hpr()const
+{
+   return theLsrHeadingPitchRoll;
+}
+
+void ossimPlanet::setComputeIntersectionFlag(bool flag)
+{
+   theComputeIntersectionFlag = flag;
+}
+
+bool ossimPlanet::getComputeIntersectionFlag()const
+{
+   return theComputeIntersectionFlag;
+}
+
+void ossimPlanet::computeIntersection(osgUtil::CullVisitor* nv)
+{
+   theNadirPoint                  = osg::Vec3d(0.0,0.0,ossim::nan());
+   theLineOfSitePoint             = osg::Vec3d(0.0,0.0,ossim::nan());
+   theNadirLatLonHeightPoint      = osg::Vec3d(0.0,0.0,ossim::nan());
+   theLineOfSiteLatLonHeightPoint = osg::Vec3d(0.0,0.0,ossim::nan());
+   if(!nv)
+   {
+      return;
+   }
+   osg::Node* node = 0;
+   if(getNumChildren() > 0)
+   {
+      node = getChild(0);
+   }
+   if(node)
+   {
+      if(theModel.valid())
+      {
+         osgUtil::IntersectVisitor iv;
+         osg::Vec3d eyeDirection = nv->getLookVectorLocal();
+         osg::Vec3d eye = nv->getEyePoint();
+         osg::Vec3d normal;
+         osg::Vec3d eyeLlh;
+         theModel->inverse(eye,
+                           eyeLlh);
+         theModel->normal(eyeLlh,
+                          normal);
+         normal.normalize();
+         osg::Vec3d endPt1 = getBound().center();
+         osg::Vec3d endPt2  = eye + eyeDirection*(1/FLT_EPSILON);
+         osg::Vec3d startPt3  = eye + normal*(1/FLT_EPSILON);
+         osg::ref_ptr<osg::LineSegment> nadirLookVector      = new osg::LineSegment(startPt3, endPt1);
+         osg::ref_ptr<osg::LineSegment> lineOfSiteLookVector = new osg::LineSegment(eye, endPt2);
+         iv.addLineSegment(nadirLookVector.get());
+         iv.addLineSegment(lineOfSiteLookVector.get());
+         node->accept(iv);
+//          this->accept(iv);
+         if(iv.hits())
+         {
+//             osg::Vec3d eyeLocal = nv->getEyeLocal();
+
+//             theNadirPoint = eyeLocal;
+//             land()->model()->inverse(theNadirPoint,
+//                                            theNadirLatLonHeightPoint);
+            
+            osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(lineOfSiteLookVector.get());
+            if (!hitList.empty())
+            {
+               theLineOfSitePoint = hitList.front().getWorldIntersectPoint();
+               theModel->inverse(theLineOfSitePoint,
+											theLineOfSiteLatLonHeightPoint);
+            }
+            osgUtil::IntersectVisitor::HitList& hitListNadir = iv.getHitList(nadirLookVector.get());
+            if (!hitListNadir.empty())
+            {
+               theNadirPoint = hitListNadir.front().getWorldIntersectPoint();
+               theModel->inverse(theNadirPoint,
+											theNadirLatLonHeightPoint);
+            }
+         }
+      }
+   }
+}
+
+ossimPlanet* ossimPlanet::findPlanet(osg::Node* startNode)
+{
+   osg::Node* rootNode = startNode;
+   osg::Node* rootNonNullNode = startNode;
+
+   while(rootNode)
+   {
+      rootNonNullNode = rootNode;
+      if(dynamic_cast<ossimPlanet*>(rootNode))
+      {
+         return (ossimPlanet*)rootNode;
+      }
+      if(rootNode->getNumParents() > 0)
+      {
+         rootNode = rootNode->getParent(0);
+      }
+      else
+      {
+         rootNode = 0;
+      }
+   }
+   if(rootNonNullNode)
+   {
+      ossimPlanetFinder finder;
+      rootNonNullNode->accept(finder);
+      if(finder.thePlanet)
+      {
+         return finder.thePlanet;
+      }
+   }
+
+   return 0;
+}
+
+ossimPlanet* ossimPlanet::findPlanet(osg::NodePath& currentNodePath)
+{
+   if(currentNodePath.empty())
+   {
+      return 0;
+   }
+   for(osg::NodePath::reverse_iterator itr = currentNodePath.rbegin();
+       itr != currentNodePath.rend();
+       ++itr)
+   {
+      ossimPlanet* node = dynamic_cast<ossimPlanet*>(*itr);
+      if (node) 
+      {
+         return node;
+      }
+   }
+   
+   return 0;
+}
+
+void ossimPlanet::resetAllRedrawFlags()
+{
+	ossimPlanetResetRedrawFlag	resetRedraw;
+	setRedrawFlag(false);
+	accept(resetRedraw);
+}
+
+
+void ossimPlanet::execute(const ossimPlanetAction& action)
+{
+   const ossimPlanetXmlAction* xmlAction = action.toXmlAction();
+	
+	if(xmlAction)
+	{
+		xmlExecute(*xmlAction);
+      if(action.command() == "Add")
+      {
+         
+      }
+	}
+}
+
+void ossimPlanet::xmlExecute(const ossimPlanetXmlAction& action)
+{
+   if(action.command() == "Add")
+   {
+   }
+}
+
+bool ossimPlanet::removeChildren(unsigned int pos,unsigned int numChildrenToRemove)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+      if(theBlockCallbacksFlag)
+      {
+         return osg::MatrixTransform::removeChildren(pos, numChildrenToRemove);
+      }
+   }
+   
+   if (pos<_children.size() && numChildrenToRemove>0)
+   {
+      unsigned int endOfRemoveRange = pos+numChildrenToRemove;
+      if (endOfRemoveRange>_children.size())
+      {
+         endOfRemoveRange=_children.size();
+      }
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < endOfRemoveRange;++idx)
+      {
+         ossimPlanetLayer* layer = dynamic_cast<ossimPlanetLayer*>(_children[idx].get());
+         if(layer)
+         {
+            notifyLayerRemoved(layer);
+         }
+      }
+      return osg::MatrixTransform::removeChildren(pos, numChildrenToRemove);
+   }
+   else return false;
+}
+
+void ossimPlanet::childInserted(unsigned int pos)
+{
+   ossimPlanetLayer* n = dynamic_cast<ossimPlanetLayer*>(getChild(pos));
+//   if(!theLand.valid())
+//   {
+//      ossimPlanetLand* land = dynamic_cast<ossimPlanetLand*>(n);
+//      if(land)
+//      {
+//         theLand = land;
+//		   theModel = theLand->model();
+//      }
+//   }
+   {
+      if(theBlockCallbacksFlag) return;
+   }
+   if(n)
+   {
+      n->setPlanet(this);
+      n->setModel(model().get());
+      setRedrawFlag(true);
+      n->addCallback(theLayerListener.get());
+      notifyLayerAdded(n);
+   }
+}
+
+void ossimPlanet::childRemoved(unsigned int /*pos*/, unsigned int /*numChildrenToRemove*/)
+{
+	setRedrawFlag(true);
+}
+
+void ossimPlanet::notifyLayerAdded(ossimPlanetLayer* layer)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->nodeAdded(layer);
+      }
+   }
+}
+
+void ossimPlanet::notifyLayerRemoved(ossimPlanetLayer* layer)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->nodeRemoved(layer);
+      }
+   }
+   
+}
+
+void ossimPlanet::notifyNeedsRedraw(ossimPlanetNode* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->needsRedraw(node); 
+      }
+   }   
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetAction.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetAction.cpp
new file mode 100644
index 0000000..466559e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetAction.cpp
@@ -0,0 +1,55 @@
+#include <iostream>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossim/base/ossimNotifyContext.h>
+#include <ossim/base/ossimCommon.h>
+
+ossimPlanetAction::ossimPlanetAction(const ossimString& originatingFederate) :
+    theOrigin(originatingFederate)
+{
+}
+
+
+
+void ossimPlanetAction::printError(const char* message) const
+{
+   ossimString code;
+   sourceCode(code);
+   ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetAction Error (" << message << ") \"" << code << '"' << std::endl;
+}
+
+void ossimPlanetAction::printError(const ossimString& message) const
+{
+    printError(message.c_str());
+}
+
+void ossimPlanetAction::execute() const
+{
+    ossimPlanetActionRouter::instance()->route(*this);
+}
+
+void ossimPlanetAction::post()const
+{
+   ossimPlanetActionRouter::instance()->post(*this);
+}
+
+void ossimPlanetAction::allExecute() const
+{
+    ossimPlanetActionRouter::instance()->allRoute(*this);
+}
+
+void ossimPlanetAction::tellExecute(const ossimString& destination) const
+{
+    ossimPlanetActionRouter::instance()->tellRoute(*this, destination);
+}
+
+
+// protected
+
+
+const ossimString& ossimPlanetAction::defaultOrigin()
+{
+    return ossimPlanetActionRouter::instance()->federateName();
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetActionReceiver.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetActionReceiver.cpp
new file mode 100644
index 0000000..d6ac321
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetActionReceiver.cpp
@@ -0,0 +1,31 @@
+#include <ossimPlanet/ossimPlanetActionReceiver.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+
+ossimPlanetActionReceiver::~ossimPlanetActionReceiver()
+{
+   if (pathname_ != ":")
+      ossimPlanetActionRouter::instance()->unregisterReceiver(this);
+}
+
+std::string ossimPlanetActionReceiver::name() const
+{
+   return pathname_.substr(pathname_.rfind(':')+1, pathname_.length());
+}
+
+void ossimPlanetActionReceiver::setPathname(const std::string& newPath)
+{
+   pathname_ = newPath;
+}
+
+void ossimPlanetActionReceiver::setPathnameAndRegister(const std::string& newPath)
+{
+   // we will unregister if already registered
+   //
+   ossimPlanetActionReceiver* r = ossimPlanetActionRouter::instance()->receiver(pathname());
+   if(r==this) // if we are ourselves then we can change our pathname
+   {
+      ossimPlanetActionRouter::instance()->unregisterReceiver(this);
+   }      
+   setPathname(newPath);
+   ossimPlanetActionRouter::instance()->registerReceiver(this);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetActionRouter.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetActionRouter.cpp
new file mode 100644
index 0000000..e78690f
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetActionRouter.cpp
@@ -0,0 +1,374 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <limits.h>
+#ifndef WIN32
+#include <sys/param.h>
+#else
+#include <winsock.h>
+#endif
+
+#include <osgDB/FileUtils>
+
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+#include <ossimPlanet/ossimPlanetSocketNetworkConnection.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossim/base/ossimNotifyContext.h>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+
+using namespace mkUtils;
+
+
+// network 
+
+void ossimPlanetActionRouter::addNetworkConnection(ossimPlanetNetworkConnection* commLink)
+{
+   if(commLink&&commLink->error().empty())
+   {
+//     assert(commLink != NULL && commLink->error().empty());
+    
+      std::vector<ossimPlanetNetworkConnection*>::iterator i = find_if(network_.begin(), network_.end(), NCEqualPred(commLink->name()));
+      if (i == network_.end())
+         network_.push_back(commLink);
+      else 
+         std::cerr << "ossimPlanetActionRouter::addNetworkConnection() already has a ossimPlanetNetworkConnection named " << commLink->name() << std::endl;
+   }
+}
+
+void ossimPlanetActionRouter::removeNetworkConnection(const ossimString& name)
+{
+    std::vector<ossimPlanetNetworkConnection*>::iterator i = find_if(network_.begin(), network_.end(), NCEqualPred(name));
+    if (i != network_.end())
+        network_.erase(i);
+}
+
+ossimPlanetNetworkConnection* ossimPlanetActionRouter::networkConnection(const ossimString& name) const
+{
+    std::vector<ossimPlanetNetworkConnection*>::const_iterator i = find_if(network_.begin(), network_.end(), NCEqualPred(name));
+    return i == network_.end() ? NULL : *i;
+}
+
+// federate name
+
+void ossimPlanetActionRouter::setFederateName(const ossimString& newName)
+{
+   
+   if(ossimString(newName).trim().empty()) return;
+   
+//     assert(!newName.empty());
+//     assert(newName.find(" ", 0) == -1);
+    
+    federateName_ = newName;
+    
+//     assert(newName == federateName());
+}
+
+void ossimPlanetActionRouter::post(const ossimPlanetAction& a)
+{
+   if(theThreadQueue.valid())
+   {
+      theThreadQueue->addAction(a);
+   }
+}
+
+// route Actions
+
+void ossimPlanetActionRouter::route(const ossimPlanetAction& a)
+{
+   ossimPlanetActionReceiver * receiver = 0; 
+   ossimString target(a.target()); 
+ 
+   // start critical section 
+   theReceiverMutex.lock();
+   
+   MapType::iterator targetObj = receivers_.find(target); 
+   if (targetObj != receivers_.end()) 
+   { 
+      receiver = targetObj->second; 
+   }
+   theReceiverMutex.unlock(); 
+   // end critical section
+   
+   if (receiver) 
+   { 
+      // found a receiver so exectute the action 
+      receiver->execute(a); 
+   } 
+   else 
+   { 
+      a.printError("bad target for action"); 
+   } 
+}
+
+void ossimPlanetActionRouter::allRoute(const ossimPlanetAction& a)
+{
+    static const ossimString emptyString;  // static since don't ctor/dtor empty string every time
+    remoteRouteImplementation(a, emptyString);
+}
+
+void ossimPlanetActionRouter::tellRoute(const ossimPlanetAction& a, const ossimString& destination)
+{
+   if(destination.empty()) return;
+   
+//     assert(!destination.empty()); 
+    remoteRouteImplementation(a, destination);
+}
+
+void ossimPlanetActionRouter::executeFile(const ossimString& filename, const ossimString& origin)
+{
+#if 0 // XXX crash in osgDB::findFileInPath(), so junk the search path until we figure this out
+    ossimString searchResult = osgDB::findFileInPath(filename, osgDB::getDataFilePathList());
+    std::ifstream fin(searchResult.empty() ? filename.c_str() : searchResult.c_str());  
+#else
+    std::ifstream fin(filename.c_str());  
+#endif
+    
+   if (!fin)
+      ossimNotify(ossimNotifyLevel_WARN) << "cannot open file " << filename << " for execution in ossimPlanetActionRouter::executeFile()" << std::endl;
+   else
+   {
+      ossimPlanetDestinationCommandAction x("", origin);
+      for (fin >> x; fin; fin >> x)
+      {
+         route(x);
+         x.setSourceCode("");
+      }
+      ossimString code;
+      x.sourceCode(code);
+      if(fin.eof()&&!code.empty())
+      {
+         route(x);
+      }
+   }
+}
+
+void ossimPlanetActionRouter::executeNetworkActions()
+{
+    for (int i = 0; i < (int)network_.size(); i++)
+        network_[i]->receive();
+}
+
+// ossimPlanetActionReceiver management
+
+void ossimPlanetActionRouter::registerReceiver(ossimPlanetActionReceiver* r)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReceiverMutex);
+   if(!r) return;
+//     assert(r != NULL);
+    
+    // If a receiver with this name was already registered, 
+    // tell us before we replace it with r.
+    MapType::iterator i = receivers_.find(r->pathname());
+    if (i != receivers_.end())
+	std::cerr << "\aWarning in ossimPlanetActionRouter::registerReceiver: ossimPlanetActionReceiver " << i->second << " with pathname " << r->pathname() << " already registered, replacing with ossimPlanetActionReceiver " << r << std::endl;
+    
+    receivers_[r->pathname()] = r;
+    
+//     assert(receiver(r->pathname()) == r);
+}
+
+void ossimPlanetActionRouter::unregisterReceiver(ossimPlanetActionReceiver* r)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReceiverMutex);
+   if(!r) return;
+//     assert(r != NULL);
+
+    MapType::iterator i = receivers_.find(r->pathname());
+	if(i!=receivers_.end())
+	{
+		if (i->second == r) 
+		{
+		// r is registered under r->pathname().
+		// this is the normal case.
+			receivers_.erase(i);
+
+		} 
+		else if (i->second == NULL) 
+		{
+			// r not registered under r->pathname(), unknown yet if r is registered
+			// under a different name.  if so, find it and remove it.
+			for (i = receivers_.begin(); i != receivers_.end() && i->second != r; i++) 
+				;
+			if (i != receivers_.end()) 
+			{
+				receivers_.erase(i);
+			}
+		} 
+		else 
+		{
+		  // some other receiver is registered under r->pathname().
+		  // the Reaper'd case.  maybe other cases?  noop is the correct response.
+		}
+	}
+	else
+	{
+			for (i = receivers_.begin(); i != receivers_.end() && i->second != r; i++) 
+				;
+			if (i != receivers_.end()) 
+			{
+				receivers_.erase(i);
+			}
+	}
+//     assert(receiver(r->pathname()) != r);
+}
+
+ossimPlanetActionReceiver* ossimPlanetActionRouter::receiver(const ossimString& receiverPathname) const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReceiverMutex);
+    ossimPlanetActionReceiver* result = NULL;
+    MapType::const_iterator r = receivers_.find(receiverPathname);
+    
+    if (r != receivers_.end())
+	result = r->second; 
+    
+//     assert(result == NULL || result->pathname() == receiverPathname);
+    
+    return result;
+}
+
+void ossimPlanetActionRouter::printReceivers()
+{
+    int i = 0;
+    MapType::iterator r;
+    
+    for (r = receivers_.begin(); r != receivers_.end(); r++)
+	std::cout << i++ << " = " << r->first << std::endl;
+}
+
+// ossimPlanetActionReceiver features
+
+void ossimPlanetActionRouter::execute(const ossimPlanetAction& action)
+{
+   const ossimPlanetDestinationCommandAction* a = action.toDestinationCommandAction();
+   // for now only support :destination command <args> style actions;
+   if(!a) return;
+   
+   ossimString command;
+   a->command(command);
+   if (command == "#") {
+	// this action is a comment, so do nothing
+    
+    } else if (command == "#syntaxerror") {
+	a->printError("illegal Action syntax");
+	
+    } else if (command == "echo") {
+	std::cout << a->argListSource() << std::endl;
+
+    } else if (command == "execfiles") {
+	for (unsigned int i = 1; i <= a->argCount(); i++)
+	    executeFile(a->arg(i));
+
+    } else if (command == "execactions") {
+	ossimPlanetDestinationCommandAction x;
+    	for (unsigned int i = 1; i <= a->argCount(); i++) {
+	    x.setSourceCode(a->arg(i));
+	    route(x);
+	}
+	
+    } else if (command == "shell") {
+	system(a->argListSource().c_str());
+
+    } 
+    else if (command == "manualaction") 
+    {
+       std::cout << "Enter action\n> " << std::flush;
+       ossimPlanetDestinationCommandAction x;
+        std::cin >> x;
+	route(x);
+
+    } else if (command == "printreceivers") {
+	printReceivers();
+
+    } else if (command == "setfederatename") {
+	if (a->argCount() == 1)
+	    setFederateName(a->arg(1));
+	else
+	    a->printError("bad argument count");
+        
+    }
+    else if (command == "opensocket")
+    {
+        if ((a->argCount() == 2 && isInt(a->arg(2))) || (a->argCount() == 3 && isInt(a->arg(2)) && isInt(a->arg(3)))) {
+            char delimiter = a->argCount() == 2 ? '\n' : static_cast<char>(asInt(a->arg(3)));
+	    ossimPlanetSocketNetworkConnection* s = new ossimPlanetSocketNetworkConnection(a->arg(1), asInt(a->arg(2)), delimiter);
+	    if (!s->error().empty()) {
+		a->printError("SocketNetworkConnection had this error: " + s->error());
+		delete s;
+	    } else
+		addNetworkConnection(s);
+	} else
+	    a->printError("bad argument count or type, needs one string (host) and one int (port) and optionally one string ('nul' or 'newline')");
+        
+    }
+    else if (command == "closesocket")
+    {
+	if (a->argCount() == 2 && isInt(a->arg(2)))
+        {
+            ossimString name = a->arg(1) + ":" + a->arg(2);
+	    ossimPlanetSocketNetworkConnection* s = dynamic_cast<ossimPlanetSocketNetworkConnection*>(networkConnection(name));
+	    if (s == NULL) 
+		a->printError("could not find a SocketNetworkConnection named: " + name);
+	    else
+		removeNetworkConnection(s->name());
+	    delete s;
+	}
+        else
+	    a->printError("bad argument count or type, needs one string (host) and one int (port)");
+        
+    }
+    else
+    {
+	a->printError("ActionRouter action not understood");
+    }
+}
+
+// protected
+
+
+ossimPlanetActionRouter* ossimPlanetActionRouter::instance_ = 0;
+
+ossimPlanetActionRouter::ossimPlanetActionRouter() :
+    federateName_("DefaultFederateName-")
+{
+    // NB: can't use setPathnameAndRegister here, it will trigger infinite
+    // recursive calls to this ctor since instance_ is still NULL right now.
+    setPathname(":");
+    registerReceiver(this);
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+    // Build a default process name that includes hostname and pid.
+    char buffer[MAXHOSTNAMELEN];
+    buffer[0] = '\0';
+    gethostname(buffer, MAXHOSTNAMELEN);
+    federateName_.append(buffer);
+	federateName_.append("-");
+#ifdef WIN32
+	federateName_.append(asString(GetCurrentProcessId()));
+#else
+	federateName_.append(asString(getpid()));
+#endif
+}
+
+ossimPlanetActionRouter::~ossimPlanetActionRouter()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReceiverMutex);
+   receivers_.clear();
+	if(theThreadQueue.valid())
+	{
+		theThreadQueue->cancel();
+	}
+    for (int i = 0; i < (int)network_.size(); i++)
+        delete network_[i];
+}
+
+void ossimPlanetActionRouter::remoteRouteImplementation(const ossimPlanetAction& a, const ossimString& destination)
+{
+    if (destination != federateName_)
+	for (int i = 0; i < (int)network_.size(); i++)
+	    network_[i]->send(a, destination);
+    
+    if (destination.empty() || destination == federateName_)
+        route(a);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetAnimatedPointModel.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetAnimatedPointModel.cpp
new file mode 100644
index 0000000..535b82c
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetAnimatedPointModel.cpp
@@ -0,0 +1,307 @@
+#include <ossimPlanet/ossimPlanetAnimatedPointModel.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+
+ossimPlanetAnimatedPointModel::ossimPlanetAnimatedPointModel()
+:theShowPathFlag(true),
+theShowModelFlag(true),
+theAnimationPathColor(1.0,0.0,0.0,.5),
+theAnimationPathLineThickness(2.0)
+{
+   setCullingActive(false);
+   thePathMatrixTransform = new osg::MatrixTransform();
+   thePathColor           = new osg::Vec4Array();
+   thePathVertices        = new osg::Vec3Array();
+   thePathGeode           = new osg::Geode();
+   thePathGeometry        = new osg::Geometry();
+   theLineWidth           = new osg::LineWidth(theAnimationPathLineThickness);
+   thePathColor->push_back(theAnimationPathColor);
+   // add the points geometry to the geode.
+   thePathGeode->addDrawable(thePathGeometry.get());
+   thePathMatrixTransform->addChild(thePathGeode.get());
+   
+   theAnimationPathCallback = new ossimPlanetAnimatedPointModel::PathCallback();
+}
+
+ossimPlanetAnimatedPointModel::~ossimPlanetAnimatedPointModel()
+{
+   if(thePointModel.valid())
+   {
+      thePointModel->setUpdateCallback(0);
+   }
+   if(theAnimationPathCallback.valid())
+   {
+      theAnimationPathCallback->setAnimationPath(0);
+   }
+}
+
+void ossimPlanetAnimatedPointModel::execute(const ossimPlanetAction& action)
+{
+   ossimPlanetAnnotationLayerNode::execute(action);
+}
+
+void ossimPlanetAnimatedPointModel::setAnimationPath(ossimPlanetAnimationPath* path)
+{
+   setDirtyBit((DirtyBit)(COLOR_DIRTY|COORDINATE_DIRTY)); // this will dirty everything so all is regenerated
+   theAnimationPath = path;
+   
+   theAnimationPathCallback->setAnimationPath(theAnimationPath.get());
+}
+
+void ossimPlanetAnimatedPointModel::setAnimationPathColor(const osg::Vec4f& value)
+{
+   setDirtyBit(COLOR_DIRTY); // this will rest color and thickness for the path
+   theAnimationPathColor = value;
+}
+
+void ossimPlanetAnimatedPointModel::setAnimationPathLineThickness(ossim_float32 value)
+{
+   setDirtyBit(COLOR_DIRTY);  // let's just reset color and thickness always
+   theAnimationPathLineThickness = value;
+}
+
+void ossimPlanetAnimatedPointModel::setShowPathFlag(bool flag)
+{
+   theShowPathFlag = flag;
+}
+
+void ossimPlanetAnimatedPointModel::setShowModelFlag(bool flag)
+{
+   theShowModelFlag = flag;
+}
+
+void ossimPlanetAnimatedPointModel::setPointModel(osg::Node* value)
+{
+   if(thePointModel.valid())
+   {
+      thePointModel->setUpdateCallback(0);
+      // need to test update callback to our animation update callback.
+      // thePointModel->getUpdateCallback();
+   }
+   thePointModel = value;
+   if(value)
+   {
+      value->setUpdateCallback(theAnimationPathCallback.get());
+   }
+}
+
+void ossimPlanetAnimatedPointModel::setTimeScale(ossim_float64 scale)
+{
+   theAnimationPathCallback->setTimeMultiplier(scale);
+}
+
+void ossimPlanetAnimatedPointModel::setTimeOffset(ossim_float64 offset)
+{
+   theAnimationPathCallback->setTimeOffset(offset);
+}
+
+void ossimPlanetAnimatedPointModel::traverse(osg::NodeVisitor& nv)
+{
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(theAnimationPath.valid()&&!theAnimationPath->geoRefModel())
+         {
+            if(layer()&&layer()->model())
+            {
+               theAnimationPath->setGeoRefModel(layer()->model());
+               // let's reset everything
+               setDirtyBit(COORDINATE_DIRTY);
+               setDirtyBit(COLOR_DIRTY);
+            }
+         }
+         if(isDirtyBitSet(COLOR_DIRTY))
+         {
+            updateColor();
+         }
+         if(isDirtyBitSet(COORDINATE_DIRTY))
+         {
+            updateCoordinates();
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   if(thePathVertices->size()>0)
+   {
+      if(nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
+      {
+         if(theShowPathFlag)
+         {
+            // draw the path
+            thePathMatrixTransform->accept(nv);
+         }
+      }
+      else
+      {
+         thePathMatrixTransform->accept(nv);
+      }
+   }
+   if(thePointModel.valid())
+   {
+      if(nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
+      {
+         if(theShowModelFlag)
+         {
+            thePointModel->accept(nv);
+         }
+      }
+      else
+      {
+         thePointModel->accept(nv);
+      }
+   }
+}
+
+void ossimPlanetAnimatedPointModel::stage()
+{
+   updateCoordinates();
+   updateColor();
+   setStagedFlag(true);
+}
+
+void ossimPlanetAnimatedPointModel::updateCoordinates()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateCoordinatesMutex);
+   if(theAnimationPath.valid())
+   {
+      ossimPlanetAnimationPath::PointList pointList;
+      theAnimationPath->generateWorldCoordinates(pointList);
+      bool updatePrimitiveSetFlag = false;
+      if(thePathVertices->size() != pointList.size())
+      {
+         updatePrimitiveSetFlag = true;
+         thePathVertices->resize(pointList.size());
+      }
+      ossim_uint32 idx = 0;
+      ossim_uint32 size = pointList.size();
+      ossim_float64 normalizer = 1.0/static_cast<ossim_float64>(size);
+      osg::Vec3d theCenter;
+      if(pointList.size())
+      {
+         theCenter = pointList[0]*normalizer;
+      }
+      for(idx=1; idx < size; ++idx)
+      {
+         theCenter += pointList[idx]*normalizer;
+      }
+      osg::Matrixd m;
+      m.setTrans(theCenter);
+      thePathMatrixTransform->setMatrix(m);
+      for(idx=0; idx < size; ++idx)
+      {
+         osg::Vec3f localPoint = pointList[idx] - theCenter;
+         (*thePathVertices)[idx] = localPoint;
+      }
+      thePathGeometry->setVertexArray(thePathVertices.get());
+      if(updatePrimitiveSetFlag)
+      {
+         if(thePathGeometry->getNumPrimitiveSets() > 0)
+         {
+            thePathGeometry->setPrimitiveSet(0, new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointList.size())); 
+         }
+         else
+         {
+            thePathGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,pointList.size())); 
+         }
+      }
+      
+      thePathGeode->dirtyBound();
+      thePathMatrixTransform->dirtyBound();
+   }
+   
+   clearDirtyBit(COORDINATE_DIRTY);
+}
+
+void ossimPlanetAnimatedPointModel::updateColor()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateColorMutex);
+   if(thePathColor->size() != 1)
+   {
+      thePathColor->push_back(theAnimationPathColor);
+   }
+   else
+   {
+      (*thePathColor)[0] = theAnimationPathColor;
+   }
+   osg::StateSet* stateset = thePathGeometry->getOrCreateStateSet();
+   theLineWidth->setWidth(theAnimationPathLineThickness);
+   thePathGeometry->setColorArray(thePathColor.get());
+   thePathGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+   stateset->setAttribute(theLineWidth.get());
+   
+   thePathGeometry->setUseVertexBufferObjects(true);
+   thePathGeometry->setUseDisplayList(false);
+//   thePathGeometry->setFastPathHint(true);
+   // for the path we will turn the lighting off
+   stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+   
+   stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
+   stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   
+   clearDirtyBit(COLOR_DIRTY);
+}
+
+
+ossimPlanetAnimatedPointModel::PathCallback::PathCallback()
+:osg::AnimationPathCallback()
+{
+   
+}
+ossimPlanetAnimatedPointModel::PathCallback::PathCallback(const PathCallback& apc,
+             const osg::CopyOp& copyop)
+:osg::AnimationPathCallback(apc, copyop)
+{
+}
+
+ossimPlanetAnimatedPointModel::PathCallback::PathCallback(osg::AnimationPath* ap,
+                                                          double timeOffset,
+                                                          double timeMultiplier)
+:osg::AnimationPathCallback(ap, timeOffset, timeMultiplier)
+{
+}
+
+void ossimPlanetAnimatedPointModel::PathCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+   ossimPlanetPointModel* pointModel = dynamic_cast<ossimPlanetPointModel*>(node);
+   ossimPlanetLsrSpaceTransform* lsrSpaceTransform = dynamic_cast<ossimPlanetLsrSpaceTransform*>(node);
+   if(pointModel||lsrSpaceTransform)
+   {
+      if (_animationPath.valid() && 
+          nv->getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR && 
+          nv->getFrameStamp())
+      {
+         double time = nv->getFrameStamp()->getSimulationTime();
+         // we might want to simulate both sim time and if real time by getting the first time to be real time
+         // but for now we will assume firstTime relative to 0 for sim time.
+         _latestTime = time;
+         _firstTime = 0.0;
+        
+         if (!_pause)
+         {
+            // Only update _firstTime the first time, when its value is still DBL_MAX
+            //if (_firstTime==DBL_MAX) _firstTime = time;
+            osg::AnimationPath::ControlPoint cp;
+            if(pointModel) lsrSpaceTransform = pointModel->lsrSpace();
+            if (_animationPath->getInterpolatedControlPoint(getAnimationTime(),cp))
+            {
+               osg::Matrixd m;
+               cp.getMatrix(m);
+               
+               lsrSpaceTransform->setMatrix(m);
+            }
+         }
+      }
+      
+      // must call any nested node callbacks and continue subgraph traversal.
+      NodeCallback::traverse(node,nv);
+   }
+   else
+   {
+      osg::AnimationPathCallback::operator()(node, nv);
+   }
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetAnimationPath.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetAnimationPath.cpp
new file mode 100644
index 0000000..d40767c
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetAnimationPath.cpp
@@ -0,0 +1,407 @@
+#include <ossimPlanet/ossimPlanetAnimationPath.h>
+#include <ossim/base/ossimXmlDocument.h>
+#include <osg/io_utils>
+#include <fstream>
+#include <sstream>
+
+ossimPlanetAnimationPath::ossimPlanetAnimationPath()
+{
+}
+
+bool ossimPlanetAnimationPath::openAnimationPathByXmlDocument(const ossimFilename& animationFile)
+{
+   std::ifstream in(animationFile.c_str());
+   if(in.good())
+   {
+      return setAnimationPathByXmlDocument(in);
+   }
+   
+   return false;
+}
+
+bool ossimPlanetAnimationPath::setAnimationPathByXmlDocument(const ossimString& xml)
+{
+   std::istringstream in(xml.c_str());
+   return setAnimationPathByXmlDocument(in);
+}
+
+bool ossimPlanetAnimationPath::setAnimationPathByXmlDocument(std::istream& xmlStream)
+{
+   bool result = false;
+   if(!xmlStream) return result;
+   
+   ossimXmlDocument document;
+   
+   if(document.read(xmlStream))
+   {
+      result = setAnimationPathByXmlNode(document.getRoot());
+   }
+   
+   return result;
+}
+
+bool ossimPlanetAnimationPath::openAnimationPathByXmlNode(const ossimFilename& animationFile)
+{
+   std::ifstream in(animationFile.c_str());
+   if(in.good())
+   {
+      return setAnimationPathByXmlNode(in);
+   }
+   
+   return false;
+}
+
+bool ossimPlanetAnimationPath::setAnimationPathByXmlNode(const ossimString& xml)
+{
+   std::istringstream in(xml.c_str());
+   return setAnimationPathByXmlNode(in);
+}
+
+bool ossimPlanetAnimationPath::setAnimationPathByXmlNode(std::istream& xmlStream)
+{
+   bool result = false;
+   if(!xmlStream) return result;
+   
+   ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+   
+   if(node->read(xmlStream))
+   {
+      result = setAnimationPathByXmlNode(node.get());
+   }
+   
+   return result;
+}
+
+
+ossimXmlNode* ossimPlanetAnimationPath::saveXml()const
+{
+   ossimXmlNode* root = new ossimXmlNode;
+   ossimXmlNode* coordinates = new ossimXmlNode;
+   ossimXmlNode* path = new ossimXmlNode;
+   root->setTag("AnimationPath");
+   path->setTag("GeospatialPath");
+   coordinates->setTag("coordinates");
+   path->setAttribute("timeUnit", "seconds", true);
+   path->setAttribute("positionType", "latlonhgt", true);
+   path->setAttribute("orientationType", "lsrhpr", true);
+   
+   path->addChildNode(coordinates);
+   
+   std::ostringstream coordinateList;
+   
+   root->addChildNode(path);
+   
+   TimeTupleMap::iterator iter    = thePath->timeTupleMap().begin();
+   TimeTupleMap::iterator endIter    = thePath->timeTupleMap().end();
+   while(iter!=endIter)
+   {
+      coordinateList << iter->first 
+      << "," << iter->second.position()[0]
+      << "," << iter->second.position()[1]
+      << "," << iter->second.position()[2]
+      << "," << iter->second.orientation()[0]
+      << "," << iter->second.orientation()[1]
+      << "," << iter->second.orientation()[2]
+      << "," << iter->second.scale()[0]
+      << "," << iter->second.scale()[1]
+      << "," << iter->second.scale()[2]
+      << " \n";
+      ++iter;
+   }
+   coordinates->setText(coordinateList.str());
+   
+   return root;
+}
+
+bool ossimPlanetAnimationPath::setAnimationPathByXmlNode(ossimRefPtr<ossimXmlNode> pathNode)
+{
+   bool result = true;
+   thePath = new GeospatialPath();
+   if((pathNode->getTag() == "AnimationPath"))
+   {
+      ossimRefPtr<ossimXmlNode> path        = pathNode->findFirstNode("GeospatialPath");
+      ossimRefPtr<ossimXmlNode> coordinates = pathNode->findFirstNode("GeospatialPath/coordinates");
+      if(coordinates.valid()&&path.valid())
+      {
+         ossimString timeUnit        = path->getAttributeValue("timeUnit");
+         ossimString positionType    = path->getAttributeValue("positionType");
+         ossimString orientationType = path->getAttributeValue("orientationType");
+         
+         // only support for now decoding relative time in seconds
+         // and lsr space type position and orientation.
+         //
+         if((timeUnit        == "seconds") &&
+            (positionType    == "latlonhgt") &&
+            (orientationType == "lsrhpr"))
+         {
+           std::istringstream in(coordinates->getText());
+            ossimString tuple = "";
+            while(in.good())
+            {
+               in >> ossim::skipws;
+               tuple = "";
+               while(in.good()&&!ossim::isWhiteSpace(in.peek()))
+               {
+                  tuple += static_cast<char>(in.get());
+               }
+               if(!tuple.empty())
+               {
+                  std::vector<ossimString> tupleValues;
+                  tuple.split(tupleValues, ",");
+                  if(tupleValues.size() >= 4) //time and position only
+                  {
+                     double t = tupleValues[0].toDouble(); // time
+                     osg::Vec3d pos(tupleValues[1].toDouble(), // positional
+                                    tupleValues[2].toDouble(),
+                                    tupleValues[3].toDouble());
+                     osg::Vec3d orient(0.0,0.0,0.0); // identity
+                     osg::Vec3d scale(1.0,1.0,1.0); // identity
+                     if(tupleValues.size() >= 7) // add orientation
+                     {
+                        orient = osg::Vec3d(tupleValues[4].toDouble(),
+                                            tupleValues[5].toDouble(),
+                                            tupleValues[6].toDouble());
+                        if(tupleValues.size()==10)  // add scale to the animation path
+                        {
+                           scale = osg::Vec3d(tupleValues[7].toDouble(),
+                                              tupleValues[8].toDouble(),
+                                              tupleValues[9].toDouble());
+                        }
+                     }
+                     thePath->timeTupleMap().insert(std::make_pair(t, Tuple(pos, orient, scale)));
+                  }
+                  else
+                  {
+                     result = false;
+                  }
+               }
+            }
+         }
+         else
+         {
+            result = false;
+         }
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   else
+   {
+      result = false;
+   }
+   
+   return result;
+}
+
+bool ossimPlanetAnimationPath::getInterpolatedControlPoint(double time,
+                                                           osg::AnimationPath::ControlPoint& controlPoint) const
+{
+   if(!theModel.valid()||!thePath.valid()||thePath->timeTupleMap().empty()) return false;
+   
+   time = adjustTime(time);
+   TimeTupleMap::const_iterator second = thePath->timeTupleMap().lower_bound(time);
+   if (second==thePath->timeTupleMap().begin())
+   {
+      // use the model to create the control point in osg form
+      //
+      osg::Quat q;
+      osg::Vec3d pos;
+      osg::Matrixd m;
+      
+      lsrMatrix(m, second->second);
+      m = osg::Matrixd::scale(second->second.scale())*m;
+      q.set(m);
+      pos.set(m(3,0), m(3,1), m(3,2));
+      controlPoint = ControlPoint(pos, q);
+   }
+   else if (second!=thePath->timeTupleMap().end())
+   {
+      TimeTupleMap::const_iterator first = second;
+      --first;        
+      
+      // we have both a lower bound and the next item.
+      
+      // delta_time = second.time - first.time
+      double delta_time = second->first - first->first;
+      
+      if (delta_time==0.0)
+      {
+         osg::Quat q;
+         osg::Vec3d pos;
+         osg::Matrixd m;
+         
+         lsrMatrix(m, first->second);
+         q.set(m);
+         pos.set(m(3,0), m(3,1), m(3,2));
+         controlPoint = ControlPoint(pos, q);
+      }
+      else
+      {
+         ControlPoint one, two;
+         osg::Quat q;
+         osg::Vec3d pos;
+         osg::Matrixd m;
+         
+         lsrMatrix(m, first->second);
+         q.set(m);
+         pos.set(m(3,0), m(3,1), m(3,2));
+         one = ControlPoint(pos, q);
+         lsrMatrix(m, second->second);
+         q.set(m);
+         pos.set(m(3,0), m(3,1), m(3,2));
+         two = ControlPoint(pos, q);
+         controlPoint.interpolate((time - first->first)/delta_time,
+                                  one,
+                                  two);
+      }   
+   }
+   else // (second==_timeControlPointMap.end())
+   {
+      osg::Quat q;
+      osg::Vec3d pos;
+      osg::Matrixd m;
+      
+      lsrMatrix(m, thePath->timeTupleMap().rbegin()->second);
+      q.set(m);
+      pos.set(m(3,0), m(3,1), m(3,2));
+      controlPoint = ControlPoint(pos, q);
+   }
+   return true;
+}
+
+double ossimPlanetAnimationPath::adjustTime(double t)const
+{
+   double time = t;
+   switch(_loopMode)
+   {
+      case(SWING):
+      {
+         double modulated_time = (time - thePath->firstTime())/(thePath->period()*2.0);
+         double fraction_part = modulated_time - floor(modulated_time);
+         if (fraction_part>0.5) fraction_part = 1.0-fraction_part;
+         
+         time = thePath->firstTime()+(fraction_part*2.0) * thePath->period();
+         break;
+      }
+      case(LOOP):
+      {
+         double modulated_time = (time - thePath->firstTime())/thePath->period();
+         double fraction_part = modulated_time - floor(modulated_time);
+         time = thePath->firstTime()+fraction_part * thePath->period();
+         break;
+      }
+      case(NO_LOOPING):
+         // no need to modulate the time.
+         break;
+   }
+   
+   return time;
+}
+
+void ossimPlanetAnimationPath::lsrMatrix(osg::Matrixd& result,
+                                         const Tuple& tuple)const
+{
+   osg::Vec3d position =  tuple.position();
+   theModel->mslToEllipsoidal(position); // adjust to ellipsoidal location
+   theModel->orientationLsrMatrix(result,
+                                  position,
+                                  tuple.orientation()[0],
+                                  tuple.orientation()[1],
+                                  tuple.orientation()[2]);
+   result = osg::Matrixd::scale(tuple.scale())*result;
+   
+}
+
+bool ossimPlanetAnimationPath::generateWorldCoordinates(PointList& worldPoints)const
+{
+   if(!theModel.valid()&&thePath.valid())
+   {
+      return false;
+   }
+   TimeTupleMap::const_iterator iter    = thePath->timeTupleMap().begin();
+   TimeTupleMap::const_iterator endIter = thePath->timeTupleMap().end();
+   
+   while(iter!=endIter)
+   {
+      osg::Vec3d worldPoint;
+      // convert Lat lon Height to world point
+      //
+      osg::Vec3d position(iter->second.position());
+      
+      // shift to ellipsoid
+      //
+      theModel->mslToEllipsoidal(position);
+      theModel->forward(position, worldPoint);
+      worldPoints.push_back(worldPoint);
+      
+      ++iter;
+   }
+   
+   return true;
+}
+
+bool ossimPlanetAnimationPath::generateModelCoordinates(PointList& modelPoints)const
+{
+   TimeTupleMap::const_iterator iter    = thePath->timeTupleMap().begin();
+   TimeTupleMap::const_iterator endIter = thePath->timeTupleMap().end();
+   
+   while(iter!=endIter)
+   {
+      modelPoints.push_back(iter->second.position());
+      ++iter;
+   }
+   
+   return true;
+}
+
+bool ossimPlanetAnimationPath::moveToLocationLatLon(const osg::Vec2d& llh)
+{
+   PointList worldPoints;
+   bool result = false;
+   if(generateWorldCoordinates(worldPoints)&&
+      (worldPoints.size()))
+   {
+      osg::Vec3d centerWorld;
+      ossim_uint32 idx = 0;
+      ossim_uint32 size = worldPoints.size();
+      for(idx = 0; idx < size; ++idx)
+      {
+         centerWorld += worldPoints[idx];
+      }
+      centerWorld *= (1.0/(double)size);
+      osg::Vec3d centerWorldLlh;
+      theModel->xyzToLatLonHeight(centerWorld, centerWorldLlh);
+      osg::Vec3d centerDistinationLlh(llh[0],
+                                      llh[1],
+                                      centerWorldLlh[2]);
+      
+      osg::Matrixd lsrSourceMatrix;
+      osg::Matrixd lsrDestinationMatrix;
+      theModel->lsrMatrix(centerWorldLlh, lsrSourceMatrix);
+      theModel->lsrMatrix(centerDistinationLlh, lsrDestinationMatrix);
+      
+      osg::Matrixd sourceInvert(osg::Matrixd::inverse(lsrSourceMatrix));
+      
+      for(idx = 0; idx < size; ++idx)
+      {
+         osg::Vec3d relative = worldPoints[idx]*sourceInvert;
+         osg::Vec3d newPoint = relative*lsrDestinationMatrix;
+         worldPoints[idx] = newPoint;
+      }
+      TimeTupleMap::iterator iter    = thePath->timeTupleMap().begin();
+      osg::Vec3d newModelPoint;
+      for(idx = 0; idx < size; ++idx)
+      {
+         theModel->xyzToLatLonHeight(worldPoints[idx], newModelPoint);
+         theModel->ellipsoidalToMsl(newModelPoint);
+         iter->second.setPosition(newModelPoint);
+         ++iter;
+      }
+      result = true;
+   }
+   
+   return result;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayer.cpp
new file mode 100644
index 0000000..c3d5817
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayer.cpp
@@ -0,0 +1,246 @@
+#include <ossimPlanet/ossimPlanetAnnotationLayer.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetNodeRegistry.h>
+#include <osgUtil/IntersectVisitor>
+#include <algorithm>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <OpenThreads/ScopedLock>
+
+
+ossimPlanetAnnotationLayer::ossimPlanetAnnotationLayer()
+{
+   theStagingThreadQueue = new ossimPlanetOperationThreadQueue;
+   theUpdateThreadQueue = new ossimPlanetOperationThreadQueue;
+	theDefaultIconImage = new osg::Image;
+	theDefaultIconImage->allocateImage(32, 32,  1, GL_RGBA, GL_UNSIGNED_BYTE);
+	memset(theDefaultIconImage->data(), 255, theDefaultIconImage->getImageSizeInBytes());
+	theDefaultIconTexture = new osg::Texture2D;
+	theDefaultIconTexture->setImage(theDefaultIconImage.get());
+	theDefaultIconTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture2D::NEAREST);
+	theDefaultIconTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture2D::NEAREST);
+	theDefaultIconTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+	theDefaultIconTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+	theDefaultIconTexture->setWrap(osg::Texture2D::WRAP_R, osg::Texture2D::CLAMP_TO_EDGE);
+	theDefaultIconTexture->setDataVariance(osg::Object::STATIC);
+	theDefaultFont = osgText::readFontFile("fonts/arial.ttf");
+
+	//theDefaultIconTexture->setResizeNonPowerOfTwoHint(true);
+}
+
+ossimPlanetAnnotationLayer::~ossimPlanetAnnotationLayer()
+{
+   theStagingThreadQueue = 0;
+}
+
+void ossimPlanetAnnotationLayer::traverse(osg::NodeVisitor& nv)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGraphMutex);
+   switch(nv.getVisitorType())
+	{
+		case osg::NodeVisitor::UPDATE_VISITOR:
+		{
+         {
+				OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNodesToRemoveListMutex);
+           ossimPlanetNode::NodeListType::iterator iter = theNodesToRemoveList.begin();
+            while(iter != theNodesToRemoveList.end())
+            {
+               ossimPlanetNode::remove((*iter).get());
+               ++iter;
+            }
+            theNodesToRemoveList.clear();
+         }
+			break;
+		}
+		default:
+		{
+			break;
+		}
+	}
+	ossimPlanetLayer::traverse(nv);
+}
+
+void ossimPlanetAnnotationLayer::execute(const ossimPlanetAction& action)
+{
+   std::string command = action.command();
+   const ossimPlanetXmlAction* xmlAction = action.toXmlAction();
+   if(command == "Add")
+   {
+      // we will use the add action to get the child
+      if(xmlAction&&xmlAction->xmlNode().valid()) 
+      {
+         const ossimXmlNode::ChildListType& children = xmlAction->xmlNode()->getChildNodes();
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < children.size(); ++idx)
+         {
+            ossimString tag = children[idx]->getTag();
+            ossimString parentId = children[idx]->getAttributeValue("parentId");
+            ossimString id = children[idx]->getChildTextValue("id");
+            if(!id.empty())
+            {
+               ossimPlanetLayerNameIdSearchVisitor nv("", id);
+               accept(nv);
+               if(nv.node().get())
+               {
+                  // already an id exists with that value so we return and don't add
+                  return;
+               }
+            }
+            osg::ref_ptr<ossimPlanetNode> layerNode;
+            if(tag != "Group")
+            {
+               layerNode = ossimPlanetNodeRegistry::instance()->create(tag);
+            }
+            if(!layerNode.valid()&&(tag == "Group"))
+            {
+               if(children[idx]->getAttributeValue("groupType")=="feature")
+               {
+                  layerNode = new ossimPlanetAnnotationGroupNode();
+               }
+            }
+            if(layerNode.valid())
+            {
+					osg::ref_ptr<ossimPlanetXmlAction> tempAction = xmlAction->duplicateChildAndMaintainAction(idx);
+					tempAction->setCommand("Set");
+					layerNode->setLayer(this);
+               layerNode->execute(*tempAction);
+            }
+				osg::ref_ptr<ossimPlanetAnnotationLayerNode> annotationNode = dynamic_cast<ossimPlanetAnnotationLayerNode*>(layerNode.get());
+            if(annotationNode.valid())
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGraphMutex);
+               if(!annotationNode->isStaged())
+               {
+                  theStagingThreadQueue->add(new ossimPlanetAnnotationLayer::Stager(annotationNode.get()));
+               }
+               ossimPlanetNode* parentNode=0;
+               if(!parentId.empty())
+               {
+                  ossimPlanetLayerNameIdSearchVisitor nv("", parentId);
+                  accept(nv);
+                  parentNode = dynamic_cast<ossimPlanetNode*>(nv.node().get());
+               }
+               
+               if(parentNode)
+               {
+                  parentNode->addChild(annotationNode.get());
+               }
+               else
+               {
+                  addChild(annotationNode.get());
+               }
+					setRedrawFlag(true);					
+            }
+         }
+      }
+   }
+   else if(command == "Set")
+   {
+      ossimString actionId = xmlAction->id();
+      if(!actionId.empty())
+      {
+         ossimPlanetLayerNameIdSearchVisitor idSearch;
+         idSearch.setId(actionId);
+         accept(idSearch);
+         ossimPlanetNode* node = dynamic_cast<ossimPlanetNode*>(idSearch.node().get());
+         if(node)
+         {
+            node->execute(action);
+         }
+      }
+      else
+      {
+         ossim_uint32 idx;
+         const ossimXmlNode::ChildListType& children = xmlAction->xmlNode()->getChildNodes();
+         for(idx = 0; idx < children.size(); ++idx)
+         {
+            ossimString id;
+            if(children[idx]->getAttributeValue(id, "id"))
+            {
+               ossimPlanetLayerNameIdSearchVisitor idSearch;
+               idSearch.setId(id);
+               accept(idSearch);
+               ossimPlanetNode* node = dynamic_cast<ossimPlanetNode*>(idSearch.node().get());
+               if(node)
+               {
+                  osg::ref_ptr<ossimPlanetXmlAction> tempAction = xmlAction->duplicateChildAndMaintainAction(idx);
+                  tempAction->setCommand("Set");
+                  node->execute(*tempAction);
+               }
+            }
+         }
+      }
+   }
+	else if(command == "Get")
+	{
+	}
+	else if(command == "Remove")
+	{
+		ossimString id; 
+		ossimString name;
+		// do short form
+		// <Remove id="">
+		if(!xmlAction->hasChildren())
+		{
+         ossimString id = xmlAction->id(); 
+         ossimString name = xmlAction->name();
+			if(!id.empty()||!name.empty())
+			{
+				removeByNameAndId(name, id);
+			}
+		}
+		else
+		{
+			const ossimXmlNode::ChildListType& children = xmlAction->xmlNode()->getChildNodes();
+			ossim_uint32 idx = 0;
+			for(idx = 0; idx < children.size();++idx)
+			{
+				name = children[idx]->getAttributeValue("name");
+				id   = children[idx]->getAttributeValue("id");
+            if(name.empty()&&id.empty())
+            {
+               name = children[idx]->getChildTextValue("name");
+               id   = children[idx]->getChildTextValue("id");
+            }
+				if(!name.empty()||!id.empty())
+				{
+					removeByNameAndId(name, id);
+				}
+			}
+		}
+	}
+}
+
+void ossimPlanetAnnotationLayer::removeByNameAndId(const ossimString& name, const ossimString& id)
+{
+   ossimPlanetLayerNameIdSearchVisitor nv(name, id);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGraphMutex);
+   accept(nv);
+   ossimPlanetNode* node = dynamic_cast<ossimPlanetNode*>(nv.node().get());
+   if(node)
+   {
+		needsRemoving(node);
+   }
+}
+
+void ossimPlanetAnnotationLayer::nodeAdded(osg::Node* /* node */)
+{
+}
+
+void ossimPlanetAnnotationLayer::nodeRemoved(osg::Node* /* node */)
+{
+}
+
+void ossimPlanetAnnotationLayer::needsRemoving(osg::Node* node)
+{
+	ossimPlanetNode* pNode = dynamic_cast<ossimPlanetNode*>(node);
+	if(pNode)
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNodesToRemoveListMutex);
+		// keep it around for next update removal
+		theNodesToRemoveList.push_back(pNode);
+	}
+	setRedrawFlag(true);
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayerNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayerNode.cpp
new file mode 100644
index 0000000..70f6ea2
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetAnnotationLayerNode.cpp
@@ -0,0 +1,557 @@
+#include <ossimPlanet/ossimPlanetAnnotationLayerNode.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetBillboardIcon.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetAnnotationLayer.h>
+#include <ossimPlanet/ossimPlanetIconGeom.h>
+#include <osgUtil/IntersectVisitor>
+#include <sstream>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+static inline void annotationAdjustHeight(osg::Vec3d& input,
+														ossimPlanetAltitudeMode mode,
+														ossimPlanetGeoRefModel* modelTransform)
+{
+	switch(mode)
+	{
+		case ossimPlanetAltitudeMode_CLAMP_TO_GROUND:
+		{
+			input[2] = modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+		case ossimPlanetAltitudeMode_RELATIVE_TO_GROUND:
+		{
+			input[2]+=modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+		case ossimPlanetAltitudeMode_ABSOLUTE:
+		{
+			input[2] += modelTransform->getGeoidOffset(input[0], input[2]);
+			break;
+		}
+		default:
+		{
+			input[2] = modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+	}			
+}
+
+class AnnotationUpdater : public ossimPlanetOperation
+	{
+	public:
+		AnnotationUpdater()
+		{}
+		AnnotationUpdater(ossimPlanetAnnotationPlacemark* placemark)
+		:theNode(placemark)
+		{
+			
+		}
+		virtual void run()
+		{
+			theNode->update();
+		}
+	protected:
+		osg::ref_ptr<ossimPlanetAnnotationPlacemark> theNode;
+	};
+
+
+
+ossimPlanetAnnotationLayerNode::ossimPlanetAnnotationLayerNode()
+:ossimPlanetNode(),
+theDirtyBit(NOT_DIRTY),
+theStagedFlag(false)
+{
+}
+
+void ossimPlanetAnnotationLayerNode::traverse(osg::NodeVisitor& nv)
+{
+   ossimPlanetNode::traverse(nv);
+}  
+
+
+void ossimPlanetAnnotationLayerNode::execute(const ossimPlanetAction& action)
+{
+	ossimPlanetNode::execute(action);
+}
+
+ossimPlanetAnnotationPlacemark::ossimPlanetAnnotationPlacemark()
+:ossimPlanetAnnotationLayerNode(),
+theLabelStyle(new ossimPlanetAnnotationLabelStyle)
+{
+}
+
+ossimPlanetAnnotationPlacemark::ossimPlanetAnnotationPlacemark(const osg::Vec3d& location,
+                                                               ossimPlanetAltitudeMode altitudeMode,
+                                                               const ossimString& nameStr,
+                                                               const ossimString& descriptionStr)
+:ossimPlanetAnnotationLayerNode(),
+theLabelStyle(new ossimPlanetAnnotationLabelStyle)
+{
+   setName(nameStr);
+   setDescription(descriptionStr);
+   ossimPlanetAnnotationPoint* point = new ossimPlanetAnnotationPoint(location);
+   point->setAltitudeMode(altitudeMode);
+   setGeometry(point);
+}
+
+void ossimPlanetAnnotationPlacemark::traverse(osg::NodeVisitor& nv)
+{
+	if(!enableFlag()) return;
+   if(!isStaged())
+   {
+      return;
+   }
+   bool needRedraw = false;
+	OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateMutex);
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+			if(isDirtyBitSet(LABEL_DIRTY)&&theLabel.valid())
+         {
+            needRedraw = true;
+            if(theLabel.valid())
+            {
+               theLabel->setText(name().c_str());
+            }
+				clearDirtyBit(LABEL_DIRTY);
+         }
+			if(isDirtyBitSet(COLOR_DIRTY))
+			{
+				if(theLabelStyle.valid()&&theLabel.valid())
+				{
+					needRedraw = true;
+					if(theLabelStyle->colorMode() == ossimPlanetAnnotationColorMode_NORMAL)
+					{
+						theLabel->setColor(theLabelStyle->color());
+					}
+					else
+					{
+						theLabel->setColor(osg::Vec4d((ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																(ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																(ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																theLabel->getColor()[3]));
+					}
+				}
+				clearDirtyBit(COLOR_DIRTY);
+			}
+         if(theExpireTime.valid())
+         {
+            if(theExpireTime->hasExpired())
+            {
+               if(theLayer)
+               {
+                  theLayer->needsRemoving(this);
+               }
+            }
+            needRedraw = true;
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   if(theExpireTime.valid())
+   {
+      setRedrawFlag(true);
+   }
+   osg::ref_ptr<ossimPlanetAnnotationGeometry> geom = geometry();
+   if(geom.valid())
+   {
+      geom->traverse(nv);
+   }
+   ossimPlanetAnnotationLayerNode::traverse(nv);
+   if(needRedraw) setRedrawFlag(true);
+}
+
+
+void ossimPlanetAnnotationPlacemark::execute(const ossimPlanetAction& action)
+{
+   std::string command = action.command();
+   const ossimPlanetXmlAction* xmlAction = action.toXmlAction();
+   ossimPlanetAnnotationLayerNode::execute(action);
+   if(command == "Set")
+   {
+		bool coordinateUpdating = false;
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateMutex);
+      if(xmlAction&&xmlAction->xmlNode().valid())
+      {
+         ossim_uint32 idx = 0;
+         const ossimXmlNode::ChildListType& childNodes = xmlAction->xmlNode()->getChildNodes();
+			const ossimXmlNode::ChildListType* properties = 0;
+			// at this point we should just have a single object in the first child of the set
+			//
+			if(childNodes.size() > 0)
+			{
+            if((childNodes[0]->getTag() == "Placemark")||
+               (childNodes[0]->getTag() == "Object"))
+            {
+               properties = &(childNodes[0]->getChildNodes());
+            }
+            else
+            {
+               properties = &childNodes;
+            }
+			}
+			if(!properties) return;
+         if(properties->size()==0)
+         {
+            properties = &childNodes; // we have direct properties first
+         }
+         for(idx = 0;idx<properties->size();++idx)
+         {
+            ossimString tag = (*properties)[idx]->getTag();
+            if(tag == "Style")
+            {
+               const ossimXmlNode::ChildListType& childStyleNodes = (*properties)[idx]->getChildNodes();  
+               ossim_uint32 styleIdx = 0;
+               for(styleIdx = 0;styleIdx<childStyleNodes.size();++styleIdx)
+               {
+                  if(childStyleNodes[styleIdx]->getTag() == "LabelStyle")
+                  {
+                     ossimString color     = childStyleNodes[styleIdx]->getChildTextValue("color").trim();
+                     ossimString colorMode = childStyleNodes[styleIdx]->getChildTextValue("colorMode").trim();
+                     ossimString scale     = childStyleNodes[styleIdx]->getChildTextValue("scale").trim();
+                     if(!color.empty())
+                     {
+                        std::vector<ossimString> colorValues;
+                        color.split(colorValues, " ");
+                        if(colorValues.size() == 4)
+                        {
+                           theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                              colorValues[1].toDouble(),
+                                                              colorValues[2].toDouble(),
+                                                              colorValues[3].toDouble()));
+                        }
+                        else if(colorValues.size() == 3)
+                        {
+                           theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                              colorValues[1].toDouble(),
+                                                              colorValues[2].toDouble(),
+                                                              1.0));
+                        }
+                        else if(colorValues.size() == 1)
+                        {
+                           theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                              colorValues[0].toDouble(),
+                                                              colorValues[0].toDouble(),
+                                                              1.0));
+                        }
+                     }
+                     if(!colorMode.empty())
+                     {
+                        if(colorMode == "random")
+                        {
+                           theLabelStyle->setColorMode(ossimPlanetAnnotationColorMode_RANDOM);
+                        }
+                        else if(colorMode == "normal")
+                        {
+                           theLabelStyle->setColorMode(ossimPlanetAnnotationColorMode_NORMAL);
+                        }
+                     }
+                  }
+               }
+               setDirtyBit(COLOR_DIRTY);
+               setRedrawFlag(true);
+            }
+            else if(tag == "color")
+            {
+               ossimString color = (*properties)[idx]->getText();
+               std::vector<ossimString> colorValues;
+               color.split(colorValues, " ");
+               if(colorValues.size() == 4)
+               {
+                  theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                     colorValues[1].toDouble(),
+                                                     colorValues[2].toDouble(),
+                                                     colorValues[3].toDouble()));
+               }
+               else if(colorValues.size() == 3)
+               {
+                  theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                     colorValues[1].toDouble(),
+                                                     colorValues[2].toDouble(),
+                                                     1.0));
+               }
+               else if(colorValues.size() == 1)
+               {
+                  theLabelStyle->setColor(osg::Vec4d(colorValues[0].toDouble(),
+                                                     colorValues[0].toDouble(),
+                                                     colorValues[0].toDouble(),
+                                                     1.0));
+               }
+               setDirtyBit(COLOR_DIRTY);
+               setRedrawFlag(true);
+            }
+            else if(tag == "description")
+            {
+               setDescription((*properties)[idx]->getText());
+            }
+            else if(tag == "name")
+            {
+               setName((*properties)[idx]->getText());
+               setDirtyBit(LABEL_DIRTY);
+               setRedrawFlag(true);
+            }
+            else if(tag == "coordinates")
+            {
+               ossimPlanetAnnotationPoint* pointGeom = dynamic_cast<ossimPlanetAnnotationPoint*>(theGeometry.get());
+               if(pointGeom)
+               {
+                  ossimString coordinates    = (*properties)[idx]->getText().trim();
+                  if(!coordinates.empty())
+                  {
+                     double lon=0.0, lat=0.0, hgt=0.0;
+                     ossimString coordinateStr;
+                     std::stringstream in(coordinates);
+                     in >> coordinateStr;
+                     std::vector<ossimString> splitArray;
+                     coordinateStr.split(splitArray, ",");
+                     if(splitArray.size() >1)
+                     {
+                        lon = splitArray[0].toDouble();
+                        lat = splitArray[1].toDouble();
+                        if(splitArray.size() > 2)
+                        {
+                           hgt = splitArray[2].toDouble();
+                        }
+                     }
+                     coordinateUpdating = true;
+                     setDirtyBit(COORDINATE_DIRTY);
+                     pointGeom->setCoordinate(osg::Vec3d(lat,lon,hgt));
+                     setRedrawFlag(true);
+                  }
+               }
+            }
+            else if(tag == "Point")
+            {
+					coordinateUpdating = true;
+               ossimPlanetAnnotationPoint* pointGeom = dynamic_cast<ossimPlanetAnnotationPoint*>(theGeometry.get());
+               if(!pointGeom)
+               {
+                  pointGeom = new ossimPlanetAnnotationPoint;
+                  theGeometry = pointGeom;
+               }
+               ossimString coordinates    = (*properties)[idx]->getChildTextValue("coordinates").trim();
+               ossimString altitudeMode   = (*properties)[idx]->getChildTextValue("altitudeMode").trim();
+               ossimString extrudeFlag    = (*properties)[idx]->getChildTextValue("extrude").trim();
+               if(!coordinates.empty())
+               {
+                  double lon=0.0, lat=0.0, hgt=0.0;
+                  ossimString coordinateStr;
+                  std::stringstream in(coordinates);
+                  in >> coordinateStr;
+                  std::vector<ossimString> splitArray;
+                  coordinateStr.split(splitArray, ",");
+                  if(splitArray.size() >1)
+                  {
+                     lon = splitArray[0].toDouble();
+                     lat = splitArray[1].toDouble();
+                     if(splitArray.size() > 2)
+                     {
+                        hgt = splitArray[2].toDouble();
+                     }
+                  }
+                  pointGeom->setCoordinate(osg::Vec3d(lat,lon,hgt));
+               }
+               ossimPlanetAltitudeMode mode = ossimPlanetAltitudeMode_NONE;
+               if(!altitudeMode.empty())
+               {
+                  if(altitudeMode.contains("clamp"))
+                  {
+                     mode = ossimPlanetAltitudeMode_CLAMP_TO_GROUND;
+                  }
+                  else if(altitudeMode.contains("relative"))
+                  {
+                     mode = ossimPlanetAltitudeMode_RELATIVE_TO_GROUND;
+                  }
+                  else if(altitudeMode.contains("absolute"))
+                  {
+                     mode = ossimPlanetAltitudeMode_ABSOLUTE;
+                  }
+               }
+               pointGeom->setAltitudeMode(mode);
+               if(extrudeFlag == "extrude")
+               {
+                  pointGeom->setExtrudeFlag(extrudeFlag.toBool());
+               }
+               setDirtyBit(COORDINATE_DIRTY);
+               setRedrawFlag(true);
+            }
+            else if(tag == "ExpireDuration")
+            {
+               ossimString value = (*properties)[idx]->getAttributeValue("value").trim();
+               ossimString units = (*properties)[idx]->getAttributeValue("units").trim();
+               if(!value.empty())
+               {
+                  ossimPlanetAnnotationExpireDuration* duration = new ossimPlanetAnnotationExpireDuration;
+                  duration->setDuration(value.toDouble());
+                  theExpireTime = duration;
+                  // right now we ignore units.  Will add that support later
+               }
+               else
+               {
+                  theExpireTime = 0;
+               }
+            }
+         }
+      }
+		if(isDirtyBitSet(COORDINATE_DIRTY)&&theStagedFlag)
+		{
+			if(geometry()->asPoint())
+			{
+				update();
+			}
+			else
+			{
+				ossimPlanetAnnotationLayer* l = dynamic_cast<ossimPlanetAnnotationLayer*>(layer());
+				if(l)
+				{
+					l->updateThreadQueue()->add(new AnnotationUpdater(this));
+				}
+				else
+				{
+					update();
+				}
+			}
+		}
+      setRedrawFlag(true);
+   }
+}
+
+void ossimPlanetAnnotationPlacemark::update()
+{
+	if(!layer()) return;
+	if(!theGeometry.valid()) return;
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = layer()->model();
+   
+	if(isDirtyBitSet(ossimPlanetAnnotationLayerNode::COORDINATE_DIRTY))
+	{
+		if(model.valid())
+		{
+			osg::ref_ptr<ossimPlanetAnnotationPoint> point = geometry()->asPoint();
+			if(point.valid())
+			{
+				osg::Matrixd localToWorld;
+				osg::Vec3d modelCoordinate;
+				osg::Vec3d normal;
+				osg::Vec3d localNormal;
+				osg::Vec3d coordinate = point->coordinate();
+				annotationAdjustHeight(coordinate, 
+											  point->altitudeMode(),
+											  model.get());
+				model->forward(coordinate, modelCoordinate);
+				normal = modelCoordinate;
+				normal.normalize();
+				point->setModelCoordinate(modelCoordinate);
+				model->lsrMatrix(coordinate, localToWorld);
+				osg::ref_ptr<osg::MatrixTransform> m = point->matrixTransform();
+				if(clusterCull().valid())
+				{
+					osg::Vec3d localNormal = osg::Matrixd::transform3x3(localToWorld, normal);
+					clusterCull()->set(osg::Vec3d(0.0,0.0,0.0), localNormal, 0.0, -1.0);
+				}
+				m->setMatrix(localToWorld);
+			}
+		}
+		clearDirtyBit(ossimPlanetAnnotationLayerNode::COORDINATE_DIRTY);
+		setRedrawFlag(true);
+	}
+}
+
+void ossimPlanetAnnotationPlacemark::stage()
+{
+	
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = layer()->model();
+	ossimPlanetAnnotationLayer* annotationLayer = dynamic_cast<ossimPlanetAnnotationLayer*>(theLayer);
+	if(annotationLayer)
+	{
+		if(annotationLayer->planet())
+		{
+			if(model.valid()&&geometry().valid())
+			{
+				osg::ref_ptr<ossimPlanetAnnotationPoint> point = geometry()->asPoint();
+				if(point.valid())
+				{
+					osg::Matrixd localToWorld;
+					osg::Vec3d modelCoordinate;
+					osg::Vec3d normal;
+					osg::Vec3d localNormal;
+					osg::Vec3d coordinate = point->coordinate();
+					annotationAdjustHeight(coordinate, 
+												  point->altitudeMode(),
+												  model.get());
+					model->forward(coordinate, modelCoordinate);
+					normal = modelCoordinate;
+					normal.normalize();
+					point->setModelCoordinate(modelCoordinate);
+					model->lsrMatrix(coordinate, localToWorld);
+					osg::MatrixTransform* m = new osg::MatrixTransform;
+					m->setMatrix(localToWorld);
+					{
+						OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateMutex);
+						osg::Vec3d localNormal = osg::Matrixd::transform3x3(localToWorld, normal);
+						theLabel = new ossimPlanetFadeText();
+						theLabel->setText(name());
+						theLabel->setFont(annotationLayer->defaultFont().get());
+						theLabel->setBackdropType(osgText::Text::OUTLINE);
+						osg::Vec3d textEcef(0.0,0.0,0.0);
+						theLabel->setPosition(textEcef);
+						theLabel->setCharacterSize(30000.0f/model->getNormalizationScale());
+						theLabel->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
+						theLabel->setAutoRotateToScreen(true);
+						theLabel->setAlignment(osgText::Text::CENTER_BOTTOM);
+						theClusterCull = new osg::ClusterCullingCallback(textEcef, localNormal, 0.0);
+						theLabel->setClusterCullingCallback(theClusterCull.get());
+						theLabelGeode = new ossimPlanetAnnotationTextGeode(this, theLabel.get());
+						theLabelGeode->addDrawable(theLabel.get());
+						theLabelGeode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+						m->addChild(theLabelGeode.get());
+						if(theLabelStyle->colorMode() == ossimPlanetAnnotationColorMode_NORMAL)
+						{
+							theLabel->setColor(theLabelStyle->color());
+						}
+						else
+						{
+							theLabel->setColor(osg::Vec4d((ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																	(ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																	(ossim_float64)rand()/(ossim_float64)RAND_MAX,
+																	theLabel->getColor()[3]));
+						}
+					}
+//					ossimPlanetBillboardIcon* icon = new ossimPlanetBillboardIcon;
+//					ossimPlanetIconGeom* geom = new ossimPlanetIconGeom;
+//					if(annotationLayer)
+//					{
+//						geom->setTexture(annotationLayer->defaultIconTexture().get());
+//					}
+//					icon->setGeom(geom);
+//					m->addChild(icon);
+					point->setMatrixTransform(m);
+               if(!lookAt().valid())
+               {
+                  setLookAt(new ossimPlanetLookAt(coordinate[0],
+                                                  coordinate[1],
+                                                  coordinate[2],
+                                                  0, 45, 0, 5000));
+               }
+				}
+			}
+		}
+	}
+   if(theExpireTime.valid())
+   {
+      theExpireTime->initTimeStamp();
+   }
+	clearDirtyBit(ALL_DIRTY);
+	setStagedFlag(true);
+}
+
+void ossimPlanetAnnotationPlacemark::setName(const ossimString& name)
+{
+   ossimPlanetAnnotationLayerNode::setName(name);
+	setDirtyBit(LABEL_DIRTY);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetApi.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetApi.cpp
new file mode 100644
index 0000000..e62ca2d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetApi.cpp
@@ -0,0 +1,1135 @@
+#include <ossimPlanet/ossimPlanetApi.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetLayerRegistry.h>
+#include <ossim/base/ossimMatrix4x4.h>
+#include <ossim/base/ossimTraceManager.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/plugin/ossimSharedPluginRegistry.h>
+#include <ossim/base/ossimGeoidManager.h>
+#include <ossim/base/ossimTrace.h>
+#include <ossim/base/ossimGeoidEgm96.h>
+#include <ossim/base/ossimGeoidNgs.h>
+#include <ossim/base/ossimPreferences.h>
+#include <ossim/init/ossimInit.h>
+#include <osgUtil/SceneView>
+#include <osgViewer/Viewer>
+#include <OpenThreads/Mutex>
+#include <OpenThreads/ScopedLock>
+#include <ossimPlanet/ossimPlanetManipulator.h>
+#include <osgGA/TerrainManipulator>
+#include <osgGA/TerrainManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgDB/Registry>
+#include <ossimPlanet/ul.h>
+#include <fstream>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetShaderProgramSetup.h>
+
+static OpenThreads::Mutex ossimPlanet_LayerListMutex;
+static ossim_uint64 ossimPlanet_initializationCount = 0;
+static ossimTrace traceDebug("ossimPlanetApi:debug");
+
+class ossimPlanetStateBase : public ossimPlanetActionReceiver
+   {
+   public:
+      ossimPlanetStateBase(ossimPlanet_ContextType type)
+      :theContextType(type),
+      thePlanet(new ossimPlanet)
+      {
+      }
+      virtual ~ossimPlanetStateBase()
+      {
+      }
+      ossimPlanet_ContextType contextType()const
+      {
+         return theContextType;
+      }
+      const osg::ref_ptr<ossimPlanetGeoRefModel> landModel()const
+      {
+         return thePlanet->model();
+      }
+      void setPlanet(ossimPlanet* planet)
+      {
+         thePlanet = planet;
+      }
+      osg::ref_ptr<ossimPlanet> planet()
+      {
+         return thePlanet;
+      }
+      const osg::ref_ptr<ossimPlanet> planet()const
+      {
+         return thePlanet;
+      }
+      virtual void setProjectionMatrix(const osg::Matrixd& m)=0;
+      virtual void setViewport(int x, int y, int w, int h)=0;
+      virtual void setViewMatrix(const osg::Matrixd& m) = 0;
+      virtual void setViewportClearColor(const osg::Vec4& color)=0;
+      virtual bool needsRendering()
+      {
+         if(thePlanet.valid())
+         {
+            return thePlanet->redrawFlag();
+         }
+         return false;
+      }
+      virtual bool frame()=0;
+      virtual void setSceneData(){}
+      virtual void setCameraManipulator(osg::ref_ptr<osgGA::CameraManipulator> m){}
+      
+      virtual void execute(const ossimPlanetAction& action)
+      {
+         ossimString command;
+         action.command(command);
+      }
+   protected:
+      ossimPlanet_ContextType theContextType;
+      osg::ref_ptr<ossimPlanet> thePlanet;
+   };
+
+#define ossimPlanetStateBaseCast(X) static_cast<ossimPlanetStateBase*>(X)
+#define ossimPlanetLayerCast(X) static_cast<ossimPlanetLayer*>(X)
+#define ossimPlanetCast(X) static_cast<ossimPlanet*>(X)
+
+class ossimPlanetStatePlanetOnly : public ossimPlanetStateBase
+{
+public:
+   ossimPlanetStatePlanetOnly()
+   :ossimPlanetStateBase(ossimPlanet_PLANET_ONLY_CONTEXT)
+   {
+   }
+   virtual void setProjectionMatrix(const osg::Matrixd& m)
+   {
+   }
+   virtual void setViewport(int x, int y, int w, int h)
+   {
+   }
+   virtual void setViewMatrix(const osg::Matrixd& m)
+   {
+   }
+   virtual void setViewportClearColor(const osg::Vec4& color)
+   {
+   }
+   virtual bool needsRendering()
+   {
+      return ossimPlanetStateBase::needsRendering();
+   }
+   virtual bool frame()
+   {
+      return false;
+   }   
+};
+
+class ossimPlanetStateSceneView : public ossimPlanetStateBase
+   {
+   public:
+      ossimPlanetStateSceneView()
+      :ossimPlanetStateBase(ossimPlanet_NOVIEWER_CONTEXT),
+      theSceneView(new osgUtil::SceneView),
+      theNeedsRedrawFlag(true)
+      {
+      }
+      virtual ~ossimPlanetStateSceneView()
+      {
+      }
+      virtual void setProjectionMatrix(const osg::Matrixd& m)
+      {
+         theNeedsRedrawFlag = true;
+         theSceneView->setProjectionMatrix(m);
+      }
+      virtual void setViewport(int x, int y, int w, int h)
+      {
+         theNeedsRedrawFlag = true;
+         theSceneView->setViewport(x, y, w, h);
+      }
+      virtual void setViewMatrix(const osg::Matrixd& m)
+      {
+         theNeedsRedrawFlag = true;
+         theSceneView->setViewMatrix(m);
+      }
+      virtual void setViewportClearColor(const osg::Vec4& color)
+      {
+         theNeedsRedrawFlag = true;
+         theSceneView->setClearColor(color);
+      }
+      virtual bool needsRendering()
+      {
+         return (theNeedsRedrawFlag||ossimPlanetStateBase::needsRendering());
+      }
+      virtual void setSceneData()
+      {
+         theNeedsRedrawFlag = true;
+         theSceneView->setSceneData(thePlanet.get());         
+      }
+      virtual bool frame()
+      {
+         theNeedsRedrawFlag = false;
+         theSceneView->update();
+         theSceneView->cull();
+         theSceneView->draw();
+         return true;
+      }
+      osg::ref_ptr<osgUtil::SceneView> sceneView()
+      {
+         return theSceneView.get();
+      }
+   protected:
+      osg::ref_ptr<osgUtil::SceneView> theSceneView;
+      bool theNeedsRedrawFlag;
+   };
+
+class ossimPlanetStateViewer : public ossimPlanetStateBase
+   {
+   public:
+      ossimPlanetStateViewer()
+         :ossimPlanetStateBase(ossimPlanet_VIEWER_CONTEXT),
+            theViewer(new ossimPlanetViewer)
+      {
+         theViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
+      }
+      virtual ~ossimPlanetStateViewer()
+      {
+      }
+      virtual void setProjectionMatrix(const osg::Matrixd& m)
+      {
+         theViewer->getCamera()->setProjectionMatrix(m);
+      }
+      virtual void setViewport(int x, int y, int w, int h)
+      {
+         theViewer->getCamera()->setViewport(x, y, w, h);
+      }
+      virtual void setViewMatrix(const osg::Matrixd& m)
+      {
+         theViewer->getCamera()->setViewMatrix(m);
+      }
+      virtual void setViewportClearColor(const osg::Vec4& color)
+      {
+         theViewer->getCamera()->setClearColor(color);
+      }
+      virtual bool needsRendering()
+      {
+         if(theManipulator.valid())
+         {
+            if(theManipulator->navigator()->needsContinuousUpdate())
+            {
+               return true;
+            }
+         }
+         return ossimPlanetStateBase::needsRendering();
+      }
+      virtual void setSceneData()
+      {
+         theViewer->setSceneData(thePlanet.get());
+      }
+      virtual bool frame()
+      {
+         
+         if (!theViewer->isRealized())
+         {
+            theViewer->realize();
+         }
+         
+         theViewer->frame();
+         
+         return !theViewer->done();
+      }
+      osg::ref_ptr<osgViewer::Viewer> viewer()
+      {
+         return theViewer;
+      }
+      virtual void setCameraManipulator(osg::ref_ptr<osgGA::CameraManipulator> m)
+      {
+         theManipulator = dynamic_cast<ossimPlanetManipulator*>(m.get());
+         theViewer->setCameraManipulator(m.get());
+      }
+   protected:
+      osg::ref_ptr<ossimPlanetManipulator> theManipulator;
+      osg::ref_ptr<osgViewer::Viewer> theViewer;
+   };
+
+// private utility functions
+static void ossimPlanetPrvt_fixReceiverPath(ossimString& pathName)
+{
+   if(!pathName.empty())
+   {
+      if(pathName[(ossimString::size_type)0] != ':')
+      {
+         pathName = ":" + pathName;
+      }
+   }
+}
+static void ossimPlanetPrvt_extractSeaparatedActions(std::vector<ossimString>& result,
+                                                     ossimPlanet_ConstStringType actions,
+                                                     ossimPlanet_ConstStringType separator)
+                                                   
+{
+   ossimString(actions).split(result, ossimString(separator));
+}
+
+// API definitions
+//
+void ossimPlanet_addOpenSceneGraphLibraryPath(ossimPlanet_ConstStringType path,
+                                              ossimPlanet_BOOL insertFrontFlag)
+{
+   if(!path) return;
+   if(insertFrontFlag != ossimPlanet_TRUE)
+   {
+      osgDB::Registry::instance()->getLibraryFilePathList().push_back(path);      
+   }
+   else
+   {
+      osgDB::Registry::instance()->getLibraryFilePathList().insert(osgDB::Registry::instance()->getLibraryFilePathList().begin(),
+                                                                   path);            
+   }
+}
+
+void ossimPlanet_addOpenSceneGraphDataPath(ossimPlanet_ConstStringType path,
+                                           ossimPlanet_BOOL insertFrontFlag)
+{
+   if(!path) return;
+   if(insertFrontFlag != ossimPlanet_TRUE)
+   {
+      osgDB::Registry::instance()->getDataFilePathList().push_back(path);      
+   }
+   else
+   {
+      osgDB::Registry::instance()->getDataFilePathList().insert(osgDB::Registry::instance()->getLibraryFilePathList().begin(),
+                                                                   path);            
+   }
+}
+
+void ossimPlanet_loadOssimPreferenceFile(ossimPlanet_ConstStringType preferenceFile)
+{
+   ossimPreferences::instance()->loadPreferences(ossimFilename(preferenceFile));
+}
+
+void ossimPlanet_setOssimPreferenceNameValue(ossimPlanet_ConstStringType name,
+                                             ossimPlanet_ConstStringType value)
+{
+   ossimPreferences::instance()->addPreference(name, value);   
+}
+
+void ossimPlanet_addOssimElevation(ossimPlanet_ConstStringType path)
+{
+   if(path&&ossimFilename(path).isDir())
+   {
+      ossimElevManager::instance()->loadElevationPath(path);
+   }
+}
+
+void ossimPlanet_addGeoid(ossimPlanet_ConstStringType path,
+                          ossimByteOrder byteOrder,
+                          ossimPlanet_BOOL insertFrontFlag)
+{
+   ossimFilename geoidFile = path;
+   if(path)
+   {
+      ossimRefPtr<ossimGeoid> geoid;
+      if(geoidFile.exists())
+      {
+         geoid = new ossimGeoidEgm96;
+         if(geoid->open(path, byteOrder))
+         {
+            ossimGeoidManager::instance()->addGeoid(geoid, insertFrontFlag==ossimPlanet_TRUE);
+         }
+         else
+         {
+            geoid = new ossimGeoidNgs;
+            if(geoid->open(path))
+            {
+               ossimGeoidManager::instance()->addGeoid(geoid, insertFrontFlag==ossimPlanet_TRUE);
+            }
+            else
+            {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_WARN) << "No grid handler found for path = " << ossimString(path) << "\n";
+               }
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanet_addOssimPlugin(ossimPlanet_ConstStringType path,
+                                ossimPlanet_BOOL insertFrontFlag)
+{
+   ossimFilename plugin(path);
+   if(plugin.exists())
+   {
+      if(plugin.isDir())
+      {
+         ossimDirectory dir;
+         if(dir.open(plugin))
+         {
+            ossimFilename file;
+            bool loadedPluginFlag = false;
+            if(dir.getFirst(file,
+                            ossimDirectory::OSSIM_DIR_FILES))
+            {
+               do
+               { 
+                  if(ossimSharedPluginRegistry::instance()->registerPlugin(file, insertFrontFlag==ossimPlanet_TRUE))
+                  {
+                     loadedPluginFlag=true;
+                  }
+               }
+               while(dir.getNext(file));
+            }
+            if(!loadedPluginFlag)
+            {
+               if(traceDebug())
+               {
+                  ossimNotify(ossimNotifyLevel_WARN) << "Unable find a plugin in directory " << file << "\n";
+               }               
+            }
+         }
+      }
+      else
+      {
+         if(!ossimSharedPluginRegistry::instance()->registerPlugin(plugin, insertFrontFlag==ossimPlanet_TRUE))
+         {
+            if(traceDebug())
+            {
+               ossimNotify(ossimNotifyLevel_WARN) << "Unable to load plugin " << plugin << "\n";
+            }
+         }
+      }
+   }
+   
+}
+
+void ossimPlanet_setTracePattern(ossimPlanet_ConstStringType pattern)
+{
+   ossimTraceManager::instance()->setTracePattern(ossimString(pattern));
+}
+
+void ossimPlanet_microSecondSleep(ossimPlanet_SizeType microSeconds)
+{
+   ulMicroSecondSleep((int)microSeconds);
+   
+}
+
+void ossimPlanet_milliSecondSleep(ossimPlanet_SizeType milliSeconds)
+{
+   ulMilliSecondSleep((int)milliSeconds);
+}
+
+void ossimPlanet_secondSleep(ossimPlanet_SizeType seconds)
+{
+   ulSleep((int)seconds);
+}
+
+ossimPlanet_StatePtr ossimPlanet_newState(ossimPlanet_ContextType type)
+{
+   switch(type)
+   {
+      case  ossimPlanet_PLANET_ONLY_CONTEXT:
+      {
+         return static_cast<ossimPlanet_StatePtr>(new ossimPlanetStatePlanetOnly());
+      }
+      case ossimPlanet_NOVIEWER_CONTEXT:
+      {
+         return static_cast<ossimPlanet_StatePtr>(new ossimPlanetStateSceneView());
+      }
+      case ossimPlanet_VIEWER_CONTEXT:
+      {
+         return static_cast<ossimPlanet_StatePtr>(new ossimPlanetStateViewer());         
+      }
+   }
+   // should never get to here
+   return static_cast<ossimPlanet_StatePtr>(0);
+}
+
+void ossimPlanet_setStateReceiverPathName(ossimPlanet_StatePtr state,
+                                          ossimPlanet_ConstStringType path)
+{
+   if(state)
+   {
+      ossimString pathName = path;
+      
+      ossimPlanetPrvt_fixReceiverPath(pathName);
+      ossimPlanetStateBaseCast(state)->setPathnameAndRegister(pathName);
+   }
+}
+
+void ossimPlanet_setPlanetReceiverPathName(ossimPlanet_StatePtr state,
+										   ossimPlanet_ConstStringType path)
+{
+	if(state)
+	{
+		ossimString pathName = path;
+		
+		ossimPlanetPrvt_fixReceiverPath(pathName);
+		ossimPlanetStateBaseCast(state)->planet()->setPathnameAndRegister(pathName);
+	}
+}
+
+void ossimPlanet_deleteState(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      delete ossimPlanetStateBaseCast(state);
+   }
+}
+
+void ossimPlanet_init()
+{
+   if(ossimPlanet_initializationCount == 0)
+   {
+      ossimInit::instance()->initialize();            
+   }
+   ++ossimPlanet_initializationCount;
+}
+
+void ossimPlanet_initWithArgs(int* argc, char** argv[])
+{
+   if(ossimPlanet_initializationCount == 0)
+   {
+      ossimInit::instance()->initialize(*argc, *argv);            
+   }
+   ++ossimPlanet_initializationCount;
+}
+
+void ossimPlanet_finalize()
+{
+   if(ossimPlanet_initializationCount > 0)
+   {
+      --ossimPlanet_initializationCount;
+   }
+   
+   // do cleanup if all users have finalized
+   //
+   if(ossimPlanet_initializationCount == 0)
+   {
+      ossimInit::instance()->finalize();            
+   }
+}
+
+ossimPlanet_PlanetPtr ossimPlanet_getNativePlanetPointer(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      return static_cast<ossimPlanet_PlanetPtr>(ossimPlanetStateBaseCast(state)->planet().get());
+   }
+   return static_cast<ossimPlanet_PlanetPtr>(0);
+}
+
+void ossimPlanet_setViewManipulator(ossimPlanet_StatePtr state,
+                                    ossimPlanet_ConstStringType typeName,
+                                    ossimPlanet_ConstStringType receiverPathName)
+{
+   ossimPlanetStateBase* base = ossimPlanetStateBaseCast(state);
+   if(base)
+   {
+      if(ossimString(typeName) == "ossimPlanetManipulator")
+      {
+         ossimPlanetManipulator* manipulator = new ossimPlanetManipulator();
+         
+         base->setCameraManipulator( manipulator );
+      }
+   }
+}
+
+void ossimPlanet_setLandFragShaderType(ossimPlanet_StatePtr state, ossimPlanetFragShaderType type)
+{
+#if 0
+   osg::ref_ptr<ossimPlanet> ptr = ossimPlanetStateBaseCast(state)->planet();
+   if(ptr.valid())
+   {
+      if(ptr->land().valid())
+      {
+         ossimPlanetShaderProgramSetup::ossimPlanetFragmentShaderType shaderType = ossimPlanetShaderProgramSetup::NO_SHADER;
+         switch(type)
+         {    
+            case ossimPlanet_NO_SHADER:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::NO_SHADER;
+               break;
+            }
+            case ossimPlanet_TOP:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::TOP;
+               break;
+            }
+            case ossimPlanet_REFERENCE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::REFERENCE;
+               break;
+            }
+            case ossimPlanet_OPACITY:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::OPACITY;
+               break;
+            }
+            case ossimPlanet_HORIZONTAL_SWIPE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::HORIZONTAL_SWIPE;
+               break;
+            }
+            case ossimPlanet_VERTICAL_SWIPE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::VERTICAL_SWIPE;
+               break;
+            }
+            case ossimPlanet_BOX_SWIPE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::BOX_SWIPE;
+               break;
+            }
+            case ossimPlanet_CIRCLE_SWIPE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::TOP;
+               break;
+            }
+            case ossimPlanet_ABSOLUTE_DIFFERENCE:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::CIRCLE_SWIPE;
+               break;
+            }
+            case ossimPlanet_FALSE_COLOR_REPLACEMENT:
+            {
+               shaderType = ossimPlanetShaderProgramSetup::FALSE_COLOR_REPLACEMENT;
+               break;
+            }
+         }
+         ptr->land()->setCurrentFragmentShaderType(shaderType);
+      }
+   }
+#endif
+}
+
+
+void ossimPlanet_setSceneDataToView(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->setSceneData();
+   }
+}
+
+void setViewTransformationsToCurrentGlSettings(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      GLint viewParams[4]; 
+      GLdouble glMat[16]; 
+      osg::Matrix m;
+      
+      glGetIntegerv(GL_VIEWPORT, viewParams); 
+      ossimPlanetStateBaseCast(state)->setViewport(viewParams[0], 
+                                                   viewParams[1], 
+                                                   viewParams[2], 
+                                                   viewParams[3]); 
+      
+      glGetDoublev(GL_PROJECTION_MATRIX, glMat); 
+      m.set( glMat ); 
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix( m );
+      //    double fov, aspect, znear, zfar;
+      //    globalSettings.theSceneView3d->getProjectionMatrixAsPerspective(fov, aspect, znear, zfar);
+      //    std::cout << "fov = " << fov << " aspect = " << aspect << " zn = " << znear << " zf = " << zfar << std::endl;
+      
+      glGetDoublev( GL_MODELVIEW_MATRIX, glMat ); 
+      m.set( glMat ); 
+      ossimPlanetStateBaseCast(state)->setViewMatrix( m );
+   }
+}
+
+void ossimPlanet_setProjectionMatrixAsPerspective(ossimPlanet_StatePtr state,
+                                                  double fovValue,
+                                                  double aspectRatioValue,
+                                                  double nearValue, 
+                                                  double farValue)
+{
+   if(state)
+   {
+      osg::Matrixd m;
+	  m.makePerspective(fovValue, aspectRatioValue, nearValue, farValue);
+      //m.makePerspective(fov, aspectRatio, near, far);
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(m);
+   }
+}
+
+void ossimPlanet_setProjectionMatrixAsFrustum(ossimPlanet_StatePtr state,
+                                              double left, double right,
+                                              double bottom, double top,
+                                              double zNear, double zFar)
+{
+   if(state)
+   {
+      osg::Matrixd m;
+      m.makeFrustum(left, right, bottom, top, zNear, zFar);
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(m);
+   }
+}
+
+void ossimPlanet_setProjectionMatrixAsOrtho(ossimPlanet_StatePtr state,
+                                            double left, double right,
+                                            double bottom, double top,
+                                            double zNear, double zFar)
+{
+   if(state)
+   {
+      osg::Matrixd m;
+      m.makeOrtho(left, right, bottom, top, zNear, zFar);
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(m);
+   }   
+}
+
+void ossimPlanet_setProjectionMatrixAsOrtho2D(ossimPlanet_StatePtr state,
+                                              double left, double right,
+                                              double bottom, double top)
+{
+   if(state)
+   {
+      osg::Matrixd m;
+      m.makeOrtho2D(left, right, bottom, top);
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(m);      
+   }
+}
+
+void ossimPlanet_setProjectionMatrixAsRowOrderedArray(ossimPlanet_StatePtr state,
+                                                      double* m)
+{
+   if(state&&m)
+   {
+      osg::Matrixd mResult;
+      mResult.set(m);
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(mResult);
+   }
+}
+
+void ossimPlanet_setProjectionMatrix(ossimPlanet_StatePtr state,
+                                     double m00, double m01, double m02, double m03,
+                                     double m10, double m11, double m12, double m13,
+                                     double m20, double m21, double m22, double m23,
+                                     double m30, double m31, double m32, double m33)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->setProjectionMatrix(osg::Matrixd(m00, m01, m02, m03,
+                                                                        m10, m11, m12, m13,
+                                                                        m20, m21, m22, m23,
+                                                                        m30, m31, m32, m33));      
+   }
+}
+void ossimPlanet_setViewMatrixAsLlhHprRelativeTangent(ossimPlanet_StatePtr state,
+                                                      double lat,
+                                                      double lon,
+                                                      double height,
+                                                      double heading,
+                                                      double pitch,
+                                                      double roll)
+{
+   if(state)
+   {
+      const osg::ref_ptr<ossimPlanetGeoRefModel> model = ossimPlanetStateBaseCast(state)->landModel();
+      if(!model.valid()) return;
+      osg::Matrixd output;
+      osg::Vec3d xyz;
+      model->forward(osg::Vec3d(lat, lon, height),
+                     xyz);
+
+      model->lsrMatrix(osg::Vec3d(lat, lon, height),
+                       output,
+                       heading);
+      output(3,0) = 0.0;
+      output(3,1) = 0.0;
+      output(3,2) = 0.0;
+      
+      
+      NEWMAT::Matrix orien = (ossimMatrix4x4::createRotationXMatrix(pitch, OSSIM_LEFT_HANDED)*
+                              ossimMatrix4x4::createRotationYMatrix(roll, OSSIM_LEFT_HANDED));
+      // now transpose since ossim matrix is column oriented and OSG is row oriented
+      osg::Matrixd tempM(orien[0][0], orien[1][0], orien[2][0], 0.0,
+                         orien[0][1], orien[1][1], orien[2][1], 0.0,
+                         orien[0][2], orien[1][2], orien[2][2], 0.0,
+                         0.0, 0.0, 0.0, 1.0);
+      
+      ossimPlanetStateBaseCast(state)->setViewMatrix(osg::Matrix::inverse(tempM*output*osg::Matrixd::translate(xyz[0], xyz[1], xyz[2])));
+   }
+}
+
+void ossimPlanet_setViewMatrixAsRowOrderedArray(ossimPlanet_StatePtr state,
+                                                const double *m)
+{
+   if(state)
+   {
+      osg::Matrixd mResult;
+      mResult.set(m);
+      ossimPlanetStateBaseCast(state)->setViewMatrix(mResult);
+   }
+}
+
+void ossimPlanet_setViewMatrix(ossimPlanet_StatePtr state,
+                               double m00, double m01, double m02, double m03,
+                               double m10, double m11, double m12, double m13,
+                               double m20, double m21, double m22, double m23,
+                               double m30, double m31, double m32, double m33)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->setViewMatrix(osg::Matrixd(m00, m01, m02, m03,
+                                                                        m10, m11, m12, m13,
+                                                                        m20, m21, m22, m23,
+                                                                        m30, m31, m32, m33));      
+   }   
+}
+
+void ossimPlanet_setViewport(ossimPlanet_StatePtr state,
+                             int x, 
+                             int y, 
+                             int w, 
+                             int h)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->setViewport(x, y, w, h);
+   }
+}
+
+void ossimPlanet_setViewportClearColor(ossimPlanet_StatePtr state,
+                                       float red,
+                                       float green,
+                                       float blue,
+                                       float alpha)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->setViewportClearColor(osg::Vec4(red, green, blue, alpha));
+   }
+}
+
+ossimPlanet_BOOL ossimPlanet_renderFrame(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      ossimPlanetStateBaseCast(state)->planet()->resetAllRedrawFlags();
+      return ossimPlanetStateBaseCast(state)->frame()?ossimPlanet_TRUE:ossimPlanet_FALSE;
+   }
+   return ossimPlanet_FALSE;
+}
+
+ossimPlanet_BOOL ossimPlanet_renderFramePreserveState(ossimPlanet_StatePtr state)
+{
+   ossimPlanet_BOOL result = ossimPlanet_TRUE;
+	
+	ossimPlanet_pushState();
+	result = ossimPlanet_renderFrame(state);
+	ossimPlanet_popState();
+
+   return result;
+}
+
+ossimPlanet_BOOL ossimPlanet_needsRendering(ossimPlanet_StatePtr state)
+{
+   if(state)
+   {
+      return ossimPlanetStateBaseCast(state)->needsRendering()?ossimPlanet_TRUE:ossimPlanet_FALSE;
+   }   
+   
+   return ossimPlanet_FALSE;
+}
+
+void ossimPlanet_pushState()
+{
+   glPushAttrib(GL_ALL_ATTRIB_BITS);
+   glMatrixMode(GL_PROJECTION);
+   glPushMatrix();
+   glMatrixMode(GL_MODELVIEW);
+   glPushMatrix();
+   glMatrixMode(GL_TEXTURE);
+   glPushMatrix();
+}
+
+void ossimPlanet_popState()
+{
+   glMatrixMode(GL_TEXTURE);
+   glPopMatrix();
+   glMatrixMode(GL_MODELVIEW);
+   glPopMatrix();
+   glMatrixMode(GL_PROJECTION);
+   glPopMatrix();
+   glPopAttrib();   
+}
+
+ossimPlanet_LayerPtr ossimPlanet_addLayer(ossimPlanet_StatePtr state,
+                                          ossimPlanet_ConstStringType layerType,
+                                          ossimPlanet_ConstStringType name,
+                                          ossimPlanet_ConstStringType id,
+                                          ossimPlanet_ConstStringType description,
+                                          ossimPlanet_ConstStringType receiverPathName)
+{
+   ossimPlanet_LayerPtr result = 0;
+   if(state)
+   {
+      osg::ref_ptr<ossimPlanetLayer> layer = ossimPlanetLayerRegistry::instance()->create(ossimString(layerType));
+      if(layer.valid())
+      {
+         ossimPlanet_setLayerName(static_cast<ossimPlanet_LayerPtr>(layer.get()), name);
+         ossimPlanet_setLayerId(static_cast<ossimPlanet_LayerPtr>(layer.get()), id);
+         ossimPlanet_setLayerDescription(static_cast<ossimPlanet_LayerPtr>(layer.get()), description);
+         ossimPlanet_setLayerReceiverPathName(static_cast<ossimPlanet_LayerPtr>(layer.get()), receiverPathName);
+         result = static_cast<ossimPlanet_LayerPtr>(layer.get());
+         ossimPlanet_LayerListMutex.lock();
+         ossimPlanetStateBaseCast(state)->planet()->addChild(layer.get());
+         ossimPlanet_LayerListMutex.unlock();
+      }
+   }
+   
+   return result;
+}
+
+OSSIMPLANET_DLL void ossimPlanet_removeLayerGivenPtr(ossimPlanet_StatePtr state,
+                                                     ossimPlanet_LayerPtr layerPtr)
+{
+   ossimPlanet_IndexType idx = ossimPlanet_getIndexOfLayerGivenPtr(state, layerPtr);
+   if(idx != ossimPlanet_INVALID_INDEX)
+   {
+      ossimPlanet_LayerListMutex.lock();
+      ossimPlanetStateBaseCast(state)->planet()->removeChildren(idx, 1);
+      ossimPlanet_LayerListMutex.unlock();
+   }
+}
+
+ossimPlanet_SizeType ossimPlanet_getNumberOfLayers(ossimPlanet_StatePtr state)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(state)
+   {
+      return static_cast<ossimPlanet_SizeType>(ossimPlanetStateBaseCast(state)->planet()->getNumChildren());
+   }
+   
+   return 0;
+}
+
+ossimPlanet_IndexType ossimPlanet_getIndexOfLayerGivenPtr(ossimPlanet_StatePtr state,
+                                                          ossimPlanet_LayerPtr layerPtr)
+{
+   ossimPlanet_IndexType result = ossimPlanet_INVALID_INDEX;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   
+   if(state&&layerPtr)
+   {
+      ossimPlanet* planet         = ossimPlanetStateBaseCast(state)->planet().get();
+      ossimPlanetLayer* layerTest = ossimPlanetLayerCast(layerPtr);
+      if(!planet) return result;
+      ossim_uint32 idx    = 0;
+      ossim_uint32 upperIndex = planet->getNumChildren();
+      for(; ((idx < upperIndex)&&(result == ossimPlanet_INVALID_INDEX));++idx)
+      {
+         ossimPlanetLayer* l = dynamic_cast<ossimPlanetLayer*>(planet->getChild(idx));
+         if(l == layerTest)
+         {
+            result = idx;
+         }
+      }
+   }
+   
+   return result;
+}
+
+ossimPlanet_LayerPtr ossimPlanet_getLayerGivenIndex(ossimPlanet_StatePtr state,
+                                                    ossimPlanet_IndexType idx)
+{
+   ossimPlanet_LayerPtr result = 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+  
+   if(state&&(idx>=0))
+   {
+      ossimPlanet* planet         = ossimPlanetStateBaseCast(state)->planet().get();
+      if(!planet) return result;
+      if(idx < static_cast<ossimPlanet_IndexType>(planet->getNumChildren()))
+      {
+         result = dynamic_cast<ossimPlanetLayer*>(planet->getChild(idx));
+      }
+   }   
+   
+   return result;
+}
+
+ossimPlanet_LayerPtr ossimPlanet_getLayerGivenId(ossimPlanet_StatePtr state,
+                                                 ossimPlanet_ConstStringType id)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   ossimPlanet_LayerPtr result = 0;
+   ossimString idString(id);
+   
+   if(state&&!idString.empty())
+   {
+      ossimPlanet* planet         = ossimPlanetStateBaseCast(state)->planet().get();
+      if(!planet) return result;
+      ossim_uint32 idx    = 0;
+      ossim_uint32 upperIndex = planet->getNumChildren();
+      for(; ((idx < upperIndex)&&(result==0));++idx)
+      {
+         ossimPlanetLayer* l = dynamic_cast<ossimPlanetLayer*>(planet->getChild(idx));
+         if(l&&l->id()==idString)
+         {
+            result = l;
+         }
+      }      
+   }
+   
+   return result;
+}
+
+void ossimPlanet_setLayerId(ossimPlanet_LayerPtr layer,
+                            ossimPlanet_ConstStringType id)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+      ossimPlanetLayerCast(layer)->setId(ossimString(id));
+   }
+}
+
+void ossimPlanet_setLayerName(ossimPlanet_LayerPtr layer,
+                              ossimPlanet_ConstStringType name)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+      ossimPlanetLayerCast(layer)->setName(ossimString(name));
+   }   
+}
+
+void ossimPlanet_setLayerDescription(ossimPlanet_LayerPtr layer,
+                                     ossimPlanet_ConstStringType description)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+      ossimPlanetLayerCast(layer)->setDescription(ossimString(description));
+   }   
+}
+
+
+void ossimPlanet_setLayerReceiverPathName(ossimPlanet_LayerPtr layer,
+                                          ossimPlanet_ConstStringType receiverPathName)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+      ossimString pathName = receiverPathName;
+      ossimPlanetPrvt_fixReceiverPath(pathName);
+      if(!pathName.empty())
+      {
+         ossimPlanetLayerCast(layer)->setPathnameAndRegister(pathName);
+      }
+   }      
+}
+
+ossimPlanet_BOOL ossimPlanet_getLayerEnableFlag(ossimPlanet_LayerPtr layer)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+     bool flag = ossimPlanetLayerCast(layer)->enableFlag();
+		
+		return flag?ossimPlanet_TRUE:ossimPlanet_FALSE;
+   }      
+	return ossimPlanet_FALSE;
+}
+
+void ossimPlanet_setLayerEnableFlag(ossimPlanet_LayerPtr layer, 
+												ossimPlanet_BOOL flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(ossimPlanet_LayerListMutex);
+   if(layer)
+   {
+		ossimPlanetLayerCast(layer)->setEnableFlag(flag==ossimPlanet_TRUE);
+	}
+}
+
+void  ossimPlanet_addImageToReceiver(ossimPlanet_ConstStringType location,
+                                     ossimPlanet_ConstStringType receiverName,
+												 ossimPlanet_BOOL addInTheBackgroundFlag)
+{
+	ossimFilename loc(location);
+	if(!loc.exists()) return;
+	
+	if(loc.isDir())
+	{
+		ossimFilename file;
+		ossimDirectory dir(location);
+		if(dir.getFirst(file, ossimDirectory::OSSIM_DIR_FILES))
+		{
+			do
+			{
+				if((file.ext() != "his")&&
+					(file.ext() != "ovr"))
+				{
+               ossimString action;
+               
+               action += "<Add target=\""+ossimString(receiverName)+"\">";
+               action += "<Image>";
+               action += ossimString("<id>")+ossimString(file)+ossimString("</id>");
+               action += ossimString("<name>")+ossimString(file)+ossimString("</name>");
+               action += ossimString("<filename>")+ossimString(file)+ossimString("</filename>");
+               action += "</Image>";
+               action += "</Add>";
+					if(addInTheBackgroundFlag == ossimPlanet_TRUE)
+					{
+						ossimPlanet_postXmlAction(action.c_str());
+					}
+					else
+					{
+						ossimPlanet_executeXmlAction(action.c_str());
+					}
+				}
+			}while(dir.getNext(file));
+		}
+	}
+	else
+	{
+      ossimString action;
+      
+      action += "<Add target=\""+ossimString(receiverName)+"\">";
+      action += "<Image>";
+      action += ossimString("<id>")+ossimString(location)+ossimString("</id>");
+      action += ossimString("<name>")+ossimString(location)+ossimString("</name>");
+      action += ossimString("<filename>")+ossimString(location)+ossimString("</filename>");
+      action += "</Image>";
+      action += "</Add>";
+		
+      if(addInTheBackgroundFlag == ossimPlanet_TRUE)
+      {
+         ossimPlanet_postXmlAction(action.c_str());
+      }
+      else
+      {
+         ossimPlanet_executeXmlAction(action.c_str());
+      }
+	}
+}
+
+OSSIMPLANET_DLL void ossimPlanet_addTextureLayersFromKwlFile(ossimPlanet_StatePtr state,
+                                                             const char* kwlFile)
+{
+#if 0
+   ossimKeywordlist kwl;
+   kwl.addFile(kwlFile);
+   
+   osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(kwl.toString());
+   if(layer.valid())
+   {
+      ossimPlanetStateBaseCast(state)->planet()->land()->referenceLayer()->addTop(layer.get());
+   }
+#endif
+}
+
+
+void ossimPlanet_executeXmlAction(ossimPlanet_ConstStringType completeAction)
+{
+   ossimPlanetXmlAction(completeAction).execute();
+}
+
+void ossimPlanet_postXmlAction(ossimPlanet_ConstStringType completeAction)
+{
+   ossimPlanetXmlAction(completeAction).post();
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetArchive.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetArchive.cpp
new file mode 100755
index 0000000..af613d4
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetArchive.cpp
@@ -0,0 +1,199 @@
+
+#include <ossim/base/ossimNotify.h>
+#include <ossimPlanet/ossimPlanetArchive.h>
+
+
+
+ossimPlanetArchive::ossimPlanetArchive()
+{	
+	useArchiveMapping = false;
+}
+
+ossimPlanetArchive::~ossimPlanetArchive()
+{
+}
+
+void ossimPlanetArchive::addMapping(ossimPlanetArchiveMapping &mapping)
+{
+	OpenThreads::ScopedLock<ossimPlanetReentrantMutex> lock(theArchiveMutex);
+
+	// test to see if the mapping has an ending slash... if not add one
+	ossimFilename src = mapping.getSource();
+	ossimFilename dest = mapping.getDestination();
+
+	src = convertToDirectory(src);
+	dest = convertToDirectory(dest);
+
+	mapping.setSource(src);
+	mapping.setDestination(dest);
+
+	mappingList.push_back(mapping);
+}
+
+
+ossimFilename ossimPlanetArchive::convertToDirectory(ossimFilename &filename)
+{
+	ossimString drive;
+	ossimString path;
+	ossimString file;
+	ossimString ext;
+
+	filename.split(drive, path, file, ext);
+
+	// if the drive is empty its a unix/linux drive
+	if( drive.empty() )
+	{
+		return (filename[filename.length()-1] != '/')? ossimFilename(filename.append("/")) : filename;
+	}
+	// else its a windows drive
+	else
+	{
+		return (filename[filename.length()-1] != '\\')? ossimFilename(filename.append("\\")) : filename;		
+	}
+}
+
+
+void ossimPlanetArchive::removeMapping(ossimPlanetArchiveMapping &mapping)
+{
+	OpenThreads::ScopedLock<ossimPlanetReentrantMutex> lock(theArchiveMutex);
+	ossim_uint32 row = 0;
+	for( row = 0; row < mappingList.size(); row++ )
+	{		
+		if( (mapping.getSource() == mappingList[row].getSource()) && 
+         (mapping.getDestination() == mappingList[row].getDestination()) )
+		{
+			break;
+		}
+	}
+
+	if( row < mappingList.size() )
+	{
+		mappingList.erase(mappingList.begin() + row);
+	}
+}
+
+ossimFilename ossimPlanetArchive::matchPath(const ossimFilename &filename)
+{
+	OpenThreads::ScopedLock<ossimPlanetReentrantMutex> lock(theArchiveMutex);
+	std::vector<ossimPlanetArchiveMapping>::iterator it;
+
+	if( mappingList.empty() || filename.exists() )
+		return filename;
+
+	ossimString file_drive;
+	ossimString file_path;
+	ossimString file_file;
+	ossimString file_ext;
+	
+	ossimString src_drive;
+	ossimString src_path;
+	ossimString src_file;
+	ossimString src_ext;
+	
+	ossimString dest_drive;
+	ossimString dest_path;
+	ossimString dest_file;
+	ossimString dest_ext;
+
+	ossimFilename src;
+	ossimFilename dest;
+
+	filename.split(file_drive, file_path, file_file, file_ext);
+	ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - filename split: drive=" << file_drive << " path=" << file_path << " file=" << file_file << " ext=" << file_ext << std::endl;
+	ossimPlanetArchiveMapping opam;
+
+	// try to clean this up
+	// first test for the exact match (drive and path)
+	ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - finding exact file_path" << std::endl;
+
+	// test for a path only  match
+	for( it = mappingList.begin(); it != mappingList.end(); it++ )
+	{
+		opam = (*it);
+		
+		src = opam.getSource();
+		src.split(src_drive, src_path, src_file, src_ext);
+		ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - src split: drive=" << src_drive << " path=" << src_path << " file=" << src_file << " ext=" << src_ext << std::endl;
+
+		if( (file_path == src_path) )
+		{
+			ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - match found. File: " << file_path << " Source: " << src_path << std::endl;
+			dest = opam.getDestination();
+			dest.split(dest_drive, dest_path, dest_file, dest_ext);
+			dest.merge(dest_drive, dest_path, file_file, file_ext);
+			//dest.convertForwardToBackSlashes();
+			return dest;
+		}
+	}
+
+
+	ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - finding exact file_drive/file_path" << std::endl;
+	for( it = mappingList.begin(); it != mappingList.end(); it++ )
+	{
+		opam = (*it);
+		
+		src = opam.getSource();
+		src.split(src_drive, src_path, src_file, src_ext); 
+		ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - src split: drive=" << src_drive << " path=" << src_path << " file=" << src_file << " ext=" << src_ext << std::endl;
+
+		if( (file_drive+file_path) == (src_drive+src_path) )
+		{
+			ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - match found. File: " << file_drive << " " << file_path << " Source: " << src_drive << " " << src_path << std::endl;
+			dest = opam.getDestination();
+			dest.split(dest_drive, dest_path, dest_file, dest_ext);
+			dest.merge(dest_drive, dest_path, file_file, file_ext);
+			//dest.convertForwardToBackSlashes();
+			return dest;
+		}
+	}
+
+
+	// any sub path of the given filename
+	// Fail safe: this is a complete hack... need to find a better way to do this
+	ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - if path contains src_path" << std::endl;
+	for( it = mappingList.begin(); it != mappingList.end(); it++ )
+	{
+		opam = (*it);
+		
+		src = opam.getSource();
+		src.split(src_drive, src_path, src_file, src_ext); 
+		ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - src split: drive=" << src_drive << " path=" << src_path << " file=" << src_file << " ext=" << src_ext << std::endl;
+
+		if( file_path.contains( src_path )  )
+		{
+			ossimNotify(ossimNotifyLevel_INFO) << "ossimPlanetArchive::matchPath() - match found. File: " << src_path << " Source: " << std::endl;
+			dest = opam.getDestination();
+			dest.split(dest_drive, dest_path, dest_file, dest_ext);
+			dest.merge(dest_drive, file_path, file_file, file_ext);
+			//dest.convertForwardToBackSlashes();
+			
+			return dest;
+		}
+	}
+	
+	// if all else fails...
+	//dest = opam.getDestination();
+	//dest.split(dest_drive, dest_path, dest_file, dest_ext);
+	//dest.merge(ossimString("x:"), file_path, file_file, file_ext);
+	//dest.convertForwardToBackSlashes();
+	
+	//return dest;
+
+	return filename;
+}
+
+void ossimPlanetArchive::setArchiveMappingEnabledFlag(bool enabled)
+{
+	OpenThreads::ScopedLock<ossimPlanetReentrantMutex> lock(theArchiveMutex);
+	useArchiveMapping = enabled;
+}
+
+bool ossimPlanetArchive::archiveMappingEnabled()
+{
+	return useArchiveMapping;
+}
+
+std::vector<ossimPlanetArchiveMapping> ossimPlanetArchive::getMappingList()
+{
+	return mappingList;
+}
\ No newline at end of file
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetArchiveMapping.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetArchiveMapping.cpp
new file mode 100755
index 0000000..a478bcc
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetArchiveMapping.cpp
@@ -0,0 +1,36 @@
+#include <ossimPlanet/ossimPlanetArchiveMapping.h>
+
+
+ossimPlanetArchiveMapping::ossimPlanetArchiveMapping()
+{
+}
+
+ossimPlanetArchiveMapping::ossimPlanetArchiveMapping(const ossimFilename &source, const ossimFilename &destination)
+{
+	src = source;
+	dest = destination;
+}
+
+ossimPlanetArchiveMapping::~ossimPlanetArchiveMapping()
+{
+}
+
+ossimFilename ossimPlanetArchiveMapping::getSource()
+{ 
+	return src; 
+}
+
+void ossimPlanetArchiveMapping::setSource(const ossimFilename &source)
+{ 
+	src = source; 
+}
+
+ossimFilename ossimPlanetArchiveMapping::getDestination()
+{ 
+	return dest; 
+}
+
+void ossimPlanetArchiveMapping::setDestination(const ossimFilename &destination)
+{ 
+	dest = destination; 
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetBillboardIcon.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetBillboardIcon.cpp
new file mode 100644
index 0000000..90846f2
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetBillboardIcon.cpp
@@ -0,0 +1,129 @@
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetBillboardIcon.h>
+#include <osgUtil/CullVisitor>
+#include <iostream>
+
+ossimPlanetBillboardIcon::ossimPlanetBillboardIcon(double objectGroundSize)
+{
+   thePixelWidth    = 32;
+   thePixelHeight   = 32;
+   theMaxPixelSize  = 32; // will be reset to the images max width height
+   theMinPixelSize  = 4;
+   theNeedsUpdateFlag = true;
+   theBillboard = new osg::Billboard;
+   theBillboard->setMode(osg::Billboard::POINT_ROT_EYE);
+   theGeom = new ossimPlanetIconGeom();
+   theBillboard->addDrawable(theGeom.get());
+   theBillboardTransform = new osg::MatrixTransform;
+   theBillboardTransform->addChild(theBillboard);
+   theFudgeFactorTransform = new osg::MatrixTransform;
+   theFudgeFactorTransform->addChild(theBillboardTransform.get());
+   setUpdateCallback(new ossimPlanetBillboardIconUpdateCallback);
+                                      // we will set the scale for now so the icon comes in
+   // at full res at approximately 5 kilomeer coverage.
+   theBillboardTransform->setMatrix(osg::Matrixd::scale(objectGroundSize, objectGroundSize, objectGroundSize));
+}
+
+void ossimPlanetBillboardIcon::setGroundObjectSize(double groundSize)
+{
+   theBillboardTransform->setMatrix(osg::Matrixd::scale(groundSize,
+                                                        groundSize,
+                                                        groundSize));
+}
+
+void ossimPlanetBillboardIcon::setIcon(osg::ref_ptr<osg::Image> img)
+{
+   thePixelWidth   = img->s();
+   thePixelHeight  = img->t();
+   theMaxPixelSize = ossim::max(thePixelWidth, thePixelHeight);
+   theGeom->setTexture(img.get());
+   dirtyBound();
+}
+
+void ossimPlanetBillboardIcon::setIcon(osg::ref_ptr<osg::Texture2D> img)
+{
+   theGeom->setTexture(img.get());
+
+   dirtyBound();
+}
+
+void ossimPlanetBillboardIcon::setGeom(osg::ref_ptr<ossimPlanetIconGeom> geom)
+{
+   theBillboard->setDrawable(0, geom.get());
+   theGeom = geom.get();
+   if(geom->texture().valid())
+   {
+      osg::Image* img = geom->texture()->getImage();
+      if(img)
+      {
+         thePixelWidth   = img->s();
+         thePixelHeight  = img->t();
+         theMaxPixelSize = ossim::max(thePixelWidth, thePixelHeight);
+      }
+   }
+   dirtyBound();
+}
+
+void ossimPlanetBillboardIcon::traverse(osg::NodeVisitor& nv)
+{
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(theNeedsUpdateFlag)
+         {
+            theFudgeFactorTransform->setMatrix(theFudgeFactorMatrix);
+            theNeedsUpdateFlag = false;
+            dirtyBound();
+         }
+         theFudgeFactorTransform->accept(nv);
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cullVisitor = (osgUtil::CullVisitor*)(&nv);
+         // make sure we compute scales from the original bill board geom and not from the current
+         // bounds of the theTransform node.
+         //
+         const osg::BoundingSphere& bs = theBillboardTransform->getBound();
+         double pixelSize = ossim::abs(cullVisitor->pixelSize(bs));
+         double scaleFactor = theMaxPixelSize/pixelSize;
+         //do some sanity checks
+         if(pixelSize < theMinPixelSize)
+         {
+            scaleFactor = theMinPixelSize/pixelSize;
+         }
+         else if(pixelSize < theMaxPixelSize)
+         {
+            scaleFactor = 1.0;
+         }
+         theTranslate =osg::Vec3d(0.0,0.0,bs.radius()*.5*scaleFactor);
+         theFudgeFactorMatrix = (osg::Matrixd::scale(osg::Vec3d(scaleFactor,
+                                                                scaleFactor,
+                                                                scaleFactor))*
+                                 osg::Matrixd::translate(theTranslate));
+         theNeedsUpdateFlag = true;
+         theCulledFlag = cullVisitor->isCulled(*theFudgeFactorTransform);
+         if(!theCulledFlag)
+         {
+           theFudgeFactorTransform->accept(nv);
+         }
+         break;
+      }
+      default:
+      {
+         theFudgeFactorTransform->accept(nv);
+         break;
+      }
+   }
+}       
+
+osg::BoundingSphere ossimPlanetBillboardIcon::computeBound() const
+{
+   return theFudgeFactorTransform->getBound();
+}
+
+bool ossimPlanetBillboardIcon::isCulled()const
+{
+   return theCulledFlag;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetBoundingBox.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetBoundingBox.cpp
new file mode 100644
index 0000000..ee4127d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetBoundingBox.cpp
@@ -0,0 +1,56 @@
+#include <ossimPlanet/ossimPlanetBoundingBox.h>
+
+#include <osg/Vec4>
+#include <iostream>
+
+bool ossimPlanetBoundingBox::intersects(const osg::Polytope& frustum)const
+{
+   const osg::Polytope::PlaneList& planeList = frustum.getPlaneList();
+   unsigned int idx = 0;
+   unsigned int ptIdx = 0;
+   unsigned int outsideCount    = 0;
+   unsigned int upperBound = planeList.size();
+   double testValue = 0.0;
+   for(; idx < upperBound;++idx)
+   {
+      const osg::Vec4& plane = planeList[idx].asVec4();
+      outsideCount = 0;
+      for(ptIdx = 0; ptIdx < 8; ++ptIdx)
+      {
+         testValue =  (((((double)plane[0])*theCorners[ptIdx][0] +
+                         ((double)plane[1])*theCorners[ptIdx][1] +
+                         ((double)plane[2])*theCorners[ptIdx][2])) + (double)plane[3]);
+         if(testValue >-FLT_EPSILON)
+         {
+            break;
+         }
+         else
+         {
+            ++outsideCount;
+         }
+      }
+      if(outsideCount == 8)
+      {
+         return false;
+      }
+   }
+   
+   return true;
+}
+
+bool ossimPlanetBoundingBox::isInFront(const osg::Vec3d& eye,
+                                       const osg::Vec3d& direction)const
+{
+   ossim_uint32 idx = 0;
+   osg::Vec3d deltaP;
+   for(idx = 0; idx < 8; ++idx)
+   {
+      deltaP = theCorners[idx]-eye;
+      if((deltaP*direction) > -FLT_EPSILON)
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetCache.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetCache.cpp
new file mode 100644
index 0000000..d0b56f9
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetCache.cpp
@@ -0,0 +1,195 @@
+#include <ossimPlanet/ossimPlanetCache.h>
+#include <ossimPlanet/ossimPlanetJpegImage.h>
+#include <ossim/imaging/ossimJpegWriter.h>
+#include <ossim/imaging/ossimMemoryImageSource.h>
+#include <ossim/imaging/ossimJpegTileSource.h>
+void ossimPlanetMemoryImageCache::shrink()
+{
+   if(!exceedsMinCacheSize())
+   {
+      return;
+   }
+   osg::Timer* timer = osg::Timer::instance();
+   ossim_float64 t;
+   while(exceedsMinCacheSize())
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+         t = timer->tick();
+         TileMap::iterator iter = theTileCache.begin();
+         TileMap::iterator currentToErase = iter;
+         ossim_float64 delta = timer->delta_m(iter->second.theTimeStamp,
+                                              t);
+         ossim_float64 testDelta = delta;
+         ++iter;
+         while(iter!=theTileCache.end())
+         {
+            testDelta = timer->delta_m(iter->second.theTimeStamp,
+                                       t);
+            if(testDelta > delta)
+            {
+               currentToErase = iter;
+               delta = testDelta;
+            }
+            ++iter;
+         }
+         if(currentToErase != theTileCache.end())
+         {
+            theCurrentCacheSize -= currentToErase->second.theImage->sizeInBytes();
+            if(theCurrentCacheSize < 0) theCurrentCacheSize = 0;
+            theTileCache.erase(currentToErase);
+         }
+      }
+   }
+}
+
+void ossimPlanetMemoryImageCache::addOrUpdate(ossimPlanetImage* image)
+{
+   if(!image||(maxCacheSizeInBytes()<=0)||!enabledFlag())
+   {
+      return;
+   }
+   ossimPlanetTerrainTileId tileId = image->tileId();
+   if(!get(tileId))
+   {   
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+         TileInfo info;
+         info.theImage = image;
+         info.theTimeStamp = osg::Timer::instance()->tick();
+         theTileCache.insert(std::make_pair(tileId, info));
+         theCurrentCacheSize += image->sizeInBytes();
+      }
+   }
+}
+
+ossimPlanetImage* ossimPlanetMemoryImageCache::get(const ossimPlanetTerrainTileId& id)
+{
+   if(!enabledFlag()) return 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   TileMap::iterator tile = theTileCache.find(id);
+   if(tile!=theTileCache.end())
+   {
+      tile->second.theTimeStamp = osg::Timer::instance()->tick();
+      return tile->second.theImage.get();
+   }
+   
+   return 0;
+}
+
+bool ossimPlanetMemoryImageCache::hasImage(const ossimPlanetTerrainTileId& id)const
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+  return (theTileCache.find(id) != theTileCache.end());
+}
+
+ossimPlanetDiskImageCache::ossimPlanetDiskImageCache()
+{
+
+}
+
+bool ossimPlanetDiskImageCache::openDirectory(const ossimFilename& file, bool createIfNotExistsFlag)
+{
+  bool result = false;
+  m_indexFileKwl.clear();
+  if(createIfNotExistsFlag&&!file.exists())
+  {
+    file.createDirectory(true);
+  }
+  if(file.exists())
+  {
+    m_directory = file;
+    m_indexFile = file.dirCat("cache.idx");
+    if(m_indexFile.exists())
+    {
+      m_indexFileKwl.addFile(m_indexFile.c_str());
+    }
+
+    result = true;
+  }
+
+  return result;
+}
+
+void ossimPlanetDiskImageCache::clean()
+{
+}
+
+void ossimPlanetDiskImageCache::shrink()
+{
+}
+
+void ossimPlanetDiskImageCache::addOrUpdate(ossimPlanetImage* image)
+{
+  ossimFilename tileFile = m_directory.dirCat(buildTileFile(image->tileId()));
+
+  ossimFilename directory = tileFile.path();
+  if(!directory.exists())
+  {
+    directory.createDirectory(true);
+  }
+
+  if(directory.exists())
+  {
+    ossimRefPtr<ossimJpegWriter> jpegWriter = new ossimJpegWriter;
+    ossimRefPtr<ossimMemoryImageSource> memSource = new ossimMemoryImageSource;
+    ossimRefPtr<ossimImageData> data = new ossimImageData(0, OSSIM_UINT8, image->getNumberOfComponents(), image->getWidth(), image->getHeight());
+    data->loadTile(image->data(), data->getImageRectangle(),OSSIM_BIP);
+
+    memSource->setImage(data.get());
+    jpegWriter->connectMyInputTo(memSource.get());
+    jpegWriter->setFilename(tileFile);
+    jpegWriter->execute();
+    jpegWriter->disconnect();
+    memSource->disconnect();
+  }
+}
+
+bool ossimPlanetDiskImageCache::hasImage(const ossimPlanetTerrainTileId& id)const
+{
+  ossimFilename tileFile = m_directory.dirCat(buildTileFile(id));
+
+  return tileFile.exists();
+}
+
+ossimPlanetImage* ossimPlanetDiskImageCache::get(const ossimPlanetTerrainTileId& id)
+{
+  ossimFilename tileFile = m_directory.dirCat(buildTileFile(id));
+  osg::ref_ptr<ossimPlanetImage> result;
+
+  if(tileFile.exists())
+  {
+    ossimRefPtr<ossimJpegTileSource> jpegReader = new ossimJpegTileSource;
+    if(jpegReader->open(tileFile))
+    {
+      ossimRefPtr<ossimImageData> data = jpegReader->getTile(jpegReader->getBoundingRect());
+
+      if(data.valid())
+      {
+        result = new ossimPlanetImage(id);
+        result->fromOssimImage(data.get());
+      }
+    }
+//    ossimPlanetJpegImage jpegImageTile;
+
+//    result = new ossimPlanetImage(id);
+
+//    if(!jpegImageTile.loadFile(tileFile, *result))
+//    {
+//      result = 0;
+//    }
+  }
+
+  return result.release();
+}
+
+ossimFilename ossimPlanetDiskImageCache::buildTileFile(const ossimPlanetTerrainTileId& id)const
+{
+  ossimFilename tileFile = ossimString::toString(id.face());
+  tileFile = tileFile.dirCat(ossimString::toString(id.level()));
+  tileFile = tileFile.dirCat(ossimString::toString(id.x()));
+  tileFile = tileFile.dirCat(ossimString::toString(id.y()));
+
+  return tileFile;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetCacheTextureLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetCacheTextureLayer.cpp
new file mode 100644
index 0000000..e406ac2
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetCacheTextureLayer.cpp
@@ -0,0 +1,283 @@
+#include <ossimPlanet/ossimPlanetCacheTextureLayer.h>
+
+ossimPlanetCacheTextureLayer::ossimPlanetCacheTextureLayer()
+{
+
+}
+
+ossimPlanetCacheTextureLayer::ossimPlanetCacheTextureLayer(const ossimPlanetCacheTextureLayer& src)
+:m_textureLayer(src.m_textureLayer.get()),
+m_cache(src.m_cache.get())
+{
+
+}
+
+ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::dup()const
+{
+  return new ossimPlanetCacheTextureLayer(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::dupType()const
+{
+  return new ossimPlanetCacheTextureLayer();
+}
+
+ossimString ossimPlanetCacheTextureLayer::getClassName()const
+{
+  return "ossimPlanetCacheTextureLayer";
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetCacheTextureLayer::updateExtents()
+{
+  ossimPlanetTextureLayerStateCode result = ossimPlanetTextureLayer_NO_SOURCE_DATA;
+  if(m_textureLayer.valid())
+  {
+    result = m_textureLayer->updateExtents();
+    theExtents = m_textureLayer->getExtents();
+  }
+
+  return result;
+}
+
+void ossimPlanetCacheTextureLayer::updateStats()const
+{
+
+}
+
+void ossimPlanetCacheTextureLayer::setTextureLayer(ossimPlanetTextureLayer* layer)
+{
+  m_textureLayer = layer;
+}
+
+void ossimPlanetCacheTextureLayer::setCache(ossimPlanetImageCache* cache)
+{
+  m_cache = cache;
+}
+
+
+bool ossimPlanetCacheTextureLayer::hasTexture(ossim_uint32 width,
+                                              ossim_uint32 height,
+                                              const ossimPlanetTerrainTileId& tileId,
+                                              const ossimPlanetGrid& grid)
+{
+  bool result = false;
+  if(m_cache.valid())
+  {
+    result = m_cache->hasImage(tileId);
+  }
+  if(!result)
+  {
+    if(m_textureLayer.valid())
+    {
+      result = m_textureLayer->hasTexture(width, height, tileId, grid);
+    }
+  }
+
+  return result;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetCacheTextureLayer::getTexture(ossim_uint32 width,
+                                                                        ossim_uint32 height,
+                                                                        const ossimPlanetTerrainTileId& tileId,
+                                                                        const ossimPlanetGrid& grid,
+                                                                        ossim_int32 padding)
+{
+  if(!enableFlag())
+  {
+    return 0;
+  }
+  osg::ref_ptr<ossimPlanetImage> result;
+  if(m_cache.valid())
+  {
+    result = m_cache->get(tileId);
+  }
+
+  if(!result.valid()&&m_textureLayer.valid())
+  {
+    result = m_textureLayer->getTexture(width, height, tileId, grid, padding);
+
+    if(result.valid()&&m_cache.valid())
+    {
+      m_cache->addOrUpdate(result.get());
+    }
+  }
+  result = applyBrightnessContrast(result.get(), true);
+
+  return result;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetCacheTextureLayer::getTexture(ossim_uint32 /* level */,
+                                                                        ossim_uint64 /* row */,
+                                                                        ossim_uint64 /* col */,
+                                                                        const ossimPlanetGridUtility& /* utility */)
+{
+  return 0;
+}
+
+const osg::ref_ptr<ossimPlanetLookAt> ossimPlanetCacheTextureLayer::getLookAt()const
+{
+  return theLookAt.get();
+}
+
+void ossimPlanetCacheTextureLayer::setLookAt(osg::ref_ptr<ossimPlanetLookAt> lookAt)
+{
+  theLookAt = lookAt.get();
+  if(m_textureLayer.valid())
+  {
+    m_textureLayer->setLookAt(lookAt);
+  }
+}
+
+
+void ossimPlanetCacheTextureLayer::getDateRange(ossimDate& minDate,
+                               ossimDate& maxDate)const
+{
+  ossimPlanetTextureLayer::getDateRange(minDate, maxDate);
+}
+
+double ossimPlanetCacheTextureLayer::getApproximateHypotneusLength()const
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->getApproximateHypotneusLength();
+  }
+
+  return ossimPlanetTextureLayer::getApproximateHypotneusLength();
+}
+
+void ossimPlanetCacheTextureLayer::getCenterLatLonLength(double& centerLat,
+                                                         double& centerLon,
+                                                         double& length)const
+{
+  if(m_textureLayer.valid())
+  {
+    m_textureLayer->getCenterLatLonLength(centerLat, centerLon, length);
+  }
+
+  ossimPlanetTextureLayer::getCenterLatLonLength(centerLat, centerLon, length);
+
+}
+
+void ossimPlanetCacheTextureLayer::setEnableFlag(bool flag)
+{
+  ossimPlanetTextureLayer::setEnableFlag(flag);
+}
+
+void ossimPlanetCacheTextureLayer::setFilterType(const ossimString& filterType)
+{
+  ossimPlanetTextureLayer::setFilterType(filterType);
+  if(m_textureLayer.valid())
+  {
+    m_textureLayer->setFilterType(filterType);
+  }
+}
+
+void ossimPlanetCacheTextureLayer::getMetadata(ossimRefPtr<ossimXmlNode> metadata)const
+{
+  if(m_textureLayer.valid())
+  {
+    m_textureLayer->getMetadata(metadata.get());
+  }
+}
+
+ossimRefPtr<ossimXmlNode> ossimPlanetCacheTextureLayer::saveXml(bool recurseFlag)const
+{
+  if(m_textureLayer.valid())
+   {
+     return m_textureLayer->saveXml(recurseFlag);
+   }
+
+  return 0;
+}
+
+bool ossimPlanetCacheTextureLayer::loadXml(ossimRefPtr<ossimXmlNode> node)
+{
+  if(m_textureLayer.valid())
+    {
+      return m_textureLayer->loadXml(node.get());
+    }
+
+   return false;
+
+}
+
+void ossimPlanetCacheTextureLayer::resetLookAt()
+{
+  if(m_textureLayer.valid())
+  {
+      m_textureLayer->resetLookAt();
+      theLookAt = m_textureLayer->getLookAt();
+  }
+
+}
+
+ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerByName(const ossimString& layerName,
+                                                       bool recurseFlag)
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerByName(layerName, recurseFlag);
+  }
+
+  return 0;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerByName(const ossimString& layerName,
+                                                             bool recurseFlag)const
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerByName(layerName, recurseFlag);
+  }
+
+  return 0;
+
+}
+
+ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerByNameAndId(const ossimString& layerName,
+                                                            const ossimString& layerId)
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerByNameAndId(layerName, layerId);
+  }
+
+  return 0;
+
+}
+
+const ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerByNameAndId(const ossimString& layerName,
+                                                                  const ossimString& layerId)const
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerByNameAndId(layerName, layerId);
+  }
+
+  return 0;
+
+}
+
+ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerById(const ossimString& layerId,
+                                                                     bool recurseFlag)
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerById(layerId, recurseFlag);
+  }
+
+  return 0;
+
+}
+
+const ossimPlanetTextureLayer* ossimPlanetCacheTextureLayer::findLayerById(const ossimString& layerId,
+                                                                           bool recurseFlag)const
+{
+  if(m_textureLayer.valid())
+  {
+    return m_textureLayer->findLayerById(layerId, recurseFlag);
+  }
+
+  return 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetClientThread.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetClientThread.cpp
new file mode 100644
index 0000000..868cd66
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetClientThread.cpp
@@ -0,0 +1,360 @@
+#include <ossimPlanet/ossimPlanetClientThread.h>
+#include <iostream>
+#include <algorithm>
+
+ossimPlanetClientConnection::ossimPlanetClientConnection(SGSocket* socket,
+                                                         ossim_uint32 queueSize)
+   :theSocket(socket),
+    theMaxQueueSize(queueSize)
+{
+}
+
+ossimPlanetClientConnection::ossimPlanetClientConnection()
+   :theSocket(0),
+    theMaxQueueSize(1024)
+{
+}
+
+ossimPlanetClientConnection::~ossimPlanetClientConnection()
+{
+   if(theSocket)
+   {
+      theSocket->close();
+      delete theSocket;
+      theSocket = 0;
+   }
+   theMessageQueue.clear();
+}
+
+
+ossimString ossimPlanetClientConnection::getHost()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimString result;
+   if(theSocket)
+   {
+      result = theSocket->get_hostname();
+   }
+
+   return result;
+}
+
+ossimString ossimPlanetClientConnection::getPortString()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimString result;
+
+   if(theSocket)
+   {
+      result = theSocket->get_port_str();
+   }
+
+   return result;
+}
+
+ossimString ossimPlanetClientConnection::getPortType()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimString result;
+
+   if(theSocket)
+   {
+      result = theSocket->get_port_style();
+   }
+
+   return result;
+}
+
+void ossimPlanetClientConnection::getConnection(ossimString& host,
+                                                ossimString& port,
+                                                ossimString& portType)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   
+   if(theSocket)
+   {
+      host     = theSocket->get_hostname();
+      port     = theSocket->get_port_str();
+      portType =  theSocket->get_port_style();
+   }
+}
+
+bool ossimPlanetClientConnection::setConnection(const ossimString& host,
+                                                const ossimString& port,
+                                                const ossimString& portType)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   bool result = false;
+   
+   if(theSocket)
+   {
+      theSocket->setSocket(host, port, portType);
+      result = theSocket->open(SG_IO_OUT);
+   }
+
+   return result;
+}
+
+void ossimPlanetClientConnection::addMessage(const ossimString& message)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageQueueMutex);
+   if(theSocket)
+   {
+      theMessageQueue.push_back(message);
+      if(theMessageQueue.size() >= theMaxQueueSize)
+      {
+         theMessageQueue.pop_front();
+      }
+   }
+}
+
+void ossimPlanetClientConnection::sendNextMessage()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(theMessageQueueMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theMutex);
+
+   if(!theMessageQueue.empty()&&theSocket)
+   {
+      ossimString message = popMessage();
+      theSocket->writestring(message.c_str());
+   }
+}
+
+bool ossimPlanetClientConnection::hasMessages()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageQueueMutex);
+
+   return !theMessageQueue.empty();
+}
+
+void ossimPlanetClientConnection::clearQueue()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageQueueMutex);
+   theMessageQueue.clear();
+}
+
+ossimString ossimPlanetClientConnection::popMessage()
+{
+   ossimString result;
+
+   if(!theMessageQueue.empty())
+   {
+      result = theMessageQueue.front();
+      theMessageQueue.pop_front();
+   }
+
+   return result;
+}
+  
+SGSocket* ossimPlanetClientConnection::getSocket()
+{
+   return theSocket;
+}
+
+void ossimPlanetClientConnection::setSocket(SGSocket* socket)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(theSocket != socket)
+   {
+      theSocket->close();
+      delete theSocket;
+
+      theSocket = socket;
+   }
+}
+
+ossimPlanetClientThread::ossimPlanetClientThread()
+   :theStartedFlag(false),
+    theDoneFlag(false)
+{
+   theBlock = new ossimPlanetRefBlock();
+}
+
+ossimPlanetClientThread::~ossimPlanetClientThread()
+{
+   
+}
+
+void ossimPlanetClientThread::run()
+{
+   if(theStartedFlag) return;
+
+   ossim_uint32 idx = 0;
+   theStartedFlag = true;
+   theDoneFlag    = false;
+   while(!theDoneFlag)
+   {
+      theBlock->block();
+      if(theDoneFlag) return;
+      bool hasMessages = false;
+      theConnectionListMutex.lock();
+      for(idx = 0; idx < theClientConnectionList.size(); ++idx)
+      {
+         if(theClientConnectionList[idx]->hasMessages())
+         {
+            theClientConnectionList[idx]->sendNextMessage();
+            hasMessages = true;
+         }
+      }
+      if(!hasMessages)
+      {
+         theBlock->set(false);
+      }
+      theConnectionListMutex.unlock();
+      YieldCurrentThread();
+   }
+   
+   theStartedFlag = false;
+}
+
+int ossimPlanetClientThread::cancel()
+{
+   theDoneFlag = true;
+   theBlock->release();
+   return OpenThreads::Thread::cancel();
+}
+
+osg::ref_ptr<ossimPlanetClientConnection>  ossimPlanetClientThread::newConnection(const ossimString& host,
+                                                                                  const ossimString& port,
+                                                                                  const ossimString& portType)
+{
+   SGSocket* socket = new SGSocket(host, port, portType);
+   socket->open(SG_IO_OUT);
+
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   osg::ref_ptr<ossimPlanetClientConnection> connection = new ossimPlanetClientConnection(socket);
+   theClientConnectionList.push_back(connection.get());
+
+   return connection.get();
+}
+
+bool ossimPlanetClientThread::setConnection(ossim_uint32 idx,
+                                            const ossimString& host,
+                                            const ossimString& port,
+                                            const ossimString& portType)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   if(idx < theClientConnectionList.size())
+   {
+      return theClientConnectionList[idx]->setConnection(host, port, portType);
+   }
+
+   return false;
+}
+
+void ossimPlanetClientThread::removeConnection(osg::ref_ptr<ossimPlanetClientConnection> connection)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   ossimPlanetClientThreadConnectionList::iterator iter = std::find(theClientConnectionList.begin(),
+                                                                    theClientConnectionList.end(),
+                                                                    connection.get());
+   if(iter != theClientConnectionList.end())
+   {
+      theClientConnectionList.erase(iter);
+   }
+}
+
+osg::ref_ptr<ossimPlanetClientConnection> ossimPlanetClientThread::removeConnection(ossim_uint32 idx)
+{
+   osg::ref_ptr<ossimPlanetClientConnection> result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   if(idx < theClientConnectionList.size())
+   {
+      result = theClientConnectionList[idx];
+      theClientConnectionList.erase(theClientConnectionList.begin() + idx);
+   }
+
+   return result;
+}
+
+
+const osg::ref_ptr<ossimPlanetClientConnection> ossimPlanetClientThread::getConnection(ossim_uint32 idx)const
+{
+   osg::ref_ptr<ossimPlanetClientConnection> result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   if(idx < theClientConnectionList.size())
+   {
+      result = theClientConnectionList[idx];
+   }
+
+   return result;
+}
+
+
+void ossimPlanetClientThread::sendMessage(ossim_uint32 idx,
+                                          const ossimString& message)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   protectedSendMessage(idx, message);
+   
+   if(theStartedFlag)
+   {
+      protectedUpdateClientThreadBlock();
+   }
+   else
+   {
+      start();
+   }
+}
+
+void ossimPlanetClientThread::protectedSendMessage(ossim_uint32 idx,
+                                                   const ossimString& message)
+{
+   if(idx < theClientConnectionList.size())
+   {
+      theClientConnectionList[idx]->addMessage(message);
+
+   }
+}
+
+void ossimPlanetClientThread::broadcastMessage(const ossimString& message)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   ossim_uint32 idx;
+   for(idx = 0; idx < theClientConnectionList.size();++idx)
+   {
+      protectedSendMessage(idx, message);
+   }
+   
+   if(theStartedFlag)
+   {
+      protectedUpdateClientThreadBlock();
+   }
+   else
+   {
+      start();
+   }
+}
+
+ossim_uint32 ossimPlanetClientThread::getNumberOfConnections()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   return theClientConnectionList.size();
+}
+
+void ossimPlanetClientThread::updateClientThreadBlock()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theConnectionListMutex);
+   protectedUpdateClientThreadBlock();
+}
+
+void ossimPlanetClientThread::protectedUpdateClientThreadBlock()
+{
+   if(!theStartedFlag) return;
+   bool blockFlag = false;
+
+   if(theClientConnectionList.size() > 0)
+   {
+      ossim_uint32 idx = 0;
+
+      for(idx = 0; idx < theClientConnectionList.size(); ++idx)
+      {
+         if(theClientConnectionList[idx]->hasMessages())
+         {
+            blockFlag = true;
+            break;
+         }
+      }
+   }
+   theBlock->set(blockFlag);   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetCloudLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetCloudLayer.cpp
new file mode 100644
index 0000000..15b2a9c
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetCloudLayer.cpp
@@ -0,0 +1,666 @@
+#include <ossimPlanet/ossimPlanetCloudLayer.h>
+#include <osg/MatrixTransform>
+#include <osg/Geometry>
+#include <osg/TexMat>
+#include <osg/io_utils>
+#include <osgUtil/CullVisitor>
+#include <osgUtil/IntersectVisitor>
+#include <osgUtil/IntersectionVisitor>
+#include <queue>
+#include <ossim/base/ossimCommon.h>
+
+ossimPlanetCloudLayer::ossimPlanetCloudLayer()
+:theHeading(0.0),
+theSpeed(0.0),
+theTextureTranslation(0.0,0.0,0.0),
+theTextureScale(1.0,1.0,1.0),
+theAutoUpdateTextureMatrixFlag(true),
+theTextureWidth(0),
+theTextureHeight(0),
+theMeshLevel(0),
+theApproximateMetersPerPixelCoverage(90000.0),// lets just init to a big coverage for cloud
+theMaxAltitudeToShowClouds(9999999999999.0)// lets just init to a big coverage for cloud
+{
+   init();
+}
+
+void ossimPlanetCloudLayer::traverse(osg::NodeVisitor& nv)
+{
+   if(dynamic_cast<osgUtil::IntersectVisitor*> (&nv) ||
+      dynamic_cast<osgUtil::IntersectionVisitor*> (&nv)||
+      !enableFlag())
+   {
+      return;
+   }
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         updateTextureMatrix(nv.getFrameStamp()->getSimulationTime());
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(cv)
+         {
+            osg::Vec3d eye = cv->getEyePoint();
+            if(theModel.valid())
+            {
+               osg::Vec3d llh;
+               theModel->xyzToLatLonHeight(eye, llh);
+               if(llh[2] > theMaxAltitudeToShowClouds)
+               {
+                  return;
+               }
+            }
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   ossimPlanetLayer::traverse(nv);
+}
+
+void ossimPlanetCloudLayer::init()
+{
+   theGrid  = new ossimPlanetAdjustableCubeGrid(ossimPlanetAdjustableCubeGrid::HIGH_CAP);
+   getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
+   getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   setNodeMask(0xffffffff);
+   theTexture = new osg::Texture2D;
+   theTexture->setResizeNonPowerOfTwoHint(false);
+   theTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+   theTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+   theTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
+   theTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
+   theTexture->setDataVariance(osg::Object::DYNAMIC);
+   theTexture->setUnRefImageDataAfterApply(false);
+   getOrCreateStateSet()->setTextureAttributeAndModes(0, 
+                                                      theTexture.get(), 
+                                                      osg::StateAttribute::ON);
+}
+
+void ossimPlanetCloudLayer::splitTiles(ossimPlanetGrid::TileIds& tiles, ossim_uint32 levels)const
+{
+   if(levels == 0) return;
+   std::queue<ossimPlanetTerrainTileId> workQueue;
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < tiles.size(); ++idx)
+   {
+      if(!theGrid->isPolar(tiles[idx]))
+      {
+         workQueue.push(tiles[idx]);
+      }
+   }
+   tiles.clear();
+   ossimPlanetTerrainTileId quad00;
+   ossimPlanetTerrainTileId quad10;
+   ossimPlanetTerrainTileId quad11;
+   ossimPlanetTerrainTileId quad01;
+   ossimPlanetTerrainTileId currentTile;
+   while(!workQueue.empty())
+   {
+      currentTile = workQueue.front();
+      workQueue.pop();
+      currentTile.splitQuad(quad00, quad10, quad11, quad01);
+      if(currentTile.level()+1 >= levels)
+      {
+         tiles.push_back(quad00);
+         tiles.push_back(quad10);
+         tiles.push_back(quad11);
+         tiles.push_back(quad01);
+      }
+      else
+      {
+         workQueue.push(quad00);
+         workQueue.push(quad10);
+         workQueue.push(quad11);
+         workQueue.push(quad01);
+      }
+   }
+}
+
+void ossimPlanetCloudLayer::updateTexture(osg::Image* cloudTexture)
+{
+   theTexture->setImage(cloudTexture);
+   if(cloudTexture)
+   {
+      theTextureWidth  = cloudTexture->s();
+      theTextureHeight = cloudTexture->t();
+      updateMetersPerPixelCoverage();
+  }
+   else
+   {
+      theTextureWidth  = 0;
+      theTextureHeight = 0;
+   }
+}
+
+void ossimPlanetCloudLayer::updateTexture(ossim_int64 seed,
+                                          ossim_int32 coverage,
+                                          ossim_float64 sharpness)
+{
+   osg::ref_ptr<ossimPlanetCloud> cloud = new ossimPlanetCloud;
+   srand(seed);
+   cloud->makeCloud(seed, coverage, sharpness);
+   updateTexture(cloud->image());
+}
+
+void ossimPlanetCloudLayer::computeMesh(double patchAltitude,
+                                        ossim_uint32 patchWidth, 
+                                        ossim_uint32 patchHeight,
+                                        ossim_uint32 level)
+{
+   if(!theModel.valid()) return;
+   theGeometryArray.clear();
+   theCenterLlh = osg::Vec3d(0.0,0.0,patchAltitude);
+   ossim_uint32 adjustedWidth  = patchWidth;
+   ossim_uint32 adjustedHeight = patchHeight;
+   double adjustedAltitude = patchAltitude;
+   bool patchFlag = false;
+   if(dynamic_cast<Patch*> (theGrid.get()))
+   {
+      if(level > 0)
+      {
+         adjustedWidth  <<= level;
+         adjustedHeight <<= level;
+      }
+      // can only do single level meshes with a local patch
+      theMeshLevel = 0;
+      adjustedAltitude = 0;
+      patchFlag = true;
+   }
+   ossimPlanetGrid::ModelPoint modelPoint;
+   ossim_uint32 numCols = adjustedWidth|1; // make sure it's odd
+   ossim_uint32 numRows = adjustedHeight|1; // make sure it's odd
+   ossim_uint32 numberOfPoints = numCols*numRows;
+   bool exceedsUshort = numberOfPoints >= 0x1111;
+   ossimPlanetGrid::TileIds tileIds;
+   theGrid->getRootIds(tileIds);
+   if(theMeshLevel != 0)
+   {
+      splitTiles(tileIds, theMeshLevel);
+   }
+   if(getNumChildren())
+   {
+      removeChildren(0, getNumChildren());
+   }
+   ossim_uint32 idx = 0;
+   double modelHeight = adjustedAltitude*theModel->getInvNormalizationScale();
+   for(idx = 0; idx < tileIds.size();++idx)
+   {
+      if(theGrid->isPolar(tileIds[idx]))
+      {
+         continue;
+      }
+      ossimPlanetTerrainTileId& tileId = tileIds[idx];
+      osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
+      osg::ref_ptr<osg::Geode>    geode = new osg::Geode;
+      osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
+      
+      osg::Matrixd localToWorld;
+      theModel->lsrMatrix(osg::Vec3d(modelPoint.y(),
+                                     modelPoint.x(),
+                                     adjustedAltitude),
+                          localToWorld);
+      osg::Matrixd inverseLocalToWorld;
+      inverseLocalToWorld.invert(localToWorld);
+      transform->addChild(geode.get());
+      geode->addDrawable(geometry.get());
+      unsigned int numVerticesInBody = numCols*numRows;
+      unsigned int numVertices       = numVerticesInBody;
+      
+      osg::ref_ptr<osg::Vec2Array> tcoords = new osg::Vec2Array;
+      tcoords->reserve(numVertices);
+      geometry->setTexCoordArray( 0, tcoords.get());   
+      
+      osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
+      vertices->reserve(numVertices);
+      geometry->setVertexArray(vertices.get());
+      
+      // allocate and assign normals
+      osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
+      if (normals.valid()) normals->reserve(numVertices);
+      geometry->setNormalArray(normals.get());
+      geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+      
+      // allocate and assign color
+      osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
+      (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
+      
+      geometry->setColorArray(colors.get());
+      geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+      theGeometryArray.push_back(geometry.get());
+      ossimPlanetGrid::LocalNdcPoint localPoint;
+      typedef std::vector<int> Indices;
+      Indices indices(numVertices, -1);
+      osg::Vec3d xyz;
+      osg::Vec3d localXyz;
+      osg::Vec3d norm1;
+      ossim_uint32 baseIdx = 0;
+      unsigned int iv = 0;
+      double txInc = 1.0/(numCols-1.0);
+      double tyInc = 1.0/(numRows-1.0);
+      double ty = 0.0;
+      ossim_uint32 colIdx, rowIdx;
+      localPoint.setZ(modelHeight);
+      for(rowIdx = 0; rowIdx < numRows;++rowIdx)
+      {
+         double tx = 0.0;
+         localPoint.setY(ty);//(double)(rowIdx)/(double)(numRows-1));
+         for(colIdx = 0; colIdx < numCols;++colIdx)
+         {
+            //rowIdx*numCols + colIdx;
+            indices[iv] = vertices->size();
+            localPoint.setX(tx);
+            tcoords->push_back(osg::Vec2d(tx, ty));
+            theGrid->localNdcToModel(tileId, localPoint, modelPoint);
+            osg::Vec3d llh(modelPoint.y(), modelPoint.x(), adjustedAltitude);
+            theModel->latLonHeightToXyz(llh, xyz);
+            localXyz = xyz*inverseLocalToWorld;
+            (*vertices).push_back(localXyz);
+            theModel->normal(xyz, norm1);
+            norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+            norm1.normalize();
+            (*normals).push_back(norm1);
+            ++iv;
+            tx+=txInc;
+         }
+         ty += tyInc;
+      }
+      transform->setMatrix(localToWorld);
+      
+      if(!exceedsUshort)
+      {
+         osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES));
+         osg::Geometry::PrimitiveSetList primSetList;
+         ossim_uint32 i = 0;
+         ossim_uint32 j = 0;
+         for(i = 1; i < numRows;i+=2)
+         {
+            for(j = 1; j < numCols;j+=2)
+            {
+               ossim_uint32 i00 = (i)*numCols + j;
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols+1));
+               drawElements.push_back(i00 - (numCols));
+               
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols));
+               drawElements.push_back(i00 - (numCols-1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols-1));
+               drawElements.push_back(i00 + 1);
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + 1);
+               drawElements.push_back(i00 + (numCols+1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols+1));
+               drawElements.push_back(i00 + (numCols));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols));
+               drawElements.push_back(i00 + (numCols-1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols-1));
+               drawElements.push_back(i00 - 1);
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - 1);
+               drawElements.push_back(i00 - (numCols+1));
+            }
+         }
+         primSetList.push_back(&drawElements);
+         geometry->setPrimitiveSetList(primSetList);
+      }
+      else
+      {
+         osg::DrawElementsUInt& drawElements = *(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES));
+         osg::Geometry::PrimitiveSetList primSetList;
+         ossim_uint32 i = 0;
+         ossim_uint32 j = 0;
+         for(i = 1; i < numRows;i+=2)
+         {
+            for(j = 1; j < numCols;j+=2)
+            {
+               ossim_uint32 i00 = (i)*numCols + j;
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols+1));
+               drawElements.push_back(i00 - (numCols));
+               
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols));
+               drawElements.push_back(i00 - (numCols-1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - (numCols-1));
+               drawElements.push_back(i00 + 1);
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + 1);
+               drawElements.push_back(i00 + (numCols+1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols+1));
+               drawElements.push_back(i00 + (numCols));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols));
+               drawElements.push_back(i00 + (numCols-1));
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 + (numCols-1));
+               drawElements.push_back(i00 - 1);
+               
+               drawElements.push_back(i00);
+               drawElements.push_back(i00 - 1);
+               drawElements.push_back(i00 - (numCols+1));
+            }
+         }
+         primSetList.push_back(&drawElements);
+         geometry->setPrimitiveSetList(primSetList);
+      }
+      //osgUtil::Simplifier simplifier(.8);
+      //simplifier.simplify(*geometry, pointsToProtect);
+      geometry->dirtyBound();
+      geometry->getBound();
+      
+      addChild(transform.get());
+   }
+   theTextureScale[0] = 1.0;
+   theTextureScale[1] = 1.0;
+   theTextureScale[2] = 1.0;
+   theTextureMatrixAttribute = new osg::TexMat();
+   updateTextureMatrix();
+   updateMetersPerPixelCoverage();
+   getOrCreateStateSet()->setTextureAttributeAndModes(0, theTextureMatrixAttribute.get(), osg::StateAttribute::ON);
+   
+   if(patchFlag)
+   {
+      moveToLocationLatLonAltitude(theCenterLlh);
+   }
+}
+
+void ossimPlanetCloudLayer::setAlphaValue(float alpha) 
+{
+   geometryPtr* geometryArray = &theGeometryArray.front();
+   ossim_uint32 length = theGeometryArray.size();
+   
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < length;++idx)
+   {
+      osg::Vec4Array* colors = (osg::Vec4Array*)((*geometryArray)->getColorArray());
+      (*colors)[0].set(1.0f,1.0f,1.0f,alpha);
+      
+      // we will let osg dirty and initialize internls s set it back on the geometry
+      (*geometryArray)->setColorArray(colors);
+      ++geometryArray;
+   }
+}
+
+void ossimPlanetCloudLayer::moveToLocationLatLonAltitude(const osg::Vec3d& llh)
+{
+  if(getNumChildren()==1)
+   {
+      osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(getChild(0));
+      if(mt)
+      {
+         osg::Vec3d newLlh = llh;
+         osg::Matrixd localToWorld;
+         theModel->mslToEllipsoidal(newLlh);
+         theModel->lsrMatrix(newLlh,
+                             localToWorld);
+         mt->setMatrix(localToWorld);
+         theCenterLlh = newLlh;
+      }
+   }
+}
+
+void ossimPlanetCloudLayer::updateTextureMatrix(double timeScale)
+{
+   if(!theAutoUpdateTextureMatrixFlag) return;
+   if((theTextureHeight>0)&&
+      (!ossim::almostEqual(theSpeed, 0.0)))
+   {
+      double distance = (((theSpeed*timeScale)/theApproximateMetersPerPixelCoverage))/theTextureHeight;
+      theTextureTranslation = ((osg::Vec3d(0.0,1.0,0.0)*
+                                osg::Matrixd::rotate(osg::DegreesToRadians(-theHeading), 
+                                                     osg::Vec3d(0.0, 0.0, 1.0)))*
+                               (-distance));
+   }
+   else
+   {
+      theTextureTranslation = osg::Vec3d(0.0,0.0,0.0);  
+   }
+   theTextureMatrix = osg::Matrixd::scale(theTextureScale);
+   theTextureMatrix(3,0) = theTextureTranslation[0];
+   theTextureMatrix(3,1) = theTextureTranslation[1];
+   theTextureMatrix(3,2) = theTextureTranslation[2];
+   
+   if(theTextureMatrixAttribute.valid())
+   {
+      theTextureMatrixAttribute->setMatrix(theTextureMatrix);
+   }
+}
+
+void ossimPlanetCloudLayer::updateMetersPerPixelCoverage()
+{
+   if(theTextureHeight>0)
+   {
+      double factor = 1.0;
+      if(theMeshLevel)
+      {
+         factor /=(ossim_float64)(1<<theMeshLevel);
+         
+      }
+      theApproximateMetersPerPixelCoverage = ((90.0*factor)/(theTextureScale[1]*theTextureHeight))*ossimGpt().metersPerDegree().y;
+   }
+}
+
+void ossimPlanetCloudLayer::setMaxAltitudeToShowClouds(ossim_float64 maxAltitude)
+{
+   theMaxAltitudeToShowClouds = maxAltitude;
+}
+
+ossim_float64 ossimPlanetCloudLayer::maxAltitudeToShowClouds()const
+{
+   return theMaxAltitudeToShowClouds;
+}
+
+void ossimPlanetCloudLayer::setTextureMatrix(osg::TexMat* texMatrix)
+{
+   if((theTextureMatrixAttribute.get()!=texMatrix)&&
+      (texMatrix))
+   {
+      theTextureMatrixAttribute = texMatrix;
+      theTextureMatrix = texMatrix->getMatrix();
+      getOrCreateStateSet()->setTextureAttributeAndModes(0, theTextureMatrixAttribute.get(), osg::StateAttribute::ON);
+   }
+   
+}
+
+ossimPlanetCloud::ossimPlanetCloud(TextureSize size)
+{
+   switch(size)
+   {
+      case TEXTURE_SIZE_256_256:
+      {
+         theCloudDataWidth=theCloudDataHeight=256;
+         theNoiseDataWidth=theNoiseDataHeight=32;
+         break;
+      }
+      case TEXTURE_SIZE_512_512:
+      {
+         theCloudDataWidth=theCloudDataHeight=512;
+         theNoiseDataWidth=theNoiseDataHeight=64;
+         break;
+      }
+      case TEXTURE_SIZE_1024_1024:
+      {
+         theCloudDataWidth=theCloudDataHeight=1024;
+         theNoiseDataWidth=theNoiseDataHeight=128;
+         break;
+      }
+      case TEXTURE_SIZE_2048_2048:
+      {
+         theCloudDataWidth=theCloudDataHeight=2048;
+         theNoiseDataWidth=theNoiseDataHeight=256;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   theCloudData.resize(theCloudDataWidth*theCloudDataHeight);
+   theNoise.resize(theNoiseDataWidth*theNoiseDataHeight);
+}
+
+double ossimPlanetCloud::noise(ossim_int32 x, ossim_int32 y, ossim_int32 random)const
+{
+   ossim_int32 n = x + y * 57 + random * 131;
+   n = (n<<13) ^ n;
+   return (1.0 - ( (n * (n * n * 15731 + 789221) +
+                    1376312589)&0x7fffffff)* 0.000000000931322574615478515625);
+}
+void ossimPlanetCloud::makeNoise(ossim_int64 seed)
+{
+   srand(seed);
+   std::vector<std::vector<ossim_float64> > temp;
+//   ossim_float64 temp[theNoiseDataWidth+2][theNoiseDataHeight+2];
+   ossim_float64* noiseMap = &theNoise.front();
+   ossim_int32 random=rand() % 100000;
+   temp.resize(theNoiseDataHeight+2);
+   temp[0].resize(theNoiseDataWidth+2);
+   temp[theNoiseDataHeight+1].resize(theNoiseDataWidth+2);
+   for (int y=1; y<(theNoiseDataHeight+1); y++) 
+   {
+	   temp[y].resize(theNoiseDataWidth+2);
+      for (int x=1; x<(theNoiseDataWidth+1); x++)
+      {
+		  temp[y][x] = 128.0 + noise(x,  y,  random)*128.0;
+       //temp[x][y] = 128.0 + noise(x,  y,  random)*128.0;
+      }
+   }
+   for (int x=1; x<(theNoiseDataWidth+1); x++)
+   {
+      temp[x][0] = temp[x][theNoiseDataWidth];
+      temp[x][theNoiseDataWidth+1] = temp[x][1];
+      temp[0][x] = temp[theNoiseDataHeight][x];
+      temp[theNoiseDataWidth+1][x] = temp[1][x];
+   }
+   temp[0][0] = temp[theNoiseDataHeight][theNoiseDataWidth];
+   temp[theNoiseDataWidth+1][theNoiseDataHeight+1] = temp[1][1];
+   temp[theNoiseDataHeight+1][0] = temp[1][theNoiseDataWidth];
+   temp[0][theNoiseDataWidth+1] = temp[theNoiseDataHeight][1];
+   for (int y=1; y<(theNoiseDataHeight+1); y++)
+   {
+      for (int x=1; x<(theNoiseDataWidth+1); x++)
+      {
+         ossim_float64 center = temp[y][x]/4.0;
+         ossim_float64 sides = (temp[y][x+1] + temp[y][x-1] + temp[y+1][x] + temp[y-1][x])/8.0;
+         ossim_float64 corners = (temp[y+1][x+1] + temp[y-1][x+1] + temp[y+1][x-1] + temp[y-1][x-1])/16.0;
+         
+         noiseMap[((x-1)*theNoiseDataWidth) + (y-1)] = center + sides + corners;
+      }
+   }
+}
+ossim_float64 ossimPlanetCloud::interpolate(ossim_float64 x, ossim_float64 y, ossim_float64  *map)
+{
+   int Xint = (int)x;
+   int Yint = (int)y;
+   
+   ossim_float64 Xfrac = x - Xint;
+   ossim_float64 Yfrac = y - Yint;
+   int X0 = Xint % theNoiseDataWidth;
+   int Y0 = Yint % theNoiseDataHeight;
+   int X1 = (Xint + 1) % theNoiseDataWidth;
+   int Y1 = (Yint + 1) % theNoiseDataHeight;      
+   ossim_float64 bot = map[X0*theNoiseDataWidth + Y0] + Xfrac * (map[X1*theNoiseDataWidth + Y0] - map[X0*theNoiseDataWidth + Y0]);
+   ossim_float64 top = map[X0*theNoiseDataWidth + Y1] + Xfrac * (map[X1*theNoiseDataWidth +  Y1] - map[X0*theNoiseDataWidth + Y1]);
+   
+   return (bot + Yfrac * (top - bot));
+}
+void ossimPlanetCloud::overlapOctaves()
+{
+   ossim_float64  *mapNoise = &theNoise.front(); 
+   ossim_float64  *mapCloud = &theCloudData.front();
+   ossim_uint32 cloudArea = theCloudDataWidth*theCloudDataHeight;
+   ossim_int32 x,y, octave;
+   for (x=0; x<cloudArea; x++)
+   {
+      mapCloud[x] = 0;
+   }
+   for (octave=0; octave<4; octave++)
+   {
+      for (x=0; x<theCloudDataWidth; x++)
+      {
+         for (y=0; y<theCloudDataHeight; y++)
+         {
+            ossim_float64 scale = 1 / pow(2.0, 3.0-octave);
+            ossim_float64 noise = interpolate(x*scale, y*scale , mapNoise);
+            mapCloud[(y*theCloudDataWidth) + x] += noise / pow(2.0, (ossim_float64)octave);
+         }
+      }
+   }
+}
+void ossimPlanetCloud::expFilter()
+{
+//   std::cout << "sharp = " << theSharpness << std::endl;
+//   std::cout << "cov = " << theCoverage << std::endl;
+   
+   ossim_float64  *map = &theCloudData.front();
+   for (int x=0; x<theCloudData.size(); x++)
+   {
+      ossim_float64 c = map[x] - (255.0-theCoverage);
+      if (c<0)
+      {
+         c = 0;
+      }
+      map[x] = 255.0 - ((ossim_float64)(pow(theSharpness, c))*255.0);
+   }
+}
+osg::Image* ossimPlanetCloud::image()
+{
+   return theImage.get();
+}
+
+void ossimPlanetCloud::makeCloud(ossim_int64 seed=0, ossim_int32 coverage, ossim_float64 sharpness)
+{
+   theCoverage = coverage;
+   theSharpness = sharpness;
+   ossim_uint32 area = theCloudDataWidth*theCloudDataHeight;
+   unsigned char* newData = new unsigned char[area*4];
+   unsigned char* newDataPtr = newData;
+   ossim_float64* cloudData = &theCloudData.front();
+   makeNoise(seed);
+   overlapOctaves();
+   expFilter();  
+   for(unsigned int idx = 0; idx < area;++idx)
+   {
+      newDataPtr[0] = (ossim_uint8)ossim::clamp((*cloudData), 0.0, 255.0);
+      newDataPtr[1] = newDataPtr[0];
+      newDataPtr[2] = newDataPtr[0];
+      newDataPtr[3] = newDataPtr[0];
+      newDataPtr+=4;
+      ++cloudData;
+   }      
+   theImage = new osg::Image();
+   theImage->setImage(theCloudDataWidth, theCloudDataHeight, 1,
+                      GL_RGBA,
+                      GL_RGBA,
+                      GL_UNSIGNED_BYTE,
+                      newData,
+                      osg::Image::USE_NEW_DELETE);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetCompass.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetCompass.cpp
new file mode 100644
index 0000000..0278e8e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetCompass.cpp
@@ -0,0 +1,638 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Copyright (c) 2007, Arizona State University
+//  All rights reserved.
+//  BSD License: http://www.opensource.org/licenses/bsd-license.html
+//  Created by: Jeff Conner
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "ossimPlanet/ossimPlanetCompass.h"
+
+
+
+
+
+// #include "Usul/CommandLine/Arguments.h"
+
+#include "osgUtil/CullVisitor"
+
+#include "osgUtil/CullVisitor"
+#include "osgDB/ReadFile"
+#include "osg/MatrixTransform"
+#include "osg/Math"
+#include "osg/Texture2D"
+#include "osg/Image"
+#include "osg/Geometry"
+#include "osg/Geode"
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Update Callback for hiding and showing the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class CompassAnimationCallback : public osg::NodeCallback
+{
+public:
+   
+   CompassAnimationCallback(ossimPlanetCompass* compass, float start, float end, float step)
+      {
+         _start = start;
+         _end = end;
+         _step = step;
+         _compass = compass;
+      }
+   
+   virtual void operator() (osg::Node* node, osg::NodeVisitor* nv)
+      {
+         osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);    
+         if(0L != transform)
+         {
+            if(_compass->isAnimating())
+            {
+               if(_compass->isVisible())
+               {
+                  if (_start < _end)
+                  {
+                     _start += _step;
+                     if(_start > _end) _start = _end;
+                     transform->setMatrix(osg::Matrix::scale(_start,_start,_start));
+                     
+                  }
+                  else
+                  {
+                     _compass->setAnimation(false);
+                  }
+               }
+               else
+               {
+                  if (_start > _end)
+                  {
+                     _start -= _step;
+                     if(_start < _end) _start = _end;
+                     transform->setMatrix(osg::Matrix::scale(_start,_start,_start));
+                     
+                  }
+                  else
+                  {
+                     _compass->setAnimation(false);
+                  }
+               }
+            }
+         }   
+         traverse(node,nv);            
+         
+      }
+   
+protected:
+   
+   osg::ref_ptr<ossimPlanetCompass> _compass;
+   float               _angular_velocity;
+   float				_start;
+   float				_end;
+   float				_step; 
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Cull Callback for rotating the compass based on the current view matrix
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class CompassOrientationCallback : public osg::NodeCallback
+{
+public:
+   CompassOrientationCallback(ossimPlanetCompass *compass) :		
+      _scale(.07f)		
+      {
+         _compass = compass;
+         _pos = (osg::Vec3(_scale * 4.0f, _scale * -3.0f, -1.0f));
+         theHeadingFlag = true;
+         theRollFlag = true;
+         thePitchFlag = true;
+      }
+   virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
+      {
+         osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(nv);
+         if( 0L != cv)
+         {
+            osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
+            if( 0L != tx )
+            {
+               double h = theHeadingFlag?_compass->heading():0.0;
+               double p = thePitchFlag? _compass->pitch():0.0;
+               double r = theRollFlag?_compass->roll():0.0;
+
+               tx->setMatrix ( osg::Matrix::scale ( _compass->scale(),
+                                                    _compass->scale(),
+                                                    _compass->scale()) * 
+                               osg::Matrix::rotate ( osg::inDegrees ( h ),
+                                                     0.0f, 0.0f, 1.0f ) *
+                               osg::Matrix::rotate ( osg::inDegrees ( p ),
+                                                     1.0f, 0.0f, 0.0f ) *
+                               osg::Matrix::rotate ( osg::inDegrees ( r ),
+                                                     0.0f, 0.0f, 1.0f ) * // make it about z as well
+                               osg::Matrix::translate ( _compass->position() ) );
+            }
+         }
+         traverse( node, nv );
+      }
+   void setFlags(bool heading, bool pitch, bool roll)
+      {
+         theHeadingFlag = heading;
+         thePitchFlag = pitch;
+         theRollFlag = roll;
+      }
+protected:
+   bool theHeadingFlag;
+   bool theRollFlag;
+   bool thePitchFlag;
+
+   ossimPlanetCompass* _compass;
+   osg::Vec3 _pos;
+   float _scale;
+}; 
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Constructor/Destructor
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ossimPlanetCompass::ossimPlanetCompass():
+  _scale ( .07f ),
+  _numslices ( 32 ),
+  _radius ( .8 ),
+  theCompassGroup ( new osg::Group() ),
+  _showOrHideCompass ( true ),
+  _animating ( false ),
+  _rotateByView ( true ),
+  _heading ( 0.0f ),
+  _pitch ( 0.0f ),
+  _roll(0.0f)
+{
+   theCommonColorArray = new osg::Vec4Array();
+   theCommonColorArray->push_back(osg::Vec4(1.0,1.0,1.0,.5));
+   ossimFilename defaultTop    = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+   defaultTop  = defaultTop.dirCat("images");
+//   theRing     = defaultTop.dirCat("compassring.png");
+//   theInterior = defaultTop.dirCat("compassrose.png");
+   
+   this->setPositionByPercentage( 1.0f, 0.0f );
+#if 0  
+   if(theCompassFilename.exists())
+   {
+      theCompassObject = this->buildCompassObject(theCompassFilename);
+//      theCompassInteriorObject = this->buildCompassObject(theInterior);
+   }
+#endif
+   buildCompass();
+}
+
+ossimPlanetCompass::~ossimPlanetCompass(){}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Return the state of the compass: visible or not
+//
+///////////////////////////////////////////////////////////////////////////////
+
+bool ossimPlanetCompass::isVisible()
+{
+   return _showOrHideCompass;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the texture filename for the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setCompassTexture(const ossimFilename& fn)
+{
+   theCompassFilename = fn;
+   theCompassObject = this->buildCompassObject(theCompassFilename);
+}
+
+//void ossimPlanetCompass::setInterior(const ossimFilename& fn)
+//{
+//   theInterior = fn;
+//   theCompassInteriorObject = this->buildCompassObject(theInterior);
+//}
+//void ossimPlanetCompass::setInterior(const ossimFilename& fn)
+//{
+//   theCompassFilename = fn;
+//   theCompassObject = this->buildCompassObject(theCompassFilename);
+//}
+
+//void ossimPlanetCompass::setCompassTexture(const ossimFilename& ring,
+//                                           const ossimFilename& interior)
+//{
+//   setRing(ring);
+//   setInterior(interior);
+//}
+
+void ossimPlanetCompass::traverse(osg::NodeVisitor& nv)
+{
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   if(theCompassGroup.valid())
+   {
+      theCompassGroup->accept(nv);
+   }
+   osg::Node::traverse(nv);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Get the heading of the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+float ossimPlanetCompass::heading()
+{
+  return _heading;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the heading of the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setHeading(float r)
+{
+  _heading = r;
+}
+
+float ossimPlanetCompass::pitch ( )
+{
+   return _pitch;
+}
+
+void ossimPlanetCompass::setPitch ( float p )
+{
+   _pitch = p;
+}
+
+float ossimPlanetCompass::roll ( )
+{
+   return _roll;
+}
+
+void ossimPlanetCompass::setRoll(float r)
+{
+   _roll = r;
+}
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the heading of the compass based on a ( x = lon, y = lat ) position 
+//  and a ( x = lon, y = lat ) north.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setHeadingRelativeToNorth(const osg::Vec2& north, const osg::Vec2& pos)
+{
+  //FILE* debug = fopen ("C:/debug.txt","a");
+
+  osg::Vec2f p ( pos.x(), pos.y() );
+
+  /*if( p.x() > 180 )
+    p.set( p.x() - 180.0f , p.y() );*/
+ 
+  float theta =  atan ( ( north.y() - p.y() ) / ( north.x() -  p.x() ) );
+
+  //fprintf(debug,"N.x=%f , N.y=%f\tP.x=%f(%f) , P.y=%f\ttheta=%f\n",north.x(),north.y(),pos.x(),p.x(),p.y(),(theta * 180 / osg::PI) );
+  //fclose(debug);
+  this->setHeading( osg::RadiansToDegrees( theta ) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Get the position on the screen of the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+const osg::Vec3& ossimPlanetCompass::position()
+{
+  return _pos;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the position on the screen of the compass by absolute postion
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setPosition(const osg::Vec3& p)
+{
+  _pos = p;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the position on the screen of the compass by percentage of screen
+//  Pass in a float value between 0 and 1;
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setPositionByPercentage ( float width, float height )
+{
+  float w = ( _scale *  width * 8.0f ) - ( 4.0f * _scale );
+  float h = ( _scale *  height * 6.0f ) - ( 3.0f * _scale );
+
+  _pos = osg::Vec3(w, h, -1.0f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Get the xyz scale value of the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+float ossimPlanetCompass::scale()
+{
+  return _scale;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the xyz scale value of the compass
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setScale(float s)
+{
+  _scale = s;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Return true if the compass is in the act of showing or hiding
+//
+///////////////////////////////////////////////////////////////////////////////
+
+bool ossimPlanetCompass::isAnimating()
+{
+  return _animating;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set the animation state to trigger a show or hide.
+//  Use showCompass() or hideCompass() methods.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setAnimation(bool state)
+{
+  _animating = state;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//  true to use the view matrix
+//  false to use "by angle degree"
+//		- set using "setRotation" method.
+//		- call "updateCompass" after changing angle values to rebuild 
+//		  the compass
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::setRotateByViewMatrix(bool m)
+{
+  _rotateByView = m;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Rebuilds compass based upon animation show/hide parameters.
+//	Call this method to rebuild after changing parameters in a set method
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::updateCompass()
+{
+	if(_showOrHideCompass)
+		buildCompass();
+	if(!_showOrHideCompass && _animating)
+		buildCompass();
+	if(!_showOrHideCompass && !_animating)
+		_emptyCompass();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Build a triangle fan object to use as a compass face
+//
+///////////////////////////////////////////////////////////////////////////////
+
+osg::Geode* ossimPlanetCompass::buildTriangleFan(const ossimFilename& tex, float zoff, unsigned int render_level, const osg::Vec3& n)
+{
+   osg::ref_ptr< osg::Geode > geode ( new osg::Geode() );
+   osg::ref_ptr< osg::StateSet > stateset ( new osg::StateSet() );
+   osg::ref_ptr< osg::Image > image;
+
+   if(tex.exists())
+   {
+      image = osgDB::readImageFile( tex );
+   }
+   if ( image.get() )
+   {
+      osg::ref_ptr< osg::Texture2D > texture ( new osg::Texture2D() ); 
+      texture->setImage ( image.get() );
+      stateset->setTextureAttributeAndModes ( 0, texture.get(), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
+      stateset->setMode ( GL_BLEND, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
+      stateset->setMode ( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );    
+      stateset->setRenderingHint ( osg::StateSet::TRANSPARENT_BIN );
+      stateset->setRenderBinDetails ( render_level, "RenderBin" );
+      
+   }
+   
+   osg::ref_ptr< osg::Vec3Array > fan ( new osg::Vec3Array() );
+   osg::ref_ptr< osg::Vec2Array > fan_tex ( new osg::Vec2Array() );
+   
+   fan->reserve( _numslices +1 );
+   fan_tex->reserve( _numslices +1 );
+   
+   fan->push_back( osg::Vec3 ( 0.0f, 0.0f, zoff ) );
+   fan_tex->push_back( osg::Vec2 ( 0.5f, 0.5f ) );
+   
+   for ( unsigned int x = 0; x < _numslices + 1; ++x )
+   {	
+      float angle =  float ( x ) * ( ( 2 * osg::PI ) / _numslices );
+      fan->push_back ( osg::Vec3 ( _radius * ( cos( angle ) ), _radius * ( sin ( angle ) ), zoff ) );
+      fan_tex->push_back(osg::Vec2(0.5f + (0.5f * ( cos( angle ) ) ),0.5f +( 0.5f * ( sin ( angle ) ) ) ));
+   }
+   osg::ref_ptr< osg::Geometry > geometry ( new osg::Geometry() ); 
+   osg::ref_ptr< osg::Vec3Array > normal = new osg::Vec3Array;
+//    osg::ref_ptr< osg::Vec4Array > color ( new osg::Vec4Array() );
+//    color->push_back ( osg::Vec4 ( 1.0f, 1.0f, 1.0f, .5f ) );
+   geometry->setColorArray ( theCommonColorArray.get() );
+   geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
+   normal->push_back ( n );
+   
+   geometry->setVertexArray ( fan.get() );
+   
+   geometry->setTexCoordArray ( 0, fan_tex.get() );
+   
+   geometry->setNormalArray ( normal.get() );
+   
+   geometry->setNormalBinding ( osg::Geometry::BIND_OVERALL );
+   
+   geometry->addPrimitiveSet ( new osg::DrawArrays ( osg::PrimitiveSet::TRIANGLE_FAN, 0, fan->size() ) );
+   
+   geometry->setStateSet ( stateset.get() );
+   
+   geode->setStateSet ( stateset.get() );
+   
+   geode->addDrawable ( geometry.get() );
+   
+   return geode.release();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Build the acutal compass object, consisting of 2 textured triangle fans
+//
+///////////////////////////////////////////////////////////////////////////////
+
+osg::Node* ossimPlanetCompass::buildCompassObject(const ossimFilename& location)
+{
+  osg::ref_ptr < osg::Group > group ( new osg::Group() );
+  group->addChild ( this->buildTriangleFan ( location,
+                                             0.0f,
+                                             1001,
+                                             osg::Vec3 ( 0.0f, 0.0f, 1.0f ) ) );
+//   group->addChild ( this->_buildTriangleFan ( _botTexfn, -0.05f, 1000, osg::Vec3 ( 0.0f, 0.0f, 1.0f ) ) );
+  return group.release();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set matrix transforms for the compass.  Add the Cull and update callbacks
+//	for rotation and animation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+osg::Group* ossimPlanetCompass::initCompass()
+{
+   osg::ref_ptr<osg::Group> group = new osg::Group;
+   osg::ref_ptr < osg::MatrixTransform > rotRing ( new osg::MatrixTransform() );
+   osg::ref_ptr < osg::MatrixTransform > rotInterior ( new osg::MatrixTransform() );
+   osg::ref_ptr < osg::MatrixTransform > animRing ( new osg::MatrixTransform() );
+   osg::ref_ptr < osg::MatrixTransform > animInterior ( new osg::MatrixTransform() );
+   osg::ref_ptr < CompassOrientationCallback > rotation_callback_ring ( new CompassOrientationCallback ( this ) );
+//   osg::ref_ptr < CompassOrientationCallback > rotation_callback_interior ( new CompassOrientationCallback ( this ) );
+
+   rotation_callback_ring->setFlags(true, true, false);
+   //rotation_callback_interior->setFlags(false, true, true);
+   CompassAnimationCallback* animCallback = new CompassAnimationCallback ( this,
+                                                                          _animationStart,
+                                                                          _animationEnd,
+                                                                          _animationStep );
+   animRing->setUpdateCallback ( animCallback );
+   animInterior->setUpdateCallback ( animCallback );
+   rotRing->setCullCallback ( rotation_callback_ring.get() );
+  // rotInterior->setCullCallback ( rotation_callback_interior.get() );
+   
+   rotRing->setReferenceFrame ( osg::Transform::ABSOLUTE_RF );
+   //rotInterior->setReferenceFrame ( osg::Transform::ABSOLUTE_RF );
+
+   animRing->addChild ( theCompassObject.get() );
+  // animInterior->addChild ( theCompassInteriorObject.get() );
+   rotRing->addChild ( animRing.get() );
+   //rotInterior->addChild ( animInterior.get() );
+  // group->addChild(rotInterior.get());
+   group->addChild(rotRing.get());
+  
+   return group.release();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Remove all children from the compass group.  Called when compass is
+//  "hidden"
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::_emptyCompass()
+{
+   theCompassGroup->removeChildren ( 0, theCompassGroup->getNumChildren() );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Build the compass.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::buildCompass()
+{
+   osg::ref_ptr < osg::Group > group ( new osg::Group() );
+//    osg::ref_ptr < osg::Node > geode = _buildCompassObject();
+   
+   osg::ref_ptr < osg::StateSet > ss ( theCompassGroup->getOrCreateStateSet() );
+   ss->setRenderBinDetails ( 1000, "RenderBin" );
+   ss->setMode ( GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
+   ss->setMode ( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::INHERIT );
+   
+   theCompassGroup->removeChildren ( 0, theCompassGroup->getNumChildren() ); 
+   theCompassGroup->addChild ( initCompass (  ) );	
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set parameters to display the "show" animation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::_showCompass()
+{
+   _animationStart = 0.0f;
+   _animationEnd = 1.0f; 
+   _animationStep = 1.0f / 20.0f;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Set parameters to display the "hide" animation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+void ossimPlanetCompass::_hideCompass()
+{
+	_animationStart = 1.0f;
+	_animationEnd = 0.0f; 
+	_animationStep = -1 * (1.0f / 20.0f);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetCubeGrid.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetCubeGrid.cpp
new file mode 100644
index 0000000..66cd7f6
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetCubeGrid.cpp
@@ -0,0 +1,221 @@
+#include <ossimPlanet/ossimPlanetCubeGrid.h>
+#include <ossimPlanet/mkUtils.h>
+#include <iostream>
+
+ossim_uint32 ossimPlanetCubeGrid::getNumberOfFaces()const
+{
+   return 6;
+}
+void ossimPlanetCubeGrid::getPixelScale(double& dx,
+                                        double& dy,
+                                        ossimUnitType& pixelScaleUnits,
+                                        ossim_uint32 level,
+                                        ossim_uint64 /*row*/,
+                                        ossim_uint64 /*col*/)const
+{
+   dx = 90.0*(1.0/(1<<level));
+   dy = dx;
+   dx/=theTileWidth;
+   dy/=theTileHeight;
+   pixelScaleUnits = OSSIM_DEGREES;
+}
+
+void ossimPlanetCubeGrid::getWidthHeightInDegrees(double& deltaX,
+                                                  double& deltaY,
+                                                  ossim_uint32 level,
+                                                  ossim_uint64 /*row*/,
+                                                  ossim_uint64 /*col*/)const
+{
+   deltaX =  (90.0/((double)(1<<level)));
+   deltaY = deltaX;
+}
+
+void ossimPlanetCubeGrid::getGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                                       const osg::Vec3d& latLon)const
+{
+   osg::Vec2d ll((ossim::clamp((double)latLon[ossimPlanetGridUtility::LAT],
+                               (double)-90.0, (double)90.0)+90)/180,
+                 (ossim::wrap((double)latLon[ossimPlanetGridUtility::LON],
+                              (double)-180.0, (double)180.0)+180)/360);
+   int face_x = (int)(4 * ll[ossimPlanetGridUtility::LON]);
+   int face_y = (int)(2 * ll[ossimPlanetGridUtility::LAT] + 0.5);
+   if(face_x == 4)
+   {
+      face_x = 3;
+   }
+   if(face_y == 1)
+   {
+      gridPoint.theFace = face_x;
+   }
+   else
+   {
+      gridPoint.theFace = face_y < 1 ? 5 : 4;
+   }
+   gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 4 * ll[ossimPlanetGridUtility::LON] - face_x;
+   gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 2 * ll[ossimPlanetGridUtility::LAT] - 0.5;
+   if(gridPoint.theFace < 4) // equatorial calculations done
+   {
+//       gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 1-gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+      return;
+   }
+
+   double tmp=0.0;
+   if(gridPoint.theFace == 4) // north polar face
+   {
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 1.5 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = (2 * (gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] - 0.5) *
+                                                                     gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] + 0.5);
+      switch(face_x)
+      {
+         case 0: // bottom
+         {
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 0.5 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            break;
+         }
+         case 1: // right side, swap and reverse lat
+         {
+            tmp = gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 0.5 + gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = tmp;
+            break;
+         }
+         case 2: // top; reverse lat and lon
+         {
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 1 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 0.5 + gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            break;
+         }
+         case 3: // left side; swap and reverse lon
+         {
+            tmp = gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 0.5 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 1 - tmp;
+            break;
+         }
+      }
+   }
+   else // south polar face
+   {
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] += 0.5;
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = (2 * (gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] - 0.5) *
+                                                                     gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] + 0.5);
+      switch(face_x)
+      {
+         case 0: // left
+         {
+            tmp = gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 0.5 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = tmp;
+            break;
+         }
+         case 1: // top
+         {
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 0.5 + gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            break;
+         }
+         case 2: // right
+         {
+            tmp = gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 0.5 + gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 1 - tmp;
+            break;
+         }
+         case 3: // bottom
+         {
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = 1 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX];
+            gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 0.5 - gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+            break;
+         }
+      }
+   }
+}
+
+
+void ossimPlanetCubeGrid::getLatLon(osg::Vec3d& latLon,
+                                    const ossimPlanetGridUtility::GridPoint& gridPoint)const
+{
+   double offset = 0.0;
+   osg::Vec2d s(ossim::clamp(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX], 0.0, 1.0),
+                ossim::clamp(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY], 0.0, 1.0));
+   const osg::Vec3d& coord = gridPoint.theGlobalGridPoint; 
+   latLon[ossimPlanetGridUtility::HGT] = 0.0;
+   if(gridPoint.theFace < 4)
+   {
+      s[ossimPlanetGridUtility::GRIDX] = (coord[ossimPlanetGridUtility::GRIDX]+gridPoint.theFace)*.25;
+      s[ossimPlanetGridUtility::GRIDY] = (coord[ossimPlanetGridUtility::GRIDY] + 0.5)*0.5;
+//      latLon[ossimPlanetGridUtility::LON] = s[ossimPlanetGridUtility::GRIDX]*360.0 - 180.0;
+//      latLon[ossimPlanetGridUtility::LAT] = 90 - s[ossimPlanetGridUtility::GRIDY]*180.0;
+//      return;
+   }
+   else if(gridPoint.theFace == 4)
+   {
+      if(coord[ossimPlanetGridUtility::GRIDX] < coord[ossimPlanetGridUtility::GRIDY])
+      {
+         if(coord[ossimPlanetGridUtility::GRIDX] + coord[ossimPlanetGridUtility::GRIDY] < 1.0)
+         {
+            s[ossimPlanetGridUtility::GRIDX] = 1.0 - coord[ossimPlanetGridUtility::GRIDY];
+            s[ossimPlanetGridUtility::GRIDY] = coord[ossimPlanetGridUtility::GRIDX];
+            offset += 3;
+         }
+         else
+         {
+            s[ossimPlanetGridUtility::GRIDY] = 1.0 - coord[ossimPlanetGridUtility::GRIDY];
+            s[ossimPlanetGridUtility::GRIDX] = 1.0 - coord[ossimPlanetGridUtility::GRIDX];
+            offset += 2;
+         }
+      }
+      else if(coord[ossimPlanetGridUtility::GRIDX] + coord[ossimPlanetGridUtility::GRIDY] >= 1.0)
+      {
+         s[ossimPlanetGridUtility::GRIDX] = coord[ossimPlanetGridUtility::GRIDY];
+         s[ossimPlanetGridUtility::GRIDY] = 1.0 - coord[ossimPlanetGridUtility::GRIDX];
+         offset += 1.0;
+      }
+      s[ossimPlanetGridUtility::GRIDX] -= s[ossimPlanetGridUtility::GRIDY];
+      if(!ossim::almostEqual(s[ossimPlanetGridUtility::GRIDY], .5))
+      {
+         s[ossimPlanetGridUtility::GRIDX] *= .5/(.5 - s[ossimPlanetGridUtility::GRIDY]);
+      }
+      s[ossimPlanetGridUtility::GRIDX] = (s[ossimPlanetGridUtility::GRIDX] + offset)*0.25;
+      s[ossimPlanetGridUtility::GRIDY] = (s[ossimPlanetGridUtility::GRIDY] + 1.5)*.5;
+   }
+   else if(gridPoint.theFace == 5)
+   {
+      offset = 1.0;
+      if(coord[ossimPlanetGridUtility::GRIDX] > coord[ossimPlanetGridUtility::GRIDY])
+      {
+         if(coord[ossimPlanetGridUtility::GRIDX] + coord[ossimPlanetGridUtility::GRIDY] >= 1.0)
+         {
+            s[ossimPlanetGridUtility::GRIDX] = 1.0 - coord[ossimPlanetGridUtility::GRIDY];
+            s[ossimPlanetGridUtility::GRIDY] = coord[ossimPlanetGridUtility::GRIDX] - .5;
+            offset += 1.0;
+         }
+         else
+         {
+            s[ossimPlanetGridUtility::GRIDX] = 1.0 - coord[ossimPlanetGridUtility::GRIDX];
+            s[ossimPlanetGridUtility::GRIDY] = 0.5 - coord[ossimPlanetGridUtility::GRIDY];
+            offset+=2;
+         }
+      }
+      else
+      {
+         if(coord[ossimPlanetGridUtility::GRIDX] + coord[ossimPlanetGridUtility::GRIDY] < 1.0)
+         {
+            s[ossimPlanetGridUtility::GRIDX] = coord[ossimPlanetGridUtility::GRIDY];
+            s[ossimPlanetGridUtility::GRIDY] = 0.5 - coord[ossimPlanetGridUtility::GRIDX];
+            offset -= 1.0;
+         }
+         else
+         {
+            s[ossimPlanetGridUtility::GRIDY] = coord[ossimPlanetGridUtility::GRIDY] - 0.5;
+         }
+      }
+      if(!ossim::almostEqual((double)s[ossimPlanetGridUtility::GRIDY], (double)0.0))
+      {
+         s[ossimPlanetGridUtility::GRIDX] = (s[ossimPlanetGridUtility::GRIDX] - 0.5)*.5/s[ossimPlanetGridUtility::GRIDY] + .5;
+      }
+      s[ossimPlanetGridUtility::GRIDX] = (s[ossimPlanetGridUtility::GRIDX] + offset) *0.25;
+      s[ossimPlanetGridUtility::GRIDY] *=.5;
+   }
+   latLon[ossimPlanetGridUtility::LON] = s[ossimPlanetGridUtility::GRIDX]*360.0 - 180.0;
+   latLon[ossimPlanetGridUtility::LAT] = s[ossimPlanetGridUtility::GRIDY]*180.0 - 90.0;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetDatabasePager.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetDatabasePager.cpp
new file mode 100644
index 0000000..9bc4c53
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetDatabasePager.cpp
@@ -0,0 +1,583 @@
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+
+
+
+ossimPlanetDatabasePager::ossimPlanetDatabasePager()
+:DatabasePager()
+{
+}
+#if 0
+bool ossimPlanetDatabasePager::isRunning() const
+{
+   return DatabasePager::isRunning();
+}
+
+void ossimPlanetDatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
+{
+   DatabasePager::signalBeginFrame(framestamp);
+}
+
+void ossimPlanetDatabasePager::signalEndFrame()
+{
+   DatabasePager::signalEndFrame();
+}
+
+void ossimPlanetDatabasePager::updateSceneGraph(const osg::FrameStamp& frameStamp)
+{
+   DatabasePager::updateSceneGraph(frameStamp);
+}
+
+void ossimPlanetDatabasePager::compileGLObjects(osg::State& state,double& availableTime)
+{
+   DatabasePager::compileGLObjects(state, availableTime);
+}
+
+void ossimPlanetDatabasePager::compileAllGLObjects(osg::State& state)
+{
+   DatabasePager::compileAllGLObjects(state);
+}
+#endif
+#if 0
+#ifdef OSSIMPLANET_USE_PAGER
+
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <ossimPlanet/ossimPlanetPagedLandLod.h>
+#include <osg/Notify>
+#include <iostream>
+#include <osg/Texture>
+#include <osgDB/ReadFile>
+#include <algorithm>
+#include <osg/GraphicsThread>
+
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static int allocationCount = 0;
+#endif
+struct ossimPlanetDatabasePager::MyCompileOperation : public osg::GraphicsOperation
+{
+   MyCompileOperation(DatabasePager* databasePager);
+   virtual ~MyCompileOperation(){}
+   virtual void operator () (osg::GraphicsContext* context);
+   
+   osg::observer_ptr<DatabasePager> _databasePager;
+};
+
+ossimPlanetDatabasePager::MyCompileOperation::MyCompileOperation(osgDB::DatabasePager* databasePager):
+    osg::GraphicsOperation("DatabasePager::MyCompileOperation",false),
+    _databasePager(databasePager)
+{
+}
+
+void ossimPlanetDatabasePager::MyCompileOperation::operator () (osg::GraphicsContext* context)
+{
+    // osg::notify(osg::NOTICE)<<"Background thread compiling"<<std::endl;
+    if (_databasePager.valid()) _databasePager->compileAllGLObjects(*(context->getState())); 
+}
+
+struct ossimPlanetDatabasePager::MySortFileRequestFunctor
+{
+    bool operator() (const osg::ref_ptr<ossimPlanetDatabasePager::DatabaseRequest>& lhs,const osg::ref_ptr<ossimPlanetDatabasePager::DatabaseRequest>& rhs) const
+    {
+        if (lhs->_timestampLastRequest>rhs->_timestampLastRequest) return true;
+        else if (lhs->_timestampLastRequest<rhs->_timestampLastRequest) return false;
+        else return (lhs->_priorityLastRequest>rhs->_priorityLastRequest);
+    }
+};
+
+class ossimPlanetDatabasePager::MyFindCompileableGLObjectsVisitor : public osg::NodeVisitor
+{
+public:
+   MyFindCompileableGLObjectsVisitor(ossimPlanetDatabasePager::DataToCompile& dataToCompile, 
+                                     bool changeAutoUnRef, bool valueAutoUnRef,
+                                     bool changeAnisotropy, float valueAnisotropy,
+                                     ossimPlanetDatabasePager::DrawablePolicy drawablePolicy):
+            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+            _dataToCompile(dataToCompile),
+            _changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef),
+            _changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy),
+            _drawablePolicy(drawablePolicy)
+    {
+    }
+    
+    virtual void apply(osg::Node& node)
+    {
+        apply(node.getStateSet());
+
+        traverse(node);
+    }
+    
+    virtual void apply(osg::Geode& geode)
+    {
+        apply(geode.getStateSet());
+    
+        for(unsigned int i=0;i<geode.getNumDrawables();++i)
+        {
+            apply(geode.getDrawable(i));
+        }
+
+        traverse(geode);
+    }
+    
+    inline void apply(osg::StateSet* stateset)
+    {
+        if (stateset)
+        {
+            // search for the existance of any texture object attributes
+            bool foundTextureState = false;
+            for(unsigned int i=0;i<stateset->getTextureAttributeList().size();++i)
+            {
+                osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
+                if (texture)
+                {
+                    if (_changeAutoUnRef) texture->setUnRefImageDataAfterApply(_valueAutoUnRef);
+                    if (_changeAnisotropy) texture->setMaxAnisotropy(_valueAnisotropy);
+                    foundTextureState = true;
+                }
+            }
+
+            // if texture object attributes exist add the state to the list for later compilation.
+            if (foundTextureState)
+            {
+                //osg::notify(osg::DEBUG_INFO)<<"Found compilable texture state"<<std::endl;
+                _dataToCompile.first.insert(stateset);
+            }
+        }
+    }
+    
+    inline void apply(osg::Drawable* drawable)
+    {
+        apply(drawable->getStateSet());
+        
+        switch(_drawablePolicy)
+        {
+        case ossimPlanetDatabasePager::DO_NOT_MODIFY_DRAWABLE_SETTINGS: 
+             // do nothing, leave settings as they came in from loaded database.
+             // osg::notify(osg::NOTICE)<<"DO_NOT_MODIFY_DRAWABLE_SETTINGS"<<std::endl;
+             break;
+        case ossimPlanetDatabasePager::USE_DISPLAY_LISTS: 
+             drawable->setUseDisplayList(true);
+             drawable->setUseVertexBufferObjects(false);
+             break;
+        case ossimPlanetDatabasePager::USE_VERTEX_BUFFER_OBJECTS:
+             drawable->setUseDisplayList(true);
+             drawable->setUseVertexBufferObjects(true);
+             // osg::notify(osg::NOTICE)<<"USE_VERTEX_BUFFER_OBJECTS"<<std::endl;
+             break;
+        case ossimPlanetDatabasePager::USE_VERTEX_ARRAYS:
+             drawable->setUseDisplayList(false);
+             drawable->setUseVertexBufferObjects(false);
+             // osg::notify(osg::NOTICE)<<"USE_VERTEX_ARRAYS"<<std::endl;
+             break;
+        }
+        
+        if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects())
+        {
+            // osg::notify(osg::NOTICE)<<"  Found compilable drawable"<<std::endl;
+            _dataToCompile.second.push_back(drawable);
+        }
+    }
+    
+    ossimPlanetDatabasePager::DataToCompile&   _dataToCompile;
+    bool                            _changeAutoUnRef;
+    bool                            _valueAutoUnRef;
+    bool                            _changeAnisotropy;
+    float                           _valueAnisotropy;
+    ossimPlanetDatabasePager::DrawablePolicy   _drawablePolicy;
+};
+
+ossimPlanetDatabasePager::ossimPlanetDatabasePager()
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++allocationCount;
+   std::cout << "ossimPlanetDatabasePager Count: " << allocationCount << std::endl;
+#endif
+}
+ossimPlanetDatabasePager::~ossimPlanetDatabasePager()
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   --allocationCount;
+   std::cout << "ossimPlanetDatabasePager Count: " << allocationCount << std::endl;
+#endif
+}
+
+int ossimPlanetDatabasePager::cancel()
+{
+   return osgDB::DatabasePager::cancel();
+}
+
+void ossimPlanetDatabasePager::invalidateRequest(const std::string& requestString)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
+   bool foundEntry = false;
+   for(DatabaseRequestList::iterator ritr = _fileRequestList.begin();
+       ritr != _fileRequestList.end() && !foundEntry;
+       ++ritr)
+   {
+      if ((*ritr)->_fileName==requestString)
+      {
+         (*ritr)->_frameNumberLastRequest = _frameNumber - 100000;
+         foundEntry = true;
+      }
+   }
+}
+
+void ossimPlanetDatabasePager::removeRequest(osg::Group* group)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
+      for(DatabaseRequestList::iterator ritr = _fileRequestList.begin();
+          ritr != _fileRequestList.end();
+          ++ritr)
+      {
+         if ((*ritr)->_groupForAddingLoadedSubgraph==group)
+         {
+            _fileRequestList.erase(ritr);
+            break;
+         }
+      }
+   }
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
+      for(DatabaseRequestList::iterator ritr = _dataToCompileList.begin();
+          ritr != _dataToCompileList.end();
+          ++ritr)
+      {
+         if ((*ritr)->_groupForAddingLoadedSubgraph==group)
+         {
+            _dataToCompileList.erase(ritr);
+            break;
+         }
+      }
+   }
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
+      for(DatabaseRequestList::iterator ritr = _dataToMergeList.begin();
+          ritr != _dataToMergeList.end();
+          ++ritr)
+      {
+         if ((*ritr)->_groupForAddingLoadedSubgraph==group)
+         {
+            _dataToMergeList.erase(ritr);
+            break;
+         }
+      }
+   }
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_fileRequestListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(_dataToCompileListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock3(_dataToMergeListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock4(_childrenToDeleteListMutex);
+      updateDatabasePagerThreadBlock();
+      if(_dataToMergeList.empty()&&
+         _dataToCompileList.empty()&&
+         _fileRequestList.empty()&&
+         _childrenToDeleteList.empty())
+      {
+         notifyNoMoreWork();
+      }
+   }
+}
+
+void ossimPlanetDatabasePager::addToDeleteList(osg::Object* obj)
+{
+   if (_deleteRemovedSubgraphsInDatabaseThread)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_childrenToDeleteListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_fileRequestListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(_dataToCompileListMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock3(_dataToMergeListMutex);
+      _childrenToDeleteList.push_back(obj);
+      notifyDoingWork();
+      updateDatabasePagerThreadBlock();
+   }
+}
+
+void ossimPlanetDatabasePager::requestNodeFile(const std::string& fileName,
+                                             osg::Group* group,
+                                             float priority,
+                                             const osg::FrameStamp* framestamp)
+{
+   DatabasePager::requestNodeFile(fileName,
+                                  group,
+                                  priority,
+                                  framestamp);
+   notifyDoingWork();
+}
+
+void ossimPlanetDatabasePager::run()
+{
+   osg::notify(osg::INFO)<<"DatabasePager::run()"<<std::endl;
+   
+   // need to set the texture object manager to be able to reuse textures
+   osg::Texture::setMinimumNumberOfTextureObjectsToRetainInCache(100);
+   
+   // need to set the texture object manager to be able to reuse textures
+   osg::Drawable::setMinimumNumberOfDisplayListsToRetainInCache(500);
+   
+   bool firstTime = true;
+   
+   do
+   {
+     _databasePagerThreadBlock->block();
+      //
+      // delete any children if required.
+      //
+//       if (_deleteRemovedSubgraphsInDatabaseThread)
+      {
+         osg::ref_ptr<osg::Object> obj = 0;
+         {
+            int deleteCount = 0;
+            int deleteCountMax = 20;
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_childrenToDeleteListMutex);
+            while (!_childrenToDeleteList.empty()&&(deleteCount < deleteCountMax))
+            {
+               //osg::notify(osg::NOTICE)<<"In DatabasePager thread deleting "<<_childrenToDeleteList.size()<<" objects"<<std::endl;
+               //osg::Timer_t before = osg::Timer::instance()->tick();
+               obj = _childrenToDeleteList.back();
+               _childrenToDeleteList.pop_back();
+               //osg::notify(osg::NOTICE)<<"Done DatabasePager thread deleted in "<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms"<<" objects"<<std::endl;
+               ++deleteCount;
+            }
+            updateDatabasePagerThreadBlock();
+         }
+      }
+      
+      //
+      // load any subgraphs that are required.
+      //
+      osg::ref_ptr<DatabaseRequest> databaseRequest;
+      
+      // get the front of the file request list.
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
+         if (!_fileRequestList.empty())
+         {
+            std::sort(_fileRequestList.begin(),_fileRequestList.end(),MySortFileRequestFunctor());
+            databaseRequest = _fileRequestList.front();
+         }
+      }
+      
+      if (databaseRequest.valid())
+      {
+         // check if databaseRequest is still relevant
+         if (_frameNumber-databaseRequest->_frameNumberLastRequest<=1)
+         {
+            
+            // assume that we only have one DatabasePager, or that readNodeFile is thread safe...
+            databaseRequest->_loadedModel = osgDB::readNodeFile(databaseRequest->_fileName,
+                                                                databaseRequest->_loadOptions.get());
+            
+            //osg::notify(osg::NOTICE)<<"     node read in "<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms"<<std::endl;
+            
+            bool loadedObjectsNeedToBeCompiled = false;
+            
+            if (_doPreCompile && databaseRequest->_loadedModel.valid() && !_activeGraphicsContexts.empty())
+            {
+               // force a compute of the loaded model's bounding volume, so that when the subgraph
+               // merged with the main scene graph and large computeBound() isn't incurred.
+               databaseRequest->_loadedModel->getBound();
+               
+               
+               ActiveGraphicsContexts::iterator itr = _activeGraphicsContexts.begin();
+               
+               DataToCompile& dtc = databaseRequest->_dataToCompileMap[*itr];
+               ++itr;                
+               
+               // find all the compileable rendering objects
+               MyFindCompileableGLObjectsVisitor frov(dtc, 
+                                                      _changeAutoUnRef, _valueAutoUnRef,
+                                                      _changeAnisotropy, _valueAnisotropy,
+                                                      _drawablePolicy);
+               
+               databaseRequest->_loadedModel->accept(frov);
+               
+               if (!dtc.first.empty() || !dtc.second.empty())
+               {
+                  loadedObjectsNeedToBeCompiled = true;                
+                  
+                  // copy the objects from the compile list to the other graphics context list.
+                  for(;
+                      itr != _activeGraphicsContexts.end();
+                      ++itr)
+                  {
+                     databaseRequest->_dataToCompileMap[*itr] = dtc;
+                  }
+               }
+            }            
+            
+            // move the databaseRequest from the front of the fileRequest to the end of
+            // dataToCompile or dataToMerge lists.
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
+               
+               DatabaseRequestList::iterator itr = std::find(_fileRequestList.begin(),_fileRequestList.end(),databaseRequest);
+               if (itr != _fileRequestList.end()) 
+               {
+                  if (databaseRequest->_loadedModel.valid())
+                  {
+                     if (loadedObjectsNeedToBeCompiled)
+                     {
+                        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
+			_dataToCompileList.push_back(databaseRequest);
+                        notifyUpdateSceneGraph();
+                     }
+                     else
+                     {
+                        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
+                        _dataToMergeList.push_back(databaseRequest);
+			notifyUpdateSceneGraph();
+                     }
+                  }        
+                  _fileRequestList.erase(itr);
+               }
+               
+               updateDatabasePagerThreadBlock();
+            }
+            
+            if (loadedObjectsNeedToBeCompiled)
+            {
+               for(ActiveGraphicsContexts::iterator itr = _activeGraphicsContexts.begin();
+                   itr != _activeGraphicsContexts.end();
+                   ++itr)
+               {
+                  osg::GraphicsContext* gc = osg::GraphicsContext::getCompileContext(*itr);
+                  if (gc)
+                  {   
+                     osg::GraphicsThread* gt = gc->getGraphicsThread();
+                     if (gt)
+                     {
+                        gt->add(new ossimPlanetDatabasePager::MyCompileOperation(this));
+                     }
+                     else
+                     {
+                        gc->makeCurrent();
+                        
+                        compileAllGLObjects(*(gc->getState()));
+                        
+                        gc->releaseContext();
+                     }
+                  }
+               }
+               
+               // osg::notify(osg::NOTICE)<<"Done compiling in paging thread"<<std::endl;                   
+            }
+            
+         }
+         else
+         {
+            //std::cout<<"frame number delta for "<<databaseRequest->_fileName<<" "<<_frameNumber-databaseRequest->_frameNumberLastRequest<<std::endl;
+            // remove the databaseRequest from the front of the fileRequest to the end of
+            // dataLoad list as its is no longer relevant
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
+            
+            if (!_fileRequestList.empty()) _fileRequestList.erase(_fileRequestList.begin());
+            
+            updateDatabasePagerThreadBlock();
+            
+         }
+      }
+      else
+      {
+      }
+      // go to sleep till our the next time our thread gets scheduled.
+      
+      if (firstTime)
+      {
+         // do a yield to get round a peculiar thread hang when testCancel() is called 
+         // in certain cirumstances - of which there is no particular pattern.
+         YieldCurrentThread();
+         firstTime = false;
+      }
+      
+   } while (!testCancel() && !_done);
+}
+
+void ossimPlanetDatabasePager::clearRequests()
+{
+   DatabasePager::clear();
+}
+
+void ossimPlanetDatabasePager::updateSceneGraph(double currentFrameTime)
+{
+   osgDB::DatabasePager::updateSceneGraph(currentFrameTime);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_fileRequestListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(_dataToCompileListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock3(_dataToMergeListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock4(_childrenToDeleteListMutex);
+   if(_dataToMergeList.empty()&&
+      _dataToCompileList.empty()&&
+      _fileRequestList.empty()&&
+      _childrenToDeleteList.empty())
+   {
+      notifyNoMoreWork();
+   }
+   updateDatabasePagerThreadBlock();
+}
+
+bool ossimPlanetDatabasePager::listsAreEmpty()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_fileRequestListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(_dataToCompileListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock3(_dataToMergeListMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock4(_childrenToDeleteListMutex);
+
+   return (_dataToMergeList.empty()&&
+           _dataToCompileList.empty()&&
+           _fileRequestList.empty()&&
+           _childrenToDeleteList.empty());
+}
+
+void ossimPlanetDatabasePager::addCallback(osg::ref_ptr<ossimPlanetDatabasePager::Callback> callback)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   ossimPlanetDatabasePager::CallbackListType::iterator i = std::find(theCallbackList.begin(),
+                                                             theCallbackList.end(),
+                                                             callback);
+   if(i == theCallbackList.end())
+   {
+      theCallbackList.push_back(callback);
+   }
+}
+
+void ossimPlanetDatabasePager::removeCallback(osg::ref_ptr<ossimPlanetDatabasePager::Callback> callback)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   ossimPlanetDatabasePager::CallbackListType::iterator i = std::find(theCallbackList.begin(),
+                                                             theCallbackList.end(),
+                                                             callback);
+   if(i != theCallbackList.end())
+   {
+      theCallbackList.erase(i);
+   }
+}
+
+void ossimPlanetDatabasePager::notifyDoingWork()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      theCallbackList[idx]->doingWork();
+   }
+}
+
+void ossimPlanetDatabasePager::notifyNoMoreWork()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      theCallbackList[idx]->noMoreWork();
+   }
+}
+
+void ossimPlanetDatabasePager::notifyUpdateSceneGraph()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCallbackList.size(); ++idx)
+   {
+      theCallbackList[idx]->updateSceneGraph();
+   }
+}
+#endif
+#endif
\ No newline at end of file
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetDepthPartitionNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetDepthPartitionNode.cpp
new file mode 100644
index 0000000..2b70875
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetDepthPartitionNode.cpp
@@ -0,0 +1,272 @@
+/* OpenSceneGraph example, osgdepthpartion.
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#include <ossimPlanet/ossimPlanetDepthPartitionNode.h>
+#include <osgUtil/CullVisitor>
+
+using namespace osg;
+
+#define CURRENT_CLASS ossimPlanetDepthPartitionNode
+
+CURRENT_CLASS::CURRENT_CLASS()
+{
+    _distAccumulator = new ossimPlanetDistanceAccumulator;
+    init();
+}
+
+CURRENT_CLASS::CURRENT_CLASS(const CURRENT_CLASS& dpn, const osg::CopyOp& copyop)
+    : osg::Group(dpn, copyop),
+          _active(dpn._active),
+          _renderOrder(dpn._renderOrder),
+          _clearColorBuffer(dpn._clearColorBuffer)
+{
+    _distAccumulator = new ossimPlanetDistanceAccumulator;
+    _numCameras = 0;
+}
+
+CURRENT_CLASS::~CURRENT_CLASS() {}
+
+void CURRENT_CLASS::init()
+{
+    _active = true;
+    _numCameras = 0;
+    setCullingActive(false);
+    _renderOrder = osg::Camera::POST_RENDER;
+    _clearColorBuffer = true;
+}
+
+void CURRENT_CLASS::setActive(bool active)
+{
+    if(_active == active) return;
+    _active = active;
+}
+
+void CURRENT_CLASS::setClearColorBuffer(bool clear)
+{
+    _clearColorBuffer = clear;
+
+    // Update the render order for the first Camera if it exists
+    if(!_cameraList.empty())
+    {
+      if(clear) 
+        _cameraList[0]->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+      else  
+        _cameraList[0]->setClearMask(GL_DEPTH_BUFFER_BIT);
+    }
+}
+
+void CURRENT_CLASS::setRenderOrder(osg::Camera::RenderOrder order)
+{
+    _renderOrder = order;
+
+    // Update the render order for existing Cameras
+    unsigned int numCameras = _cameraList.size();
+    for(unsigned int i = 0; i < numCameras; i++)
+    {
+      _cameraList[i]->setRenderOrder(_renderOrder);
+    }
+}
+
+void CURRENT_CLASS::traverse(osg::NodeVisitor &nv)
+{
+    // If the scene hasn't been defined then don't do anything
+    unsigned int numChildren = _children.size();
+    if(numChildren == 0) return;
+
+    // If the node is not active then don't analyze it
+    if(!_active)
+    {
+      // Traverse the graph as usual
+      Group::traverse(nv);
+      return;
+    }
+
+    // If the visitor is not a cull visitor, pass it directly onto the scene.
+    osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+    if(!cv) 
+    { 
+      Group::traverse(nv);
+      return; 
+    }
+
+    // We are in the cull traversal, so first collect information on the
+    // current modelview and projection matrices and viewport.
+    osg::RefMatrix& modelview = *(cv->getModelViewMatrix());
+    osg::RefMatrix& projection = *(cv->getProjectionMatrix());
+    osg::Viewport* viewport = cv->getViewport();
+
+    // Prepare for scene traversal.
+    _distAccumulator->setMatrices(modelview, projection);
+    _distAccumulator->setNearFarRatio(cv->getNearFarRatio());
+    _distAccumulator->reset();
+
+    // Step 1: Traverse the children, collecting the near/far distances.
+    unsigned int i;
+    for(i = 0; i < numChildren; i++)
+    {
+      _children[i]->accept(*(_distAccumulator.get()));
+    }
+
+    // Step 2: Compute the near and far distances for every Camera that
+    // should be used to render the scene.
+    _distAccumulator->computeCameraPairs();
+
+    // Step 3: Create the Cameras, and add them as children.
+    ossimPlanetDistanceAccumulator::PairList& camPairs = _distAccumulator->getCameraPairs();
+    _numCameras = camPairs.size(); // Get the number of cameras
+
+    // Create the Cameras, and add them as children.
+    if(_numCameras > 0)
+    {
+      osg::Camera *currCam;
+      ossimPlanetDistanceAccumulator::DistancePair currPair;
+
+      for(i = 0; i < _numCameras; i++)
+      {
+        // Create the camera, and clamp it's projection matrix
+        currPair = camPairs[i];  // (near,far) pair for current camera
+        currCam = createOrReuseCamera(projection, currPair.first, 
+                                      currPair.second, i);
+
+        // Set the modelview matrix and viewport of the camera
+        currCam->setViewMatrix(modelview);
+        currCam->setViewport(viewport);
+
+        // Redirect the CullVisitor to the current camera
+        currCam->accept(nv);
+      }
+
+      // Set the clear color for the first camera
+      _cameraList[0]->setClearColor(cv->getRenderStage()->getClearColor());
+    }
+}
+
+bool CURRENT_CLASS::addChild(osg::Node *child)
+{
+    return insertChild(_children.size(), child);
+}
+
+bool CURRENT_CLASS::insertChild(unsigned int index, osg::Node *child)
+{
+    if(!Group::insertChild(index, child)) return false; // Insert child
+
+    // Insert child into each Camera
+    unsigned int totalCameras = _cameraList.size();
+    for(unsigned int i = 0; i < totalCameras; i++)
+    {
+      _cameraList[i]->insertChild(index, child);
+    }
+    return true;
+}
+
+
+bool CURRENT_CLASS::removeChildren(unsigned int pos, unsigned int numRemove)
+{
+    if(!Group::removeChildren(pos, numRemove)) return false; // Remove child
+
+    // Remove child from each Camera
+    unsigned int totalCameras = _cameraList.size();
+    for(unsigned int i = 0; i < totalCameras; i++)
+    {
+      _cameraList[i]->removeChildren(pos, numRemove);
+    }
+    return true;
+}
+
+bool CURRENT_CLASS::setChild(unsigned int i, osg::Node *node)
+{
+    if(!Group::setChild(i, node)) return false; // Set child
+
+    // Set child for each Camera
+    unsigned int totalCameras = _cameraList.size();
+    for(unsigned int j = 0; j < totalCameras; j++)
+    {
+      _cameraList[j]->setChild(i, node);
+    }
+    return true;
+}
+
+osg::Camera* CURRENT_CLASS::createOrReuseCamera(const osg::Matrix& proj, 
+                            double znear, double zfar, 
+                            const unsigned int &camNum)
+{
+    if(_cameraList.size() <= camNum) _cameraList.resize(camNum+1);
+    osg::Camera *camera = _cameraList[camNum].get();
+    
+    if(!camera) // Create a new Camera
+    {
+      camera = new osg::Camera;
+      camera->setCullingActive(false);
+      camera->setRenderOrder(_renderOrder);
+      camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+
+      // We will compute the near/far planes ourselves
+      camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+      camera->setCullingMode(osg::CullSettings::ENABLE_ALL_CULLING);
+
+      if(camNum == 0 && _clearColorBuffer)
+        camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+      else
+        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
+
+      // Add our children to the new Camera's children
+      unsigned int numChildren = _children.size();
+      for(unsigned int i = 0; i < numChildren; i++)
+      {
+        camera->addChild(_children[i].get());
+      }
+
+      _cameraList[camNum] = camera;
+    }
+
+    osg::Matrixd &projection = camera->getProjectionMatrix();
+    projection = proj;
+
+    // Slightly inflate the near & far planes to avoid objects at the
+    // extremes being clipped out.
+    znear *= 0.999;
+    zfar *= 1.001;
+
+    // Clamp the projection matrix z values to the range (near, far)
+    double epsilon = 1.0e-6;
+    if(fabs(projection(0,3)) < epsilon &&
+       fabs(projection(1,3)) < epsilon &&
+       fabs(projection(2,3)) < epsilon ) // Projection is Orthographic
+    {
+      epsilon = -1.0/(zfar - znear); // Used as a temp variable
+      projection(2,2) = 2.0*epsilon;
+      projection(3,2) = (zfar + znear)*epsilon;
+    }
+    else // Projection is Perspective
+    {
+      double trans_near = (-znear*projection(2,2) + projection(3,2)) /
+                          (-znear*projection(2,3) + projection(3,3));
+      double trans_far = (-zfar*projection(2,2) + projection(3,2)) /
+                         (-zfar*projection(2,3) + projection(3,3));
+      double ratio = fabs(2.0/(trans_near - trans_far));
+      double center = -0.5*(trans_near + trans_far);
+
+      projection.postMult(osg::Matrixd(1.0, 0.0, 0.0, 0.0,
+                                       0.0, 1.0, 0.0, 0.0,
+                            0.0, 0.0, ratio, 0.0,
+                       0.0, 0.0, center*ratio, 1.0));
+    }
+
+    return camera;
+}
+#undef CURRENT_CLASS
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetDestinationCommandAction.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetDestinationCommandAction.cpp
new file mode 100644
index 0000000..81530bd
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetDestinationCommandAction.cpp
@@ -0,0 +1,97 @@
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+#include <ossim/base/ossimCommon.h>
+
+const char ossimPlanetDestinationCommandAction::theWhitespace[] = " \t";
+
+ossimPlanetDestinationCommandAction::ossimPlanetDestinationCommandAction(const ossimString& code, 
+                                                                         const ossimString& originatingFederate)
+:ossimPlanetAction(originatingFederate)
+{
+   setSourceCode(code);
+}
+
+ossimString ossimPlanetDestinationCommandAction::argListSource() const
+{
+   int start = -1;
+   
+   if (theCommand != "#") 
+   {
+      start = theSourceCode.find_first_not_of(theWhitespace, 0);   // eat leading whitespace
+      int end = theSourceCode.find_first_of(theWhitespace, start);
+      start = theSourceCode.find_first_not_of(theWhitespace, end); // eat target
+      end = theSourceCode.find_first_of(theWhitespace, start);
+      start = theSourceCode.find_first_not_of(theWhitespace, end); // eat command
+      
+   }
+   return (start > 0) ? ossimString(theSourceCode.substr(start, theSourceCode.length() - start)) :
+      ossimString();
+}
+
+bool ossimPlanetDestinationCommandAction::setSourceCode(const ossimString& newSourcecode)
+{
+   bool result = true;
+   theSourceCode = newSourcecode;
+   
+   int start = theSourceCode.find_first_not_of(theWhitespace, 0);
+   bool isComment = start < 0 || theSourceCode[(size_t)start] == '#';
+   
+   if (isComment) 
+   {
+      theTokens.clear();
+      theTokens.push_back(":");
+      theTokens.push_back("#");
+   }
+   else
+   {
+      bool unbalancedBraces;
+      ossim::lexQuotedTokens(theSourceCode, start, theWhitespace, "{}", theTokens, unbalancedBraces);
+      if (unbalancedBraces || theTokens.size() == 1)
+      {
+         theTokens.clear();
+         theTokens.push_back(":");
+         theTokens.push_back("#syntaxerror");
+         result = false;
+      }
+   }
+   theArgCount = 0;
+   if(theTokens.size() > 2)
+   {
+      theArgCount = theTokens.size()-2;
+   }
+   
+   setTarget(theTokens[0]);
+   setCommand(theTokens[1]);
+   
+   return result;
+}
+
+void ossimPlanetDestinationCommandAction::print(std::ostream& s)const
+{
+   const char* pre[]  = {"", "{"};
+   const char* postToken[] = {" ", "", "} ", "}" };
+   ossim_uint32 i;
+   for (i = 0; i < theTokens.size(); i++) 
+   {
+      ossim_int32 needsQuoting = theTokens[i].empty() || (int)theTokens[i].find_first_of(theWhitespace, 0) != -1;
+      ossim_int32 lastToken = i == theTokens.size() - 1;
+      s << pre[needsQuoting] << theTokens[i] << postToken[2*needsQuoting + lastToken];
+   }
+}
+
+void ossimPlanetDestinationCommandAction::read(std::istream& s)
+{
+   ossimString buffer;
+   buffer.reserve(1000);
+   
+   // read arbitrary length line from s into buffer.
+   char c;
+   for (s.get(c); s.gcount() == 1 && c != '\n' && !s.eof(); s.get(c))
+      buffer.append(1, c);
+   
+   // init the ossimPlanetAction
+   if (s || s.eof()) 
+   {
+      setSourceCode(buffer);
+   } 
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetDistanceAccumulator.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetDistanceAccumulator.cpp
new file mode 100644
index 0000000..432a9bb
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetDistanceAccumulator.cpp
@@ -0,0 +1,402 @@
+/* OpenSceneGraph example, osgdepthpartion.
+*
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+#include <ossimPlanet/ossimPlanetDistanceAccumulator.h>
+#include <osg/Geode>
+#include <osg/Transform>
+#include <osg/Projection>
+#include <algorithm>
+#include <math.h>
+#include <limits.h>
+
+/** Function that sees whether one DistancePair should come before another in
+    an sorted list. Used to sort the vector of DistancePairs. */
+static bool precedes(const ossimPlanetDistanceAccumulator::DistancePair &a, 
+              const ossimPlanetDistanceAccumulator::DistancePair &b)
+{
+    // This results in sorting in order of descending far distances
+    if(a.second > b.second) return true;
+    else return false;
+}
+
+/** Computes distance (in z direction) betwen a point and the viewer's eye,
+    given by a view matrix */
+static double distance(const osg::Vec3 &coord, const osg::Matrix& matrix)
+{
+    // Here we are taking only the z coordinate of the point transformed
+    // by the matrix, ie coord*matrix. The negative sign is because we
+    // want to consider into the screen as INCREASING distance.
+    return -( coord[0]*matrix(0,2) + coord[1]*matrix(1,2) +
+              coord[2]*matrix(2,2) + matrix(3,2) );
+}
+
+#define CURRENT_CLASS ossimPlanetDistanceAccumulator
+CURRENT_CLASS::CURRENT_CLASS()
+    : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), 
+      _nearFarRatio(0.0005), _maxDepth(UINT_MAX)
+{
+    setMatrices(osg::Matrix::identity(), osg::Matrix::identity());
+    reset();
+}
+
+CURRENT_CLASS::~CURRENT_CLASS() {}
+
+void CURRENT_CLASS::pushLocalFrustum()
+{
+    osg::Matrix& currMatrix = _viewMatrices.back();
+
+    // Compute the frustum in local space
+    osg::Polytope localFrustum;
+    localFrustum.setToUnitFrustum(false, false);
+    localFrustum.transformProvidingInverse(currMatrix*_projectionMatrices.back());
+    _localFrusta.push_back(localFrustum);
+
+    // Compute new bounding box corners
+    bbCornerPair corner;
+    corner.second = (currMatrix(0,2)<=0?1:0) |
+                    (currMatrix(1,2)<=0?2:0) |
+                    (currMatrix(2,2)<=0?4:0);
+    corner.first = (~corner.second)&7;
+    _bbCorners.push_back(corner);
+}
+
+void CURRENT_CLASS::pushDistancePair(double zNear, double zFar)
+{
+    if(zFar > 0.0) // Make sure some of drawable is visible
+    {
+      // Make sure near plane is in front of viewpoint.
+      if(zNear <= 0.0)
+      {
+        zNear = zFar*_nearFarRatio;
+        if(zNear >= 1.0) zNear = 1.0; // 1.0 limit chosen arbitrarily!
+      }
+
+      // Add distance pair for current drawable
+      _distancePairs.push_back(DistancePair(zNear, zFar));
+
+      // Override the current nearest/farthest planes if necessary
+      if(zNear < _limits.first) _limits.first = zNear;
+      if(zFar > _limits.second) _limits.second = zFar;
+    }
+}
+
+/** Return true if the node should be traversed, and false if the bounding sphere
+    of the node is small enough to be rendered by one Camera. If the latter
+    is true, then store the node's near & far plane distances. */
+bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node)
+{
+    // Allow traversal to continue if we haven't reached maximum depth.
+    bool keepTraversing = (_currentDepth < _maxDepth);
+
+    osg::BoundingSphere bs = node.getBound();
+    double zNear = 0.0, zFar = 0.0;
+
+    // Make sure bounding sphere is valid
+    if(bs.valid())
+    {
+      // Make sure bounding sphere is within the viewing volume
+      if(!_localFrusta.back().contains(bs)) keepTraversing = false;
+
+      else // Compute near and far planes for this node
+      {
+        // Since the view matrix could involve complex transformations,
+        // we need to determine a new BoundingSphere that would encompass
+        // the transformed BoundingSphere.
+        const osg::Matrix &l2w = _viewMatrices.back();
+
+        // Get the transformed x-axis of the BoundingSphere
+        osg::Vec3d newX = bs._center;
+        newX.x() += bs._radius; // Get X-edge of bounding sphere
+        newX = newX * l2w;
+
+        // Get the transformed y-axis of the BoundingSphere
+        osg::Vec3d newY = bs._center;
+        newY.y() += bs._radius; // Get Y-edge of bounding sphere
+        newY = newY * l2w;
+
+        // Get the transformed z-axis of the BoundingSphere
+        osg::Vec3d newZ = bs._center;
+        newZ.z() += bs._radius; // Get Z-edge of bounding sphere
+        newZ = newZ * l2w;
+
+        // Get the transformed center of the BoundingSphere
+        bs._center = bs._center * l2w;
+
+        // Compute lengths of transformed x, y, and z axes
+        double newXLen = (newX - bs._center).length();
+        double newYLen = (newY - bs._center).length();
+        double newZLen = (newZ - bs._center).length();
+
+        // The encompassing radius is the max of the transformed lengths
+        bs._radius = newXLen;
+        if(newYLen > bs._radius) bs._radius = newYLen;
+        if(newZLen > bs._radius) bs._radius = newZLen;
+
+        // Now we can compute the near & far planes, noting that for
+        // complex view transformations (ie. involving scales) the new
+        // BoundingSphere may be bigger than the original one.
+        // Note that the negative sign on the bounding sphere center is
+        // because we want distance to increase INTO the screen.
+        zNear = -bs._center.z() - bs._radius;
+        zFar = -bs._center.z() + bs._radius;
+
+        // If near/far ratio is big enough, then we don't need to keep
+        // traversing children of this node.
+        if(zNear >= zFar*_nearFarRatio) keepTraversing = false;
+      }
+    }
+
+    // If traversal should stop, then store this node's (near,far) pair
+    if(!keepTraversing) pushDistancePair(zNear, zFar);
+
+    return keepTraversing;
+}
+
+void CURRENT_CLASS::apply(osg::Node &node)
+{
+    if(shouldContinueTraversal(node))
+    {
+      // Traverse this node
+      ++_currentDepth;
+      traverse(node);
+      --_currentDepth;
+    }
+}
+
+void CURRENT_CLASS::apply(osg::Projection &proj)
+{
+    if(shouldContinueTraversal(proj))
+    {
+      // Push the new projection matrix view frustum
+      _projectionMatrices.push_back(proj.getMatrix());
+      pushLocalFrustum();
+
+      // Traverse the group
+      ++_currentDepth;
+      traverse(proj);
+      --_currentDepth;
+
+      // Reload original matrix and frustum
+      _localFrusta.pop_back();
+      _bbCorners.pop_back();
+      _projectionMatrices.pop_back();
+    }
+}
+
+void CURRENT_CLASS::apply(osg::Transform &transform)
+{
+    if(shouldContinueTraversal(transform))
+    {
+      // Compute transform for current node
+      osg::Matrix currMatrix = _viewMatrices.back();
+      bool pushMatrix = transform.computeLocalToWorldMatrix(currMatrix, this);
+
+      if(pushMatrix) 
+      {
+        // Store the new modelview matrix and view frustum
+        _viewMatrices.push_back(currMatrix);
+        pushLocalFrustum();
+      }
+
+      ++_currentDepth;
+      traverse(transform);
+      --_currentDepth;
+
+      if(pushMatrix) 
+      {
+        // Restore the old modelview matrix and view frustum
+        _localFrusta.pop_back();
+        _bbCorners.pop_back();
+        _viewMatrices.pop_back();
+      }
+    }
+}
+
+void CURRENT_CLASS::apply(osg::Geode &geode)
+{
+    // Contained drawables will only be individually considered if we are
+    // allowed to continue traversing.
+    if(shouldContinueTraversal(geode))
+    {
+      osg::Drawable *drawable;
+      double zNear, zFar;
+
+      // Handle each drawable in this geode
+      for(unsigned int i = 0; i < geode.getNumDrawables(); ++i)
+      {
+        drawable = geode.getDrawable(i);
+
+        const osg::BoundingBox &bb = drawable->getBound();
+        if(bb.valid())
+        {
+          // Make sure drawable will be visible in the scene
+          if(!_localFrusta.back().contains(bb)) continue;
+
+          // Compute near/far distances for current drawable
+          zNear = distance(bb.corner(_bbCorners.back().first), 
+                               _viewMatrices.back());
+          zFar = distance(bb.corner(_bbCorners.back().second), 
+                          _viewMatrices.back());
+          if(zNear > zFar) std::swap(zNear, zFar);
+          pushDistancePair(zNear, zFar);
+        }
+      }
+    }
+}
+
+void CURRENT_CLASS::setMatrices(const osg::Matrix &modelview,
+                                const osg::Matrix &projection)
+{
+    _modelview = modelview;
+    _projection = projection;
+}
+
+void CURRENT_CLASS::reset()
+{
+    // Clear vectors & values
+    _distancePairs.clear();
+    _cameraPairs.clear();
+    _limits.first = DBL_MAX;
+    _limits.second = 0.0;
+    _currentDepth = 0;
+
+    // Initial transform matrix is the modelview matrix
+    _viewMatrices.clear();
+    _viewMatrices.push_back(_modelview);
+
+    // Set the initial projection matrix
+    _projectionMatrices.clear();
+    _projectionMatrices.push_back(_projection);
+
+    // Create a frustum without near/far planes, for cull computations
+    _localFrusta.clear();
+    _bbCorners.clear();
+    pushLocalFrustum();
+}
+
+void CURRENT_CLASS::computeCameraPairs()
+{
+    // Nothing in the scene, so no cameras needed
+    if(_distancePairs.empty()) return;
+
+    // Entire scene can be handled by just one camera
+    if(_limits.first >= _limits.second*_nearFarRatio)
+    {
+      _cameraPairs.push_back(_limits);
+      return;
+    }
+
+    PairList::iterator i,j;
+
+    // Sort the list of distance pairs by descending far distance
+    std::sort(_distancePairs.begin(), _distancePairs.end(), precedes);
+
+    // Combine overlapping distance pairs. The resulting set of distance
+    // pairs (called combined pairs) will not overlap.
+    PairList combinedPairs;
+    DistancePair currPair = _distancePairs.front();
+    for(i = _distancePairs.begin(); i != _distancePairs.end(); ++i)
+    {
+      // Current distance pair does not overlap current combined pair, so
+      // save the current combined pair and start a new one.
+      if(i->second < 0.99*currPair.first)
+      {
+        combinedPairs.push_back(currPair);
+        currPair = *i;
+      }
+
+      // Current distance pair overlaps current combined pair, so expand
+      // current combined pair to encompass distance pair.
+      else
+        currPair.first = std::min(i->first, currPair.first);
+    }
+    combinedPairs.push_back(currPair); // Add last pair
+
+    // Compute the (near,far) distance pairs for each camera.
+    // Each of these distance pairs is called a "view segment".
+    double currNearLimit, numSegs, new_ratio;
+    double ratio_invlog = 1.0/log(_nearFarRatio);
+    unsigned int temp;
+    for(i = combinedPairs.begin(); i != combinedPairs.end(); ++i)
+    {
+      currPair = *i; // Save current view segment
+
+      // Compute the fractional number of view segments needed to span
+      // the current combined distance pair.
+      currNearLimit = currPair.second*_nearFarRatio;
+      if(currPair.first >= currNearLimit) numSegs = 1.0;
+      else 
+      {
+        numSegs = log(currPair.first/currPair.second)*ratio_invlog;
+
+        // Compute the near plane of the last view segment
+        //currNearLimit *= pow(_nearFarRatio, -floor(-numSegs) - 1);
+        for(temp = (unsigned int)(-floor(-numSegs)); temp > 1; temp--)
+        {
+          currNearLimit *= _nearFarRatio;
+        }
+      }
+
+      // See if the closest view segment can absorb other combined pairs
+      for(j = i+1; j != combinedPairs.end(); ++j)
+      {
+        // No other distance pairs can be included
+        if(j->first < currNearLimit) break;
+      }
+
+      // If we did absorb another combined distance pair, recompute the
+      // number of required view segments.
+      if(i != j-1)
+      {
+        i = j-1;
+        currPair.first = i->first;
+        if(currPair.first >= currPair.second*_nearFarRatio) numSegs = 1.0;
+        else numSegs = log(currPair.first/currPair.second)*ratio_invlog;
+      }
+
+      /* Compute an integer number of segments by rounding the fractional
+         number of segments according to how many segments there are.
+         In general, the more segments there are, the more likely that the 
+         integer number of segments will be rounded down.
+         The purpose of this is to try to minimize the number of view segments
+         that are used to render any section of the scene without violating
+         the specified _nearFarRatio by too much. */
+      if(numSegs < 10.0) numSegs = floor(numSegs + 1.0 - 0.1*floor(numSegs));
+      else numSegs = floor(numSegs);
+
+
+      // Compute the near/far ratio that will be used for each view segment
+      // in this section of the scene.
+      new_ratio = pow(currPair.first/currPair.second, 1.0/numSegs);
+
+      // Add numSegs new view segments to the camera pairs list
+      for(temp = (unsigned int)numSegs; temp > 0; temp--)
+      {
+        currPair.first = currPair.second*new_ratio;
+        _cameraPairs.push_back(currPair);
+        currPair.second = currPair.first;
+      }
+    }
+}
+
+void CURRENT_CLASS::setNearFarRatio(double ratio)
+{
+    if(ratio <= 0.0 || ratio >= 1.0) return;
+    _nearFarRatio = ratio;
+}
+#undef CURRENT_CLASS
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetDtedElevationDatabase.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetDtedElevationDatabase.cpp
new file mode 100644
index 0000000..93d6b5a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetDtedElevationDatabase.cpp
@@ -0,0 +1,715 @@
+#include <ossimPlanet/ossimPlanetDtedElevationDatabase.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimRegExp.h>
+#include <ossim/support_data/ossimDtedVol.h>
+#include <ossim/support_data/ossimDtedHdr.h>
+#include <ossim/support_data/ossimDtedUhl.h>
+#include <ossim/support_data/ossimDtedDsi.h>
+#include <ossim/support_data/ossimDtedAcc.h>
+#include <ossim/support_data/ossimDtedRecord.h>
+#include <sstream>
+
+ossimPlanetDtedElevationDatabase::ossimPlanetDtedElevationDatabase()
+   :ossimPlanetElevationDatabase()
+{
+   theOpenFlag = false;
+   theLocation = "";
+   theMaxOpenFiles = 25;
+   theMinOpenFiles = 20;
+   
+   theSwapBytesFlag = ossim::byteOrder() == OSSIM_LITTLE_ENDIAN;
+}
+
+ossimPlanetDtedElevationDatabase::ossimPlanetDtedElevationDatabase(const ossimPlanetDtedElevationDatabase& src)
+   :ossimPlanetElevationDatabase(src),
+    theLocation(src.theLocation),
+    theOpenFlag(src.theOpenFlag),
+    theMaxOpenFiles(src.theMaxOpenFiles),
+    theMinOpenFiles(src.theMinOpenFiles)
+{
+   theSwapBytesFlag = ossim::byteOrder() == OSSIM_LITTLE_ENDIAN;
+}
+
+ossimPlanetDtedElevationDatabase::~ossimPlanetDtedElevationDatabase()
+{
+}
+
+ossimPlanetTextureLayer* ossimPlanetDtedElevationDatabase::dup()const
+{
+   return new ossimPlanetDtedElevationDatabase(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetDtedElevationDatabase::dupType()const
+{
+   return new ossimPlanetDtedElevationDatabase;
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetDtedElevationDatabase::updateExtents()
+{
+
+   theDirtyExtentsFlag = false;
+   return theStateCode;
+}
+
+void ossimPlanetDtedElevationDatabase::updateStats()const
+{
+   theStats->setTotalTextureSize(0);
+   theDirtyStatsFlag = false;
+   
+}
+
+void ossimPlanetDtedElevationDatabase::resetStats()const
+{
+   theStats->setBytesTransferred(0);
+   theStats->setTotalTextureSize(0);
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetDtedElevationDatabase::open(const std::string& location)
+{
+   ossimElevManager::ConnectionStringVisitor visitor(location);
+   
+   ossimElevManager::instance()->accept(visitor);
+   //std::cout << "DATABASE ==== " << (visitor.getElevationDatabase()?visitor.getElevationDatabase()->getConnectionString():"NOT FOUND") << std::endl;
+   
+   ossimFilename file(location);
+   bool result = false;
+   theLocation = "";
+   theExtents = new ossimPlanetExtents;
+   ossim_uint32 count = 0;
+   ossim_uint32 maxCount = 25;
+   if(file.exists())
+   {
+      if(file.isDir())
+      {
+         ossimDirectory dir;
+
+         if(dir.open(file))
+         {
+            ossimFilename testFile;
+            if(dir.getFirst(testFile))
+            {
+               ++count;
+               do
+               {
+                  ossimRegExp eastern;
+                  ossimRegExp western;
+                  ossimRegExp easternUp;
+                  ossimRegExp westernUp;
+                  eastern.compile("e[0-9][0-9][0-9]");
+                  western.compile("w[0-9][0-9][0-9]");
+                  easternUp.compile("E[0-9][0-9][0-9]");
+                  westernUp.compile("W[0-9][0-9][0-9]");
+                  if(testFile.isDir())
+                  {
+                     if(eastern.find(testFile.c_str())||
+                        western.find(testFile.c_str())||
+                        easternUp.find(testFile.c_str())||
+                        westernUp.find(testFile.c_str()))
+                     {
+                        result = true;
+                     }
+                     if(result)
+                     {
+                        result = false; // now find a North South file
+                        ossimDirectory dirNS;
+                        dirNS.open(testFile);
+                        if(dirNS.getFirst(testFile))
+                        {
+                           do
+                           {
+                              std::ifstream in;
+                              
+                              in.open(testFile.c_str(), std::ios::binary|std::ios::in);
+                              
+                              if(!in.fail())
+                              {
+                                 
+                                 ossimDtedVol vol(in);
+                                 ossimDtedHdr hdr(in);
+                                 ossimDtedUhl uhl(in);
+                                 ossimDtedDsi dsi(in);
+                                 ossimDtedAcc acc(in);
+                                 
+                                 if(uhl.getErrorStatus() != ossimErrorCodes::OSSIM_ERROR)
+                                 {
+                                    double metersPerPixel   = ossimGpt().metersPerDegree().y*uhl.latInterval();
+                                    dirtyExtents(); // make sure parents are marked as dirty
+
+                                    if(fabs(metersPerPixel - (ossimGpt().metersPerDegree().y *(30.0/3600))) < .25) // 30 arc
+                                    {
+                                       setName("DTED0");
+                                       setDescription("DTED 1 kilometer elevation database");
+                                       theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 6));
+                                    }
+                                    else if(fabs(metersPerPixel - (ossimGpt().metersPerDegree().y *(3.0/3600))) < .25) // 3 arc
+                                    {
+                                       setName("DTED1");
+                                       setDescription("DTED 90 meter elevation database");
+                                       theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 8));
+                                    }
+                                    else if(fabs(metersPerPixel - (ossimGpt().metersPerDegree().y *(1.0/3600))) < .25) // 1 arc
+                                    {
+                                       setName("DTED2");
+                                       setDescription("DTED 30 meter elevation database");
+                                       theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 10));
+                                    }
+                                    else
+                                    {
+                                       setName("DTED");
+                                       setDescription("DTED elevation database");
+                                       theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 12));
+                                    }
+                                    result = true;
+                                 }
+                              }
+                           }while(dirNS.getNext(testFile)&&(!result));
+                        }
+                     }
+                  }
+
+               }while(dir.getNext(testFile)&&(!result)&&(count < maxCount));
+            }
+         }
+      }
+   }
+   
+   theOpenFlag = result;
+   if(theOpenFlag)
+   {
+      theStateCode = ossimPlanetTextureLayer_VALID;
+      theLocation = location;
+   }
+   else
+   {
+      theStateCode = ossimPlanetTextureLayer_NO_SOURCE_DATA;
+   }
+
+   return theStateCode;
+}
+bool ossimPlanetDtedElevationDatabase::hasTexture(ossim_uint32 width,
+                                                  ossim_uint32 height,
+                                                  const ossimPlanetTerrainTileId& tileId,
+                                                  const ossimPlanetGrid& grid)
+{
+   if(!theOpenFlag)
+   {
+      return false;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return false;
+   }
+   ossimPlanetGrid::GridBound bound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      ossimPlanetGrid::GridBound tileBound;
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return false;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   ossimPlanetGrid::ModelPoint minLatLon, maxLatLon;
+   grid.modelBound(tileId, minLatLon, maxLatLon);
+   if((gsd.y >= theExtents->getMinScale()) &&
+      (gsd.y <= theExtents->getMaxScale()))
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points);
+      ossim_float64 minModelX, minModelY, maxModelX, maxModelY;
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      minModelX = points[0].x();
+      maxModelX = minModelX;
+      minModelY = points[0].y();
+      maxModelY = minModelY;
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      ++optimizedOutPtr;
+      for(idxPts = 1; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         if(optimizedOutPtr->x() < minModelX) minModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->x() > maxModelX) maxModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->y() < minModelY) minModelY = optimizedOutPtr->y();
+         if(optimizedOutPtr->y() > maxModelY) maxModelY = optimizedOutPtr->y();
+      }
+      ossim_int32 wholeMinY = (ossim_int32)std::floor(minModelY);
+      ossim_int32 wholeMinX = (ossim_int32)std::floor(minModelX);
+      ossim_int32 wholeMaxY = (ossim_int32)std::floor(maxModelY);
+      ossim_int32 wholeMaxX = (ossim_int32)std::floor(maxModelX);
+      
+      
+      ossim_int32 lat = wholeMaxY;
+      ossim_int32 lon = wholeMinX;
+      
+      
+      //    std::vector<ossimDpt> latLonOrigins;
+      std::vector<std::string> latLonOrigins;
+      
+      for(;lat >= wholeMinY; --lat)
+      {
+         lon = wholeMinX;
+         for(;lon <= wholeMaxX; ++lon)
+         {
+            ossimFilename filename = buildFilename(lat, lon);
+            if(filename != "")
+            {
+               return true;
+            }
+         }
+      }
+   }
+   
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetDtedElevationDatabase::getTexture(ossim_uint32 width,
+                                                                            ossim_uint32 height,
+                                                                            const ossimPlanetTerrainTileId& tileId,
+                                                                            const ossimPlanetGrid& grid,
+                                                                            ossim_int32 padding)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+      ossimElevManager* manager = ossimElevManager::instance();
+      double minValue = 999999999.0;
+      double maxValue = -999999999.0;
+      for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         double h = manager->getHeightAboveEllipsoid(ossimGpt((*optimizedOutPtr).y(), (*optimizedOutPtr).x()));
+         if(!ossim::isnan(h))
+         {
+            *bufPtr = h;
+         }
+         
+         ++bufPtr;
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+            
+
+   return texture;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetDtedElevationDatabase::getTexture(ossim_uint32 level,
+                                                                            ossim_uint64 row,
+                                                                            ossim_uint64 col,
+                                                                            const ossimPlanetGridUtility& utility)
+{
+   if(!theOpenFlag)
+   {
+      return 0;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+   ossim_uint32 width = utility.getTileWidth();
+   ossim_uint32 height = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, 
+                           col);
+
+  if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+   {
+      return 0;
+   }
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/height;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(!theExtents->intersectsScale(gsd.y-FLT_EPSILON,
+                                  gsd.y+FLT_EPSILON))//gsd.y <= theExtents.theMaxGsd)
+   {
+      return 0;
+   }
+  double minSubRectLat = ossim::max(theExtents->getMinLat(),
+                                    minLat);
+   double minSubRectLon = ossim::max(theExtents->getMinLon(),
+                                    minLon);
+   double maxSubRectLat = ossim::min(theExtents->getMaxLat(),
+                                   maxLat);
+   double maxSubRectLon = ossim::min(theExtents->getMaxLon(),
+                                   maxLon);
+   ossim_int32 wholeMinLat = (ossim_int32)std::floor(minSubRectLat);
+   ossim_int32 wholeMinLon = (ossim_int32)std::floor(minSubRectLon);
+   ossim_int32 wholeMaxLat = (ossim_int32)std::floor(maxSubRectLat);
+   ossim_int32 wholeMaxLon = (ossim_int32)std::floor(maxSubRectLon);
+   
+
+   ossim_int32 lat = wholeMaxLat;
+   ossim_int32 lon = wholeMinLon;
+
+
+//    std::vector<ossimDpt> latLonOrigins;
+   std::vector<std::string> latLonOrigins;
+
+   for(;lat >= wholeMinLat; --lat)
+   {
+      lon = wholeMinLon;
+      for(;lon <= wholeMaxLon; ++lon)
+      {
+         ossimFilename filename = buildFilename(lat, lon);
+         if(filename != "")
+         {
+            latLonOrigins.push_back(filename);
+         }
+      }
+   }
+
+   if(latLonOrigins.size() == 0)
+   {
+      return 0;
+   }
+   ossim_uint32 idx  = 0;
+   ossim_uint32 numberOfFilesNeeded = latLonOrigins.size();
+   texture = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                                           level,
+                                                           col,
+                                                           row));
+   ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                  OSSIM_FLOAT32,
+                                                                  1,
+                                                                  width,
+                                                                  height);
+   compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+   compositeData->initialize();
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   utility.createGridPoints(points,
+                            level,
+                            row,
+                            col,
+                            height,
+                            width);
+
+   ossim_uint32 idxPts = 0;
+   ossim_uint32 nPoints = points.size();
+   osg::Vec3d latLonPoint;
+   double minValue = 1.0/DBL_EPSILON -1;
+   double maxValue = -1.0/DBL_EPSILON +1;
+   //double offset = 0.0;
+
+   for(idx = 0; idx < numberOfFilesNeeded;++idx)
+   {
+
+      osg::ref_ptr<ossimPlanetDtedElevationDatabase::DtedInfo> dtedFile = getInfo(latLonOrigins[idx]);
+
+      if(dtedFile.valid())
+      {
+         ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+         for(idxPts = 0; idxPts < nPoints; ++idxPts)
+         {
+            utility.getLatLon(latLonPoint, points[idxPts]);
+            if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&
+               (latLonPoint[0] >= dtedFile->theMinLat)&&
+               (latLonPoint[0] <= dtedFile->theMaxLat)&&
+               (latLonPoint[1] >= dtedFile->theMinLon)&&
+               (latLonPoint[1] <= dtedFile->theMaxLon))
+            {
+               utility.getLatLon(latLonPoint, points[idxPts]);
+               ossim_float64 nullHeight = dtedFile->theHandler->getNullHeightValue();
+              double h = dtedFile->theHandler->getHeightAboveMSL(ossimGpt(latLonPoint[0],
+                                                                           latLonPoint[1]));
+               if(!ossim::isnan(h)&&
+                  (h!=nullHeight))
+               {
+                  if(theGeoRefModel.valid())
+                  {
+                     h+=theGeoRefModel->getGeoidOffset(latLonPoint[0], latLonPoint[1]);
+                  }
+                  *bufPtr = h;
+                  if(*bufPtr < minValue)
+                  {
+                     minValue = *bufPtr;
+                  }
+                  if(*bufPtr > maxValue)
+                  {
+                     maxValue = *bufPtr;
+                  }
+               }   
+               else
+               {
+                  *bufPtr = 0;
+               }
+            }
+            ++bufPtr;
+         }
+      }
+   }
+   compositeData->validate();
+
+   if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+   {
+      texture->fromOssimImage(compositeData, false);
+      if(minValue < maxValue)
+      {
+         texture->setMinMax(minValue, maxValue);
+      }
+   }
+   else
+   {
+      texture = 0;
+   }
+
+   return texture;
+
+}
+
+osg::ref_ptr<ossimPlanetDtedElevationDatabase::DtedInfo> ossimPlanetDtedElevationDatabase::getInfo(const std::string& name)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDtedInfoMutex);
+   DtedFilePointerList::iterator iter = theFilePointers.find(name);
+
+   if(iter != theFilePointers.end())
+   {
+      iter->second->theTimeStamp = osg::Timer::instance()->tick();
+
+      return iter->second;
+   }
+   osg::ref_ptr<DtedInfo> info     = new DtedInfo;
+   
+   ossimFilename dtedFile = ossimFilename(theLocation).dirCat(ossimFilename(name));
+
+   ifstream in;
+
+   in.open(dtedFile.c_str(), std::ios::binary|std::ios::in);
+
+   if(in.fail()) return 0;
+
+   ossimDtedVol vol(in);
+   ossimDtedHdr hdr(in);
+   ossimDtedUhl uhl(in);
+
+   in.close();
+   
+   if((uhl.getErrorStatus() == ossimErrorCodes::OSSIM_ERROR))
+   {
+      return 0;
+   }
+   info->theNumLonLines  = uhl.numLonLines();
+   info->theNumLatPoints = uhl.numLatPoints();
+   info->theLatSpacing   = uhl.latInterval();
+   info->theLonSpacing   = uhl.lonInterval();
+   info->theMinLat = uhl.latOrigin();
+   info->theMinLon = uhl.lonOrigin();
+   info->theMaxLat = info->theMinLat + info->theLatSpacing*(info->theNumLatPoints-1);
+   info->theMaxLon = info->theMinLon + info->theLonSpacing*(info->theNumLonLines-1);
+   info->theTimeStamp  = osg::Timer::instance()->tick();
+   info->theFilename   = dtedFile;
+   info->theHandler = new ossimDtedHandler(dtedFile, false);
+   //info->theHandler->setMemoryMapFlag(false);
+   theFilePointers.insert(std::make_pair(name, info));
+   shrinkFilePointers();
+   
+   return info;
+   
+}
+
+void ossimPlanetDtedElevationDatabase::shrinkFilePointers()
+{
+   if(theFilePointers.size() <= theMaxOpenFiles) return;
+
+   const osg::Timer* timer = osg::Timer::instance();
+   
+   osg::Timer_t currentTime = timer->tick();
+
+   while((theFilePointers.size()>0) &&
+         (theFilePointers.size() > theMinOpenFiles))
+   {
+      DtedFilePointerList::iterator iter = theFilePointers.begin();
+      DtedFilePointerList::iterator currentLargestTimeDelta = iter;
+      double delta = 0.0;
+      while(iter!=theFilePointers.end())
+      {
+         double testDelta = timer->delta_m(currentLargestTimeDelta->second->theTimeStamp, currentTime);
+         if(testDelta > delta)
+         {
+            currentLargestTimeDelta = iter;
+            delta = testDelta;
+         }
+         ++iter;
+      }
+
+      if(currentLargestTimeDelta != theFilePointers.end())
+      {
+         theFilePointers.erase(currentLargestTimeDelta);
+      }
+   }
+}
+
+ossimFilename ossimPlanetDtedElevationDatabase::buildFilename(double lat, double lon)const
+{
+   ossimFilename dtedFileBase;
+   
+   int ilon = static_cast<int>(lon);
+   
+   if (ilon < 0)
+   {
+      dtedFileBase = "w";
+   }
+   else
+   {
+      dtedFileBase = "e";
+   }
+   
+   ilon = abs(ilon);
+   std::ostringstream  s1;
+   s1 << std::setfill('0') << std::setw(3)<< ilon;
+   
+   dtedFileBase += s1.str().c_str();//ossimString::toString(ilon);
+   dtedFileBase += "/";
+   
+   int ilat =  static_cast<int>(floor(lat));
+   if (ilat < 0)
+   {
+      dtedFileBase += "s";
+   }
+   else
+   {
+      dtedFileBase += "n";
+   }
+
+   ilat = abs(ilat);
+   std::ostringstream  s2;
+
+   s2<< std::setfill('0') << std::setw(2)<< ilat;
+   
+   dtedFileBase += s2.str().c_str();
+
+   ossimFilename tempDir(theLocation);
+   // Look for a dted file with a level 3 extension first.
+   ossimFilename dtedName = tempDir.dirCat(dtedFileBase);
+   dtedName += ".dt3";
+
+   if (dtedName.exists())
+   {
+      return dtedFileBase + ".dt3";
+   }
+
+   // Look for a dted file with a level 2 extension next.
+   dtedName = tempDir.dirCat(dtedFileBase);
+   dtedName += ".dt2";
+
+   if(dtedName.exists())
+   {
+      return dtedFileBase + ".dt2";
+   }
+
+   // Look for a dted file with a level 1 extension next.
+   dtedName = tempDir.dirCat(dtedFileBase);
+   dtedName += ".dt1";
+  if(dtedName.exists())
+   {
+      return dtedFileBase + ".dt1";
+   }
+
+   // Look for a dted file with a level 0 extension next.
+   dtedName = tempDir.dirCat(dtedFileBase);
+   dtedName += ".dt0";
+   if(dtedName.exists())
+   {
+      return dtedFileBase + ".dt0";
+   }
+   
+   return "";
+}
+
+osg::ref_ptr<ossimPlanetDtedElevationDatabase::DtedInfo> ossimPlanetDtedElevationDatabase::findDtedInfo(const std::string& name)
+{
+   DtedFilePointerList::iterator iter = theFilePointers.find(name);
+   
+   if(iter != theFilePointers.end())
+   {
+      iter->second->theTimeStamp = osg::Timer::instance()->tick();
+      return iter->second;
+   }
+
+   return 0;
+ 
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabase.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabase.cpp
new file mode 100644
index 0000000..8b5beb5
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabase.cpp
@@ -0,0 +1,92 @@
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetElevationDatabase::getTexture(const ossimPlanetTerrainTileId& tileId,
+                                                                                osg::ref_ptr<ossimPlanetGrid> theGrid)
+{
+   return 0;
+}
+
+void ossimPlanetElevationDatabase::mergeDataObjects(ossimRefPtr<ossimImageData> destData,
+                                                    ossimRefPtr<ossimImageData> srcData)
+{
+   if(destData.valid()&&srcData.valid()&&
+      destData->getBuf()&&srcData->getBuf())
+   {
+      if((destData->getScalarType() == OSSIM_FLOAT)&&
+         (destData->getWidth()==srcData->getWidth())&&
+         (destData->getHeight()==srcData->getHeight()))
+      {
+         ossim_float32* destBuf = (ossim_float32*)destData->getBuf();
+         ossim_float32  destNp  = (ossim_float32)destData->getNullPix(0);
+         ossim_uint32 idx = 0;
+         ossim_uint32 area = destData->getWidth()*destData->getHeight();
+
+         switch(srcData->getScalarType())
+         {
+            case OSSIM_UINT16:
+            case OSSIM_USHORT11:
+            {
+               ossim_uint16* srcBuf = (ossim_uint16*)srcData->getBuf();
+               ossim_uint16 srcNp = (ossim_uint16)srcData->getNullPix(0);
+               
+               for(;idx < area; ++idx)
+               {
+                  if(*destBuf == destNp)
+                  {
+                     if(*srcBuf != srcNp)
+                     {
+                        *destBuf = (ossim_float32)*srcBuf;
+                     }
+                  }
+                  ++destBuf;
+                  ++srcBuf;
+               }
+               break;
+            }
+            case OSSIM_SINT16:
+            {
+               ossim_sint16* srcBuf = (ossim_sint16*)srcData->getBuf();
+               ossim_sint16 srcNp = (ossim_sint16)srcData->getNullPix(0);
+               
+               for(;idx < area; ++idx)
+               {
+                  if(*destBuf == destNp)
+                  {
+                     if(*srcBuf != srcNp)
+                     {
+                        *destBuf = (ossim_float32)*srcBuf;
+                     }
+                  }
+                  ++destBuf;
+                  ++srcBuf;
+               }
+               break;
+            }
+            case OSSIM_FLOAT32:
+            {
+               ossim_float32* srcBuf = (ossim_float32*)srcData->getBuf();
+               ossim_float32 srcNp = (ossim_float32)srcData->getNullPix(0);
+               
+               for(;idx < area; ++idx)
+               {
+                  if(*destBuf == destNp)
+                  {
+                     if(*srcBuf != srcNp)
+                     {
+                        *destBuf = *srcBuf;
+                     }
+                  }
+                  ++destBuf;
+                  ++srcBuf;
+               }
+               break;
+            }
+            default:
+            {
+               break;
+               // not supported
+            }
+         }
+      }
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabaseGroup.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabaseGroup.cpp
new file mode 100644
index 0000000..6d22dc4
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationDatabaseGroup.cpp
@@ -0,0 +1,518 @@
+#include <ossimPlanet/ossimPlanetElevationDatabaseGroup.h>
+#include <ossimPlanet/ossimPlanetElevationDatabase.h>
+#include <stack>
+#include <ossim/base/ossimDrect.h>
+#include <ossim/base/ossimGpt.h>
+
+ossimPlanetElevationDatabaseGroup::ossimPlanetElevationDatabaseGroup()
+   :ossimPlanetTextureLayerGroup(),
+    theFillNullWithGeoidOffsetFlag(false)
+{
+}
+
+ossimPlanetElevationDatabaseGroup::ossimPlanetElevationDatabaseGroup(const ossimPlanetElevationDatabaseGroup& src)
+:ossimPlanetTextureLayerGroup(src),
+theFillNullWithGeoidOffsetFlag(src.theFillNullWithGeoidOffsetFlag)
+{
+}
+
+ossimPlanetTextureLayer* ossimPlanetElevationDatabaseGroup::dup()const
+{
+   return new ossimPlanetElevationDatabaseGroup(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetElevationDatabaseGroup::dupType()const
+{
+   return new ossimPlanetElevationDatabaseGroup;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetElevationDatabaseGroup::getTexture(ossim_uint32 width,
+                                                                             ossim_uint32 height,
+                                                                             const ossimPlanetTerrainTileId& tileId,
+                                                                             const ossimPlanetGrid& grid,
+                                                                             ossim_int32 padding)
+{
+   ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                  OSSIM_FLOAT32,
+                                                                  1,
+                                                                  width+2*padding,
+                                                                  height+2*padding);
+   compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT);
+   compositeData->initialize();
+   osg::ref_ptr<ossimPlanetImage> result = new ossimPlanetImage(tileId);
+   result->fromOssimImage(compositeData, false);
+   result->setPadding(padding);
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   bool withinExtents = true;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         withinExtents = false;
+      }
+   }
+   else
+   {
+      withinExtents = false;
+   }
+   ossim_uint32 idx = 0;
+   for(idx = 0; (idx < theChildrenList.size())&&withinExtents&&getEnableFlag(); ++idx)
+   {
+      if(theChildrenList[idx].valid())
+      {
+         const osg::ref_ptr<ossimPlanetExtents> extents = theChildrenList[idx]->getExtents();
+         
+         if(extents.valid())
+         {
+            if(grid.findGridBound(tileId.face(),
+                                  ossimPlanetGrid::ModelPoint(extents->getMinLon(), extents->getMinLat()),
+                                  ossimPlanetGrid::ModelPoint(extents->getMaxLon(), extents->getMaxLat()),
+                                  bound))
+            {
+//               std::cout << "TESTING INTERSECTS" << std::endl;
+//               std::cout << "tileBound = " << tileBound.toDrect() << std::endl
+//               << "fullBound = " << bound.toDrect() << std::endl;
+               if(tileBound.toDrect().intersects(bound.toDrect()))
+               {
+                  osg::ref_ptr<ossimPlanetImage> image = theChildrenList[idx]->getTexture(width,
+                                                                                          height,
+                                                                                          tileId,
+                                                                                          grid,
+                                                                                          padding);
+                  if(image.valid())
+                  {
+                     if(result.valid())
+                     {
+                        mergeImage(image.get(), result.get());
+                        result = image;
+                        if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                        {
+                           return result;
+                        }
+                     }
+                     else
+                     {
+                        result = (ossimPlanetImage*)image->clone(osg::CopyOp::DEEP_COPY_ALL);
+                        if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                        {
+                          return result;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+   if((result->getPixelStatus() != ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)&&
+      (theFillNullWithGeoidOffsetFlag)&&
+      (theGeoRefModel.valid()))
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             result->padding());
+      
+      ossim_uint32 nPoints = points.size();
+      osg::Vec3d latLonPoint;
+      double minValue = 1.0/FLT_EPSILON -1;
+      double maxValue = -1.0/FLT_EPSILON +1;
+      ossim_float32* bufPtr = (ossim_float32*)result->data();   
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      for(idx = 0; idx < nPoints; ++idx,++optimizedOutPtr)
+      { 
+         if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)||
+            (ossim::isnan(*bufPtr)))
+         {
+            *bufPtr = theGeoRefModel->getGeoidOffset(ossim::clamp(optimizedOutPtr->y(),-90.0, 90.0), 
+                                                     ossim::wrap(optimizedOutPtr->x(), -180.0, 180.0));
+         }
+         if(ossim::isnan(*bufPtr))
+         {
+            *bufPtr = 0;
+         }
+         else if(*bufPtr < minValue)
+         {
+            minValue = *bufPtr;
+         }
+         else if(*bufPtr > maxValue)
+         {
+            maxValue = *bufPtr;
+         }
+        ++bufPtr;
+      }
+      
+      if(minValue < maxValue)
+      {
+         result->setMinMax(minValue, maxValue);
+      }
+      result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_FULL);
+   }
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetElevationDatabaseGroup::getTexture(ossim_uint32 level,
+                                                                             ossim_uint64 row,
+                                                                             ossim_uint64 col,
+                                                                             const ossimPlanetGridUtility& utility)
+{   
+   ossim_uint32 width = utility.getTileWidth();
+   ossim_uint32 height = utility.getTileHeight();
+
+   ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                  OSSIM_FLOAT32,
+                                                                  1,
+                                                                  width,
+                                                                  height);
+   compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT);
+   compositeData->initialize();
+   osg::ref_ptr<ossimPlanetImage> result = new ossimPlanetImage(ossimPlanetTerrainTileId(0, level, col, row));
+
+   result->fromOssimImage(compositeData, false);
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   ossim_uint32 idx = 0;
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+//   unsigned int w = utility.getTileWidth();
+   unsigned int h = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, 
+                           col );
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/h;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon)&&
+      theExtents->intersectsScale(gsd.y,
+                                  gsd.y)&&
+      getEnableFlag())
+   {
+      for(idx = 0; idx < theChildrenList.size(); ++idx)
+      {
+         if(theChildrenList[idx].valid())
+         {
+            const osg::ref_ptr<ossimPlanetExtents> extents = theChildrenList[idx]->getExtents();
+            
+            if(extents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+            {
+               osg::ref_ptr<ossimPlanetImage> image = theChildrenList[idx]->getTexture(level, row, col, utility);
+               if(image.valid())
+               {
+                  if(result.valid())
+                  {
+                     mergeImage(image.get(), result.get());
+                     result = image;
+                     if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                     {
+                        return result;
+                     }
+                  }
+                  else
+                  {
+                     result = (ossimPlanetImage*)image->clone(osg::CopyOp::DEEP_COPY_ALL);
+                     if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                     {
+                       return result;
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+   if((result->getPixelStatus() != ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)&&
+      (theFillNullWithGeoidOffsetFlag)&&
+      (theGeoRefModel.valid()))
+   {
+      std::vector<ossimPlanetGridUtility::GridPoint> points;
+      utility.createGridPoints(points,
+                               level,
+                               row,
+                               col,
+                               height,
+                               width);
+      
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      osg::Vec3d latLonPoint;
+      double minValue = 1.0/FLT_EPSILON -1;
+      double maxValue = -1.0/FLT_EPSILON +1;
+      ossim_float32* bufPtr = (ossim_float32*)result->data();   
+      for(idxPts = 0; idxPts < nPoints; ++idxPts)
+      { 
+         if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)||
+            (ossim::isnan(*bufPtr)))
+         {
+            utility.getLatLon(latLonPoint, points[idxPts]);
+
+            *bufPtr = theGeoRefModel->getGeoidOffset(latLonPoint[0], latLonPoint[1]);
+         }
+         if(*bufPtr < minValue)
+         {
+            minValue = *bufPtr;
+         }
+         if(*bufPtr > maxValue)
+         {
+            maxValue = *bufPtr;
+         }
+         ++bufPtr;
+      }
+      
+      if(minValue < maxValue)
+      {
+         result->setMinMax(minValue, maxValue);
+      }
+      result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_FULL);
+   }
+   return result;
+   
+}
+
+bool ossimPlanetElevationDatabaseGroup::replaceLayer(ossim_uint32 idx,
+                                                     osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layer.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::replaceLayer(idx, layer.get());
+   }
+
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addTop(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layer.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addTop(layer.get());
+   }
+   
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addBeforeIdx(ossim_uint32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layer.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addBeforeIdx(idx, layer.get());
+   }
+
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addBeforeLayer(const osg::ref_ptr<ossimPlanetTextureLayer> beforeLayer,
+                                                       osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layerToAdd.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addBeforeLayer(beforeLayer.get(),
+                                                          layerToAdd.get());
+   }
+
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addAfterIdx(ossim_int32 idx, osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layer.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addAfterIdx(idx, layer.get());
+   }
+
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addAfterLayer(const osg::ref_ptr<ossimPlanetTextureLayer> afterLayer,
+                                                      osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layerToAdd.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addAfterLayer(afterLayer.get(),
+                                                         layerToAdd.get());
+      
+   }
+
+   return false;
+}
+
+bool ossimPlanetElevationDatabaseGroup::addBottom(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   ossimPlanetElevationDatabase* databaseLayer = dynamic_cast<ossimPlanetElevationDatabase*>(layer.get());
+   if(databaseLayer)
+   {
+      databaseLayer->setGeoRefModel(theGeoRefModel.get());
+      return ossimPlanetTextureLayerGroup::addBottom(layer.get());
+   }
+
+   return false;
+}
+
+void ossimPlanetElevationDatabaseGroup::mergeImage(ossimPlanetImage* result,
+                                                   const ossimPlanetImage* source)const
+{
+   if(result&&source)
+   {
+      
+      if((source->getDataType() == GL_FLOAT)&&
+         (source->getPixelFormat()== GL_LUMINANCE)&&
+         (result->getDataType() == GL_FLOAT)&&
+         (result->getPixelFormat()== GL_LUMINANCE)&&
+         (result->s() == source->s())&&
+         (result->t() == source->t()))
+      {
+         const ossim_float32* srcPtr = reinterpret_cast<const ossim_float32*>(source->data());
+         ossim_float32* resultPtr = reinterpret_cast<ossim_float32*>(result->data());
+         ossim_uint32 area = source->s()*source->t();
+         
+         if(area>0)
+         {
+            ossim_uint32 idx = 0;
+            ossim_uint32 nullCount = 0;
+            for(idx = 0; idx < area; ++idx)
+            {
+               if(*resultPtr ==  OSSIMPLANET_NULL_HEIGHT)
+               {
+                  if(*srcPtr !=  OSSIMPLANET_NULL_HEIGHT)
+                  {
+                     *resultPtr = *srcPtr;
+                  }
+                  else
+                  {
+                     ++nullCount;
+                  }
+               }
+               ++resultPtr;
+               ++srcPtr;
+            }
+
+            if(nullCount < 1)
+            {
+               result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_FULL);
+            }
+            else if(nullCount == area)
+            {
+               result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_EMPTY);
+            }
+            else if(nullCount > 0)
+            {
+               result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_PARTIAL);
+            }
+         }
+         else
+         {
+            result->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_EMPTY);
+         }
+         if(source->hasMinMax())
+         {
+            if(result->hasMinMax())
+            {
+               ossim_uint32 idx = 0;
+               ossim_uint32 maxCount = ossim::max(source->minValue().size(), result->minValue().size());
+               for(;idx < maxCount; ++idx)
+               {
+                  result->setMin(idx,
+                                 ossim::min(source->minValue()[idx],
+                                          result->minValue()[idx]));
+                  result->setMax(idx,
+                                 ossim::max(source->maxValue()[idx],
+                                          result->maxValue()[idx]));
+               }
+            }
+            else
+            {
+               result->setMinMax(source->minValue(),
+                                 source->maxValue());
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanetElevationDatabaseGroup::setPixelStatus(ossimPlanetImage* image)
+{
+   if((image->getDataType() == GL_FLOAT)&&
+      (image->getPixelFormat()== GL_LUMINANCE))
+   {
+      ossim_uint32 area = image->s()*image->t();
+      ossim_uint32 nullCount = 0;
+      ossim_uint32 idx = 0;
+      ossim_float32* imagePtr = reinterpret_cast<ossim_float32*>(image->data());
+      image->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_EMPTY);
+      
+      for(idx = 0; idx < area; ++idx)
+      {
+         if(*imagePtr == OSSIMPLANET_NULL_HEIGHT)
+         {
+            ++nullCount;
+         }
+         ++imagePtr;
+      }
+      if(nullCount == area)
+      {
+         image->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_EMPTY);
+      }
+      else if(nullCount > 0)
+      {
+         image->setPixelStatus(ossimPlanetImage::ossimPlanetImagePixelStatus_PARTIAL);   
+      }
+   }
+}
+
+void ossimPlanetElevationDatabaseGroup::setGeoRefModel(osg::ref_ptr<ossimPlanetGeoRefModel> model)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   theGeoRefModel = model.get();
+   ossim_uint32 bound = theChildrenList.size();
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < bound; ++idx)
+   {
+      ossimPlanetElevationDatabase* database = dynamic_cast<ossimPlanetElevationDatabase*>(theChildrenList[idx].get());
+      if(database)
+      {
+         database->setGeoRefModel(model.get());
+      }
+   }
+}
+
+void ossimPlanetElevationDatabaseGroup::setFillNullWithGeoidOffsetFlag(bool flag)
+{
+   theFillNullWithGeoidOffsetFlag = flag;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetElevationFactory.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationFactory.cpp
new file mode 100644
index 0000000..3574119
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationFactory.cpp
@@ -0,0 +1,49 @@
+#include <ossimPlanet/ossimPlanetElevationFactory.h>
+#include <ossimPlanet/ossimPlanetSrtmElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetDtedElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h>
+
+ossimPlanetElevationFactory::ossimPlanetElevationFactory()
+{
+   setId("default");
+}
+
+ossimPlanetElevationFactory* ossimPlanetElevationFactory::instance()
+{
+   static ossimPlanetElevationFactory* theInstance = 0;
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetElevationFactory;
+   }
+   
+   return theInstance;
+}
+
+ossimPlanetElevationDatabase* ossimPlanetElevationFactory::openDatabase(const ossimString& location)
+{
+   // check SRTM database
+   osg::ref_ptr<ossimPlanetElevationDatabase> database = new ossimPlanetSrtmElevationDatabase;
+   
+   if(database->open(location) == ossimPlanetTextureLayer_VALID)
+   {
+      return database.release();
+   }
+   else
+   {
+      database = new ossimPlanetDtedElevationDatabase;
+      if(database->open(location) == ossimPlanetTextureLayer_VALID)
+      {
+         return database.release();
+      }
+      else
+      {
+         database = new ossimPlanetGeneralRasterElevationDatabase;
+         if(database->open(location) == ossimPlanetTextureLayer_VALID)
+         {
+            return database.release();
+         }
+      }
+   }
+   
+   return 0;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetElevationGrid.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationGrid.cpp
new file mode 100644
index 0000000..9228e23
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationGrid.cpp
@@ -0,0 +1,174 @@
+#include <ossimPlanet/ossimPlanetElevationGrid.h>
+#include <iostream>
+#include <ossim/base/ossimCommon.h>
+ossimPlanetElevationGrid::ossimPlanetElevationGrid(ossim_uint32 w,
+                                               ossim_uint32 h)
+{
+   theGrid = 0;
+   theWidth = 0;
+   theHeight = 0;
+   resize(w,h);
+}
+
+ossimPlanetElevationGrid::~ossimPlanetElevationGrid()
+{
+   if(theGrid)
+   {
+      delete [] theGrid;
+      theGrid = 0;
+   }
+}
+
+void ossimPlanetElevationGrid::resize(ossim_uint32 w,
+                                    ossim_uint32 h)
+{
+   if(theGrid)
+   {
+      delete [] theGrid;
+      theGrid = 0;
+   }
+   theGrid = new float[w*h];
+   
+   theWidth  = w;
+   theHeight = h;
+}
+
+osg::ref_ptr<ossimPlanetElevationGrid>  ossimPlanetElevationGrid::scaleBy2Nearest()const
+{
+   // note our elevation has one extra row and 1 extra column so the
+   // scaled should be 2*(height-1) + 1 and 2*(width-1) + 1 for
+   // the new dimensions
+   //
+//    ossim_uint32 outputWidth  = ((theWidth-1) <<1) + 1;
+//    ossim_uint32 outputHeight = ((theHeight-1)<<1) + 1;
+   ossim_uint32 outputWidth  = theWidth<<1;
+   ossim_uint32 outputHeight = theHeight<<1;
+   osg::ref_ptr<ossimPlanetElevationGrid> result = new ossimPlanetElevationGrid(outputWidth,
+                                                                            outputHeight);
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+   const float* inputData = theGrid;
+   float* outputData = result->theGrid;
+   ossim_uint32 inputOffsetY = 0;
+   ossim_uint32 inputOffset = 0;
+   for(y = 0; y < outputHeight; ++y)
+   {
+      inputOffsetY = (y>>1)*theWidth;
+      for(x = 0; x < outputWidth; ++x)
+      {
+         inputOffset = inputOffsetY + (x>>1);
+         *outputData= inputData[inputOffset];
+         ++outputData;
+      }
+   }
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetElevationGrid>  ossimPlanetElevationGrid::scaleBy2Bilinear()const
+{
+//    ossim_uint32 outputWidth  = theWidth<<1;
+//    ossim_uint32 outputHeight = theHeight<<1;
+   ossim_uint32 outputWidth  = ( ((theWidth-1)<<1) + 1);
+   ossim_uint32 outputHeight = ( ((theHeight-1)<<1) + 1);
+   osg::ref_ptr<ossimPlanetElevationGrid> result = new ossimPlanetElevationGrid(outputWidth,
+                                                                            outputHeight);
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+   const float* inputData = theGrid;
+   float* outputData = result->theGrid;
+   ossim_uint32 inputOffsetY = 0;
+   ossim_uint32 inputOffset = 0;
+   ossim_uint8 testLocation=0;
+   for(y = 0; y < outputHeight; ++y)
+   {
+      inputOffsetY = (y>>1)*theWidth;
+      for(x = 0; x < outputWidth; ++x)
+      {
+         inputOffset = inputOffsetY + (x>>1);
+         testLocation = ((y&1) << 1) | (x&1);
+         switch(testLocation)
+         {
+            case 0: // upper left 
+            {
+               // just copy the point
+               *outputData = inputData[inputOffset];
+               
+               break;
+            }
+            case 1: // upper right
+            {
+               // do horizontal t for x edge
+               *outputData = (inputData[inputOffset] +
+                              inputData[inputOffset+1])*.5;
+               break;
+            }
+            case 2: // lower left
+            {
+               // do vertical t for y edge
+               *outputData = (inputData[inputOffset] +
+                              inputData[inputOffset+theWidth])*.5;
+               
+               break;
+            }
+            case 3: // lower right
+            {
+               // do both horizontal and vertical using all 4 points
+               *outputData = (inputData[inputOffset] +
+                              inputData[inputOffset+theWidth]+
+                              inputData[inputOffset+theWidth+1]+
+                              inputData[inputOffset+1]
+                              )*.25;
+               break;
+            }
+         }
+         ++outputData;
+      }
+   }
+   return result;
+}
+
+void ossimPlanetElevationGrid::copyGrid(ossim_uint32 ulx,
+                                      ossim_uint32 uly,
+                                      osg::ref_ptr<ossimPlanetElevationGrid> output)const
+{
+   if(!output.valid()) return;
+   ossim_uint32 outputWidth  = output->getWidth();
+   ossim_uint32 outputHeight = output->getHeight();
+   ossim_float32 *outputBuf  = output->theGrid;
+   const ossim_float32 *inputBuf  = theGrid;
+   ossim_uint32 leftOffset = 0;
+   ossim_uint32 x = 0;
+   ossim_uint32 y = 0;
+
+   leftOffset = uly*theWidth + ulx;
+   for(y=0;y < outputHeight;++y)
+   {
+      for(x=0;x < outputWidth; ++x)
+      {
+         *outputBuf = inputBuf[leftOffset+x];
+         ++outputBuf;
+      }
+      leftOffset += theWidth;
+   }
+}
+
+bool ossimPlanetElevationGrid::isEqualTo(osg::ref_ptr<ossimPlanetElevationGrid> grid)const
+{
+   if(!grid.valid()) return false;
+   if(grid.get() == this) return true;
+   if( (grid->theWidth!=theWidth)||
+       (grid->theHeight != theHeight) ) return false;
+
+   ossim_uint32 idx = 0;
+   ossim_uint32 upperBound = theWidth*theHeight;
+
+   for(idx = 0; idx < upperBound;++idx)
+   {
+      if(theGrid[idx] != grid->theGrid[idx])
+      {
+         return false;
+      }
+   }
+
+   return true;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetElevationRegistry.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationRegistry.cpp
new file mode 100644
index 0000000..1f863ab
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetElevationRegistry.cpp
@@ -0,0 +1,61 @@
+#include <ossimPlanet/ossimPlanetElevationRegistry.h>
+#include <ossimPlanet/ossimPlanetElevationFactory.h>
+#include <OpenThreads/ScopedLock>
+#include <algorithm>
+
+ossimPlanetElevationRegistry::ossimPlanetElevationRegistry()
+{
+}
+
+bool ossimPlanetElevationRegistry::registerFactory(FactoryBase* factory)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   bool result = false;
+   FactoryList::iterator iter = std::find(theFactoryList.begin(), theFactoryList.end(), factory);
+   
+   if(iter == theFactoryList.end())
+   {
+      theFactoryList.push_back(factory);
+      result = true;
+   }
+   
+   return result;
+}
+
+void ossimPlanetElevationRegistry::unregisterFactory(FactoryBase* factory)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   FactoryList::iterator iter = std::find(theFactoryList.begin(), theFactoryList.end(), factory);
+   
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+}
+
+ossimPlanetElevationDatabase* ossimPlanetElevationRegistry::openDatabase(const ossimString& location)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimPlanetElevationDatabase* result = 0;
+   
+   FactoryList::iterator iter = theFactoryList.begin();
+   while(!result&&(iter != theFactoryList.end()))
+   {
+      result = (*iter)->openDatabase(location);
+      ++iter;
+   }
+   
+   return result;
+}
+
+ossimPlanetElevationRegistry* ossimPlanetElevationRegistry::instance()
+{
+   static ossimPlanetElevationRegistry* theInstance = 0;
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetElevationRegistry();
+      theInstance->registerFactory(ossimPlanetElevationFactory::instance());
+   }
+   
+   return theInstance;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetEphemeris.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetEphemeris.cpp
new file mode 100644
index 0000000..d55f82e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetEphemeris.cpp
@@ -0,0 +1,2508 @@
+#ifdef OSSIMPLANET_ENABLE_EPHEMERIS
+#include <osg/ShapeDrawable>
+#include <osg/PositionAttitudeTransform>
+#include <osg/io_utils>
+//#include <gpstk/Geodetic.hpp>
+#include <gpstk/SunPosition.hpp>
+#include <gpstk/MoonPosition.hpp>
+#include <gpstk/Position.hpp>
+#include <gpstk/WGS84Ellipsoid.hpp>
+#include <gpstk/SystemTime.hpp>
+#include <gpstk/ReferenceFrame.hpp>
+//#include <gpstk/ECEF.hpp>
+//#include <gpstk/WGS84Geoid.hpp>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetPointModel.h>
+#include <ossimPlanet/ossimPlanetBillboardIcon.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetCloudLayer.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossim/base/ossimUnitConversionTool.h>
+#include <ossim/imaging/ossimJpegWriter.h>
+#include <ossim/imaging/ossimMemoryImageSource.h>
+#include <ossim/base/ossimUnitConversionTool.h>
+#include <osg/CoordinateSystemNode>
+#include <osg/VertexProgram>
+#include <osg/Fog>
+#include <osg/Camera>
+#include <osg/io_utils>
+#include <osg/Depth>
+#include <osg/BlendFunc>
+#include <osg/AlphaFunc>
+#include <osg/FragmentProgram>
+#include <osgGA/EventVisitor>
+#include <osgUtil/IntersectVisitor>
+#include <osgUtil/IntersectionVisitor>
+
+#include <osg/io_utils>
+#include <time.h>
+#include <osgDB/Registry>
+#include <osgDB/ReadFile>
+#include <osgDB/WriteFile>
+#include <queue>
+
+
+
+
+class EnvEffect : public osg::Referenced
+{
+public:
+   
+   EnvEffect( const std::string& name = "EnvEffect" )
+   {
+      
+   }
+   
+protected:
+   
+   virtual ~EnvEffect()
+   {
+      
+   }
+   
+public:
+   
+   /// Must override this to supply the repainting routine
+   virtual void Repaint(const osg::Vec3& skyColor, 
+                        const osg::Vec3& fogColor,
+                        double sunAngle, 
+                        double sunAzimuth,
+                        double visibility,
+                        double altitude=0.0) = 0;
+   
+   ///required by DeltaDrawable
+   osg::Node* GetOSGNode(){return mNode.get();}
+   const osg::Node* GetOSGNode() const{return mNode.get();}
+   
+   void SetOSGNode(osg::Node* pNode){mNode = pNode;}
+   
+private:
+   
+   // Disallowed to prevent compile errors on VS2003. It apparently
+   // creates this functions even if they are not used, and if
+   // this class is forward declared, these implicit functions will
+   // cause compiler errors for missing calls to "ref".
+   EnvEffect& operator=( const EnvEffect& ); 
+   EnvEffect( const EnvEffect& );
+   
+   osg::ref_ptr<osg::Node> mNode;
+};
+
+class  MoveEarthySkyWithEyePointTransform : public osg::Transform
+{
+public:
+   
+   ///Get the transformation matrix which moves from local coords to world coords.
+   virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+   
+   ///Get the transformation matrix which moves from world coords to local coords.
+   virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+};
+
+class  MoveEarthySkyWithEyePointTransformAzimuth : public osg::Transform
+{
+public:
+   
+   ///Get the transformation matrix which moves from local coords to world coords.
+   virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+   
+   ///Get the transformation matrix which moves from world coords to local coords.
+   virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
+   
+   float GetAzimuth() const { return mAzimuth; }
+   void SetAzimuth( float azimuth ) { mAzimuth = azimuth; }
+   
+private:
+   
+   float mAzimuth;
+};
+bool MoveEarthySkyWithEyePointTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+   if ( osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv) )
+   {
+      osg::Vec3 eyePointLocal = cv->getEyeLocal();
+      matrix.preMult(osg::Matrix::translate(eyePointLocal.x(),eyePointLocal.y(),eyePointLocal.z()));
+   }
+   return true;
+}
+
+///Get the transformation matrix which moves from world coords to local coords.
+bool MoveEarthySkyWithEyePointTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+   if ( osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv) )
+   {
+      osg::Vec3 eyePointLocal = cv->getEyeLocal();
+      matrix.postMult(osg::Matrix::translate(-eyePointLocal.x(),-eyePointLocal.y(),-eyePointLocal.z()));
+   }
+   return true;
+}
+
+///Get the transformation matrix which moves from local coords to world coords.
+bool MoveEarthySkyWithEyePointTransformAzimuth::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+   if ( osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv) )
+   {
+      osg::Vec3 eyePointLocal = cv->getEyeLocal();
+      matrix.preMult(osg::Matrix::translate(eyePointLocal.x(),eyePointLocal.y(),eyePointLocal.z()));
+      matrix.preMult(osg::Matrix::rotate(osg::DegreesToRadians(mAzimuth-90.0f), 0.0f, 0.0f, 1.0f));
+   }
+   return true;
+}
+
+///Get the transformation matrix which moves from world coords to local coords.
+bool MoveEarthySkyWithEyePointTransformAzimuth::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+  if ( osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv) )
+   {
+      osg::Vec3 eyePointLocal = cv->getEyeLocal();
+      matrix.postMult(osg::Matrix::translate(-eyePointLocal.x(),-eyePointLocal.y(),-eyePointLocal.z()));
+   }
+   return true;
+}
+
+class SkyDomeShader : public osg::Referenced
+{
+public:
+   SkyDomeShader()
+   {
+      mLightScatterinVP = new osg::VertexProgram();
+      mDomeFP = new osg::FragmentProgram();
+      
+      char data[] =
+      "!!ARBvp1.0                                              \n"
+      "                                                        \n"
+      "   PARAM mvp[4] = { state.matrix.mvp };                 \n"
+      "   PARAM camera = program.local[0];                     \n"
+      "   PARAM dir = program.local[1];                        \n"
+      "   PARAM betaRay = program.local[2];                    \n"
+      "   PARAM betaMie = program.local[3];                    \n"
+      "                                                          \n"
+      "   # Energy / (betaRay + betaMie)                       \n"
+      "   PARAM energyOverRayMie = program.local[4];              \n"
+      "                                                            \n"
+      "   # G = greenstein                                         \n"
+      "   # (-G * 2.0, G * G + 1.0, (1.0 - G) * (1.0 - G))  \n"
+      "   PARAM greenstein = program.local[5];                  \n"
+      "                                                        \n"
+      "   PARAM time = program.local[6];                         \n"
+      "                                                         \n"
+      "   ATTRIB xyz = vertex.position;                        \n"
+      "   ATTRIB texcoord = vertex.texcoord;                    \n"
+      "   ATTRIB norm = vertex.normal;                         \n"
+      "                                                         \n"
+      "   DP4 result.position.x, mvp[0], xyz;                  \n"
+      "   DP4 result.position.y, mvp[1], xyz;                  \n"
+      "   DP4 result.position.z, mvp[2], xyz;                   \n"
+      "   DP4 result.position.w, mvp[3], xyz;                \n"
+      "                                                        \n"
+      "   TEMP temp;                                  \n"
+      "   SUB temp, camera, xyz;                      \n"
+      "   DP3 temp.w, temp, temp;                      \n"
+      "   RSQ temp.w, temp.w;                         \n"
+      "   MUL temp, temp, temp.w;                        \n"
+      "                                               \n"
+      "   TEMP cos;                                         \n"
+      "   DP3 cos.x, temp, dir;                          \n"
+      "   MUL cos.y, cos.x, cos.x;   # cos * cos           \n"
+      "   SUB cos.z, 1.0, cos.y;      # 1.0 - cos * cos       \n"
+      "                                                      \n"
+      "   TEMP ray;                                             \n"
+      "   MUL ray, cos.z, 0.0597;      # 3.0 / (16.0 * PI)  \n"
+      "   MUL ray, ray, betaRay;                            \n"
+      "                                                     \n"
+      "   TEMP mie;                                         \n"
+      "   MAD mie, greenstein.x, cos.x, greenstein.y;       \n"
+      "   MOV cos.w, 1.5;                                   \n"
+      "   POW mie.x, mie.x, cos.w;                          \n"
+      "   RCP mie.x, mie.x;                                 \n"
+      "   MUL mie, mie.x, greenstein.z;                      \n"
+      "   MUL mie, mie, 0.0796;      # 1.0 / (4.0 * PI)       \n"
+      "   MUL mie, mie, betaMie;                            \n"
+      "                                                     \n"
+      "   SUB temp, camera, xyz;                         \n"
+      "   DP3 temp.w, temp, temp;                           \n"
+      "   RSQ temp.w, temp.w;                               \n"
+      "   RCP temp.w, temp.w;      # distance to camera        \n"
+      "                                                     \n"
+      "   TEMP fog;                                       \n"
+      "   ADD fog, betaRay, betaMie;                         \n"
+      "   MUL fog, fog, temp.w;                                \n"
+      "   MUL fog, fog, 0.693;   # ln(2.0)                  \n"
+      "                                                     \n"
+      "   EX2 fog.x, -fog.x;                                \n"
+      "   EX2 fog.y, -fog.y;                                \n"
+      "   EX2 fog.z, -fog.z;                                \n"
+      "                                                     \n"
+      "   SUB temp, 1.0, fog;      # 1.0 - fog                 \n"
+      "                                                     \n"
+      "   TEMP scattering;                                  \n"
+      "   ADD scattering, ray, mie;                          \n"
+      "   MUL scattering, scattering, energyOverRayMie;        \n"
+      "   MUL scattering, scattering, temp;                  \n"
+      "                                                        \n"
+      "   MOV result.texcoord[0], texcoord;                    \n"
+      "   MOV result.texcoord[1], scattering;                 \n"
+      "   MOV result.texcoord[2], fog;                         \n"
+      "   MOV result.texcoord[3], norm;                        \n"
+      "   MOV result.color, vertex.color;                      \n"
+      "   END                                                  \n";
+      
+      mLightScatterinVP->setVertexProgram(data);
+      
+      char data2[] =
+      "!!ARBfp1.0                                     \n"
+      "                                                \n"
+      "   # brightness, contrast                      \n"
+      "   PARAM bc = program.local[0];                 \n"
+      "                                                \n"
+      "   TEMP clouds;                                   \n"
+      "   MOV clouds, fragment.color;                    \n"
+      "                                                  \n"
+      "   TEMP color;                                 \n"
+      "   LRP color, fragment.texcoord[2], clouds, fragment.texcoord[1];  \n"
+      "                           \n"
+      "   TEMP temp; \n"
+      "   SUB temp, color, 0.5;  \n"
+      "   MAD color, temp, bc.y, color;   \n"
+      "   ADD result.color, color, bc.x;  \n"
+      "                                      \n"
+      "   END  \n";
+      mDomeFP->setFragmentProgram( data2 );
+      
+      lambda = osg::Vec3(1.0f/650e-9f, 1.0f/570e-9f, 1.0f/475e-9f);
+      
+      for (int i = 0; i < 3; i++)
+      {
+         lambda2[i] = lambda[i] * lambda[i];
+         lambda4[i] = lambda2[i] * lambda2[i];
+      }
+      
+      //constants
+      n = 1.003f; //refractive index of air
+      pn = 0.035f; //depolarization factor of air
+      
+      mBrightness = 0.125f;
+      mContrast = 0.15f;
+      
+      greenstein = 0.8f * 1.5f; ///< Magic number
+      
+   }
+   virtual ~SkyDomeShader(){
+   }
+   
+   ///Update the shader with new values
+   void Update(const osg::Vec3d& sunVec,//const osg::Vec2& sunDir,
+               float turbidity, 
+               float energy, 
+               float molecules )
+   {
+      mLightScatterinVP->setProgramLocalParameter(0, osg::Vec4(0.f, 0.f, 0.f, 0.f) );
+      mLightScatterinVP->setProgramLocalParameter(1, osg::Vec4( sunVec[0], sunVec[1], sunVec[2], 0));
+      
+      float tempMie = 0.434 * ConcentrationFactor(turbidity) * osg::PI * (2 * osg::PI) * (2 * osg::PI) * 0.5;
+      betaMie = osg::Vec3(lambda2[0] * 0.685,lambda2[1] * 0.679,lambda2[2] * 0.67) * tempMie;
+      
+      //Rayleigh scattering
+      float tempRay = osg::PI * osg::PI * (n * n - 1.0) * (n * n - 1.0) * (6.0 + 3.0 * pn) / (6.0 - 7.0 * pn) / molecules;
+      betaRay = lambda4 * 8.0 * tempRay * osg::PI / 3.0;
+      
+      mLightScatterinVP->setProgramLocalParameter(2, osg::Vec4(betaRay,0) );
+      mLightScatterinVP->setProgramLocalParameter(3, osg::Vec4(betaMie, 0));
+      mLightScatterinVP->setProgramLocalParameter(4, osg::Vec4(energy / (betaRay[0] + betaMie[0]),
+                                                               energy / (betaRay[1] + betaMie[1]),
+                                                               energy / (betaRay[2] + betaMie[2]),0));
+      mLightScatterinVP->setProgramLocalParameter(5, osg::Vec4(-greenstein * 2.0,
+                                                               greenstein * greenstein + 1.0,
+                                                               (1.0 - greenstein) * (1.0 - greenstein),0));
+      
+      mDomeFP->setProgramLocalParameter(0, osg::Vec4( mBrightness, mContrast, 0, 0));
+   }
+   
+   osg::VertexProgram* GetLightScatterinVP() { return mLightScatterinVP.get(); }
+   osg::FragmentProgram* GetDomeFP() { return mDomeFP.get(); }
+   
+private:
+   
+   ///our vertex program pointer
+   osg::ref_ptr<osg::VertexProgram> mLightScatterinVP;
+   ///our fragment program pointer
+   osg::ref_ptr<osg::FragmentProgram> mDomeFP;
+   
+   osg::Vec3 lambda;
+   osg::Vec3 lambda2;
+   osg::Vec3 lambda4;
+   float n; ///<Refractive index of air
+   float pn; ///<depolarization factor of air
+   float greenstein; ///<eccentricity value
+   float mBrightness; ///<scene brightness adjustment
+   float mContrast; ///<scene contrast adjustment
+   osg::Vec3 betaRay;
+   osg::Vec3 betaMie;
+   
+   float ConcentrationFactor(float turbidity)
+   {
+      return (6.544 * turbidity - 6.51) * 1e-17; ///<more magic numbers
+   }
+   
+};
+
+class  MakeSkyDome
+   {
+   public:
+      
+      MakeSkyDome(float radius, bool capEnabled = true);
+      ~MakeSkyDome();
+      
+      osg::Geode* Compute();
+      
+   protected:
+      
+   private:
+      unsigned int GetNumLevels();
+      void SetCoordinatesAndColors();
+      void SetCapCoordinatesAndColors();
+      void CreateTriangleStrips();
+      osg::StateSet* CreateStateSet() const;
+      
+      float                  mRadius;
+      osg::Geometry*         mGeom;
+      osg::Vec3Array*        mCoordArray;
+      osg::Vec4Array*        mColorArray;
+      std::vector<float>     mLevelHeight;
+      std::vector<osg::Vec3> mCCArray;
+      bool                   theCapEnabled;
+      
+      static const unsigned int VERTS_IN_CIRCUM;
+   };
+const unsigned int MakeSkyDome::VERTS_IN_CIRCUM = 19;
+
+////////////////////////////////////////////////////////////////////////////////
+MakeSkyDome::MakeSkyDome(float radius, bool capEnabled)
+: mRadius(radius)
+, mGeom(new osg::Geometry()),
+theCapEnabled(capEnabled)
+{
+   mLevelHeight.push_back(-9.0f);
+   mLevelHeight.push_back(-9.0f);
+   mLevelHeight.push_back(0.0f);
+   mLevelHeight.push_back(7.2f);
+   mLevelHeight.push_back(15.0f);
+   mLevelHeight.push_back(90.0f);
+   
+   mCCArray.push_back(osg::Vec3(0.15f, 0.25f, 0.1f));
+   mCCArray.push_back(osg::Vec3(0.6f, 0.6f, 0.7f));
+   mCCArray.push_back(osg::Vec3(0.4f, 0.4f, 0.7f));
+   mCCArray.push_back(osg::Vec3(0.2f, 0.2f, 0.6f));
+   mCCArray.push_back(osg::Vec3(0.1f, 0.1f, 0.6f));
+   mCCArray.push_back(osg::Vec3(0.1f, 0.1f, 0.7f));
+   
+   mCoordArray = new osg::Vec3Array(VERTS_IN_CIRCUM * mLevelHeight.size());
+   mColorArray = new osg::Vec4Array(VERTS_IN_CIRCUM * mLevelHeight.size());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+MakeSkyDome::~MakeSkyDome()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+osg::Geode* MakeSkyDome::Compute()
+{
+   SetCoordinatesAndColors();
+   
+   CreateTriangleStrips();
+   
+   mGeom->setVertexArray(mCoordArray);
+   mGeom->setColorArray(mColorArray);
+   mGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+   
+   mGeom->setStateSet(CreateStateSet());
+   //mGeom->setUseVertexBufferObjects(true);
+//   mGeom->setFastPathHint(false);
+   osg::Geode* geode = new osg::Geode;
+   geode->addDrawable(mGeom);
+   geode->setName("Sky");
+  
+   return geode;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned int MakeSkyDome::GetNumLevels()
+{
+   return (mLevelHeight.size() - (theCapEnabled? 0: 1));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void MakeSkyDome::SetCoordinatesAndColors()
+{
+   unsigned int ci = theCapEnabled?VERTS_IN_CIRCUM:0;
+   
+   // Set dome coordinates & colors
+   for(unsigned int i = theCapEnabled ? 1: 0; i < GetNumLevels(); i++)
+   {
+      for(unsigned int j = 0; j < VERTS_IN_CIRCUM; j++)
+      {
+         float alpha = osg::DegreesToRadians(mLevelHeight[i+(theCapEnabled ? 0: 1)]);
+         float theta = osg::DegreesToRadians((float)(j * 20));
+         
+         float x = mRadius * cos(alpha) * cos(theta);
+         float y = mRadius * cos(alpha) * -sin( theta );
+         float z = mRadius * sin(alpha);
+         
+         assert(ci < mCoordArray->size());
+         (*mCoordArray)[ci].set(x,y,z);
+         
+         assert(ci < mColorArray->size());
+         assert(i < mCCArray.size());
+         (*mColorArray)[ci].set(mCCArray[i].x(), mCCArray[i].y(), mCCArray[i].z(), 1.f);
+         
+         ci++;
+      }
+   }
+   
+   SetCapCoordinatesAndColors();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void MakeSkyDome::SetCapCoordinatesAndColors()
+{
+   if(theCapEnabled)
+   {
+      osg::Vec3 capCenter(0.0f, 0.0f, mRadius * osg::DegreesToRadians(sin(mLevelHeight[0])));
+      
+      for(unsigned int j = 0; j < VERTS_IN_CIRCUM; j++)
+      {
+         (*mCoordArray)[j] = capCenter;
+         
+         assert(j < mColorArray->size());
+         (*mColorArray)[j].set(mCCArray.back().x(), mCCArray.back().y(), mCCArray.back().z(), 1.0f);
+      }
+   }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void MakeSkyDome::CreateTriangleStrips()
+{
+   for(unsigned int i = 0; i < GetNumLevels() - 1; i++)
+   {
+      osg::DrawElementsUShort* drawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP);
+      drawElements->reserve(38);
+      
+      for(unsigned j = 0; j < VERTS_IN_CIRCUM; j++)
+      {
+         drawElements->push_back((i + 1) * VERTS_IN_CIRCUM + j);
+         drawElements->push_back((i + 0) * VERTS_IN_CIRCUM + j);
+      }
+      
+      mGeom->addPrimitiveSet(drawElements);
+   }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+osg::StateSet* MakeSkyDome::CreateStateSet() const
+{
+   osg::StateSet *dstate = new osg::StateSet;
+   
+   dstate->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+   dstate->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+   
+   // clear the depth to the far plane.
+   osg::Depth* depth = new osg::Depth(osg::Depth::ALWAYS);
+   depth->setWriteMask(false);   
+   dstate->setAttributeAndModes(depth,osg::StateAttribute::ON);
+   dstate->setMode(GL_FOG, osg::StateAttribute::OFF);
+   dstate->setMode(GL_BLEND, osg::StateAttribute::ON);
+   
+   dstate->setRenderBinDetails(-2,"RenderBin");
+   
+   return dstate;
+}
+#if 0
+static double fade_coefficient(double currentAltitude, 
+                             double refAltitude)
+{
+   return exp( - currentAltitude / refAltitude );
+}
+#endif
+static void fade_to_black(osg::Vec3 sky_color[], 
+                          double currentAltitude, 
+                          double refAltitude,
+                          int count)
+{
+   double d = mkUtils::fadeCoefficient(currentAltitude, refAltitude);
+   d = ossim::clamp(d, 0.0, 1.0);
+   for(int i = 0; i < count ; i++)
+   {
+      sky_color[i] *= d;
+   }
+}
+static double fade_to_black(double curretValue, 
+                            double currentAltitude, 
+                            double refAltitude)
+{
+   double d = mkUtils::fadeCoefficient(currentAltitude, refAltitude);
+   d = ossim::clamp(d, 0.0, 1.0);
+   return curretValue*d;
+}
+
+class SkyDome : public EnvEffect
+{
+public:
+   SkyDome(const std::string& name = "SkyDome", bool createCapGeometry = true, float radius = 6000.0f)
+   :mEnableCap(createCapGeometry),
+   theMaxAltitude(80000)
+   {
+      SetOSGNode(new osg::Group());
+      mBaseColor.set(0.5f, 0.5f, 0.2f);
+      Config(radius);
+   }
+protected:
+   virtual ~SkyDome()
+   {
+      
+   }
+   
+public:
+   ///sets the base color
+   void SetBaseColor(const osg::Vec3& color)
+   {
+      osg::Geometry* geom = mGeode->getDrawable(0)->asGeometry();
+      osg::Array* array = geom->getColorArray();
+      if (array && array->getType() == osg::Array::Vec4ArrayType)
+      {
+         mBaseColor.set(color);
+         
+         osg::Vec4Array* color = static_cast<osg::Vec4Array*>(array);
+         unsigned int limit = mEnableCap ? 38: 19;
+         
+         for (unsigned int i=0; i<limit; i++)
+         {
+            assert(i<color->size());
+            (*color)[i].set(mBaseColor[0], mBaseColor[1], mBaseColor[2], 1.f);
+         }
+         geom->dirtyDisplayList();
+      }
+      
+   }
+   
+   ///gets the base color
+   void GetBaseColor(osg::Vec3& color) const { color.set(mBaseColor); }
+   
+   bool GetCapEnabled() const { return mEnableCap; }
+   
+   ///the virtual paint function
+   /** 0 degrees  = horizon
+    *  90 degrees = high noon
+    *  - degrees  = below horizon
+    */
+   virtual void Repaint(const osg::Vec3& skyColor, 
+                        const osg::Vec3& fogColor,
+                        double sunAngle, 
+                        double sunAzimuth,
+                        double visibility,
+                        double altitude = 0.0)
+   {
+      outer_param.set(0.0, 0.0, 0.0);
+      middle_param.set(0.0, 0.0, 0.0);
+      
+      outer_diff.set(0.0, 0.0, 0.0);
+      middle_diff.set(0.0, 0.0, 0.0);
+      
+      // Check for sunrise/sunset condition
+      if(IsSunsetOrSunrise(sunAngle))
+      {
+         // 0.0 - 0.4
+         outer_param.set((10.0 - std::abs(sunAngle)) / 20.0,
+                         (10.0 - std::abs(sunAngle)) / 40.0,
+                         -(10.0 - std::abs(sunAngle)) / 30.0);
+         
+         middle_param.set((10.0 - std::abs(sunAngle)) / 40.0,
+                          (10.0 - std::abs(sunAngle)) / 80.0,
+                          0.0);
+         
+         outer_diff = outer_param / 9.0;
+         
+         middle_diff = middle_param / 9.0;
+      } 
+      
+      outer_amt.set(outer_param);
+      middle_amt.set(middle_param);
+      
+      // First, recaclulate the basic colors
+      
+      CalcNewColors(visibility, skyColor, fogColor, altitude);
+      
+      AssignColors();
+   }
+   void setMaxAltitude(double maxAltitude)
+   {
+      theMaxAltitude = maxAltitude;
+   }
+private:
+   
+   
+   /// Build the sky dome
+   void Config(float radius)
+   {
+      osg::Group* group = new osg::Group();
+
+      mGeode = MakeSkyDome(radius, mEnableCap).Compute();
+      GetOSGNode()->asGroup()->addChild(mGeode.get());
+   }
+   bool IsSunsetOrSunrise(double sunAngle) const
+   {
+      return ((sunAngle > -10.0) && (sunAngle < 10.0));
+   }
+   osg::Vec3 CalcCenterColors(double vis_factor,
+                              const osg::Vec3& skyColor, 
+                              const osg::Vec3& fogColor) const
+   {
+      osg::Vec3 center_color;
+      
+      for (unsigned int j = 0; j < 3; j++) 
+      {
+         const osg::Vec3::value_type diff = skyColor[j] - fogColor[j];
+         center_color[j] = skyColor[j] - diff * (1.0 - vis_factor);
+      }
+      
+      return center_color;
+      
+   }
+   
+   void CalcNewColors(double visibility, const osg::Vec3& skyColor, 
+                      const osg::Vec3& fogColor,
+                      double altitude = 0.0)
+   {
+      center_color = CalcCenterColors(GetVisibilityFactor(visibility), skyColor, fogColor);
+      
+      for (unsigned int i = 0; i < 9; i++) 
+      {
+         SetUpperMiddleLowerColors(skyColor, fogColor, i, visibility, altitude);
+         
+         outer_amt -= outer_diff;
+         middle_amt -= middle_diff;
+      }
+      
+      outer_amt.set(0.0, 0.0, 0.0);
+      middle_amt.set(0.0, 0.0, 0.0);
+      
+      for (unsigned int i = 9; i < 19; i++) 
+      {
+         SetUpperMiddleLowerColors(skyColor, fogColor, i, visibility, altitude);
+         
+         outer_amt += outer_diff;
+         middle_amt += middle_diff;
+      }
+      
+      for (unsigned int i = 0; i < 19; i++) 
+      {
+         bottom_color[i] = fogColor;
+      }
+   }
+   
+   
+   double CalcCVF(double visibility) const
+   {
+      return ossim::clamp(visibility, 0.0, 20000.0);
+   }
+   
+   void SetUpperMiddleLowerColors(const osg::Vec3& skyColor, const osg::Vec3& fogColor,
+                                  unsigned int i, double visibility, double altitude=0.0 )
+   {
+      const double cvf = CalcCVF(visibility);
+      
+      for (unsigned int j = 0; j < 3; j++) 
+      {
+         const osg::Vec3::value_type diff = skyColor[j] - fogColor[j];
+         
+         upper_color[i][j] = skyColor[j] - diff *
+         (1.0 - GetVisibilityFactor(visibility) * (0.7 + 0.3 * cvf/20000.f));
+         
+         middle_color[i][j] = skyColor[j] - diff *
+         (1.0 - GetVisibilityFactor(visibility) * (0.1 + 0.85 * cvf/20000.f))
+         + middle_amt[j];
+         
+         lower_color[i][j] = fogColor[j] + outer_amt[j];
+         
+         
+         upper_color[i][j] = ossim::clamp(upper_color[i][j], 0.f, 1.f);
+         middle_color[i][j] = ossim::clamp(middle_color[i][j], 0.f, 1.f);
+         lower_color[i][j] = ossim::clamp(lower_color[i][j], 0.f, 1.f);
+         
+
+      }
+      //fade_to_black(&(*dome_cl)[0], asl * center_elev, 1);
+      fade_to_black(&upper_color[i], altitude, theMaxAltitude, 1);
+      fade_to_black(&middle_color[i], altitude, theMaxAltitude, 1);
+      fade_to_black(&lower_color[i], altitude, theMaxAltitude, 1);
+   }
+   
+   void AssignColors() const
+   {
+      osg::Geometry* geom = mGeode->getDrawable(0)->asGeometry();
+      osg::Array* array = geom->getColorArray();
+      if (array && array->getType()==osg::Array::Vec4ArrayType)
+      {
+         osg::Vec4Array* color = dynamic_cast<osg::Vec4Array*>(array);
+         // Set cap color
+         if(mEnableCap)
+         {
+            for (unsigned int i = 0; i < 19; i++)
+            {
+               (*color)[i].set(bottom_color[i][0], bottom_color[i][1], bottom_color[i][2], 1.0);
+            }
+         }
+         
+         // Set dome colors
+         unsigned int c = mEnableCap?19:0;
+         for(unsigned int i = 0; i < 19; i++)
+         {
+            (*color)[c].set(bottom_color[i][0], bottom_color[i][1], bottom_color[i][2], 1.0);
+            (*color)[c+19].set(lower_color[i][0], lower_color[i][1], lower_color[i][2], 1.0);
+            (*color)[c+19+19].set(middle_color[i][0], middle_color[i][1], middle_color[i][2], 1.0);
+            (*color)[c+19+19+19].set(upper_color[i][0], upper_color[i][1], upper_color[i][2], 1.0);
+            (*color)[c+19+19+19+19].set(center_color[0], center_color[1], center_color[2], 1.0);
+            c++;
+         }
+         geom->dirtyDisplayList();
+     }
+   }
+   double GetVisibilityFactor(double visibility) const
+   {
+      if (visibility < 3000.0) 
+      {
+         double vis_factor = (visibility - 1000.0) / 2000.0;
+         
+         ossim::clamp(vis_factor, 0.0, 1.0);
+         return vis_factor;
+      }
+      
+      return 1.0;
+      
+   }
+   osg::ref_ptr<osg::Geode> mGeode;
+   osg::ref_ptr<MoveEarthySkyWithEyePointTransformAzimuth> mXform;
+   
+   bool mEnableCap;
+   osg::Vec3 mBaseColor;
+   osg::Vec3 outer_param, outer_amt, outer_diff;
+   osg::Vec3 middle_param, middle_amt, middle_diff;
+   osg::Vec3 center_color;
+   osg::Vec3 upper_color[19];
+   osg::Vec3 middle_color[19];
+   osg::Vec3 lower_color[19];
+   osg::Vec3 bottom_color[19];
+   osg::ref_ptr<osg::Group> theOsgNode;
+   ossim_float64 theMaxAltitude;
+};
+
+class ossimPlanetEphemeris::EphemerisData
+{
+public:
+   typedef std::vector<osg::ref_ptr<ossimPlanetCloudLayer> > CloudLayers;
+   ~EphemerisData()
+   {
+      theLayer = 0;
+   }
+   EphemerisData(ossimPlanetEphemeris* layer,
+                 ossim_uint64 membersBitMap);
+   void setMembers(ossim_uint64 membersBitMap);
+   void traverse(osg::NodeVisitor& nv);
+   void updatePositions(osg::NodeVisitor& nv);
+   void setMoonLightIndex(ossim_uint32 idxNumber)
+   {
+      theMoonLightIdx = idxNumber;
+      if(theMoonLightSource.valid())
+      {
+         theMoonLightSource->getLight()->setLightNum(theMoonLightIdx);
+      }
+   }
+   ossim_uint32 moonLightIndex()const
+   {
+      return theMoonLightIdx;
+   }
+   void setSunLightIndex(ossim_uint32 idxNumber)
+   {
+      theSunLightIdx = idxNumber;
+      if(theSunLightSource.valid())
+      {
+         theSunLightSource->getLight()->setLightNum(theSunLightIdx);
+      }
+   }
+   ossim_uint32 sunLightIndex()const
+   {
+      return theSunLightIdx;
+   }
+   ossim_uint64 members()const
+   {
+      return theMembers;
+   }
+   void setDate(const ossimLocalTm& date)
+   {
+      theDate = date;
+   }
+   const ossimLocalTm& date()const
+   {
+      return theDate;
+   }
+   void setAutoUpdateToCurrentTimeFlag(bool flag)
+   {
+      theAutoUpdateCurrenTimeFlag = flag;
+   }
+   bool autoUpdateCurrentTimeFlag()const
+   {
+      return theAutoUpdateCurrenTimeFlag;
+   }
+   void setApplySimulationTimeOffsetFlag(bool flag)
+   {
+      theApplySimulationTimeOffsetFlag = flag;
+   }
+   void setAdjustedVisibility(ossim_float64 vis)
+   {
+      double sqrt_m_log01 = sqrt(-log(0.01));
+      float density = sqrt_m_log01 / vis;
+      
+      theFog->setDensity(density);
+      if(theLayer->model())
+      {
+         theFog->setEnd(vis/theLayer->model()->getNormalizationScale());
+      }
+   }
+   void setVisibility(ossim_float64 visibility)
+   {
+      theVisibility = visibility;
+      setAdjustedVisibility(visibility);
+   }
+   double getVisibility()const
+   {
+      return theVisibility;
+   }
+   void setFogNear(ossim_float64 val)
+   {
+      theFogNear = val;
+      theFogNear = val;
+      
+      if (theFogNear < 0.f)
+      {
+         theFogNear = 0.f;
+      }
+      if (theFogNear > theVisibility)
+      {
+         theFogNear = theVisibility;
+      }
+      
+      if(theLayer->model())
+      {
+         theFog->setEnd(theVisibility/theLayer->model()->getNormalizationScale());
+         theFog->setStart(theFogNear/theLayer->model()->getNormalizationScale());///osg::WGS_84_RADIUS_EQUATOR);
+      }
+   }
+   void setFogFar(ossim_float64 val)
+   {
+      theFog->setEnd(val);///osg::WGS_84_RADIUS_EQUATOR);
+   }
+   void setFogDensity(ossim_float64 val)
+   {
+      theFog->setDensity(val);
+   }
+   void setFogMode(FogMode mode)
+   {
+      theFogMode = mode;
+      osg::Fog::Mode fm;
+      short attr = osg::StateAttribute::OFF;
+      
+      switch (mode)
+      {
+         case ossimPlanetEphemeris::LINEAR:  fm = osg::Fog::LINEAR; break;
+         case ossimPlanetEphemeris::EXP:     fm = osg::Fog::EXP;    break;
+         case ossimPlanetEphemeris::EXP2:    fm = osg::Fog::EXP2;   break;
+#if 0
+         case ossimPlanetEphemer::ADV:
+         {
+            fm = osg::Fog::LINEAR;
+            if (GetFogEnable())  { attr = osg::StateAttribute::ON;  }
+            else                 { attr = osg::StateAttribute::OFF; }
+         }
+#endif
+            break;
+         default: fm = osg::Fog::LINEAR; break;
+      }
+
+      theFog->setMode(fm);
+   }
+   void updateSunLight()
+   {
+      double coefficient = mkUtils::fadeCoefficient(theEyeLlh[2], theMaxAltitudeToDoSunriseSunsetColorAdjustment);
+      coefficient = ossim::clamp(coefficient, 0.0, 1.0);
+      if(!theUseFadingFlagForSunriseSunsetCalculation)
+      {
+         if(theEyeLlh[2] > theMaxAltitudeToDoSunriseSunsetColorAdjustment)
+         {
+            coefficient = 0.0;
+         }
+         else
+         {
+            coefficient = 1.0;
+         }
+      }
+      osg::Vec3d position = theSunXyz;
+      osg::Vec3d direction = -theSunXyz;
+      direction.normalize();
+      if(!theSunLightSource.valid())
+      {
+         return;
+      }
+      double red   = theSunElevation * 0.5;
+      double green = theSunElevation * 0.25;
+      double blue  = theSunElevation * 0.125;
+      red = ossim::clamp(red,   0.0, 1.0);
+      green = ossim::clamp(green, 0.0, 1.0);
+      blue = ossim::clamp(blue,  0.0, 1.0);
+      osg::Vec3 diff1(1.0, 1.0, 1.0);
+      osg::Vec3 amb1(.01, 0.01, 0.01);
+      osg::Vec3 amb2(red, green, blue);
+      osg::Vec3 diff2(red, green, blue);
+      
+      // setup a calculated ambient based on sun elevation 
+      //
+      red   = (theSunElevation + 10.0) * 0.04;
+      green = (theSunElevation + 10.0) * 0.02;
+      blue  = (theSunElevation + 10.0) * 0.01;
+      red = ossim::clamp(red,   0.01, 0.3);
+      green = ossim::clamp(green, 0.01, 0.3);
+      blue = ossim::clamp(blue,  0.01, 0.3);
+      amb2 = osg::Vec3d(red, green, blue);
+      
+      // fade the colors together to the reference height
+      //
+      osg::Vec3 diff = diff2*(coefficient) + diff1*(1.0-coefficient);
+      osg::Vec3 amb = amb2*(coefficient)   + amb1*(1.0-coefficient);
+      osg::Vec4 d(diff[0], diff[1], diff[2], 1.0);
+
+      osg::Vec4 a(amb[0], amb[1], amb[2], 1.0);
+      theSunColor = diff;
+      theSunLightSource->getLight()->setDiffuse(d);
+      theSunLightSource->getLight()->setSpecular(d);
+      theSunLightSource->getLight()->setAmbient(a);
+      theSunLightSource->getLight()->setPosition(osg::Vec4d(position, 0.0));
+      theSunLightSource->getLight()->setDirection(direction);
+      
+      if(theSunLightCallback.valid())
+      {
+         (*theSunLightCallback)(theLayer,
+                                theSunLightSource.get());
+         osg::Vec4d diff = theSunLightSource->getLight()->getDiffuse();
+         theSunColor = osg::Vec3d(diff[0], diff[1], diff[2]);    
+      }
+      
+
+      osg::Vec4 d2(diff1[0], diff1[1], diff1[2], 1.0);
+      osg::Vec4 a2(amb1[0], amb1[1], amb1[2], 1.0);
+
+      theSunLightSourceMoonPhase->getLight()->setDiffuse(d2);
+      theSunLightSourceMoonPhase->getLight()->setSpecular(d2);
+      theSunLightSourceMoonPhase->getLight()->setAmbient(a2);
+      theSunLightSourceMoonPhase->getLight()->setPosition(osg::Vec4d(position, 0.0));
+      theSunLightSourceMoonPhase->getLight()->setDirection(direction);
+   }
+   void updateMoonLight()
+   {
+      if(theMembers&ossimPlanetEphemeris::MOON_LIGHT)
+      {
+         osg::Vec3d position = theSunXyz;
+         osg::Vec3d direction = -theSunXyz;
+         direction.normalize();
+         osg::Vec3d sunxyz=theSunXyz, moonxyz = theMoonXyz;
+         sunxyz.normalize();
+         moonxyz.normalize();
+         // Part of the calculations are used from osgEpehermis code
+         //
+         const double angle = (sunxyz*moonxyz);
+         const double moonBrightness = ((angle) * -0.5 + 0.5);
+         const double moonlight = moonBrightness*.5;
+         // Make the final values a little bit blue, and always add in a tiny bit of ambient starlight
+         osg::Vec4 ambient(moonlight * 0.32 + 0.05, moonlight * 0.32 + 0.05, moonlight * 0.4 + 0.05, 1);
+         osg::Vec4 diffuse(moonlight * 0.8, moonlight * 0.8, moonlight, 1);
+         osg::Light &light = *(theMoonLightSource->getLight());
+         light.setAmbient( ambient );
+         light.setDiffuse( diffuse );
+         light.setSpecular( diffuse );
+         
+         theMoonLightSource->getLight()->setPosition( osg::Vec4d(theMoonXyz,0.0) );
+         theMoonLightSource->getLight()->setDirection(-moonxyz);
+         if(theMoonLightCallback.valid())
+         {
+             (*theMoonLightCallback)(theLayer,
+                                     theMoonLightSource.get());
+         }
+      }
+   }
+   void updateEnvColors()
+   {
+      float skyBright = theSkyLightTable->Interpolate(theSunElevation);
+      theModSkyColor = theSkyColor * skyBright;
+      
+      // Modify the fog color based on sky brightness
+      theModFogColor = theFogColor * skyBright;
+   }
+   void updateFogColor()
+   {
+      // Calculate the fog color in the direction of the sun for
+      // sunrise/sunset effects.
+      float red   = (theModFogColor[0] + 2.f * theSunColor[0] * theSunColor[0]) / 3.f;
+      float green = (theModFogColor[1] + 2.f * theSunColor[1] * theSunColor[1]) / 3.f;
+      float blue  = (theModFogColor[2] + 2.f * theSunColor[2]) / 3.f;
+      
+      // interpolate between the sunrise/sunset color and the color
+      // at the opposite direction of this effect. Take in account
+      // the current visibility.
+      double vis = getVisibility();
+      const float MAX_VISIBILITY = 20000;
+      
+      // Clamp visibility
+      if (vis > MAX_VISIBILITY)
+      {
+         vis = MAX_VISIBILITY;
+      }
+      
+      double sunRotation = osg::DegreesToRadians(-95.0);
+      double heading     = osg::DegreesToRadians(-95.0);
+      
+      double rotation = -(sunRotation + osg::PI) - heading;
+      
+      float inverseVis = 1.f - (MAX_VISIBILITY - vis) / MAX_VISIBILITY;
+      float sif = 0.5f - cos(osg::DegreesToRadians(theSunElevation) * 2.f) / 2.f + 0.000001f;
+      
+      float rf1  = std::abs((rotation-osg::PI) / osg::PI); // difference between eyepoint heading and sun heading (rad)
+      float rf2 = inverseVis * pow(rf1 * rf1, 1.0f / sif);
+      
+      float rf3  = 1.f - rf2;
+      
+      theModFogColor[0] = rf3 * theModFogColor[0] + rf2 * red;
+      theModFogColor[1] = rf3 * theModFogColor[1] + rf2 * green;
+      theModFogColor[2] = rf3 * theModFogColor[2] + rf2 * blue;
+      
+      // now apply the fog's color
+      theFog->setColor(osg::Vec4(theModFogColor[0], theModFogColor[1], theModFogColor[2], 1.f));
+   }
+   bool getFogEnableFlag()const
+   {
+      return theFogEnableFlag;
+   }
+   void setFogEnableFlag(bool enable)
+   {
+      theFogEnableFlag = enable;
+      if(theRootStateSet.valid())
+      {
+         short attr = osg::StateAttribute::ON;
+         
+         if (enable)
+         {
+            attr = osg::StateAttribute::ON;
+         }
+         else
+         {
+            attr = osg::StateAttribute::OFF;
+         }
+         
+         theRootStateSet->setAttributeAndModes(theFog.get(), attr);
+#if 0
+         if (GetFogMode() == Environment::ADV)
+         {
+            // if we're using ADV, then we turn on/off this shader which overrides
+            // the standard openGL fog
+            state->setAttributeAndModes(mSunlightShader->GetLightScatterinVP(), attr);
+            state->setAttributeAndModes(mSunlightShader->GetTerrainFP(), attr);
+            
+            // if we're using a skyDome, turn on/off its shader
+            if (mSkyDome.valid())
+            {
+               state = mSkyDome.get()->GetOSGNode()->getOrCreateStateSet();
+               state->setAttributeAndModes(mSkyDomeShader->GetLightScatterinVP(), attr);
+               state->setAttributeAndModes(mSkyDomeShader->GetDomeFP(), attr);
+            }
+         }
+#endif
+      }
+   }
+   osg::Texture2D* createBillboardTexture(osg::Image* image)
+   {
+      osg::Texture2D* texture = 0;
+      if ( image )
+      {
+         texture = new osg::Texture2D( image );
+         texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
+         texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
+         texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+         texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+      }
+      
+      return texture;
+   }
+   ossimPlanetBillboardIcon* createPlanetBillBoard(double diameter,
+                                                   const string& name,
+                                                   const string& imageFile)
+   {
+      ossimPlanetBillboardIcon* result = new ossimPlanetBillboardIcon();
+      result->setName(name);
+      result->setGroundObjectSize(diameter);
+      if(!imageFile.empty())
+      {
+         osg::Image* image = osgDB::readImageFile( imageFile );
+         if ( image )
+         {
+            result->setIcon(createBillboardTexture(image));
+         }
+      }
+      
+      return result;
+   }
+   void setNumberOfCloudLayers(ossim_uint32 numberOfLayers)
+   {
+      ossim_uint32 idx = 0;
+      if(theCloudLayers.size() == numberOfLayers) return; // nothing to do
+      if(numberOfLayers == 0)
+      {
+         theCloudLayers.clear();
+         return;
+      }
+      theCloudLayers.resize(numberOfLayers);
+      for(idx = 0; idx < numberOfLayers;++idx)
+      {
+         if(!theCloudLayers[idx].valid())
+         {
+            theCloudLayers[idx] = new ossimPlanetCloudLayer();
+            theCloudLayers[idx]->setModel(theLayer->theModel.get());
+            theCloudLayers[idx]->setCullingActive(false);
+         }
+      }
+   }
+   void removeClouds(ossim_uint32 idx, ossim_uint32 count)
+   {
+      if((idx < theCloudLayers.size())&&
+         (count != 0))
+      {
+         ossim_uint32 maxIdx = ossim::min(idx+count, (ossim_uint32)theCloudLayers.size());;
+         CloudLayers::iterator start = theCloudLayers.begin()+idx;
+         CloudLayers::iterator end   = theCloudLayers.begin()+maxIdx;
+         theCloudLayers.erase(start, end);
+      }
+   }
+                              
+   ossimPlanetCloudLayer* cloudLayer(ossim_uint32 idx)
+   {
+      if(idx < theCloudLayers.size())
+      {
+         return theCloudLayers[idx].get();
+      }
+      return 0;
+   }
+  public:
+   class InterpTable : public osg::Referenced
+      {
+      public:
+         InterpTable()
+         {
+            
+         }
+         ~InterpTable()
+         {
+            
+         }
+         void addEntry(double ind, double dep)
+         {
+            theTable.insert(std::make_pair(ind, dep));
+         }
+         double Interpolate(double x) const
+         {
+            double result = 0.0;
+            if(theTable.size() == 0) return result;
+            IntensityTableType::const_iterator upper = theTable.lower_bound(x);
+            IntensityTableType::const_iterator lower = upper;
+            if(upper != theTable.end())
+            {
+               if(upper != theTable.begin())
+               {
+                  --lower;
+               }
+            }
+            if(upper!=theTable.end())
+            {
+               double t = 0.0;
+               if(lower!=upper)
+               {
+                  t = (x-lower->first)/(upper->first-lower->first);
+                  result = lower->second + (upper->second-lower->second)*t;
+               }
+               else
+               {
+                  result = lower->second;
+               }
+            }
+            else if(upper==theTable.end())
+            {
+               if(lower!=theTable.end())
+               {
+                  result = lower->second;
+               }
+            }
+            return result;
+         }
+       const ossimPlanetEphemeris::IntensityTableType& table()const
+         {
+            return theTable;
+         }
+         void setTable(const ossimPlanetEphemeris::IntensityTableType& value)
+         {
+            theTable = value;
+         }
+      protected:
+         ossimPlanetEphemeris::IntensityTableType theTable;
+      };
+   
+   osg::ref_ptr<InterpTable> theSkyLightTable;
+
+   ossimPlanetEphemeris* theLayer;
+   ossim_uint64          theMembers;
+   ossimLocalTm          theDate;
+   gpstk::SunPosition    theSunPosition;
+   gpstk::MoonPosition   theMoonPosition;
+   osg::Vec3d            theSunLlh;
+   osg::Vec3d            theMoonLlh;
+   osg::Vec3d            theSunXyz;
+   osg::Vec3d            theMoonXyz;
+   
+   gpstk::WGS84Ellipsoid theEllipsoidModel;
+   //gpstk::WGS84Geoid     theGeoidModel;
+   ossim_uint32          theSunLightIdx;
+   ossim_uint32          theMoonLightIdx;
+   ossim_uint32          theAmbientLightIdx;
+   osg::Vec3d            theEyeLlh;
+   osg::Vec3d            theEyeXyz;
+   osg::ref_ptr<osg::LightSource> theSunLightSource;
+   osg::ref_ptr<osg::LightSource> theSunLightSourceMoonPhase;
+   osg::ref_ptr<osg::LightSource> theMoonLightSource;
+   osg::ref_ptr<osg::LightSource> theAmbientLightSource;
+   
+   osg::ref_ptr<osg::Group> theLightGroup;
+   osg::ref_ptr<osg::MatrixTransform> theObjectGroup;
+   osg::ref_ptr<osg::Group> theMoonGroup;
+   osg::ref_ptr<osg::Group> theSunGroup;
+   
+   osg::ref_ptr<osg::MatrixTransform> theSkyDomeTransform;
+   osg::ref_ptr<SkyDome>            theSkyDome;
+
+   /**
+    * This is the root stateset used for light source definitions
+    */
+   osg::observer_ptr<osg::StateSet> theRootStateSet;
+   osg::observer_ptr<osg::Group>    theRootStateSetGroup;
+   
+   bool theAutoUpdateCurrenTimeFlag;
+   bool theApplySimulationTimeOffsetFlag;
+   bool theSettingsChangedFlag;
+   
+   ossim_float64 theSunElevation;
+   ossim_float64 theSunAzimuth;
+   osg::Vec3d theGlobalAmbientColor;
+   osg::Vec3d theSunColor;
+   osg::ref_ptr<ossimPlanetEphemeris::LightingCallback> theSunLightCallback;
+   osg::ref_ptr<ossimPlanetEphemeris::LightingCallback> theMoonLightCallback;
+   osg::ref_ptr<ossimPlanetEphemeris::LightingCallback> theGlobalAmbientLightCallback;
+   osg::Vec3d theSkyColor;
+   osg::Vec3d theFogColor;
+   osg::Vec3d theModSkyColor;
+   osg::Vec3d theModFogColor;
+   
+   ossim_float64 theVisibility;
+   osg::ref_ptr<osg::Fog> theFog;
+   ossim_float64 theFogNear;
+   ossimPlanetEphemeris::FogMode theFogMode;
+   bool theFogEnableFlag;
+   
+   osg::ref_ptr<ossimPlanetPointModel>    theSunPointModel;
+   osg::ref_ptr<ossimPlanetBillboardIcon> theSunBillboard;
+   osg::ref_ptr<ossimPlanetPointModel>    theMoonPointModel;
+   
+   osg::ref_ptr<osg::PositionAttitudeTransform> theMoonModel;
+   osg::ref_ptr<osg::PositionAttitudeTransform> theSunModel;
+   osg::ref_ptr<osg::Camera> theSkyDomeCamera;
+   
+   ossim_float64 theMaximumAltitudeToShowDome;
+   ossim_float64 theMaximumAltitudeToShowFog;
+   ossim_float64 theMaxAltitudeToDoSunriseSunsetColorAdjustment;
+   bool          theUseFadingFlagForSunriseSunsetCalculation;
+   ossim_int64 theFrameStamp;
+
+   CloudLayers theCloudLayers;
+};
+ossimPlanetEphemeris::EphemerisData::EphemerisData(ossimPlanetEphemeris* layer,
+                                                   ossim_uint64 membersBitMap)
+:theLayer(layer),
+theSunLightIdx(0),
+theMoonLightIdx(1),
+theAmbientLightIdx(2),
+theAutoUpdateCurrenTimeFlag(false),
+theApplySimulationTimeOffsetFlag(false),
+theSettingsChangedFlag(false),
+theMaximumAltitudeToShowDome(40000),
+theMaximumAltitudeToShowFog(20000),
+theMaxAltitudeToDoSunriseSunsetColorAdjustment(20000),
+theUseFadingFlagForSunriseSunsetCalculation(true),
+theFrameStamp(-1)
+{
+   theFogNear = 1.0;
+   theRootStateSet = 0;
+   theRootStateSetGroup = 0;
+   theGlobalAmbientColor = osg::Vec3d(0.2,0.2,0.2);
+   theSkyLightTable = new InterpTable();
+   theObjectGroup = new osg::MatrixTransform;
+   theLightGroup  = new osg::Group;
+   theMoonGroup   = new osg::Group;
+   theSunGroup    = new osg::Group;
+   theMoonLightSource = new osg::LightSource;
+   theSunLightSource  = new osg::LightSource;
+   theSunLightSourceMoonPhase = new osg::LightSource;
+   theAmbientLightSource = new osg::LightSource;
+   theLightGroup->addChild(theSunLightSource.get());
+   theLightGroup->addChild(theMoonLightSource.get());
+   theLightGroup->addChild(theAmbientLightSource.get());
+   theLightGroup->setCullingActive(false);
+   theSunLightSource->getLight()->setLightNum(theSunLightIdx);
+   theSunLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+   theSunLightSourceMoonPhase->getLight()->setLightNum(theSunLightIdx);
+   theSunLightSourceMoonPhase->setLocalStateSetModes(osg::StateAttribute::OFF); 
+   theMoonLightSource->getLight()->setLightNum(theMoonLightIdx);
+   theMoonLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+   theAmbientLightSource->getLight()->setLightNum(theAmbientLightIdx);
+   theAmbientLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+
+   theAmbientLightSource->getLight()->setDiffuse(osg::Vec4d(0.0,0.0,0.0,1.0));
+   theAmbientLightSource->getLight()->setSpecular(osg::Vec4d(0.0,0.0,0.0,1.0));
+   theAmbientLightSource->getLight()->setAmbient(osg::Vec4d(theGlobalAmbientColor[0],
+                                                            theGlobalAmbientColor[1],
+                                                            theGlobalAmbientColor[2], 1.0));
+   theSunPointModel = new ossimPlanetPointModel;
+   theMoonPointModel = new ossimPlanetPointModel;
+   theMoonModel = new osg::PositionAttitudeTransform;
+   theSunModel = new osg::PositionAttitudeTransform;
+   
+   osg::Geode* geode = new osg::Geode();
+   
+   osg::TessellationHints* hints = new osg::TessellationHints;
+   hints->setDetailRatio(2.0);
+   
+   geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3d(0.0f,0.0f,0.0f), 1.0), hints));
+   
+   geode->setCullingActive(false);
+
+   theMoonModel->addChild(geode);
+   theMoonModel->setScale(osg::Vec3d(1.0, 1.0, 1.0));
+   theMoonModel->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);
+   theMoonModel->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
+  
+   theSunModel->addChild(geode);
+   theSunModel->setScale(osg::Vec3d(1.0, 1.0, 1.0));
+   theSunModel->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+   theSunModel->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
+
+   theSkyDome = new SkyDome("SkyDome", false, .4);//osg::WGS_84_RADIUS_EQUATOR);
+   theSkyDome->setMaxAltitude(theMaximumAltitudeToShowDome);
+   theSkyDomeTransform = new osg::MatrixTransform;
+   theSkyDomeTransform->addChild(theSkyDome->GetOSGNode());
+   theSkyDomeTransform->setCullingActive(false);
+   setMembers(membersBitMap);
+   theSkyLightTable->addEntry(-90.0, 0.080);
+   theSkyLightTable->addEntry(-50.0, 0.080);
+   theSkyLightTable->addEntry(-40.0, 0.090);
+   theSkyLightTable->addEntry(-25.0, 0.090);
+   theSkyLightTable->addEntry(-20.0, 0.110);
+   theSkyLightTable->addEntry(-15.0, 0.120);
+   theSkyLightTable->addEntry(-10.0, 0.200);
+   theSkyLightTable->addEntry(-5.0, 0.350);
+   theSkyLightTable->addEntry(0.0, 0.616);
+   theSkyLightTable->addEntry(5.0, 0.806);
+   theSkyLightTable->addEntry(10.0, 0.895);
+   theSkyLightTable->addEntry(20.0, 0.962);
+   theSkyLightTable->addEntry(30.0, 0.989);
+   theSkyLightTable->addEntry(40.0, 0.997);
+   theSkyLightTable->addEntry(50.0, 1.0);
+   theSkyLightTable->addEntry(90.0, 1.0);
+   
+   theSkyColor.set(0.39f, 0.50f, 0.74f);
+   theFogColor.set(0.84f, 0.87f, 1.f);
+
+   theSunColor.set(1.f, 1.f, 1.f);
+   theModFogColor.set(theFogColor);
+   theModSkyColor.set(theSkyColor);
+   theVisibility = 20000;
+   theFog = new osg::Fog();
+   theFog->setDensity(0.0);
+   theMoonGroup->addChild(theSunLightSourceMoonPhase.get());
+   theObjectGroup->setUpdateCallback(new ossimPlanetTraverseCallback());
+   theObjectGroup->setCullCallback(new ossimPlanetTraverseCallback());
+   theObjectGroup->addChild(theSkyDomeTransform.get());
+
+   theObjectGroup->addChild(theMoonGroup.get());
+   theObjectGroup->addChild(theSunGroup.get());
+
+   setFogMode(ossimPlanetEphemeris::LINEAR);   
+   
+}
+
+void ossimPlanetEphemeris::EphemerisData::setMembers(ossim_uint64 membersBitMap)
+{
+   theMembers = membersBitMap;
+   if(theMembers&ossimPlanetEphemeris::SUN_LIGHT)
+   {
+      theSunLightSource->setLocalStateSetModes(osg::StateAttribute::ON); 
+      theSunLightSource->getLight()->setLightNum(theSunLightIdx);
+      theSunLightSource->setNodeMask(0xffffffff);
+
+      theSunLightSourceMoonPhase->setLocalStateSetModes(osg::StateAttribute::ON); 
+      theSunLightSourceMoonPhase->getLight()->setLightNum(theSunLightIdx);
+      theSunLightSourceMoonPhase->setNodeMask(0xffffffff);
+   }
+   else
+   {
+      theSunLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+      theSunLightSource->setNodeMask(0x0);
+      theSunLightSourceMoonPhase->setLocalStateSetModes(osg::StateAttribute::OFF); 
+      theSunLightSourceMoonPhase->setNodeMask(0x0);
+   }
+   if(theMembers&ossimPlanetEphemeris::MOON_LIGHT)
+   {
+      theMoonLightSource->getLight()->setLightNum(theMoonLightIdx);
+      theMoonLightSource->setLocalStateSetModes(osg::StateAttribute::ON); 
+      theMoonLightSource->setNodeMask(0xffffffff);
+   }
+   else
+   {
+      theMoonLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+      theMoonLightSource->setNodeMask(0x0);
+   }
+   if(theMembers&ossimPlanetEphemeris::SKY)
+   {
+      theSkyDome->GetOSGNode()->setNodeMask(0xffffffff);
+   }
+   else
+   {
+      theSkyDome->GetOSGNode()->setNodeMask(0x0);
+   }
+   
+
+   if(theMembers&ossimPlanetEphemeris::AMBIENT_LIGHT)
+   {
+      theAmbientLightSource->getLight()->setLightNum(theAmbientLightIdx);
+      theAmbientLightSource->setLocalStateSetModes(osg::StateAttribute::ON); 
+      theAmbientLightSource->setNodeMask(0xffffffff);
+   }
+   else
+   {
+      theAmbientLightSource->setLocalStateSetModes(osg::StateAttribute::OFF); 
+      theAmbientLightSource->setNodeMask(0x0);
+   }
+
+   theMoonGroup->removeChild(theMoonModel.get());
+   
+   if(theMembers&ossimPlanetEphemeris::MOON)
+   {
+      theMoonGroup->addChild(theMoonModel.get());
+   }
+
+   theSunGroup->removeChild(theSunModel.get());
+   if(theMembers&ossimPlanetEphemeris::SUN)
+   {
+     theSunGroup->addChild(theSunModel.get());
+   }
+
+   if(theMembers&ossimPlanetEphemeris::FOG)
+   {
+      setFogEnableFlag(true);
+   }
+   else
+   {
+      setFogEnableFlag(false);
+   }
+   if(theRootStateSet.valid())
+   {
+      if(theMembers&ossimPlanetEphemeris::MOON_LIGHT)
+      {
+         theMoonLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::ON);
+      }
+      else
+      {
+         theMoonLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::OFF);
+      }
+      if(theMembers&ossimPlanetEphemeris::SUN_LIGHT)
+      {
+         theSunLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::ON);
+         theSunLightSourceMoonPhase->setStateSetModes(*theRootStateSet,osg::StateAttribute::ON);
+      }
+      else
+      {
+         theSunLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::OFF);
+         theSunLightSourceMoonPhase->setStateSetModes(*theRootStateSet,osg::StateAttribute::OFF);
+      }
+
+      if(theMembers&ossimPlanetEphemeris::AMBIENT_LIGHT)
+      {
+         theAmbientLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::ON);
+      }
+      else
+      {
+         theAmbientLightSource->setStateSetModes(*theRootStateSet,osg::StateAttribute::OFF);
+      }
+   }
+   
+   theLayer->setRedrawFlag(true);
+}
+
+void ossimPlanetEphemeris::EphemerisData::traverse(osg::NodeVisitor& nv)
+{
+   if(dynamic_cast<osgUtil::IntersectVisitor*> (&nv) ||
+      dynamic_cast<osgUtil::IntersectionVisitor*> (&nv))
+   {
+      return;
+   }
+  switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         break;
+      }
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+      
+         bool updatePositionFlag = true;
+         
+         if(nv.getFrameStamp())
+         {
+            if(theFrameStamp == nv.getFrameStamp()->getFrameNumber())
+            {
+               updatePositionFlag = false;
+            }
+            theFrameStamp = nv.getFrameStamp()->getFrameNumber();
+         }
+         updatePositions(nv);
+         break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         static bool slaveAdded = false;
+         osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+         if(ev)
+         {
+            ossimPlanetViewer* viewer = dynamic_cast<ossimPlanetViewer*>(ev->getActionAdapter());
+            if(viewer&&viewer->currentCamera())
+            {
+               theEyeLlh[0] = viewer->currentCamera()->lat(); 
+               theEyeLlh[1] = viewer->currentCamera()->lon(); 
+               theEyeLlh[2] = viewer->currentCamera()->altitude();
+            }
+            if(theSkyDomeCamera.valid())
+            {
+               theSkyDomeCamera->setNearFarRatio(.0001);
+            }
+#if 1
+            if(theEyeLlh[2] > theMaximumAltitudeToShowFog)
+            {
+               if(theRootStateSet.valid()&&getFogEnableFlag())
+               {
+                  if(theRootStateSet->getMode(GL_FOG) == osg::StateAttribute::ON)
+                  {
+                     theRootStateSet->setAttributeAndModes(theFog.get(), osg::StateAttribute::OFF);
+                  }
+               }
+            }
+            else
+            {
+               if(theRootStateSet.valid()&&getFogEnableFlag())
+               {
+                  if(theRootStateSet->getMode(GL_FOG) == osg::StateAttribute::OFF)
+                  {
+                     theRootStateSet->setAttributeAndModes(theFog.get(), osg::StateAttribute::ON);
+                  }
+               }
+            }
+#endif
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   if(!theSkyDomeCamera.valid())
+   {
+      theObjectGroup->accept(nv);
+   }
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theCloudLayers.size();++idx)
+   {
+      if(theCloudLayers[idx].valid())
+      {
+         theCloudLayers[idx]->accept(nv);
+      }
+   }
+   return;
+}
+
+void ossimPlanetEphemeris::EphemerisData::updatePositions(osg::NodeVisitor& nv)
+{
+   if(!theLayer||!theLayer->model()) return;
+   
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = theLayer->model();
+ 
+   if(theAutoUpdateCurrenTimeFlag)
+   {
+      theDate.now();
+      theLayer->setRedrawFlag(true);
+   }
+   ossimLocalTm adjustedDate(theDate);
+   if(theApplySimulationTimeOffsetFlag&&nv.getFrameStamp())
+   {
+      double time = nv.getFrameStamp()->getSimulationTime();
+      adjustedDate.addSeconds(time);
+      theLayer->setRedrawFlag(true);
+   }
+ //gpstk::SystemTime now;
+ //ossimLocalTm gmt = adjustedDate;//.convertToGmt();
+ gpstk::UnixTime now(adjustedDate);
+ now.setTimeSystem(gpstk::TimeSystem::UTC);
+   //gpstk::DayTime now(gmt.getYear(),
+   //                   gmt.getMonth(),
+   //                   gmt.getDay(),
+   //                   gmt.getHour(),
+   //                   gmt.getMin(),
+   //                   gmt.getSec(),
+   //                   gpstk::DayTime::UTC);
+   gpstk::Position sunEcef;
+   sunEcef = theSunPosition.getPosition(now);
+
+//std::cout << "x: " << theEyeLlh[0] << std::endl;
+   gpstk::Position eyeLocation(theEyeLlh[0],
+                               theEyeLlh[1],
+                               theEyeLlh[2],
+                               gpstk::Position::Geodetic,
+                               &theEllipsoidModel,
+                               gpstk::ReferenceFrame::WGS84);
+
+   gpstk::Position sunLlh = gpstk::Position(sunEcef,
+                                            gpstk::Position::Cartesian,
+                                            &theEllipsoidModel).asGeodetic(&theEllipsoidModel);
+   
+   //gpstk::Position sunPosition(sunLlh.getLatitude(),
+   //                            sunLlh.getLongitude(),
+   //                            sunLlh.getAltitude(),
+   //                            gpstk::Position::Geodetic,
+   //                            &theEllipsoidModel);
+
+   theSunAzimuth   = eyeLocation.azimuth(sunLlh);
+   theSunElevation = eyeLocation.elevation(sunLlh);
+
+   //std::cout << "Eye Position:  " << eyeLocation << std::endl;
+   //std::cout << "Position:      " << sunLlh << std::endl;
+   //std::cout << "Azimuth:       " << theSunAzimuth << std::endl;
+   //std::cout << "Elevation:     " << theSunElevation << std::endl;
+
+   theSunLlh = osg::Vec3d(sunLlh.getGeodeticLatitude(),
+                          sunLlh.getLongitude(),
+                          sunLlh.getAltitude());
+
+   gpstk::Position moonEcef;
+   moonEcef = theMoonPosition.getPosition(now);
+   gpstk::Position moonLlh = moonEcef.asGeodetic(&theEllipsoidModel);
+   
+   theMoonLlh = osg::Vec3d(moonLlh.getGeodeticLatitude(),
+                           moonLlh.getLongitude(),
+                           moonLlh.getAltitude());
+   
+   model->latLonHeightToXyz(theMoonLlh,
+                            theMoonXyz);
+   
+   osg::Matrixd m;
+   osg::Vec3d shiftedEye(theEyeLlh[0], theEyeLlh[1], 0.0);//theEyeLlh[2]);
+   theLayer->model()->lsrMatrix(shiftedEye, m, theSunAzimuth-90.0);
+   theLayer->model()->latLonHeightToXyz(theSunLlh, 
+                                        theSunXyz);
+
+   theSkyDomeTransform->setMatrix(m);//*osg::Matrixd::Scale(.5,.5,.5));
+   osg::Vec3d eyexyzNorm;
+   theLayer->model()->latLonHeightToXyz(theEyeLlh, theEyeXyz);
+   eyexyzNorm = theEyeXyz;
+   eyexyzNorm.normalize();
+
+   theAmbientLightSource->getLight()->setDirection(-eyexyzNorm);
+   theAmbientLightSource->getLight()->setPosition(osg::Vec4d(theEyeXyz[0],
+                                                             theEyeXyz[1],
+                                                             theEyeXyz[2],
+                                                              0.0));
+
+   theSunModel->setPosition(theSunXyz);
+   theMoonModel->setPosition(theMoonXyz);
+#if 0
+      osg::Vec3d adjMoonXyz = theMoonXyz - theEyeXyz;
+      adjMoonXyz.normalize();
+      osg::Vec3d newMoonPos = theEyeXyz + adjMoonXyz*2;
+      osg::Vec3d newMoonLlh;
+      theLayer->theModel->xyzToLatLonHeight(newMoonPos, newMoonLlh);
+
+#endif
+   
+   updateSunLight();
+   updateMoonLight();
+   updateEnvColors();
+   updateFogColor();
+
+   ossim_float64 vis = theVisibility;
+   osg::Vec3 fogColor = theModFogColor;
+   osg::Vec3 skyColor = theModSkyColor;
+   if (!getFogEnableFlag()) 
+   { 
+      vis = 200000.f; 
+      fogColor = theModSkyColor;
+   }
+   fade_to_black(&fogColor, theEyeLlh[2], theMaximumAltitudeToShowFog, 1);
+   fade_to_black(&skyColor, theEyeLlh[2], theMaximumAltitudeToShowDome, 1);
+   // if fog is enabled, use the modified fog color otherwise just use
+   // the modified sky color
+   theSkyDome->Repaint(skyColor,
+                       fogColor,
+                       theSunElevation, 
+                       theSunAzimuth, 
+                       vis,
+                       theEyeLlh[2]);
+}
+
+ossimPlanetEphemeris::ossimPlanetEphemeris(ossim_uint64 membersBitMap)
+:theEphemerisData(new EphemerisData(this, membersBitMap))
+{
+   
+}
+
+ossimPlanetEphemeris::~ossimPlanetEphemeris()
+{
+   if(theEphemerisData)
+   {
+      delete theEphemerisData;
+      theEphemerisData = 0;
+   }
+}
+
+void ossimPlanetEphemeris::setMembers(ossim_uint64 membersBitMap)
+{
+   if(theEphemerisData)
+   {
+      theEphemerisData->setMembers(membersBitMap);
+   }
+}
+
+ossim_uint64 ossimPlanetEphemeris::members()const
+{
+   return theEphemerisData->members();
+}
+
+void ossimPlanetEphemeris::setRoot(osg::Group* group)
+{
+   if(theEphemerisData->theRootStateSetGroup.valid())
+   {
+      theEphemerisData->theRootStateSetGroup->removeChild(theEphemerisData->theLightGroup.get());
+   }
+   theEphemerisData->theRootStateSetGroup = group;
+   if(group)
+   {
+      theEphemerisData->theRootStateSet = group->getOrCreateStateSet();
+      group->addChild(theEphemerisData->theLightGroup.get());
+   }
+}
+
+void ossimPlanetEphemeris::setMoonLightCallback(LightingCallback* callback)
+{
+   theEphemerisData->theMoonLightCallback = callback;
+}
+
+void ossimPlanetEphemeris::setMoonCullCallback(osg::NodeCallback* callback)
+{
+   theEphemerisData->theMoonGroup->setCullCallback(callback);
+}
+
+void ossimPlanetEphemeris::setMoonLightIndex(ossim_uint32 idxNumber)
+{
+   theEphemerisData->setMoonLightIndex(idxNumber);
+}
+
+ossim_uint32 ossimPlanetEphemeris::moonLightIndex()const
+{
+   return theEphemerisData->moonLightIndex();
+}
+
+osg::Vec3d ossimPlanetEphemeris::moonPositionXyz()const
+{
+   return theEphemerisData->theMoonXyz;
+}
+
+osg::Vec3d ossimPlanetEphemeris::moonPositionLatLonHeight()const
+{
+   return theEphemerisData->theMoonLlh;
+}
+
+void ossimPlanetEphemeris::setSunLightIndex(ossim_uint32 idxNumber)
+{
+   theEphemerisData->setSunLightIndex(idxNumber);
+}
+
+ossim_uint32 ossimPlanetEphemeris::sunLightIndex()const
+{
+   return theEphemerisData->sunLightIndex();
+}
+void ossimPlanetEphemeris::setSunLightCallback(LightingCallback* callback)
+{
+   theEphemerisData->theSunLightCallback = callback;
+}
+
+void ossimPlanetEphemeris::setSunCullCallback(osg::NodeCallback* callback)
+{
+   theEphemerisData->theSunGroup->setCullCallback(callback);
+}
+
+osg::Vec3d ossimPlanetEphemeris::sunPositionXyz()const
+{
+   return theEphemerisData->theSunXyz;
+}
+
+osg::Vec3d ossimPlanetEphemeris::sunPositionLatLonHeight()const
+{
+   return theEphemerisData->theSunLlh;
+}
+
+void ossimPlanetEphemeris::setDate(const ossimLocalTm& date)
+{
+   theEphemerisData->setDate(date);
+   theEphemerisData->setAutoUpdateToCurrentTimeFlag(false);
+}
+
+void ossimPlanetEphemeris::setAutoUpdateToCurrentTimeFlag(bool flag)
+{
+   theEphemerisData->setAutoUpdateToCurrentTimeFlag(flag);
+}
+
+void ossimPlanetEphemeris::setApplySimulationTimeOffsetFlag(bool flag)
+{
+   theEphemerisData->setApplySimulationTimeOffsetFlag(flag);
+   theEphemerisData->setAutoUpdateToCurrentTimeFlag(false);
+}
+
+
+void ossimPlanetEphemeris::traverse(osg::NodeVisitor& nv)
+{
+   if(!theEnableFlag) return;
+   
+   theEphemerisData->traverse(nv);
+   
+   ossimPlanetLayer::traverse(nv);
+}
+
+osg::Vec3d ossimPlanetEphemeris::eyePositionXyz()const
+{
+   return theEphemerisData->theEyeXyz;
+}
+
+osg::Vec3d ossimPlanetEphemeris::eyePositionLatLonHeight()const
+{
+   return theEphemerisData->theEyeLlh;
+}
+
+void ossimPlanetEphemeris::setCamera(osg::Camera* camera)
+{
+   if(theEphemerisData->theSkyDomeCamera.get() == camera) return;
+   
+   if(theEphemerisData->theSkyDomeCamera.valid())
+   {
+      theEphemerisData->theSkyDomeCamera->removeChild(theEphemerisData->theObjectGroup.get());
+   }
+   theEphemerisData->theSkyDomeCamera = camera;
+   if(camera)
+   {
+      theEphemerisData->theSkyDomeCamera->addChild(theEphemerisData->theObjectGroup.get());
+   }
+}
+
+void ossimPlanetEphemeris::setVisibility(ossim_float64 visibility)
+{
+   theEphemerisData->setVisibility(visibility);
+}
+
+
+ossim_float64 ossimPlanetEphemeris::visibility()const
+{
+   return theEphemerisData->theVisibility;
+}
+
+osg::BoundingSphere ossimPlanetEphemeris::computeBound() const
+{
+   if(getNumChildren() == 0)
+   {
+      return osg::BoundingSphere(osg::Vec3(0.0,0.0,0.0),
+                                 1.0);
+   }
+   return ossimPlanetLayer::computeBound();
+   
+}
+
+void ossimPlanetEphemeris::setSunTextureFromFile(const ossimFilename& texture)
+{
+   osg::Image* image = osgDB::readImageFile( texture );
+   setSunTextureFromImage(image);
+}
+
+void ossimPlanetEphemeris::setSunTextureFromImage(osg::Image* texture)
+{
+  if ( texture )
+  {
+     osg::Texture2D* tex = new osg::Texture2D();
+     tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
+     tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
+     tex->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+     tex->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+     tex->setWrap(osg::Texture2D::WRAP_R, osg::Texture2D::CLAMP_TO_EDGE);
+
+     tex->setImage(texture);
+     theEphemerisData->theSunModel->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
+  }
+  else
+  {
+     theEphemerisData->theSunModel->getOrCreateStateSet()->setTextureAttributeAndModes(0, 0, osg::StateAttribute::OFF);
+  }
+}
+
+void ossimPlanetEphemeris::setMoonTextureFromFile(const ossimFilename& texture)
+{
+   osg::Image* image = osgDB::readImageFile( texture );
+   setMoonTextureFromImage(image);
+}
+
+void ossimPlanetEphemeris::setMoonScale(const osg::Vec3d& scale)
+{
+   theEphemerisData->theMoonModel->setScale(scale);
+}
+
+void ossimPlanetEphemeris::setSunScale(const osg::Vec3d& scale)
+{
+   theEphemerisData->theSunModel->setScale(scale);
+}
+
+void ossimPlanetEphemeris::setMoonTextureFromImage(osg::Image* texture)
+{
+   if ( texture )
+   {
+      osg::Texture2D* tex = new osg::Texture2D();
+      tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
+      tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST);
+      tex->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+      tex->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+      tex->setWrap(osg::Texture2D::WRAP_R, osg::Texture2D::CLAMP_TO_EDGE);
+
+      tex->setImage(texture);
+      theEphemerisData->theMoonModel->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
+   }
+   else
+   {
+      theEphemerisData->theMoonModel->getOrCreateStateSet()->setTextureAttributeAndModes(0, 0, osg::StateAttribute::OFF);
+   }
+}
+
+
+void ossimPlanetEphemeris::setSunMinMaxPixelSize(ossim_uint32 minPixelSize,
+                                                 ossim_uint32 maxPixelSize)
+{
+   
+   theEphemerisData->theSunBillboard->setMinPixelSize(minPixelSize);
+   theEphemerisData->theSunBillboard->setMaxPixelSize(maxPixelSize);
+}
+
+void ossimPlanetEphemeris::setMaximumAltitudeToShowDomeInMeters(ossim_float64 maxAltitude)
+{
+   theEphemerisData->theMaximumAltitudeToShowDome = maxAltitude;
+}
+
+void ossimPlanetEphemeris::setMaximumAltitudeToShowFogInMeters(ossim_float64 maxAltitude)
+{
+   theEphemerisData->theMaximumAltitudeToShowFog = maxAltitude;
+}
+void ossimPlanetEphemeris::setMaxAltitudeToDoSunriseSunsetColorAdjustment(ossim_float64 maxAltitude,
+                                                                          bool useFading)
+{
+   theEphemerisData->theMaxAltitudeToDoSunriseSunsetColorAdjustment = maxAltitude;
+   theEphemerisData->theUseFadingFlagForSunriseSunsetCalculation = useFading;
+}
+
+ossim_float64  ossimPlanetEphemeris::maxAltitudeToDoSunriseSunsetColorAdjustment()const
+{
+   return theEphemerisData->theMaxAltitudeToDoSunriseSunsetColorAdjustment;
+}
+
+
+void ossimPlanetEphemeris::setGlobalAmbientLight(const osg::Vec3d& ambient)
+{
+   theEphemerisData->theGlobalAmbientColor = ambient;
+   theEphemerisData->theAmbientLightSource->getLight()->setAmbient(osg::Vec4d(theEphemerisData->theGlobalAmbientColor[0],
+                                                            theEphemerisData->theGlobalAmbientColor[1],
+                                                            theEphemerisData->theGlobalAmbientColor[2], 1.0));
+}
+
+void ossimPlanetEphemeris::setGlobalAmbientLightIndex(ossim_uint32 idx)
+{
+   theEphemerisData->theAmbientLightIdx = idx;
+   theEphemerisData->theAmbientLightSource->getLight()->setLightNum(theEphemerisData->theAmbientLightIdx);
+}
+
+ossim_uint32 ossimPlanetEphemeris::globalAmbientLightIndex()const
+{
+   return theEphemerisData->theAmbientLightIdx;
+}
+
+void ossimPlanetEphemeris::setSkyColorAdjustmentTable(IntensityTableType& table)
+{
+   theEphemerisData->theSkyLightTable->setTable(table);
+}
+
+const ossimPlanetEphemeris::IntensityTableType* ossimPlanetEphemeris::skyColorAdjustmentTable()const
+{
+   return &theEphemerisData->theSkyLightTable->table();
+}
+
+void ossimPlanetEphemeris::setBaseSkyColor(const osg::Vec3d& color)
+{
+   theEphemerisData->theSkyColor = color;
+}
+osg::Vec3d ossimPlanetEphemeris::getBaseSkyColor()const
+{
+   return theEphemerisData->theSkyColor;
+}
+
+void ossimPlanetEphemeris::setBaseFogColor(const osg::Vec3d& color)
+{
+   theEphemerisData->theFogColor = color;
+}
+
+osg::Vec3d ossimPlanetEphemeris::getBaseFogColor()const
+{
+   return theEphemerisData->theFogColor;
+}
+
+void ossimPlanetEphemeris::setFogMode(FogMode mode)
+{
+   theEphemerisData->setFogMode(mode);
+}
+
+void ossimPlanetEphemeris::setFogNear(ossim_float64 value)
+{
+   theEphemerisData->setFogNear(value);///osg::WGS_84_RADIUS_EQUATOR);
+}
+void ossimPlanetEphemeris::setFogFar(ossim_float64 value)
+{
+   theEphemerisData->setFogFar(value);///osg::WGS_84_RADIUS_EQUATOR);
+}
+void ossimPlanetEphemeris::setFogDensity(ossim_float64 value)
+{
+   theEphemerisData->setFogDensity(value);
+}
+
+void ossimPlanetEphemeris::setFogEnableFlag(bool flag)
+{
+   theEphemerisData->setFogEnableFlag(flag);
+}
+void ossimPlanetEphemeris::setNumberOfCloudLayers(ossim_uint32 numberOfLayers)
+{
+   theEphemerisData->setNumberOfCloudLayers(numberOfLayers);
+}
+
+void ossimPlanetEphemeris::removeClouds(ossim_uint32 idx, ossim_uint32 count)
+{
+   theEphemerisData->removeClouds(idx, count);
+}
+
+ossimPlanetCloudLayer* ossimPlanetEphemeris::cloudLayer(ossim_uint32 idx)
+{
+   return theEphemerisData->cloudLayer(idx);
+}
+
+ossim_uint32 ossimPlanetEphemeris::numberOfCloudLayers()const
+{
+   return theEphemerisData->theCloudLayers.size();
+}
+
+void ossimPlanetEphemeris::createCloudPatch(ossim_uint32 cloudLayerIndex,
+                                            const osg::Vec3d& theCenterLatLonHeight,
+                                            ossim_float64 numberOfMeshSamples,
+                                            ossim_float64 patchSizeInDegrees,
+                                            ossim_uint64  seed,
+                                            ossim_float64 coverage,
+                                            ossim_float64 sharpness)
+{
+   if(cloudLayerIndex == numberOfCloudLayers())
+   {
+      setNumberOfCloudLayers(cloudLayerIndex+1);
+   }
+   osg::ref_ptr<ossimPlanetCloudLayer> layer = cloudLayer(cloudLayerIndex);
+   if(layer.valid())
+   {
+      layer->setGrid(new ossimPlanetCloudLayer::Patch(patchSizeInDegrees, patchSizeInDegrees));
+      layer->computeMesh(0.0, numberOfMeshSamples, numberOfMeshSamples, 0);
+      layer->updateTexture(seed, coverage, sharpness);
+      layer->moveToLocationLatLonAltitude(theCenterLatLonHeight);
+   }
+}
+
+void ossimPlanetEphemeris::createGlobalCloud(ossim_uint32 cloudLayerIndex,
+                                             ossim_float64 altitude,
+                                             ossim_float64 numberOfMeshSamples,
+                                             ossim_uint64  seed,
+                                             ossim_float64 coverage,
+                                             ossim_float64 sharpness)
+{
+   if(cloudLayerIndex == numberOfCloudLayers())
+   {
+      setNumberOfCloudLayers(cloudLayerIndex+1);
+   }
+   osg::ref_ptr<ossimPlanetCloudLayer> layer = cloudLayer(cloudLayerIndex);
+   if(layer.valid())
+   {
+      layer->computeMesh(altitude, numberOfMeshSamples, numberOfMeshSamples, 0);
+      layer->updateTexture(seed, coverage, sharpness);
+   }
+}
+
+#else
+#include <iostream>
+#include <ossimPlanet/ossimPlanetEphemeris.h>
+static void noossimPlanetEphemerisSupportMessage()
+{
+   static bool messageDisplayed = false;
+   if(!messageDisplayed)
+   {
+      messageDisplayed = true;
+      std::cout << "ossimPlanetEphemeris support disabled, please recompile with OSSIMPLANET_ENABLE_EPHEMERIS defined\n";
+   }
+}
+ossimPlanetEphemeris::ossimPlanetEphemeris(ossim_uint64 )
+:theEphemerisData(0)
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossimPlanetEphemeris::~ossimPlanetEphemeris()
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::traverse(osg::NodeVisitor& nv)
+{
+   noossimPlanetEphemerisSupportMessage();
+   ossimPlanetLayer::traverse(nv);
+}
+
+osg::Vec3d ossimPlanetEphemeris::eyePositionXyz()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+osg::Vec3d ossimPlanetEphemeris::eyePositionLatLonHeight()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+void ossimPlanetEphemeris::setMembers(ossim_uint64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_uint64 ossimPlanetEphemeris::members()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+
+void ossimPlanetEphemeris::setRoot(osg::Group* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+
+void ossimPlanetEphemeris::setMoonLightIndex(ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_uint32 ossimPlanetEphemeris::moonLightIndex()const
+{
+   noossimPlanetEphemerisSupportMessage();
+
+   return 0;
+}
+
+void ossimPlanetEphemeris::setMoonLightCallback(LightingCallback* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+osg::Vec3d ossimPlanetEphemeris::moonPositionXyz()const
+{
+   noossimPlanetEphemerisSupportMessage();
+
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+osg::Vec3d ossimPlanetEphemeris::moonPositionLatLonHeight()const
+{
+   noossimPlanetEphemerisSupportMessage();
+
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+
+void ossimPlanetEphemeris::setSunLightIndex(ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_uint32 ossimPlanetEphemeris::sunLightIndex()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+
+void ossimPlanetEphemeris::setSunLightCallback(LightingCallback* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+osg::Vec3d ossimPlanetEphemeris::sunPositionXyz()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+osg::Vec3d ossimPlanetEphemeris::sunPositionLatLonHeight()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+void ossimPlanetEphemeris::setAutoUpdateSunColorFlag(bool )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setGlobalAmbientLightIndex(ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_uint32 ossimPlanetEphemeris::globalAmbientLightIndex()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+
+void ossimPlanetEphemeris::setGlobalAmbientLight(const osg::Vec3d& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setDate(const ossimLocalTm& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setAutoUpdateToCurrentTimeFlag(bool )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setApplySimulationTimeOffsetFlag(bool )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setCamera(osg::Camera* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setVisibility(ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_float64 ossimPlanetEphemeris::visibility()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0.0;
+}
+
+void ossimPlanetEphemeris::setSunTextureFromFile(const ossimFilename& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::setSunTextureFromImage(osg::Image* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setMoonTextureFromFile(const ossimFilename& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::setMoonTextureFromImage(osg::Image* )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setMoonScale(const osg::Vec3d& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setSunScale(const osg::Vec3d& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setSunMinMaxPixelSize(ossim_uint32 ,
+                           ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+
+void ossimPlanetEphemeris::setMaximumAltitudeToShowDomeInMeters(ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+
+void ossimPlanetEphemeris::setMaximumAltitudeToShowFogInMeters(ossim_float64 /*maxAltitude*/)
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setMaxAltitudeToDoSunriseSunsetColorAdjustment(ossim_float64 /*maxAltitude*/,
+                                                                          bool /*useFading*/)
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+ossim_float64  ossimPlanetEphemeris::maxAltitudeToDoSunriseSunsetColorAdjustment()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0.0;
+}
+
+void ossimPlanetEphemeris::setSkyColorAdjustmentTable(IntensityTableType& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+const ossimPlanetEphemeris::IntensityTableType* ossimPlanetEphemeris::skyColorAdjustmentTable()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+
+void ossimPlanetEphemeris::setBaseSkyColor(const osg::Vec3d& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+osg::Vec3d ossimPlanetEphemeris::getBaseSkyColor()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+
+void ossimPlanetEphemeris::setBaseFogColor(const osg::Vec3d& )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+osg::Vec3d ossimPlanetEphemeris::getBaseFogColor()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return osg::Vec3d(0.0,0.0,0.0);
+}
+
+void ossimPlanetEphemeris::setFogMode(FogMode )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::setFogNear(ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+
+}
+void ossimPlanetEphemeris::setFogFar(ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::setFogDensity(ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::setFogEnableFlag(bool )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::setNumberOfCloudLayers(ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+void ossimPlanetEphemeris::removeClouds(ossim_uint32 , ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+ossimPlanetCloudLayer* ossimPlanetEphemeris::cloudLayer(ossim_uint32 )
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+ossim_uint32 ossimPlanetEphemeris::numberOfCloudLayers()const
+{
+   noossimPlanetEphemerisSupportMessage();
+   return 0;
+}
+
+void ossimPlanetEphemeris::createCloudPatch(ossim_uint32 ,
+                                            const osg::Vec3d& ,
+                                            ossim_float64 ,
+                                            ossim_float64 ,
+                                            ossim_uint64  ,
+                                            ossim_float64 ,
+                                            ossim_float64 )
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+void ossimPlanetEphemeris::createGlobalCloud(ossim_uint32 cloudLayerIndex,
+                                             ossim_float64 altitude,
+                                             ossim_float64 numberOfMeshSamples,
+                                             ossim_uint64  seed,
+                                             ossim_float64 coverage,
+                                             ossim_float64 sharpness)
+{
+   noossimPlanetEphemerisSupportMessage();
+}
+
+osg::BoundingSphere ossimPlanetEphemeris::computeBound() const
+{
+   noossimPlanetEphemerisSupportMessage();
+   if(getNumChildren() == 0)
+   {
+      return osg::BoundingSphere(osg::Vec3(0.0,0.0,0.0),
+                                 1.0);
+   }
+   return ossimPlanetLayer::computeBound();
+}
+
+#endif
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetFadeText.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetFadeText.cpp
new file mode 100644
index 0000000..d57eaba
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetFadeText.cpp
@@ -0,0 +1,471 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <iostream>
+#include <ossimPlanet/ossimPlanetFadeText.h>
+#include <osg/Notify>
+#include <osg/io_utils>
+#include <OpenThreads/Mutex>
+#include <OpenThreads/ScopedLock>
+#include <osgUtil/CullVisitor>
+#include <ossim/base/ossimCommon.h>
+
+// using namespace osgText;
+
+// struct ossimPlanetFadeTextData : public osg::Referenced
+// {
+//     ossimPlanetFadeTextData(ossimPlanetFadeText* fadeText=0):
+//         _fadeText(fadeText),
+//         _visible(true) {}
+        
+//     bool operator < (const ossimPlanetFadeTextData& rhs) const
+//     {
+//         return _fadeText < rhs._fadeText;
+//     }    
+    
+//     double getNearestZ() const
+//     {
+//         double nearestZ = _vertices[0].z();
+//         if (nearestZ < _vertices[1].z()) nearestZ = _vertices[1].z();
+//         if (nearestZ < _vertices[2].z()) nearestZ = _vertices[2].z();
+//         if (nearestZ < _vertices[3].z()) nearestZ = _vertices[3].z();
+
+//         // osg::notify(osg::NOTICE)<<"getNearestZ()="<<_fadeText->getText().createUTF8EncodedString()<<" "<<nearestZ<<std::endl;
+
+//         return nearestZ;
+//     }
+
+//     ossimPlanetFadeText* _fadeText;
+//     osg::Vec3d           _vertices[4];
+//     bool                 _visible;
+// };
+
+// struct ossimPlanetFadeTextPolytopeData : public ossimPlanetFadeTextData, public osg::Polytope
+// {
+//     ossimPlanetFadeTextPolytopeData(ossimPlanetFadeTextData& fadeTextData):
+//         ossimPlanetFadeTextData(fadeTextData)
+//     {
+//         _referenceVertexList.push_back(_vertices[0]);
+//         _referenceVertexList.push_back(_vertices[1]);
+//         _referenceVertexList.push_back(_vertices[2]);
+//         _referenceVertexList.push_back(_vertices[3]);
+//     }
+    
+//     void addEdgePlane(const osg::Vec3& corner, const osg::Vec3& edge)
+//     {
+//         osg::Vec3 normal( edge.y(), -edge.x(), 0.0f);
+//         normal.normalize();
+        
+//         add(osg::Plane(normal, corner));
+//     }
+     
+//     void buildPolytope()
+//     {
+//         osg::Vec3d edge01 = _vertices[1] - _vertices[0];
+//         osg::Vec3d edge12 = _vertices[2] - _vertices[1];
+//         osg::Vec3d edge23 = _vertices[3] - _vertices[2];
+//         osg::Vec3d edge30 = _vertices[0] - _vertices[3];
+
+//         osg::Vec3d normalFrontFace = edge01 ^ edge12;
+//         bool needToFlip = normalFrontFace.z()>0.0f;
+
+//         normalFrontFace.normalize();
+//         add(osg::Plane(normalFrontFace, _vertices[0]));
+
+//         add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[0], _vertices[1]));
+//         add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[1], _vertices[2]));
+//         add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[2], _vertices[3]));
+//         add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[3], _vertices[0]));
+        
+// #if 0
+//         osg::notify(osg::NOTICE)<<" normalFrontFace = "<<normalFrontFace<<std::endl;
+//         osg::notify(osg::NOTICE)<<" edge01 = "<<edge01<<std::endl;
+//         osg::notify(osg::NOTICE)<<" edge12 = "<<edge12<<std::endl;
+//         osg::notify(osg::NOTICE)<<" edge23 = "<<edge23<<std::endl;
+//         osg::notify(osg::NOTICE)<<" _vertices[0]= "<<_vertices[0]<<std::endl;
+//         osg::notify(osg::NOTICE)<<" _vertices[1]= "<<_vertices[1]<<std::endl;
+//         osg::notify(osg::NOTICE)<<" _vertices[2]= "<<_vertices[2]<<std::endl;
+//         osg::notify(osg::NOTICE)<<" _vertices[3]= "<<_vertices[3]<<std::endl;
+// #endif
+
+//         if (needToFlip) flip();
+
+// #if 0        
+//         osg::notify(osg::NOTICE)<<"   plane 0 "<< _planeList[0]<<std::endl;
+//         osg::notify(osg::NOTICE)<<"   plane 1 "<< _planeList[1]<<std::endl;
+//         osg::notify(osg::NOTICE)<<"   plane 2 "<< _planeList[2]<<std::endl;
+//         osg::notify(osg::NOTICE)<<"   plane 3 "<< _planeList[3]<<std::endl;
+//         osg::notify(osg::NOTICE)<<"   plane 4 "<< _planeList[4]<<std::endl;
+// #endif
+        
+//     }
+    
+//     inline bool contains(const std::vector<osg::Vec3>& vertices)
+//     {
+//         for(std::vector<osg::Vec3>::const_iterator itr = vertices.begin();
+//             itr != vertices.end();
+//             ++itr)
+//         {
+//             if (osg::Polytope::contains(*itr))
+//             {
+//                 return true;
+//             }
+//         }
+//         return false;
+//     }
+    
+// };
+
+// struct ossimPlanetFadeTextUserData : public osg::Referenced
+// {
+//     ossimPlanetFadeTextUserData():
+//         _frameNumber(0) {}
+
+//     typedef std::list<ossimPlanetFadeTextData> FadeTextList;
+//     unsigned int _frameNumber;
+//     FadeTextList _fadeTextInView;
+// };
+
+// struct ossimPlanetGlobalFadeText : public osg::Referenced
+// {
+//     typedef std::set< osg::ref_ptr<ossimPlanetFadeTextUserData> > UserDataSet;
+//     typedef std::set<ossimPlanetFadeText*> FadeTextSet;
+//     typedef std::multimap<double, osg::ref_ptr<ossimPlanetFadeTextPolytopeData> > FadeTextPolytopeMap;
+//     typedef std::map<osg::View*, UserDataSet> ViewUserDataMap;
+//     typedef std::map<osg::View*, FadeTextSet > ViewFadeTextMap;
+
+//     ossimPlanetGlobalFadeText():
+//         _frameNumber(0xffffffff)
+//     {
+//     }
+
+    
+//     ossimPlanetFadeTextUserData* createNewFadeTextUserData(osg::View* view)
+//     {
+//         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
+        
+//         ossimPlanetFadeTextUserData* userData = new ossimPlanetFadeTextUserData;
+
+//         if (!userData)
+//         {
+//             osg::notify(osg::NOTICE)<<"Memory error, unable to create FadeTextUserData."<<std::endl;
+//             return 0;
+//         }
+
+//         _viewMap[view].insert(userData);
+        
+//         return userData;
+//     }
+    
+    
+//     void update(unsigned int frameNumber)
+//     {
+//         _frameNumber = frameNumber;
+//         for(ossimPlanetGlobalFadeText::ViewUserDataMap::iterator vitr = _viewMap.begin();
+//             vitr != _viewMap.end();
+//             ++vitr)
+//         {
+//             osg::View* view = vitr->first;
+
+//             FadeTextSet& fadeTextSet = _viewFadeTextMap[view];
+//             fadeTextSet.clear();
+
+//             FadeTextPolytopeMap fadeTextPolytopeMap;
+
+//             for(ossimPlanetGlobalFadeText::UserDataSet::iterator uitr = vitr->second.begin();
+//                 uitr != vitr->second.end();
+//                 ++uitr)
+//             {
+//                 ossimPlanetFadeTextUserData* userData = uitr->get();
+                
+//                 int frameDelta = frameNumber - userData->_frameNumber;
+//                 if (frameDelta<=1)
+//                 {
+//                     for(ossimPlanetFadeTextUserData::FadeTextList::iterator fitr = userData->_fadeTextInView.begin();
+//                         (fitr != userData->_fadeTextInView.end());
+//                         ++fitr)
+//                     {
+//                         ossimPlanetFadeTextData& fadeTextData = *fitr;
+//                         if (fadeTextSet.count(fadeTextData._fadeText)==0)
+//                         {
+//                             fadeTextSet.insert(fadeTextData._fadeText);
+//                             fadeTextPolytopeMap.insert(FadeTextPolytopeMap::value_type(
+//                                 -fadeTextData.getNearestZ(), new ossimPlanetFadeTextPolytopeData(fadeTextData)));
+//                         }
+//                     }
+//                 }
+//             }
+
+// #if 0
+//             // for each FadeTexPoltopeData            
+//             //    create polytopes
+//             //    test against all FTPD's later in the list
+//             //       test all control points on FTPD against each plane of the current polytope
+//             //       if all control points removed or outside then discard FTPD and make FT visible = false;
+            
+//             FadeTextPolytopeMap::iterator outer_itr = fadeTextPolytopeMap.begin();                
+//             while (outer_itr != fadeTextPolytopeMap.end()) 
+//             {
+//                 FadeTextPolytopeMap::iterator inner_itr = outer_itr;
+//                 ++inner_itr;
+
+//                 if (inner_itr == fadeTextPolytopeMap.end()) break;
+
+//                 ossimPlanetFadeTextPolytopeData& outer_ftpm = *(outer_itr->second);
+//                 outer_ftpm.buildPolytope();
+
+//                 // osg::notify(osg::NOTICE)<<"Outer z "<<outer_ftpm.getNearestZ()<<std::endl;
+
+//                 while(inner_itr != fadeTextPolytopeMap.end())
+//                 {
+//                     ossimPlanetFadeTextPolytopeData& inner_ftpm = *(inner_itr->second);
+                    
+//                     // osg::notify(osg::NOTICE)<<"Inner z "<<inner_ftpm.getNearestZ()<<std::endl;
+
+//                     if (outer_ftpm.contains(inner_ftpm.getReferenceVertexList()))
+//                     {
+//                         FadeTextPolytopeMap::iterator erase_itr = inner_itr;
+//                         // move to next ftpm
+//                         ++inner_itr;
+                        
+//                         fadeTextSet.erase(inner_ftpm._fadeText);
+
+//                         // need to remove inner_ftpm as its occluded.
+//                         fadeTextPolytopeMap.erase(erase_itr);
+                        
+//                     }
+//                     else
+//                     {
+//                         // move to next ftpm
+//                         ++inner_itr;
+//                     }
+//                 }
+
+//                 ++outer_itr;
+
+//             }
+// #endif
+//         }
+//     }
+    
+//     inline void updateIfRequired(unsigned int frameNumber)
+//     {
+//         if (_frameNumber!=frameNumber) update(frameNumber);
+//     }
+
+//     unsigned int _frameNumber;
+//     OpenThreads::Mutex _mutex;
+//     ViewUserDataMap _viewMap;
+//     ViewFadeTextMap _viewFadeTextMap;
+// };
+
+// ossimPlanetGlobalFadeText* getGlobalFadeText()
+// {
+//     static osg::ref_ptr<ossimPlanetGlobalFadeText> s_globalFadeText = new ossimPlanetGlobalFadeText;
+//     return s_globalFadeText.get();
+// }
+struct ossimPlanetFadeText::FadeTextCullCallback : public osg::Drawable::CullCallback
+{
+public:
+   virtual bool cull(osg::NodeVisitor* nv,
+                     osg::Drawable* drawable,
+                     osg::RenderInfo* renderInfo) const
+      {
+         ossimPlanetFadeText* fadeText = dynamic_cast<ossimPlanetFadeText*>(drawable);
+         if(!fadeText) return false;
+         fadeText->setVisibleFlag(true);
+         if(fadeText->theClusterCull.get())
+         {
+            if(fadeText->theClusterCull->cull(nv, drawable, renderInfo->getState()))
+            {
+               fadeText->setVisibleFlag(false);
+            }
+         }
+         osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
+         if(cv&&fadeText->visibleFlag())
+         {
+            const osg::Polytope& p = cv->getCurrentCullingSet().getFrustum();
+            if(!p.contains(fadeText->getPosition()))
+            {
+               fadeText->setVisibleFlag(false);
+            }
+         }
+         
+         return !fadeText->theVisibleFlag;
+      }
+};
+
+struct ossimPlanetFadeText::FadeTextUpdateCallback : public osg::Drawable::UpdateCallback
+{
+//     ossimPlanetFadeTextData _ftd;
+
+    virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
+    {
+       
+       ossimPlanetFadeText* fadeText = dynamic_cast<ossimPlanetFadeText*>(drawable);
+       if (!fadeText) return;
+
+       
+       unsigned int frameNumber = nv->getFrameStamp()->getFrameNumber();
+       if(fadeText->theFrameNumber!=frameNumber)
+       {
+          fadeText->theFrameNumber = frameNumber;
+          
+          if(!fadeText->theVisibleFlag)
+          {
+             if( fadeText->theCurrentOpacity != 0.0)
+             {
+                fadeText->theCurrentOpacity -= fadeText->theFadeSpeed;
+                if(fadeText->theCurrentOpacity < 0.0) 
+                {
+                   fadeText->theCurrentOpacity = 0.0;
+                }
+            }
+          }
+          else if(fadeText->theCurrentOpacity != 1.0)
+          {
+             fadeText->theCurrentOpacity += fadeText->theFadeSpeed;
+             if(fadeText->theCurrentOpacity > 1.0) fadeText->theCurrentOpacity = 1.0;
+          }
+       }
+//         ossimPlanetGlobalFadeText* gft = getGlobalFadeText();
+//         gft->updateIfRequired(frameNumber);
+        
+//         ossimPlanetFadeText::ViewBlendColourMap& vbcm = fadeText->getViewBlendColourMap();
+
+//         _ftd._fadeText = fadeText;
+        
+//         float fadeSpeed = fadeText->getFadeSpeed();
+
+//         ossimPlanetGlobalFadeText::ViewFadeTextMap& vftm = gft->_viewFadeTextMap;
+//         for(ossimPlanetGlobalFadeText::ViewFadeTextMap::iterator itr = vftm.begin();
+//             itr != vftm.end();
+//             ++itr)
+//         {
+//             osg::View* view = itr->first;
+//             ossimPlanetGlobalFadeText::FadeTextSet& fadeTextSet = itr->second;
+//             bool visible = fadeTextSet.count(fadeText)!=0;
+
+//             osg::Vec4& tec = vbcm[view];
+//             tec[0] = 1.0f;
+//             tec[1] = 1.0f;
+//             tec[2] = 1.0f;
+//             if (visible)
+//             {
+//                 if (tec[3]<1.0f)
+//                 {
+//                     tec[3] += fadeSpeed;
+//                     if (tec[3]>1.0f) tec[3] = 1.0f;
+//                 }
+
+//             }
+//             else
+//             {
+//                 if (tec[3]>0.0f)
+//                 {
+//                     tec[3] -= fadeSpeed;
+//                     if (tec[3]<0.0f) tec[3] = 0.0f;
+//                 }
+//             }
+//         }
+    }
+};
+
+
+ossimPlanetFadeText::ossimPlanetFadeText()
+{
+    init();
+}
+
+ossimPlanetFadeText::ossimPlanetFadeText(const Text& text,const osg::CopyOp& copyop):
+    Text(text,copyop)
+{
+    init();
+}
+
+void ossimPlanetFadeText::init()
+{
+   theFadeSpeed = 0.01f;
+   setUpdateCallback(new FadeTextUpdateCallback());
+   setCullCallback(new FadeTextCullCallback());
+   theCurrentOpacity = 0.0f;
+   theVisibleFlag = false;
+   theFrameNumber = 0;   
+}
+
+void ossimPlanetFadeText::drawImplementation(osg::RenderInfo& renderInfo) const
+{
+   if(ossim::almostEqual(theCurrentOpacity, 0.0f)) return;
+   
+   ossimPlanetFadeText* constCast = const_cast<ossimPlanetFadeText*>(this);
+   ossim_float64 preserveColorBackground = constCast->_backdropColor[3];
+   constCast->_backdropColor[3] = theCurrentOpacity*preserveColorBackground;
+   constCast->_color[3] = theCurrentOpacity*preserveColorBackground;
+   Text::drawImplementation(renderInfo);
+   constCast->_backdropColor[3] = preserveColorBackground;
+#if 0
+   
+   // now pass on new details 
+   
+   ossimPlanetFadeTextUserData* userData = dynamic_cast<ossimPlanetFadeTextUserData*>(renderInfo.getUserData());
+   if (!userData)
+   {
+      if (renderInfo.getUserData())
+      {
+         osg::notify(osg::NOTICE)<<"Warning user data not of supported type."<<std::endl;
+         return;
+      }
+      
+      userData = getGlobalFadeText()->createNewFadeTextUserData(renderInfo.getView());
+      
+      if (!userData)
+      {
+         osg::notify(osg::NOTICE)<<"Memory error, unable to create FadeTextUserData."<<std::endl;
+         return;
+      }
+      
+      renderInfo.setUserData(userData);
+   }
+   
+   unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber();
+   if (frameNumber != userData->_frameNumber)
+   {
+      // new frame so must reset UserData structure.
+      userData->_frameNumber = frameNumber;
+      userData->_fadeTextInView.clear();
+   }
+   
+   
+   
+   osgText::Text::AutoTransformCache& atc = _autoTransformCache[renderInfo.getContextID()];
+   
+   osg::Matrix lmv = atc._matrix;
+   lmv.postMult(state.getModelViewMatrix());
+   
+   if (renderInfo.getView() && renderInfo.getView()->getCamera())
+   {
+        // move from camera into the view space.
+        lmv.postMult(state.getInitialInverseViewMatrix());
+        lmv.postMult(renderInfo.getView()->getCamera()->getViewMatrix());
+    }
+    
+    ossimPlanetFadeTextData ftd(const_cast<ossimPlanetFadeText*>(this));
+    
+    ftd._vertices[0].set(osg::Vec3d(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*lmv);
+    ftd._vertices[1].set(osg::Vec3d(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*lmv);
+    ftd._vertices[2].set(osg::Vec3d(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*lmv);
+    ftd._vertices[3].set(osg::Vec3d(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*lmv);
+
+    userData->_fadeTextInView.push_back(ftd);
+#endif
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.cpp
new file mode 100644
index 0000000..29b8cab
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.cpp
@@ -0,0 +1,616 @@
+#include <ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimGrect.h>
+#include <ossim/imaging/ossimImageHandlerRegistry.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/support_data/ossimSrtmSupportData.h>
+#include <ossim/projection/ossimImageViewProjectionTransform.h>
+
+ossimPlanetGeneralRasterElevationDatabase::ossimPlanetGeneralRasterElevationDatabase()
+   :ossimPlanetElevationDatabase()
+{
+   theOpenFlag = false;
+   theLocation = "";
+   theMaxOpenFiles = 25;
+   theMinOpenFiles = 20;
+   theCurrentInfoIdx = -1;
+//    theRenderer = new ossimImageRenderer;
+//    theRenderer->getResampler()->setFilterType("bilinear");
+//    theProjection    = new ossimEquDistCylProjection;
+//    theNullHeightValue = -32768.0;
+}
+
+ossimPlanetGeneralRasterElevationDatabase::ossimPlanetGeneralRasterElevationDatabase(const ossimPlanetGeneralRasterElevationDatabase& src)
+   :ossimPlanetElevationDatabase(src),
+    theLocation(src.theLocation),
+    theOpenFlag(src.theOpenFlag),
+    theMaxOpenFiles(src.theMaxOpenFiles),
+    theMinOpenFiles(src.theMinOpenFiles)
+{
+   theCurrentInfoIdx = -1;
+//    theMosaic   = new ossimOrthoImageMosaic;
+//    theRenderer = new ossimImageRenderer;
+//    theRenderer->getResampler()->setFilterType("bilinear");
+//    theProjection    = new ossimEquDistCylProjection;
+   open(theLocation);
+}
+
+ossimPlanetGeneralRasterElevationDatabase::~ossimPlanetGeneralRasterElevationDatabase()
+{
+   
+}
+
+ossimPlanetTextureLayer* ossimPlanetGeneralRasterElevationDatabase::dup()const
+{
+   return new ossimPlanetGeneralRasterElevationDatabase(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetGeneralRasterElevationDatabase::dupType()const
+{
+   return new ossimPlanetGeneralRasterElevationDatabase;
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetGeneralRasterElevationDatabase::updateExtents()
+{
+
+   theDirtyExtentsFlag = false;
+   return theStateCode;
+}
+
+void ossimPlanetGeneralRasterElevationDatabase::updateStats()const
+{
+   theStats->setTotalTextureSize(0);
+   theDirtyStatsFlag = false;
+   
+}
+
+void ossimPlanetGeneralRasterElevationDatabase::resetStats()const
+{
+   theStats->setBytesTransferred(0);
+   theStats->setTotalTextureSize(0);
+}
+
+
+ossimPlanetTextureLayerStateCode ossimPlanetGeneralRasterElevationDatabase::open(const std::string& location)
+{
+   ossimFilename file(location);
+   bool result = false;
+   theLocation = "";
+   theExtents = new ossimPlanetExtents;
+   theCurrentInfoIdx = -1;
+
+   if(file.exists())
+   {
+      if(file.isDir())
+      {
+         ossimDirectory dir;
+
+         if(dir.open(file))
+         {
+            ossimFilename testFile;
+            if(dir.getFirst(testFile))
+            {
+               do
+               {
+                  if(testFile.ext().downcase() == "ras")
+                  {
+                     ossimRefPtr<ossimGeneralRasterElevHandler> rasterHandler = new ossimGeneralRasterElevHandler();
+                     if(rasterHandler->open(testFile))
+                     {
+                        osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> rasterInfo =  new ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo;
+                        ossimGrect grect = rasterHandler->getBoundingGndRect();
+                        rasterInfo->theMinLat = ossim::min(grect.lr().latd(), grect.ul().latd());
+                        rasterInfo->theMaxLat = ossim::max(grect.lr().latd(), grect.ul().latd());
+                        rasterInfo->theMinLon = ossim::min(grect.lr().lond(), grect.ul().lond());
+                        rasterInfo->theMaxLon = ossim::max(grect.lr().lond(), grect.ul().lond());
+                        if(!result)
+                        {
+                           double gsd = rasterHandler->getMeanSpacingMeters();
+                           theExtents->setMinMaxScale(gsd, gsd*std::pow(2.0, 12));
+                           theExtents->setMinMaxLatLon(rasterInfo->theMinLat,
+                                                       rasterInfo->theMinLon,
+                                                       rasterInfo->theMaxLat,
+                                                       rasterInfo->theMaxLon);
+
+                        }
+                        else
+                        {
+                           theExtents->combineMinMaxLatLon(rasterInfo->theMinLat,
+                                                           rasterInfo->theMinLon,
+                                                           rasterInfo->theMaxLat,
+                                                           rasterInfo->theMaxLon);
+                        }
+                        result = true;
+                        
+                        rasterInfo->theFilename = testFile.string();
+                        rasterInfo->theGeneralRasterHandler = rasterHandler;
+                        
+                       theFilePointers.push_back(rasterInfo.get());
+                     }
+                  }
+               }while(dir.getNext(testFile)&&!result);
+            }
+         }
+      }
+   }
+   
+   theOpenFlag = result;
+   if(theOpenFlag)
+   {
+      theStateCode = ossimPlanetTextureLayer_VALID;
+      theLocation = location;
+      theCurrentInfoIdx = 0;
+   }
+   else
+   {
+      theStateCode = ossimPlanetTextureLayer_NO_SOURCE_DATA;
+   }
+   
+   return theStateCode;
+}
+
+bool ossimPlanetGeneralRasterElevationDatabase::hasTexture(ossim_uint32 width,
+                                                           ossim_uint32 height,
+                                                           const ossimPlanetTerrainTileId& tileId,
+                                                           const ossimPlanetGrid& grid)
+{
+   if(!theOpenFlag)
+   {
+      return false;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return false;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return false;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   double deltaLon    = (deltaXY[0])/(double)(width);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if((gsd.x >= theExtents->getMinScale()) &&
+      (gsd.y <= theExtents->getMaxScale()))
+   {
+      return true;
+   }
+   
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetGeneralRasterElevationDatabase::getTexture(ossim_uint32 width,
+                                                                                     ossim_uint32 height,
+                                                                                     const ossimPlanetTerrainTileId& tileId,
+                                                                                     const ossimPlanetGrid& grid,
+                                                                                     ossim_int32 padding)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+      ossimElevManager* manager = ossimElevManager::instance();
+      double minValue = 999999999.0;
+      double maxValue = -999999999.0;
+      for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         double h = manager->getHeightAboveEllipsoid(ossimGpt((*optimizedOutPtr).y(), (*optimizedOutPtr).x()));
+         if(!ossim::isnan(h))
+         {
+            *bufPtr = h;
+         }
+         
+         ++bufPtr;
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+#if 0
+   if(!theOpenFlag)
+   {
+      return 0;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   double deltaLon    = (deltaXY[0])/(double)(width);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_float64 minModelX, minModelY, maxModelX, maxModelY;
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      minModelX = points[0].x();
+      maxModelX = minModelX;
+      minModelY = minModelX;
+      maxModelY = minModelX;
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      ++optimizedOutPtr;
+      for(idxPts = 1; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         if(optimizedOutPtr->x() < minModelX) minModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->x() > maxModelX) maxModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->y() < minModelY) minModelY = optimizedOutPtr->y();
+         if(optimizedOutPtr->y() > maxModelY) maxModelY = optimizedOutPtr->y();
+      }
+      
+      //    std::vector<ossimDpt> latLonOrigins;
+      osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> handlerInfo = 0;
+      osg::Vec3d latLonPoint;
+      double minValue = 1.0/DBL_EPSILON -1;
+      double maxValue = -1.0/DBL_EPSILON +1;
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+            optimizedOutPtr = &points.front();      
+      optimizedOutPtr = &points.front();
+      
+      if(theFilePointers.size() == 1)
+      {
+         handlerInfo = getHandlerInfo(optimizedOutPtr->y(), optimizedOutPtr->x());
+         if(!handlerInfo) return 0;
+         ossim_float64 nullHeight = handlerInfo->theGeneralRasterHandler->getNullHeightValue();
+        
+         for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+         {
+            if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&handlerInfo.valid())
+            {
+               double h = handlerInfo->theGeneralRasterHandler->getHeightAboveMSL(ossimGpt(optimizedOutPtr->y(),
+                                                                                           optimizedOutPtr->x()));
+               if(!ossim::isnan(h)&&
+                  (h!=nullHeight))
+               {
+                  if(theGeoRefModel.valid())
+                  {
+                     h+=theGeoRefModel->getGeoidOffset(optimizedOutPtr->y(), optimizedOutPtr->x());
+                  }
+                  *bufPtr = h;
+                  if(h < minValue)
+                  {
+                     minValue = h;
+                  }
+                  if(h > maxValue)
+                  {
+                     maxValue = h;
+                  }
+               }   
+               else
+               {
+                  *bufPtr = 0;
+               }
+            }
+            ++bufPtr;
+         }
+      }
+      else
+      {
+         for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+         {
+            handlerInfo = getHandlerInfo(optimizedOutPtr->y(), optimizedOutPtr->x());
+            if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&handlerInfo.valid())
+            {
+               ossim_float64 nullHeight = handlerInfo->theGeneralRasterHandler->getNullHeightValue();
+               
+               double h = handlerInfo->theGeneralRasterHandler->getHeightAboveMSL(ossimGpt(optimizedOutPtr->y(),
+                                                                                           optimizedOutPtr->x()));
+               if(!ossim::isnan(h)&&
+                  (h!=nullHeight))
+               {
+                  if(theGeoRefModel.valid())
+                  {
+                     h+=theGeoRefModel->getGeoidOffset(optimizedOutPtr->y(), optimizedOutPtr->x());
+                  }
+                  *bufPtr = h;
+                  if(h < minValue)
+                  {
+                     minValue = h;
+                  }
+                  if(h > maxValue)
+                  {
+                     maxValue = h;
+                  }
+               }   
+               else
+               {
+                  *bufPtr = 0;
+               }
+            }
+            ++bufPtr;
+         }
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+#endif
+   return texture;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetGeneralRasterElevationDatabase::getTexture(ossim_uint32 level,
+                                                                            ossim_uint64 row,
+                                                                            ossim_uint64 col,
+                                                                            const ossimPlanetGridUtility& utility)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+
+   if(!theOpenFlag)
+   {
+      return 0;
+   }
+
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+   ossim_uint32 width = utility.getTileWidth();
+   ossim_uint32 height = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, 
+                           col);
+
+   if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+   {
+      return 0;
+   }
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/height;
+ //  double deltaLon    = deltaX/width;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(!theExtents->intersectsScale(gsd.y-FLT_EPSILON,
+                                  gsd.y+FLT_EPSILON))//gsd.y <= theExtents.theMaxGsd)
+   {
+      return 0;
+   }
+
+ //  double minSubRectLat = ossim::max(theExtents->getMinLat(),
+ //                                    minLat);
+   //double minSubRectLon = ossim::max(theExtents->getMinLon(),
+   //                                  minLon);
+ //  double maxSubRectLat = ossim::min(theExtents->getMaxLat(),
+ //                                    maxLat);
+   //double maxSubRectLon = ossim::min(theExtents->getMaxLon(),
+   //                                  maxLon);
+   //ossim_int32 wholeMinLat = (ossim_int32)std::floor(minSubRectLat);
+   //ossim_int32 wholeMinLon = (ossim_int32)std::floor(minSubRectLon);
+   //ossim_int32 wholeMaxLat = (ossim_int32)std::floor(maxSubRectLat);
+   //ossim_int32 wholeMaxLon = (ossim_int32)std::floor(maxSubRectLon);
+   
+
+   //ossim_int32 lat = wholeMaxLat;
+   //ossim_int32 lon = wholeMinLon;
+   osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> handlerInfo = 0;//theFilePointers[theCurrentInfoIdx];
+   texture = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                                           level,
+                                                           col,
+                                                           row));
+   ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                  OSSIM_FLOAT32,
+                                                                  1,
+                                                                  width,
+                                                                  height);
+   compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+   compositeData->initialize();
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   utility.createGridPoints(points,
+                            level,
+                            row,
+                            col,
+                            height,
+                            width);
+
+   ossim_uint32 idxPts = 0;
+   ossim_uint32 nPoints = points.size();
+   osg::Vec3d latLonPoint;
+   double minValue = 1.0/DBL_EPSILON -1;
+   double maxValue = -1.0/DBL_EPSILON +1;
+   ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();   
+  for(idxPts = 0; idxPts < nPoints; ++idxPts)
+   {      
+      utility.getLatLon(latLonPoint, points[idxPts]);
+      handlerInfo = getHandlerInfo(latLonPoint[0], latLonPoint[1]);
+      if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&handlerInfo.valid())
+      {
+         ossim_float64 nullHeight = handlerInfo->theGeneralRasterHandler->getNullHeightValue();
+         utility.getLatLon(latLonPoint, points[idxPts]);
+         double h = handlerInfo->theGeneralRasterHandler->getHeightAboveMSL(ossimGpt(latLonPoint[0],
+                                                                                     latLonPoint[1]));
+         if(!ossim::isnan(h)&&(h!=nullHeight))
+         {            
+            if(theGeoRefModel.valid())
+            {
+               h+=theGeoRefModel->getGeoidOffset(latLonPoint[0], latLonPoint[1]);
+            }
+            *bufPtr = h;
+            if(*bufPtr < minValue)
+            {
+               minValue = *bufPtr;
+            }
+            if(*bufPtr > maxValue)
+            {
+               maxValue = *bufPtr;
+            }
+         }   
+      }
+      ++bufPtr;
+   }
+   
+   compositeData->validate();
+   
+   if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+   {
+      texture->fromOssimImage(compositeData, false);
+      
+      if(minValue < maxValue)
+      {
+         texture->setMinMax(minValue, maxValue);
+      }
+   }
+   else
+   {
+      texture = 0;
+   }
+
+   return texture;
+}
+osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> ossimPlanetGeneralRasterElevationDatabase::getHandlerInfo(const double& lat,
+                                                                                                                                     const double& lon)
+{
+   if(theFilePointers.size() < 1) return 0;
+
+   osg::ref_ptr<ossimPlanetGeneralRasterElevationDatabase::GeneralRasterInfo> result = 0;
+
+   if(theCurrentInfoIdx < 0) theCurrentInfoIdx = 0;
+   result = theFilePointers[theCurrentInfoIdx];
+   if((lat >= result->theMinLat)&&
+      (lat <= result->theMaxLat)&&
+      (lon >= result->theMinLon)&&
+      (lon <= result->theMaxLon))
+   {
+      return result;
+   }
+   theCurrentInfoIdx = 0;
+   while(theCurrentInfoIdx < (int)theFilePointers.size())
+   {
+      result = theFilePointers[theCurrentInfoIdx];
+      if((lat >= result->theMinLat)&&
+         (lat <= result->theMaxLat)&&
+         (lon >= result->theMinLon)&&
+         (lon <= result->theMaxLon))
+      {
+         return result;
+      }
+      ++theCurrentInfoIdx;
+     
+   }
+   theCurrentInfoIdx = 0;
+   
+   return 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetGeocoder.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetGeocoder.cpp
new file mode 100644
index 0000000..f11c703
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetGeocoder.cpp
@@ -0,0 +1,81 @@
+#include <ossimPlanet/ossimPlanetGeocoder.h>
+#include <sstream>
+#include <iostream>
+static std::istream& geocoderskipws(std::istream& in)
+{
+   int c = in.peek();
+   while((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n')||
+	 (c == '\r'))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+ossimPlanetGoecoder::ossimPlanetGeocoderLocation::ossimPlanetGeocoderLocation()
+{
+   theMetaInformation = new ossimXmlNode;
+   theMetaInformation->setTag("kml");
+   theNameNode = new ossimXmlNode;
+   theNameNode->setTag("name");
+   theMetaInformation->addChildNode(theNameNode.get());
+   thePlacemarkNode = new ossimXmlNode;
+   thePlacemarkNode->setTag("Placemark");
+   theMetaInformation->addChildNode(thePlacemarkNode.get());
+   theAddressNode = new ossimXmlNode;
+   theAddressNode->setTag("Address");
+   thePointNode = new ossimXmlNode;
+   theCoordinatesNode = new ossimXmlNode;
+   theCoordinatesNode->setText("0.0, 0.0, 0.0");
+   thePointNode->addChildNode(theCoordinatesNode.get());
+   
+   theMetaInformation->addChildNode(theNameNode.get());
+   theMetaInformation->addChildNode(thePlacemarkNode.get());
+   theMetaInformation->addChildNode(theAddressNode.get());
+   theMetaInformation->addChildNode(thePointNode.get());
+}
+
+void ossimPlanetGoecoder::ossimPlanetGeocoderLocation::setLocation(const ossimGpt& location)
+{
+   theCoordinatesNode->setText(ossimString::toString(location.latd())+ "," +
+                               ossimString::toString(location.lond())+ ", 0.0");
+                                                     
+}
+
+ossimGpt ossimPlanetGoecoder::ossimPlanetGeocoderLocation::getLocation()const
+{
+   ossimGpt result;
+   std::istringstream in(theCoordinatesNode->getText());
+
+   char c;
+   double lat, lon;
+
+   in >> lat >> geocoderskipws >> c >> geocoderskipws >>lon;
+   result.latd(lat);
+   result.lond(lon);
+
+   return result;
+}
+
+void ossimPlanetGoecoder::ossimPlanetGeocoderLocation::setName(const ossimString& name)
+{
+   theNameNode->setText(name);
+}
+
+ossimString ossimPlanetGoecoder::ossimPlanetGeocoderLocation::getName()const
+{
+   return theNameNode->getText();
+}
+
+ossimString ossimPlanetGoecoder::ossimPlanetGeocoderLocation::getAddress()const
+{
+   return theAddressNode->getText();
+}
+
+void ossimPlanetGoecoder::ossimPlanetGeocoderLocation::setAddress(const ossimString& address)
+{
+   theAddressNode->setText(address);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetGrid.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetGrid.cpp
new file mode 100644
index 0000000..cf458d8
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetGrid.cpp
@@ -0,0 +1,1100 @@
+#include <ossimPlanet/ossimPlanetGrid.h>
+#include <ossimPlanet/ossimPlanetPlaneGrid.h>
+#include <ossimPlanet/ossimPlanetCubeGrid.h>
+#include <osg/Vec2d>
+#include <osg/io_utils>
+#include <ossim/base/ossimDrect.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimUnitConversionTool.h>
+#include <iomanip>
+
+void ossimPlanetGrid::numberOfTilesPerFace(ossim_uint32 lod, ossim_uint64& tilesWide, ossim_uint64& tilesHigh) const
+{
+   ossim_uint64 value = 1<<lod;
+   
+   tilesWide = value;
+   tilesHigh = value;
+}
+
+void ossimPlanetGrid::bounds(const ossimPlanetTerrainTileId& tileId, GridBound& bound)const
+{
+   ossim_float64 w,h;
+   GridPoint gridPoint;
+   origin(tileId, gridPoint);
+   widthHeight(tileId, w, h);
+   
+   bound.theMinx = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+   bound.theMiny = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+   bound.theWidth  = w;
+   bound.theHeight = h;
+   bound.theFace   = tileId.face();
+}
+
+void ossimPlanetGrid::boundsToModel(const ossimPlanetTerrainTileId& tileId, 
+                                    ModelPoint& p0, 
+                                    ModelPoint& p1, 
+                                    ModelPoint& p2,
+                                    ModelPoint& p3)const
+{
+   GridBound bound;
+   bounds(tileId, bound);
+   globalGridToModel(GridPoint(tileId.face(),bound.minx(), bound.miny()),
+                     p0);
+   globalGridToModel(GridPoint(tileId.face(),bound.maxx(), bound.miny()),
+                     p1);
+   globalGridToModel(GridPoint(tileId.face(),bound.maxx(), bound.maxy()),
+                     p2);
+   globalGridToModel(GridPoint(tileId.face(),bound.minx(), bound.maxy()),
+                     p3);
+}
+
+void ossimPlanetGrid::centerGrid(const ossimPlanetTerrainTileId& tileId, GridPoint& gridPoint)
+{
+   ossim_float64 w,h;
+   origin(tileId, gridPoint);
+   widthHeight(tileId, w, h);
+   gridPoint.theXYZ[ossimPlanetGrid::X_IDX] += (w*.5);
+   gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] += (h*.5);
+}
+
+void ossimPlanetGrid::centerModel(const ossimPlanetTerrainTileId& tileId, ModelPoint& modelPoint)
+{
+   GridPoint gridPoint;
+   centerGrid(tileId, gridPoint);
+   globalGridToModel(gridPoint, modelPoint);
+}
+
+void ossimPlanetGrid::widthHeight(const ossimPlanetTerrainTileId& tileId, ossim_float64& width, ossim_float64& height)const
+{
+   // assume square in NDC 0..1 and divide by the 2^level
+   //
+   ossim_float64 value = 1.0/(ossim_float64)(1<<tileId.level());
+   
+   width  = value;
+   height = value;
+}
+
+void ossimPlanetGrid::origin(const ossimPlanetTerrainTileId& tileId, GridPoint& gridPoint)const
+{
+   ossim_float64 w,h;
+   
+   // get the width hieght in global 0..1 grid space.
+   widthHeight(tileId, w, h);
+   gridPoint.theFace = tileId.face();
+   gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = tileId.x()*w;
+   gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = tileId.y()*h;
+}
+
+void ossimPlanetGrid::getUnitsPerPixel(osg::Vec2d& unitsPerPixel,
+                                       const ossimPlanetTerrainTileId& tileId, 
+                                       ossim_uint32 w, 
+                                       ossim_uint32 h,
+                                       const ossimUnitType unitType)const
+{
+   unitsPerPixel[0] = unitsPerPixel[1] = 0.0;
+   if(theModelType == GEODETIC_MODEL)
+   {
+      osg::Vec2d modelWH;
+
+      widthHeightInModelSpace(tileId, modelWH);
+      ossimUnitConversionTool toolX(modelWH[0], OSSIM_DEGREES);
+      ossimUnitConversionTool toolY(modelWH[1], OSSIM_DEGREES);
+      unitsPerPixel[0]  =  toolX.getValue(unitType);
+      unitsPerPixel[1]  =  toolY.getValue(unitType);
+      unitsPerPixel[0] /= w;
+      unitsPerPixel[1] /= h;
+   }
+}
+
+bool ossimPlanetGrid::convertToGeographicExtents(const ossimPlanetTerrainTileId& tileId,
+                                                 ossimPlanetExtents& extents, 
+                                                 ossim_uint32 w, ossim_uint32 h)const
+{
+   static const ossimGpt wgs84Point;
+   bool result = false;
+   if(theModelType == GEODETIC_MODEL)
+   {
+      ModelPoint minPoint, maxPoint;
+      osg::Vec2d modelWH;
+      modelBound(tileId, minPoint, maxPoint);
+      extents.setMinMaxLatLon(minPoint.y(), minPoint.x(),
+                              maxPoint.y(), maxPoint.x());
+      widthHeightInModelSpace(tileId, modelWH);
+      ossim_float64 average = (modelWH[0]+modelWH[1])*.5;
+      ossim_float64 mpd = wgs84Point.metersPerDegree().y;
+      ossim_float64 mpp = (mpd*average)/((w+h)*.5);
+      // we will set the gsd as the center for this tile and then make a range that covers to approximately
+      // the next level down and the next level up.
+      //
+      extents.setMinMaxScale(mpp*.5, mpp*2.0);
+      
+      result = true;
+   }
+   return result;
+}
+
+void ossimPlanetGrid::localNdcToGlobalGrid(const ossimPlanetTerrainTileId& tileId, const LocalNdcPoint& localNdc, GridPoint& globalGrid)const
+{
+   GridBound b;
+   bounds(tileId, b);
+   
+   globalGrid.setZ(localNdc.z());
+   globalGrid.setX(b.minx() + b.width()*localNdc.x());
+   globalGrid.setY(b.miny() + b.height()*localNdc.y());
+   globalGrid.setFace(tileId.face());
+}
+
+void ossimPlanetGrid::localNdcToModel(const ossimPlanetTerrainTileId& tileId, const LocalNdcPoint& localNdc, ModelPoint& model)const
+{
+   GridPoint gridPoint;
+   localNdcToGlobalGrid(tileId, localNdc, gridPoint);
+   globalGridToModel(gridPoint, model);
+}
+
+void ossimPlanetCubeGrid2::getRootIds(TileIds &ids) const
+{
+   ids.push_back(ossimPlanetTerrainTileId(0,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(1,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(2,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(3,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(4,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(5,0,0,0));
+}
+
+
+void ossimPlanetGrid::getInternationalDateLineCrossings(const ossimPlanetTerrainTileId& tileId,
+                                                        std::vector<osg::Vec2d>& minMaxPairs)const
+{
+   ModelPoint ll, lr, ur, ul;
+   
+   GridBound bound;
+   bounds(tileId, bound);
+   
+   globalGridToModel(GridPoint(tileId.face(), bound.minx(), bound.miny()), ll);
+   globalGridToModel(GridPoint(tileId.face(), bound.maxx(), bound.miny()), lr);
+   globalGridToModel(GridPoint(tileId.face(), bound.maxx(), bound.maxy()), ur);
+   globalGridToModel(GridPoint(tileId.face(), bound.minx(), bound.maxy()), ul);
+   if(!crossesInternationalDateLine(tileId)||(theModelType!=GEODETIC_MODEL))
+   {
+      double minLon = ossim::min(ll.x(), ossim::min(lr.x(), ossim::min(ur.x(), ul.x())));
+      double maxLon = ossim::max(ll.x(), ossim::max(lr.x(), ossim::max(ur.x(), ul.x())));
+      minMaxPairs.push_back(osg::Vec2d(minLon, maxLon));
+   }
+   else if(theModelType == GEODETIC_MODEL) 
+   {
+      
+      osg::Vec2d pt;
+      pt[0] = -180.0;
+      pt[1] = -180.0;
+      if(ul.x() < FLT_EPSILON)
+      {
+         if(ul.x() > pt[1])
+         {
+            pt[1] = ul.x();
+         }
+      }
+      if(ur.x() < FLT_EPSILON)
+      {
+         if(ur.x() > pt[1])
+         {
+            pt[1] = ur.x();
+         }
+      }
+      if(lr.x() < FLT_EPSILON)
+      {
+         if(lr.x() > pt[1])
+         {
+            pt[1] = lr.x();
+         }
+      }
+      if(ll.x() < FLT_EPSILON)
+      {
+         if(ll.x() > pt[1])
+         {
+            pt[1] = ll.x();
+         }
+      }
+      minMaxPairs.push_back(pt);
+      
+      pt[0] = 180.0;
+      pt[1] = 180.0;
+      if(ul.x() > -FLT_EPSILON)
+      {
+         if(ul.x() < pt[0])
+         {
+            pt[0] = ul.x();
+         }
+      }
+      if(ur.x() > -FLT_EPSILON)
+      {
+         if(ur.x() < pt[0])
+         {
+            pt[0] = ur.x();
+         }
+      }
+      if(lr.x() > -FLT_EPSILON)
+      {
+         if(lr.x() < pt[0])
+         {
+            pt[0] = lr.x();
+         }
+      }
+      if(ll.x() > -FLT_EPSILON)
+      {
+         if(ll.x() < pt[0])
+         {
+            pt[0] = ll.x();
+         }
+      }
+      minMaxPairs.push_back(pt);
+   }
+}
+
+void ossimPlanetGrid::createModelPoints(const ossimPlanetTerrainTileId& tileId,
+                                        ossim_uint32 w,
+                                        ossim_uint32 h,
+                                        ossimPlanetGrid::ModelPoints& modelPoints,
+                                        ossim_uint32 padding)const
+{
+   ossim_int32 signedPadding = padding;
+   ossim_int32 rowIdx = 0;
+   ossim_int32 colIdx = 0;
+   ossim_float64 incH = 1.0/(h-1);
+   ossim_float64 incW = 1.0/(w-1);
+   ossim_int32 maxH = h + padding;
+   ossim_int32 maxW = w + padding;
+   ossimPlanetGrid::LocalNdcPoint localPoint;
+   ossimPlanetGrid::ModelPoint modelPoint;
+   modelPoints.clear();
+   for(rowIdx = -signedPadding; rowIdx < maxH;++rowIdx)
+   {
+      localPoint.setY(rowIdx*incH);
+      for(colIdx = -signedPadding; colIdx < maxW;++colIdx)
+      {
+         localPoint.setX(colIdx*incW);
+         localNdcToModel(tileId, localPoint, modelPoint);
+         modelPoints.push_back(modelPoint);
+      }
+   }
+}
+
+bool ossimPlanetGrid::crossesInternationalDateLine(const ossimPlanetTerrainTileId& tileId)const
+{
+   if(theModelType != GEODETIC_MODEL) return false;
+   ModelPoint minPoint, maxPoint;
+   modelBound(tileId, minPoint, maxPoint);
+   return (fabs(minPoint.x()-maxPoint.x()) > 180.0);
+}
+
+void ossimPlanetGrid::modelBound(const ossimPlanetTerrainTileId& tileId, 
+                                 ModelPoint& minPoint, ModelPoint& maxPoint)const
+{
+   ModelPoints points;
+   createModelPoints(tileId,
+                     3,
+                     3,
+                     points);
+   minPoint.setX(1.0/FLT_EPSILON);
+   minPoint.setY(1.0/FLT_EPSILON);
+   minPoint.setZ(1.0/FLT_EPSILON);
+   maxPoint.setX(-1.0/FLT_EPSILON);
+   maxPoint.setY(-1.0/FLT_EPSILON);
+   maxPoint.setZ(-1.0/FLT_EPSILON);
+   ossim_uint32 idx = 0;
+   ossim_uint32 size = points.size();
+   osg::Vec3d latLon;
+   for(idx = 0; idx < size; ++idx)
+   {
+      minPoint.setX(ossim::min(minPoint.x(), points[idx].x()));
+      minPoint.setY(ossim::min(minPoint.y(), points[idx].y()));
+      minPoint.setZ(ossim::min(minPoint.z(), points[idx].z()));
+      maxPoint.setX(ossim::max(maxPoint.x(), points[idx].x()));
+      maxPoint.setY(ossim::max(maxPoint.y(), points[idx].y()));
+      maxPoint.setZ(ossim::max(maxPoint.z(), points[idx].z()));
+   }
+}
+
+void ossimPlanetCubeGrid2::modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                             GridPoint& gridPoint)const
+{
+   osg::Vec2d ll((ossim::clamp((double)modelPoint.y(),
+                               (double)-90.0, (double)90.0)+90)/180,
+                 (ossim::wrap((double)modelPoint.x(),
+                              (double)-180.0, (double)180.0)+180)/360);
+   int face_x = (int)(4 * ll[ossimPlanetGrid::LON_IDX]);
+   int face_y = (int)(2 * ll[ossimPlanetGrid::LAT_IDX] + 0.5);
+   if(face_x == 4)
+   {
+      face_x = 3;
+   }
+   if(face_y == 1)
+   {
+      gridPoint.theFace = face_x;
+   }
+   else
+   {
+      gridPoint.theFace = face_y < 1 ? 5 : 4;
+   }
+   gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 4 * ll[ossimPlanetGrid::LON_IDX] - face_x;
+   gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 2 * ll[ossimPlanetGrid::LAT_IDX] - 0.5;
+   if(gridPoint.theFace < 4) // equatorial calculations done
+   {
+      //       gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = 1-gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY];
+      return;
+   }
+   
+   double tmp=0.0;
+   if(gridPoint.theFace == 4) // north polar face
+   {
+      gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 1.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+      gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = (2 * (gridPoint.theXYZ[ossimPlanetGrid::X_IDX] - 0.5) * 
+                                                  gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] + 0.5);
+      switch(face_x)
+      {
+         case 0: // bottom
+         {
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            break;
+         }
+         case 1: // right side, swap and reverse lat
+         {
+            tmp = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 0.5 + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = tmp;
+            break;
+         }
+         case 2: // top; reverse lat and lon
+         {
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 1 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 0.5 + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            break;
+         }
+         case 3: // left side; swap and reverse lon
+         {
+            tmp = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX]= 1 - tmp;
+            break;
+         }
+      }
+   }
+   else // south polar face
+   {
+      gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] += 0.5;
+      gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = (2 * (gridPoint.theXYZ[ossimPlanetGrid::X_IDX] - 0.5) * gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] + 0.5);
+      switch(face_x)
+      {
+         case 0: // left
+         {
+            tmp = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = tmp;
+            break;
+         }
+         case 1: // top
+         {
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 0.5 + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            break;
+         }
+         case 2: // right
+         {
+            tmp = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 0.5 + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 1 - tmp;
+            break;
+         }
+         case 3: // bottom
+         {
+            gridPoint.theXYZ[ossimPlanetGrid::X_IDX] = 1 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            break;
+         }
+      }
+   }
+}
+
+void ossimPlanetCubeGrid2::globalGridToModel(const GridPoint& gridPoint, 
+                                             ModelPoint& modelPoint)const
+{
+   globalGridToModelLat45(gridPoint, modelPoint);
+}
+
+void ossimPlanetCubeGrid2::globalGridToModelLat45(const GridPoint& gridPoint, 
+                                                  ModelPoint& modelPoint)const
+{
+   
+   double offset = 0.0;
+   osg::Vec2d s(ossim::clamp(gridPoint.theXYZ[ossimPlanetGrid::X_IDX], 0.0, 1.0),
+                ossim::clamp(gridPoint.theXYZ[ossimPlanetGrid::Y_IDX], 0.0, 1.0));
+   modelPoint.theXYZ[ossimPlanetGrid::Z_IDX] = gridPoint.z();
+   if(gridPoint.theFace < 4)
+   {
+      s[ossimPlanetGrid::X_IDX] = (gridPoint.theXYZ[ossimPlanetGrid::X_IDX]+gridPoint.theFace)*.25;
+      s[ossimPlanetGrid::Y_IDX] = (gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] + 0.5)*0.5;
+      //      latLon.x() = s[ossimPlanetGridUtility::GRIDX]*360.0 - 180.0;
+      //      latLon[ossimPlanetGridUtility::LAT] = 90 - s[ossimPlanetGridUtility::GRIDY]*180.0;
+      //      return;
+   }
+   else if(gridPoint.theFace == 4)
+   {
+      if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] < gridPoint.theXYZ[ossimPlanetGrid::Y_IDX])
+      {
+         if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] < 1.0)
+         {
+            s[ossimPlanetGrid::X_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            s[ossimPlanetGrid::Y_IDX] = gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            offset += 3;
+         }
+         else
+         {
+            s[ossimPlanetGrid::Y_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            s[ossimPlanetGrid::X_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            offset += 2;
+         }
+      }
+      else if((gridPoint.theXYZ[ossimPlanetGrid::X_IDX] + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX]) >= 1.0)
+      {
+         s[ossimPlanetGrid::X_IDX] = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+         s[ossimPlanetGrid::Y_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+         offset += 1.0;
+      }
+      s[ossimPlanetGrid::X_IDX] -= s[ossimPlanetGrid::Y_IDX];
+      if(!ossim::almostEqual(s[ossimPlanetGrid::Y_IDX], .5))
+      {
+         s[ossimPlanetGrid::X_IDX] *= .5/(.5 - s[ossimPlanetGrid::Y_IDX]);
+      }
+      s[ossimPlanetGrid::X_IDX] = (s[ossimPlanetGrid::X_IDX] + offset)*0.25;
+      s[ossimPlanetGrid::Y_IDX] = (s[ossimPlanetGrid::Y_IDX] + 1.5)*.5;
+   }
+   else if(gridPoint.theFace == 5)
+   {
+      offset = 1.0;
+      if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] > gridPoint.theXYZ[ossimPlanetGrid::Y_IDX])
+      {
+         if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] >= 1.0)
+         {
+            s[ossimPlanetGrid::X_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            s[ossimPlanetGrid::Y_IDX] = gridPoint.theXYZ[ossimPlanetGrid::X_IDX] - .5;
+            offset += 1.0;
+         }
+         else
+         {
+            s[ossimPlanetGrid::X_IDX] = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            s[ossimPlanetGrid::Y_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            offset+=2;
+         }
+      }
+      else
+      {
+         if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] +  gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] < 1.0)
+         {
+            s[ossimPlanetGrid::X_IDX] = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            s[ossimPlanetGrid::Y_IDX] = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            offset -= 1.0;
+         }
+         else
+         {
+            s[ossimPlanetGrid::Y_IDX] = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] - 0.5;
+         }
+      }
+      if(!ossim::almostEqual((double)s[ossimPlanetGrid::Y_IDX], (double)0.0))
+      {
+         //         s[ossimPlanetGrid::X_IDX] = ((s[ossimPlanetGrid::X_IDX] - 0.5)*.5)/s[ossimPlanetGrid::Y_IDX] + .5;
+         s[ossimPlanetGrid::X_IDX] = ((s[ossimPlanetGrid::X_IDX] - 0.5)*.5)/s[ossimPlanetGrid::Y_IDX] + .5;
+      }
+      s[ossimPlanetGrid::X_IDX] = (s[ossimPlanetGrid::X_IDX] + offset) *0.25;
+      s[ossimPlanetGrid::Y_IDX] *=.5;
+   }
+   modelPoint.theXYZ[ossimPlanetGrid::X_IDX] = s[ossimPlanetGrid::X_IDX]*360.0 - 180.0;
+   modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] = s[ossimPlanetGrid::Y_IDX]*180.0 - 90;
+   modelPoint.theXYZ[ossimPlanetGrid::Z_IDX] = gridPoint.z();
+}
+
+void ossimPlanetCubeGrid2::globalGridToModelLat67_5(const GridPoint& gridPoint, ModelPoint& modelPoint)const
+{
+   
+   // double offset = 0.0;
+   osg::Vec2d s(ossim::clamp(gridPoint.theXYZ[ossimPlanetGrid::X_IDX], 0.0, 1.0),
+                ossim::clamp(gridPoint.theXYZ[ossimPlanetGrid::Y_IDX], 0.0, 1.0));
+   modelPoint.theXYZ[ossimPlanetGrid::Z_IDX] = gridPoint.z();
+   if(gridPoint.theFace < 24)
+   {
+      modelPoint.setX(gridPoint.x()*360.0 - 180.0);
+      modelPoint.setY(-67.5 + gridPoint.y()*135);
+      return;
+   }
+   else if(gridPoint.theFace == 24)// north cap
+   {
+   }
+   else if(gridPoint.theFace == 25)
+   {
+   }
+}
+
+void ossimPlanetCubeGrid2::widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, osg::Vec2d& deltaXY)const
+{
+   GridBound b;
+   
+   bounds(tileId, b);
+   ossim_float64 multiplier = 90;
+   deltaXY[0] = multiplier*b.width();
+   deltaXY[1] = multiplier*b.height();
+}
+
+
+bool ossimPlanetCubeGrid2::findGridBound(ossim_uint32 face,
+                                         const ModelPoint& minPoint,
+                                         const ModelPoint& maxPoint,
+                                         GridBound& bound,
+                                         ossim_uint32 numberOfPoints)const
+{
+   ossimDrect modelClipBound;
+   ossimDrect modelBound(minPoint.x(), maxPoint.y(), maxPoint.x(), minPoint.y(), OSSIM_RIGHT_HANDED);
+   ossimDrect modelFaceBound;
+   modelFaceBound.makeNan();
+   double epsilon = 1e-10;
+   if(face < 4)
+   {
+      // ossim_uint32 dx=0;
+      ossim_float64 originLat=-45, originLon=-180;
+      originLon = -180.0+(face*90);
+      modelFaceBound = ossimDrect(originLon, 
+                                  originLat+90-epsilon, originLon + 90.0-epsilon, originLat, OSSIM_RIGHT_HANDED);
+   }
+   else if(face == 4)
+   {
+      modelFaceBound = ossimDrect(-180.0, 90.0, 180.0, 45.0, OSSIM_RIGHT_HANDED);
+      
+   }
+   else if(face == 5)
+   {
+      modelFaceBound = ossimDrect(-180.0, -45.0-epsilon, 180.0-epsilon, -90.0, OSSIM_RIGHT_HANDED);
+   }
+   bool result = modelFaceBound.intersects(modelBound);
+   if(result)
+   {
+      modelClipBound = modelBound.clipToRect(modelFaceBound);
+      
+      std::vector<ossimDpt> gridPoints;
+      ossim_uint32 idxY = 0;
+      ossim_uint32 idxX = 0;
+      double deltaModelX = modelClipBound.ur().x-modelClipBound.ll().x;
+      double deltaModelY = modelClipBound.ur().y-modelClipBound.ll().y;
+      ossimDpt ll = modelClipBound.ll();
+      
+      ossimPlanetGrid::GridPoint gridPoint;
+      for(idxY = 0; idxY <numberOfPoints; ++idxY)
+      {
+         for(idxX = 0; idxX < numberOfPoints; ++idxX)
+         {
+            double tx = (double)idxX/(numberOfPoints-1);
+            double ty = (double)idxY/(numberOfPoints-1);
+            
+            ossimPlanetGrid::ModelPoint modelPoint(ll.x + deltaModelX*tx,
+                                                   ll.y + deltaModelY*ty);
+            modelToGlobalGrid(modelPoint, gridPoint);
+           gridPoints.push_back(ossimDpt(gridPoint.x(), gridPoint.y()));
+         }
+      }
+      ossimDrect rect(gridPoints, OSSIM_RIGHT_HANDED);
+      bound.theMinx = rect.ll().x;
+      bound.theMiny = rect.ll().y;
+      bound.theWidth = (rect.ur().x-rect.ll().x);
+      bound.theHeight= (rect.ur().y-rect.ll().y);
+      bound.theFace = face;
+   }
+   return result;
+}
+
+ossim_uint32 ossimPlanetCubeGrid2::numberOfFaces()const
+{
+   return 6;
+}
+
+ossimPlanetGridUtility* ossimPlanetCubeGrid2::newBackwardCompatableGrid(ossim_uint32 width,
+                                                                        ossim_uint32 height)const
+{
+   return new ossimPlanetCubeGrid(width, height);
+}
+
+bool ossimPlanetCubeGrid2::isPolar(const ossimPlanetTerrainTileId& id)const
+{
+   return (id.face() >3);
+}
+
+void ossimPlanetPlaneGrid2::getRootIds(TileIds &ids) const
+{
+   ids.push_back(ossimPlanetTerrainTileId(0,0,0,0));
+   ids.push_back(ossimPlanetTerrainTileId(1,0,0,0));
+}
+
+void ossimPlanetPlaneGrid2::globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const
+{
+   modelPoint.setY(180.0*gridPoint.y() - 90.0);
+   if(gridPoint.face() == 0)
+   {
+      modelPoint.setX(180.0*gridPoint.x() - 180.0);
+   }
+   else
+   {
+      modelPoint.setX(180.0*gridPoint.x());
+   }
+   
+   modelPoint.setZ(gridPoint.z());
+}
+
+void ossimPlanetPlaneGrid2::modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                             GridPoint& gridPoint)const
+{
+   gridPoint.setY((modelPoint.y()+90.0)/180.0);      
+   if(modelPoint.x() < 0.0)
+   {
+      gridPoint.setFace(0);
+      gridPoint.setX(modelPoint.x()/180.0 + 1.0);
+   }
+   else
+   {
+      gridPoint.setFace(1);
+      gridPoint.setX(modelPoint.x()/180.0);
+   }
+   
+   gridPoint.setZ(modelPoint.z());
+}
+
+void ossimPlanetPlaneGrid2::widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, 
+                                                    osg::Vec2d& deltaXY)const
+{
+   GridBound b;
+   
+   bounds(tileId, b);
+   
+   deltaXY[0] = 180.0*b.width();
+   deltaXY[1] = 180.0*b.height();
+}
+
+bool ossimPlanetPlaneGrid2::findGridBound(ossim_uint32 face,
+                                          const ModelPoint& minPoint,
+                                          const ModelPoint& maxPoint,
+                                          GridBound& bound,
+                                          ossim_uint32 /* numberOfPoints */)const
+{
+   ossimDrect modelClipBound;
+   ossimDrect modelBound(minPoint.x(), maxPoint.y(), maxPoint.x(), minPoint.y(), OSSIM_RIGHT_HANDED);
+   ossimDrect modelFaceBound;
+   if(face == 0)
+   {
+      modelFaceBound = ossimDrect(-180.0, 90.0, 0.0, -90.0, OSSIM_RIGHT_HANDED);
+   }
+   else
+   {
+      modelFaceBound = ossimDrect(0.0, 90, 180.0, -90.0, OSSIM_RIGHT_HANDED);
+   }
+   bool result = modelFaceBound.intersects(modelBound);
+   if(result)
+   {
+      modelClipBound = modelBound.clipToRect(modelFaceBound);
+//      std::cout << "modelClipBound " << modelClipBound << std::endl;
+  }
+      
+   bound.theMiny = (90.0 + modelClipBound.ll().y)/180.0;
+   bound.theMinx = modelClipBound.ll().x/180.0;
+   if(face == 0)
+   {
+       bound.theMinx+= 1.0;
+   }
+   
+   bound.setFace(face);
+   bound.theWidth  = (modelClipBound.ur().x-modelClipBound.ll().x)/180.0;
+   bound.theHeight = (modelClipBound.ur().y-modelClipBound.ll().y)/180.0;
+   
+//   std::cout << "bound.theMinX = " << bound.theMinx << "\n"
+//   << "bound.theMinY = " << bound.theMiny << "\n";
+   return result;
+}
+
+ossim_uint32 ossimPlanetPlaneGrid2::numberOfFaces()const
+{
+   return 12;
+}
+
+ossimPlanetGridUtility* ossimPlanetPlaneGrid2::newBackwardCompatableGrid(ossim_uint32 width,
+                                                                         ossim_uint32 height)const
+{
+   return new ossimPlanetPlaneGrid(width, height);
+}
+
+ossimPlanetAdjustableCubeGrid::ossimPlanetAdjustableCubeGrid(CapLocation location)
+:ossimPlanetCubeGrid2()
+{
+   setCapLocation(location);
+}
+
+void ossimPlanetAdjustableCubeGrid::setCapLocation(CapLocation location)
+{
+   theCapLocation = location;
+   switch(location)
+   {
+      case LOW_CAP:
+      {
+         thePolarLat = 45.0;
+         break;
+      }
+      case MEDIUM_LOW_CAP:
+      {
+         thePolarLat = 67.5;
+         break;
+      }
+      case MEDIUM_CAP:
+      {
+         thePolarLat = 78.75;
+         break;
+      }
+      case MEDIUM_HIGH_CAP:
+      {
+         thePolarLat = 84.375;
+         break;
+      }
+      case HIGH_CAP:
+      {
+         thePolarLat = 87.1875;
+         break;
+      }
+      default:
+      {
+         thePolarLat = 78.75;
+         break;
+      }
+   }
+   theUpperEquatorialBandLatDelta = thePolarLat-45.0;
+   thePolarWidth                  = 2*(90-thePolarLat);// used in calculating crude ground distance.
+}
+
+void ossimPlanetAdjustableCubeGrid::getRootIds(TileIds &ids) const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      ossimPlanetCubeGrid2::getRootIds(ids);
+   }
+   else
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < numberOfFaces(); ++idx)
+      {
+         ids.push_back(ossimPlanetTerrainTileId(idx,0,0,0));
+      }
+   }
+}
+
+void ossimPlanetAdjustableCubeGrid::globalGridToModel(const GridPoint& gridPoint, ModelPoint& modelPoint)const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      ossimPlanetCubeGrid2::globalGridToModel(gridPoint, modelPoint);
+      return;
+   }
+   double xt = ossim::clamp(gridPoint.x(), 0.0, 1.0);
+   double yt = ossim::clamp(gridPoint.y(), 0.0, 1.0);
+   // equatorial 
+   if(gridPoint.face() < 4)
+   {
+      modelPoint.setY(90.0*yt - 45.0);
+      modelPoint.setX(-180 + 90*(gridPoint.face() + xt));
+   }
+   // northern band
+   else if(gridPoint.face() < 8)
+   {
+      modelPoint.setY(45+theUpperEquatorialBandLatDelta*yt);
+      modelPoint.setX(-180 + 90.0*(gridPoint.face()-4 + xt));
+   }
+   // southern band
+   else if(gridPoint.face() < 12)
+   {
+      modelPoint.setY(-thePolarLat + theUpperEquatorialBandLatDelta*yt);
+      modelPoint.setX(-180 + 90.0*(gridPoint.face()-8 +xt));
+   }
+   // north polar cap
+   else if(gridPoint.face() == 12)
+   {
+      GridPoint gPt(gridPoint);
+      
+      gPt.setFace(4);
+      ossimPlanetCubeGrid2::globalGridToModel(gPt, modelPoint);
+      // since we are using the formula for a 45 degree lat cube we will remap
+      // to our polar hack location.
+      //
+      double latT = (modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] - 45.0)/45;
+      modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] = thePolarLat + latT*(90.0-thePolarLat);
+   }
+   // south polar cap
+   else if(gridPoint.face() == 13)
+   {
+      double offset = 1.0;
+      if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] > gridPoint.theXYZ[ossimPlanetGrid::Y_IDX])
+      {
+         if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] + gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] >= 1.0)
+         {
+            xt = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            yt = gridPoint.theXYZ[ossimPlanetGrid::X_IDX] - .5;
+            offset += 1.0;
+         }
+         else
+         {
+            xt = 1.0 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            yt = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            offset+=2;
+         }
+      }
+      else
+      {
+         if(gridPoint.theXYZ[ossimPlanetGrid::X_IDX] +  gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] < 1.0)
+         {
+            xt = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX];
+            yt = 0.5 - gridPoint.theXYZ[ossimPlanetGrid::X_IDX];
+            offset -= 1.0;
+         }
+         else
+         {
+            yt = gridPoint.theXYZ[ossimPlanetGrid::Y_IDX] - 0.5;
+         }
+      }
+      if(!ossim::almostEqual((double)yt, (double)0.0))
+      {
+         xt = ((xt - 0.5)*.5)/yt + .5;
+      }
+      xt = (xt + offset) *0.25;
+      yt *=.5;
+      modelPoint.theXYZ[ossimPlanetGrid::X_IDX] = xt*360.0 - 180.0;
+      modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] = yt*180.0 - 90;
+      double latT = (modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] + 45.0)/45;
+      modelPoint.theXYZ[ossimPlanetGrid::Y_IDX] = -thePolarLat - latT*(-90+thePolarLat);
+   }
+   modelPoint.setZ(gridPoint.z());
+}
+
+void ossimPlanetAdjustableCubeGrid::modelToGlobalGrid(const ModelPoint& modelPoint, 
+                                              GridPoint& gridPoint)const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      ossimPlanetCubeGrid2::modelToGlobalGrid(modelPoint, gridPoint);
+      return;
+   }
+   double shiftedX = ossim::clamp(modelPoint.x() + 180.0,
+                                  0.0, 360.0);
+   // south polar region
+   if(modelPoint.y() >= thePolarLat)
+   {
+      gridPoint.setFace(12);
+      // map into 45 to 90
+      //
+      double adjustedModelY = 45 + 45*((modelPoint.y()-thePolarLat)/(.5*thePolarWidth)); 
+      ModelPoint adjustedModel(modelPoint.x(),
+                               adjustedModelY,
+                               modelPoint.z());
+      ossimPlanetCubeGrid2::modelToGlobalGrid(adjustedModel, gridPoint);
+      gridPoint.setFace(12);
+   }
+   // south polar region
+   else if(modelPoint.y() < -thePolarLat)
+   {
+      double adjustedModelY = -45.0+((modelPoint.y() + thePolarLat)/(thePolarWidth*.5))*45;
+      ModelPoint adjustedModel(modelPoint.x(),
+                               adjustedModelY,
+                               modelPoint.z());
+      ossimPlanetCubeGrid2::modelToGlobalGrid(adjustedModel, gridPoint);
+      gridPoint.setFace(13);
+   }
+   // north band
+   else if(modelPoint.y() > 45.0)
+   {
+      ossim_uint32 face = (ossim_uint32)ossim::clamp((shiftedX / 90),
+                                                     0.0, 4.0);
+      gridPoint.setX((shiftedX-face*90.0)/90.0);
+      gridPoint.setY((modelPoint.y()-45.0)/theUpperEquatorialBandLatDelta);
+      gridPoint.setFace(face+4);
+   }
+   // equatorial band
+   else if(modelPoint.y() >= -45.0)
+   {
+      ossim_uint32 face = ossim::clamp(((modelPoint.x()+180.0) / 90.0),
+                                       0.0, 3.0);
+      gridPoint.setX((shiftedX-face*90.0)/90.0);
+      gridPoint.setY((45.0+modelPoint.y())/90.0);
+      gridPoint.setFace(face);
+   }
+   // south lat band
+   else if(modelPoint.y() < -45.0)
+   {
+      ossim_uint32 face = ossim::clamp((shiftedX / 90),
+                                       0.0, 7.0);
+      gridPoint.setX((shiftedX-face*90.0)/90.0);
+      gridPoint.setY((45.0+modelPoint.y())/theUpperEquatorialBandLatDelta);
+      gridPoint.setFace(face+8);
+   }
+}
+
+void ossimPlanetAdjustableCubeGrid::widthHeightInModelSpace(const ossimPlanetTerrainTileId& tileId, 
+                                                    osg::Vec2d& deltaXY)const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      ossimPlanetCubeGrid2::widthHeightInModelSpace(tileId, deltaXY);
+      return;
+   }
+   GridBound b;
+   
+   bounds(tileId, b);
+   
+   ossim_float64 multiplierx = 90;
+   ossim_float64 multipliery = 90;
+   
+   if(tileId.face() < 4)
+   {
+      // purposely left blank;
+   }
+   else if(tileId.face() < 12)
+   {
+      
+      multiplierx = 90;
+      multipliery = theUpperEquatorialBandLatDelta;
+   }
+   else if((tileId.face() == 12)||
+           (tileId.face() == 13))
+   {
+      multiplierx = (90-thePolarLat)*2.0;
+      multipliery = multiplierx;
+   }
+   deltaXY[0] = multiplierx*b.width();
+   deltaXY[1] = multipliery*b.height();
+}
+
+bool ossimPlanetAdjustableCubeGrid::findGridBound(ossim_uint32 face,
+                                              const ModelPoint& minPoint,
+                                              const ModelPoint& maxPoint,
+                                              GridBound& bound,
+                                              ossim_uint32 numberOfPoints)const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      return ossimPlanetCubeGrid2::findGridBound(face, minPoint, maxPoint, bound, numberOfPoints);
+   }
+   ossimDrect modelClipBound;
+   ossimDrect modelBound(minPoint.x(), maxPoint.y(), maxPoint.x(), minPoint.y(), OSSIM_RIGHT_HANDED);
+   ossimDrect modelFaceBound;
+   double epsilon = 1e-12;
+
+   if(face < 4)
+   {
+      double originX = -180.0 + face*90.0;
+      modelFaceBound = ossimDrect(originX, 45-epsilon, originX + 90.0-epsilon, -45.0, OSSIM_RIGHT_HANDED);
+   }
+   else if(face < 8)
+   {
+      double originX = -180.0 + (face-4)*90.0;
+      modelFaceBound = ossimDrect(originX, thePolarLat-epsilon, originX + 90.0, 45, OSSIM_RIGHT_HANDED);
+   }
+   else if(face < 12)
+   {
+      double originX = -180.0 + (face-8)*90.0;
+      modelFaceBound = ossimDrect(originX, -45.0+epsilon, originX + 90.0, -thePolarLat, OSSIM_RIGHT_HANDED);
+   }
+   else if(face == 12)
+   {
+      modelFaceBound = ossimDrect(-180.0, 90.0, 180.0, thePolarLat, OSSIM_RIGHT_HANDED);
+   }
+   else if(face == 13)
+   {
+      modelFaceBound = ossimDrect(-180.0, -thePolarLat+epsilon, 180.0, -90.0, OSSIM_RIGHT_HANDED);
+   }
+   else
+   {
+      return false;
+   }
+   bool result = modelFaceBound.intersects(modelBound);
+   if(result)
+   {
+      modelClipBound = modelBound.clipToRect(modelFaceBound);
+      //      std::cout << "modelClipBound " << modelClipBound << std::endl;
+      // 4 equatorial faces
+      if(face < 4)
+      {
+         bound.theMiny = (45.0 + modelClipBound.ll().y)/90.0;
+         bound.theMinx = ((180.0 +modelClipBound.ll().x)/90.0) - face;
+         bound.theWidth  = (modelClipBound.ur().x-modelClipBound.ll().x)/90.0;
+         bound.theHeight = (modelClipBound.ur().y-modelClipBound.ll().y)/90.0;
+      }
+      // 4 upper band faces
+      else if(face < 8)
+      {
+         bound.theMiny = (modelClipBound.ll().y - 45)/theUpperEquatorialBandLatDelta;
+         bound.theMinx = (180.0 + modelClipBound.ll().x)/90 - (face-4);
+         bound.theWidth  = (modelClipBound.ur().x-modelClipBound.ll().x)/90.0;
+         bound.theHeight = (modelClipBound.ur().y-modelClipBound.ll().y)/theUpperEquatorialBandLatDelta;
+      }
+      // 4 lower band faces
+      else if(face < 12)
+      {
+         bound.theMiny = (modelClipBound.ll().y + thePolarLat)/theUpperEquatorialBandLatDelta;
+         bound.theMinx = (180.0 + modelClipBound.ll().x)/90.0 - (face-8);
+         bound.theWidth  = (modelClipBound.ur().x-modelClipBound.ll().x)/90.0;
+         bound.theHeight = (modelClipBound.ur().y-modelClipBound.ll().y)/theUpperEquatorialBandLatDelta;
+      }
+      // north and south polar faces
+      else if((face == 12)||
+              (face == 13))
+      {
+         std::vector<ossimDpt> gridPoints;
+         ossim_uint32 idxY = 0;
+         ossim_uint32 idxX = 0;
+         double deltaModelX = modelClipBound.ur().x-modelClipBound.ll().x;
+         double deltaModelY = modelClipBound.ur().y-modelClipBound.ll().y;
+         ossimDpt ll = modelClipBound.ll();
+         
+         ossimPlanetGrid::GridPoint gridPoint;
+         for(idxY = 0; idxY <numberOfPoints; ++idxY)
+         {
+            for(idxX = 0; idxX < numberOfPoints; ++idxX)
+            {
+               double tx = (double)idxX/(numberOfPoints-1);
+               double ty = (double)idxY/(numberOfPoints-1);
+               
+               ossimPlanetGrid::ModelPoint modelPoint(ll.x + deltaModelX*tx,
+                                                      ll.y + deltaModelY*ty);
+               modelToGlobalGrid(modelPoint, gridPoint);
+               gridPoints.push_back(ossimDpt(gridPoint.x(), gridPoint.y()));
+            }
+         }
+         ossimDrect rect(gridPoints, OSSIM_RIGHT_HANDED);
+         bound.theMinx = rect.ll().x;
+         bound.theMiny = rect.ll().y;
+         bound.theWidth = (rect.ur().x-rect.ll().x);
+         bound.theHeight= (rect.ur().y-rect.ll().y);
+         bound.theFace = face;
+      }
+      bound.setFace(face);
+   }
+  
+   //   std::cout << "bound.theMinX = " << bound.theMinx << "\n"
+   //   << "bound.theMinY = " << bound.theMiny << "\n";
+   return result;
+}
+
+ossim_uint32 ossimPlanetAdjustableCubeGrid::numberOfFaces()const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      return ossimPlanetCubeGrid2::numberOfFaces();
+   }
+   return 14;
+}
+
+bool ossimPlanetAdjustableCubeGrid::isPolar(const ossimPlanetTerrainTileId& id)const
+{
+   if(theCapLocation == LOW_CAP)
+   {
+      return ossimPlanetCubeGrid2::isPolar(id);
+   }
+   return ((id.face() == 12)||
+           (id.face() == 13));
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetGridUtility.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetGridUtility.cpp
new file mode 100644
index 0000000..5bd30eb
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetGridUtility.cpp
@@ -0,0 +1,526 @@
+#include "ossimPlanet/ossimPlanetGridUtility.h"
+#include <ossim/base/ossimCommon.h>
+#include <iostream>
+#include <ossim/base/ossimUnitConversionTool.h>
+#include "ossimPlanet/mkUtils.h"
+
+
+
+ossim_uint64 ossimPlanetGridUtility::getId(ossim_uint32 level,
+                                           ossim_uint64 row,
+                                           ossim_uint64 col)const
+{
+   ossim_uint64 w,h;
+   getNumberOfTilesWideHigh(w, h, level);
+   if(level == 0)
+   {
+      return ((ossim_uint64)row*w + (ossim_uint64)col);
+   }
+   ossim_uint64 shift = getTotalNumberOfTiles(level - 1);
+
+   return (shift + ((ossim_uint64)w*row +
+                    (ossim_uint64)col));
+}
+
+void ossimPlanetGridUtility::getPixelScaleAsDegrees(double& dx,
+                                                    double& dy,
+                                                    ossim_uint32 level,
+                                                    ossim_uint64 row,
+                                                    ossim_uint64 col)const
+{
+   ossimUnitType pixelScaleUnits;
+   getPixelScale(dx, dy, pixelScaleUnits, level, row, col);
+
+   if(pixelScaleUnits != OSSIM_DEGREES)
+   {
+      ossimUnitConversionTool conversion(dx, pixelScaleUnits);
+      dx = conversion.getValue(OSSIM_DEGREES);
+      conversion.setValue(dy, pixelScaleUnits);
+      dy = conversion.getValue(OSSIM_DEGREES);
+   }
+}
+
+void ossimPlanetGridUtility::getPixelScaleAsMeters(double& dx,
+                                                   double& dy,
+                                                   ossim_uint32 level,
+                                                   ossim_uint64 row,
+                                                   ossim_uint64 col)const
+{
+   ossimUnitType pixelScaleUnits;
+   getPixelScale(dx, dy, pixelScaleUnits, level, row, col);
+
+   if(pixelScaleUnits != OSSIM_METERS)
+   {
+      ossimUnitConversionTool conversion(dx, pixelScaleUnits);
+      dx = conversion.getValue(OSSIM_METERS);
+      conversion.setValue(dy, pixelScaleUnits);
+      dy = conversion.getValue(OSSIM_METERS);
+   }
+}
+      
+void ossimPlanetGridUtility::mapToRowCol(ossim_uint64& targetRow,
+                                         ossim_uint64& targetCol,
+                                         ossim_uint32  targetLevel,
+                                         ossim_uint32  srcLevel,
+                                         ossim_uint64  srcRow,
+                                         ossim_uint64  srcCol)const
+{
+   if(targetLevel > srcLevel)
+   {
+      ossim_uint32 diff = targetLevel-srcLevel;
+      targetRow = srcRow<<diff;
+      targetCol = srcCol<<diff;
+   }
+   else if(targetLevel < srcLevel)
+   {
+      ossim_uint32 diff = srcLevel-targetLevel;
+      targetRow = srcRow>>diff;
+      targetCol = srcCol>>diff;
+   }
+   else
+   {
+      targetRow = srcRow;
+      targetCol = srcCol;
+   }
+}
+
+void ossimPlanetGridUtility::getGeographicLonCrossings(std::vector<osg::Vec2d>& minMaxPairs,
+                                                       ossim_uint32 level,
+                                                       ossim_uint64 row,
+                                                       ossim_uint64 col)const
+{
+   if(!crossesGeographicBounds(level, row, col))
+   {
+      double minLat, minLon, maxLat, maxLon;
+      getLatLonBounds(minLat, minLon, maxLat, maxLon, level, row, col);
+      minMaxPairs.push_back(osg::Vec2d(minLon, maxLon));
+   }
+   else
+   {
+      osg::Vec3d ul, ur, lr, ll;
+      getLatLonCorners(ul, ur, lr, ll, level, row, col);
+      osg::Vec2d pt;
+      pt[0] = -180.0;
+      pt[1] = -180.0;
+      if(ul[ossimPlanetGridUtility::LON] < FLT_EPSILON)
+      {
+         if(ul[ossimPlanetGridUtility::LON] > pt[1])
+         {
+            pt[1] = ul[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(ur[ossimPlanetGridUtility::LON] < FLT_EPSILON)
+      {
+         if(ur[ossimPlanetGridUtility::LON] > pt[1])
+         {
+            pt[1] = ur[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(lr[ossimPlanetGridUtility::LON] < FLT_EPSILON)
+      {
+         if(lr[ossimPlanetGridUtility::LON] > pt[1])
+         {
+            pt[1] = lr[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(ll[ossimPlanetGridUtility::LON] < FLT_EPSILON)
+      {
+         if(ll[ossimPlanetGridUtility::LON] > pt[1])
+         {
+            pt[1] = ll[ossimPlanetGridUtility::LON];
+         }
+      }
+      minMaxPairs.push_back(pt);
+      
+      pt[0] = 180.0;
+      pt[1] = 180.0;
+      if(ul[ossimPlanetGridUtility::LON] > -FLT_EPSILON)
+      {
+         if(ul[ossimPlanetGridUtility::LON] < pt[0])
+         {
+            pt[0] = ul[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(ur[ossimPlanetGridUtility::LON] > -FLT_EPSILON)
+      {
+         if(ur[ossimPlanetGridUtility::LON] < pt[0])
+         {
+            pt[0] = ur[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(lr[ossimPlanetGridUtility::LON] > -FLT_EPSILON)
+      {
+         if(lr[ossimPlanetGridUtility::LON] < pt[0])
+         {
+            pt[0] = lr[ossimPlanetGridUtility::LON];
+         }
+      }
+      if(ll[ossimPlanetGridUtility::LON] > -FLT_EPSILON)
+      {
+         if(ll[ossimPlanetGridUtility::LON] < pt[0])
+         {
+            pt[0] = ll[ossimPlanetGridUtility::LON];
+         }
+      }
+      minMaxPairs.push_back(pt);
+   }
+}
+
+bool ossimPlanetGridUtility::crossesGeographicBounds(ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col)const
+{
+   osg::Vec3d ul;
+   osg::Vec3d ur;
+   osg::Vec3d lr;
+   osg::Vec3d ll;
+
+   getLatLonCorners(ul, ur, lr, ll, level, row, col);
+
+   if((std::abs(ul[ossimPlanetGridUtility::LON]-ur[ossimPlanetGridUtility::LON])>180.0)||
+      (std::abs(ur[ossimPlanetGridUtility::LON]-lr[ossimPlanetGridUtility::LON])>180.0)||
+      (std::abs(lr[ossimPlanetGridUtility::LON]-ll[ossimPlanetGridUtility::LON])>180.0)||
+      (std::abs(ll[ossimPlanetGridUtility::LON]-ul[ossimPlanetGridUtility::LON])>180.0))
+   {
+      return true;
+   }
+//    std::cout << "ul-ur = " << (ul[ossimPlanetGridUtility::LON]-ur[ossimPlanetGridUtility::LON]) << std::endl;
+//    std::cout << "ur-lr = " << (ur[ossimPlanetGridUtility::LON]-lr[ossimPlanetGridUtility::LON]) << std::endl;
+//    std::cout << "lr-ll = " << (lr[ossimPlanetGridUtility::LON]-ll[ossimPlanetGridUtility::LON]) << std::endl;
+//    std::cout << "ll-ul = " << (ll[ossimPlanetGridUtility::LON]-ul[ossimPlanetGridUtility::LON]) << std::endl;
+//    if((std::abs(ul[ossimPlanetGridUtility::LON] -
+//                 ur[ossimPlanetGridUtility::LON]) > 200.0)||
+//       (std::abs(ur[ossimPlanetGridUtility::LON] -
+//                 lr[ossimPlanetGridUtility::LON]) > 200.0)||
+//       (std::abs(lr[ossimPlanetGridUtility::LON] -
+//                 ll[ossimPlanetGridUtility::LON]) > 200.0)||
+//       (std::abs(ll[ossimPlanetGridUtility::LON] -
+//                 ul[ossimPlanetGridUtility::LON]) > 200.0))
+//    {
+//       return true; 
+//    }
+
+   return false;
+}
+
+void ossimPlanetGridUtility::getWidthHeightInDegrees(double& deltaX,
+                                                     double& deltaY,
+                                                     ossim_uint32 level,
+                                                     ossim_uint64 row,
+                                                     ossim_uint64 col)const
+{
+
+   osg::Vec3d ul;
+   osg::Vec3d ur;
+   osg::Vec3d lr;
+   osg::Vec3d ll;
+
+   getLatLonCorners(ul, ur, lr, ll, level, row, col);
+   ul[2] = 0;
+   ur[2] = 0;
+   lr[2] = 0;
+   ll[2] = 0;
+   deltaX = ossim::max((ul-ur).length(), (ll-lr).length());
+   deltaY = ossim::max((ul-ll).length(), (ur-lr).length());
+}
+
+void ossimPlanetGridUtility::getLatLonCorners(osg::Vec3d& ul,
+                                              osg::Vec3d& ur,
+                                              osg::Vec3d& lr,
+                                              osg::Vec3d& ll,
+                                              ossim_uint32 level,
+                                              ossim_uint32 row,
+                                              ossim_uint32 col)const
+{
+   ossimPlanetGridUtility::GridPoint gPoint;
+   getCenterGridPoint(gPoint,
+                      level, row, col);
+   const osg::Vec3d& gridPoint = gPoint.theGlobalGridPoint;
+   ossimPlanetGridUtility::GridPoint p(gPoint);
+   double xSpacing, ySpacing;
+   getGridSpacing(xSpacing, ySpacing, level, row, col);
+
+   double xHalf = xSpacing*.5;
+   double yHalf = ySpacing*.5;
+   p.theGlobalGridPoint = osg::Vec3d(gridPoint[ossimPlanetGridUtility::LAT] - yHalf,
+                                     gridPoint[ossimPlanetGridUtility::LON] - xHalf,
+                                     gridPoint[ossimPlanetGridUtility::HGT]);
+   getLatLon(ul,
+             p);
+   
+   p.theGlobalGridPoint = osg::Vec3d(gridPoint[ossimPlanetGridUtility::LAT] + yHalf,
+                                     gridPoint[ossimPlanetGridUtility::LON] - xHalf,
+                                     gridPoint[ossimPlanetGridUtility::HGT]);
+   getLatLon(ur,
+             p);
+   
+   p.theGlobalGridPoint = osg::Vec3d(gridPoint[ossimPlanetGridUtility::LAT] + yHalf,
+                                     gridPoint[ossimPlanetGridUtility::LON] + xHalf,
+                                     gridPoint[ossimPlanetGridUtility::HGT]);
+   getLatLon(lr,
+             p);
+   
+   p.theGlobalGridPoint = osg::Vec3d(gridPoint[ossimPlanetGridUtility::LAT] - yHalf,
+                                     gridPoint[ossimPlanetGridUtility::LON] + xHalf,
+                                     gridPoint[ossimPlanetGridUtility::HGT]);
+   getLatLon(ll,
+             p);
+}
+
+void ossimPlanetGridUtility::getCenterLatLon(osg::Vec3d& center,
+                                             ossim_uint32 level,
+                                             ossim_uint32 row,
+                                             ossim_uint32 col)const
+{
+   ossimPlanetGridUtility::GridPoint centerPoint;
+   getCenterGridPoint(centerPoint,
+                      level,
+                      row,
+                      col);
+   getLatLon(center,
+             centerPoint);
+}
+
+
+void ossimPlanetGridUtility::getLatLonBounds(double& minLat,
+                                             double& minLon,
+                                             double& maxLat,
+                                             double& maxLon,
+                                             ossim_uint32 level,
+                                             ossim_uint64 row,
+                                             ossim_uint64 col)const
+{
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   createGridPoints(points,
+                    level,
+                    row,
+                    col,
+                    3,
+                    3);
+   minLat = 90.0;
+   maxLat = -90.0;
+   minLon = 180.0;
+   maxLon = -180.0;
+
+   ossim_uint32 idx = 0;
+   ossim_uint32 size = points.size();
+   osg::Vec3d latLon;
+   for(idx = 0; idx < size; ++idx)
+   {
+      getLatLon(latLon, points[idx]);
+      minLat = ossim::min(minLat, latLon[ossimPlanetGridUtility::LAT]);
+      minLon = ossim::min(minLon, latLon[ossimPlanetGridUtility::LON]);
+      maxLat = ossim::max(maxLat, latLon[ossimPlanetGridUtility::LAT]);
+      maxLon = ossim::max(maxLon, latLon[ossimPlanetGridUtility::LON]);
+   }
+//    ossimPlanetGridUtility::GridPoint centerPoint;
+//    osg::Vec3d ul;
+//    osg::Vec3d ur;
+//    osg::Vec3d lr;
+//    osg::Vec3d ll;
+//    osg::Vec3d center=ul;
+//    ossimPlanetGridUtility::GridPoint point;
+//    getCenterGridPoint(centerPoint, level, row, col);
+//    getLatLon(center, centerPoint);
+//    getLatLonCorners(ul, ur, lr, ll, level, row, col);
+//    minLat = ossim::min(center[0], ossim::min(ll[0], ossim::min(lr[0], ossim::min(ul[0], ur[0]))));
+//    maxLat = ossim::max(center[0], ossim::max(ll[0], ossim::max(lr[0], ossim::max(ul[0], ur[0]))));
+//    minLon = ossim::min(center[1], ossim::min(ll[1], ossim::min(lr[1], ossim::min(ul[1], ur[1]))));
+//    maxLon = ossim::max(center[1], ossim::max(ll[1], ossim::max(lr[1], ossim::max(ul[1], ur[1]))));
+   
+}
+
+void ossimPlanetGridUtility::getCenterGridPoint(ossimPlanetGridUtility::GridPoint& point,
+                                              ossim_uint32 level,
+                                              ossim_uint32 row,
+                                              ossim_uint32 col)const
+{
+   ossim_uint64 localRow; // local to the face
+   ossim_uint64 localCol;
+   ossim_uint64 wide;
+   ossim_uint64 high;
+   double xSpacing, ySpacing;
+   getNumberOfTilesWideHighPerFace(wide, high, level);
+   getGridSpacing(xSpacing, ySpacing, level, row, col);
+   getLocalRowColumn(localRow, localCol,
+                     level, row, col);
+   
+   point.theLocalGridPoint[ossimPlanetGridUtility::GRIDX] = .5;
+   point.theLocalGridPoint[ossimPlanetGridUtility::GRIDY] = .5;
+   point.theLocalGridPoint[ossimPlanetGridUtility::GRIDZ] = 0;
+   point.theFace = getFace(level, row, col);
+
+   point.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = ((double)localCol/(double)wide) + (xSpacing*.5);
+   point.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = ((double)localRow/(double)high) + (ySpacing*.5);
+   point.theGlobalGridPoint[ossimPlanetGridUtility::GRIDZ] = 0.0;
+}
+
+void ossimPlanetGridUtility::getCenterGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                                                ossim_uint32 level,
+                                                const osg::Vec3d& latLon)const
+{
+   ossim_uint64 tilesWide, tilesHigh;
+   getGridPoint(gridPoint, latLon);
+   getNumberOfTilesWideHighPerFace(tilesWide, tilesHigh, level);
+   double normWide = 1.0/tilesWide;
+   double normHigh = 1.0/tilesHigh;
+
+   ossim_uint32 col = (ossim_uint32)(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX]/normWide);
+   ossim_uint32 row = (ossim_uint32)(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY]/normHigh);
+
+   getCenterGridPoint(gridPoint,
+                      level,
+                      row,
+                      col);
+}
+
+void ossimPlanetGridUtility::createGridPoints(std::vector<ossimPlanetGridUtility::GridPoint>& points,
+                                              ossim_uint32 level,
+                                              ossim_uint64 row,
+                                              ossim_uint64 col,
+                                              ossim_uint32 rows,
+                                              ossim_uint32 cols)const
+{
+   ossim_uint64 wide;
+   ossim_uint64 high;
+   ossim_uint64 localRow;
+   ossim_uint64 localCol;
+   ossim_uint32 face = getFace(level, row, col);
+   ossim_uint32 idx=0;
+   ossim_uint32 rowIdx = 0;
+   ossim_uint32 colIdx = 0;
+   getLocalRowColumn(localRow, localCol,
+                     level, row, col);
+   getNumberOfTilesWideHighPerFace(wide, high, level);
+
+   ossim_float64 globalColTOrigin = (double)localCol/(double)(wide);
+   ossim_float64 globalRowTOrigin = (double)localRow/(double)(high);
+   ossim_float64 spacingCol       = (1.0/(double)wide)/(cols-1);
+   ossim_float64 spacingRow       = (1.0/(double)high)/(rows-1);
+   ossim_uint32 size = (rows)*(cols);
+   if(points.size() != size)
+   {
+      points.resize(size);
+   }
+  ossimPlanetGridUtility::GridPoint* pointList = &points.front();
+
+   double rowT = globalRowTOrigin;
+   for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+   {
+      double localRowT  = ((double)rowIdx/((double)rows-1));
+      double colT = globalColTOrigin;
+      for(colIdx = 0; colIdx < cols; ++colIdx)
+      {
+         pointList[idx].theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = colT; 
+         pointList[idx].theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = rowT;
+         pointList[idx].theGlobalGridPoint[ossimPlanetGridUtility::GRIDZ] = 0.0;
+         
+         pointList[idx].theLocalGridPoint[ossimPlanetGridUtility::GRIDX] = (double)colIdx/((double)cols-1.0);
+         pointList[idx].theLocalGridPoint[ossimPlanetGridUtility::GRIDY] = localRowT;
+         pointList[idx].theLocalGridPoint[ossimPlanetGridUtility::GRIDZ] = 0.0;
+
+         pointList[idx].theFace = face;
+         ++idx;
+         colT += spacingCol;
+      }
+      rowT += spacingRow;
+   }
+}
+
+void ossimPlanetGridUtility::getGridSpacing(double& xSpacing,
+                                            double& ySpacing,
+                                            ossim_uint32 level,
+                                            ossim_uint64 /*row*/,
+                                            ossim_uint64 /*col*/)const
+{
+   ossim_uint64 wide;
+   ossim_uint64 high;
+   getNumberOfTilesWideHighPerFace(wide, high, level);
+   xSpacing       = 1.0/(double)wide;
+   ySpacing       = 1.0/(double)high;
+   
+}
+
+void ossimPlanetGridUtility::getNumberOfTilesWideHigh(ossim_uint64 &wide,
+                                                      ossim_uint64 &high,
+                                                      ossim_uint32 level)const
+{
+   wide = (ossim_uint64)1<<(ossim_uint64)level;
+   high = (ossim_uint64)1<<(ossim_uint64)level;
+
+   wide*=getNumberOfFaces();
+}
+
+void ossimPlanetGridUtility::getLocalRowColumn(ossim_uint64& localRow,
+                                               ossim_uint64& localCol,
+                                               ossim_uint32 level,
+                                               ossim_uint64 row,
+                                               ossim_uint64 col)const
+{
+   ossim_uint64 wide;
+   ossim_uint64 high;
+   getNumberOfTilesWideHighPerFace(wide, high, level);
+   ossim_uint32 face = getFace(level, row, col);
+
+   localRow = row;
+   localCol = col - face*wide;
+}
+
+ossim_uint32 ossimPlanetGridUtility::getFace(ossim_uint32 level,
+                                             ossim_uint64 /*row*/,
+                                             ossim_uint64 col)const
+{
+   return (col >> level);
+   
+}
+
+void ossimPlanetGridUtility::getNumberOfTilesWideHighPerFace(ossim_uint64 &wide,
+                                                             ossim_uint64 &high,
+                                                             ossim_uint32 level)const
+{
+   wide = (ossim_uint64)1<<(ossim_uint64)level;
+   high = (ossim_uint64)1<<(ossim_uint64)level;
+}
+
+ossim_uint64 ossimPlanetGridUtility::getNumberOfTiles(ossim_uint32 level)const
+{
+   ossim_uint64 wide;
+   ossim_uint64 high;
+
+   getNumberOfTilesWideHigh(wide, high, level);
+
+   return ((ossim_uint64)wide * (ossim_uint64)high);
+}
+
+
+ossim_uint64 ossimPlanetGridUtility::getTotalNumberOfTiles(ossim_uint32 level)const
+{
+   ossim_uint64 result = 0;
+   ossim_uint32 idx=0;
+
+   for(idx = 0; idx <= level; ++idx)
+   {
+      result += getNumberOfTiles(idx);
+   }
+
+   return result;
+}
+
+
+ossim_uint32 ossimPlanetGridUtility::getTileWidth()const
+{
+   return theTileWidth;
+}
+
+ossim_uint32 ossimPlanetGridUtility::getTileHeight()const
+{
+   return theTileHeight;
+}
+
+void ossimPlanetGridUtility::setTileWidthHeight(ossim_uint32 tileWidth,
+                                                ossim_uint32 tileHeight)
+{
+   theTileWidth  = tileWidth;
+   theTileHeight = tileHeight;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIconGeom.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIconGeom.cpp
new file mode 100644
index 0000000..0988738
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIconGeom.cpp
@@ -0,0 +1,157 @@
+#include <ossimPlanet/ossimPlanetIconGeom.h>
+#include <iostream>
+
+ossimPlanetIconGeom::ossimPlanetIconGeom( const osg::Vec3d& corner,
+                                          const osg::Vec3d& width,
+                                          const osg::Vec3d& height)
+{
+   setUseDisplayList(false);
+   setupGeom(corner, width, height);
+   theAlpha = 1.0;
+}
+
+void ossimPlanetIconGeom::setTexture(osg::ref_ptr<osg::Image> img)
+{
+   if(!theTexture.valid())
+   {
+      theTexture = new osg::Texture2D;
+      theTexture->setResizeNonPowerOfTwoHint(false);
+      theTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+      theTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+   }
+   theTexture->setImage(img.get());   
+}
+
+void ossimPlanetIconGeom::setTexture(osg::ref_ptr<osg::Texture2D> texture)
+{
+   theTexture = texture.get();
+   getOrCreateStateSet()->setTextureAttributeAndModes(0,theTexture.get(),osg::StateAttribute::ON);   
+}
+
+void ossimPlanetIconGeom::resetToUnitGeometry()
+{
+   setGeometry(osg::Vec3d(-.5,0.0,-.5),
+               osg::Vec3d(1.0,0.0,0.0),
+               osg::Vec3d(0.0,0.0,1.0));
+}
+
+
+void ossimPlanetIconGeom::setGeometry(const osg::Vec3d& corner,
+                                      const osg::Vec3d& width,
+                                      const osg::Vec3d& height)
+{
+   osg::ref_ptr<osg::Vec3dArray> coords = dynamic_cast<osg::Vec3dArray*>(getVertexArray());
+   if(coords.valid())
+   {
+      (*coords)[0] = corner;
+      (*coords)[1] = corner+width;
+      (*coords)[2] = corner+width+height;
+      (*coords)[3] = corner+height;
+      setVertexArray(coords.get());
+   }
+   osg::ref_ptr<osg::Vec3Array> norms = dynamic_cast<osg::Vec3Array*>(getNormalArray());
+   if(norms.valid())
+   {
+      (*norms)[0] = width^height;
+      (*norms)[0].normalize();
+      setNormalArray(norms.get());
+   }
+}
+
+void ossimPlanetIconGeom::drawImplementation(osg::RenderInfo& renderInfo) const
+{
+   osg::Vec4 save = (*theColorArray)[0];
+   (*theColorArray)[0][3] = theAlpha;
+   osg::Geometry::drawImplementation(renderInfo);
+   (*theColorArray)[0] = save;
+}
+
+void ossimPlanetIconGeom::setupGeom(const osg::Vec3d& corner,
+                                    const osg::Vec3d& width,
+                                    const osg::Vec3d& height)
+{
+   osg::Vec3dArray* coords = new osg::Vec3dArray(4);
+   (*coords)[0] = corner;
+   (*coords)[1] = corner+width;
+   (*coords)[2] = corner+width+height;
+   (*coords)[3] = corner+height;
+   setVertexArray(coords);
+   
+   osg::Vec3dArray* norms = new osg::Vec3dArray(1);
+   (*norms)[0] = width^height;
+   (*norms)[0].normalize();
+   
+   setNormalArray(norms);
+   setNormalBinding(osg::Geometry::BIND_OVERALL);
+   theColorArray = new osg::Vec4dArray;
+   theColorArray->push_back(osg::Vec4(1.0,
+                              1.0,
+                              1.0,
+                              1.0));
+   setColorBinding(osg::Geometry::BIND_OVERALL);
+   setColorArray(theColorArray.get());
+   
+   osg::Vec2dArray* tcoords = new osg::Vec2dArray(4);
+   (*tcoords)[0].set(0.0,0.0);
+   (*tcoords)[1].set(1.0,0.0);
+   (*tcoords)[2].set(1.0,1.0);
+   (*tcoords)[3].set(0.0,1.0);
+   setTexCoordArray(0,tcoords);
+   addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
+   osg::StateSet* stateset = new osg::StateSet;
+   theTexture = new osg::Texture2D;
+   theTexture->setResizeNonPowerOfTwoHint(false);
+   stateset->setTextureAttributeAndModes(0,theTexture.get(),osg::StateAttribute::ON);
+   setStateSet(stateset);
+}
+
+void ossimPlanetIconGeom::setTextureCoordinatesGivenPixels(int originX,
+                                                           int originY,
+                                                           int pixelWidth,
+                                                           int pixelHeight)
+{
+   if(theTexture.valid())
+   {
+      float w  = theTexture->getTextureWidth();
+      float h  = theTexture->getTextureHeight();
+      osg::ref_ptr<osg::Vec2Array> tcoords = dynamic_cast<osg::Vec2Array*>(getVertexArray());
+      float cornertx = (float)originX/w;
+      float cornerty = (float)originY/h;
+      
+      (*tcoords)[0].set(cornertx, cornerty);
+      (*tcoords)[1].set(cornertx+pixelWidth/w, cornerty);
+      (*tcoords)[2].set(cornertx+pixelWidth/w, cornerty+pixelHeight/h);
+      (*tcoords)[3].set(cornertx, cornerty+pixelHeight/h);
+      dirtyBound();
+   }
+}
+
+ossim_uint32 ossimPlanetIconGeom::width()const
+{
+   if(theTexture.valid())
+   {
+      theTexture->getTextureWidth();
+   }
+   return 0;
+}
+
+ossim_uint32 ossimPlanetIconGeom::height()const
+{
+   if(theTexture.valid())
+   {
+      theTexture->getTextureHeight();
+   }
+   
+   return 0;
+}
+
+
+osg::ref_ptr<osg::Texture2D> ossimPlanetIconGeom::texture()
+{
+   return theTexture;
+}
+
+const osg::ref_ptr<osg::Texture2D> ossimPlanetIconGeom::texture()const
+{
+   return theTexture;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetId.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetId.cpp
new file mode 100644
index 0000000..42104bd
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetId.cpp
@@ -0,0 +1,8 @@
+#include <ossimPlanet/ossimPlanetId.h>
+
+ossim_int64 ossimPlanetId::theInvalidId = -1;
+
+ossim_int64 ossimPlanetId::invalidId()
+{
+   return theInvalidId;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIdManager.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIdManager.cpp
new file mode 100644
index 0000000..6684896
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIdManager.cpp
@@ -0,0 +1,12 @@
+#include <ossimPlanet/ossimPlanetIdManager.h>
+#include <OpenThreads/ScopedLock>
+
+ossimPlanetId ossimPlanetIdManager::theCurrentId = 0;
+ossimPlanetReentrantMutex ossimPlanetIdManager::theMutex;
+
+ossimPlanetId ossimPlanetIdManager::nextId()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   
+   return ++theCurrentId;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetImage.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetImage.cpp
new file mode 100644
index 0000000..8499993
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetImage.cpp
@@ -0,0 +1,1157 @@
+#include <iostream>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <OpenThreads/ScopedLock>
+#include <ossim/imaging/ossimImageHandlerRegistry.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/base/ossimHsiVector.h>
+#include <ossim/base/ossimRgbVector.h>
+#include <osgDB/ReadFile>
+//#define OSGPLANET_ENABLE_ALLOCATION_COUNT
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static ossim_uint32 imageCount = 0;
+#endif
+
+ossimPlanetImage::ossimPlanetImage()
+:osg::Image(),
+theState(ossimPlanetImageStateType_NONE),
+thePixelStatus(ossimPlanetImagePixelStatus_EMPTY),
+thePadding(0)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++imageCount;
+   std::cout << "ossimPlanetImage2D count = " << imageCount << std::endl;
+#endif
+}
+
+ossimPlanetImage::ossimPlanetImage(const osg::Image& src)
+:osg::Image(src),
+theState(ossimPlanetImageStateType_NONE),
+thePixelStatus(ossimPlanetImagePixelStatus_EMPTY),
+thePadding(0)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++imageCount;
+   std::cout << "ossimPlanetImage2D count = " << imageCount << std::endl;
+#endif
+}
+
+ossimPlanetImage::ossimPlanetImage(const ossimPlanetTerrainTileId& id)
+:osg::Image(),
+theState(ossimPlanetImageStateType_NONE),
+theTileId(id),
+thePixelStatus(ossimPlanetImagePixelStatus_EMPTY),
+thePadding(0)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++imageCount;
+   std::cout << "ossimPlanetImage2D count = " << imageCount << std::endl;
+#endif
+}
+
+ossimPlanetImage::ossimPlanetImage(const ossimPlanetImage& image, 
+const osg::CopyOp& copyop)
+:osg::Image(image,copyop),
+theState(image.theState),
+theTileId(image.theTileId),
+thePixelStatus(image.thePixelStatus),
+theMinValue(image.theMinValue),
+theMaxValue(image.theMaxValue),
+thePadding(image.thePadding)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++imageCount;
+   std::cout << "ossimPlanetImage2D count = " << imageCount << std::endl;
+#endif
+}
+
+ossimPlanetImage::~ossimPlanetImage()
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   --imageCount;
+   std::cout << "ossimPlanetImage2D count = " << imageCount << std::endl;
+#endif
+}
+
+void ossimPlanetImage::stripPadding()
+{
+   if(padding() > 0)
+   {
+      osg::ref_ptr<ossimPlanetImage> tempImage = new ossimPlanetImage(*this);
+      allocateImage(widthWithoutPadding(), 
+                    heightWithoutPadding(), 
+                    1,
+                    getPixelFormat(), 
+                    getDataType(), 
+                    getPacking());
+      setPadding(0);
+      tempImage->copyTo(tempImage->padding(), tempImage->padding(), this);
+   }
+}
+
+int ossimPlanetImage::getNumberOfComponents()const
+{
+   return computeNumComponents(getPixelFormat());
+}
+
+int ossimPlanetImage::getHeight()const
+{
+   return t();
+}
+
+int ossimPlanetImage::getWidth()const
+{
+   return s();
+}
+
+void ossimPlanetImage::setId(const ossimPlanetTerrainTileId& id)
+{
+   theTileId = id;
+}
+
+const ossimPlanetTerrainTileId& ossimPlanetImage::tileId()const
+{
+   return theTileId;
+}
+
+ossimPlanetImage::ossimPlanetImageStateType ossimPlanetImage::getState()const
+{
+   return theState;
+}
+
+void ossimPlanetImage::setState(ossimPlanetImageStateType stateType)
+{
+   theState = stateType;
+}
+
+OpenThreads::Mutex& ossimPlanetImage::mutex()const
+{
+   return theMutex;
+}
+
+void ossimPlanetImage::setPixelStatus()
+{
+   GLint internalFormat = getInternalTextureFormat();
+   switch(internalFormat)
+   {
+      case GL_RGBA:
+      {
+         unsigned char* dataPtr = data();
+         unsigned int w = s();
+         unsigned int h = t();
+         unsigned int area = w*h;
+         thePixelStatus = ossimPlanetImagePixelStatus_FULL;
+         bool hasFull = false;
+         bool hasTranslucent = false;
+         bool hasTransparent = false;
+         if(!dataPtr) return;
+         
+         for(unsigned int idx = 0; idx < area;++idx)
+         {
+            if(dataPtr[3] == 0)
+            {
+               hasTransparent = true;
+            }
+            if(dataPtr[3] == 255)
+            {
+               hasFull = true;
+            }
+            else
+            {
+               hasTranslucent = true;
+            }
+            if((hasTranslucent) ||
+               (hasFull&&hasTransparent))
+            {
+               break;
+            }
+            dataPtr+=4;
+         }
+         if(hasTranslucent)
+         {
+            thePixelStatus = ossimPlanetImagePixelStatus_PARTIAL;
+         }
+         else if(hasTransparent&&hasFull)
+         {
+            thePixelStatus = ossimPlanetImagePixelStatus_PARTIAL;
+         }
+         else if(hasTransparent)
+         {
+            thePixelStatus = ossimPlanetImagePixelStatus_EMPTY;
+         }
+         else if(hasFull)
+         {
+            thePixelStatus = ossimPlanetImagePixelStatus_FULL;
+         }
+         break;
+      }
+      default:
+      {
+         thePixelStatus = ossimPlanetImagePixelStatus_FULL;
+      }
+   }
+}
+
+void ossimPlanetImage::setPixelStatus(ossimPlanetImagePixelStatus pixelStatus)
+{
+   thePixelStatus = pixelStatus;
+}
+
+ossimPlanetImage::ossimPlanetImagePixelStatus ossimPlanetImage::getPixelStatus()const
+{
+   return thePixelStatus;
+}
+
+void ossimPlanetImage::applyBrightnessContrast(ossim_float32 brightness, ossim_float32 contrast)
+{
+  GLint internalFormat = getInternalTextureFormat();
+  ossim_uint32 width  = s();
+  ossim_uint32 height = t();
+  ossim_uint32 inputBands = 4;
+  switch(internalFormat)
+  {
+     case GL_RGBA:
+     {
+       ossim_float32 normBrightness = brightness/255.0;
+       ossim_uint8* inputPtr = (ossim_uint8*)data();
+       ossim_uint32 size = width*height;
+       ossim_uint32 idx = 0;
+       inputBands = 4;
+       for(;idx < size; ++idx)
+       {
+         if(inputPtr[3] > 0.0)
+         {
+           ossimHsiVector hsi(ossimRgbVector(inputPtr[0], inputPtr[1], inputPtr[2]));
+
+           ossim_float32 i = hsi.getI()*contrast + normBrightness;
+           //           i = ossim::clamp(i, OSSIM_DEFAULT_MIN_PIX_NORM_FLOAT, 1.0f);
+           i = ossim::clamp(i, 0.0f, 1.0f);
+           hsi.setI(i);
+           ossimRgbVector newRgb(hsi);
+           inputPtr[0] = newRgb.getR();
+           inputPtr[1] = newRgb.getG();
+           inputPtr[2] = newRgb.getB();
+         }
+         inputPtr+=inputBands;
+       }
+       break;
+     }
+     default:
+     {
+       break;
+     }
+  }
+}
+
+ossimRefPtr<ossimImageData> ossimPlanetImage::toOssimImage()const
+{
+   ossimRefPtr<ossimImageData> imageData;
+   GLint internalFormat = getInternalTextureFormat();
+   ossim_uint32 inputBands = 3;
+   if(internalFormat == GL_RGBA)
+   {
+      inputBands = 4;
+   }
+
+   if(!data()) return 0;
+   ossim_uint32 width  = s();
+   ossim_uint32 height = t();
+
+   switch(internalFormat)
+   {
+      case GL_RGB:
+      case GL_RGBA:
+      {
+         if((internalFormat == GL_RGB)||
+            (internalFormat == GL_RGBA))
+         {
+            imageData = new ossimImageData(0,
+                                           OSSIM_UINT8,
+                                           3,
+                                           width,
+                                           height);
+            imageData->initialize();
+            const ossim_uint8* inputPtr = (const ossim_uint8*)data();
+            ossim_uint8* outputPtr[3];
+            outputPtr[0] = (ossim_uint8*)(imageData->getBuf(0));
+            outputPtr[1] = (ossim_uint8*)(imageData->getBuf(1));
+            outputPtr[2] = (ossim_uint8*)(imageData->getBuf(2));
+            ossim_uint32 idx = 0;
+            ossim_uint32 size = width*height;
+            if(internalFormat != GL_RGBA)
+            {
+               for(idx =0; idx < size; ++idx)
+               {
+                  outputPtr[0][idx] = inputPtr[0];
+                  outputPtr[1][idx] = inputPtr[1];
+                  outputPtr[2][idx] = inputPtr[2];
+                  inputPtr+=inputBands;
+               }
+            }
+            else
+            {
+               for(idx =0; idx < size; ++idx)
+               {
+                  if(inputPtr[3] == 0)
+                  {
+                     outputPtr[0][idx] = 0;
+                     outputPtr[1][idx] = 0;
+                     outputPtr[2][idx] = 0;
+                     
+                  }
+                  else
+                  {
+                     outputPtr[0][idx] = inputPtr[0];
+                     outputPtr[1][idx] = inputPtr[1];
+                     outputPtr[2][idx] = inputPtr[2];
+                  }
+                  inputPtr+=inputBands;
+               }
+            }
+            imageData->validate();
+         }
+         break;
+      }
+      case GL_LUMINANCE:
+      {
+         if(getDataType() == GL_FLOAT)
+         {
+            imageData = new ossimImageData(0,
+                                           OSSIM_FLOAT32,
+                                           1,
+                                           width,
+                                           height);
+            imageData->initialize();
+            const ossim_float32* inputPtr = (const ossim_float32*)data();
+            ossim_float32* outputPtr = (ossim_float32*)imageData->getBuf();
+            ossim_uint32 idx = 0;
+            ossim_uint32 size = width*height;
+            for(idx =0; idx < size; ++idx)
+            {
+               *outputPtr = *inputPtr;
+               ++inputPtr;
+               ++outputPtr;
+            }
+            imageData->setDataObjectStatus(OSSIM_FULL);
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+
+   return imageData;
+}
+
+void ossimPlanetImage::fromOssimImage(ossimRefPtr<ossimImageData> data,
+                                      bool reassignNullFlag,
+                                      double nullValue)
+{
+   ossim_uint32 w = 0;
+   ossim_uint32 h = 0;
+   GLint internalFormat = GL_LUMINANCE;
+   GLenum pixelFormat   = GL_LUMINANCE;
+   GLenum type          = GL_FLOAT;
+   osg::Image::AllocationMode allocMode = osg::Image::USE_NEW_DELETE;
+   unsigned char* buf = 0;
+   ossim_uint32 validPixelCount = 0;
+   ossim_uint32 invalidPixelCount = 0;
+   if(data.valid())
+   {
+      w = data->getWidth();
+      h = data->getHeight();
+      switch(data->getScalarType())
+      {
+         case OSSIM_UINT8: // only support 1 to 3 band and will convert to RGBA gl type 
+         {
+            if(data->getNumberOfBands()>0)
+            {
+               ossim_uint8 nullPix = (ossim_uint8)data->getNullPix(0);
+               ossim_uint32 sizeInBytes = data->getSizePerBandInBytes()*4;
+               buf = new unsigned char[sizeInBytes];
+               unsigned char* bufPtr = buf;
+               
+               
+               memset(buf, 0, sizeInBytes);
+
+               if(data->getBuf()&&
+                  data->getDataObjectStatus() != OSSIM_EMPTY)
+               {
+                  unsigned char* dataBuf[3];
+
+                  dataBuf[0] = (unsigned char*)data->getBuf(0);
+                  if(data->getNumberOfBands() > 1)
+                  {
+                     dataBuf[1] = (unsigned char*)data->getBuf(1);
+                  }
+                  else
+                  {
+                     dataBuf[1] = (unsigned char*)data->getBuf(0);
+                  }
+                  if(data->getNumberOfBands() > 2)
+                  {
+                     dataBuf[2] = (unsigned char*)data->getBuf(2);
+                  }
+                  else
+                  {
+                     dataBuf[2] = (unsigned char*)data->getBuf(0);
+                  }
+                  ossim_uint32 area = data->getWidth()*data->getHeight();
+                  ossim_uint32 idx = 0;
+                  for(;idx < area; ++idx)
+                  {
+                     if((*dataBuf[0] != nullPix)||
+                        (*dataBuf[1] != nullPix)||
+                        (*dataBuf[2] != nullPix))
+                     {
+                        bufPtr[0] = *dataBuf[0];
+                        bufPtr[1] = *dataBuf[1];
+                        bufPtr[2] = *dataBuf[2];
+                        bufPtr[3] = 255;
+                        ++validPixelCount;
+                     }
+                     else
+                     {
+                       ++invalidPixelCount;
+                        bufPtr[3] = 0;
+                     }
+                     bufPtr+=4;
+                     ++dataBuf[0];
+                     ++dataBuf[1];
+                     ++dataBuf[2];
+                  }
+                  if(invalidPixelCount > 0)
+                  {
+                    thePixelStatus = validPixelCount > 0?ossimPlanetImagePixelStatus_PARTIAL:ossimPlanetImagePixelStatus_EMPTY;
+                  }
+                  else
+                  {
+                    thePixelStatus = ossimPlanetImagePixelStatus_FULL;
+                  }
+               }
+               else
+               {
+                 thePixelStatus = ossimPlanetImagePixelStatus_EMPTY;
+               }
+               internalFormat = GL_RGBA;
+               pixelFormat    = GL_RGBA;
+               type           = GL_UNSIGNED_BYTE;
+            }
+            break;
+         }
+         case OSSIM_FLOAT32: // only support 1 band 
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+            
+            ossim_float32* dataBuf = (ossim_float32*)data->getBuf();
+            ossim_float32 nullPix  = (ossim_float32)data->getNullPix(0);
+            ossim_float32 tempNullValue = nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            
+            break;
+         }
+         case OSSIM_SINT16: // only support 1 band
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+
+            ossim_sint16* dataBuf = (ossim_sint16*)data->getBuf();
+            ossim_sint16 nullPix  = (ossim_sint16)data->getNullPix(0);
+            ossim_float32 tempNullValue = (ossim_float32)nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            break;
+         }
+         case OSSIM_UINT16: // only support 1 band
+         case OSSIM_USHORT11: // only support 1 band
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+
+            ossim_uint16* dataBuf       = (ossim_uint16*)data->getBuf();
+            ossim_uint16 nullPix        = (ossim_uint16)data->getNullPix(0);
+            ossim_float32 tempNullValue = (ossim_float32)nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            break;
+         }
+         default:
+         {
+            // not supported yet
+            break;
+         }
+      }
+   }
+
+   if(buf)
+   {
+      setImage(w, h, 1, internalFormat, pixelFormat, type, buf, allocMode);
+   }
+}
+
+void ossimPlanetImage::fromOssimImageNoAlpha(ossimRefPtr<ossimImageData> data,
+                                             bool reassignNullFlag,
+                                             double nullValue)
+{
+   ossim_uint32 w = 0;
+   ossim_uint32 h = 0;
+   GLint internalFormat = GL_LUMINANCE;
+   GLenum pixelFormat   = GL_LUMINANCE;
+   GLenum type          = GL_FLOAT;
+   osg::Image::AllocationMode allocMode = osg::Image::USE_NEW_DELETE;
+   unsigned char* buf = 0;
+   if(data.valid())
+   {
+      w = data->getWidth();
+      h = data->getHeight();
+      switch(data->getScalarType())
+      {
+         case OSSIM_UINT8: // only support 1 to 3 band and will convert to RGBA gl type 
+         {
+            if(data->getNumberOfBands()>0)
+            {
+               ossim_uint8 nullPix = (ossim_uint8)data->getNullPix(0);
+               ossim_uint32 sizeInBytes = data->getSizePerBandInBytes()*3;
+               buf = new unsigned char[sizeInBytes];
+               unsigned char* bufPtr = buf;
+               
+               
+               memset(buf, 0, sizeInBytes);
+
+               if(data->getBuf()&&
+                  data->getDataObjectStatus() != OSSIM_EMPTY)
+               {
+                  unsigned char* dataBuf[3];
+
+                  dataBuf[0] = (unsigned char*)data->getBuf(0);
+                  if(data->getNumberOfBands() > 1)
+                  {
+                     dataBuf[1] = (unsigned char*)data->getBuf(1);
+                  }
+                  else
+                  {
+                     dataBuf[1] = (unsigned char*)data->getBuf(0);
+                  }
+                  if(data->getNumberOfBands() > 2)
+                  {
+                     dataBuf[2] = (unsigned char*)data->getBuf(2);
+                  }
+                  else
+                  {
+                     dataBuf[2] = (unsigned char*)data->getBuf(0);
+                  }
+                  ossim_uint32 area = data->getWidth()*data->getHeight();
+                  ossim_uint32 idx = 0;
+                  for(;idx < area; ++idx)
+                  {
+                     if((*dataBuf[0] != nullPix)||
+                        (*dataBuf[1] != nullPix)||
+                        (*dataBuf[2] != nullPix))
+                     {
+                        bufPtr[0] = *dataBuf[0];
+                        bufPtr[1] = *dataBuf[1];
+                        bufPtr[2] = *dataBuf[2];
+                     }
+                     bufPtr+=3;
+                     ++dataBuf[0];
+                     ++dataBuf[1];
+                     ++dataBuf[2];
+                  }
+                  internalFormat = GL_RGB;
+                  pixelFormat    = GL_RGB;
+                  type           = GL_UNSIGNED_BYTE;
+               }
+            }
+            break;
+         }
+         case OSSIM_FLOAT32: // only support 1 band 
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+            
+            ossim_float32* dataBuf = (ossim_float32*)data->getBuf();
+            ossim_float32 nullPix  = (ossim_float32)data->getNullPix(0);
+            ossim_float32 tempNullValue = nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            
+            break;
+         }
+         case OSSIM_SINT16: // only support 1 band
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+
+            ossim_sint16* dataBuf = (ossim_sint16*)data->getBuf();
+            ossim_sint16 nullPix  = (ossim_sint16)data->getNullPix(0);
+            ossim_float32 tempNullValue = (ossim_float32)nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            break;
+         }
+         case OSSIM_UINT16: // only support 1 band
+         case OSSIM_USHORT11: // only support 1 band
+         {
+            ossim_float32* bufPtr = new ossim_float32[w*h];
+            buf = reinterpret_cast<unsigned char*>(bufPtr);
+
+            memset(buf, 0, w*h*sizeof(ossim_float32));
+
+            ossim_uint16* dataBuf       = (ossim_uint16*)data->getBuf();
+            ossim_uint16 nullPix        = (ossim_uint16)data->getNullPix(0);
+            ossim_float32 tempNullValue = (ossim_float32)nullValue;
+            
+            ossim_uint32 idx = 0;
+            ossim_uint32 area = w*h;
+            
+            if(dataBuf)
+            {
+               for(;idx < area; ++idx)
+               {
+                  *bufPtr = *dataBuf;
+                  if(reassignNullFlag)
+                  {
+                     if(nullPix == *dataBuf)
+                     {
+                        *bufPtr = tempNullValue;
+                     }
+                  }
+                  ++bufPtr;
+                  ++dataBuf;
+               }
+            }
+            break;
+         }
+         default:
+         {
+            // not supported yet
+            break;
+         }
+      }
+   }
+
+   if(buf)
+   {
+      setImage(w, h, 1, internalFormat, pixelFormat, type, buf, allocMode);
+   }
+}
+
+osg::Image* ossimPlanetImage::readNewOsgImage(const ossimFilename& src,
+                                              bool flipVerticalFlag,
+                                              bool insertAlphaFlag)
+{
+   ossimRefPtr<ossimImageHandler> ih = ossimImageHandlerRegistry::instance()->open(ossimFilename(src));
+
+//    if(!ih.valid()) return 0;
+//    if(!ih.valid())
+//    {
+//       return osgDB::readImageFile(src);
+//    }
+//    else
+   if(ih.valid())
+   {
+      osg::ref_ptr<ossimPlanetImage> planetImage = new ossimPlanetImage;
+      ossimIrect rect                  = ih->getBoundingRect() ;
+      ossimRefPtr<ossimImageData> tile = ih->getTile(rect);
+      if(insertAlphaFlag)
+      {
+         planetImage->fromOssimImage(tile.get());
+      }
+      else
+      {
+         planetImage->fromOssimImageNoAlpha(tile.get());
+      }
+      if(flipVerticalFlag)
+      {
+         planetImage->flipVertical();
+      }
+      return new osg::Image(*(planetImage.get()), osg::CopyOp::DEEP_COPY_ALL);
+   }
+   
+   return 0;
+}
+
+ossimPlanetImage* ossimPlanetImage::scaleImagePowerOf2()const
+{
+   GLint internalFormat = getInternalTextureFormat();
+//   ossim_int32 oddW = getWidth()%2;
+//   ossim_int32 oddH = getHeight()%2;
+   switch(internalFormat)
+   {
+      case GL_LUMINANCE:
+      {
+         if(getDataType() == GL_FLOAT)
+         {
+            return scaleImagePowerOf2((ossim_float32)0.0);
+         }
+         break;
+      }
+   }
+   
+   return 0;
+}
+
+void ossimPlanetImage::copySubImageAndInsertPointsPowerOf2(int x, // starting x 
+                                                           int y, // starting y
+                                                           ossim_uint32 lengthx, // length x
+                                                           ossim_uint32 lengthy, // length y
+                                                           ossimPlanetImage* source)
+{
+   if(!source||!source->data()||(_pixelFormat != source->getPixelFormat())||
+      (getDataType()!=source->getDataType()))
+   {
+      return;
+   }
+   GLint internalFormat = getInternalTextureFormat();
+
+   switch(internalFormat)
+   {
+      case GL_LUMINANCE:
+      {
+         if(getDataType() == GL_FLOAT)
+         {
+            copySubImageAndInsertPointsPowerOf2((ossim_float32)0,
+                                                x,
+                                                y,
+                                                lengthx,
+                                                lengthy,
+                                                source);
+         }
+         break;
+      }
+   }
+}
+
+void ossimPlanetImage::copyTo(ossim_uint32 x, ossim_uint32 y, ossimPlanetImage* destination)const
+{
+   if(!destination||!data()||(_pixelFormat != destination->getPixelFormat())||
+      (getDataType()!=destination->getDataType()))
+   {
+      return;
+   }
+   GLint internalFormat = getInternalTextureFormat();
+   
+   switch(internalFormat)
+   {
+      case GL_LUMINANCE:
+      {
+         if(getDataType() == GL_FLOAT)
+         {
+            copyTo((ossim_float32)0,
+                 x,
+                 y,
+                 destination);
+         }
+         break;
+      }
+   }
+}
+
+template<class T>
+void ossimPlanetImage::copyTo(T dummy, ossim_uint32 x, ossim_uint32 y, ossimPlanetImage* destination)const
+{
+   ossim_uint32 outW = destination->getWidth();
+   ossim_uint32 outH = destination->getHeight();
+   ossim_uint32 inW = getWidth();
+   
+   T* destData = (T*)destination->data();
+   T* srcData  = (T*)data();
+   
+   srcData = srcData + inW*y + x;
+   
+   ossim_uint32 xidx = 0;
+   ossim_uint32 yidx = 0;
+   for(yidx = 0; yidx < outH; ++yidx)
+   {
+      for(xidx = 0; xidx < outW; ++xidx)
+      {
+         destData[xidx] = srcData[xidx];
+      }
+      destData+=outW;
+      srcData += inW;
+   }
+   destination->setMinMax(minValue(), maxValue());
+}
+
+template<class T>
+ossimPlanetImage* ossimPlanetImage::scaleImagePowerOf2(T dummy)const
+{
+   ossimPlanetImage* result = new ossimPlanetImage(tileId());
+   result->setPadding(padding());
+   result->setMinMax(minValue(), maxValue());
+   result->setId(tileId());
+   
+   //   ossim_uint32 outW = widthWithoutPadding()*2+2*padding() - ((ossim_int32)widthWithoutPadding()%2); 
+   //   ossim_uint32 outH = heightWithoutPadding()*2+2*padding()- ((ossim_int32)heightWithoutPadding()%2); 
+   ossim_uint32 outW = getWidth()*2 - ((ossim_int32)widthWithoutPadding()%2); 
+   ossim_uint32 outH = getHeight()*2- ((ossim_int32)heightWithoutPadding()%2); 
+   ossim_uint32 srcW = getWidth(); 
+//   ossim_uint32 srcH = getHeight();
+   ossim_uint32 inOriginY = 0;//padding();
+   ossim_uint32 inOriginX = 0;//padding();
+   ossim_uint32 outOriginX = 0;//result->padding();
+   ossim_uint32 outOriginY = 0;//result->padding();
+   // we will interpolate the padding differently if padding exists
+//      ossim_uint32 lengthX = outW - padding()*2; // now setup the bilinear interpolation length for x direction
+//      ossim_uint32 lengthY = outH - padding()*2; // now setup the bilinear interpolation length for y direction
+   ossim_uint32 lengthX = outW;// - padding(); // now setup the bilinear interpolation length for x direction
+   ossim_uint32 lengthY = outH;// - padding(); // now setup the bilinear interpolation length for y direction
+   result->allocateImage(outW, outH, 1, getPixelFormat(), getDataType(), getPacking());
+   
+   T* destData = (T*)result->data();
+   T* srcData  = (T*)data();
+
+   ossim_uint32 xidx = 0;
+   ossim_uint32 yidx = 0;
+   
+   ossim_uint32 inputOffsetY = 0;
+   ossim_uint32 inputOffset  = 0;
+   ossim_uint8  testLocation  = 0;
+   ossim_uint32 destOffset = outOriginY*outW + outOriginX;
+   // first resample the interior points that aren't padding points
+   //
+   for(yidx = 0; yidx < lengthY; ++yidx)
+   {
+      inputOffsetY = ((yidx>>1)+inOriginY)*srcW; // offset for padding along y
+      for(xidx = 0; xidx < lengthX; ++xidx)
+      {
+         inputOffset = inputOffsetY + ((xidx>>1)+inOriginX);
+         testLocation = ((yidx&1) << 1) | (xidx&1); // test even odd resampling
+         switch(testLocation)
+         {
+            case 0: // if none are odd then just copy the point over
+            {
+               destData[destOffset+xidx] = srcData[inputOffset];
+               break;
+            }
+            case 1: // if x is odd the do horizontal edge post
+            {
+               destData[destOffset+xidx] = (srcData[inputOffset] +
+                                            srcData[inputOffset+1])*.5;
+               break;
+            }
+            case 2: // if y is odd then do vertical edge post
+            {
+               destData[destOffset+xidx] = (srcData[inputOffset] +
+                                            srcData[inputOffset+srcW])*.5;
+               break;
+            }
+            case 3: // do center post if both bits are set
+            {
+               destData[destOffset+xidx] = (srcData[inputOffset] +
+                                            srcData[inputOffset+srcW]+
+                                            srcData[inputOffset+srcW+1]+
+                                            srcData[inputOffset+1]
+                                            )*.25;
+               break;
+            }
+            default:
+            {
+               destData[destOffset+xidx] = srcData[inputOffset];
+            }
+         }
+      }
+      destOffset += outW;
+   }
+   
+   result->setMinMax(minValue(), maxValue());
+   
+#if 0
+   // now scale the edges
+   //
+   destData = (T*)result->data();
+   srcData  = (T*)data();
+   T* rightDestData = (T*)result->data() + outW-1;
+   T* rightSrcData  = (T*)data() + srcW - 1;
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < outH; ++idx)
+   {
+      inputOffset = (idx>>1)*srcW;
+      testLocation = (idx&1); // test even odd resampling
+      destOffset = idx*outW;
+      switch(testLocation)
+      {
+         case 0: // if none are odd then just copy the point over
+         {
+            destData[destOffset]      = srcData[inputOffset];
+            rightDestData[destOffset] = rightSrcData[inputOffset];
+            break;
+         }
+         case 1: // if x is odd the do vertical edge post
+         {
+            destData[destOffset] = (srcData[inputOffset] +
+                                    srcData[inputOffset+srcW] )*.5;
+            rightDestData[destOffset] = (rightSrcData[inputOffset] +
+                                         rightSrcData[inputOffset + srcW])*.5;
+            break;
+         }
+      }
+   }
+   destData = (T*)result->data();
+   srcData  = (T*)data();
+   T* destDataTop = (T*)result->data() + (outH-1)*outW;
+   T* srcDataTop  = (T*)data() + (srcH-1)*srcW;
+   for(idx = 0; idx < outW; ++idx)
+   {
+      inputOffset = (idx>>1);
+      testLocation = (idx&1); // test even odd resampling
+      switch(testLocation)
+      {
+         case 0: // if none are odd then just copy the point over
+         {
+            destData[idx]    = srcData[inputOffset];
+            destDataTop[idx] = srcDataTop[inputOffset];
+            break;
+         }
+         case 1: // if x is odd the do horizontal edge post
+         {
+            destData[idx] = (srcData[inputOffset] +
+                             srcData[inputOffset+1])*.5;
+            destDataTop[idx] = (srcDataTop[inputOffset] +
+                                srcDataTop[inputOffset + 1])*.5;
+            break;
+         }
+      }
+   }
+#endif
+   return result;
+}
+
+template<class T>
+void ossimPlanetImage::copySubImageAndInsertPointsPowerOf2(T dummy,
+                                                   int x, // starting x 
+                                                   int y, // starting y
+                                                   ossim_uint32 lengthx, // length x
+                                                   ossim_uint32 lengthy, // length y
+                                                   ossimPlanetImage* source)
+{
+   ossim_uint32 srcWidth = source->s();
+   ossim_uint32 myWidth = s();
+   T* myData = (T*)data();
+   T* srcData = (T*)source->data();
+   
+   ossim_float64 minValue = 1.0/FLT_EPSILON;
+   ossim_float64 maxValue = -minValue;
+//   GLint internalFormat = getInternalTextureFormat();
+   
+   srcData = srcData + y*srcWidth + x;
+
+   //std::cout << "SRC W = " << source->s() << std::endl
+   //<< "SRC H = " << source->t() << std::endl;
+   //std::cout << "DEST W = " << s() << std::endl
+   //<< "DEST H = " << t() << std::endl;
+   // copy the shared points then go back through and fill in
+   // the holes with a bilinear estimate
+   //
+   ossim_uint32 idxY = 0;
+   ossim_uint32 idxX = 0;
+   ossim_uint32 myHeight = t();
+   ossim_uint32 inputOffsetY = 0;
+   ossim_uint32 inputOffset = 0;
+   ossim_uint8 testLocation=0;
+   for(idxY = 0; idxY < myHeight; ++idxY)
+   {
+      inputOffsetY = (idxY>>1)*srcWidth;
+      for(idxX = 0; idxX < myWidth; ++idxX)
+      {
+         inputOffset = inputOffsetY + (idxX>>1);
+         testLocation = ((idxY&1) << 1) | (idxX&1);
+         switch(testLocation)
+         {
+            case 0: // if none are odd then just copy the point over
+            {
+               *myData = srcData[inputOffset];
+               break;
+            }
+            case 1: // if x is odd the do horizontal edge post
+            {
+               *myData = (srcData[inputOffset] +
+                          srcData[inputOffset+1])*.5;
+               break;
+            }
+            case 2: // if y is odd then do vertical edge post
+            {
+               *myData = (srcData[inputOffset] +
+                          srcData[inputOffset+srcWidth])*.5;
+              break;
+            }
+            case 3: // do center post if both bits are set
+            {
+               *myData = (srcData[inputOffset] +
+                          srcData[inputOffset+srcWidth]+
+                          srcData[inputOffset+srcWidth+1]+
+                          srcData[inputOffset+1]
+                          )*.25;
+               break;
+            }
+            default:
+            {
+               *myData = srcData[inputOffset];
+            }
+               
+               
+         }
+         if(*myData > maxValue) maxValue = *myData;
+         if(*myData < minValue) minValue = *myData;
+         
+         ++myData;
+      }
+   }
+   
+   theMinValue.resize(1);
+   theMaxValue.resize(1);
+   theMinValue[0] = minValue;
+   theMaxValue[0] = maxValue;
+}
+
+osg::Vec2 ossimPlanetImage::deltas(ossim_int32 x,
+                                   ossim_int32 y)const
+{
+   osg::Vec2 delta(0.0,0.0);
+   GLint internalFormat = getInternalTextureFormat();
+   
+   // we only support single band float for delta lookups
+   if(internalFormat != GL_LUMINANCE) return delta;
+   if(getDataType()!=GL_FLOAT)
+   {
+      return delta;
+   }
+   
+   if (x==0)
+   {
+      delta.x() = (elevationValue(x+1,y)-elevationValue(x,y));
+   }
+   else if (x==getWidth()-1)
+   {
+      delta.x() = (elevationValue(x,y)-elevationValue(x-1,y));
+   }
+   else // assume 0<c<_numColumns-1
+   {
+      delta.x() = 0.5f*(elevationValue(x+1,y)-elevationValue(x-1,y));
+   }
+   
+   if (y==0)
+   {
+      delta.y() = (elevationValue(x,y+1)-elevationValue(x,y));
+   }
+   else if (y==getHeight()-1)
+   {
+      delta.y() = (elevationValue(x,y)-elevationValue(x,y-1));
+   }
+   else // assume 0<r<_numRows-1
+   {
+      delta.y() = 0.5f*(elevationValue(x,y+1)-elevationValue(x,y-1));
+   }
+   
+   return delta;
+}
+
+ossim_uint64 ossimPlanetImage::sizeInBytes()const
+{
+   return ((((ossim_uint64)getRowSizeInBytes())*((ossim_uint64)_t)*((ossim_uint64)_r))+
+           (ossim_uint64)sizeof(ossimPlanetImage));
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetInteractionController.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetInteractionController.cpp
new file mode 100644
index 0000000..9f02b9e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetInteractionController.cpp
@@ -0,0 +1,338 @@
+#include <algorithm>
+#include <fstream>
+
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+#include <ossimPlanet/ossimPlanetInteractionController.h>
+#include <ossim/base/ossimCommon.h>
+
+ossimPlanetInteractionController* ossimPlanetInteractionController::instance_ = NULL;
+
+ossimPlanetInteractionController::ossimPlanetInteractionController()
+{
+    setPathnameAndRegister(":iac");
+}
+
+ossimPlanetInteractionController::~ossimPlanetInteractionController()
+{
+    ossimPlanetActionRouter::instance()->unregisterReceiver(this);
+   deviceList_.clear();
+}
+
+void ossimPlanetInteractionController::registerDevice(ossimPlanetInputDevice* d)
+{
+    //     assert(d != NULL);
+    
+    if(!d) return;
+    
+    deviceList_.push_back(d);
+}
+
+void ossimPlanetInteractionController::unregisterDevice(ossimPlanetInputDevice* d)
+{
+    //     assert(d != NULL);
+    if(!d) return;
+    DeviceList::iterator i = find(deviceList_.begin(), deviceList_.end(), d);
+    if (i != deviceList_.end())
+        deviceList_.erase(i);
+}
+
+void ossimPlanetInteractionController::processPendingInputs()
+{
+    for (int i = 0; i < (int)deviceList_.size(); i++)
+	deviceList_[i]->processInput();
+}
+
+void ossimPlanetInteractionController::defineInteractionValuator(const std::string& name, double minValue, double maxValue)
+{
+    if(name.empty() || ossim::isnan(minValue) || ossim::isnan(maxValue)) return;
+    //     assert(!name.empty());
+    //     assert(!ossim::isnan(minValue));
+    //     assert(!ossim::isnan(maxValue));
+    
+    valuators_[name] = ossimPlanetInteractionValuatorData(minValue, maxValue);
+    
+    //     assert(!ossim::isnan(interactionValuatorValue(name)));
+}
+
+float ossimPlanetInteractionController::interactionValuatorValue(const std::string& interactionValuator) const
+{
+    float result = ossim::nan();
+    
+    std::map<std::string, ossimPlanetInteractionValuatorData>::const_iterator i = valuators_.find(interactionValuator);
+    if (i != valuators_.end())
+	result = i->second.value;
+    else
+	std::cerr << "ossimPlanetInteractionController::interactionValuatorValue(): no defined interactionValuator " << interactionValuator << std::endl;
+    return result;
+}
+
+void ossimPlanetInteractionController::bind(const std::string& event, const ossimPlanetAction& a)
+{
+    if(event.empty()) return;
+    //     assert(!event.empty());
+
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theBoundActionsMutex);
+    boundActions_[event] = a.clone();
+}
+
+void ossimPlanetInteractionController::unbind(const std::string& event)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theBoundActionsMutex);
+   std::map<std::string, osg::ref_ptr<ossimPlanetAction> >::iterator i = boundActions_.find(event);
+    
+    if (i != boundActions_.end())
+    {
+       boundActions_.erase(i);
+    }
+}
+
+void ossimPlanetInteractionController::unbindAll()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theBoundActionsMutex);
+    boundActions_.clear();
+}
+
+void ossimPlanetInteractionController::tie(const std::string& valuatorList)
+{
+   std::vector<std::string> list;
+   bool unbalanced;
+   mkUtils::lexBraceQuotedTokens(valuatorList, 0, " \t", &list, &unbalanced);
+   
+   if (!unbalanced && list.size() > 1) {
+      std::vector<std::string>& v = deviceTies_[list[0]];  // deviceTies_[] creates a blank entry if needed
+      v.clear();
+      for (unsigned int i = 1; i < list.size(); i++)
+         if (!ossim::isnan(interactionValuatorValue(list[i])))
+            v.push_back(list[i]);
+   } else
+      std::cerr << "ossimPlanetInteractionController::tie() had malformed interactionValuatorList, ignoring: " << valuatorList << std::endl;
+}
+
+void ossimPlanetInteractionController::untie(const std::string& deviceValuator)
+{
+    std::map<std::string, std::vector<std::string> >::iterator i = deviceTies_.find(deviceValuator);
+    if (i != deviceTies_.end())
+        deviceTies_.erase(i);
+}
+
+void ossimPlanetInteractionController::untieAll()
+{
+    deviceTies_.clear();
+}
+
+void ossimPlanetInteractionController::writeConfiguration(std::ostream& stream) const
+{
+    for (std::map<std::string, std::vector<std::string> >::const_iterator i = deviceTies_.begin(); i != deviceTies_.end(); i++) {
+        stream << ":iac tie " << i->first;
+        const std::vector<std::string>& v = i->second;
+        for (unsigned int j = 0; j < v.size(); j++)
+            stream << ' ' << v[j];
+        stream << std::endl;
+    }
+    
+   for (std::map<std::string, osg::ref_ptr<ossimPlanetAction> >::const_iterator i = boundActions_.begin(); i != boundActions_.end(); i++)
+        stream << ":iac bind " << i->first << " {" << *i->second << '}' << std::endl;
+}
+
+void ossimPlanetInteractionController::executeBoundAction(const std::string& event)
+{
+    // Debug::log("InteractionController_events") << "--- " << event << std::endl;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theBoundActionsMutex);
+    
+   std::map<std::string,osg::ref_ptr< ossimPlanetAction> >::const_iterator i = boundActions_.find(event);
+    if (i != boundActions_.end()) 
+	i->second->execute();
+}
+
+void ossimPlanetInteractionController::updateInteractionValuators(const std::string& deviceValuator, float normalizedValue)
+{
+    // XXX assert(mkUtils::inInterval(normalizedValue, 0.0f, 1.0f));
+    
+    // Debug::log("InteractionController_events") << "--- " << deviceValuator << " = " << normalizedValue << std::endl;
+    
+    std::map<std::string, std::vector<std::string> >::iterator i = deviceTies_.find(deviceValuator);
+    if (i != deviceTies_.end())
+    {
+        std::vector<std::string>& v = i->second;
+        for (unsigned int j = 0; j < v.size(); j++)
+        {
+            std::map<std::string, ossimPlanetInteractionValuatorData>::iterator iter = valuators_.find(v[j]);
+            if (iter != valuators_.end())
+            {
+                // ossimPlanetInteractionValuatorData data& = (valuators_.find(v[j])->second);
+                iter->second.value = normalizedValue*iter->second.maxMinusMin + iter->second.min;
+            }
+        }
+    }
+}
+
+void ossimPlanetInteractionController::execute(const ossimPlanetAction& action)
+{
+   const ossimPlanetDestinationCommandAction* a = action.toDestinationCommandAction();
+   const ossimPlanetXmlAction* xml = action.toXmlAction();
+   if(a)
+   {
+      destinationCommandExecute(*a);
+   }
+   else if(xml)
+   {
+      xmlExecute(*xml);
+   }
+   
+}
+
+void ossimPlanetInteractionController::xmlExecute(const ossimPlanetXmlAction& a)
+{
+   ossimString command = a.command();
+   if(command == "Bind")
+   {
+      ossimString bindString;
+      ossimPlanetXmlAction tempAction;
+      // need to create objects for these so we can do a common string encode.  We will do it here
+      // for now and move out later for common use.
+      //
+      ossim_uint32 idx;
+      const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();
+      for(idx = 0; idx < children.size();++idx)
+      {
+         if(children[idx]->getTag() == "Keyboard")
+         {
+            ossimString key     = children[idx]->getAttributeValue("key");
+            ossimString metaKey = children[idx]->getAttributeValue("metaKey");
+            if(key == " ")
+            {
+               key = "space";
+            }
+            bindString = key;
+            if(!metaKey.empty())
+            {
+               bindString = metaKey + "_" + bindString;
+            }
+            bindString += "_key";
+         }
+         else if(children[idx]->getTag() == "Mouse")
+         {
+            
+         }
+         else if(children[idx]->findAttribute("target").valid())
+         {
+            tempAction.setXmlNode((ossimXmlNode*)children[idx]->dup());
+         }
+         
+         if(tempAction.xmlNode().valid())
+         {
+            bind(bindString, tempAction);
+         }
+      }
+   }
+   else if(command == "Unbind")
+   {
+      
+   }
+   else if(command == "UnbindAll")
+   {
+      unbindAll();
+   }
+}
+
+void ossimPlanetInteractionController::destinationCommandExecute(const ossimPlanetDestinationCommandAction& a)
+{
+   
+   ossimString command = a.command();
+   if (command == "bind")
+   {
+      if (a.argCount() == 2)
+      {
+         if (!a.arg(1).empty())
+            bind(a.arg(1), 
+                 ossimPlanetDestinationCommandAction(a.arg(2)));
+         else
+            a.printError("cannot bind empty event name because this name is guaranteed a noop");
+      } else
+         a.printError("bad argument count");
+      
+   }
+   else if (command == "unbind")
+   {
+      for (unsigned int i = 1; i <= a.argCount(); i++)
+         unbind(a.arg(i));
+      
+   }
+   else if (command == "unbindall")
+   {
+      unbindAll();
+      
+   }
+   else if (command == "tie")
+   {
+      if (a.argCount() > 1)
+         tie(a.argListSource());
+      else
+         a.printError("bad argument count: need device valuator followed by 1 or more interaction valuator");
+      
+   }
+   else if (command == "untie")
+   {
+      for (unsigned int i = 1; i <= a.argCount(); i++)
+         untie(a.arg(i));
+      
+   }
+   else if (command == "untieall")
+   {
+      untieAll();
+      
+   }
+   else if (command == "printvaluators")
+   {
+      std::map<std::string, ossimPlanetInteractionValuatorData>::const_iterator i;
+      for (i = valuators_.begin(); i != valuators_.end(); i++)
+         std::cout << i->first << " = " << i->second.value << "\trange [" << i->second.min << ',' << (i->second.maxMinusMin + i->second.min) << ']' << std::endl;
+      
+   }
+   else if (command == "writeconfiguration")
+   {
+      if (a.argCount() == 0)
+      {
+         writeConfiguration(std::cout);
+      }
+      else if (a.argCount() == 1)
+      {
+         std::ofstream f(a.arg(1).c_str());
+         if (!f)
+            std::cerr << "cannot open file " << a.arg(1) << " for :iac writeconfiguration" << std::endl;
+         else
+            writeConfiguration(f);
+      }
+      else
+         a.printError("bad argument count, must specify a filename, or no argument for stdout");
+      
+   }
+   else if (command == "doevents")
+   {
+      for (unsigned int i = 1; i <= a.argCount(); i++)
+         executeBoundAction(a.arg(i));
+      
+   }
+   else if (command == "updatevaluators")
+   {
+      if (a.argCount() % 2 == 0) {
+         for (unsigned int i = 1; i < a.argCount(); i += 2) {
+            float x = mkUtils::asFloat(a.arg(i+1));
+            if (mkUtils::inInterval(x, 0.0f, 1.0f)) {
+               std::map<std::string, ossimPlanetInteractionValuatorData>::iterator iter = valuators_.find(a.arg(i));
+               if (iter != valuators_.end())
+               {
+                  iter->second.value = x*iter->second.maxMinusMin + iter->second.min;
+               }
+               else 
+                  a.printError("Undefined simulation variable " + a.arg(i));
+            }
+         }
+      } else
+         a.printError("bad arg count");
+      
+   } else {
+      a.printError("ossimPlanetInteractionController Action not understood");
+   }   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIoRoutableMessageHandler.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIoRoutableMessageHandler.cpp
new file mode 100644
index 0000000..4a7113d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIoRoutableMessageHandler.cpp
@@ -0,0 +1,20 @@
+#include <ossimPlanet/ossimPlanetIoRoutableMessageHandler.h>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+
+bool ossimPlanetIoRoutableMessageHandler::handleMessage(osg::ref_ptr<ossimPlanetMessage> message)
+{
+   bool result = false;
+   if(!enableFlag()) return result;
+   if(!message->data().empty())
+   {
+      if(*(message->data().begin()) == ':')
+      {
+         result = true;
+         ossimPlanetDestinationCommandAction(std::string(message->data().begin(),
+                                                         message->data().end())).execute();
+      }
+   }
+   
+   return result;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocket.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocket.cpp
new file mode 100644
index 0000000..301e73e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocket.cpp
@@ -0,0 +1,665 @@
+#include <ossimPlanet/ossimPlanetIoSocket.h>
+#include <iostream>
+#include <ossim/base/ossimConstants.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <sstream>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+#include <ossim/base/ossimTrace.h>
+#include <ossim/base/ossimNotify.h>
+#include <algorithm>
+
+static ossimTrace traceDebug("ossimPlanetIoSocket:debug");
+
+ossimPlanetIoSocket::ossimPlanetIoSocket()
+   :ossimPlanetIo(),
+    theSocket(new netSocket()),
+    theHost(""),
+    thePort(0),
+    theIoType(""),
+    theStreamingFlag(false),
+    theTempBuffer(4096),
+    //theAutoCloseOnPeerShutdownFlag(true),
+    theAutoReconnectFlag(true),
+    theAutoReconnectInterval(5000),
+    theMaxBytesToSendPerIo(1024*4),
+    theMaxOutgoingBacklogInBytes(1024*1024),
+    theTotalBytesToSend(0),
+    theFirstReadFlag(true)
+{
+   setIoDirection(ossimPlanetIoDirection_INOUT);
+}
+
+ossimPlanetIoSocket::~ossimPlanetIoSocket()
+{
+   if(theSocket)
+   {
+      closeIo();
+      delete theSocket;
+      theSocket = 0;
+   }
+}
+
+void ossimPlanetIoSocket::setHandle(int handle)
+{
+   theSocket->setHandle(handle);
+}
+
+void ossimPlanetIoSocket::searchName(ossimString& searchNameResult)const
+{
+   if(name().empty())
+   {
+      searchNameResult = host() + ":" + ossimString::toString(thePort);
+   }
+   else
+   {
+      searchNameResult = name() + ":" + ossimString::toString(thePort);
+   }
+}
+
+ossim_uint32 ossimPlanetIoSocket::read(char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoMutex);
+   ossim_uint32 resultBytesRead = 0;
+   if(handle() < 0)
+   {
+      ioResult = IO_FAIL;
+      return resultBytesRead;
+   }
+	
+//   bool useRecvFlag = (theStreamingFlag||(theHost.empty()||(thePort <=0)));
+   int bytes = -1;
+//	if(useRecvFlag)
+	{
+		bytes = theSocket->recv(buffer, bufferSize);
+	}
+//	else
+//	{
+//		netAddress add(theHost, thePort);
+//		bytes = theSocket->recvfrom(buffer, bufferSize, 0, &add);
+//	}
+   if(bytes>0)
+   {
+      resultBytesRead = bytes;
+      ioResult = IO_SUCCESS;
+   }
+   else if(bytes < 0) // peer performed shutdown
+   {
+		if(!theSocket->isNonBlockingError())
+		{
+			ioResult = IO_FAIL;
+		}
+		else
+		{
+			ioResult = IO_NO_DATA;
+		}
+   }
+   else
+   {
+      ioResult = IO_FAIL;
+   }
+   
+   return resultBytesRead;
+}
+
+
+ossim_uint32 ossimPlanetIoSocket::write(const char* buffer, ossim_uint32 bufferSize, ossimPlanetIo::IoResultType& ioResult)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoMutex);
+   ossim_uint32 resultBytesWritten = 0;
+   if(handle() < 0)
+   {
+      ioResult = IO_NO_DATA;
+      return resultBytesWritten;
+   }
+//   bool useSendFlag = (theStreamingFlag||theHost.empty()||(thePort <=0));
+   int bytes = -1;
+	
+//	if(useSendFlag)
+	{
+		bytes = theSocket->send(buffer, bufferSize);
+	}
+//	else
+//	{
+//		netAddress add(theHost, thePort);
+//		bytes = theSocket->sendto(buffer, bufferSize, 0, &add);
+//	}
+   if(bytes > 0)
+   {
+      resultBytesWritten = bytes;
+      ioResult = IO_SUCCESS;
+   }
+   else if(bytes == 0)
+	{
+      ioResult = IO_NO_DATA;
+	}
+	else
+   {
+		if(!theSocket->isNonBlockingError())
+		{
+			ioResult = IO_FAIL;
+		}
+		else
+		{
+			ioResult = IO_NO_DATA;
+		}
+   }
+   
+   return resultBytesWritten;
+}
+
+
+bool ossimPlanetIoSocket::setSocket(const ossimString& host,
+                                    int port,
+                                    const ossimString& ioType)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theSocketMutex);
+   return protectedSetSocket(host, port, ioType);
+}
+
+bool ossimPlanetIoSocket::protectedSetSocket(const ossimString& host,
+                                             int port,
+                                             const ossimString& ioType)
+{
+   bool result = false;
+   closeIo();
+ 	setFinishedFlag(false);
+  
+   theHost        = host;
+   theIoType      = ioType;
+   thePort        = port;
+	theStreamingFlag = theIoType == "tcp";
+	//std::cout << "Trying " << host << " " << port << " " << ioType << std::endl;
+   // if I am enabled or not enabled and can't do a reconect in the io thread then
+   // go ahead and do a connection now
+   //
+   if((enableFlag())||
+      (!enableFlag()&&!theAutoReconnectFlag))
+   {
+      if (makeClientSocket())
+      {
+         pushConnectionHeader();// add connection header if one exists
+         result = true;
+      }
+   }
+  
+   nonblock();
+	
+	theFirstReadFlag = true;
+   return result;
+}
+
+bool ossimPlanetIoSocket::nonblock()
+{
+	return setBlockingFlag(false);
+}
+
+bool ossimPlanetIoSocket::setBlockingFlag(bool flag)
+{
+   if (theSocket->getHandle() < 0)
+   {
+      return false;
+   }
+   theSocket->setBlocking( false );
+	
+	return true;
+}
+
+void ossimPlanetIoSocket::setEnableFlag(bool flag)
+{
+   bool stateChanged = false;
+   // if we are currently going from enabled to disabled then clear the lists after we disable
+   // ourselves
+   if(!flag&&enableFlag())
+   {
+      stateChanged = true;
+   }
+   ossimPlanetIo::setEnableFlag(flag);
+   if(stateChanged)
+   {
+      clearAllBuffers();
+   }
+
+}
+
+const ossimString& ossimPlanetIoSocket::host()const
+{
+   return theHost;
+}
+
+int ossimPlanetIoSocket::port()const
+{
+   return thePort;
+}
+
+const ossimString& ossimPlanetIoSocket::ioType()const
+{
+   return theIoType;
+}
+
+void ossimPlanetIoSocket::performIo()
+{
+   ossimPlanetIo::IoResultType ioResult;
+   bool hasOutput = false;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theSocketMutex);
+
+   if(theSocket->getHandle()<0)
+   {
+      if(theAutoReconnectFlag&&enableFlag())
+      {
+         if(theLastTick == 0)
+         {
+           theLastTick = osg::Timer::instance()->tick();
+         }
+         else if(osg::Timer::instance()->delta_m(theLastTick, osg::Timer::instance()->tick()) > theAutoReconnectInterval)
+         {
+            theLastTick = 0; // reset the next try
+            protectedSetSocket(theHost, thePort, theIoType);  // connect and see if we can perform io on next cycle
+            if(theSocket->getHandle() >=0)
+            {
+               pushConnectionHeader();
+            }
+         }
+			return;
+      }
+      else if(!theAutoReconnectFlag)
+		{
+			setFinishedFlag(true);
+			return;
+		}
+		else
+      {
+        return;
+      }
+   }
+   if(ioDirection()&ossimPlanetIoDirection_OUT&&enableFlag())
+   {
+      addToOutputBufferIfNeeded();
+      OpenThreads::ScopedLock<OpenThreads::Mutex> outBufferLock(theOutBufferMutex);
+      if(theOutBuffer.size())
+      {
+         hasOutput = true;
+         // do any sends if we are an output socket
+         ossim_uint32 bytesToSend =  ossim::min((ossim_uint32)theOutBuffer.size(),
+                                                (ossim_uint32)maxBytesToSendPerIo());
+      
+         ossim_uint32 bytes = write((char*)(&theOutBuffer.front()), bytesToSend, ioResult);
+         if(ioResult == IO_SUCCESS)
+         {
+            theOutBuffer.erase(theOutBuffer.begin(),
+                               theOutBuffer.begin() + bytes);
+            
+           // theTotalBytesToSend-=bytes;
+//            if(theTotalBytesToSend < 0)
+//            {
+//               theTotalBytesToSend = 0;
+//            }
+         }
+//         if(theOutBuffer.empty())
+//         {
+//            theTotalBytesToSend = 0;
+//         }
+      }
+   }
+   else
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> outBufferLock(theOutBufferMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> outQueueLock(theOutQueueMutex);
+      theOutBuffer.clear();
+      theOutQueue.clear();
+   }
+   if(ioDirection()&ossimPlanetIoDirection_IN)
+   {
+   // do any receives if we are an input socket
+      ossim_uint32 bytes = read(&theTempBuffer.front(), theTempBuffer.size(), ioResult);
+      if(ioResult==IO_SUCCESS)
+      {
+			theFirstReadFlag = false; // we have performed the first read so set the flag now to false
+         if(enableFlag())
+         {
+				//std::cout << ossimString(theTempBuffer.begin(), theTempBuffer.begin()+bytes) << "\n";
+            theInBuffer.insert(theInBuffer.end(), theTempBuffer.begin(), theTempBuffer.begin()+bytes);
+         }
+      }
+      else if(ioResult == IO_FAIL) // peer performed shutdown
+      {
+         if(traceDebug())
+         {
+            ossimNotify(ossimNotifyLevel_DEBUG) << "ossimPlanetIoSocket::performIo(): read io failed" << std::endl;
+         }
+			//if(!theFirstReadFlag)
+			closeIo();
+			if(!theAutoReconnectFlag)
+			{
+				setFinishedFlag(true);
+			}
+		}
+      bool doneSending = false;
+      while(!theInBuffer.empty()&&!doneSending)
+      {
+         // check if start of old style router or 
+         // new style XML token
+         //
+//         bool hasValidStartToken = ((theInBuffer[(size_t)0] == ':')||
+//                                    (theInBuffer[(size_t)0] == '<');
+         bool hasValidStartToken = (theInBuffer[(size_t)0] == '<');
+         if(!hasValidStartToken)
+         {
+            // then skip til we find the first valid token
+            //
+            const char tokens[]={'<'};
+            ossimPlanetIo::ByteBufferType::iterator iter = std::find_first_of(theInBuffer.begin(),
+                                                                          theInBuffer.end(),
+                                                                          tokens,
+                                                                          tokens+1);
+            if(iter == theInBuffer.end())
+            {
+               theInBuffer.clear();
+            }
+            else
+            {
+               // remove the characters since not a valid start token
+               //
+               theInBuffer.erase(theInBuffer.begin(),
+                                 iter);
+            }
+         }
+         
+         if(!theInBuffer.empty())
+         {
+            {
+               ossimString value;
+               ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+               std::istringstream in(ossimString(theInBuffer.begin(),
+                                                 theInBuffer.end()));
+               if(node->read(in))
+               {
+						//std::cout<<(*node) << "\n";
+                  if(node->getTag() == "Message")
+                  {
+                     // container for multiple Actions
+                     //
+                     const vector<ossimRefPtr<ossimXmlNode> >& childNodes = node->getChildNodes();
+                     ossim_uint32 idx = 0;
+                     for(idx = 0; idx < childNodes.size();++idx)
+                     {
+                        if(childNodes[idx]->getAttributeValue(value, "target"))
+                        {
+                           ossimPlanetXmlAction action;
+                           action.setXmlNode(childNodes[idx]);
+                           action.execute();
+                        }
+                     }
+                  }
+                  else if(node->getAttributeValue(value, "target")) // is it a direct message
+                  {
+                     if(traceDebug())
+                     {
+                        ossimNotify(ossimNotifyLevel_DEBUG) << "ossimPlanetIoSocket::performIo(): processing message = " << ossimString(theInBuffer.begin(),
+                                                                                                                                        theInBuffer.begin()+in.tellg())<<std::endl;
+                     }
+                     // must be a direct action object
+                     //
+                     ossimPlanetXmlAction action;
+                     action.setXmlNode(node);
+                     action.execute();
+                  }
+                  else // will have to do a custom parse later.
+                  {
+                     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theInQueueMutex);
+                     
+                     theInQueue.push(new ossimPlanetMessage("",std::vector<char>(theInBuffer.begin(),
+                                                                              theInBuffer.begin()+in.tellg())));
+                  }
+                  theInBuffer.erase(theInBuffer.begin(),
+                                    theInBuffer.begin()+in.tellg());
+               }
+               else
+               {
+                  if(traceDebug())
+                  {
+                     ossimNotify(ossimNotifyLevel_DEBUG) << "ossimPlanetIoSocket::performIo(): Read had a parse error that stopped short of the end of buffer location" << std::endl;
+                  }
+                  //if(!theFirstReadFlag)
+                  // if stopped short then we had a parse error.  Just erase the buffer up to the error and keep trying
+                  // if we reached the end the we may need more
+                  //
+                  if(((ossim_int64)in.tellg() >=0) && ((ossim_int64)in.tellg() < (ossim_int64)theInBuffer.size()))
+                  {
+//							std::cout << "ERROR=======> " << ossimString(theInBuffer.begin(),
+//																						theInBuffer.begin()+in.tellg()) << "\n";
+                     theInBuffer.erase(theInBuffer.begin(),
+                                       theInBuffer.begin()+in.tellg());
+
+                  }
+                  doneSending = true;
+               }
+            }
+         }
+      }
+   }
+   else // only outgoing so let's do a check to see if the peer shutdown
+   {
+      theInBuffer.clear();
+      // let's ignor any incoming bytes and do a check to see if we are still connected to the peer
+      
+      read(&theTempBuffer.front(), theTempBuffer.size(), ioResult);
+      if(ioResult == IO_FAIL) // peer performed shutdown
+      {
+         closeIo();
+         theOutBuffer.clear();
+//         theTotalBytesToSend=0;
+
+			if(!theAutoReconnectFlag)
+			{
+				setFinishedFlag(true);
+			}
+      }
+   }
+   if(finishedFlag())
+   {
+      theInBuffer.clear();
+      theOutBuffer.clear();
+   }
+}
+
+bool ossimPlanetIoSocket::pushMessage(osg::ref_ptr<ossimPlanetMessage> message, bool forcePushFlag)
+{
+   if(!(ioDirection()&ossimPlanetIoDirection_OUT) || !enableFlag()) return false; 
+   bool result = true;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOutQueueMutex);
+   OutQueueType::iterator iter = theOutQueue.begin();
+   if(!message->id().empty())
+   {
+      while(iter != theOutQueue.end())
+      {
+         if((*iter)->id() == message->id())
+         {
+            OutQueueType::iterator iter2 = theOutQueue.erase(iter);
+            theOutQueue.insert(iter2, message);
+            std::cout << "REPLACING!!!!!" << std::endl;
+            return result;
+         }
+         ++iter;
+      }
+   }
+   theOutQueue.push_back(message);
+   
+   return result;
+#if 0
+   bool needTerminator = message[(size_t)0] == ':'; // check for old : action message format
+   if(!enableFlag()) return false;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOutGoingMutex);
+   if(forcePushFlag) // we will always support one message no matter the size
+   {
+      theOutBuffer.push_back(message);
+      if(needTerminator)
+      {
+         theOutBuffer.back().push_back(terminator());
+      }
+      theTotalBytesToSend += theOutBuffer.back().size();
+   }
+   else if(theTotalBytesToSend > (int)theMaxOutgoingBacklogInBytes)
+   {
+      // create some kind of notification for this
+      result = false;
+   }
+   else
+   {
+      if(theSocket->getHandle() < 0) return false;
+      theOutBuffer.push_back(message);
+      theOutBuffer.back().push_back(terminator());
+      if(needTerminator)
+      {
+         theOutBuffer.back().push_back(terminator());
+      }
+      theTotalBytesToSend += theOutBuffer.back().size();
+   }
+   return result;
+#endif
+}
+
+osg::ref_ptr<ossimPlanetMessage> ossimPlanetIoSocket::popMessage()
+{
+   if(!enableFlag()) return 0;
+   theInQueueMutex.lock();
+   osg::ref_ptr<ossimPlanetMessage> message;
+   if(!theInQueue.empty())
+   {
+      message = theInQueue.front();
+      theInQueue.pop();
+   }
+   theInQueueMutex.unlock();
+  
+   return message;
+}
+
+void ossimPlanetIoSocket::clearAllBuffers()
+{
+   theInQueueMutex.lock();
+   while(!theInQueue.empty())theInQueue.pop();
+   theInQueueMutex.unlock();
+   theInBuffer.clear();
+   theOutBufferMutex.lock();
+   theOutBuffer.clear();
+//   theTotalBytesToSend = 0;
+   theOutBufferMutex.unlock();
+   theOutQueueMutex.lock();
+   theOutQueue.clear();
+   theOutQueueMutex.unlock();
+}
+
+//void ossimPlanetIoSocket::setAutoCloseOnPeerShutdownFlag(bool flag)
+//{
+//   theAutoCloseOnPeerShutdownFlag = flag;
+//}
+
+//bool ossimPlanetIoSocket::autoCloseOnPeerShutdownFlag()const
+//{
+//   return theAutoCloseOnPeerShutdownFlag;
+//}
+
+void ossimPlanetIoSocket::setAutoReconnectFlag(bool flag)
+{
+   theAutoReconnectFlag = flag;
+}
+
+bool ossimPlanetIoSocket::autoReconnectFlag()const
+{
+   return theAutoReconnectFlag;
+}
+
+void ossimPlanetIoSocket::setAutoReconnectInterval(ossim_uint32 milliseconds)
+{
+   theAutoReconnectInterval = milliseconds;
+}
+
+ossim_uint32 ossimPlanetIoSocket::autoReconnectInterval()const
+{
+   return theAutoReconnectInterval;
+}
+
+void ossimPlanetIoSocket::setMaxOutputBacklogInBytes(ossim_uint32 bytes)
+{
+   theMaxOutgoingBacklogInBytes = bytes;
+}
+
+ossim_uint32 ossimPlanetIoSocket::maxOutputBacklogInBytes()const
+{
+   return theMaxOutgoingBacklogInBytes;
+}
+
+void ossimPlanetIoSocket::closeIo()
+{
+   theSocket->close();
+}
+
+bool ossimPlanetIoSocket::openIo()
+{
+   return setSocket(theHost, thePort, theIoType);
+}
+
+void ossimPlanetIoSocket::setMaxBytesToSendPerIo(ossim_uint32 byte)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMaxBytesToSendPerIoMutex);
+
+   theMaxBytesToSendPerIo = byte;
+}
+
+ossim_uint32 ossimPlanetIoSocket::maxBytesToSendPerIo()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMaxBytesToSendPerIoMutex);
+   return theMaxBytesToSendPerIo;
+}
+
+
+bool ossimPlanetIoSocket::makeClientSocket()
+{
+   if (!theSocket->open( theStreamingFlag ))
+   {
+      return false;
+   }
+   
+	if(theStreamingFlag)
+	{
+		int testValue = theSocket->connect( theHost.c_str(), thePort );
+		if (testValue < 0)
+		{
+			theSocket->close();
+			return false;
+		}
+	}
+  
+   return true;
+}
+
+void ossimPlanetIoSocket::addToOutputBufferIfNeeded()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(theOutQueueMutex);
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theOutBufferMutex);
+ 
+   if(theOutBuffer.empty()&&(!theOutQueue.empty()))
+   {
+      bool needTerminator = theOutQueue.front()->data()[(size_t)0] == ':'; // check for old : action message format
+      theOutBuffer.insert(theOutBuffer.end(), theOutQueue.front()->data().begin(), theOutQueue.front()->data().end());
+      if(needTerminator)
+      {
+         theOutBuffer.push_back(terminator());
+      }
+      theOutQueue.pop_front();
+   }
+#if 0
+   while((theOutBuffer.size() < maxBytesToSendPerIo())&&(!theOutQueue.empty()))
+   {
+      bool needTerminator = theOutQueue.front()->data()[(size_t)0] == ':'; // check for old : action message format
+      theOutBuffer.push_back(theOutQueue.front()->data());
+      if(needTerminator)
+      {
+         theOutBuffer.push_back(terminator());
+      }
+      //         theTotalBytesToSend += theOutBuffer.size();
+   }
+#endif
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocketServerChannel.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocketServerChannel.cpp
new file mode 100644
index 0000000..f0b4943
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIoSocketServerChannel.cpp
@@ -0,0 +1,330 @@
+#include <ossimPlanet/ossimPlanetIoSocketServerChannel.h>
+#include <ossimPlanet/ossimPlanetIoSocket.h>
+#include <iostream>
+ossimPlanetIoSocketServerChannel::ossimPlanetIoSocketServerChannel()
+   :ossimPlanetIo(),netChannel(),
+    theHost(""),
+    thePort(0),
+    theIoType("tcp"),
+    theIsTcp(true),
+    theAutoReconnectFlag(true),
+    theAutoReconnectInterval(10000),
+    theLastTick(0)
+{
+   setIoDirection(ossimPlanetIoDirection_IN);
+}
+
+ossimPlanetIoSocketServerChannel::~ossimPlanetIoSocketServerChannel()
+{
+   theIoListMutex.lock();
+   theIoList.clear();
+   theIoListMutex.unlock();
+   clearAllBuffers();
+   close();
+}
+
+void ossimPlanetIoSocketServerChannel::searchName(ossimString& searchNameResult)const
+{
+   if(name().empty())
+   {
+      searchNameResult = host() + ":" + ossimString::toString(thePort);
+   }
+   else
+   {
+      searchNameResult = name() + ":" + ossimString::toString(thePort);
+   }
+}
+
+bool ossimPlanetIoSocketServerChannel::setSocket(const std::string& host,
+                                                 int port,
+                                                 const std::string& ioType)
+{
+   
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theSocketMutex);
+   return protectedSetSocket(host, port, ioType);
+}
+
+bool ossimPlanetIoSocketServerChannel::protectedSetSocket(const std::string& host,
+                                                          int port,
+                                                          const std::string& ioType)
+{
+   
+   theIoList.clear();
+
+   theHost = host;
+   thePort = port;
+   theIoType = ioType;
+   theIsTcp = theIoType!="udp";
+   if(getHandle() > -1)
+   {
+      close();
+   }
+	if(open(theIsTcp))
+   {
+      if( bind("", port)<0)
+      {
+         close();
+         return false;
+      }
+//       if(!theIsTcp)
+      {
+         setBlocking( false );
+      }
+//       else
+      if(theIsTcp)
+      {
+         listen(32); // need to add something that is not hardcoded here
+      }
+   }
+   else
+   {
+      return false;
+   }
+   return true;
+}
+
+void ossimPlanetIoSocketServerChannel::setEnableFlag(bool flag)
+{
+   bool clearBuffersFlag = false;
+   // if we are currently going from enabled to disabled then clear the lists after we disable
+   // ourselves
+   if(!flag&&enableFlag())
+   {
+      clearBuffersFlag = true;
+   }
+   ossimPlanetIo::setEnableFlag(flag);
+}
+
+void ossimPlanetIoSocketServerChannel::clearAllBuffers()
+{
+   theInQueueMutex.lock();
+   while(!theInQueue.empty())theInQueue.pop();
+   theInQueueMutex.unlock();
+}
+
+const std::string& ossimPlanetIoSocketServerChannel::host()const
+{
+   return theHost;
+}
+
+const std::string& ossimPlanetIoSocketServerChannel::ioType()const
+{
+   return theIoType;
+}
+
+int ossimPlanetIoSocketServerChannel::port()const
+{
+   return thePort;
+}
+
+bool ossimPlanetIoSocketServerChannel::isTcp()const
+{
+   return theIsTcp;
+}
+
+void ossimPlanetIoSocketServerChannel::performIo()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theSocketMutex);
+   if(handle() < 0)
+   {
+      if(theAutoReconnectFlag)
+      {
+         if(theLastTick == 0)
+         {
+            theLastTick = osg::Timer::instance()->tick();
+            return;
+         }
+         else 
+         {
+				double delta = osg::Timer::instance()->delta_m(theLastTick, osg::Timer::instance()->tick());
+				
+				if(delta < 0.0)
+				{
+					theLastTick = 0;
+				}
+				else if(delta > theAutoReconnectInterval)
+				{
+					theLastTick = 0; // reset the next try
+					if(!protectedSetSocket(theHost, thePort, theIoType))
+					{
+						return;
+					}
+					else if(handle() < 0)// Quick test again to make sure its valid
+					{
+						return;
+					}
+				}
+				else // we were not able to update the handle yet so return, still invalid
+				{
+					return;
+				}
+			}
+		}
+		else// we were not able to update the handle yet so return, still invalid
+		{
+			return;
+		}
+   }
+      
+   // poll for additional I/O connections
+   poll(10);
+   
+   // handle any current connections and process the messages.
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lockList(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+   while(iter!=theIoList.end())
+   {
+      
+      osg::ref_ptr<ossimPlanetMessage> msg;
+      // perform IO
+      (*iter)->performIo();
+      
+      // now pop any message for handling
+      //
+      while((msg=(*iter)->popMessage()).valid())
+      {
+         theInQueueMutex.lock();
+         if(enableFlag())
+         {
+            theInQueue.push(msg);
+         }
+         else
+         {
+            while(!theInQueue.empty())
+            {
+               theInQueue.pop();
+            }
+         }
+         theInQueueMutex.unlock();
+      }
+      // check to see if it's been marked as finished and if so remove from the list
+      if((*iter)->finishedFlag())
+      {
+         iter = theIoList.erase(iter);
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+}
+
+osg::ref_ptr<ossimPlanetMessage> ossimPlanetIoSocketServerChannel::popMessage()
+{
+   osg::ref_ptr<ossimPlanetMessage> message;
+   if(!enableFlag()) return message;
+   theInQueueMutex.lock();
+   if(!theInQueue.empty())
+   {
+      message = theInQueue.front();
+      theInQueue.pop();
+   }
+   theInQueueMutex.unlock();
+   
+   return message;
+}
+
+void ossimPlanetIoSocketServerChannel::setAutoReconnectFlag(bool flag)
+{
+   theAutoReconnectFlag = flag;
+}
+
+bool ossimPlanetIoSocketServerChannel::autoReconnectFlag()const
+{
+   return theAutoReconnectFlag;
+}
+
+void ossimPlanetIoSocketServerChannel::setAutoReconnectInterval(ossim_uint32 milliseconds)
+{
+   theAutoReconnectInterval = milliseconds;
+}
+
+ossim_uint32 ossimPlanetIoSocketServerChannel::autoReconnectInterval()const
+{
+   return theAutoReconnectInterval;
+}
+
+
+void ossimPlanetIoSocketServerChannel::handleRead (void) // for udp servers we can read
+{
+   netAddress addr ;
+   accept ( &addr ) ;
+   int h = getHandle();
+   if(h > -1)
+   {
+      theIoListMutex.lock();
+      if(!protectedFindHandle(h))
+      {
+         osg::ref_ptr<ossimPlanetIoSocket> socket = new ossimPlanetIoSocket();
+         socket->setIoDirection(ossimPlanetIoDirection_IN);
+			//socket->setAutoCloseOnPeerShutdownFlag(true);
+			socket->setAutoReconnectFlag(false);
+         socket->setHandle(getHandle());
+         if(enableFlag())
+         {
+            theIoList.push_back(socket.get());
+         }
+//          std::cout << "List size = " << theIoList.size() << "\n";;
+      }
+      theIoListMutex.unlock();
+   }
+}
+
+void ossimPlanetIoSocketServerChannel::handleWrite (void) 
+{
+#if 0
+   netAddress addr ;
+   accept ( &addr ) ;
+   int h = getHandle();
+   if(h > -1)
+   {
+		osg::ref_ptr<ossimPlanetIoSocket> socket = new ossimPlanetIoSocket();
+		socket->setIoDirection((ossimPlanetIoDirection)(ossimPlanetIoDirection_IN));
+		socket->setHandle(getHandle());
+		socket->closeIo();
+   }
+#endif
+}
+
+void ossimPlanetIoSocketServerChannel::handleAccept (void)// for tcp servers we can accept
+{
+   netAddress addr ;
+   int h = accept ( &addr ) ;
+   if(h != -1)
+   {
+      theIoListMutex.lock();
+      if(!protectedFindHandle(h))
+      {
+//          std::cout << "Addind a io to the handleAccept " << h << "\n";
+         osg::ref_ptr<ossimPlanetIoSocket> socket = new ossimPlanetIoSocket();
+         socket->setIoDirection(ossimPlanetIoDirection_IN);
+         socket->setHandle(h);
+			socket->setBlockingFlag(false);
+			//socket->setAutoCloseOnPeerShutdownFlag(true);
+			socket->setAutoReconnectFlag(false);
+         if(enableFlag())
+         {
+            theIoList.push_back(socket.get());
+//             std::cout << "Io list size === " << theIoList.size() << std::endl;
+         }
+      }
+      theIoListMutex.unlock();
+   }
+}
+
+bool ossimPlanetIoSocketServerChannel::protectedFindHandle(int h)const
+{
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::const_iterator it = theIoList.begin();
+
+   while(it!=theIoList.end())
+   {
+      ossimPlanetIoSocket* io = static_cast<ossimPlanetIoSocket*>((*it).get());
+      if(io->handle() == h)
+      {
+         return true;
+      }
+      ++it;
+   }
+
+   return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetIoThread.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetIoThread.cpp
new file mode 100644
index 0000000..8375215
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetIoThread.cpp
@@ -0,0 +1,748 @@
+#include <ossimPlanet/ossimPlanetIoThread.h>
+#include <ossimPlanet/ossimPlanetIoRoutableMessageHandler.h>
+#include <ossimPlanet/ossimPlanetIoSocket.h>
+#include <ossimPlanet/ossimPlanetIoSocketServerChannel.h>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+ossimPlanetIoThread::ossimPlanetIoThread()
+   :theDoneFlag(false),
+    theStartedFlag(false),
+    theStartCalledFlag(false),
+   thePauseFlag(false)
+{
+   setPathnameAndRegister(":io");
+   //addMessageHandler(new ossimPlanetIoRoutableMessageHandler);
+}
+
+void ossimPlanetIoThread::addIo(osg::ref_ptr<ossimPlanetIo> io,
+                                bool autoStartFlag)
+{
+   theIoListMutex.lock();
+   theIoList.push_back(io);
+   theIoListMutex.unlock();
+   if(autoStartFlag&&!startedFlag())
+   {
+      start();
+   }
+}
+
+void ossimPlanetIoThread::execute(const ossimPlanetAction &a)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDelayedExecutionMutex);
+   theDelayedExecution.push(a.clone());
+   if(!startedFlag())
+   {
+      start();
+   }
+}
+
+void ossimPlanetIoThread::sendMessage(osg::ref_ptr<ossimPlanetMessage> message, bool forceSendFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+   while(iter != theIoList.end())
+   {
+      (*iter)->pushMessage(message, forceSendFlag);
+      ++iter;
+   }
+}
+
+bool ossimPlanetIoThread::sendMessage(const ossimString& searchName,
+                                      osg::ref_ptr<ossimPlanetMessage> message,
+                                      bool forceSendFlag)
+{
+   bool result = false;
+   osg::ref_ptr<ossimPlanetIo> io = findIo(searchName);
+   if(io.valid())
+   {
+      result = true;
+      io->pushMessage(message, forceSendFlag);
+   }
+
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetIo> ossimPlanetIoThread::removeIoGivenSearchString(const ossimString& searchString)
+{
+   osg::ref_ptr<ossimPlanetIo> result = 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+   ossimString tempSearchString;
+   while(iter != theIoList.end())
+   {
+      (*iter)->searchName(tempSearchString);
+      if(tempSearchString == searchString)
+      {
+         result = (*iter);
+         theIoList.erase(iter);
+         
+         return result;
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+   
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetIo> ossimPlanetIoThread::findIo(const ossimString& searchString)
+{
+   osg::ref_ptr<ossimPlanetIo> result = 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+   ossimString tempSearchString;
+   while(iter != theIoList.end())
+   {
+      (*iter)->searchName(tempSearchString);
+      if(tempSearchString == searchString)
+      {
+         return (*iter);
+      }
+      ++iter;
+   }
+   
+   return result;
+}
+
+const osg::ref_ptr<ossimPlanetIo> ossimPlanetIoThread::findIo(const ossimString& searchString)const
+{
+   const osg::ref_ptr<ossimPlanetIo> result = 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::const_iterator iter = theIoList.begin();
+   ossimString tempSearchString;
+   while(iter != theIoList.end())
+   {
+      (*iter)->searchName(tempSearchString);
+      if(tempSearchString == searchString)
+      {
+         return (*iter).get();
+      }
+      ++iter;
+   }
+   
+   return result;
+}
+
+
+bool ossimPlanetIoThread::removeIo(osg::ref_ptr<ossimPlanetIo> io)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theIoListMutex);
+   std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+   ossimString tempSearchString;
+   while(iter != theIoList.end())
+   {
+      if((*iter).get() == io.get())
+      {
+         theIoList.erase(iter);
+         return true;
+      }
+      ++iter;
+   }
+   return false;
+}
+
+void ossimPlanetIoThread::run()
+{
+   if(startedFlag()) return;
+   setStartedFlag(theStartedFlag);
+   setDoneFlag(false);
+   
+   while(!doneFlag())
+   {
+      {
+         
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theLoopMutex);
+         if(!pauseFlag())
+         {
+            theDelayedExecutionMutex.lock();
+            while(!theDelayedExecution.empty())
+            {
+               delayedExecute(*theDelayedExecution.front());
+               theDelayedExecution.pop();
+            }
+            theDelayedExecutionMutex.unlock();
+            theIoListMutex.lock();
+            std::vector<osg::ref_ptr<ossimPlanetIo> >::iterator iter = theIoList.begin();
+            while(iter != theIoList.end())
+            {
+               osg::ref_ptr<ossimPlanetMessage> msg;
+               (*iter)->performIo();
+               
+               while((msg = (*iter)->popMessage()).valid())
+               {
+                  handleMessage(msg);
+               }
+               msg = 0;
+               if((*iter)->finishedFlag())
+               {
+                  iter = theIoList.erase(iter);
+               }
+               else
+               {
+                  ++iter;
+               }
+            }
+            theIoListMutex.unlock();
+         }
+      }
+      microSleep(5000);
+   }
+   setDoneFlag(true);
+   setStartedFlag(false);
+   setStartCalledFlag(false);
+}
+
+int ossimPlanetIoThread::cancel()
+{
+   setDoneFlag(true);
+   return OpenThreads::Thread::cancel();
+}
+
+bool ossimPlanetIoThread::addMessageHandler(osg::ref_ptr<ossimPlanetIoMessageHandler> handler)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theMessageHandlerList.size(); ++idx)
+   {
+      if(handler.get()==theMessageHandlerList[idx].get())
+      {
+         return false;
+      }
+   }
+   theMessageHandlerList.push_back(handler.get());
+   return true;
+}
+
+bool ossimPlanetIoThread::removeMessageHandler(osg::ref_ptr<ossimPlanetIoMessageHandler> handler)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerListMutex);
+   ossimPlanetIoThread::MessageHandlerListType::iterator iter = theMessageHandlerList.begin();
+
+   while(iter != theMessageHandlerList.end())
+   {
+      if((*iter).get() == handler.get())
+      {
+         theMessageHandlerList.erase(iter);
+         return true;
+      }
+      ++iter;
+   }
+   
+   return false;
+}
+
+bool ossimPlanetIoThread::removeMessageHandler(const ossimString& handlerName)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerListMutex);
+   ossimPlanetIoThread::MessageHandlerListType::iterator iter = theMessageHandlerList.begin();
+
+   while(iter != theMessageHandlerList.end())
+   {
+      if((*iter)->name() == handlerName)
+      {
+         theMessageHandlerList.erase(iter);
+         return true;
+      }
+   }
+   
+   return false;
+}
+
+ossim_uint32 ossimPlanetIoThread::ioCount()const
+{
+   return theIoList.size();
+}
+
+void ossimPlanetIoThread::clearIo()
+{
+   theIoListMutex.lock();
+   theIoList.clear();
+   theIoListMutex.unlock();
+}
+
+bool ossimPlanetIoThread::startedFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theStartedFlag;
+}
+
+void ossimPlanetIoThread::setStartedFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theStartedFlag = flag;
+}
+   
+bool ossimPlanetIoThread::doneFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theDoneFlag;
+}
+
+void ossimPlanetIoThread::setDoneFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theDoneFlag = flag;
+}
+
+void ossimPlanetIoThread::setPauseFlag(bool flag, bool waitTilPaused)
+{
+   if(waitTilPaused)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(theLoopMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(thePropertyMutex);
+      thePauseFlag = flag;
+   }
+   else
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      thePauseFlag = flag;
+   }
+}
+
+bool ossimPlanetIoThread::pauseFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return thePauseFlag;
+}
+
+bool ossimPlanetIoThread::startCalledFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theStartCalledFlag;  
+}
+
+void ossimPlanetIoThread::setStartCalledFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theStartCalledFlag = flag;
+}
+
+void ossimPlanetIoThread::start()
+{
+   if(startCalledFlag())
+   {
+      return;
+   }
+   setStartCalledFlag(true);
+   OpenThreads::Thread::start();
+}
+
+void ossimPlanetIoThread::handleMessage(osg::ref_ptr<ossimPlanetMessage> msg)
+{
+   ossim_uint32 idx = 0;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerListMutex);
+   for(idx = 0; idx < theMessageHandlerList.size();++idx)
+   {
+      if(theMessageHandlerList[idx]->handleMessage(msg))
+      {
+         return;
+      }
+   }
+}
+
+void ossimPlanetIoThread::delayedXmlExecute(const ossimPlanetXmlAction& a)
+{
+   ossimString command = a.command();
+   if(command == "SendMessage")
+   {
+      if(a.xmlNode().valid())
+      {
+         ossimString id = a.xmlNode()->getAttributeValue("id");
+         ossimString searchName = a.xmlNode()->getAttributeValue("ioTargetId");
+         ossimString forceSend = a.xmlNode()->getAttributeValue("forceSend");
+         bool forceSendFlag = forceSend.empty()?false:forceSend.toBool();
+         ossim_uint32 idx = 0;
+         const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+         for(idx = 0;idx<children.size();++idx)
+         {
+            std::ostringstream out;
+            out << *children[idx] << std::endl;
+            if(searchName.empty())
+            {
+               sendMessage(new ossimPlanetMessage(id, ossimString(out.str())), forceSendFlag);
+            }
+            else
+            {
+               sendMessage(searchName, new ossimPlanetMessage(id, ossimString(out.str())), forceSendFlag);
+            }
+         }
+      }
+   }
+   else if(command == "Set")
+   {
+      if(a.xmlNode().valid())
+      {
+         ossim_uint32 idx = 0;
+         const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+         ossimString id = a.xmlNode()->getAttributeValue("id");
+         for(idx = 0;idx<children.size();++idx)
+         {
+            ossimString tag = children[idx]->getTag();
+            if(tag == "connectionHeader")
+            {
+               ossimString headerValue = children[idx]->getText();
+               osg::ref_ptr<ossimPlanetIo> io = findIo(id);
+               if(io.valid())
+               {
+                  std::vector<char> value(headerValue.begin(),
+                                          headerValue.end());
+                  io->setConnectionHeader(new ossimPlanetMessage("", ossimString(headerValue)));
+               }
+            }
+         }
+      }
+   }
+   else if((command == "Remove")||
+           (command == "Close"))
+   {
+      if(a.xmlNode().valid())
+      {
+         ossimString id = a.xmlNode()->getAttributeValue("id");
+         removeIoGivenSearchString(id);
+      }
+   }
+   else if(command == "Open")
+   {
+      ossim_uint32 idx = 0;
+      const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+      for(idx = 0;idx<children.size();++idx)
+      {
+         ossimString tag = children[idx]->getTag();
+         if(tag == "ServerSocket")
+         {
+            ossimString name       = children[idx]->getChildTextValue("name");
+            ossimString ip         = children[idx]->getChildTextValue("ip");
+            ossimString port       = children[idx]->getChildTextValue("port");
+            ossimString portType   = children[idx]->getChildTextValue("portType");
+            ossimString terminator = children[idx]->getChildTextValue("terminator");
+            if(name.empty())
+            {
+               name = ip;
+            }
+#if 0
+            char terminatorChar = '\0';
+            if((terminator == "nul")||
+               (terminator == "eos"))
+            {
+               terminatorChar = '\0';
+            }
+            else if(terminator == "eol")
+            {
+               terminatorChar = '\n';
+            }
+#endif
+            if(portType.empty())
+            {
+               portType = "tcp";
+            }
+            if(!port.empty())
+            {
+               
+            }
+            ossimPlanetIoSocketServerChannel* channel = new ossimPlanetIoSocketServerChannel;
+            channel->setName(name);
+            if(channel->setSocket(ip,
+                                  port.toInt32(),
+                                  portType))
+            {
+               addIo(channel);
+            }
+            else
+            {
+               delete channel;
+               channel = 0;
+            }
+         }
+         else if(tag == "ClientSocket")
+         {
+            osg::ref_ptr<ossimPlanetIoSocket> socket = 0;
+            ossimString name       = children[idx]->getChildTextValue("name");
+            ossimString ip         = children[idx]->getChildTextValue("ip");
+            ossimString port       = children[idx]->getChildTextValue("port");
+            ossimString portType   = children[idx]->getChildTextValue("portType");
+            ossimString terminator = children[idx]->getChildTextValue("terminator");
+				ossimString autoReconnectFlag = children[idx]->getChildTextValue("autoReconnectFlag");
+            char terminatorChar = '\0';
+            if((terminator == "nul")||
+               (terminator == "eos"))
+            {
+               terminatorChar = '\0';
+            }
+            else if(terminator == "eol")
+            {
+               terminatorChar = '\n';
+            }
+            if(portType.empty())
+            {
+               portType = "tcp";
+            }
+            if(name.empty())
+            {
+               name = ip;
+            }
+				if(autoReconnectFlag.empty())
+				{
+					autoReconnectFlag = "true";
+				}
+            if(!ip.empty() && !port.empty())
+            {
+               osg::ref_ptr<ossimPlanetIo> io = findIo(name + ":" + port);
+               if(!io.valid())
+               {
+                  socket = new ossimPlanetIoSocket();
+                  socket->setName(name);
+                  socket->setTerminator(terminatorChar);
+                  socket->setSocket(ip, port.toInt32(), portType);
+						socket->setBlockingFlag(false);
+						socket->setAutoReconnectFlag(autoReconnectFlag.toBool());
+               }
+            }
+            if(socket.valid())
+            {
+               addIo(socket.get());
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanetIoThread::delayedExecute(const ossimPlanetAction &action)
+{
+   const ossimPlanetXmlAction* xmlAction = action.toXmlAction();
+   
+	if(xmlAction)
+	{
+		delayedXmlExecute(*xmlAction);
+      return;
+	}
+   
+   const ossimPlanetDestinationCommandAction* a = action.toDestinationCommandAction();
+   // for now only support :destination command <args> style actions;
+   if(!a) return;
+   ossimString command = a->command();
+   if(command == "openServerSocket")
+   {
+      if(a->argCount() == 2) // name and port
+      {
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1) + ":" + a->arg(2));
+         if(!io.valid())
+         {
+            ossimPlanetIoSocketServerChannel* channel = new ossimPlanetIoSocketServerChannel;
+            channel->setName(a->arg(1));
+            if(channel->setSocket("",
+                                  ossimString(a->arg(2)).toUInt32(),
+                                  "tcp"))
+            {
+               addIo(channel);
+            }
+            else
+            {
+               delete channel;
+            }
+         }
+      }
+      else if(a->argCount() == 3) // <name> <port> <tcp or udp>
+      {
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1) + ":" + a->arg(2));
+         if(!io.valid())
+         {
+            osg::ref_ptr<ossimPlanetIoSocketServerChannel> channel = new ossimPlanetIoSocketServerChannel;
+            channel->setName(a->arg(1));
+            if(channel->setSocket("",
+                                  ossimString(a->arg(2)).toUInt32(),
+                                  a->arg(3)))
+            {
+               addIo(channel.get());
+            }
+         }
+      }
+   }
+   // Can have the form of:
+   //     {ClientSocket {Name <name>} {Port <port>} {Ip <ip>} {Type <type>} {Terminator <eos|eol>} }
+   else if(command == "openConnection")
+   {
+      ossim_uint32 idx = 0;
+      ossimString objectName;
+      ossimString objectArg;
+      for(idx = 1; idx <= a->argCount(); ++idx)
+      {
+         if(mkUtils::extractObjectAndArg(objectName, objectArg, a->arg(idx)))
+         {
+            if(objectName == "ClientSocket")
+            {
+               osg::ref_ptr<ossimPlanetIoSocket> socket = 0;
+               ossimString name;
+               ossimString port;
+               ossimString ip;
+               ossimString type = "tcp";
+               char terminator = '\0';
+               ossimPlanetDestinationCommandAction nestedAction(": ClientSocket " + objectArg);
+               ossim_uint32 nestedIdx = 1;
+               for(;nestedIdx <= nestedAction.argCount(); ++nestedIdx)
+               {
+                  if(mkUtils::extractObjectAndArg(objectName, objectArg, nestedAction.arg(nestedIdx)))
+                  {
+                     if(objectName == "Port")
+                     {
+                        port = objectArg;
+                     }
+                     else if(objectName == "Ip")
+                     {
+                        ip = objectArg;
+                     }
+                     else if(objectName == "PortType")
+                     {
+                        type = objectArg;
+                     }
+                     else if(objectName == "Type")
+                     {
+                        std::cout << "Obsolete object arg.  Please use PortType instead of Type" << std::endl;
+                        type = objectArg;
+                     }
+                     else if(objectName == "Name")
+                     {
+                        name = objectArg;
+                     }
+                     else if(objectName == "Terminator")
+                     {
+                        if((objectArg == "nul")||
+                           (objectArg == "eos"))
+                        {
+                           terminator = '\0';
+                        }
+                        else if(objectArg == "eol")
+                        {
+                           terminator = '\n';
+                        }
+                     }
+                  }
+               }// end for nested action
+
+               if(!ip.empty() && !port.empty())
+               {
+                  osg::ref_ptr<ossimPlanetIo> io = findIo(name + ":" + port);
+                  if(!io.valid())
+                  {
+                     socket = new ossimPlanetIoSocket();
+                     socket->setName(name);
+                     socket->setTerminator(terminator);
+                     if(!socket->setSocket(ip, port.toInt32(), type))
+                     {
+                        socket = 0;
+                     }
+                  }
+               }
+               
+               if(socket.valid())
+               {
+                  addIo(socket.get());
+               }
+            }// end if ClientSocket
+         }
+      }
+   }
+   else if(command == "openClientSocket")
+   {
+      // This is a bidirectional client socket
+      osg::ref_ptr<ossimPlanetIoSocket> socket = 0;
+      if(a->argCount() == 3) // default tcp
+      {
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1) + ":" + a->arg(3));
+         if(!io.valid())
+         {
+            socket = new ossimPlanetIoSocket();
+            socket->setName(a->arg(1));
+            if(!socket->setSocket(a->arg(2),
+                                  ossimString(a->arg(3)).toInt32(),
+                                  "tcp"))
+            {
+               socket = 0;
+            }
+         }
+      }
+      else if(a->argCount() == 4) // specify the type
+      {
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1) + ":" + a->arg(3));
+         if(!io.valid())
+         {
+            socket = new ossimPlanetIoSocket();
+            socket->setName(a->arg(1));
+            
+            if(!socket->setSocket(a->arg(2),//host
+                                  ossimString(a->arg(3)).toInt32(), // port
+                                  a->arg(4)))
+            {
+               socket = 0;
+            }
+         }
+      }
+      if(socket.valid())
+      {
+         addIo(socket.get());
+      }
+   }
+   else if(command == "sendMessage")
+   {
+      // check for form <search name> <message>
+      if(a->argCount() == 2)
+      {
+         sendMessage(a->arg(1),
+                     new ossimPlanetMessage("", a->arg(2)));
+      }
+      else if(a->argCount() == 1)
+      {
+         sendMessage(new ossimPlanetMessage("", a->arg(1)));
+      }
+   }
+   else if(command == "removeIo")
+   {
+      if(a->argCount() == 1)
+      {
+         removeIoGivenSearchString(a->arg(1));
+      }
+   }
+   else if(command == "changeName")
+   {
+      if(a->argCount() == 2)
+      {
+         // need form of <search name> <new name>
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1));
+         if(io.valid())
+         {
+            io->setName(a->arg(2));
+         }
+      }
+   }
+   else if(command == "setTerminator")
+   {
+      if(a->argCount() == 2)
+      {
+         osg::ref_ptr<ossimPlanetIo> io = findIo(a->arg(1));
+         if(io.valid())
+         {
+            ossimString terminatorType = a->arg(2);
+            
+            char terminator;
+            if(terminatorType == "eos")
+            {
+               terminator = '\0';
+            }
+            else if(terminatorType == "eol")
+            {
+               terminator = '\n';
+            }
+            else
+            {
+               terminator = *(terminatorType.begin());
+            }
+            io->setTerminator(terminator);
+         }
+      }
+      else if(a->argCount() == 1)
+      {
+      }
+   }   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetJpegImage.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetJpegImage.cpp
new file mode 100644
index 0000000..113b46e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetJpegImage.cpp
@@ -0,0 +1,363 @@
+#include <ossimPlanet/ossimPlanetJpegImage.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <iostream>
+#include <fstream>
+
+extern "C" {
+#include <jpeglib.h>
+#include <setjmp.h>
+#define JPEG_IO_BUFFER_SIZE   2048
+#define OUTPUT_BUF_SIZE  4096    /* choose an efficiently fwrite'able size */
+  
+typedef struct {
+    struct jpeg_source_mgr pub;   /* public fields */
+
+    JOCTET* buffer;               /* start of buffer */
+   std::istream *stream;
+} ossimPlanet_source_mgr;
+typedef struct {
+    struct jpeg_destination_mgr pub;
+
+   std::ostream *stream;
+    JOCTET * buffer;
+} ossimPlanet_destination_mgr;
+
+typedef ossimPlanet_destination_mgr * ossimPlanet_dest_ptr;
+
+
+typedef ossimPlanet_source_mgr * ossimPlanet_src_ptr;
+
+   
+static void ossimPlanet_init_source ( j_decompress_ptr )
+{
+}
+#define OUTPUT_BUF_SIZE  4096    /* choose an efficiently fwrite'able size */
+
+static void init_destination (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+
+    /* Allocate the output buffer --- it will be released when done with image */
+    dest->buffer = (JOCTET *)
+        (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+        OUTPUT_BUF_SIZE * sizeof(JOCTET));
+    dest->pub.next_output_byte = dest->buffer;
+    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+static boolean empty_output_buffer (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+
+    dest->stream->write((char*)dest->buffer, OUTPUT_BUF_SIZE);
+    dest->pub.next_output_byte = dest->buffer;
+    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+    return TRUE;
+}
+	
+static void term_destination (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+    size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+    /* Write any data remaining in the buffer */
+    if (datacount > 0)
+       dest->stream->write((char*)dest->buffer, datacount);
+}
+
+static boolean ossimPlanet_fill_input_buffer ( j_decompress_ptr cinfo )
+{
+    ossimPlanet_src_ptr src = (ossimPlanet_src_ptr) cinfo->src;
+
+    src->pub.next_input_byte = src->buffer;
+    std::streamsize start = src->stream->tellg();
+    src->stream->read((char*)(src->buffer),
+                      JPEG_IO_BUFFER_SIZE).tellg();
+    std::streamsize end = src->stream->tellg();
+    
+    src->pub.bytes_in_buffer = end - start;
+
+    if (src->pub.bytes_in_buffer == 0) // check for end-of-stream
+    {
+        // Insert a fake EOI marker
+        src->buffer[0] = 0xFF;
+        src->buffer[1] = JPEG_EOI;
+        src->pub.bytes_in_buffer = 2;
+    }
+    return TRUE;
+}
+
+static void ossimPlanet_skip_input_data ( j_decompress_ptr cinfo, long num_bytes )
+{
+    if (num_bytes > 0)
+    {
+        ossimPlanet_src_ptr src = (ossimPlanet_src_ptr) cinfo->src;
+
+        while (num_bytes > (long)src->pub.bytes_in_buffer)
+        {
+            num_bytes -= (long) src->pub.bytes_in_buffer;
+            src->pub.fill_input_buffer(cinfo);
+        }
+        src->pub.next_input_byte += (size_t) num_bytes;
+        src->pub.bytes_in_buffer -= (size_t) num_bytes;
+    }
+}
+
+static void ossimPlanet_term_source ( j_decompress_ptr cinfo )
+{
+    ossimPlanet_src_ptr src = (ossimPlanet_src_ptr) cinfo->src;
+
+    if (src->pub.bytes_in_buffer > 0)
+       src->stream->seekg(-(long)src->pub.bytes_in_buffer, std::ios_base::cur);
+    delete[] src->buffer;
+}
+
+
+// JPEG error manager:
+
+struct ossimPlanet_error_mgr {
+  struct jpeg_error_mgr pub;    /* "public" fields */
+
+  jmp_buf setjmp_buffer;    /* for return to caller */
+};
+
+typedef struct ossimPlanet_error_mgr * ossimPlanet_error_ptr;
+
+/*
+ * Here's the routine that will replace the standard error_exit method:
+ */
+
+static void ossimPlanet_error_exit (j_common_ptr cinfo)
+{
+  /* cinfo->err really points to a ossimPlanet_error_mgr struct, so coerce pointer */
+  ossimPlanet_error_ptr myerr = (ossimPlanet_error_ptr) cinfo->err;
+
+  /* Always display the message. */
+  /* We could postpone this until after returning, if we chose. */
+  if (cinfo->err->output_message) (*cinfo->err->output_message) (cinfo);
+
+  /* Return control to the setjmp point */
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+   
+void ossimPlanet_jpeg_io_src( j_decompress_ptr cinfo, std::istream& infile )
+{
+    ossimPlanet_src_ptr src;
+
+    if (cinfo->src == NULL) {    /* first time for this JPEG object? */
+        cinfo->src = (struct jpeg_source_mgr *)
+            (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+            sizeof(ossimPlanet_source_mgr));
+    }
+    src = (ossimPlanet_src_ptr) cinfo->src;
+    src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+    src->buffer = new JOCTET[JPEG_IO_BUFFER_SIZE];
+    src->pub.next_input_byte = NULL; /* until buffer loaded */
+    src->stream = &infile;
+
+    src->pub.init_source = ossimPlanet_init_source;
+    src->pub.fill_input_buffer = ossimPlanet_fill_input_buffer;
+    src->pub.skip_input_data = ossimPlanet_skip_input_data;
+    src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+    src->pub.term_source = ossimPlanet_term_source;
+}
+
+static void ossimPlanet_init_destination (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+
+    /* Allocate the output buffer --- it will be released when done with image */
+    dest->buffer = (JOCTET *)
+        (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+        OUTPUT_BUF_SIZE * sizeof(JOCTET));
+    dest->pub.next_output_byte = dest->buffer;
+    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+static boolean ossimPlanet_empty_output_buffer (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+
+    dest->stream->write((char*)(dest->buffer), OUTPUT_BUF_SIZE);
+    dest->pub.next_output_byte = dest->buffer;
+    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+    return TRUE;
+}
+
+static void ossimPlanet_term_destination (j_compress_ptr cinfo)
+{
+    ossimPlanet_dest_ptr dest = (ossimPlanet_dest_ptr) cinfo->dest;
+    size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+    /* Write any data remaining in the buffer */
+    if (datacount > 0)
+       dest->stream->write((char*)(dest->buffer), datacount);
+}
+
+static void ossimPlanet_jpeg_io_dest (j_compress_ptr cinfo, std::ostream& outfile)
+{
+    ossimPlanet_dest_ptr dest;
+
+    if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
+        cinfo->dest = (struct jpeg_destination_mgr *)
+            (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+            sizeof(ossimPlanet_destination_mgr));
+    }
+
+    dest = (ossimPlanet_dest_ptr) cinfo->dest;
+    dest->pub.init_destination = ossimPlanet_init_destination;
+    dest->pub.empty_output_buffer = ossimPlanet_empty_output_buffer;
+    dest->pub.term_destination = ossimPlanet_term_destination;
+    dest->stream = &outfile;
+}
+
+
+
+ossimPlanetJpegImage::ossimPlanetJpegImage()
+{
+}
+
+ossimPlanetJpegImage::~ossimPlanetJpegImage()
+{
+}
+
+bool ossimPlanetJpegImage::loadFile(std::istream& inputStream,
+                                  ossimPlanetImage& image)
+{
+    struct jpeg_decompress_struct cinfo;
+    struct ossimPlanet_error_mgr jerr;
+    JSAMPARRAY tempbuf;
+    unsigned char *ptr;
+    unsigned stride;
+
+    cinfo.err = jpeg_std_error( &jerr.pub );
+    jerr.pub.error_exit = ossimPlanet_error_exit;
+
+    cinfo.err->output_message=NULL;
+
+    /* Establish the setjmp return context for ossimPlanet_error_exit to use. */
+    if (setjmp(jerr.setjmp_buffer)) {
+      /* If we get here, the JPEG code has signaled an error.
+       * We need to clean up the JPEG object, close the input file, and return.
+       */
+      (cinfo.src->term_source)(&cinfo);
+      jpeg_destroy_decompress(&cinfo);
+      return FALSE;
+    }
+
+    jpeg_create_decompress( &cinfo );
+    ossimPlanet_jpeg_io_src( &cinfo, inputStream );
+    jpeg_read_header( &cinfo, TRUE );
+    cinfo.out_color_space = JCS_RGB;
+    jpeg_start_decompress( &cinfo );
+
+    image.allocateImage(cinfo.image_width,
+                        cinfo.image_height,
+                        1,
+                        GL_RGB,               
+                        GL_UNSIGNED_BYTE);
+//    image.create(cinfo.image_width, cinfo.image_height);
+    ptr = image.data();
+    stride = cinfo.output_width * 3;
+    tempbuf = (*cinfo.mem->alloc_sarray)
+        ((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1 );
+
+    while ( cinfo.output_scanline < cinfo.output_height )
+    {
+        jpeg_read_scanlines( &cinfo, tempbuf, 1 );
+        memcpy( ptr, tempbuf[0], stride );
+        ptr += stride;
+    }
+    jpeg_finish_decompress( &cinfo );
+    jpeg_destroy_decompress( &cinfo );
+    
+    return TRUE;
+}
+
+bool ossimPlanetJpegImage::saveFile( std::ostream& stream,
+                                   ossimPlanetImage &image,
+                                   bool verbose )
+{
+    struct jpeg_compress_struct cinfo;
+    struct ossimPlanet_error_mgr jerr;
+    JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
+    JSAMPLE *image_buffer;
+    int stride;                /* physical row width in image buffer */
+
+    cinfo.err = jpeg_std_error(&jerr.pub);
+    jerr.pub.error_exit = ossimPlanet_error_exit;
+
+    if (!verbose) cinfo.err->output_message=NULL;
+
+    /* Establish the setjmp return context for my_error_exit to use. */
+    if (setjmp(jerr.setjmp_buffer))
+    {
+        /* If we get here, the JPEG code has signaled an error.
+         * We need to clean up the JPEG object, close the input file, and return.
+         */
+         jpeg_destroy_compress(&cinfo);
+         return false;
+    }
+
+    jpeg_create_compress(&cinfo);
+    ossimPlanet_jpeg_io_dest(&cinfo, stream);
+
+    cinfo.image_width      = image.getWidth();
+    cinfo.image_height     = image.getHeight();
+    cinfo.input_components = 3;
+    cinfo.in_color_space = JCS_RGB;
+    jpeg_set_defaults(&cinfo);
+
+    // TODO: 3rd parameter is force_baseline, what value should this be?
+    // Code says: "If force_baseline is TRUE, the computed quantization table entries
+    // are limited to 1..255 for JPEG baseline compatibility."
+    // 'Quality' is a number between 0 (terrible) and 100 (very good).
+    // The default (in jcparam.c, jpeg_set_defaults) is 75,
+    // and force_baseline is TRUE.
+    jpeg_set_quality(&cinfo, 100, TRUE);
+
+    jpeg_start_compress(&cinfo, TRUE);
+
+    stride = cinfo.image_width * 3;    /* JSAMPLEs per row in image_buffer */
+    image_buffer = image.data();
+    ossim_uint32 scanlineTemp = cinfo.next_scanline;
+    while (cinfo.next_scanline < cinfo.image_height)
+    {
+        row_pointer[0] = &image_buffer[cinfo.next_scanline * stride];
+        jpeg_write_scanlines( &cinfo, row_pointer, 1 );
+        if(scanlineTemp == cinfo.next_scanline)
+        {
+           ++cinfo.next_scanline;
+        }
+        scanlineTemp = cinfo.next_scanline;
+    }
+    jpeg_finish_compress(&cinfo);
+    jpeg_destroy_compress(&cinfo);
+
+    return true;
+}
+
+bool ossimPlanetJpegImage::loadFile(std::string& inputFile,
+                                  ossimPlanetImage& image)
+{
+   std::ifstream in(inputFile.c_str(),
+                    std::ios::in|std::ios::binary);
+   if(in)
+   {
+      return loadFile(in, image);
+   }
+   return false;
+}
+   
+bool ossimPlanetJpegImage::saveFile(std::string& outputFile,
+                                  ossimPlanetImage& image)
+{
+   std::ofstream out(outputFile.c_str(),
+                     std::ios::out|std::ios::binary);
+   if(out)
+   {
+      return saveFile(out, image);
+   }
+   return false;
+}
+  
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKml.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKml.cpp
new file mode 100644
index 0000000..e26db79
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKml.cpp
@@ -0,0 +1,2818 @@
+#include <ossimPlanet/ossimPlanetKml.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetSetup.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <wms/wmsCurlMemoryStream.h>
+
+#include <queue>
+#ifdef OSSIMPLANET_HAS_LIBZ
+#include <ossimPlanet/unzip.h>
+#endif
+
+static std::istream& kmlskipws(std::istream& in)
+{
+   int c = in.peek();
+   while(!in.fail()&&
+         ((c == ' ') ||
+         (c == '\t') ||
+         (c == '\n')||
+	 (c == '\r')))
+   {
+      in.ignore(1);
+      c = in.peek();
+   }
+   
+   return in;
+}
+
+static void kmlReadCoordinates(ossimPlanetKmlGeometry::PointListType& pointListResult,
+                            std::istream& in)
+{
+   bool pointIsGood = true;
+   osg::Vec3d point;
+   while(!in.fail())
+   {
+      in >>point[0]>>kmlskipws;
+      in.ignore();
+      in >>point[1]>>kmlskipws;
+	  
+	  // if we get at least 2 values then we are good
+      pointIsGood = !in.fail();
+      point[2] = 0.0;
+      if(in.peek() == ',')
+      {
+         in.ignore();
+         in >> point[2];
+      }
+      
+      in>>kmlskipws;
+      
+      if(in.peek() == ',')
+      {
+         in.ignore(); // we will suport separated by commas even though the spec says spaces
+      }
+      if(pointIsGood)
+      {
+         pointListResult.push_back(point);
+      }
+   }
+}
+
+static void kmlReadCoordinates(ossimPlanetKmlGeometry::PointListType& pointListResult,
+                            const ossimString& inString)
+{
+   if(inString.empty()) return;
+   std::vector<ossimString> points;
+   inString.split(points, " \n\t\r");
+   ossim_uint32 idx = 0;
+   osg::Vec3d point;
+   for(idx = 0; idx < points.size(); ++idx)
+   {
+	   std::vector<ossimString> coordinate;
+	   points[idx].split(coordinate, ",");
+	   if(coordinate.size() >= 2)
+	   {
+	      point[0] = coordinate[0].toDouble();
+	      point[1] = coordinate[1].toDouble();
+		  if(coordinate.size() > 2)
+		  {
+			point[2] = coordinate[2].toDouble();
+		  }
+		  else
+		  {
+			point[2] = 0.0;
+		  }
+		  pointListResult.push_back(point);
+	   }
+   }
+   //std::istringstream in(inString);
+   //kmlReadCoordinates(pointListResult, in);
+}
+
+ossimPlanetKmlObjectRegistry* ossimPlanetKmlObjectRegistry::theInstance = 0;
+ossimPlanetKmlObjectRegistry::ossimPlanetKmlObjectRegistry()
+{
+   theInstance = this;
+}
+
+
+ossimPlanetKmlObjectRegistry* ossimPlanetKmlObjectRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetKmlObjectRegistry;
+   }
+
+   return theInstance;
+} 
+ossimPlanetKmlObject* ossimPlanetKmlObjectRegistry::newObject(const ossimString& tag)const
+{
+   if(tag == "Document")
+   {
+      return new ossimPlanetKmlDocument;
+   }
+   else if(tag == "Placemark")
+   {
+      return new ossimPlanetKmlPlacemark;
+   }
+   else if(tag == "Folder")
+   {
+      return new ossimPlanetKmlFolder;
+   }
+   else if(tag == "Icon")
+   {
+      return new ossimPlanetKmlIcon;
+   }
+   else if(tag == "LatLonBox")
+   {
+      return new ossimPlanetKmlLatLonBox;
+   }
+   else if(tag == "LatLonAltBox")
+   {
+      return new ossimPlanetKmlLatLonAltBox;
+   }
+   else if(tag == "GroundOverlay")
+   {
+      return new ossimPlanetKmlGroundOverlay;
+   }
+   else if(tag == "ScreenOverlay")
+   {
+      return new ossimPlanetKmlScreenOverlay;
+   }
+   else if(tag == "Point")
+   {
+      return new ossimPlanetKmlPoint;
+   }
+   else if(tag == "NetworkLink")
+   {
+      return new ossimPlanetKmlNetworkLink;
+   }
+   else if(tag == "Orientation")
+   {
+      return new ossimPlanetKmlOrientation;
+   }
+   else if(tag == "Location")
+   {
+      return new ossimPlanetKmlLocation;
+   }
+   else if(tag == "Scale")
+   {
+      return new ossimPlanetKmlScale;
+   }
+   else if(tag == "Lod")
+   {
+      return new ossimPlanetKmlLod;
+   }
+   else if(tag == "Region")
+   {
+      return new ossimPlanetKmlRegion;
+   }
+   else if(tag == "BalloonStyle")
+   {
+      return new ossimPlanetKmlBalloonStyle;
+   }
+   else if(tag == "Style")
+   {
+      return new ossimPlanetKmlStyle;
+   }
+   else if(tag == "StyleMap")
+   {
+      return new ossimPlanetKmlStyleMap;
+   }
+   ossimPlanetKmlObject* obj = newTimePrimitive(tag);
+   if(obj)
+   {
+      return obj;
+   }
+   obj = newColorStyle(tag);
+   if(obj)
+   {
+      return obj;
+   }
+   return newGeometry(tag);
+}
+
+ossimPlanetKmlObject* ossimPlanetKmlObjectRegistry::newGeometry(const ossimString& tag)const
+{
+   if(tag == "Point")
+   {
+      return new ossimPlanetKmlPoint;
+   }
+   else if(tag == "LineString")
+   {
+      return new ossimPlanetKmlLineString;
+   }
+   else if(tag == "LinearRing")
+   {
+      return new ossimPlanetKmlLinearRing;
+   }
+   else if(tag == "Polygon")
+   {
+      return new ossimPlanetKmlPolygon;
+   }
+   else if((tag == "MultiGeometry")||
+           (tag == "GeometryCollection"))
+   {
+      return new ossimPlanetKmlMultiGeometry;
+   }
+   else if(tag == "Model")
+   {
+      return new ossimPlanetKmlModel;
+   }
+   return 0;
+}
+
+ossimPlanetKmlObject* ossimPlanetKmlObjectRegistry::newColorStyle(const ossimString& tag)const
+{
+   if(tag == "LineStyle")
+   {
+      return new ossimPlanetKmlLineStyle;
+   }
+   else if(tag == "PolyStyle")
+   {
+      return new ossimPlanetKmlPolyStyle;
+   }
+   else if(tag == "IconStyle")
+   {
+      return new ossimPlanetKmlIconStyle;
+   }
+   else if(tag == "LabelStyle")
+   {
+      return new ossimPlanetKmlLabelStyle;
+   }
+   return 0;
+}
+
+ossimPlanetKmlObject* ossimPlanetKmlObjectRegistry::newTimePrimitive(const ossimString& tag)const
+{
+   if(tag == "TimeSpan")
+   {
+      return new ossimPlanetKmlTimeSpan;
+   }
+   else if(tag == "TimeStamp")
+   {
+      return new ossimPlanetKmlTimeStamp;
+   }
+
+   return 0;
+}
+
+ossimPlanetKmlObject* ossimPlanetKmlObjectRegistry::newObject(const ossimXmlNode* tag)const
+{
+   if(tag)
+   {
+      return newObject(tag->getTag());
+      
+   }
+
+   return 0;
+}
+
+bool ossimPlanetKmlObject::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   if(!xmlNode.valid()) return false;
+
+   xmlNode->getAttributeValue(theId, "id");
+   xmlNode->getAttributeValue(theTargetId, "targetId");
+   
+   return true;
+}
+
+void ossimPlanetKmlObject::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   if(!xmlNode.valid()) return;
+   if(!theId.empty())
+   {
+      xmlNode->addAttribute("id", theId);
+   }
+   if(!theTargetId.empty())
+   {
+      xmlNode->addAttribute("targetId", theTargetId);      
+   }
+}
+
+ossimPlanetKmlObject* ossimPlanetKmlObject::getRoot(ossimPlanetKmlObject* start)
+{
+   ossimPlanetKmlObject* root = start;
+
+   if(!root) return 0;
+   while(root->getParent()) root = root->getParent();
+   return root;
+}
+
+ossimFilename ossimPlanetKmlObject::getKmlFile()const
+{
+   if(getParent()) return getParent()->getKmlFile();
+
+   return "";
+}
+
+const ossimPlanetKmlObject* ossimPlanetKmlObject::getRoot(const ossimPlanetKmlObject* start)
+{
+   const ossimPlanetKmlObject* root = start;
+
+   if(!root) return 0;
+   while(root->getParent()) root = root->getParent();
+   return root;
+}
+
+
+ossimFilename ossimPlanetKmlObject::getCacheLocation(bool sharedLocationFlag)const
+{
+   const ossimPlanetKmlObject* kmlObject = getRoot(this);
+
+   const ossimPlanetKml* kml = dynamic_cast<const ossimPlanetKml*>(kmlObject);
+
+   if(kml)
+   {
+      return kml->getCacheLocation(sharedLocationFlag);
+   }
+
+   if(sharedLocationFlag)
+   {
+      ossimFilename sharedDir = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+      sharedDir = sharedDir.dirCat("kml");
+      if(!sharedDir.exists())
+      {
+         sharedDir.createDirectory();
+      }
+      return sharedDir;
+   }
+   return "";
+}
+
+bool ossimPlanetKmlBalloonStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+
+   ossim_uint32 idx;
+   ossim_uint32 upper=childNodes.size();
+
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "bgColor")
+      {
+         theBackgroundColor = childNodes[idx]->getText();
+         theBackgroundColor = theBackgroundColor.trim();
+      }
+      else if(tag == "textColor")
+      {
+         theTextColor = childNodes[idx]->getText();
+         theTextColor = theTextColor.trim();
+      }
+      else if(tag == "text")
+      {
+         theText = childNodes[idx]->getText();
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlBalloonStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+   
+   xmlNode->setTag("BalloonStyle");
+   xmlNode->addChildNode("bgColor", theBackgroundColor);
+   xmlNode->addChildNode("textColor", theTextColor);
+   xmlNode->addChildNode("text", theText);
+}
+
+bool ossimPlanetKmlLod::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+
+   ossim_uint32 idx;
+   ossim_uint32 upper=childNodes.size();
+
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+
+      if(tag == "minLodPixels")
+      {
+         theMinLodPixels = childNodes[idx]->getText().toInt32();
+      }
+      else if(tag == "maxLodPixels")
+      {
+         theMaxLodPixels = childNodes[idx]->getText().toInt32();
+      }
+      else if(tag == "minFadeExtent")
+      {
+         theMinFadeExtent = childNodes[idx]->getText().toInt32();
+      }
+      else if(tag == "maxFadeExtent")
+      {
+         theMaxFadeExtent = childNodes[idx]->getText().toInt32();
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlLod::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("Lod");
+   
+   xmlNode->addChildNode("minLodPixels", ossimString::toString(theMinLodPixels));
+   xmlNode->addChildNode("maxLodPixels", ossimString::toString(theMaxLodPixels));
+   xmlNode->addChildNode("minFadeExtent", ossimString::toString(theMinFadeExtent));
+   xmlNode->addChildNode("maxFadeExtent", ossimString::toString(theMaxFadeExtent));
+   
+   ossimPlanetKmlObject::write(xmlNode);   
+}
+
+bool ossimPlanetKmlScale::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+
+   for(idx = 0; idx< upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "x")
+      {
+         theX = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "y")
+      {
+         theY = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "z")
+      {
+          theZ = childNodes[idx]->getText().toDouble();
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlScale::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("Scale");
+   
+   xmlNode->addChildNode("x", ossimString::toString(theX));
+   xmlNode->addChildNode("y", ossimString::toString(theY));
+   xmlNode->addChildNode("z", ossimString::toString(theZ));
+
+   ossimPlanetKmlObject::write(xmlNode);
+}
+
+bool ossimPlanetKmlLocation::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+
+   for(idx = 0; idx< upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "longitude")
+      {
+         theLongitude = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "latitude")
+      {
+         theLatitude = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "altitude")
+      {
+         theAltitude = childNodes[idx]->getText().toDouble();
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlLocation::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("Location");
+
+   xmlNode->addChildNode("longitude",ossimString::toString(theLongitude));
+   xmlNode->addChildNode("latitude", ossimString::toString(theLatitude));
+   xmlNode->addChildNode("altitude", ossimString::toString(theAltitude));
+   
+   ossimPlanetKmlObject::write(xmlNode);
+}
+
+bool ossimPlanetKmlOrientation::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+
+   for(idx = 0; idx< upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "heading")
+      {
+         theHeading = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "tilt")
+      {
+         thePitch = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "roll")
+      {
+          theRoll = childNodes[idx]->getText().toDouble();
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlOrientation::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("Orientation");
+   xmlNode->addChildNode("heading", ossimString::toString(theHeading));
+   xmlNode->addChildNode("tilt", ossimString::toString(thePitch));
+   xmlNode->addChildNode("roll", ossimString::toString(theRoll));
+}
+
+bool ossimPlanetKmlLatLonBox::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempText;
+   if(!xmlNode->getChildTextValue(tempText, "north"))
+   {
+      return false;
+   }
+   theNorth = tempText.toDouble();
+   if(!xmlNode->getChildTextValue(tempText, "south"))
+   {
+      return false;
+   }
+   theSouth = tempText.toDouble();
+   if(!xmlNode->getChildTextValue(tempText, "east"))
+   {
+      return false;
+   }
+   theEast = tempText.toDouble();
+   if(!xmlNode->getChildTextValue(tempText, "west"))
+   {
+      return false;
+   }
+   theWest = tempText.toDouble();
+   
+   if(xmlNode->getChildTextValue(tempText, "rotation"))
+   {
+      theRotation = tempText.toDouble();
+   }
+   return true;
+}
+void ossimPlanetKmlLatLonBox::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("LatLonBox");
+   xmlNode->addChildNode("north", ossimString::toString(theNorth));
+   xmlNode->addChildNode("south", ossimString::toString(theSouth));
+   xmlNode->addChildNode("east",  ossimString::toString(theEast));
+   xmlNode->addChildNode("west",  ossimString::toString(theWest));
+   xmlNode->addChildNode("rotation", ossimString::toString(theRotation));
+}
+
+bool ossimPlanetKmlLatLonAltBox::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlLatLonBox::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempText;
+   if(xmlNode->getChildTextValue(tempText, "minAltitude"))
+   {
+      theMinAltitude = tempText.toDouble();
+   }
+   if(xmlNode->getChildTextValue(tempText, "maxAltitude"))
+   {
+      theMaxAltitude = tempText.toDouble();
+   }
+   ossimString altMode;
+   xmlNode->getChildTextValue(altMode, "altitudeMode");
+   theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(altMode);
+   
+   return true;
+}
+
+void ossimPlanetKmlLatLonAltBox::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlLatLonBox::write(xmlNode);
+   xmlNode->setTag("LatLonAltBox");
+   xmlNode->addChildNode("minAltitude", ossimString::toString(theMinAltitude));
+   xmlNode->addChildNode("maxAltitude", ossimString::toString(theMaxAltitude));
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+}
+
+bool ossimPlanetKmlColorStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+
+   ossim_uint32 idx;
+   ossim_uint32 upper = childNodes.size();;
+   ossim_uint32 count = 0;
+   for(idx = 0; ((idx < upper)&&(count < 2)); ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "color")
+      {
+         theColor = childNodes[idx]->getText();
+         ++count;
+      }
+      else if(tag == "colorMode")
+      {
+         theColorMode = ossimPlanetKmlConvertColorMode(childNodes[idx]->getText());
+         ++count;
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlColorStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+   xmlNode->setTag("ColorStyle");
+   xmlNode->addChildNode("color", theColor);
+   xmlNode->addChildNode("colorMode", ossimPlanetKmlConvertColorMode(theColorMode));
+}
+
+bool ossimPlanetKmlLineStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   if(!ossimPlanetKmlColorStyle::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempString;
+
+   if(xmlNode->getChildTextValue(tempString, "width"))
+   {
+      theWidth = tempString.toFloat32();
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlLineStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlColorStyle::write(xmlNode);
+   xmlNode->setTag("LineStyle");
+   xmlNode->addChildNode("width", ossimString::toString(theWidth));
+}
+
+bool ossimPlanetKmlPolyStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   if(!ossimPlanetKmlColorStyle::parse(xmlNode))
+   {
+      return false;
+   }
+
+   ossimString tempString;
+
+   if(xmlNode->getChildTextValue(tempString, "fill"))
+   {
+      theFillFlag = tempString.toBool();
+   }
+
+   if(xmlNode->getChildTextValue(tempString, "outline"))
+   {
+      theOutlineFlag = tempString.toBool();
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlPolyStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlColorStyle::write(xmlNode);
+   xmlNode->setTag("PolyStyle");
+   xmlNode->addChildNode("fill", theFillFlag?"1":"0");   
+   xmlNode->addChildNode("outline", theOutlineFlag?"1":"0");   
+}
+
+bool ossimPlanetKmlIconStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlColorStyle::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   ossim_uint32 count = 0;
+   for(idx = 0; ((idx< upper)&&(count < 4)); ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+
+      if(tag == "scale")
+      {
+         theScale = childNodes[idx]->getText().toDouble();
+         ++count;
+      }
+      else if(tag == "heading")
+      {
+         theHeading = childNodes[idx]->getText().toDouble();
+         ++count;
+      }
+      else if(tag == "Icon")
+      {
+         theIcon = new ossimPlanetKmlIcon;
+         theIcon->setParent(this);
+         if(!theIcon->parse(childNodes[idx]))
+         {
+            theIcon = 0;
+            return false;
+         }
+         ++count;
+      }
+      else if(tag == "hotSpot")
+      {
+         ossimString tempString;
+         if(childNodes[idx]->getAttributeValue(tempString, "x"))
+         {
+            theXHotspot = tempString.toFloat32();
+         }
+         if(childNodes[idx]->getAttributeValue(tempString, "y"))
+         {
+            theYHotspot = tempString.toFloat32();
+         }
+         if(childNodes[idx]->getAttributeValue(tempString, "xunits"))
+         {
+            theXUnits   = ossimPlanetKmlConvertUnits(tempString);
+         }
+         if(childNodes[idx]->getAttributeValue(tempString, "yunits"))
+         {
+            theYUnits   = ossimPlanetKmlConvertUnits(tempString);
+         }
+         
+         ++count;
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlIconStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlColorStyle::write(xmlNode);
+   xmlNode->setTag("IconStyle");
+   xmlNode->addChildNode("scale", ossimString::toString(theScale));
+   xmlNode->addChildNode("heading", ossimString::toString(theHeading));
+   if(theIcon.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theIcon->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+   node->setTag("hotSpot");
+   node->addAttribute("x", ossimString::toString(theXHotspot));
+   node->addAttribute("y", ossimString::toString(theYHotspot));
+   node->addAttribute("xunits", ossimPlanetKmlConvertUnits(theXUnits));
+   node->addAttribute("yunits", ossimPlanetKmlConvertUnits(theYUnits));
+}
+
+bool ossimPlanetKmlLabelStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+
+   if(!ossimPlanetKmlColorStyle::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempText;
+   if(xmlNode->getChildTextValue(tempText, "scale"))
+   {
+      theScale = tempText.toDouble();
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlLabelStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlColorStyle::write(xmlNode);
+   xmlNode->setTag("LabelStyle");
+   xmlNode->addChildNode("scale", ossimString::toString(theScale));
+}
+
+bool ossimPlanetKmlStyle::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlStyleSelector::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "LineStyle")
+      {
+         theLineStyle = new ossimPlanetKmlLineStyle;
+         theLineStyle->setParent(this);
+         if(!theLineStyle->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "IconStyle")
+      {
+         theIconStyle = new ossimPlanetKmlIconStyle;
+         theIconStyle->setParent(this);
+         if(!theIconStyle->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "LabelStyle")
+      {
+         theLabelStyle = new ossimPlanetKmlLabelStyle;
+         theLabelStyle->setParent(this);
+         if(!theLabelStyle->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "PolyStyle")
+      {
+         thePolyStyle = new ossimPlanetKmlPolyStyle;
+         thePolyStyle->setParent(this);
+         if(!thePolyStyle->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "BalloonStyle")
+      {
+         theBalloonStyle = new ossimPlanetKmlBalloonStyle;
+         theBalloonStyle->setParent(this);
+         if(!theBalloonStyle->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlStyle::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlStyleSelector::write(xmlNode);
+   xmlNode->setTag("Style");
+   if(theIconStyle.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theIconStyle->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   if(theLabelStyle.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theLabelStyle->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   if(theLineStyle.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theLineStyle->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   if(thePolyStyle.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      thePolyStyle->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   if(theBalloonStyle.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theBalloonStyle->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+bool ossimPlanetKmlStyleMap::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlStyleSelector::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+
+      if(tag == "Pair")
+      {
+         ossimString key;
+         ossimString value;
+         if( childNodes[idx]->getChildTextValue(key, "key")&&
+             childNodes[idx]->getChildTextValue(value, "styleUrl"))
+         {
+//             if(key == "normal")
+//             {
+//                theNormalUrl = value;
+//             }
+//             else if(key == "highlight")
+//             {
+//                theHighlightUrl = value;
+//             }
+            theStyleMap.insert(std::make_pair(key.c_str(), value.c_str()));
+         }
+      }
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlStyleMap::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlStyleSelector::write(xmlNode);
+   xmlNode->setTag("StyleMap");
+   MapType::const_iterator i = theStyleMap.begin();
+   while(i != theStyleMap.end())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      
+      node->setTag("Pair");
+      node->addChildNode(ossimString(i->first), ossimString(i->second));
+      xmlNode->addChildNode(node.get());
+      
+      ++i;
+   }
+}
+
+bool ossimPlanetKmlLink::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempText;
+
+   xmlNode->getChildTextValue(theHref, "href");
+   xmlNode->getChildTextValue(tempText, "refreshMode");
+   theRefreshMode = ossimPlanetKmlConvertRefreshMode(tempText);
+   
+   xmlNode->getChildTextValue(tempText, "viewRefreshMode");
+   theViewRefreshMode = ossimPlanetKmlConvertViewRefreshMode(tempText);
+   xmlNode->getChildTextValue(theViewFormat, "viewFormat");
+   xmlNode->getChildTextValue(theHttpQuery, "httpQuery");
+   if(xmlNode->getChildTextValue(tempText, "refreshInterval"))
+   {
+      theRefreshInterval = tempText.toDouble();
+   }
+   if(xmlNode->getChildTextValue(tempText, "viewRefreshTime"))
+   {
+      theViewRefreshTime = tempText.toDouble();
+   }
+   if(xmlNode->getChildTextValue(tempText, "viewBoundScale"))
+   {
+      theViewBoundScale = tempText.toDouble();
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlLink::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+   xmlNode->setTag("Link");
+   xmlNode->addChildNode("href", theHref);
+   xmlNode->addChildNode("refreshMode", ossimPlanetKmlConvertRefreshMode(theRefreshMode));
+   xmlNode->addChildNode("viewRefreshMode", ossimPlanetKmlConvertViewRefreshMode(theViewRefreshMode));
+   xmlNode->addChildNode("viewFormat", theViewFormat);
+   xmlNode->addChildNode("httpQuery", theHttpQuery);
+   xmlNode->addChildNode("refreshInterval", ossimString::toString(theRefreshInterval));
+   xmlNode->addChildNode("viewRefreshTime", ossimString::toString(theViewRefreshTime));
+   xmlNode->addChildNode("viewBoundScale", ossimString::toString(theViewBoundScale));
+                         
+}
+
+ossimFilename ossimPlanetKmlLink::download(bool forceOverwrite,
+                                           const ossimFilename& locationOverride)const
+{
+   ossimFilename fileToLoad = theHref;
+   
+   if(ossimFilename(fileToLoad).downcase().contains("http"))
+   {
+      if(locationOverride == "")
+      {
+         fileToLoad = getCacheLocation(true); // will use the root kml to find the cache location
+         if(fileToLoad == "")
+         {
+            return "";
+         }
+//          ossimFilename temp(ossimString(wmsUrl(theHref).path()).after("/"));
+         ossimFilename temp(wmsUrl(theHref.string()).server());
+         temp = ossimFilename(temp.substitute(".", "_", true));
+         temp = temp.dirCat(ossimFilename(wmsUrl(theHref.string()).path()));
+         fileToLoad = fileToLoad.dirCat(temp);
+         ossimFilename path = fileToLoad.path();
+         path.createDirectory();
+      }
+      else
+      {
+         fileToLoad = locationOverride;
+      }
+      
+      if((!fileToLoad.exists())||
+         (forceOverwrite))
+      {
+         ossimFilename tempFile = ossimFilename(fileToLoad + ".tmp");
+         wmsCurlMemoryStream netDownload(theHref);
+         
+         if(!netDownload.download(tempFile))
+         {
+            return "";
+         }
+         tempFile.rename(fileToLoad, true);
+         
+      }
+   }
+   else if(!fileToLoad.exists())// check absolute and relative
+   {
+      ossimFilename file = getKmlFile();
+      if(!file.empty())
+      {
+         ossimFilename testFile = file.path().dirCat(fileToLoad);
+         if(testFile.exists())
+         {
+            fileToLoad = testFile;
+         }
+      }
+   }
+   // really need to check other protocols.  Maybe need to check for file:// and convert to
+   // local file 
+   //
+
+   return fileToLoad;
+}
+
+bool ossimPlanetKmlIcon::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   return ossimPlanetKmlLink::parse(xmlNode);
+}
+
+void ossimPlanetKmlIcon::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlLink::write(xmlNode);
+   xmlNode->setTag("Icon");
+}
+
+bool ossimPlanetKmlRegion::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid()) return false;
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+
+      if(tag == "Lod")
+      {
+         theLod = new ossimPlanetKmlLod;
+         theLod->setParent(this);
+         if(!theLod->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "LatLonAltBox")
+      {
+         theBox = new ossimPlanetKmlLatLonAltBox;
+         theBox->setParent(this);
+         if(!theBox->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+   }
+
+   return theBox.valid();
+}
+
+
+void ossimPlanetKmlRegion::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+   
+   xmlNode->setTag("Region");
+   if(theLod.valid())
+   {
+      ossimRefPtr<ossimXmlNode> lodNode = new ossimXmlNode;
+      theLod->write(lodNode.get());
+      xmlNode->addChildNode(lodNode.get());
+   }
+   if(theBox.valid())
+   {
+      ossimRefPtr<ossimXmlNode> boxNode = new ossimXmlNode;
+      theBox->write(boxNode.get());
+      xmlNode->addChildNode(boxNode.get());
+   }
+}
+
+bool ossimPlanetKmlLookAt::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempText;
+   if(!xmlNode->getChildTextValue(tempText, "longitude"))
+   {
+      return false;
+   }
+   theLookAt->setLon(tempText.toDouble());
+   if(!xmlNode->getChildTextValue(tempText, "latitude"))
+   {
+      return false;
+   }
+   theLookAt->setLat(tempText.toDouble());
+   if(!xmlNode->getChildTextValue(tempText, "range"))
+   {
+      return false;
+   }
+   theLookAt->setRange(tempText.toDouble());
+
+   if(xmlNode->getChildTextValue(tempText, "altitude"))
+   {
+      theLookAt->setAltitude(tempText.toDouble());
+   }
+
+   if(xmlNode->getChildTextValue(tempText, "tilt"))
+   {
+      theLookAt->setPitch(tempText.toDouble());
+      theLookAt->setPitch(mkUtils::clamp(theLookAt->pitch(), (double)0.0, (double)90.0));
+   }
+
+   if(xmlNode->getChildTextValue(tempText, "heading"))
+   {
+      theLookAt->setHeading(tempText.toDouble());
+   }
+   if(xmlNode->getChildTextValue(tempText, "altitudeMode"))
+   {
+      theLookAt->setAltitudeMode(ossimPlanetLookAt::modeFromString(tempText));
+   }
+   
+   return true;
+}
+
+void ossimPlanetKmlLookAt::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+   xmlNode->setTag("LookAt");
+
+   xmlNode->addChildNode("longitude", ossimString::toString(theLookAt->lon()));
+   xmlNode->addChildNode("latitude", ossimString::toString(theLookAt->lat()));
+   xmlNode->addChildNode("range", ossimString::toString(theLookAt->range()));
+   xmlNode->addChildNode("altitude", ossimString::toString(theLookAt->altitude()));
+   xmlNode->addChildNode("tilt", ossimString::toString(theLookAt->pitch()));
+   xmlNode->addChildNode("heading", ossimString::toString(theLookAt->heading()));
+   xmlNode->addChildNode("altitudeMode", ossimPlanetLookAt::modeToString(theLookAt->altitudeMode()));
+}
+
+bool ossimPlanetKmlTimeSpan::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   
+   xmlNode->getChildTextValue(theBegin, "begin");
+   xmlNode->getChildTextValue(theEnd, "end");
+  
+   return true;
+}
+
+void ossimPlanetKmlTimeSpan::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlTimePrimitive::write(xmlNode);
+   xmlNode->setTag("TimeSpan");
+
+   if(!theBegin.empty())
+   {
+      xmlNode->addChildNode("begin", theBegin);
+   }
+   if(!theEnd.empty())
+   {
+      xmlNode->addChildNode("end", theEnd);      
+   }
+}
+
+bool ossimPlanetKmlTimeStamp::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   
+   xmlNode->getChildTextValue(theWhen, "when");
+
+   return true;
+}
+
+void ossimPlanetKmlTimeStamp::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   xmlNode->setTag("TimeStamp");
+   ossimPlanetKmlTimePrimitive::write(xmlNode);
+   xmlNode->addChildNode("when", theWhen);
+}
+
+bool ossimPlanetKmlFeature::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!xmlNode.valid()) return false;
+   if(!ossimPlanetKmlObject::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      ossimString tempString;
+
+      if(tag == "name")
+      {
+         theName = childNodes[idx]->getText();
+      }
+      else if(tag == "visibility")
+      {
+         theVisibilityFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "open")
+      {
+         theOpenFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "address")
+      {
+         theAddress = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "phoneNumber")
+      {
+         theAddress = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "Region")
+      {
+         theRegion = new ossimPlanetKmlRegion();
+         theRegion->setParent(this);
+         if(!theRegion->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "description")
+      {
+         theDescription = childNodes[idx]->getText();
+         theCDataDescriptionFlag = childNodes[idx]->cdataFlag();
+         if(!theCDataDescriptionFlag)
+         {
+            theDescription = ossim::convertHtmlSpecialCharactersToNormalCharacter(theDescription);
+         }
+      }
+      else if(tag == "LookAt")
+      {
+         theLookAt = new ossimPlanetKmlLookAt();
+         theLookAt->setParent(this);
+         if(!theLookAt->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "styleUrl")
+      {
+         theStyleUrl = childNodes[idx]->getText();
+      }
+      else if(tag == "Snippet")
+      {
+         theSnippet = childNodes[idx]->getText();
+         childNodes[idx]->getAttributeValue(theSnippetMaxLines, "maxLines");
+      }
+      else if(tag == "Metadata")
+      {
+         theExtendedData = childNodes[idx];
+      }
+      else if(tag == "ExtendedData")
+      {
+         theExtendedData = childNodes[idx];
+      }
+      else if(tag == "Style")
+      {
+         theStyleSelector = new ossimPlanetKmlStyle;
+         theStyleSelector->setParent(this);
+         if(!theStyleSelector->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "StyleMap")
+      {
+         theStyleSelector = new ossimPlanetKmlStyleMap;
+         theStyleSelector->setParent(this);
+         if(!theStyleSelector->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else
+      {
+         ossimPlanetKmlObject* timePrimitive = ossimPlanetKmlObjectRegistry::instance()->newTimePrimitive(tag);
+         if(timePrimitive)
+         {
+            theTimePrimitive = (ossimPlanetKmlTimePrimitive*)timePrimitive;
+            theTimePrimitive->setParent(this);
+         }
+      }
+   }
+   return true;
+}
+
+void ossimPlanetKmlFeature::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+
+   xmlNode->addChildNode("name", name());
+   xmlNode->addChildNode("visibility", visibilityFlag()?"1":"0");
+   xmlNode->addChildNode("open", openFlag()?"1":"0");
+   xmlNode->addChildNode("address", address());
+   xmlNode->addChildNode("phoneNumber", phoneNumber());
+   if(theCDataDescriptionFlag)
+   {
+      ossimRefPtr<ossimXmlNode> xmlTempNode = new ossimXmlNode;
+      xmlNode->setTag("description");
+      xmlNode->setCDataFlag(true);
+      xmlNode->setText(description());
+   }
+   else
+   {
+      xmlNode->addChildNode("description", description());
+   }
+   xmlNode->addChildNode("styleUrl", styleUrl());
+   if(theRegion.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theRegion->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   if(theLookAt.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theLookAt->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   if(!theSnippet.empty())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      node->setTag("Snippet");
+      if(!theSnippetMaxLines.empty())
+      {
+         node->addAttribute("maxLines", theSnippetMaxLines);
+      }
+      xmlNode->addChildNode(node.get());
+      
+   }
+   if(theExtendedData.valid())
+   {
+      xmlNode->addChildNode((ossimXmlNode*)theExtendedData->dup());
+   }
+   if(theStyleSelector.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theStyleSelector->write(node.get());
+      xmlNode->addChildNode(node.get());      
+   }
+   if(theTimePrimitive.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theTimePrimitive->write(node.get());
+      xmlNode->addChildNode(node.get());      
+   }
+}
+
+bool ossimPlanetKmlGeometry::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   return ossimPlanetKmlObject::parse(xmlNode);
+}
+
+void ossimPlanetKmlGeometry::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlObject::write(xmlNode);
+}
+
+void ossimPlanetKmlGeometry::computeCenter(osg::Vec3d& result,
+                                           const PointListType& pointList)
+{
+   ossim_uint32 idx;
+   double minLat=999999.0, minLon=999999.0;
+   double maxLat=-999999.0, maxLon=-999999.0;
+   double minAlt=99999999.0, maxAlt=-99999999.0;
+
+   if(pointList.size())
+   {
+      for(idx = 0; idx < pointList.size(); ++idx)
+      {
+         osg::Vec3d pt = pointList[idx];
+        if(pt[0]<minLon) minLon = pt[0];
+         if(pt[0]>maxLon) maxLon = pt[0];
+         if(pt[1]<minLat) minLat = pt[1];
+         if(pt[1]>maxLat) maxLat = pt[1];
+         if(pt[2]<minAlt) minAlt = pt[2];
+         if(pt[2]>maxAlt) maxAlt = pt[2];
+      }
+      result[0] = (maxLon+minLon)*.5;
+      result[1] = (maxLat+minLat)*.5;
+      result[2] = (maxAlt+minAlt)*.5;
+      if(maxLon-minLon > 180.0) // we will guess it crossed the -180 mark.
+      {
+         double len1, len2, totalLen;
+         len1 = 180-maxLon;
+         len2 = 180+minLon;
+         totalLen = len1+len2;
+         result[0] += maxLon + totalLen*.5;
+         if(result[0] > 180) result[0] -= 360.0;
+      }
+   }
+}
+
+bool ossimPlanetKmlPoint::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   bool hasCoordinates = true;
+   for(idx = 0; idx < childNodes.size(); ++idx)
+   {
+      if(childNodes[idx]->getTag() == "extrude")
+      {
+         theExtrudeFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "tessellate")
+      {
+         theTesselateFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "altitudeMode")
+      {
+         theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(childNodes[idx]->getText());
+      }
+      else if(childNodes[idx]->getTag() == "coordinates")
+      {
+         kmlReadCoordinates(thePointList, childNodes[idx]->getText());
+         computeCenter(theCenter, thePointList);
+      }
+   }
+   return hasCoordinates;
+}
+
+void ossimPlanetKmlPoint::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+   xmlNode->setTag("Point");
+
+   xmlNode->addChildNode("extrude", theExtrudeFlag?"1":"0");
+   xmlNode->addChildNode("tessellate", theTesselateFlag?"1":"0");
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+
+   if(thePointList.size() > 0)
+   {
+      ossimString value = ossimString::toString(thePointList[0][0]) + "," +
+                          ossimString::toString(thePointList[0][1]) + "," +
+                          ossimString::toString(thePointList[0][2]);
+         
+      xmlNode->addChildNode("coordinates", value);
+   }
+}
+
+bool ossimPlanetKmlLineString::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempString;
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   bool hasCoordinates = false;
+   for(idx = 0; idx < childNodes.size(); ++idx)
+   {
+      if(childNodes[idx]->getTag() == "extrude")
+      {
+         theExtrudeFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "tessellate")
+      {
+         theTesselateFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "altitudeMode")
+      {
+         theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(childNodes[idx]->getText());
+      }
+      else if(childNodes[idx]->getTag() == "coordinates")
+      {
+         hasCoordinates = true;
+         kmlReadCoordinates(thePointList, childNodes[idx]->getText());
+         computeCenter(theCenter, thePointList);
+      }
+   }
+   return hasCoordinates;   
+}
+
+void ossimPlanetKmlLineString::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+   xmlNode->setTag("LineString");
+   xmlNode->addChildNode("extrude", theExtrudeFlag?"1":"0");
+   xmlNode->addChildNode("tessellate", theTesselateFlag?"1":"0");
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+   ossimString value;
+   if(thePointList.size() > 0)
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < thePointList.size(); ++idx)
+      {
+         value += (ossimString::toString(thePointList[idx][0])+","+
+                   ossimString::toString(thePointList[idx][1])+","+
+                   ossimString::toString(thePointList[idx][2])+" ");
+      }
+   }
+   xmlNode->addChildNode("coordinates", value);
+}
+
+bool ossimPlanetKmlLinearRing::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempString;
+
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   bool hasCoordinates = false;
+   for(idx = 0; idx < childNodes.size(); ++idx)
+   {
+      if(childNodes[idx]->getTag() == "extrude")
+      {
+         theExtrudeFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "tessellate")
+      {
+         theTesselateFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "altitudeMode")
+      {
+         theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(childNodes[idx]->getText());
+      }
+      else if(childNodes[idx]->getTag() == "coordinates")
+      {
+         hasCoordinates = true;
+         kmlReadCoordinates(thePointList, childNodes[idx]->getText());
+         computeCenter(theCenter, thePointList);
+      }
+   }
+   return hasCoordinates;   
+}
+
+void ossimPlanetKmlLinearRing::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+   xmlNode->setTag("LinearRing");
+   xmlNode->addChildNode("extrude", theExtrudeFlag?"1":"0");
+   xmlNode->addChildNode("tessellate", theTesselateFlag?"1":"0");
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+   ossimString value;
+   if(thePointList.size() > 0)
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < thePointList.size()-1; ++idx)
+      {
+         value += (ossimString::toString(thePointList[idx][0])+","+
+                   ossimString::toString(thePointList[idx][1])+","+
+                   ossimString::toString(thePointList[idx][2])+" ");
+      }
+   }
+   xmlNode->addChildNode("coordinates", value);
+}
+
+bool ossimPlanetKmlPolygon::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = childNodes.size();
+
+   for(idx = 0; idx < bound; ++idx)
+   {
+      if(childNodes[idx]->getTag() == "extrude")
+      {
+         theExtrudeFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "tessellate")
+      {
+         theTesselateFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(childNodes[idx]->getTag() == "altitudeMode")
+      {
+         theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(childNodes[idx]->getText());
+      }
+      else if(childNodes[idx]->getTag() == "outerBoundaryIs")
+      {
+         theOuterBoundary = new ossimPlanetKmlLinearRing;
+         theOuterBoundary->parse(childNodes[idx]->findFirstNode("LinearRing"));
+         theOuterBoundary->setParent(this);
+      }
+      else if(childNodes[idx]->getTag() == "innerBoundaryIs")
+      {
+         ossimPlanetKmlLinearRing* linearRing = new ossimPlanetKmlLinearRing;
+         if(linearRing->parse(childNodes[idx]->findFirstNode("LinearRing")))
+         {
+            linearRing->setParent(this);
+            theInnerBoundaryList.push_back(linearRing);
+         }
+      }
+   }
+   return theOuterBoundary.valid();   
+}
+
+void ossimPlanetKmlPolygon::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+
+   xmlNode->setTag("Polygon");
+
+   xmlNode->addChildNode("extrude", theExtrudeFlag?"1":"0");
+   xmlNode->addChildNode("tessellate", theTesselateFlag?"1":"0");
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+   if(theOuterBoundary.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      ossimRefPtr<ossimXmlNode> linearRingNode = new ossimXmlNode;
+      theOuterBoundary->write(linearRingNode);
+      node->addChildNode(linearRingNode.get());
+      node->setTag("outerBoundaryIs");
+      xmlNode->addChildNode(node.get());
+   }
+   if(!theInnerBoundaryList.empty())
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theInnerBoundaryList.size(); ++idx)
+      {
+         ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+         ossimRefPtr<ossimXmlNode> linearRingNode = new ossimXmlNode;
+         theInnerBoundaryList[idx]->write(linearRingNode);
+         node->addChildNode(linearRingNode.get());
+         node->setTag("innerBoundaryIs");
+         xmlNode->addChildNode(node.get());
+      }
+   }
+}
+
+bool ossimPlanetKmlMultiGeometry::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = childNodes.size();
+
+   for(idx = 0; idx < bound; ++idx)
+   {
+      osg::ref_ptr<ossimPlanetKmlGeometry> geom = (ossimPlanetKmlGeometry*)ossimPlanetKmlObjectRegistry::instance()->newGeometry(childNodes[idx]->getTag());
+      if(geom.valid())
+      {
+         if(geom->parse(childNodes[idx]))
+         {
+            theGeometryList.push_back(geom.get());
+            geom->setParent(this);
+         }
+         else
+         {
+            return false;
+         }
+      }
+   }
+   return true;   
+   
+}
+
+void ossimPlanetKmlMultiGeometry::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+
+   xmlNode->setTag("MultiGeometry");
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theGeometryList.size(); ++idx)
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theGeometryList[idx]->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+bool ossimPlanetKmlModel::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!xmlNode.valid())
+   {
+      return false;
+   }
+   if(!ossimPlanetKmlGeometry::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = childNodes.size();
+   for(idx = 0; idx < bound; ++idx)
+   {
+      if(childNodes[idx]->getTag() == "Location")
+      {         
+         if(!theLocation->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(childNodes[idx]->getTag() == "Orientation")
+      {
+         if(!theOrientation->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(childNodes[idx]->getTag() == "Scale")
+      {
+         if(!theScale->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(childNodes[idx]->getTag() == "Link")
+      {
+         theLink = new ossimPlanetKmlLink;
+         theLink->setParent(this);
+         if(!theLink->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(childNodes[idx]->getTag() == "altitudeMode")
+      {
+         theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(childNodes[idx]->getText());
+      }
+   }
+   
+   return true;   
+  
+}
+
+void ossimPlanetKmlModel::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlGeometry::write(xmlNode);
+   xmlNode->setTag("Model");
+   ossimRefPtr<ossimXmlNode> node;
+   if(theLocation.valid())
+   {
+      node = new ossimXmlNode;
+      theLocation->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   if(theOrientation.valid())
+   {
+      node = new ossimXmlNode;
+      theOrientation->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   if(theScale.valid())
+   {
+      node = new ossimXmlNode;
+      theScale->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+   if(theLink.valid())
+   {
+      node = new ossimXmlNode;
+      theLink->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+bool ossimPlanetKmlOverlay::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   ossimString tempString;
+   clearFields();
+
+   xmlNode->getChildTextValue(theColor, "color");
+   if(xmlNode->getChildTextValue(tempString, "drawOrder"))
+   {
+      theDrawOrder = tempString.toInt32();
+   }
+   const ossimRefPtr<ossimXmlNode> iconNode = xmlNode->findFirstNode("Icon");
+   if(iconNode.valid())
+   {
+      theIcon = new ossimPlanetKmlIcon();
+      theIcon->setParent(this);
+      if(!theIcon->parse(iconNode))
+      {
+         return false;
+      }
+   }
+   return ossimPlanetKmlFeature::parse(xmlNode);
+}
+
+void ossimPlanetKmlOverlay::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlFeature::write(xmlNode);
+   xmlNode->addChildNode("color", theColor);
+   xmlNode->addChildNode("drawOrder", ossimString::toString(theDrawOrder));
+
+   if(theIcon.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theIcon->write(node);
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+bool ossimPlanetKmlScreenOverlay::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   if(!ossimPlanetKmlOverlay::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimString tempString;
+   ossimRefPtr<ossimXmlNode> tempNode = xmlNode->findFirstNode("overlayXY");
+   if(tempNode.valid())
+   {
+      if(tempNode->getAttributeValue(tempString, "x"))
+      {
+         theOverlayX = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "y"))
+      {
+         theOverlayY = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "xunits"))
+      {
+         theOverlayXUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+      if(tempNode->getAttributeValue(tempString, "yunits"))
+      {
+         theOverlayYUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+   }
+   tempNode = xmlNode->findFirstNode("screenXY");
+   if(tempNode.valid())
+   {
+      if(tempNode->getAttributeValue(tempString, "x"))
+      {
+         theScreenX = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "y"))
+      {
+         theScreenY = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "xunits"))
+      {
+         theScreenXUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+      if(tempNode->getAttributeValue(tempString, "yunits"))
+      {
+         theScreenYUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+   }
+   tempNode = xmlNode->findFirstNode("rotationXY");
+   if(tempNode.valid())
+   {
+      if(tempNode->getAttributeValue(tempString, "x"))
+      {
+         theRotationX = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "y"))
+      {
+         theRotationY = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "xunits"))
+      {
+         theRotationXUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+      if(tempNode->getAttributeValue(tempString, "yunits"))
+      {
+         theRotationYUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+   }
+   tempNode = xmlNode->findFirstNode("size");
+   if(tempNode.valid())
+   {
+      if(tempNode->getAttributeValue(tempString, "x"))
+      {
+         theSizeX = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "y"))
+      {
+         theSizeY = tempString.toDouble();
+      }
+      if(tempNode->getAttributeValue(tempString, "xunits"))
+      {
+         theSizeXUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+      if(tempNode->getAttributeValue(tempString, "yunits"))
+      {
+         theSizeYUnits = ossimPlanetKmlConvertUnits(tempString);
+      }
+   }
+   tempNode = xmlNode->findFirstNode("rotation");
+   if(tempNode.valid())
+   {
+      theRotation = tempNode->getText().toDouble();
+   }
+
+   return true;
+}
+
+void ossimPlanetKmlScreenOverlay::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlOverlay::write(xmlNode);
+   xmlNode->setTag("ScreenOverlay");
+   ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+   node->setTag("overlayXY");
+   node->addAttribute("x", ossimString::toString(theOverlayX));
+   node->addAttribute("y", ossimString::toString(theOverlayY));
+   node->addAttribute("xunits", ossimPlanetKmlConvertUnits(theOverlayXUnits));
+   node->addAttribute("yunits", ossimPlanetKmlConvertUnits(theOverlayYUnits));   
+   xmlNode->addChildNode(node.get());
+   
+   node = new ossimXmlNode;
+   node->setTag("screenXY");
+   node->addAttribute("x", ossimString::toString(theScreenX));
+   node->addAttribute("y", ossimString::toString(theScreenY));
+   node->addAttribute("xunits", ossimPlanetKmlConvertUnits(theScreenXUnits));
+   node->addAttribute("yunits", ossimPlanetKmlConvertUnits(theScreenYUnits));   
+   xmlNode->addChildNode(node.get());
+   
+   node = new ossimXmlNode;
+   node->setTag("rotationXY");
+   node->addAttribute("x", ossimString::toString(theRotationX));
+   node->addAttribute("y", ossimString::toString(theRotationY));
+   node->addAttribute("xunits", ossimPlanetKmlConvertUnits(theRotationXUnits));
+   node->addAttribute("yunits", ossimPlanetKmlConvertUnits(theRotationYUnits));   
+   xmlNode->addChildNode(node.get());
+   
+   node = new ossimXmlNode;
+   xmlNode->setTag("size");
+   node->addAttribute("x", ossimString::toString(theSizeX));
+   node->addAttribute("y", ossimString::toString(theSizeY));
+   node->addAttribute("xunits", ossimPlanetKmlConvertUnits(theSizeXUnits));
+   node->addAttribute("yunits", ossimPlanetKmlConvertUnits(theSizeYUnits));   
+   xmlNode->addChildNode(node.get());
+   
+   xmlNode->addChildNode("rotation", ossimString::toString(theRotation));
+}
+
+bool ossimPlanetKmlGroundOverlay::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlOverlay::parse(xmlNode))
+   {
+      return false;
+   }
+   ossimRefPtr<ossimXmlNode> latLonBoxNode = xmlNode->findFirstNode("LatLonBox");
+   if(!latLonBoxNode.valid())
+   {
+      return false;
+   }
+   theLatLonBox = new ossimPlanetKmlLatLonBox();
+   theLatLonBox->setParent(this);
+   if(!theLatLonBox->parse(latLonBoxNode))
+   {
+      theLatLonBox = 0;
+      return false;
+   }
+   ossimString tempString;
+   if(xmlNode->getChildTextValue(tempString, "altitude"))
+   {
+      theAltitude = tempString.toDouble();
+   }
+   xmlNode->getChildTextValue(tempString, "altitudeMode");
+   theAltitudeMode = ossimPlanetKmlConvertAltitudeMode(tempString);
+   
+   return true;
+}
+
+void ossimPlanetKmlGroundOverlay::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlOverlay::write(xmlNode);
+   xmlNode->setTag("GroundOverlay");
+   if(theLatLonBox.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theLatLonBox->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   xmlNode->addChildNode("altitude", ossimString::toString(theAltitude));
+   xmlNode->addChildNode("altitudeMode", ossimPlanetKmlConvertAltitudeMode(theAltitudeMode));
+}
+bool ossimPlanetKmlNetworkLink::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(!ossimPlanetKmlFeature::parse(xmlNode))
+   {
+      return false;
+   }
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < childNodes.size(); ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "flyToView")
+      {
+         theFlyToViewFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "refreshVisibility")
+      {
+         theRefreshVisibilityFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "Link")
+      {
+         theLink = new ossimPlanetKmlLink;
+         theLink->setParent(this);
+         if(!theLink->parse(childNodes[idx]))
+         {
+            return false;
+         }
+      }
+      else if(tag == "Url")
+      {
+         theLink = new ossimPlanetKmlLink;
+         theLink->setParent(this);
+         if(!theLink->parse(childNodes[idx]))
+         {
+            return false;
+         }         
+      }
+   }
+   
+   
+   return theLink.valid();
+}
+
+void ossimPlanetKmlNetworkLink::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlFeature::write(xmlNode);
+   xmlNode->setTag("NetworkLink");
+   if(theLink.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theLink->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+   xmlNode->addChildNode("refreshVisibility", theRefreshVisibilityFlag?"1":"0");
+   xmlNode->addChildNode("flyToView", theFlyToViewFlag?"!":"0");
+}
+
+
+bool ossimPlanetKmlPlacemark::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   clearFields();
+   if(xmlNode->getTag() == "Placemark")
+   {
+      ossim_uint32 foundCount = 0;
+      ossim_uint32 idx = 0;
+      const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+      for(idx = 0; (idx < childNodes.size())&&(foundCount < 1); ++idx)
+      {
+        std::string tag = childNodes[idx]->getTag().c_str();
+        if(tag == "description")
+        {
+            theDescription = childNodes[idx]->getText();
+            
+            /*
+            theCDataDescriptionFlag = childNodes[idx]->cdataFlag();
+            ossimRefPtr<ossimXmlNode> node2 = new ossimXmlNode;
+            std::istringstream in(theDescription);
+            if(node2->read(in))
+            {
+            }
+            */
+              
+            if(theDescription.contains("<color>"))
+            {
+                ossimString temp = theDescription.after("<color>");
+                std::string color = temp.before("</color>").c_str();
+                //std::cout << "T:" << color << "\n";
+                this->setColor(color);
+            }
+          }
+         theGeometry = (ossimPlanetKmlGeometry*)ossimPlanetKmlObjectRegistry::instance()->newGeometry(childNodes[idx]->getTag());
+         if(theGeometry.valid())
+         {
+            theGeometry->setParent(this);
+            if(!theGeometry->parse(childNodes[idx]))
+            {
+               return false;
+            }
+            ++foundCount;
+         }
+      }
+      
+      return ossimPlanetKmlFeature::parse(xmlNode);
+   }
+
+   return false;
+}
+
+void ossimPlanetKmlPlacemark::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlFeature::write(xmlNode);
+   xmlNode->setTag("Placemark");
+   if(theGeometry.valid())
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theGeometry->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+
+bool ossimPlanetKmlContainer::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   if(!xmlNode.valid()) return false;
+   
+   bool result = ossimPlanetKmlFeature::parse(xmlNode);
+   if(result)
+   {
+      const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+      ossim_uint32 idx = 0;
+      
+      for(idx = 0; (idx < childNodes.size())&&result; ++idx)
+      {
+         osg::ref_ptr<ossimPlanetKmlObject> obj = ossimPlanetKmlObjectRegistry::instance()->newObject(childNodes[idx].get());
+         if(obj.valid())
+         {
+            obj->setParent(this);
+            if(obj->parse(childNodes[idx]))
+            {
+               theObjectList.push_back(obj.get());
+            }
+            else
+            {
+               result = false;
+            }
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimPlanetKmlContainer::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlFeature::write(xmlNode);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theObjectList.size(); ++idx)
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theObjectList[idx]->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+bool ossimPlanetKmlFolder::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   return ossimPlanetKmlContainer::parse(xmlNode);
+}
+
+void ossimPlanetKmlFolder::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlContainer::write(xmlNode);
+   xmlNode->setTag("Folder");
+}
+
+
+ossimPlanetKmlDocument::ossimPlanetKmlDocument()
+{
+}
+
+bool ossimPlanetKmlDocument::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   return ossimPlanetKmlContainer::parse(xmlNode);
+}
+
+void ossimPlanetKmlDocument::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossimPlanetKmlContainer::write(xmlNode);
+    xmlNode->setTag("Document");
+  
+}
+
+ossimPlanetKml::ossimPlanetKml()
+   :theIdMapGeneratedFlag(false)
+{
+}
+
+bool ossimPlanetKml::parse(const ossimFilename& file)
+{
+   theIdMapGeneratedFlag = false;
+
+   std::vector<char> buf(file.fileSize());
+   if(!buf.size())
+   {
+      return false;
+   }
+   std::ifstream in(file.c_str(), std::ios::binary|std::ios::in);
+   in.read(&buf.front(), buf.size());
+   
+   if(in.gcount())
+   {
+      std::istringstream inStringStream(std::string(buf.begin(),
+                                                    buf.begin()+in.gcount()));
+      theFilename = file;
+      
+      return parse(inStringStream);
+   }
+
+   return false;
+}
+
+bool ossimPlanetKml::parse(std::istream& in, bool fullDocumentFlag)
+{
+  bool result = false;
+   theIdMapGeneratedFlag = false;
+   if(!in.fail())
+   {
+      if(fullDocumentFlag)
+      {
+         ossimRefPtr<ossimXmlDocument> document = new ossimXmlDocument;
+         
+         if(document->read(in))
+         {
+            result = parse(document.get());
+         }
+      }
+      else
+      {
+         ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+         if(node->read(in))
+         {
+            result = parse(node.get());
+         }
+      }
+   }
+
+   return result;
+}
+
+bool ossimPlanetKml::parse(const ossimRefPtr<ossimXmlDocument> document)
+{
+   bool result = document.valid();
+   theIdMapGeneratedFlag = false;
+
+   if(result)
+   {
+      if(document->getRoot().valid())
+      {
+         result = parse(document->getRoot());
+      }
+      else
+      {
+         result = false;
+      }
+   }
+   
+   return result;
+}
+
+bool ossimPlanetKml::parse(const ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   bool result = true;
+   if(!xmlNode.valid()) return false;
+   if(xmlNode->getTag() != "kml") return false;
+   
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+   
+   ossim_uint32 idx = 0;
+   
+   for(idx = 0; (idx < childNodes.size())&&(result); ++idx)
+   {
+      osg::ref_ptr<ossimPlanetKmlObject> obj = ossimPlanetKmlObjectRegistry::instance()->newObject(childNodes[idx].get());
+      if(obj.valid())
+      {
+         obj->setParent(this);
+         result = obj->parse(childNodes[idx]);
+         if(result)
+         {
+            theObjectList.push_back(obj.get());
+         }
+      }
+   }
+
+//    if(result)
+//    {
+//       ossimRefPtr<ossimXmlDocument> doc = writeDocument();
+//       std::cout << *(doc.get()) << std::endl;
+//    }
+   return result;
+}
+
+void ossimPlanetKml::write(ossimRefPtr<ossimXmlNode> xmlNode)const
+{
+   ossim_uint32 idx = 0;
+   xmlNode->setTag("Kml");
+   for(idx = 0; idx < theObjectList.size(); ++idx)
+   {
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+      theObjectList[idx]->write(node.get());
+      xmlNode->addChildNode(node.get());
+   }
+}
+
+ossimRefPtr<ossimXmlDocument> ossimPlanetKml::writeDocument()const
+{
+   ossimRefPtr<ossimXmlDocument> document = new ossimXmlDocument;
+   ossimRefPtr<ossimXmlNode> rootNode = new ossimXmlNode;
+   document->initRoot(rootNode);
+   write(rootNode);
+   
+   return document;
+}
+
+void ossimPlanetKml::createIdMap()const
+{
+   theIdMap.clear();
+   std::queue<osg::ref_ptr<ossimPlanetKmlObject> > objectSearchQueue;
+   ossimPlanetKmlObject::ObjectList::const_iterator iter = theObjectList.begin();
+   while(iter != theObjectList.end())
+   {
+      objectSearchQueue.push(*iter);
+      ++iter;
+   }
+   while(!objectSearchQueue.empty())
+   {
+      osg::ref_ptr<ossimPlanetKmlObject> topObj = objectSearchQueue.front().get();
+      objectSearchQueue.pop();
+      if(topObj->id() != "")
+      {
+         theIdMap.insert(std::make_pair(topObj->id().c_str(), topObj));
+      }
+      if(topObj->getObjectList().size())
+      {
+         ossim_uint32 idx = 0;
+         ossimPlanetKmlObject::ObjectList& objList = topObj->getObjectList();
+         
+         for(idx = 0; idx < objList.size(); ++idx)
+         {
+            objectSearchQueue.push(objList[idx]);
+         }
+      }
+   }
+   theIdMapGeneratedFlag = true;
+}
+
+osg::ref_ptr<ossimPlanetKmlObject> ossimPlanetKml::findById(const ossimString& id)
+{
+   if(!theIdMapGeneratedFlag)
+   {
+      createIdMap();
+   }
+   IdMapType::iterator iter = theIdMap.find(id);
+
+   if(iter != theIdMap.end())
+   {
+      return iter->second;
+   }
+
+   return 0;
+}
+
+const osg::ref_ptr<ossimPlanetKmlObject> ossimPlanetKml::findById(const ossimString& id)const
+{
+   if(!theIdMapGeneratedFlag)
+   {
+      createIdMap();
+   }
+
+   IdMapType::const_iterator iter = theIdMap.find(id);
+
+   if(iter != theIdMap.end())
+   {
+      return iter->second.get();
+   }
+
+   return 0;
+}
+
+ossimFilename ossimPlanetKml::getCacheLocation(bool sharedLocationFlag)const
+{
+   if(sharedLocationFlag)
+   {
+      ossimFilename sharedDir = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+      sharedDir = sharedDir.dirCat("kml");
+      if(!sharedDir.exists())
+      {
+         sharedDir.createDirectory();
+      }
+      return sharedDir;
+   }
+   if(theCacheLocation == "")
+   {
+      theCacheLocation = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+      theCacheLocation = theCacheLocation.dirCat("kml");
+      if(theCacheLocation != "")
+      {
+         theCacheLocation = theCacheLocation.dirCat(theFilename.fileNoExtension());
+      }
+      if(!theCacheLocation.exists())
+      {
+         theCacheLocation.createDirectory();
+      }
+   }
+
+   return theCacheLocation;
+}
+
+bool ossimPlanetKml::getAllFeatures(ossimPlanetKmlObject::ObjectList& features)
+{
+   std::queue<osg::ref_ptr<ossimPlanetKmlObject> > objectSearchQueue;
+   ossimPlanetKmlObject::ObjectList::iterator iter = theObjectList.begin();
+   
+   while(iter != theObjectList.end())
+   {
+      objectSearchQueue.push(*iter);
+      ++iter;
+   }
+
+   while(!objectSearchQueue.empty())
+   {
+      osg::ref_ptr<ossimPlanetKmlObject> topObj = objectSearchQueue.front().get();
+      objectSearchQueue.pop();
+      if(dynamic_cast<ossimPlanetKmlPlacemark*>(topObj.get()))
+      {
+         features.push_back(topObj.get());
+      }
+      else if(dynamic_cast<ossimPlanetKmlGroundOverlay*>(topObj.get()))
+      {
+         features.push_back(topObj.get());
+      }
+      else if(dynamic_cast<ossimPlanetKmlNetworkLink*>(topObj.get()))
+      {
+         features.push_back(topObj.get());
+      }
+      if(topObj->getObjectList().size())
+      {
+         ossim_uint32 idx = 0;
+         ossimPlanetKmlObject::ObjectList& objList = topObj->getObjectList();
+
+         for(idx = 0; idx < objList.size(); ++idx)
+         {
+            objectSearchQueue.push(objList[idx]);
+         }
+      }
+   }
+
+   return (features.size() > 0);
+}
+
+
+#ifdef OSSIMPLANET_HAS_LIBZ
+struct ossimPlantKmzPrivate
+{
+   ossimPlantKmzPrivate()
+      {
+         theArchive = 0;
+      }
+   unzFile       theArchive;
+   std::vector<ossimFilename> theFileList;
+};
+static ossimPlantKmzPrivate* ossimPlanetKmzPrivateData(void* pvt)
+{
+   return (ossimPlantKmzPrivate*)pvt;
+}
+#endif
+
+ossimPlanetKmz::ossimPlanetKmz()
+   :ossimPlanetKml()
+{
+#ifdef OSSIMPLANET_HAS_LIBZ
+   thePrivateData = 0;
+#endif
+}
+
+
+ossimPlanetKmz::~ossimPlanetKmz()
+{
+#ifdef OSSIMPLANET_HAS_LIBZ
+   if(thePrivateData)
+   {
+      ossim_uint32 idx = 0;
+      std::vector<ossimFilename>& fileList = ossimPlanetKmzPrivateData(thePrivateData)->theFileList;
+      for(idx = 0; idx < fileList.size(); ++idx)
+      {
+         fileList[idx].remove();
+         fileList[idx].path().remove();
+      }
+      unzClose(ossimPlanetKmzPrivateData(thePrivateData)->theArchive);
+      delete ossimPlanetKmzPrivateData(thePrivateData);
+      thePrivateData = 0;
+   }
+#endif
+
+}
+
+bool ossimPlanetKmz::parse(std::istream& /*in*/)
+{
+   // currently we do not support bridging an istream to libz
+   return false;
+}
+
+bool ossimPlanetKmz::parse(const ossimFilename& file)
+{
+#ifdef OSSIMPLANET_HAS_LIBZ
+   if(thePrivateData)
+   {
+      unzClose(ossimPlanetKmzPrivateData(thePrivateData)->theArchive);
+      delete ossimPlanetKmzPrivateData(thePrivateData);
+      thePrivateData = 0;
+   }
+   thePrivateData = new ossimPlantKmzPrivate;
+   ossimPlanetKmzPrivateData(thePrivateData)->theArchive = unzOpen(file.c_str());
+   
+   if(!(ossimPlanetKmzPrivateData(thePrivateData))->theArchive)
+   {
+      delete ossimPlanetKmzPrivateData(thePrivateData);
+      thePrivateData = 0;
+   }
+   if(thePrivateData)
+   {
+      unz_global_info gi;
+      int err;
+      unzFile uf = ossimPlanetKmzPrivateData(thePrivateData)->theArchive;
+      err = unzGetGlobalInfo (uf, &gi);
+      if (err!=UNZ_OK)
+      {
+         return false;
+      }
+      theFilename = file;
+      ossimFilename cacheLocation = getCacheLocation();
+      cacheLocation.createDirectory();
+      ossim_uint32 i = 0;
+      for (i=0;i<gi.number_entry;i++)
+      {
+         std::vector<char> tempFileInfo(2048);
+         unz_file_info file_info;
+         err = unzGetCurrentFileInfo(uf,
+                                     &file_info,
+                                     (char*)(&tempFileInfo.front()),
+                                     tempFileInfo.size(),
+                                     NULL,
+                                     0,NULL,0);
+         if (err!=UNZ_OK)
+         {
+            //ossimNotify(ossimNotifyLevel_WARN) << "Unable to get the global information to read the directory of the passed in KMZ file\n";
+            return false;
+         }
+         ossimFilename outFile;
+         ossimFilename testFile((char*)(&tempFileInfo.front()));
+         if(!testFile.empty())
+         {
+            testFile = cacheLocation.dirCat(testFile.c_str());
+            outFile = testFile;
+            if(testFile.ext().downcase() == "kml")
+            {
+               theFilename =  testFile.path().dirCat(theFilename.fileNoExtension()) + ".kml";
+               outFile = theFilename;
+            }
+            if(unzOpenCurrentFile(ossimPlanetKmzPrivateData(thePrivateData)->theArchive) == UNZ_OK)
+            {
+               ossimFilename dir(outFile.path());
+               if(!dir.exists())
+               {
+                  dir.createDirectory();
+               }
+               ossimPlanetKmzPrivateData(thePrivateData)->theFileList.push_back(outFile);
+                  std::ofstream out(outFile.c_str(),
+                                 std::ios::out|std::ios::binary);
+
+               if(!out.fail())
+               {
+                  std::vector<char> buf(2048);
+                  int bytes = 0;
+                  while((bytes=unzReadCurrentFile(uf, (char*)(&buf.front()), buf.size()))>0)
+                  {
+                     out.write((char*)(&buf.front()), bytes);
+                  }
+                  out.close();
+               }
+               unzCloseCurrentFile(ossimPlanetKmzPrivateData(thePrivateData)->theArchive);
+            }
+         }
+         if ((i+1)<gi.number_entry)
+         {
+            unzGoToNextFile(uf);
+         }
+      }
+      if(theFilename.exists())
+      {
+            ossimRefPtr<ossimXmlDocument> document = new ossimXmlDocument;
+            
+            if(document->openFile(theFilename))
+            {
+               return ossimPlanetKml::parse(document);
+            }
+      }
+   }
+#if 0
+   if(thePrivateData&&!ossimPlanetKmzPrivateData(thePrivateData)->theKmlFile.empty())
+   {
+      
+      unzFile uf = ossimPlanetKmzPrivateData(thePrivateData)->theArchive;
+      if(unzLocateFile(uf,
+                       ossimPlanetKmzPrivateData(thePrivateData)->theKmlFile.c_str(),
+                       true) == UNZ_OK)
+      {
+         if(unzOpenCurrentFile(ossimPlanetKmzPrivateData(thePrivateData)->theArchive) == UNZ_OK)
+         {
+            std::stringstream kmlBuf;
+            int bytes = 0;
+            std::vector<char> buf(2048);
+            while((bytes=unzReadCurrentFile(uf, (char*)(&buf.front()), buf.size()))>0)
+            {
+               kmlBuf.write((char*)(&buf.front()), bytes);
+            }
+            
+            ossimRefPtr<ossimXmlDocument> document = new ossimXmlDocument;
+            
+            if(document->read(kmlBuf))
+            {
+               return ossimPlanetKml::parse(document);
+            }
+         }
+      }
+   }
+#endif
+   return false;
+//    if(thePrivateData)
+//    {
+//       if(ossimPlanetKmzPrivateData(thePrivateData)->theDocFile)
+//       {
+//          zzip_file_close(ossimPlanetKmzPrivateData(thePrivateData)->theDocFile);
+//       }
+//       zzip_dir_close(ossimPlanetKmzPrivateData(thePrivateData)->theArchive);
+//       ossimPlanetKmzPrivateData(thePrivateData)->theArchive = 0;
+//       delete ossimPlanetKmzPrivateData(thePrivateData);
+//       thePrivateData = 0;
+      
+//    }
+//    theFilename = file;
+//    zzip_error_t errorFlag = ZZIP_NO_ERROR;
+//    thePrivateData = new ossimPlantKmzPrivate;
+//    ossimPlanetKmzPrivateData(thePrivateData)->theArchive = zzip_dir_open(file.c_str(), &errorFlag);
+//    if((!ossimPlanetKmzPrivateData(thePrivateData)->theArchive)||(ZZIP_NO_ERROR != ZZIP_NO_ERROR))
+//    {
+//       if(ossimPlanetKmzPrivateData(thePrivateData)->theArchive)
+//       {
+//          zzip_dir_close(ossimPlanetKmzPrivateData(thePrivateData)->theArchive);
+//       }
+      
+//       return false;
+//    }
+//    ossimPlanetKmzPrivateData(thePrivateData)->theDocFile = zzip_file_open(ossimPlanetKmzPrivateData(thePrivateData)->theArchive,
+//                                                                           "doc.kml",
+//                                                                           0);
+
+//    if(!ossimPlanetKmzPrivateData(thePrivateData)->theDocFile)
+//    {
+//       return false;
+//    }
+//    std::stringstream buf;
+//    std::vector<char> tempBuf(1024);
+
+//    int count = 0;
+//    while( (count = zzip_file_read(ossimPlanetKmzPrivateData(thePrivateData)->theDocFile,
+//                                   &tempBuf.front(),
+//                                   1024)) != 0)
+//    {
+//       buf.write(&tempBuf.front(), count);
+//    }
+//    buf.seekg(0);
+//    ossimRefPtr<ossimXmlDocument> document = new ossimXmlDocument;
+   
+//    if(document->read(buf))
+//    {
+//       return ossimPlanetKml::parse(document);
+//    }
+
+   return false;
+#else
+      return ossimPlanetKml::parse(file);
+#endif
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayer.cpp
new file mode 100644
index 0000000..6e81464
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayer.cpp
@@ -0,0 +1,504 @@
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <osgDB/Registry>
+#include <osg/Geode>
+#include <osgUtil/SmoothingVisitor>
+#include <osgUtil/Optimizer>
+#include <osg/Group>
+#include <osg/Texture2D>
+#include <osg/CoordinateSystemNode>
+#include <osg/Billboard>
+#include <osg/DrawPixels>
+#include <osg/MatrixTransform>
+#include <osgUtil/CullVisitor>
+#include <ossim/imaging/ossimMemoryImageSource.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetOssimImage.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/mkUtils.h>
+#include <osg/PolygonOffset>
+#include <osg/PolygonMode>
+#include <osg/TextureRectangle>
+#include <osgDB/ReadFile>
+#include <osg/CoordinateSystemNode>
+#include <osgText/Text>
+#include <time.h>
+#include <ossimPlanet/ossimPlanetLabelGeom.h>
+#include <ossimPlanet/ossimPlanetBillboardIcon.h>
+#include <ossimPlanet/ossimPlanetKmlPlacemarkNode.h>
+#include <ossimPlanet/ossimPlanetKmlScreenOverlayNode.h>
+#include <ossimPlanet/ossimPlanetKml.h>
+#include <ossimPlanet/ossimPlanetKmlNetworkLinkNode.h>
+#include <osgGA/GUIActionAdapter>
+#include <osgGA/EventVisitor>
+#include <wms/wmsCurlMemoryStream.h>
+
+class ossimPlanetStageKmlOperation : public ossimPlanetOperation
+{
+public:
+   ossimPlanetStageKmlOperation(ossimPlanetKmlLayer* layer)
+   :theKmlLayer(layer),
+   theParent(layer)
+   {
+      
+   }
+   virtual void run()
+   {
+     if(!theKmlObject.valid())
+      {
+         if(theKmlFile.exists())
+         {
+            osg::ref_ptr<ossimPlanetKml> kmlObject;
+            if(theKmlFile.ext() == "kmz")
+            {
+               kmlObject = new ossimPlanetKmz;
+            }
+            else if(theKmlFile.ext() == "kml")
+            {
+
+               kmlObject = new ossimPlanetKml;
+            }
+            if(kmlObject.valid()&&!kmlObject->parse(theKmlFile))
+            {
+               return;
+            }
+            theKmlObject = kmlObject.get();
+         }
+      }
+      if(theKmlObject.valid())
+      {
+         osg::ref_ptr<ossimXmlNode> xml = new ossimXmlNode;
+         theKmlObject->write(xml.get());
+         
+         osg::ref_ptr<ossimPlanetKmlLayerNode> layerNode = 0;
+         if(theKmlObject->getObjectList().size() > 0)
+         {
+            layerNode = setupContainer(theKmlObject.get()).get();
+         }
+         else
+         {
+            layerNode = setupFeature(theKmlObject.get()).get();
+         }
+         if(layerNode.valid())
+         {
+            layerNode->setId(theKmlObject->id());
+         }
+         if(theKmlLayer)
+         {
+            theKmlLayer->readyToAddNode(theParent, layerNode.get());
+         }
+      }
+   }
+   void setParent(osg::Group* parent)
+   {
+      theParent = parent;
+   }
+   void setKmlObject(osg::ref_ptr<ossimPlanetKmlObject> kml)
+   {
+      theKmlObject = kml;
+   }
+   void setFile(const ossimFilename& file)
+   {
+      theKmlFile = file;
+   }
+protected:
+   osg::ref_ptr<ossimPlanetKmlLayerNode> setupContainer(osg::ref_ptr<ossimPlanetKmlObject> container)const
+   {
+      const ossimPlanetKmlObject::ObjectList& objList = container->getObjectList();
+      ossim_uint32 idx = 0;
+      osg::ref_ptr<ossimPlanetKmlLayerNode> group = new ossimPlanetKmlLayerNode;
+      group->setKmlObject(container.get());
+      for(idx = 0; idx < objList.size();++idx)
+      {
+         osg::ref_ptr<ossimPlanetKmlLayerNode> node = 0;
+         if(objList[idx]->getObjectList().size())
+         {
+            node = setupContainer(objList[idx].get());
+         }
+         else
+         {
+            node = setupFeature(objList[idx].get());
+         }
+         if(node.valid())
+         {
+            node->setId(objList[idx]->id());
+            group->addChild(node.get());
+         }
+      }
+      return group.get();
+   }
+   
+   osg::ref_ptr<ossimPlanetKmlLayerNode> setupFeature(osg::ref_ptr<ossimPlanetKmlObject> featureObject)const
+   {
+      ossimPlanetKmlFeature* feature = dynamic_cast<ossimPlanetKmlFeature*>(featureObject.get());
+      if(feature)
+      {
+         if(dynamic_cast<ossimPlanetKmlPlacemark*>(feature))
+         {
+            osg::ref_ptr<ossimPlanetKmlPlacemarkNode> result = new ossimPlanetKmlPlacemarkNode(theKmlLayer, featureObject.get());
+            
+            if(result->init())
+            {
+               return result.get();
+            }
+         }
+         else if(dynamic_cast<ossimPlanetKmlScreenOverlay*>(feature))
+         {
+            osg::ref_ptr<ossimPlanetKmlScreenOverlayNode> result = new ossimPlanetKmlScreenOverlayNode(theKmlLayer,
+                                                                                                       featureObject.get());
+            if(result->init())
+            {
+               return result.get();
+            }
+         }
+         else if(dynamic_cast<ossimPlanetKmlNetworkLink*>(feature))
+         {
+            ossimPlanetKmlNetworkLink* link = dynamic_cast<ossimPlanetKmlNetworkLink*>(feature);
+            if(link->link())
+            {
+               if(!link->link()->href().empty())
+               {
+                  ossimPlanetKmlNetworkLinkNode* node = new ossimPlanetKmlNetworkLinkNode(theKmlLayer,
+                                                                                          featureObject.get());
+                  node->init();
+                  
+                  return node;
+              }
+            }
+         }
+     }
+
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetKmlObject> theKmlObject;
+   ossimFilename theKmlFile;
+   ossimPlanetKmlLayer* theKmlLayer;
+   osg::Group* theParent;
+};
+
+
+osgDB::ReaderWriter::ReadResult ossimPlanetKmlLayerReaderWriter::readNode(
+   const std::string& /* fileName */, const Options*)const
+{
+#if 0
+   osg::ref_ptr<osg::Node> node;
+   if(fileName == "PLW_STAGE_OBJECTS")
+   {
+      std::vector<char> buf(1024);
+      ossimFilename file = theLayer->nextCityDatabase();
+      const ossimPlanetGeoRefModel* model = theLayer->landModel();
+      if(!model) return 0;
+      if(file.isDir())
+      {
+         file = file.dirCat("origins.txt");
+      }
+      if(file.exists())
+      {
+         osg::Vec3d localOrigin;
+         osg::Vec3d origin;
+         double x,y,z,lat,lon,height;
+         ossimFilename path = file.path();
+         theCurrentPlwLocation = path;
+         std::ifstream in(file.c_str(), std::ios::in);
+         if(in.getline(&buf.front(), buf.size()))
+         {
+            std::istringstream header(&buf.front());
+            ossimString field1;
+            header >> field1;
+            if(field1.downcase().contains("origin_wgs84"))
+            {
+               osg::MatrixTransform* modelScaleTransform      = new osg::MatrixTransform;
+               node = modelScaleTransform;
+               header >>x>>y>>z>>lat>>lon>>height;
+               double ellipsoidalHeight = model->getHeightAboveEllipsoid(lat, lon);
+
+               modelScaleTransform->setMatrix(osg::Matrixd::scale(1.0/model->getNormalizationScale(),
+                                                                  1.0/model->getNormalizationScale(),
+                                                                  1.0/model->getNormalizationScale()));
+               while(in.getline(&buf.front(), buf.size()))
+               {
+                  std::istringstream files(&buf.front());
+                  files >>field1>>x>>y>>z>>lat>>lon>>height;
+                  osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(path.dirCat(field1).c_str()));
+                  if(loadedModel.get())
+                  {
+                     osg::MatrixTransform* modelTransform = new osg::MatrixTransform;
+                     osg::Matrixd lsrMatrix;
+                     ellipsoidalHeight = model->getHeightAboveEllipsoid(lat, lon);
+                     model->lsrMatrix(osg::Vec3d(lat, lon, ellipsoidalHeight),
+                                                   lsrMatrix);
+                     lsrMatrix(3, 0) *= model->getNormalizationScale();
+                     lsrMatrix(3, 1) *= model->getNormalizationScale();
+                     lsrMatrix(3, 2) *= model->getNormalizationScale();
+                     modelTransform->setMatrix(lsrMatrix);
+                     modelTransform->addChild(loadedModel.get());
+                     modelScaleTransform->addChild(modelTransform);
+                  }
+               }
+            }
+         }
+         theCurrentPlwLocation = "";
+      }
+   }
+   return node.get();
+#endif
+   return 0;
+}
+
+osgDB::ReaderWriter::ReadResult ossimPlanetKmlLayerReaderWriter::readImage(const std::string& fileName, const Options*) const
+{
+   if(theRecurseFlag) return 0;
+   if(ossimFilename(fileName).exists())
+   {
+      theRecurseFlag = true;
+      osgDB::ReaderWriter::ReadResult i = osgDB::Registry::instance()->readImage(fileName, 0);
+      theRecurseFlag = false;
+      if(i.getImage()) return i;
+     
+      ossimPlanetOssimImage loader;
+      ossimPlanetImage img;
+      if(loader.loadFile(fileName, img))
+      {
+         osg::Image* i= new osg::Image(img);
+         i->flipVertical();
+         return i;
+      }
+   }
+   if(theCurrentPlwLocation.exists())
+   {
+      ossimFilename tempInputFile(fileName);
+      tempInputFile.convertBackToForwardSlashes();
+      ossimFilename file = theCurrentPlwLocation.dirCat(tempInputFile);
+      if(file.exists())
+      {
+         theRecurseFlag = true;
+         osgDB::ReaderWriter::ReadResult i = osgDB::Registry::instance()->readImage(file.c_str(), 0);
+         theRecurseFlag = false;
+         return i;
+      }
+   }
+   return ReadResult(ReadResult::FILE_NOT_HANDLED);
+}
+
+ossimPlanetKmlLayer::ossimPlanetKmlLayer()
+{
+   theFudgeStamp = new osg::FrameStamp;
+   theReaderWriter = new ossimPlanetKmlLayerReaderWriter(this);
+   osgDB::Registry::instance()->addReaderWriter(theReaderWriter.get());
+   theKmlCacheLocation = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+   theKmlCacheLocation = theKmlCacheLocation.dirCat("kml");
+   theReaderWriter->setKmlCacheLocation(theKmlCacheLocation);
+   getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   initializePalettes();
+   theOperationQueue = new ossimPlanetOperationThreadQueue;
+}
+
+void ossimPlanetKmlLayer::traverse(osg::NodeVisitor& nv)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGraphMutex);
+   
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!thePlanet)
+         {
+            thePlanet = ossimPlanet::findPlanet(this);
+         }
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNodesToAddListMutex);
+            if(theNodesToAddList.size()>0)
+            {
+               ossim_uint32 idx = 0;
+               for(idx=0;idx<theNodesToAddList.size();++idx)
+               {
+                  theNodesToAddList[idx].theParent->addChild(theNodesToAddList[idx].theNode.get());
+               }
+               theNodesToAddList.clear();
+            }
+
+         }
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         if((theReadyToProcessKmlFileList.size() > 0) ||
+            (theReadyToProcessKmlList.size()>0) )
+         {
+            nv.getDatabaseRequestHandler()->requestNodeFile("KML_STAGE_OBJECTS",
+                                                            nv.getNodePath(),
+                                                            9999999,
+                                                            theFudgeStamp.get(),
+                                                            theRequestRef, 
+                                                            0);
+         }
+        break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theNodeList.size(); ++idx)
+   {
+      theNodeList[idx]->accept(nv);
+   }
+   ossimPlanetLayer::traverse(nv);
+}
+
+void ossimPlanetKmlLayer::addKml(osg::ref_ptr<ossimPlanetKmlObject> kml)
+{
+   addKml(this, kml.get());
+}
+
+void ossimPlanetKmlLayer::addKml(osg::ref_ptr<osg::Group> parent,
+                                 osg::ref_ptr<ossimPlanetKmlObject> kml)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToProcessKmlListMutex);
+   ossimPlanetStageKmlOperation* operation = new ossimPlanetStageKmlOperation(this);  
+   operation->setKmlObject(kml);
+   operation->setParent(parent.get());
+   theOperationQueue->add(operation);
+}
+
+void ossimPlanetKmlLayer::addKml(const ossimFilename& kmlFile)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToProcessKmlListMutex);
+   ossimPlanetStageKmlOperation* operation = new ossimPlanetStageKmlOperation(this);  
+   operation->setFile(kmlFile);
+   theOperationQueue->add(operation);
+   //theReadyToProcessKmlFileList.push(kmlFile);
+//   setRedrawFlag(true);
+}
+
+bool ossimPlanetKmlLayer::addChild( Node *child )
+{
+   return ossimPlanetLayer::addChild(child);
+}
+
+
+osg::ref_ptr<ossimPlanetIconGeom> ossimPlanetKmlLayer::getOrCreateIconEntry(const ossimString& src)
+{
+   osg::ref_ptr<ossimPlanetIconGeom> result = getIconEntry(src);
+   if(result.valid())
+   {
+      return result.get();
+   }
+
+   if(ossimFilename(src).exists())
+   {
+      osg::ref_ptr<osg::Image> img = ossimPlanetImage::readNewOsgImage(ossimFilename(src));
+      osg::ref_ptr<ossimPlanetIconGeom> geom = new ossimPlanetIconGeom;
+      geom->setTexture(new osg::Texture2D(img.get()));
+      theIconMap.insert(std::make_pair(src.c_str(),geom.get()));
+   }
+   
+   return getIconEntry(src);
+}
+
+
+osg::ref_ptr<ossimPlanetIconGeom> ossimPlanetKmlLayer::getIconEntry(const ossimString& src)
+{
+   ossimPlanetKmlLayer::IconMap::iterator iter = theIconMap.find(src);
+
+   if(iter!=theIconMap.end())
+   {
+      return iter->second.get();
+   }
+
+   return 0;
+}
+
+
+void ossimPlanetKmlLayer::initializePalettes()
+{
+//    ossimFilename paletteDir = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+//    paletteDir = paletteDir.dirCat("images");
+//    paletteDir = paletteDir.dirCat("icons");
+//    if(!paletteDir.exists())
+//    {
+//       paletteDir = ossimEnvironmentUtility::instance()->getInstalledOssimSupportDir();
+//       paletteDir = paletteDir.dirCat("images");
+//       paletteDir = paletteDir.dirCat("icons");      
+//    }
+
+
+//    if(paletteDir.exists())
+//    {
+//       theIconMap.clear();
+//       ossim_uint32 idx = 2;
+//       for(idx = 1; idx <=5; ++idx)
+//       {
+//          ossimFilename tempFile = paletteDir;
+//          tempFile = tempFile.dirCat(ossimString("palette-") +
+//                                     ossimString::toString(idx)+".png");
+         
+//          osg::ref_ptr<osg::Image> img = ossimPlanetImage::readNewOsgImage(tempFile);
+//          if(img.valid())
+//          {
+//             std::cout << "Adding icon " << tempFile << std::endl;
+//             theIconMap.insert(std::make_pair(tempFile.fileNoExtension(), new osg::Texture2D(img.get())));
+//          }
+//       }
+//    }
+}
+
+void ossimPlanetKmlLayer::deleteNode(const ossimString& id)
+{
+   ossimPlanetKmlLayer::FindNodeVisitor nv(id);
+
+   this->accept(nv);
+   if(nv.layerList().size())
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theGraphMutex);
+      FindNodeVisitor::LayerNodeList&  layerList = nv.layerList();
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < layerList.size(); ++idx)
+      {
+         if(layerList[idx]->getParent(0))
+         {
+            layerList[idx]->getParent(0)->removeChild(layerList[idx].get());
+            notifyRemoveChild(layerList[idx].get());
+         }
+      }
+   }
+}
+
+void ossimPlanetKmlLayer::readyToAddNode(osg::Group* parent, 
+                                         osg::Node* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNodesToAddListMutex);
+
+   theNodesToAddList.push_back(NodeToAddInfo(parent, node));
+   setRedrawFlag(true);
+}
+
+
+const ossimPlanetGeoRefModel* ossimPlanetKmlLayer::landModel()const
+{
+   if(thePlanet)
+   {
+      return thePlanet->model().get();
+   }
+   return 0;
+}
+
+ossimPlanetGeoRefModel* ossimPlanetKmlLayer::landModel()
+{
+   if(thePlanet)
+   {
+      return thePlanet->model().get();
+   }
+   return 0;
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayerNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayerNode.cpp
new file mode 100644
index 0000000..239e498
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlLayerNode.cpp
@@ -0,0 +1,50 @@
+#include <ossimPlanet/ossimPlanetKmlLayerNode.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+
+ossimPlanetKmlLayerNode::ossimPlanetKmlLayerNode(ossimPlanetKmlLayer* layer,
+                                                 ossimPlanetKmlObject* obj)
+   :theLayer(layer),
+    theKmlObject(obj)
+{
+   ossimPlanetKmlFeature* feature = dynamic_cast<ossimPlanetKmlFeature*>(obj);
+   if(feature)
+   {
+      setName(feature->name());
+      setDescription(feature->description());
+      setId(feature->id());
+   }
+}
+
+void ossimPlanetKmlLayerNode::traverse(osg::NodeVisitor& nv)
+{
+   if(!enableFlag()) return;
+
+   ossimPlanetNode::traverse(nv);
+}
+
+void ossimPlanetKmlLayerNode::setLayer(ossimPlanetKmlLayer* layer)
+{
+   theLayer = layer;
+}
+
+ossimPlanetKmlLayer* ossimPlanetKmlLayerNode::layer()
+{
+   return theLayer;
+}
+
+void ossimPlanetKmlLayerNode::setKmlObject(ossimPlanetKmlObject* obj)
+{
+   theKmlObject = obj;
+   ossimPlanetKmlFeature* feature = dynamic_cast<ossimPlanetKmlFeature*>(obj);
+   if(feature)
+   {
+      setName(feature->name());
+      setDescription(feature->description());
+      setId(feature->id());
+   }
+}
+
+bool ossimPlanetKmlLayerNode::init()
+{
+   return true;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKmlNetworkLinkNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlNetworkLinkNode.cpp
new file mode 100644
index 0000000..21d4a6a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlNetworkLinkNode.cpp
@@ -0,0 +1,108 @@
+#include <ossimPlanet/ossimPlanetKmlNetworkLinkNode.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <wms/wmsCurlMemoryStream.h>
+#include <ossim/base/ossimTempFilename.h>
+
+ossimPlanetKmlNetworkLinkNode::ossimPlanetKmlNetworkLinkNode(ossimPlanetKmlLayer* layer,
+                                                             ossimPlanetKmlObject* obj)
+:ossimPlanetKmlLayerNode(layer, obj)
+{
+   theScheduledFlag = false;
+}
+
+void ossimPlanetKmlNetworkLinkNode::traverse(osg::NodeVisitor& nv)
+{
+   ossimPlanetKmlLayerNode::traverse(nv);
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!getNumChildren()&&!theScheduledFlag)
+         {
+            if(theKmlData.valid())
+            {
+               if(theLayer)
+               {
+                  theScheduledFlag = true;
+                  theLayer->addKml(this, theKmlData.get());
+               }
+            }         
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+}
+
+bool ossimPlanetKmlNetworkLinkNode::init()
+{
+   ossimPlanetKmlNetworkLink* link = dynamic_cast<ossimPlanetKmlNetworkLink*>(theKmlObject.get());
+   if(!link) return false;
+   wmsRefPtr<wmsCurlMemoryStream> curlMemoryStream = new wmsCurlMemoryStream;
+   curlMemoryStream->setMaxRedirects(1);
+   curlMemoryStream->setUrl(link->link()->href().string());
+   bool result = false;
+   ossimTempFilename tempFile("","","kmz");
+   theKmlData = 0;
+//   std::cout << "CACHE DIRECTORY ================ " << theKmlObject->getCacheLocation() << std::endl;
+//   std::cout << "TRYING LINK ========================== " << link->link()->href() << std::endl;
+   if(ossimFilename(link->link()->href()).ext() == "kmz")
+   {
+ //     std::cout << "DOWNLOAD KMZ!!!!!!!!!!!!!!!!!!!" << std::endl;
+      tempFile.generateRandomFile();
+      result = curlMemoryStream->download(tempFile);
+//      std::cout << "result ============= " << result << "  with file exists " << tempFile << std::endl;
+   }
+   else
+   {
+      result = curlMemoryStream->download();
+//      std::cout << "result ============= " << result << std::endl;
+   }
+   if(curlMemoryStream->getStream().valid()&&!tempFile.exists())
+   {
+      ossimRefPtr<wmsMemoryStream> stream =  new wmsMemoryStream(curlMemoryStream->getStream()->getBuffer(),
+                                                                  curlMemoryStream->getStream()->getBufferSize());
+      if(stream->getBuffer())
+      {
+         stringstream in(ossimString(curlMemoryStream->getStream()->getBuffer(),
+                                     curlMemoryStream->getStream()->getBuffer()+
+                                     curlMemoryStream->getStream()->getBufferSize()));
+//         std::cout << "PEEEEEK ==== " << (char)in.peek() << std::endl;
+//         std::cout << "---------------------------------------------------------------" << std::endl;
+      //   std::cout << stream->getBuffer() << std::endl;
+         theKmlData = new ossimPlanetKml;
+         theKmlData->setParent(theKmlObject.get());
+         if(!theKmlData->parse(in, false))
+         {
+            in.clear();
+            in.seekg(0);//, std::ios::beg);
+            if(theKmlData->parse(in, true))
+            {
+            }
+         }
+         else
+         {
+         }
+//         std::cout << "==============================================================" << std::endl;
+      }
+   }
+   else if(result&&tempFile.exists())
+   {
+      theKmlData = new ossimPlanetKmz;
+      theKmlData->setParent(theKmlObject.get());
+      if(!theKmlData->parse(tempFile))
+      {
+//         std::cout << "NO KMZ!!!!!!!!!!!!!!!!!!!" << std::endl;
+        theKmlData = 0;
+      }
+      else
+      {
+//         std::cout << "GOT KMZ!!!!!!!!!!!!!!!!!!!" << std::endl;
+      }
+   }
+   
+   return result;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKmlPlacemarkNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlPlacemarkNode.cpp
new file mode 100644
index 0000000..d918d17
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlPlacemarkNode.cpp
@@ -0,0 +1,1176 @@
+#include <ossimPlanet/ossimPlanetKmlPlacemarkNode.h>
+#include <osgUtil/IntersectVisitor>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossimPlanet/ossimPlanetCubeGrid.h>
+#include <osg/LineWidth>
+#include <osg/PolygonOffset>
+#include <osg/PolygonMode>
+#include <osg/CullSettings>
+#include <osgUtil/SmoothingVisitor>
+#include <osgUtil/TriStripVisitor>
+#include <osgUtil/CullVisitor>
+#include <osgUtil/Tessellator>
+#include <osg/TriangleFunctor>
+#include <osg/ShadeModel>
+#include <osg/Point>
+#include <osg/Node>
+#include <osgDB/ReadFile>
+
+
+void ossimPlanetKmlPlacemarkNode::PlacemarkGeometryDraw::drawImplementation(osg::RenderInfo& renderInfo,
+                                                                            const osg::Drawable* drawable)const
+{
+   osg::Drawable* nonConstDrawable = const_cast<osg::Drawable*>(drawable);
+   osg::Geometry* geom = dynamic_cast<osg::Geometry*>(nonConstDrawable);
+   if(geom)
+   {
+      osg::Vec4Array* array = dynamic_cast<osg::Vec4Array*>(geom->getColorArray());
+      if(array&&array->size()==1)
+      {
+         float previous = (*array)[0][3];
+         (*array)[0][3] *=theOpacity;
+         geom->setColorArray(array);
+         drawable->drawImplementation(renderInfo);
+         (*array)[0][3] = previous;
+         geom->setColorArray(array);
+         
+      }
+      else
+      {
+         drawable->drawImplementation(renderInfo);
+      }
+   }
+   else
+   {
+      drawable->drawImplementation(renderInfo);
+   }
+}
+
+ossimPlanetKmlPlacemarkNode::ossimPlanetKmlPlacemarkNode(ossimPlanetKmlLayer* layer,
+                                                         ossimPlanetKmlObject* obj)
+   :ossimPlanetKmlLayerNode(layer, obj)
+{
+//    setCullingActive(false);
+   getOrCreateStateSet()->setMode( GL_LIGHTING,
+                                   osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF );
+   theCulledFlag = false;
+}
+
+
+void ossimPlanetKmlPlacemarkNode::traverse(osg::NodeVisitor& nv)
+{
+   if(!enableFlag()) return;
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         theCulledFlag = false;
+         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(theLod.valid())
+         {
+//            float opacity = 1.0;
+            // divide by root 2
+            //  this is a unit square so the radius is more than likely similar to the radius along the
+            // diagonal.  We just need a crude approximation to give the visual afect we want.
+            //
+            float pixelSize = cullVisitor->clampedPixelSize(theCenter, theRadius)/1.41421356237309504880;
+            if(pixelSize > theLod->minLodPixels())
+            {
+               ossim_int32 maxLod = theLod->maxLodPixels();
+               if((maxLod > 0)&&(pixelSize > maxLod))
+               {
+                  theCulledFlag = true;
+                  return;
+               }
+            }
+            else
+            {
+               theCulledFlag = true;
+               return;
+            }
+            if(theLod->minFadeExtent()&&
+               theLod->maxFadeExtent()&&
+               (theLod->minFadeExtent()<theLod->maxFadeExtent()))
+            {
+               if (pixelSize < theLod->minLodPixels())
+               {
+                  theFadeAlpha=0;
+               }
+               else if((pixelSize < (theLod->minLodPixels() + theLod->minFadeExtent())))
+               {
+                  theFadeAlpha=(pixelSize - theLod->minLodPixels())/theLod->minFadeExtent();
+               }
+               else if(pixelSize < (theLod->maxLodPixels() - theLod->maxFadeExtent()))
+               {
+                  theFadeAlpha=1;
+               }
+               else if (pixelSize < theLod->maxLodPixels())
+               {
+                  theFadeAlpha=(theLod->maxLodPixels()-pixelSize)/theLod->maxFadeExtent();
+               }
+               else
+               {
+                  theFadeAlpha=0;
+               }
+               if(theDraw.valid())
+               {
+                  theDraw->theOpacity = theFadeAlpha;
+               }
+               if(theFadeAlpha==0)
+               {
+                  theCulledFlag = true;
+                  return;
+               }
+            }
+            else
+            {
+               if(theDraw.valid())
+               {
+                  theDraw->theOpacity = 1.0;
+               }
+            }
+         }
+         break;
+      }
+      default:
+      {
+         if(theCulledFlag)
+         {
+            return;
+         }
+      }
+   }
+   if(theKmlGeometries.valid())
+   {
+      if(dynamic_cast<osgUtil::IntersectVisitor*>(&nv))
+      {
+         if(theKmlPickableGeometries.valid())
+         {
+            theKmlPickableGeometries->accept(nv);
+         }
+      }
+      else
+      {
+         theKmlGeometries->accept(nv);
+      }
+   }
+}
+#if 0
+static std::ostream& operator << (std::ostream& out, const osg::Vec3d& src)
+{
+   out << "<" << src[0] <<", " << src[1] << ", " << src[2];
+   return out;
+}
+static std::ostream& operator << (std::ostream& out, const osg::Vec4& src)
+{
+   out << "<" << src[0] <<", " << src[1] << ", " << src[2] << ", " << src[3];
+   return out;
+}
+#endif
+
+class ossimPlanetKmlTextShiftUpdate : public osg::Drawable::UpdateCallback
+{
+public:
+   ossimPlanetKmlTextShiftUpdate(ossimPlanetBillboardIcon* icon,
+                                 osg::ClusterCullingCallback* clusterCallback,
+                                 osg::ref_ptr<osg::Drawable::UpdateCallback> oldCallback=0)
+      :theIcon(icon),
+       theCallback(clusterCallback),
+       theOldCallback(oldCallback)
+      {}
+   virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
+      {
+         osgText::Text* text = dynamic_cast<osgText::Text*>(drawable);
+         if(text&&theIcon)
+         {
+            if(theOldCallback.valid())
+            {
+               theOldCallback->update(nv, drawable);
+            }
+            osg::Vec3d labelShift(0.0,0.0,0.0);
+            osg::BoundingSphere bs = theIcon->getBound();
+            if(bs.valid())
+            {
+               labelShift[2] = bs.radius()*1.5;
+            }
+            
+            if(!ossim::almostEqual(labelShift[2],
+                                   (double)text->getPosition()[2],
+                                   DBL_EPSILON))
+            {
+               text->setPosition(labelShift);
+//                if(theCallback)
+//                {
+//                   theCallback->set(labelShift,
+//                                    theCallback->getNormal(),
+//                                    theCallback->getDeviation(),
+//                                    theCallback->getRadius());
+//                }
+               text->dirtyBound();
+            }
+         }
+      }
+   ossimPlanetBillboardIcon* theIcon;
+   osg::ClusterCullingCallback* theCallback;
+   osg::ref_ptr<osg::Drawable::UpdateCallback> theOldCallback;
+};
+bool ossimPlanetKmlPlacemarkNode::init()
+{
+   if(!theLayer) return false;
+   ossimPlanetGeoRefModel* landModel = theLayer->landModel();
+   ossimPlanetKmlPlacemark* placemark = dynamic_cast<ossimPlanetKmlPlacemark*>(theKmlObject.get());
+   if(!placemark||!landModel) return false;
+   
+   std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> > primitiveGeomList;
+   theKmlGeometries = new osg::Group;
+   theKmlPickableGeometries = new osg::Group;
+   
+   // load placemark feature
+   osg::ref_ptr<ossimPlanetKmlGeometry> geom = placemark->getGeometry();
+   if(geom.valid())
+   {
+      if(geom->toMultiGeometry())
+      {
+         std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> >& multiGeomList = geom->toMultiGeometry()->geomtryList();
+         
+         primitiveGeomList.insert(primitiveGeomList.begin(),
+                                  multiGeomList.begin(),
+                                  multiGeomList.end());
+      }
+      else
+      {
+         primitiveGeomList.push_back(geom.get());
+      }
+   }
+   
+   theRegion = placemark->region();
+   if(theRegion.valid())
+   {
+      theLod = theRegion->lod();
+   }
+   else
+   {
+      theLod = 0;
+   }
+   // let's setup the global stuff that all geometries will need access to to initialize itself
+   //
+   static osg::ref_ptr<osgText::Font> defaultFont = osgText::readFontFile("fonts/arial.ttf");
+   ossimPlanetKml* kml = dynamic_cast<ossimPlanetKml*>(placemark->getRoot(placemark));
+   theNormalizationScale = landModel->getNormalizationScale();
+   const ossimPlanetKmlStyleSelector* styleSelector = placemark->getStyleSelector().get();
+   ossimString styleUrl = placemark->styleUrl();
+   
+   if(kml)
+   {
+//       std::cout << "STYLE URL == " << styleUrl << std::endl;
+      // check for the inline style
+      if(!styleSelector&&!styleUrl.empty())
+      {
+         if(*(styleUrl.begin()) == '#')
+         {
+            // no inline style
+            // Now check for shared style
+            const osg::ref_ptr<ossimPlanetKmlObject> obj = kml->findById(styleUrl.after("#"));
+            if(obj.valid())
+            {
+               styleSelector = dynamic_cast<const ossimPlanetKmlStyleSelector*>(obj.get());
+            }
+         }
+      }
+   }
+
+   const ossimPlanetKmlStyle*        normalStyle = 0;
+   const ossimPlanetKmlStyle*        highlightStyle = 0;
+   const ossimPlanetKmlIconStyle*    normalIconStyle = 0;
+   const ossimPlanetKmlLabelStyle*   normalLabelStyle = 0;
+   // const ossimPlanetKmlLineStyle*    normalLineStyle = 0;
+   const ossimPlanetKmlPolyStyle*    normalPolyStyle = 0;
+   // const ossimPlanetKmlBalloonStyle* normalBalloonStyle = 0;
+   const ossimPlanetKmlStyleMap*     styleMap = 0;
+
+   if(styleSelector)
+   {
+      styleMap = styleSelector->toStyleMap();
+      if(styleMap&&kml)
+      {
+         const ossimPlanetKmlObject* obj = kml->findById(styleMap->normalUrl().after("#")).get();
+         styleSelector = dynamic_cast<const ossimPlanetKmlStyleSelector*>(obj);
+         if(styleSelector)
+         {
+//             std::cout << "Found normal style!" << std::endl;
+            normalStyle = styleSelector->toStyle();
+         }
+         obj = kml->findById(styleMap->highlightUrl().after("#")).get();
+         styleSelector = dynamic_cast<const ossimPlanetKmlStyleSelector*>(obj);
+         if(styleSelector)
+         {
+            highlightStyle = styleSelector->toStyle();
+         }
+      }
+      else 
+      {
+         normalStyle = styleSelector->toStyle();
+      }
+      
+      if(normalStyle)
+      {
+         normalIconStyle = normalStyle->iconStyle().get();
+         normalLabelStyle = normalStyle->labelStyle().get();
+         // normalLineStyle = normalStyle->lineStyle().get();
+         normalPolyStyle = normalStyle->polyStyle().get();
+         // normalBalloonStyle = normalStyle->balloonStyle().get();
+         if(normalPolyStyle)
+         {
+//             std::cout << "OUTLINE? " << normalPolyStyle->getOutlineFlag() << std::endl;
+         }
+      }
+   }
+   if(highlightStyle)
+   {
+      if(highlightStyle->iconStyle().valid())
+      {
+      }
+      if(highlightStyle->labelStyle().valid())
+      {
+      }
+      if(highlightStyle->lineStyle().valid())
+      {
+      }
+   }
+//    if(placemark->getCenter(lat, lon, alt))
+//    {
+//       llh = osg::Vec3d(lat, lon, alt);
+//       double geoidOffset = landModel->getGeoidOffset(lat,
+//                                                      lon);
+//       if(!ossim::isnan(geoidOffset))
+//       {
+//          llh[2]+=geoidOffset;
+//       }
+//    }
+   ossimPlanetCubeGrid grid;
+   ossimPlanetGridUtility::GridPoint gridPt;
+   for(std::vector<osg::ref_ptr<ossimPlanetKmlGeometry> >::const_iterator iter = primitiveGeomList.begin();
+       iter != primitiveGeomList.end();
+       ++iter)
+   {
+      bool needsReTessFlag = false;
+      double lat, lon, alt;
+      osg::Vec3d llh;;
+      if(!(*iter)->getCenter(lat, lon, alt))
+      {
+         continue;
+      }
+      llh = osg::Vec3d(lat, lon, alt);
+      llh[2] += landModel->getGeoidOffset(lat,
+                                          lon);
+      osg::Matrixd localToWorld;
+      osg::Matrixd inverseLocalToWorld;
+      landModel->lsrMatrix(llh, localToWorld);
+      osg::ref_ptr<osg::MatrixTransform> localToWorldTransform         = new osg::MatrixTransform;
+      osg::ref_ptr<osg::MatrixTransform> localToWorldPickableTransform = new osg::MatrixTransform;
+      localToWorldTransform->setMatrix(localToWorld);
+      localToWorldPickableTransform->setMatrix(localToWorld);
+      inverseLocalToWorld.invert(localToWorld);
+      osg::Vec3d ecef;
+      osg::Vec3d normal;
+      landModel->forward(llh, ecef);
+      landModel->normal(ecef, normal);
+      normal.normalize();
+//       osg::Vec3d centerGridLatLon;
+//       std::cout << "llh before = " << llh[0] << ", " << llh[1] << ", " << llh[2] <<  "\n";
+//       grid.getGridPoint(gridPt,
+//                         llh);
+//       std::cout << "gridPt before = " << gridPt.theGlobalGridPoint[0] << ", " << gridPt.theGlobalGridPoint[1] <<  "\n";
+//       grid.getCenterGridPoint(gridPt,
+//                               5,
+//                               llh);
+//       grid.getLatLon(centerGridLatLon,
+//                      gridPt);
+      
+//       centerGridLatLon[2] = landModel->getHeightAboveEllipsoid(centerGridLatLon[0],
+//                                                                centerGridLatLon[1]);
+ //      landModel->lsrMatrix(centerGridLatLon, localToWorld);
+//       localToWorldTransform->setMatrix(localToWorld);
+//       localToWorldPickableTransform->setMatrix(localToWorld);
+//       inverseLocalToWorld.invert(localToWorld);
+
+//       std::cout << "llh after = " << centerGridLatLon[0] << ", " << centerGridLatLon[1] << ", " << centerGridLatLon[2] <<  "\n";
+      osg::Vec3d localNormal = osg::Matrixd::transform3x3(localToWorld, normal);
+      osg::ref_ptr<ossimPlanetKmlGeometry> geom = *iter;
+      osg::ref_ptr<osg::Vec3Array> verts         = new osg::Vec3Array;
+      osg::ref_ptr<osg::Vec3Array> extrusionVerts = new osg::Vec3Array;
+      std::vector<std::pair<ossim_uint32, ossim_uint32> > extrusionGroups; // will be used for extrusions
+      osg::ref_ptr<osg::Geometry> kmlPrimitiveGeom      = new osg::Geometry;
+      double minHeight, maxHeight;
+      ossimPlanetAltitudeMode altMode = geom->altitudeMode();
+      bool needsOutline = false;
+      double offset = 0.0;
+      osg::ref_ptr<osg::Geode> geometryNode = new osg::Geode;
+      // bool computeNormals = false;
+      bool extrudeFlag = false;
+      // bool hasInnerRings = false;
+      
+      if(geom->toPoint())
+      {
+         ossimPlanetKmlPoint* point = geom->toPoint();
+         const ossimPlanetKmlGeometry::PointListType& pointList = point->pointList();
+         if(pointList.size())
+         {            
+            // we actually need to adjust the Matrix transform for points since we need to center
+            // the location based on altitude type
+            //
+            //
+            osg::Vec3d tempLlh (pointList[0][1],
+                                pointList[0][0],
+                                convertHeight(pointList[0], altMode, landModel));
+            landModel->lsrMatrix(tempLlh, localToWorld);
+            localToWorldTransform->setMatrix(localToWorld);
+            localToWorldPickableTransform->setMatrix(localToWorld);
+            inverseLocalToWorld.invert(localToWorld);
+
+            convertPointsToLocalCoordinates(verts.get(),
+                                            pointList,
+                                            inverseLocalToWorld,
+                                            landModel,
+                                            altMode,
+                                            minHeight,
+                                            maxHeight);
+            
+            if(point->extrudeFlag()&&(altMode!=ossimPlanetAltitudeMode_CLAMP_TO_GROUND))
+            {
+               extrudeFlag = true;
+               // computeNormals = false;
+               convertPointsToLocalCoordinates(extrusionVerts.get(),
+                                               pointList,
+                                               inverseLocalToWorld,
+                                               landModel,
+                                               ossimPlanetAltitudeMode_CLAMP_TO_GROUND,
+                                               minHeight,
+                                               maxHeight);
+               extrusionGroups.push_back(std::make_pair(0, 1));
+            }
+         }
+         osg::ref_ptr<ossimPlanetFadeText> text;
+         osg::ref_ptr<osg::ClusterCullingCallback> textCull;
+         osg::ref_ptr<osg::Geode> textGeometry;
+         osg::ref_ptr<ossimPlanetBillboardIcon> billboardIcon;
+         if(!placemark->name().empty())
+         {
+            text = new ossimPlanetFadeText();
+            text->setText(placemark->name());
+            text->setFont(defaultFont.get());
+            text->setBackdropType(osgText::Text::OUTLINE);
+            osg::Vec3d textEcef(0.0,0.0,0.0);//1000.0/landModel->getNormalizationScale());
+            text->setPosition(textEcef);
+            text->setCharacterSize(30000.0f/landModel->getNormalizationScale());
+            text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
+            text->setAutoRotateToScreen(true);
+            text->setAlignment(osgText::Text::CENTER_BOTTOM);
+            textCull = new osg::ClusterCullingCallback(textEcef, localNormal, 0.0);
+            text->setClusterCullingCallback(textCull.get());
+            textGeometry = new osg::Geode;
+            textGeometry->addDrawable(text.get());
+            textGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+         }
+         if(normalIconStyle)
+         {
+           
+            const osg::ref_ptr<ossimPlanetKmlIcon> icon = normalIconStyle->icon();
+            if(icon.valid())
+            {
+               ossimFilename file = icon->download();
+               osg::ref_ptr<osg::Image> img;
+               if(file.exists())
+               {
+                  osg::ref_ptr<ossimPlanetIconGeom> geom = theLayer->getOrCreateIconEntry(file);
+                  
+                  if(geom.valid())
+                  {
+                     billboardIcon = new ossimPlanetBillboardIcon;
+                     billboardIcon->setGeom(geom.get());
+                  }
+               }
+            }
+         }
+
+         localToWorldPickableTransform->setMatrix(localToWorld);
+         if(billboardIcon.valid())
+         {
+            
+            localToWorldTransform->addChild(billboardIcon.get());
+            localToWorldPickableTransform->addChild(billboardIcon.get());
+            if(text.get()&&textCull.get())
+            {               
+               text->setUpdateCallback(new ossimPlanetKmlTextShiftUpdate(billboardIcon.get(),
+                                                                         textCull.get(),
+                                                                         text->getUpdateCallback()));
+            }
+         }
+         if(textGeometry.valid())
+         {
+            localToWorldTransform->addChild(textGeometry.get());
+         }
+         if(!billboardIcon.valid())
+         {
+            localToWorldPickableTransform->addChild(textGeometry.get());
+            
+         }
+         
+         if(normalLabelStyle&&text.valid())
+         {
+            ossimString color = normalLabelStyle->color();
+            if(color != "")
+            {
+               ossim_uint8 r, g, b, a;
+               ossimPlanetKmlColorToRGBA(r,g,b,a, color);
+               if(normalLabelStyle->colorMode() == ossimPlanetKmlColorMode_RANDOM)
+               {
+                  double tr = (double)rand()/(double)RAND_MAX;
+                  double tg = (double)rand()/(double)RAND_MAX;
+                  double tb = (double)rand()/(double)RAND_MAX;
+                  r = (ossim_uint8)(tr*r);
+                  g = (ossim_uint8)(tg*g);
+                  b = (ossim_uint8)(tb*b);
+               }
+               text->setColor(osg::Vec4(r/255.0,g/255.0,b/255.0,a/255.0) );
+            }
+         }
+         if(localToWorldPickableTransform.valid())
+         {
+            theKmlPickableGeometries->addChild(localToWorldPickableTransform.get());
+         }
+      } // end toPoint
+      else if(geom->toLineString())
+      {
+         ossimPlanetKmlLineString* lineString = geom->toLineString();
+         const ossimPlanetKmlGeometry::PointListType& pointList = lineString->pointList();
+         if(pointList.size())
+         {
+            convertPointsToLocalCoordinates(verts.get(),
+                                            pointList,
+                                            inverseLocalToWorld,
+                                            landModel,
+                                            altMode,
+                                            minHeight,
+                                            maxHeight);
+            if(lineString->extrudeFlag()&&(altMode!=ossimPlanetAltitudeMode_CLAMP_TO_GROUND))
+            {
+               extrudeFlag = true;
+               // computeNormals = true;
+               convertPointsToLocalCoordinates(extrusionVerts.get(),
+                                               pointList,
+                                               inverseLocalToWorld,
+                                               landModel,
+                                               ossimPlanetAltitudeMode_CLAMP_TO_GROUND,
+                                               minHeight,
+                                               maxHeight);
+               extrusionGroups.push_back(std::make_pair((ossim_uint32)0,
+                                                        (ossim_uint32)verts->size()));
+            }
+            kmlPrimitiveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,verts->size()));
+         }
+      }
+      else if(geom->toLinearRing())
+      {
+         ossimPlanetKmlLinearRing* linearRing = geom->toLinearRing();
+         
+         const ossimPlanetKmlGeometry::PointListType& pointList = linearRing->pointList();
+         if(pointList.size())
+         {
+            convertPointsToLocalCoordinates(verts.get(),
+                                            pointList,
+                                            inverseLocalToWorld,
+                                            landModel,
+                                            altMode,
+                                            minHeight,
+                                            maxHeight);
+            if(linearRing->extrudeFlag()&&(altMode!=ossimPlanetAltitudeMode_CLAMP_TO_GROUND))
+            {
+               extrudeFlag = true;
+               // computeNormals = true;
+               convertPointsToLocalCoordinates(extrusionVerts.get(),
+                                               pointList,
+                                               inverseLocalToWorld,
+                                               landModel,
+                                               ossimPlanetAltitudeMode_CLAMP_TO_GROUND,
+                                               minHeight,
+                                               maxHeight);
+               extrusionGroups.push_back(std::make_pair((ossim_uint32)0,
+                                                        (ossim_uint32)verts->size()));
+               
+            }
+            kmlPrimitiveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,verts->size()));
+         }
+      }
+      else if(geom->toPolygon())
+      {
+         ossimPlanetKmlLinearRing* linearRing = geom->toPolygon()->outerBoundary().get();
+         const ossimPlanetKmlPolygon::InnerBoundaryList& innerRings = geom->toPolygon()->innerBoundaryList();
+         extrudeFlag = geom->toPolygon()->extrudeFlag();
+         ossim_uint32 startGroupIdx = 0;
+         
+         if(linearRing)
+         {
+            const ossimPlanetKmlGeometry::PointListType& pointList = linearRing->pointList();
+            if(pointList.size())
+            {
+               convertPointsToLocalCoordinates(verts.get(),
+                                               pointList,
+                                               inverseLocalToWorld,
+                                               landModel,
+                                               altMode,
+                                               minHeight,
+                                               maxHeight);
+               if(extrudeFlag&&(altMode!=ossimPlanetAltitudeMode_CLAMP_TO_GROUND))
+               {
+                     needsReTessFlag = true;
+                     // computeNormals = true;
+                     convertPointsToLocalCoordinates(extrusionVerts.get(),
+                                                     pointList,
+                                                     inverseLocalToWorld,
+                                                     landModel,
+                                                     ossimPlanetAltitudeMode_CLAMP_TO_GROUND,
+                                                     minHeight,
+                                                     maxHeight);
+                     extrusionGroups.push_back(std::make_pair((ossim_uint32)startGroupIdx,
+                                                              (ossim_uint32)pointList.size()));
+                     startGroupIdx += pointList.size();
+               }
+               else
+               {
+                  offset = ossim::max((maxHeight-minHeight)*.25, 5.0);
+               }
+            }
+         }
+         if(innerRings.size() > 0)
+         {
+            // hasInnerRings = true;
+            needsReTessFlag = true;
+            ossim_uint32 innerRingIdx = 0;
+            for(innerRingIdx = 0; innerRingIdx < innerRings.size(); ++innerRingIdx)
+            {
+               const ossimPlanetKmlGeometry::PointListType& pointList = innerRings[innerRingIdx]->pointList();
+               convertPointsToLocalCoordinates(verts.get(),
+                                               pointList,
+                                               inverseLocalToWorld,
+                                               landModel,
+                                               altMode,
+                                               minHeight,
+                                               maxHeight);
+               if(extrudeFlag)
+               {
+                  convertPointsToLocalCoordinates(extrusionVerts.get(),
+                                                  pointList,
+                                                  inverseLocalToWorld,
+                                                  landModel,
+                                                  ossimPlanetAltitudeMode_CLAMP_TO_GROUND,
+                                                  minHeight,
+                                                  maxHeight);
+                  extrusionGroups.push_back(std::make_pair((ossim_uint32)startGroupIdx,
+                                                           (ossim_uint32)(pointList.size())));
+                  startGroupIdx += pointList.size();
+                  
+               }
+               if(!extrudeFlag)
+               {
+                  offset = ossim::max(offset, ossim::max((maxHeight-minHeight)*.25, 5.0));
+               }
+            }
+         }
+         kmlPrimitiveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,verts->size()));
+
+         if(!needsReTessFlag)
+         {
+            if(normalStyle->polyStyle().get())
+            { 
+               const osg::ref_ptr<ossimPlanetKmlPolyStyle> polyStyle = normalStyle->polyStyle();
+               if(polyStyle.valid())
+               {
+                polyStyle->theColor = placemark->getPColor();
+                polyStyle->clearFields();
+                  if(polyStyle->getFillFlag())
+                  {
+                     needsReTessFlag = true;
+                  }
+               }
+            }
+         }
+      }// toPolygon
+      else if(geom->toModel())
+      {
+         const ossimPlanetKmlModel* model = geom->toModel();
+         osg::ref_ptr<ossimPlanetKmlLocation> location = model->location();
+         osg::ref_ptr<ossimPlanetKmlOrientation> orientation = model->orientation();
+         const osg::ref_ptr<ossimPlanetKmlScale> scale = model->scale();
+         osg::ref_ptr<ossimPlanetKmlLink> link     = model->link();
+         double heading = 0.0, pitch = 0.0, roll = 0.0;
+         double scalex = 1.0, scaley=1.0, scalez=1.0;
+         if(orientation.valid())
+         {
+            heading = orientation->heading();
+            pitch = orientation->pitch();
+            roll  = orientation->roll();
+         }
+         if(scale.valid())
+         {
+            scalex = scale->x();
+            scaley = scale->y();
+            scalez = scale->z();
+         }
+         if(location.get()&&link.get())
+         {
+            osg::Vec3d kmlPoint(location->longitude(),
+                                location->latitude(),
+                                location->altitude());
+            osg::Vec3d tempLlh(kmlPoint[1],
+                               kmlPoint[0],
+                               convertHeight(kmlPoint, altMode, landModel));
+//             std::cout << "H = " << tempLlh[2] << std::endl;
+            landModel->lsrMatrix(tempLlh, localToWorld, heading);
+            localToWorld = (osg::Matrixd::scale(scalex, scaley, scalez)*
+                            osg::Matrixd::rotate(pitch, osg::Vec3d(1.0, 0.0, 0.0))*
+                            osg::Matrixd::rotate(roll, osg::Vec3d(0.0, 1.0, 0.0)))*localToWorld;
+            localToWorldTransform->setMatrix(localToWorld);
+            localToWorldPickableTransform->setMatrix(localToWorld);
+            ossimFilename modelName = link->download();
+            if(modelName.exists())
+            {
+               osg::NotifySeverity severity = osg::getNotifyLevel();
+               osg::setNotifyLevel(osg::ALWAYS);
+               osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(modelName.c_str()));
+               osg::setNotifyLevel(severity);
+//                osgDB::ReaderWriter::ReadResult result = osgDB::Registry::instance()->readNode(modelName.c_str(), 0);
+               if(loadedModel.valid())
+               {
+                  std::ifstream in(modelName.c_str());
+                  std::vector<char> buf(4048);
+                  in.read(&buf.front(), buf.size());
+                  double scaleMultiplier = 1.0;
+                  if(in.gcount() > 0)
+                  {
+                     ossimString s(buf.begin(),
+                                   buf.begin() + in.gcount());
+                     ossimString::size_type beginPos = s.find("<asset>");
+                     if(beginPos != std::string::npos)
+                     {
+                        ossimString assetXmlNode;
+                        ossimString::size_type endPos = s.find("</asset>");
+                        if(endPos != std::string::npos)
+                        {
+                           assetXmlNode = ossimString(buf.begin() + beginPos,
+                                                      buf.begin() + endPos+8);
+                           ossimRefPtr<ossimXmlNode> xmlNode = new ossimXmlNode;
+                           std::istringstream inStringStream(assetXmlNode);
+                           if(xmlNode->read(inStringStream))
+                           {
+                              ossimRefPtr<ossimXmlNode> unitNode =  xmlNode->findFirstNode("unit");
+                              if(unitNode.valid())
+                              {
+                                 ossimString scaleValue;
+                                 if(unitNode->getAttributeValue(scaleValue, "meter"))
+                                 {
+                                    scaleMultiplier = scaleValue.toDouble();
+                                 }
+                              }
+                           }
+                        }
+                     }
+                  }
+//                   osg::Vec3d v;
+//                   landModel->forward(tempLlh, v);
+                  osg::MatrixTransform* modelTransform = new osg::MatrixTransform;
+                  double scale2 = (1.0/landModel->getNormalizationScale());
+                  modelTransform->setMatrix(osg::Matrixd::scale((scale2*scaleMultiplier),
+                                                                (scale2*scaleMultiplier),
+                                                                (scale2*scaleMultiplier)));
+                  modelTransform->addChild(loadedModel.get());
+                  modelTransform->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);        
+                  
+//                   modelScaleTransform->addChild(modelTransform);
+                  localToWorldTransform->addChild(modelTransform);
+                  ossimSetNonPowerOfTwoTextureVisitor nv;
+                  localToWorldTransform->accept(nv);
+               }
+            }
+         }
+      }
+//    } 
+      
+      if(extrudeFlag)
+      {
+         extrude(kmlPrimitiveGeom.get(),
+                 verts.get(),
+                 extrusionVerts.get(),
+                 extrusionGroups);
+      }
+      
+      if(altMode==ossimPlanetAltitudeMode_CLAMP_TO_GROUND&&offset > 0.0)
+      {
+         kmlPrimitiveGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonOffset(-offset, -offset),
+                                                                       osg::StateAttribute::ON);
+      }
+      else
+      {
+         offset = 0.0;
+      }
+         
+      
+      if(offset > 0.0)//||(altMode == ossimPlanetAltitudeMode_CLAMP_TO_GROUND))
+      {
+         kmlPrimitiveGeom->setCullCallback(new osg::ClusterCullingCallback(osg::Vec3d(0.0,0.0,0.0),
+                                                                           localNormal,
+                                                                           0.0));
+      }
+
+      
+      kmlPrimitiveGeom->setSupportsDisplayList(true);
+      kmlPrimitiveGeom->setUseDisplayList(true);
+      
+//       kmlPrimitiveGeom->setSupportsDisplayList(!theLod.valid());
+      kmlPrimitiveGeom->setVertexArray(verts.get());
+      
+      osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
+      float lineWidth = 2.0;
+      osg::Vec4 lineColor(1.0,1.0,1.0,1.0);
+      osg::Vec4 polyColor(1.0,1.0,1.0,1.0);
+      osg::PolygonMode::Mode polygonStyleMode = osg::PolygonMode::LINE;
+      bool polyStyleOutline = false;
+      if(normalStyle)
+      {
+         // bool lineColorSetFlag;
+         const osg::ref_ptr<ossimPlanetKmlLineStyle> lineStyle = normalStyle->lineStyle();
+         if(lineStyle.valid())
+         {
+            ossim_uint8 r,g,b,a;
+            ossimPlanetKmlColorToRGBA(r,g,b,a,lineStyle->color());
+            // lineColorSetFlag = true;
+            lineColor = osg::Vec4(r/255.0,
+                                  g/255.0,
+                                  b/255.0,
+                                  a/255.0);
+            lineWidth = lineStyle->width();
+            if(lineWidth != 0.0)
+            {
+               kmlPrimitiveGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(lineWidth),
+                                                                             osg::StateAttribute::ON);
+            }
+         }
+         if(normalStyle->polyStyle().get())
+         {
+            const osg::ref_ptr<ossimPlanetKmlPolyStyle> polyStyle = normalStyle->polyStyle();
+            if(polyStyle.valid())
+            {
+               ossim_uint8 r,g,b,a;
+               ossimPlanetKmlColorToRGBA(r,g,b,a, polyStyle->color());
+               // lineColorSetFlag = true;
+               polyColor = osg::Vec4(r/255.0,
+                                     g/255.0,
+                                     b/255.0,
+                                     a/255.0);
+               
+               if(polyStyle->getFillFlag())
+               {
+                  polygonStyleMode = osg::PolygonMode::FILL;
+               }
+               if(polyStyle->getOutlineFlag())
+               {
+                  polyStyleOutline = true;//(polygonStyleMode == osg::PolygonMode::FILL);
+//                         ossimNotify(ossimNotifyLevel_WARN) << "Outlining not supported yet in Kml drawing" << std::endl;
+               }
+            }
+            kmlPrimitiveGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
+                                                                                               polygonStyleMode),
+                                                                          osg::StateAttribute::ON);
+         }
+      }
+      // check to see if we need to do an outline
+      // If we are extruded or a plygon and have the outline flag enabled
+      // 
+      if(geom->toPolygon())
+      {
+         if(polyStyleOutline&&(polygonStyleMode==osg::PolygonMode::FILL))
+         {
+            needsOutline = true;
+         }
+      }
+      else if(extrudeFlag&&!geom->toPoint()&&!geom->toPolygon())
+      {
+         needsOutline = true;
+      }
+      
+      
+      if((extrudeFlag&&!geom->toPoint())||
+         ((geom->toPolygon()&&(polygonStyleMode==osg::PolygonMode::FILL))))
+      {
+         color->push_back(polyColor);
+      }
+      else
+      {
+         color->push_back(lineColor);
+      }
+//      if((*color)[0][3] < 1.0)
+      {
+         kmlPrimitiveGeom->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);
+      }
+      kmlPrimitiveGeom->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
+      kmlPrimitiveGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
+      kmlPrimitiveGeom->setColorArray(color.get());
+
+
+      osg::ref_ptr<osg::Geometry> outlineGeom;
+#if 1
+      if(needsOutline)
+      {
+         outlineGeom = new osg::Geometry(*kmlPrimitiveGeom, osg::CopyOp::DEEP_COPY_ALL);
+         if(!geom->toPoint()&&extrudeFlag)
+         {
+            // we will only keep the walls around.  Walls are after the root primitive
+            // when extruding
+            //
+            outlineGeom->removePrimitiveSet(0);
+         }
+         outlineGeom->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::OFF);
+         outlineGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
+                                                                                       osg::PolygonMode::LINE),
+                                                                  osg::StateAttribute::ON);
+         outlineGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonOffset(-(offset+1), -(offset+1)),
+                                                                  osg::StateAttribute::ON);
+         outlineGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(lineWidth),
+                                                                  osg::StateAttribute::ON);
+         color = new osg::Vec4Array;
+         color->push_back(lineColor);
+         if((*color)[0][3] < 1.0)
+         {
+            outlineGeom->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
+            outlineGeom->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
+         }
+         outlineGeom->setColorArray(color.get());
+         outlineGeom->setCullCallback(new osg::ClusterCullingCallback(osg::Vec3d(0.0,0.0,0.0),
+                                                                      localNormal,
+                                                                      0.0));
+        geometryNode->addDrawable(outlineGeom.get());
+        outlineGeom->setSupportsDisplayList(true);
+        outlineGeom->setUseDisplayList(true);
+      }
+#endif
+      if(needsReTessFlag)
+      {
+         osgUtil::Tessellator tes;
+         
+         tes.setTessellationType(osgUtil::Tessellator::TESS_TYPE_POLYGONS);
+         tes.setBoundaryOnly(false);
+         tes.setWindingType( osgUtil::Tessellator::TESS_WINDING_ODD);
+         tes.retessellatePolygons(*kmlPrimitiveGeom);
+      }
+
+#if 0
+      if(computeNormals)
+      {
+//          if(outlineGeom.valid())
+         {
+            osgUtil::SmoothingVisitor sv;
+            sv.smooth(*kmlPrimitiveGeom);
+//                FaceNormalVisitor sv;
+//                sv.createFaceNormals(*kmlPrimitiveGeom);  // this will replace the normal vector with a new one
+            kmlPrimitiveGeom->getOrCreateStateSet()->setMode(GL_LIGHTING,
+                                                             osg::StateAttribute::ON);
+            kmlPrimitiveGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::ShadeModel(osg::ShadeModel::FLAT),
+                                                                          osg::StateAttribute::ON);
+         }
+      }
+#endif
+      if(theLod.valid()) // only do a custom draw if we need to
+      {
+         theDraw = new ossimPlanetKmlPlacemarkNode::PlacemarkGeometryDraw;
+         kmlPrimitiveGeom->setDrawCallback(theDraw.get());
+      }
+      if(outlineGeom.valid())
+      {
+         outlineGeom->setDrawCallback(theDraw.get());
+      }
+      if(kmlPrimitiveGeom->getNumPrimitiveSets() > 0)
+      {
+         geometryNode->addDrawable(kmlPrimitiveGeom.get());
+      }
+      if(geometryNode->getNumDrawables()> 0)
+      {
+         localToWorldTransform->addChild(geometryNode.get());
+      }
+      theKmlGeometries->addChild(localToWorldTransform.get());      
+   } // end for loop for each geomtry primitive
+   osg::BoundingSphere bs = theKmlGeometries->getBound();
+   theRadius = bs.radius();
+   theCenter = bs.center();
+   osg::Vec3d tempLlh;
+   landModel->inverse(theCenter, tempLlh);
+   tempLlh[2] = 0.0;
+   landModel->forward(tempLlh, theCenter);
+
+//    std::cout << "<" << tempLlh[0] << ", " << tempLlh[1] << ", " << tempLlh[2] << std::endl;
+//          osgUtil::TriStripVisitor tsv;
+//          tsv.setMinStripSize(3);
+//          tsv.stripify(*kmlPrimitiveGeom);
+   // Now add the geometry
+//    theKmlGeometries->addChild(theGeometry.get());
+   
+   return true;
+}
+
+double ossimPlanetKmlPlacemarkNode::convertHeight(const osg::Vec3d& kmlWorldPoint,
+                                                ossimPlanetAltitudeMode altMode,
+                                                ossimPlanetGeoRefModel* landModel)const
+{
+   osg::Vec3d worldPoint(kmlWorldPoint[1],
+                         kmlWorldPoint[0],
+                         kmlWorldPoint[2]);
+   switch(altMode)
+   {
+      case ossimPlanetAltitudeMode_CLAMP_TO_GROUND:
+      {
+         // note KML is lon then lat so let's reverse
+         return landModel->getHeightAboveEllipsoid(kmlWorldPoint[1],
+                                                   kmlWorldPoint[0]);
+         break;
+      }
+      case ossimPlanetAltitudeMode_RELATIVE_TO_GROUND:
+      {
+         return kmlWorldPoint[2] + landModel->getHeightAboveEllipsoid(kmlWorldPoint[1],
+                                                                      kmlWorldPoint[0]);
+         break;
+      }
+      default:
+      {
+         return kmlWorldPoint[2] + landModel->getGeoidOffset(kmlWorldPoint[1],
+                                                             kmlWorldPoint[0]);
+         break;
+      }
+   }
+   
+   return 0.0;
+}
+
+void ossimPlanetKmlPlacemarkNode::convertPointsToLocalCoordinates(osg::Vec3Array* result,
+                                                                const ossimPlanetKmlGeometry::PointListType& pointList,
+                                                                const osg::Matrixd& worldToLocalTransform,
+                                                                ossimPlanetGeoRefModel* landModel,
+                                                                ossimPlanetAltitudeMode altMode,
+                                                                double& minHeight,
+                                                                double& maxHeight)const
+{
+   minHeight = 99999999.0;
+   maxHeight = -99999999.0;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = pointList.size();
+   osg::Vec3d xyz;
+   osg::Vec3d localPoint;
+   for(idx = 0; idx < upper; ++idx)
+   {
+      osg::Vec3d worldPoint(pointList[idx][1],
+                            pointList[idx][0],
+                            convertHeight(pointList[idx],
+                                          altMode,
+                                          landModel));
+      if(worldPoint[2] < minHeight) minHeight = worldPoint[2];
+      if(worldPoint[2] > maxHeight) maxHeight = worldPoint[2];
+      landModel->forward(worldPoint, xyz);
+      localPoint = xyz*worldToLocalTransform;
+      result->push_back(localPoint);
+   }
+}
+
+// void ossimPlanetKmlPlacemarkNode::extrude(osg::ref_ptr<osg::Geometry> result,
+//                                         osg::Vec3Array* verts,
+//                                         bool polygonFlag)const
+// {
+//    if(verts->size() > 1)
+//    {
+//       ossim_uint32 topSequenceMaxIdx    = verts->size()/2; // top layer
+//       ossim_uint32 startTopIdx = 0;
+//       ossim_uint32 startBottomIdx = topSequenceMaxIdx;
+//       ossim_uint32 idx = 0;
+//       ossim_uint32 idxMax = verts->size();
+      
+//       // lt's do the wall first
+//       osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP, idxMax));
+      
+//       for(idx = 0; idx < idxMax; ++idx)
+//       {
+//          if((idx%2)==0) // do top
+//          {
+//             drawElements[idx] = startTopIdx;
+//             ++startTopIdx;
+//          }
+//          else // do bottom
+//          {
+//             drawElements[idx] = startBottomIdx;
+//             ++startBottomIdx;
+//          }
+//       }
+//       result->addPrimitiveSet(&drawElements);
+//       if(polygonFlag)
+//       {
+//          osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_POLYGON, topSequenceMaxIdx));
+//          for(idx = 0; idx < topSequenceMaxIdx; ++idx)
+//          {
+//             drawElements[idx] = idx;
+//          }
+//          result->addPrimitiveSet(&drawElements);
+//       }
+//       result->setSupportsDisplayList(true);
+//    }
+//    else
+//    {
+//       result->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, verts->size()));  
+//    }
+// }
+void ossimPlanetKmlPlacemarkNode::extrude(osg::ref_ptr<osg::Geometry> result,
+                                          osg::Vec3Array* verts,
+                                          osg::Vec3Array* extrusionVerts,
+                                          const std::vector<std::pair<ossim_uint32, ossim_uint32> >& extrusionGroups)const
+{
+   if(verts->size() == 1)
+   {
+      verts->insert(verts->end(),
+                    extrusionVerts->begin(),
+                    extrusionVerts->end());
+      result->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, verts->size()));  
+   }
+   else
+   {
+      ossim_uint32 offsetIdx = verts->size();
+      ossim_uint32 extrusionIdx = 0;
+      // create walls for geometry
+      verts->insert(verts->end(),
+                    extrusionVerts->begin(),
+                    extrusionVerts->end());
+      for(extrusionIdx = 0; extrusionIdx<extrusionGroups.size();++extrusionIdx)
+      {
+         ossim_uint32 startIdx = extrusionGroups[extrusionIdx].first;
+         ossim_uint32 startTopIdx = startIdx;
+         ossim_uint32 startBottomIdx = startTopIdx + offsetIdx;
+         ossim_uint32 idx = 0;
+         ossim_uint32 idxMax = extrusionGroups[extrusionIdx].second*2;
+         // makeWalls
+         osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP, idxMax));
+         for(idx = 0;idx < idxMax;++idx)
+         {
+            if((idx%2)==0)
+            {
+               drawElements[idx] = startTopIdx;
+               ++startTopIdx;
+               // do top point
+            }
+            else
+            {
+               drawElements[idx] = startBottomIdx;
+               ++startBottomIdx;
+               // do bottom point
+            }
+         }
+         result->addPrimitiveSet(&drawElements);
+      }
+   }
+   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetKmlScreenOverlayNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlScreenOverlayNode.cpp
new file mode 100644
index 0000000..422384d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetKmlScreenOverlayNode.cpp
@@ -0,0 +1,359 @@
+#include <ossimPlanet/ossimPlanetKmlScreenOverlayNode.h>
+#include <osg/Projection>
+#include <osg/Geode>
+#include <osg/MatrixTransform>
+#include <osg/Matrixd>
+#include <osgUtil/CullVisitor>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <osgUtil/IntersectVisitor>
+
+ossimPlanetKmlScreenOverlayNode::ossimPlanetKmlScreenOverlayNode(ossimPlanetKmlLayer* layer,
+                                                                 ossimPlanetKmlObject* obj)
+   :ossimPlanetKmlLayerNode(layer, obj)
+{
+   theCameraNode = new osg::CameraNode;
+   theGroup = new osg::Group;
+   theCameraNode->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+   theCameraNode->setViewMatrix(osg::Matrix::identity());
+   theCameraNode->setClearMask(GL_DEPTH_BUFFER_BIT);
+   theCameraNode->setRenderOrder(osg::CameraNode::POST_RENDER);
+   theGroup->addChild(theCameraNode.get());
+   theViewportChangedFlag = false;
+   theNeedsUpdateFlag = false;
+   osg::StateSet* stateset = theCameraNode->getOrCreateStateSet();
+   stateset->setMode(GL_LIGHTING,
+                     osg::StateAttribute::OFF);
+//   stateset->setMode(GL_COLOR_MATERIAL,
+//                     osg::StateAttribute::OFF);
+   stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+//    stateset->setRenderBinDetails(12,"RenderBin");
+   stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+   stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+}
+
+void ossimPlanetKmlScreenOverlayNode::traverse(osg::NodeVisitor& nv)
+{
+   if(!enableFlag()) return;
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(theViewport.valid()&&theViewportChangedFlag)
+         {
+            theCameraNode->setProjectionMatrix(osg::Matrix::ortho2D(theViewport->x(),
+                                                                    theViewport->width(),
+                                                                    theViewport->y(),
+                                                                    theViewport->height()));
+            theViewportChangedFlag = false;
+            update();
+        }
+
+         if(theNeedsUpdateFlag)
+         {
+            update();
+         }
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(cullVisitor)
+         {
+            double x = cullVisitor->getViewport()->x();
+            double y = (int)cullVisitor->getViewport()->y();
+            double w = (int)cullVisitor->getViewport()->width();
+            double h = (int)cullVisitor->getViewport()->height();
+            if(!theViewport.valid())
+            {
+               theViewport = new osg::Viewport(x,y,w,h);
+               theViewportChangedFlag = true;
+            }
+            else
+            {
+               if( !ossim::almostEqual(theViewport->x(), x)||
+                   !ossim::almostEqual(theViewport->y(), y)||
+                   !ossim::almostEqual(theViewport->width(), w)||
+                   !ossim::almostEqual(theViewport->height(), h))
+               {
+                  theViewport->setViewport(x,y,w,h);
+                  theViewportChangedFlag = true;
+               }
+            }
+         }
+         break;
+      }
+      default:
+      {
+         if(dynamic_cast<osgUtil::IntersectVisitor*>(&nv))
+         {
+            return;
+         }
+         break;
+      }
+   }
+         // if the viewport is valid and we have been setup to draw for the current viewport
+         //
+   if(theViewport.valid())
+   {
+      theGroup->accept(nv);
+   }
+}
+
+bool ossimPlanetKmlScreenOverlayNode::init()
+{
+   osg::ref_ptr<ossimPlanetKmlScreenOverlay> overlay = dynamic_cast<ossimPlanetKmlScreenOverlay*> (theKmlObject.get());
+   if(!overlay.valid()) return false;
+   theViewportChangedFlag = true;
+   theOverlayOrigin[0] = overlay->overlayX();
+   theOverlayOrigin[1] = overlay->overlayY();
+   theOverlayXUnits    = overlay->overlayXUnits();
+   theOverlayYUnits    = overlay->overlayYUnits();
+   theScreenOrigin[0] = overlay->screenX();
+   theScreenOrigin[1] = overlay->screenY();
+   theScreenXUnits    = overlay->screenXUnits();
+   theScreenYUnits    = overlay->screenYUnits();
+   theRotationOrigin[0] = overlay->rotationX();
+   theRotationOrigin[1] = overlay->rotationY();
+   theRotationXUnits    = overlay->rotationXUnits();
+   theRotationYUnits    = overlay->rotationYUnits();
+   theSize[0] = overlay->sizeX();
+   theSize[1] = overlay->sizeY();
+   theSizeXUnits = overlay->sizeXUnits();
+   theSizeYUnits = overlay->sizeYUnits();
+   theRotation   = overlay->rotation();
+   
+   if(overlay->icon().valid())
+   {
+//       std::cout << "Downoading overlay image" << std::endl;
+      ossimFilename file = overlay->icon()->download();
+//      std::cout << "file = " << file << std::endl;
+      if(file.exists())
+      {
+         theIconGeode = new osg::Geode;
+         
+         theIconGeom = theLayer->getOrCreateIconEntry(file);
+         theIconGeom->setGeometry(osg::Vec3d(0.0,0.0,0.0),
+                                  osg::Vec3d(0.0, 0.0, 0.0),
+                                  osg::Vec3d(0.0, 0.0, 0.0));
+         theIconGeode->addDrawable(theIconGeom.get());
+         theCameraNode->addChild(theIconGeode.get());
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   return overlay->icon().valid();
+}
+
+void ossimPlanetKmlScreenOverlayNode::update()
+{
+   if((!theIconGeom.valid())||(!theIconGeom->texture().valid())) return;
+   if(theIconGeom->texture()->getImage())
+   {
+      ossim_uint32 w = theIconGeom->texture()->getImage()->s();
+      ossim_uint32 h = theIconGeom->texture()->getImage()->t();
+      if(w||h)
+      {
+         osg::Vec3d screenOrigin;
+         osg::Vec3d overlayOrigin;
+         osg::Vec3d size;
+         computeScreenXY(screenOrigin);
+         computeOverlayXY(overlayOrigin);
+         computeSize(size);
+//          std::cout << "oringx = " << origin[0] << std::endl;
+//          std::cout << "oringy = " << origin[1] << std::endl;
+         theIconGeom->setGeometry(screenOrigin-overlayOrigin,
+                                  osg::Vec3d(size[0], 0.0, 0.0),
+                                  osg::Vec3d(0.0, size[1], 0.0));
+//       std::cout << "W = " << theIconGeom->texture()->getImage()->s() << std::endl;
+         theNeedsUpdateFlag = false;
+      }
+      else
+      {
+         theNeedsUpdateFlag = true;
+      }
+   }
+   else
+   {
+      theNeedsUpdateFlag = true;
+//       std::cout << "NOT VALID!!!" << std::endl;
+   }
+}
+
+void ossimPlanetKmlScreenOverlayNode::computeOverlayXY(osg::Vec3d& position)
+{
+   osg::Vec3d size;
+   computeSize(size);
+   switch(theOverlayXUnits)
+   {
+      case ossimPlanetKmlUnits_FRACTION:
+      {
+         position[0] = theOverlayOrigin[0]*size[0];
+         break;
+      }
+      case ossimPlanetKmlUnits_PIXELS:
+      {
+         position[0] = theOverlayOrigin[0];
+         break;
+      }
+      case ossimPlanetKmlUnits_INSET_PIXELS:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   switch(theScreenYUnits)
+   {
+      case ossimPlanetKmlUnits_FRACTION:
+      {
+         position[1] = theOverlayOrigin[1]*size[1];
+         
+         break;
+      }
+      case ossimPlanetKmlUnits_PIXELS:
+      {
+         position[1] = theOverlayOrigin[1];
+         break;
+      }
+      case ossimPlanetKmlUnits_INSET_PIXELS:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }   
+}
+
+void ossimPlanetKmlScreenOverlayNode::computeScreenXY(osg::Vec3d& position)
+{
+   switch(theScreenXUnits)
+   {
+      case ossimPlanetKmlUnits_FRACTION:
+      {
+         position[0] = theViewport->x() + theScreenOrigin[0]*theViewport->width();
+         break;
+      }
+      case ossimPlanetKmlUnits_PIXELS:
+      {
+         position[0] = theViewport->x() + theScreenOrigin[0];
+         break;
+      }
+      case ossimPlanetKmlUnits_INSET_PIXELS:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   switch(theScreenYUnits)
+   {
+      case ossimPlanetKmlUnits_FRACTION:
+      {
+         position[1] = theViewport->y() + theScreenOrigin[1]*theViewport->height();
+         
+         break;
+      }
+      case ossimPlanetKmlUnits_PIXELS:
+      {
+         position[1] = theViewport->y() + theScreenOrigin[1];
+         break;
+      }
+      case ossimPlanetKmlUnits_INSET_PIXELS:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+}
+
+void ossimPlanetKmlScreenOverlayNode::computeSize(osg::Vec3d& size)
+{
+   ossim_uint32 iw = (ossim_uint32)theIconGeom->texture()->getImage()->s();
+   ossim_uint32 ih = (ossim_uint32)theIconGeom->texture()->getImage()->t();
+   ossim_uint32 vw = (ossim_uint32)theViewport->width();
+   ossim_uint32 vh = (ossim_uint32)theViewport->height();
+   if(theSize[0] < 0)
+   {
+      size[0] = iw;
+   }
+   else if(theSize[0] > 0)
+   {
+      switch(theSizeXUnits)
+      {
+         case ossimPlanetKmlUnits_FRACTION:
+         {
+            size[0] = theSize[0]*vw;
+            break;
+         }
+         case ossimPlanetKmlUnits_PIXELS:
+         {
+            size[0] = theSize[0];
+            break;
+         }
+         case ossimPlanetKmlUnits_INSET_PIXELS:
+         {
+            break;
+         }
+         default:
+         {
+            break;
+         }
+      }
+   }
+   if(theSize[1] < 0)
+   {
+      size[1] = ih;
+   }
+   else if(theSize[1] > 0)
+   {
+      switch(theSizeXUnits)
+      {
+         case ossimPlanetKmlUnits_FRACTION:
+         {
+            size[1] = theSize[1]*vh;
+            break;
+         }
+         case ossimPlanetKmlUnits_PIXELS:
+         {
+            size[1] = theSize[1];
+            break;
+         }
+         case ossimPlanetKmlUnits_INSET_PIXELS:
+         {
+            break;
+         }
+         default:
+         {
+            break;
+         }
+      }
+   }
+
+   if(theSize[0] == 0 && theSize[1] == 0)
+   {
+      size[0] = iw;
+      size[1] = ih;
+   }
+   else if(theSize[0] == 0)
+   {
+      double scale = (double)size[1]/(double)ih;
+      size[0] = scale*iw;
+   }
+   else if(theSize[1] == 0)
+   {
+      double scale = (double)size[0]/(double)iw;
+      size[1] = scale*ih;
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLabelGeom.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLabelGeom.cpp
new file mode 100644
index 0000000..47d5e61
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLabelGeom.cpp
@@ -0,0 +1,166 @@
+#include <ossimPlanet/ossimPlanetLabelGeom.h>
+#include <osgUtil/CullVisitor>
+
+ossimPlanetLabelGeom::ossimPlanetLabelGeom(const ossimString& label,
+                                           double characterSizeInObjectSpace)
+{
+   theColor = osg::Vec4f(1.0f,1.0f, 1.0f, 1.0f);
+   theLabel = new osgText::Text;
+   theLabel->setAxisAlignment(osgText::Text:: XZ_PLANE);
+   theLabel->setColor(theColor);
+   theLabel->setCharacterSize(characterSizeInObjectSpace);
+   theLabel->setLayout(osgText::Text::LEFT_TO_RIGHT);
+   theLabel->setPosition(osg::Vec3d(0.0,0.0,0.0));
+   theLabel->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
+   theLabel->setAlignment(osgText::Text:: CENTER_BOTTOM);
+   theLabel->setMaximumWidth(-1.0);
+   theLabel->setMaximumHeight(-1.0);
+   theLabel->setText(label);
+   theBillboard = new osg::Billboard;
+   theBillboard->addDrawable(theLabel.get());
+   theBillboard->setMode(osg::Billboard::POINT_ROT_WORLD);
+   theTransform = new osg::MatrixTransform;
+   theShowState = ossimPlanetLabelGeom::SHOW_WHEN_FULL_RES;
+   theShowFlag = true;
+   theEnableFlag = true;
+   theTransform->addChild(theBillboard.get());
+   
+   
+   setUpdateCallback(new ossimPlanetLabelGeomUpdateCallback());
+   dirtyBound();   
+}
+
+ossimPlanetLabelGeom::~ossimPlanetLabelGeom()
+{
+   theLabel     = 0;
+   theBillboard = 0;
+   theTransform = 0;
+}
+
+void ossimPlanetLabelGeom::setAlignment(osgText::Text::AlignmentType alignment)
+{
+   theLabel->setAlignment(alignment);
+   dirtyBound();
+}
+
+void ossimPlanetLabelGeom::setCharacterSizeInObjectSpace(double objectSize)
+{
+   theLabel->setCharacterSize(objectSize);
+   dirtyBound();
+}
+
+osg::ref_ptr<osgText::Text> ossimPlanetLabelGeom::getLabel()
+{
+   return theLabel.get();
+}
+
+void ossimPlanetLabelGeom::setLabel(const ossimString& label)
+{
+   theLabel->setText(label);
+   dirtyBound();
+}
+/**
+ * Setting to 0 or negative says there is no max height.
+ */ 
+void ossimPlanetLabelGeom::setMaxHeightInPixels(double pixelHeight)
+{
+   theMaxHeightInPixels = pixelHeight;
+   dirtyBound();
+}
+/**
+ * Setting to 0 or negative value says there is no minimum height.
+ */ 
+void ossimPlanetLabelGeom::setMinHeightInPixels(double pixelHeight)
+{
+   theMinHeightInPixels = pixelHeight;
+   dirtyBound();
+}
+   
+void ossimPlanetLabelGeom::setColor(float r, float g, float b, float a)
+{
+   theColor[0] = r;
+   theColor[1] = g;
+   theColor[2] = b;
+   theColor[3] = a;
+   
+   theLabel->setColor(theColor);
+}
+
+void ossimPlanetLabelGeom::setEnableFlag(bool enableFlag)
+{
+   theEnableFlag = enableFlag;
+}
+
+void ossimPlanetLabelGeom::setShowFlag(bool show)
+{
+   theShowFlag = show;
+}
+
+void ossimPlanetLabelGeom::traverse(osg::NodeVisitor& nv)
+{
+   if(!theEnableFlag) return;
+   
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(theUpdateTransformFlag)
+         {
+            theTransform->setMatrix(theMatrix);
+            dirtyBound();
+            theUpdateTransformFlag = false;
+         }
+         theTransform->accept(nv);
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cullVisitor = (osgUtil::CullVisitor*)(&nv);
+         double pixelSize = cullVisitor->pixelSize(osg::Vec3d(0.0,0.0,0.0), theLabel->getCharacterHeight());
+         if(theMaxHeightInPixels > 0.0)
+         {
+            if(pixelSize > theMaxHeightInPixels)
+            {
+               theUpdateTransformFlag = true;
+               double scale = theMaxHeightInPixels/pixelSize;
+               theMatrix = osg::Matrixd::scale(osg::Vec3d(scale, scale, scale));
+               if(theShowState == ossimPlanetLabelGeom::SHOW_WHEN_FULL_RES)
+               {
+                  theShowFlag = true;
+               }
+            }
+            else if(theShowState == ossimPlanetLabelGeom::SHOW_WHEN_FULL_RES)
+            {
+               theShowFlag = false;
+            }
+         }
+         else
+         {
+            if((theMinHeightInPixels > 0.0)&&
+               (pixelSize < theMinHeightInPixels))
+            {
+               theUpdateTransformFlag = true;
+               double scale = theMinHeightInPixels/pixelSize;
+               theMatrix = osg::Matrixd::scale(osg::Vec3d(scale, scale, scale));
+            }
+            
+            theShowFlag = true;
+         }
+         if(theShowFlag)
+         {
+            theTransform->accept(nv);
+         }
+         break;
+      }
+      default:
+      {
+         theTransform->accept(nv);
+         break;
+      }
+   }
+}
+
+osg::BoundingSphere ossimPlanetLabelGeom::computeBound() const
+{
+   return theTransform->getBound();
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLand.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLand.cpp
new file mode 100644
index 0000000..296d362
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLand.cpp
@@ -0,0 +1,1695 @@
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <osgUtil/CullVisitor>
+#include <osgDB/DatabasePager>
+#include <osgDB/Registry>
+#include <osgGA/EventVisitor>
+#include <ossimPlanet/ossimPlanetGridUtility.h>
+#include <ossimPlanet/ossimPlanetPagedLandLod.h>
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossimPlanet/ossimPlanetLandReaderWriter.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossim/base/ossimFilename.h>
+#include <iostream>
+#include <osg/GL2Extensions>
+#include <ossimPlanet/ossimPlanetSrtmElevationDatabase.h>
+#include <ossim/elevation/ossimElevSourceFactory.h>
+#include <ossimPlanet/ossimPlanetElevationRegistry.h>
+#include <ossimPlanet/ossimPlanetSrtmElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetDtedElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetGeneralRasterElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+
+class ossimPlanetLandUpdateCallback : public osg::NodeCallback
+{
+public:
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         ossimPlanetLand* n = dynamic_cast<ossimPlanetLand*>(node);
+         if(n)
+         {
+            n->traverse(*nv);
+
+            return;
+         }
+      }
+};
+
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static ossim_uint32 allocated = 0;
+#endif
+
+class ossimPlanetLandRefreshVisitor : public osg::NodeVisitor
+{
+public:
+   ossimPlanetLandRefreshVisitor(ossimPlanetLand* land)
+      :osg::NodeVisitor(NODE_VISITOR,
+                        TRAVERSE_ALL_CHILDREN),
+       theLand(land)
+      {
+         theGrid = theLand->theReaderWriter->gridUtility();
+         theW = theGrid->getTileWidth();
+         theH = theGrid->getTileHeight();
+      }
+   virtual void apply(osg::Group& node)
+      {
+         ossimPlanetPagedLandLod* lod = dynamic_cast<ossimPlanetPagedLandLod*>(&node);
+         if(lod)
+         {
+            double deltaX;
+            double deltaY;
+            theGrid->getWidthHeightInDegrees(deltaX,
+                                             deltaY,
+                                             lod->getLevel(),
+                                             lod->getRow(),
+                                             lod->getCol());
+            double minLat, minLon, maxLat, maxLon;
+            double deltaLat    = deltaY/theH;
+//            double deltaLon    = deltaX/theW;
+            ossimDpt gsd = ossimGpt().metersPerDegree();
+            gsd.y *= deltaLat;
+            theGrid->getLatLonBounds(minLat,
+                                     minLon,
+                                     maxLat,
+                                     maxLon,
+                                     lod->getLevel(),
+                                     lod->getRow(),
+                                     lod->getCol());
+            osg::ref_ptr<ossimPlanetLand::refreshInfo> info = intersects(minLat, minLon, maxLat, maxLon, gsd.y);
+            if(info.valid())
+            {
+               lod->setRefreshType((ossimPlanetLandRefreshType)(lod->refreshType()|info->theRefreshType));
+            }
+         }
+         osg::NodeVisitor::apply(node);
+      }
+   osg::ref_ptr<ossimPlanetLand::refreshInfo> intersects(double minLat, double minLon, double maxLat, double maxLon,
+                                        double gsd)const
+      {
+         ossim_uint32 idx = 0;
+         ossim_uint32 size = theLand->theExtentRefreshList.size();
+         
+         for(idx = 0; idx < size; ++idx)
+         {
+            if(theLand->theExtentRefreshList[idx]->theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon)&&
+               theLand->theExtentRefreshList[idx]->theExtents->intersectsScale(gsd, gsd))
+            {
+               return theLand->theExtentRefreshList[idx].get();
+            }
+         }
+
+         return 0;
+      }
+protected:
+   ossimPlanetLand* theLand;
+   const ossimPlanetGridUtility* theGrid;
+   ossim_uint32 theW;
+   ossim_uint32 theH;
+};
+
+class ossimPlanetLandTextureCallback : public ossimPlanetTextureLayerCallback
+{
+public:
+   ossimPlanetLandTextureCallback(ossimPlanetLand* land, ossimPlanetLandRefreshType refreshType)
+      :theLand(land),
+       theRefreshType(refreshType)
+      {
+      }
+   
+   void setLand(ossimPlanetLand* land)
+      {
+         theLand = land;
+      }
+   virtual void refreshExtent(osg::ref_ptr<ossimPlanetExtents> extent)
+      {
+         if(theLand)
+         {
+            theLand->resetGraph(extent, theRefreshType);
+         }
+      }
+   virtual void layerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+      {
+         if(theLand)
+         {
+            theLand->resetGraph(layer->getExtents(), theRefreshType);
+         }
+      }
+   virtual void layerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                             osg::ref_ptr<ossimPlanetTextureLayer> /*parent*/)
+      {
+         if(theLand)
+         {
+            // only refresh if it was originally enabled
+            if(layer->getEnableFlag())
+            {
+               refreshExtent(layer->getExtents());
+            }
+         }         
+      }
+//    virtual bool addRequest(osg::ref_ptr<ossimPlanetTextureLayer::TextureRequest> request)
+//       {
+//          return false;
+//       }
+  
+protected:
+   ossimPlanetLand* theLand;
+   ossimPlanetLandRefreshType theRefreshType;
+};
+
+ossimPlanetLand::ossimPlanetLand()
+{
+   theShadersInitializedFlag = false;
+//   setPathnameAndRegister(":land");
+//    ossim_uint64 megaByte     = 1024*1024; 
+//    ossim_uint64 gigaByte     = 1024*megaByte; 
+//    ossim_uint64 maxCacheSize = megaByte*2;
+   theTextureLayerCallback = new ossimPlanetLandTextureCallback(this, ossimPlanetLandRefreshType_TEXTURE);
+   theElevationLayerCallback = new ossimPlanetLandTextureCallback(this, ossimPlanetLandRefreshType_PRUNE);
+   //theLandCache = new ossimPlanetLandCache(maxCacheSize, (ossim_uint64)(maxCacheSize*.85));
+   theCurrentShaderProgram = new ossimPlanetShaderProgramSetup();
+   theLandCache = new ossimPlanetLandCache(0,0);
+   theReferenceLayer = new ossimPlanetTextureLayerGroup;
+   theOverlayLayers  = new ossimPlanetTextureLayerGroup;
+   theReferenceLayer->setName("Reference");
+   theOverlayLayers->setName("Overlay");
+   theReaderWriter = new ossimPlanetLandReaderWriter();
+   theReaderWriter->setMultiTextureEnableFlag(false);
+   theReaderWriter->setReferenceLayer(theReferenceLayer.get());
+   theReaderWriter->setOverlayLayers(theOverlayLayers);
+   theReaderWriter->setLandCache(theLandCache.get());
+   initElevation();
+   theReaderWriter->setElevationDatabase(theElevationDatabase.get());
+//    theReaderWriter->setShaderProgram(theCurrentShaderProgram.get());
+   osgDB::Registry::instance()->addReaderWriter(theReaderWriter.get());
+//    theGraphResetFlag = true;
+   setUpdateCallback(new ossimPlanetLandUpdateCallback);
+   theCullCallback = new ossimPlanetLandCullCallback();
+   theReaderWriter->setLandNodeCullCallback(theCullCallback.get());
+   theReferenceLayer->addCallback(theTextureLayerCallback);
+   theOverlayLayers->addCallback(theTextureLayerCallback);
+   theElevationDatabase->addCallback( theElevationLayerCallback );
+   
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++allocated;
+   std::cout << "ossimPlanetLand count++: " << allocated << std::endl;
+#endif
+}
+
+ossimPlanetLand::~ossimPlanetLand()
+{
+   ((ossimPlanetLandTextureCallback*) theTextureLayerCallback.get())->setLand(0);
+   if(theReferenceLayer.valid())
+   {
+      theReferenceLayer->removeCallback(theTextureLayerCallback);
+   }
+   if(theOverlayLayers.valid())
+   {
+      theOverlayLayers->removeCallback(theTextureLayerCallback);
+   }
+   if( theElevationDatabase.valid())
+   {
+      theElevationDatabase->removeCallback( theTextureLayerCallback );
+   }
+   theStateSet = 0;
+  // OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   osgDB::Registry::instance()->removeReaderWriter(theReaderWriter.get());
+//    theNeighborhoodGraph = 0;
+   theReaderWriter      = 0;
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   --allocated;
+   std::cout << "ossimPlanetLand count--: " << allocated << std::endl;
+#endif
+}
+
+void ossimPlanetLand::traverse(osg::NodeVisitor& nv)
+{
+//    static osg::Timer_t lastTick = osg::Timer::instance()->tick();
+   //OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if((theCurrentShaderProgram.valid())&&(!theGL2Extensions.valid()))//&&
+            //(theCurrentShaderProgram->fragmentType() != ossimPlanetShaderProgramSetup::NO_SHADER))
+         {
+            if(!theStateSet.valid())
+            {
+               theStateSet = getOrCreateStateSet();
+               setStateSet(theStateSet.get());
+               initShaders();
+            }
+         }
+         if(!getNumChildren())
+         {
+            resetGraphLocal();
+         }
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshMutex);
+            if(theExtentRefreshList.size())
+            {
+#if 0
+               osgDB::DatabasePager* pager = dynamic_cast<osgDB::DatabasePager*>(nv.getDatabaseRequestHandler());
+               
+               
+               if(pager)
+               {
+                   pager->setAcceptNewDatabaseRequests(false);
+                   pager->clear();
+                   pager->setDatabasePagerThreadPause(true);
+                  
+                  ossimPlanetLandRefreshVisitor refreshVisitor(this);
+                  ossim_uint32 idx = 0;
+                  for(idx = 0; idx < getNumChildren(); ++idx)
+                  {
+                     getChild(idx)->accept(refreshVisitor);
+                  }
+                  pager->setAcceptNewDatabaseRequests(true);
+                  pager->setDatabasePagerThreadPause(false);
+
+                  for(idx = 0; idx < theExtentRefreshList.size(); ++idx)
+                  {
+                     theLandCache->clearTexturesWithinExtents(theExtentRefreshList[idx]->theExtents.get());
+                  }
+               }
+#else
+               osgDB::DatabasePager* pager = dynamic_cast<osgDB::DatabasePager*>(nv.getDatabaseRequestHandler());
+               if(pager)
+               {
+                  pager->setAcceptNewDatabaseRequests(false);
+                  pager->clear();
+                  pager->setDatabasePagerThreadPause(true);
+               }
+               ossimPlanetLandRefreshVisitor refreshVisitor(this);
+               ossim_uint32 idx = 0;
+               for(idx = 0; idx < getNumChildren(); ++idx)
+               {
+                  getChild(idx)->accept(refreshVisitor);
+               }
+               for(idx = 0; idx < theExtentRefreshList.size(); ++idx)
+               {
+                  theLandCache->clearTexturesWithinExtents(theExtentRefreshList[idx]->theExtents.get());
+               }
+               if(pager)
+               {
+                  pager->setAcceptNewDatabaseRequests(true);
+                  pager->setDatabasePagerThreadPause(false);
+               }
+#endif
+               theExtentRefreshList.clear();
+               setRedrawFlag(true);
+            }
+         }
+         ossimPlanetLayer::traverse(nv);
+         
+	break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(cullVisitor)
+         {
+            osg::CullSettings::CullingMode mode = cullVisitor->getCullingMode();
+            
+            ossimPlanetLayer::traverse(nv);
+
+            cullVisitor->setCullingMode(mode);
+         }
+         else
+         {
+            
+            ossimPlanetLayer::traverse(nv);
+         }
+         break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+#if 0
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshMutex);
+         if(theRedrawFlag)
+         {
+            osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+            if(ev)
+            {
+               const osgGA::EventVisitor::EventList& eventList = ev->getEvents();
+               if(eventList.size())
+               {
+                  osgGA::EventVisitor::EventList::const_iterator iter = eventList.begin();
+                  if(((*iter)->getEventType() == osgGA::GUIEventAdapter::FRAME)&&ev->getActionAdapter())
+                  {
+                     ev->getActionAdapter()->requestRedraw();
+                     theRedrawFlag = false;
+                  }
+               }
+            }
+         }
+#endif
+         break;
+      }
+      default:
+      {
+         ossimPlanetLayer::traverse(nv);
+         break;
+      }
+   }
+}
+
+void ossimPlanetLand::setLineOfSiteIntersection(const osg::Vec3d& pt)
+{
+   if(theCullCallback.valid())
+   {
+      theCullCallback->setLineOfSite(pt);
+   }
+}
+
+void ossimPlanetLand::setModel(ossimPlanetGeoRefModel* model)
+{
+   ossimPlanetLayer::setModel(model);
+   resetGraph();
+   theCullCallback = theCullCallback->clone();
+   theReaderWriter->setLandNodeCullCallback(theCullCallback.get());
+   theReaderWriter->setModel(model);
+}
+
+bool ossimPlanetLand::getElevationEnabledFlag()const
+{
+   return theReaderWriter->getElevationEnabledFlag();
+}
+
+void ossimPlanetLand::setElevationEnabledFlag(bool elevationEnabledFlag)
+{
+   resetGraph();
+   theReaderWriter->setElevationEnabledFlag(elevationEnabledFlag);
+}
+
+ossim_float64 ossimPlanetLand::getHeightExag()const
+{
+   return theReaderWriter->getHeightExag();
+}
+
+void ossimPlanetLand::setHeightExag(ossim_float64 heightExag)
+{
+   resetGraph();
+   theReaderWriter->setHeightExag(heightExag);
+}
+
+ossim_uint32 ossimPlanetLand::getElevationPatchSize()const
+{
+   return theReaderWriter->getElevationPatchSize();
+}
+
+void ossimPlanetLand::setElevationPatchSize(ossim_uint32 patchSize)
+{
+   resetGraph();
+   theReaderWriter->setElevationPatchSize(patchSize);
+}
+
+void ossimPlanetLand::setReaderWriter(ossimPlanetLandReaderWriter* /*readerWriter*/)
+{
+}
+
+ossimPlanetLandReaderWriter* ossimPlanetLand::getReaderWriter()
+{
+	return theReaderWriter.get();
+}
+
+const ossimPlanetLandReaderWriter* ossimPlanetLand::getReaderWriter()const
+{
+	return theReaderWriter.get();
+}
+
+ossim_uint32 ossimPlanetLand::getMaxLevelDetail()const
+{
+   return theReaderWriter->getMaxLevelDetail();
+}
+
+void ossimPlanetLand::setMaxLevelDetail(ossim_uint32 maxLevelDetail)
+{
+   resetGraph();
+   theReaderWriter->setMaxLevelDetail(maxLevelDetail);
+}
+
+ossimFilename ossimPlanetLand::getElevationCacheDir()const
+{
+   return theReaderWriter->getElevationCacheDir();
+}
+
+void ossimPlanetLand::setElevationCacheDir(const ossimFilename& cacheDir)
+{
+   resetGraph();
+   theReaderWriter->setElevationCacheDir(cacheDir);
+}
+
+void ossimPlanetLand::resetGraph(const osg::ref_ptr<ossimPlanetExtents> extents,
+                                 ossimPlanetLandRefreshType refreshType)
+
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshMutex);
+   
+   osg::ref_ptr<ossimPlanetLand::refreshInfo> info = new ossimPlanetLand::refreshInfo;
+   info->theRefreshType = refreshType;
+
+   if(extents.valid())
+   {
+      info->theExtents = extents->clone();
+   }
+   else
+   {
+      info->theExtents = new ossimPlanetExtents();
+   }
+   ossim_uint32 idx = 0;
+   bool found = false;
+   for(idx = 0; idx < theExtentRefreshList.size(); ++idx)
+   {
+      if(theExtentRefreshList[idx]->theExtents->equal(info->theExtents))
+      {
+         theExtentRefreshList[idx]->theRefreshType = (ossimPlanetLandRefreshType)(theExtentRefreshList[idx]->theRefreshType |
+                                                                                  refreshType);
+         found = true;
+      }
+   }
+   if(!found)
+   {
+      theExtentRefreshList.push_back(info);
+   }
+   setRedrawFlag(true);
+}
+
+void ossimPlanetLand::resetGraphLocal()
+{
+   theExtentRefreshList.clear();
+   bool hasPagedLods = false;
+
+   ossim_uint32 idx = 0;
+   for(;((idx < getNumChildren())&&(!hasPagedLods));++idx)
+   {
+      hasPagedLods = (dynamic_cast<ossimPlanetPagedLandLod*>(getChild(idx))!= 0);
+   }
+
+   if(!hasPagedLods)
+   {
+      bool addedChild = false;
+      ossim_uint32 faceCount = theReaderWriter->gridUtility()->getNumberOfFaces();
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < faceCount; ++idx)
+      {
+         osg::ref_ptr<osg::Node> node = theReaderWriter->readNode(theReaderWriter->createDbString(0,0,idx), 0).getNode();
+         if(node.valid())
+         {
+            addedChild = true;
+            addChild(node.get());
+         }
+      }
+   }
+   else
+   {
+     for(idx = 0;idx < getNumChildren();++idx)
+      {
+         ossimPlanetPagedLandLod* lod = dynamic_cast<ossimPlanetPagedLandLod*>(getChild(idx));
+         if(lod)
+         {
+            lod->setRefreshType(ossimPlanetLandRefreshType_PRUNE);
+         }
+      }
+   }
+   setRedrawFlag(true);
+}
+
+const osg::ref_ptr<ossimPlanetGeoRefModel> ossimPlanetLand::model()const
+{
+   
+   if(theReaderWriter.valid())
+   {
+      return theReaderWriter->model();
+   }
+
+   return 0;
+}
+
+
+void ossimPlanetLand::accept(osg::NodeVisitor& nv)
+{
+   if(nv.validNodeMask(*this))
+   {
+      nv.pushOntoNodePath(this);
+      nv.apply(*this);
+      nv.popFromNodePath();
+   }
+}
+
+bool ossimPlanetLand::addChild( Node *child )
+{
+   setRedrawFlag(true);
+   return Group::addChild(child);
+}
+
+// ossim_uint32 ossimPlanetLand::getNumberOfTextureLayers()const
+// {
+//    return theTextureLayers->getNumberOfLayers();
+// }
+
+
+// void ossimPlanetLand::setTextureLayer(osg::ref_ptr<ossimPlanetTextureLayer> textureLayer,
+//                                       ossim_uint32 idx)
+// {
+//    ossim_uint32 nLayers = getNumberOfTextureLayers();
+//    if(idx == nLayers)
+//    {
+//       theTextureLayers->addBottom(textureLayer.get());
+//    }
+//    else if(idx < nLayers)
+//    {
+//       theTextureLayers->replaceLayer(idx, textureLayer.get());
+//    }
+//    resetGraph();
+// }
+
+// osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::getTextureLayer(ossim_uint32 idx)
+// {
+//    return theTextureLayers->getLayer(idx);
+// }
+
+// const osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::getTextureLayer(ossim_uint32 idx)const
+// {
+//    return theTextureLayers->getLayer(idx);
+// }
+
+// osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::removeTextureLayer(ossim_uint32 idx)
+// {
+//    return theTextureLayers->removeLayer(idx);
+// }
+
+ossim_uint32 ossimPlanetLand::getNumberOfOverlayLayers()const
+{
+   if(theOverlayLayers.valid())
+   {
+      return theOverlayLayers->numberOfLayers();
+   }
+
+   return 0;
+}
+
+void ossimPlanetLand::setReferenceLayer(osg::ref_ptr<ossimPlanetTextureLayerGroup> reference)
+{
+   if(theReferenceLayer.valid())
+   {
+      theReferenceLayer->removeCallback(theTextureLayerCallback);
+
+   }
+   theReferenceLayer = reference;
+   if(theReaderWriter.valid())
+   {
+      theReaderWriter->setReferenceLayer(theReferenceLayer.get());
+   }
+   if(theReferenceLayer.valid())
+   {
+      theReferenceLayer->addCallback(theTextureLayerCallback);
+   }
+}
+
+osg::ref_ptr<ossimPlanetTextureLayerGroup> ossimPlanetLand::referenceLayer()
+{
+   return theReferenceLayer.get();
+}
+
+const osg::ref_ptr<ossimPlanetTextureLayerGroup> ossimPlanetLand::referenceLayer()const
+{
+   return theReferenceLayer.get();
+}
+
+osg::ref_ptr<ossimPlanetTextureLayerGroup> ossimPlanetLand::overlayLayers()
+{
+   return theOverlayLayers.get();
+}
+
+const osg::ref_ptr<ossimPlanetTextureLayerGroup> ossimPlanetLand::overlayLayers()const
+{
+   return theOverlayLayers.get();
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::overlayLayer(ossim_uint32 layerIdx)
+{
+   if(!theOverlayLayers.valid()) return 0;
+   if(layerIdx < theOverlayLayers->numberOfLayers())
+   {
+      return theOverlayLayers->layer(layerIdx);
+   }
+   
+   return 0;
+}
+
+const osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::overlayLayer(ossim_uint32 layerIdx)const
+{
+   if(!theOverlayLayers.valid()) return 0;
+   if(layerIdx < theOverlayLayers->numberOfLayers())
+   {
+      return theOverlayLayers->layer(layerIdx);
+   }
+   
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetLand::removeOverlayLayer(ossim_uint32 layerIdx)
+{
+   if(!theOverlayLayers.valid()) return 0;
+   return theOverlayLayers->removeLayer(layerIdx);
+}
+
+void ossimPlanetLand::setCurrentFragmentShaderType(ossimPlanetShaderProgramSetup::ossimPlanetFragmentShaderType fragType)
+{
+   if(!theFragShader.valid()||!theCurrentShaderProgram.valid()) return;
+   if((theCurrentShaderProgram->fragmentType() == ossimPlanetShaderProgramSetup::NO_SHADER)&&
+      (fragType!=ossimPlanetShaderProgramSetup::NO_SHADER))
+   {
+      theReaderWriter->setMultiTextureEnableFlag(true);
+   }
+   switch(fragType)
+   {
+      case ossimPlanetShaderProgramSetup::NO_SHADER:
+      {
+         theReaderWriter->setMultiTextureEnableFlag(false);
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::NO_SHADER);
+         theCurrentShaderProgram->setProgram(theNoShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::TOP:
+      {
+         theFragShader->setShaderSource(theTopSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::TOP);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::REFERENCE:
+      {
+         theFragShader->setShaderSource(theReferenceSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::REFERENCE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::OPACITY:
+      {
+         theFragShader->setShaderSource(theOpacitySource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::OPACITY);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::HORIZONTAL_SWIPE:
+      {
+         osg::ref_ptr<osg::Uniform> uniformParam = theCurrentShaderProgram->getUniform("swipeType");
+         if(uniformParam.valid())
+         {
+            uniformParam->set((int)0);  
+         }
+         theFragShader->setShaderSource(theSwipeSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::HORIZONTAL_SWIPE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::VERTICAL_SWIPE:
+      {
+         osg::ref_ptr<osg::Uniform> uniformParam = theCurrentShaderProgram->getUniform("swipeType");
+         if(uniformParam.valid())
+         {
+            uniformParam->set((int)1);  
+         }
+         theFragShader->setShaderSource(theSwipeSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::VERTICAL_SWIPE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::BOX_SWIPE:
+      {
+         osg::ref_ptr<osg::Uniform> uniformParam = theCurrentShaderProgram->getUniform("swipeType");
+         if(uniformParam.valid())
+         {
+            uniformParam->set((int)2);  
+         }
+         theFragShader->setShaderSource(theSwipeSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::BOX_SWIPE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::CIRCLE_SWIPE:
+      {
+         osg::ref_ptr<osg::Uniform> uniformParam = theCurrentShaderProgram->getUniform("swipeType");
+         if(uniformParam.valid())
+         {
+            uniformParam->set((int)3);  
+         }
+         theFragShader->setShaderSource(theSwipeSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::CIRCLE_SWIPE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::ABSOLUTE_DIFFERENCE:
+      {
+         theFragShader->setShaderSource(theAbsoluteDifferenceSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::ABSOLUTE_DIFFERENCE);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+
+         break;
+      }
+      case ossimPlanetShaderProgramSetup::FALSE_COLOR_REPLACEMENT:
+      {
+         theFragShader->setShaderSource(theFalseColorReplacementSource);
+         theFragShader->dirtyShader();
+         theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::FALSE_COLOR_REPLACEMENT);
+         theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+         resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }// end switch
+   if(!theStateSet.valid())
+   {
+	theStateSet = getOrCreateStateSet();
+   }
+   theStateSet->setAttribute(theCurrentShaderProgram->getProgram());
+   setRedrawFlag(true);
+}
+
+void ossimPlanetLand::setCacheSize(ossim_uint64 maxSize, ossim_uint64 minSize)
+{
+   theLandCache->setCacheSize(maxSize, minSize);
+}
+
+ossim_uint64 ossimPlanetLand::getCacheSize()const
+{
+   return theLandCache->getCacheSize();
+}
+
+
+void ossimPlanetLand::setSplitMetricRatio(double ratio)
+{
+   theCullCallback->setSplitMetricRatio(ratio);
+   resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+}
+
+double ossimPlanetLand::getSplitMetricRatio()const
+{
+   return theCullCallback->getSplitMetricRatio();
+
+}
+
+void ossimPlanetLand::setSplitPriorityType(ossimPlanetPriorityType priorityType)
+{
+   theCullCallback->setSplitPriorityType(priorityType);
+}
+
+ossimPlanetPriorityType ossimPlanetLand::getSplitPrioirtyType()const
+{
+   return theCullCallback->getSplitPriorityType();
+}
+
+void ossimPlanetLand::setCullingFlag(bool flag)
+{
+   theCullCallback->setCullingFlag(flag);
+}
+
+bool ossimPlanetLand::getCullingFlag()const
+{
+   return theCullCallback->getCullingFlag();
+}
+
+void ossimPlanetLand::setFreezeRequestFlag(bool flag)
+{
+   theCullCallback->setFreezeRequestFlag(flag);
+}
+
+bool ossimPlanetLand::getFreezRequestFlag()const
+{
+   return theCullCallback->getFreezRequestFlag();
+}
+
+bool ossimPlanetLand::getMipMappingFlag()const
+{
+   return theReaderWriter->getMipMappingFlag();
+}
+
+void ossimPlanetLand::setMipMappingFlag(bool flag)
+{
+   theReaderWriter->setMipMappingFlag(flag);
+   resetGraph(0, ossimPlanetLandRefreshType_TEXTURE);
+}
+
+void ossimPlanetLand::pagedLodAdded(osg::Node* /*parent*/ , osg::Node* /*child*/)
+{
+   setRedrawFlag(true);
+}
+
+void ossimPlanetLand::pagedLodRemoved(osg::Node* /*node*/)
+{
+   setRedrawFlag(true);
+}
+
+void ossimPlanetLand::pagedLodModified(osg::Node* /*node*/)
+{
+   setRedrawFlag(true);
+}
+
+osg::ref_ptr<ossimPlanetShaderProgramSetup> ossimPlanetLand::getCurrentShader()
+{
+   return theCurrentShaderProgram.get();
+}
+
+void ossimPlanetLand::initShaders()
+{
+   theGL2Extensions = new osg::GL2Extensions(0);
+   theShadersInitializedFlag = false;
+   if(!theGL2Extensions->isGlslSupported())
+   {
+      theCurrentShaderProgram = 0;
+      theReaderWriter->setMultiTextureEnableFlag(false);
+      return;
+   }
+   theShadersInitializedFlag = true;
+   theReaderWriter->setMultiTextureEnableFlag(true);
+   theNoShaderProgram = new osg::Program;
+   
+   theCurrentShaderProgram = new ossimPlanetShaderProgramSetup;
+   theLandShaderProgram = new osg::Program;
+   theCurrentShaderProgram->setProgram(theLandShaderProgram.get());
+   ossimFilename file = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+   ossimFilename shaders = file.dirCat("planet");
+   shaders = shaders.dirCat("shaders");
+   if(!shaders.exists())
+   {
+      shaders = ossimEnvironmentUtility::instance()->getInstalledOssimSupportDir();
+      shaders = shaders.dirCat("planet");
+      shaders = shaders.dirCat("shaders");
+   }
+   bool vertexShaderExists = false;
+   if(shaders.exists())
+   {
+      ossimFilename vertShader = shaders.dirCat("land.vert");
+      if(vertShader.exists())
+      {
+         std::vector<char> vertBuf(vertShader.fileSize());
+         std::ifstream in(vertShader.c_str());
+
+         in.read(&vertBuf.front(), vertBuf.size());
+         theLandShaderProgram->addShader(new osg::Shader(osg::Shader::VERTEX, &vertBuf.front()));
+         vertexShaderExists = true;
+      }
+      ossimFilename fragFunctions = shaders.dirCat("land.frag");
+      if(fragFunctions.exists())
+      {
+         std::vector<char> buf(fragFunctions.fileSize());
+         std::ifstream in(fragFunctions.c_str());
+
+         in.read(&buf.front(), buf.size());
+         theLandShaderProgram->addShader(new osg::Shader(osg::Shader::FRAGMENT, &buf.front()));
+      }
+   }
+   if(!vertexShaderExists)
+   {
+      char vertexShaderSource[] = 
+         "varying vec2 projectedPosition;\n"
+         "varying vec4 position;\n"
+         "varying vec3 normal;\n"
+         "void main(void)\n"
+         "{\n"
+         "\n"
+         "   vec4 projPosition = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
+         "   projectedPosition = vec2(projPosition[0]/projPosition[2],projPosition[1]/projPosition[2]);\n"
+         "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+         "   gl_Position = ftransform(); \n"
+         "   position = gl_Position; \n"
+         "   normal = gl_NormalMatrix*gl_Normal; \n"
+        "}\n";
+      theLandShaderProgram->addShader(new osg::Shader(osg::Shader::VERTEX, vertexShaderSource));
+   }
+   theFalseColorReplacementSource =
+      "uniform sampler2D referenceTexture; \n"
+      "uniform sampler2D topTexture; \n"
+      "vec4 simpleShader(vec4 color);\n"
+      "void main(void) \n"
+      "{\n"
+      "    vec4 color;\n"
+      "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+      "    vec4 texb = vec4(0.0,0.0,0.0,0.0);\n"
+      "    float weight = 0.0;\n"
+      "    texa = texture2D(referenceTexture, gl_TexCoord[0].st);\n"
+      "    texb = texture2D(topTexture, gl_TexCoord[0].st);\n"
+      "    color[0] = texa[0];\n"
+      "    color[1] = 0.0;\n"
+      "    color[2] = texb[0];\n"
+      "    color[3] = 1.0;\n"
+      "    if(texb[3] < .000001)\n"
+      "    {\n"
+      "         color = texa;\n"
+      "    }\n"
+     "    gl_FragColor = (color);\n"
+      "}\n";
+   theAbsoluteDifferenceSource =
+      "uniform sampler2D referenceTexture; \n"
+      "uniform sampler2D topTexture; \n"
+      "\n"
+      "void main(void) \n"
+      "{\n"
+      "    vec4 color;\n"
+      "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+      "    vec4 texb = vec4(0.0,0.0,0.0,0.0);\n"
+      "    texa = texture2D(referenceTexture, gl_TexCoord[0].st);\n"
+      "    texb = texture2D(topTexture, gl_TexCoord[0].st);\n"
+      "    color = texa-texb;\n"
+      "    if(texb[3] > .000001)\n"
+      "    {\n"
+      "       color[0] = abs(color[0]);\n"
+      "       color[1] = abs(color[1]);\n"
+      "       color[2] = abs(color[2]);\n"
+      "       color[3] = 1.0;\n"
+      "    }\n"
+      "    else\n"
+      "       color = texa;\n"
+      "    gl_FragColor = color;\n"
+      "}\n";
+   
+      theTopSource = 
+         "uniform sampler2D topTexture; \n"
+         "\n"
+         "void main(void) \n"
+         "{\n"
+         "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+         "    gl_FragColor = texture2D(topTexture, gl_TexCoord[0].st);\n"
+         "}\n";
+      theReferenceSource = 
+         "uniform sampler2D referenceTexture; \n"
+         "\n"
+         "void main(void) \n"
+         "{\n"
+         "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+         "    gl_FragColor = texture2D(referenceTexture, gl_TexCoord[0].st);\n"
+         "}\n";
+      
+      theOpacitySource = 
+         "uniform sampler2D referenceTexture; \n"
+         "uniform sampler2D topTexture; \n"
+         "uniform float param;\n"
+         "\n"
+         "void main(void) \n"
+         "{\n"
+         "    vec4 color;\n"
+         "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+         "    vec4 texb = vec4(0.0,0.0,0.0,0.0);\n"
+         "    texa = texture2D(referenceTexture, gl_TexCoord[0].st);\n"
+         "    texb = texture2D(topTexture, gl_TexCoord[0].st);\n"
+         "    if(texb[3] > .1)\n"
+         "       if(texa[3] > .1)\n"
+         "       {\n"
+         "          color = mix(texa, texb, param*texb[3]);\n"
+         "          color[3] = 1.0;\n"
+         "       }\n"
+         "       else\n"
+         "          color = texb;\n"
+         "    else\n"
+         "       color = texa;\n"
+         "    gl_FragColor = color;\n"
+         "}\n";
+      theSwipeSource = 
+         "uniform sampler2D referenceTexture; \n"
+         "uniform sampler2D topTexture; \n"
+         "uniform float param;\n"
+         "uniform int swipeType;\n"
+         "varying vec2  projectedPosition;\n"
+         "\n"
+         "void main(void) \n"
+         "{\n"
+         "    vec4 color;\n"
+         "    vec4 texa = vec4(0.0,0.0,0.0,0.0);\n"
+         "    vec4 texb = vec4(0.0,0.0,0.0,0.0);\n"
+         "    float dist;\n"
+         "    bool selected = false;\n"
+         "    if(swipeType == 0)\n"
+         "    {\n"
+         "       dist = (1.0 + projectedPosition[0])/2.0;\n"
+         "    }\n"
+         "    else if(swipeType == 1)\n"
+         "    {\n"
+         "       dist = (1.0 + projectedPosition[1])/2.0;\n"
+         "    }\n"
+         "    else if(swipeType == 2)\n"
+         "    {\n"
+         "       dist = max(abs(projectedPosition[0]), abs(projectedPosition[1]));\n"
+         "    }\n"
+         "    else \n"
+         "    {\n"
+         "       dist = length(projectedPosition);\n"
+         "    }\n"
+         "    texa = texture2D(referenceTexture, gl_TexCoord[0].st);\n"
+         "    texb = texture2D(topTexture, gl_TexCoord[0].st);\n"
+         "    if(texb[3] > .000001)\n"
+         "       if(texa[3] > .000001)\n"
+         "         if(dist < abs(param))\n"
+         "            color = texa;\n"
+         "         else\n"
+         "            color = texb;\n"
+         "       else\n"
+         "          color = texb;\n"
+         "    else\n"
+         "       color = texa;\n"
+         "    gl_FragColor = color;\n"
+         "}\n";
+      
+      osg::ref_ptr<osg::Uniform> param = new osg::Uniform("param",
+                                                          (float)1.0);
+      osg::ref_ptr<osg::Uniform> swipeType = new osg::Uniform("swipeType",
+                                                               0);
+      theReferenceTexture = new osg::Uniform("referenceTexture",0);
+      theTopTexture       = new osg::Uniform("topTexture",1);
+      theFragShader = new osg::Shader(osg::Shader::FRAGMENT, theReferenceSource);
+      theCurrentShaderProgram->addUniform(swipeType.get());
+      theCurrentShaderProgram->addUniform(param.get());
+      theCurrentShaderProgram->addUniform(theReferenceTexture.get());
+      theCurrentShaderProgram->addUniform(theTopTexture.get());
+      theLandShaderProgram->addShader(theFragShader.get());   
+      theCurrentShaderProgram->setFragmentType(ossimPlanetShaderProgramSetup::REFERENCE);
+
+
+      theStateSet->addUniform(swipeType.get());
+      theStateSet->addUniform(param.get());
+      theStateSet->addUniform(theReferenceTexture.get());
+      theStateSet->addUniform(theTopTexture.get());
+      theStateSet->setAttribute(theCurrentShaderProgram->getProgram());
+   
+      resetGraph();
+
+}
+
+void ossimPlanetLand::initElevation()
+{
+   ossim_uint32 idx = 0;
+   ossim_uint32 numberOfDatabases = ossimElevManager::instance()->getNumberOfElevationDatabases();
+   theElevationDatabase = new ossimPlanetElevationDatabaseGroup;
+
+   for(idx = 0; idx < numberOfDatabases; ++idx)
+   {
+      const ossimRefPtr<ossimElevationDatabase> database = ossimElevManager::instance()->getElevationDatabase(idx);
+
+      if(database.valid())
+      {
+         ossimFilename directory = ossimFilename(database->getConnectionString());
+         addElevationDirectory(directory, false);
+      }
+   }
+   
+   theElevationDatabase->sortByGsd();
+      
+}
+
+void ossimPlanetLand::addElevationDirectory(const ossimFilename& file, bool sortFlag)
+{
+   osg::ref_ptr<ossimPlanetElevationDatabase> database = ossimPlanetElevationRegistry::instance()->openDatabase(file);
+   addElevation(database.get(), sortFlag);
+}
+
+void ossimPlanetLand::addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag)
+{
+   if(database.valid())
+   {
+      theElevationDatabase->addBottom(database.get());
+   }
+   
+   if(sortFlag)
+   {
+      // make sure the highest accuracy is on top
+      theElevationDatabase->sortByGsd();
+   }   
+}
+
+bool ossimPlanetLand::shadersInitialized()const
+{
+   return theShadersInitializedFlag;
+}
+
+void ossimPlanetLand::clearElevation()
+{
+   if(theElevationDatabase->numberOfLayers() > 0)
+   {
+      theElevationDatabase->removeLayers(0, theElevationDatabase->numberOfLayers());
+   }
+}
+
+void ossimPlanetLand::execute(const ossimPlanetAction &a)
+{
+   const ossimPlanetXmlAction* xmlAction = a.toXmlAction();
+	
+	if(xmlAction)
+	{
+		xmlExecute(*xmlAction);
+	}
+}
+
+void ossimPlanetLand::xmlExecute(const ossimPlanetXmlAction& a)
+{
+
+	std::string command = a.command();
+	if(a.xmlNode().valid())
+	{
+		ossim_uint32 idx = 0;
+		const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+		if(command == "Add")
+		{
+         for(idx = 0;idx<children.size();++idx)
+         {
+				ossimString tag = children[idx]->getTag();
+				osg::ref_ptr<ossimPlanetTextureLayer> layer;
+				osg::ref_ptr<ossimPlanetTextureLayer> namedLayer;
+				ossimString parentName  = children[idx]->getChildTextValue("Parent/name");
+				ossimString parentId    = children[idx]->getChildTextValue("Parent/id");;
+				ossimString description = children[idx]->getChildTextValue("description");
+				ossimString id          = children[idx]->getChildTextValue("id");
+				ossimString name        = children[idx]->getChildTextValue("name");
+				ossimString groupType   = children[idx]->getAttributeValue("groupType");
+				if(!id.empty()&&referenceLayer().valid())
+				{
+					namedLayer = referenceLayer()->findLayerByNameAndId("", id);
+					if(namedLayer.valid())
+					{
+						// do not do duplicate named ID's
+						return;
+					}
+				}
+				if(tag == "Image")
+				{
+					ossimFilename filename  = children[idx]->getChildTextValue("filename");
+					layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(filename);
+				}
+				else if(groupType == "groundTexture")
+				{
+					layer = new ossimPlanetTextureLayerGroup;
+				}
+				if(layer.valid()&&referenceLayer().valid())
+				{
+					if(!parentName.empty()&&!parentId.empty())
+					{
+						namedLayer = referenceLayer()->findLayerByNameAndId(parentName, parentId);
+					}
+					else if(!parentName.empty())
+					{
+						namedLayer = referenceLayer()->findLayerByName(parentName);
+					}
+					else if(!parentId.empty())
+					{
+						namedLayer = referenceLayer()->findLayerById(parentId);
+					}
+					
+					layer->setName(name);
+					layer->setId(id);
+					layer->setDescription(description);
+					
+					if(namedLayer.valid()&&namedLayer->asGroup())
+					{
+						ossimPlanetTextureLayerGroup* group = namedLayer->asGroup();
+						group->addTop(layer.get());
+					}
+					else 
+					{
+						referenceLayer()->addTop(layer.get());
+					}
+				}
+			}
+		}
+		else if(command == "Remove")
+		{
+			ossimString id;
+			ossimString name;
+         ossimString parentId;
+			if(children.size() > 0)
+			{
+				for(idx = 0;idx<children.size();++idx)
+				{
+               parentId = children[idx]->getAttributeValue("parentId");;
+					id       = children[idx]->getAttributeValue("id");
+					name     = children[idx]->getAttributeValue("name");
+					
+					if(id.empty() && name.empty())
+					{
+						id   = children[idx]->getChildTextValue("id");
+						name = children[idx]->getChildTextValue("name");
+					}
+					if(!id.empty()||
+						!name.empty())
+					{
+						ossimPlanetTextureLayer* parent = 0;
+                  if(!parentId.empty())
+						{
+							parent = referenceLayer()->findLayerById(parentId);
+						}
+						else 
+						{
+							parent = referenceLayer().get();
+						}
+						ossimPlanetTextureLayer* layerToRemove = 0;
+						if(parent)
+						{
+							if(!name.empty()&&!id.empty())
+							{
+								layerToRemove = parent->findLayerByNameAndId(name, id);
+							}
+							else if(!name.empty())
+							{
+								layerToRemove = parent->findLayerByName(name);
+							}
+							else if(!id.empty())
+							{
+								layerToRemove = parent->findLayerById(id);
+							}
+						}
+						if(layerToRemove)
+						{
+							layerToRemove->remove();
+						}
+					}
+					
+				}
+			}
+			else
+			{
+				id         = a.xmlNode()->getAttributeValue("id");
+				name       = a.xmlNode()->getAttributeValue("name");
+				ossimPlanetTextureLayer* layerToRemove = 0;
+				if(!name.empty()&&!id.empty())
+				{
+					layerToRemove = referenceLayer()->findLayerByNameAndId(name, id);
+				}
+				else if(!name.empty())
+				{
+					layerToRemove = referenceLayer()->findLayerByName(name);
+				}
+				else if(!id.empty())
+				{
+					layerToRemove = referenceLayer()->findLayerById(id);
+				}
+				
+				if(layerToRemove)
+				{
+					layerToRemove->remove();
+				}
+			}
+		}
+	}
+}
+
+void ossimPlanetLand::addImageObject(const ossimString& /*type*/, const ossimString& /*arg*/)
+{
+#if 0
+   ossimString name;
+   ossimString id;
+   ossimString description;
+   ossimString parentName;
+   ossimString parentId;
+   ossimString objectName;
+   ossimString objectArg;
+   ossim_uint32 idx;
+   if(type == "Image")
+   {
+      ossimString filename;
+      ossimPlanetAction nestedAction(": dummy " + arg);
+      for(idx = 1; idx <= nestedAction.argCount(); ++idx)
+      {
+         if(mkUtils::extractObjectAndArg(objectName,
+                                         objectArg,
+                                         nestedAction.arg(idx)))
+         {
+            if(objectName == "Description")
+            {
+               description = objectArg;
+            }
+            else if(objectName == "Name")
+            {
+               name = objectArg;
+            }
+            else if(objectName == "Id")
+            {
+               id = objectArg;
+            }
+            else if(objectName == "Filename")
+            {
+               filename = objectArg;
+            }
+            else if(objectName == "Parent")
+            {
+               ossimString objectName2;
+               ossimString objectArg2;
+               ossimPlanetAction nestedParentAction(": dummy " + objectArg);
+               ossim_uint32 idx2;
+               for(idx2 = 1; idx2 <= nestedParentAction.argCount(); ++idx2)
+               {
+                  if(mkUtils::extractObjectAndArg(objectName2,
+                                                  objectArg2,
+                                                  nestedAction.arg(idx)))
+                  {
+                     if(objectName == "Name")
+                     {
+                        parentName = objectArg;
+                     }
+                     else if(objectName == "Id")
+                     {
+                        parentId = objectArg;
+                     }
+                  }
+               }// end Parent object for loop
+            }
+         }
+      } // end Image object for loop
+      if(ossimFilename(filename).exists())
+      {
+         osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(filename.c_str());
+         
+         if(layer.valid())
+         {
+				if(layer->isStateSet(ossimPlanetTextureLayer_NO_SOURCE_DATA)||
+					layer->isStateSet(ossimPlanetTextureLayer_NO_GEOM))
+				{
+					// will need to notify later.
+					layer = 0;
+					return;
+				}
+            if(!description.empty())
+            {
+               layer->setDescription(description);
+            }
+            if(!name.empty())
+            {
+               layer->setName(name);
+            }
+            if(!id.empty())
+            {
+               layer->setId(id);
+            }
+            
+            if(parentName.empty()&&parentId.empty())
+            {
+               referenceLayer()->addTop(layer);
+            }
+            else
+            {
+               osg::ref_ptr<ossimPlanetTextureLayer> tempLayer;
+               if(!parentName.empty()&&!parentId.empty())
+               {
+                  tempLayer = referenceLayer()->findLayerByNameAndId(parentName, parentId);
+               }
+               else if(!parentName.empty())
+               {
+                  tempLayer = referenceLayer()->findLayerByNameAndId(parentName, true);                  
+               }
+               else if(!parentId.empty())
+               {
+                  tempLayer = referenceLayer()->findLayerById(parentName, true);                  
+               }
+               osg::ref_ptr<ossimPlanetTextureLayerGroup> layerToAddTo = tempLayer.valid()?tempLayer->asGroup():0;
+                  
+               
+               if(layerToAddTo.valid())
+               {
+                  layerToAddTo->addTop(layer.get());
+               }
+               else
+               {
+               }
+            }
+         }
+      }
+   }   
+   else if(type == "ImageGroup")
+   {
+      ossimPlanetAction nestedAction(": dummy " + arg);
+      for(idx = 1; idx <= nestedAction.argCount(); ++idx)
+      {
+         if(mkUtils::extractObjectAndArg(objectName,
+                                         objectArg,
+                                         nestedAction.arg(idx)))
+         {
+            if(objectName == "Description")
+            {
+               description = objectArg;
+            }
+            else if(objectName == "Name")
+            {
+               name = objectArg;
+            }
+            else if(objectName == "Id")
+            {
+               id = objectArg;
+            }
+            else if(objectName == "Parent")
+            {
+               ossimString objectName2;
+               ossimString objectArg2;
+               ossimPlanetAction nestedParentAction(": dummy " + objectArg);
+               ossim_uint32 idx2;
+               for(idx2 = 1; idx2 <= nestedParentAction.argCount(); ++idx2)
+               {
+                  if(mkUtils::extractObjectAndArg(objectName2,
+                                                  objectArg2,
+                                                  nestedAction.arg(idx)))
+                  {
+                     if(objectName == "Name")
+                     {
+                        parentName = objectArg;
+                     }
+                     else if(objectName == "Id")
+                     {
+                        parentId = objectArg;
+                     }
+                  }
+               }// end Parent object for loop
+            }
+         }
+      }
+      
+      osg::ref_ptr<ossimPlanetTextureLayerGroup> layer = new ossimPlanetTextureLayerGroup;
+      if(!description.empty())
+      {
+         layer->setDescription(description);
+      }
+      if(!name.empty())
+      {
+         layer->setName(name);
+      }
+      if(!id.empty())
+      {
+         layer->setId(id);
+      }
+      if(parentName.empty())
+      {
+         referenceLayer()->addTop(layer.get());
+      }
+      else
+      {
+         osg::ref_ptr<ossimPlanetTextureLayer> tempLayer;
+         if(!parentName.empty()&&!parentId.empty())
+         {
+            tempLayer = referenceLayer()->findLayerByNameAndId(parentName, parentId);
+         }
+         else if(!parentName.empty())
+         {
+            tempLayer = referenceLayer()->findLayerByNameAndId(parentName, true);                  
+         }
+         else if(!parentId.empty())
+         {
+            tempLayer = referenceLayer()->findLayerById(parentName, true);                  
+         }
+         
+         osg::ref_ptr<ossimPlanetTextureLayerGroup> layerToAddTo = tempLayer.valid()?tempLayer->asGroup():0;
+         
+         if(layerToAddTo.valid())
+         {
+            layerToAddTo->addTop(layer.get());
+         }
+         else
+         {
+            
+         }
+      }
+   }
+#endif
+}
+
+void ossimPlanetLand::add(const ossimPlanetAction& /*a*/)
+{
+#if 0
+   ossimString   objectName;
+   ossimString   objectArg;
+   
+   ossim_uint32 idx = 1;
+   for(idx = 1; idx <= (ossim_uint32)a.argCount(); ++idx)
+   {
+      if(mkUtils::extractObjectAndArg(objectName,
+                                      objectArg,
+                                      a.arg(idx)))
+      {
+         if(objectName == "Image")
+         {
+            addImageObject(objectName, objectArg);
+         }
+      }
+   }
+#endif
+}
+
+void ossimPlanetLand::remove(const ossimPlanetAction& /*a*/)
+{
+#if 0
+   ossimString   objectName;
+   ossimString   objectArg;
+   ossim_uint32 idx = 1;
+   for(idx = 1; idx <= (ossim_uint32)a.argCount(); ++idx)
+   {
+      if(mkUtils::extractObjectAndArg(objectName,
+                                      objectArg,
+                                      a.arg(idx)))
+      {
+         if((objectName == "Image")||
+            (objectName == "ImageGroup"))
+         {
+            ossimPlanetAction nestedAction(": dummy " + objectArg);
+            ossim_uint32 idx2;
+            ossimString layerName;
+            ossimString id;
+            for(idx2=1; idx2 <= nestedAction.argCount();++idx2)
+            {
+               ossimString   tempObjectName;
+               ossimString   tempObjectArg;
+               if(mkUtils::extractObjectAndArg(tempObjectName,
+                                               tempObjectArg,
+                                               nestedAction.arg(idx)))
+               {
+                  if(tempObjectName == "Name")
+                  {
+                     layerName = tempObjectArg;
+                  }
+                  else if(tempObjectName == "Id")
+                  {
+                     id = tempObjectArg;
+                  }
+               }
+            }
+            osg::ref_ptr<ossimPlanetTextureLayer> layer;
+            if(!id.empty()&&!layerName.empty())
+            {
+               layer = referenceLayer()->findLayerByNameAndId(layerName, id);
+            }
+            else if(!id.empty())
+            {
+               layer = referenceLayer()->findLayerById(id, true);
+            }
+            else if(!layerName.empty())
+            {
+               layer = referenceLayer()->findLayerByName(layerName, true);
+            }
+            if(layer.valid())
+            {
+               layer->remove();
+            }
+         }
+      }
+   }
+#endif
+}
+
+void ossimPlanetLand::resetGraph(const ossimPlanetAction& /*a*/)
+{
+#if 0
+   if(a.argCount() == 0)
+   {
+      resetGraph();
+   }
+   else
+   {
+      ossimString  bbox = "-180,-90,180,90";
+      ossimString scaleRangeString = "";
+      double minLat = -90.0, minLon = -180.0, maxLat = 90.0, maxLon = 180.0;
+      ossimString  refreshTypeString = "all";
+      ossimString  objectName;
+      ossimString  objectArg;
+      ossim_uint32 idx = 1;
+      for(idx = 1; idx <= (ossim_uint32)a.argCount(); ++idx)
+      {
+         if(mkUtils::extractObjectAndArg(objectName,
+                                         objectArg,
+                                         a.arg(idx)))
+         {
+            if(objectName == "Extents")
+            {
+               ossimPlanetAction nestedAction(": Extents " + objectArg);
+               ossim_uint32 idx2=1;
+               for(;idx2 <= (ossim_uint32)nestedAction.argCount(); ++idx2)
+               {
+                  if(mkUtils::extractObjectAndArg(objectName,
+                                                  objectArg,
+                                                  nestedAction.arg(idx2)))
+                  {
+                     if(objectName == "Bbox")
+                     {
+                        bbox = objectArg;
+                     }
+                     else if(objectName == "ScaleRange")
+                     {
+                        scaleRangeString = objectArg;
+                     }
+                  }
+               }
+            }
+            else if(objectName == "Type")
+            {
+               refreshTypeString = objectArg;
+            }
+         }
+      }
+      osg::ref_ptr<ossimPlanetExtents> extents = new ossimPlanetExtents;
+      ossimPlanetLandRefreshType refreshType = ossimPlanetLandRefreshType_PRUNE;
+      std::vector<ossimString> splitVector;
+      bbox.split(splitVector, ",");
+      if(splitVector.size() == 4)
+      {
+         minLon = splitVector[0].toDouble();
+         minLat = splitVector[1].toDouble();
+         maxLon = splitVector[2].toDouble();
+         maxLat = splitVector[3].toDouble();
+      }
+      refreshTypeString = refreshTypeString.downcase();
+      if(refreshTypeString == "texture")
+      {
+         refreshType = ossimPlanetLandRefreshType_TEXTURE;
+      }
+      else if(refreshTypeString == "geometry")
+      {
+         refreshType = ossimPlanetLandRefreshType_GEOM;
+      }
+      extents->setMinMaxLatLon(minLat, minLon, maxLat, maxLon);
+      if(!scaleRangeString.empty())
+      {
+         splitVector.clear();
+         scaleRangeString.split(splitVector,",");
+         if(splitVector.size() == 2)
+         {
+            extents->setMinMaxScale(splitVector[0].toDouble(),
+                                    splitVector[1].toDouble());
+         }
+      }
+      resetGraph(extents,refreshType);
+   }
+#endif
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLandCache.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLandCache.cpp
new file mode 100644
index 0000000..7fda66b
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLandCache.cpp
@@ -0,0 +1,290 @@
+#include <ossimPlanet/ossimPlanetLandCache.h>
+
+
+void ossimPlanetLandCacheNode::access()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theTimeStamp = osg::Timer::instance()->tick();
+}
+
+void ossimPlanetLandCacheNode::protectedAccess()
+{
+   theTimeStamp = osg::Timer::instance()->tick();
+   
+}
+
+void ossimPlanetLandCacheNode::setExtents(osg::ref_ptr<ossimPlanetExtents> extents)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theExtents = extents.get();
+}
+
+void ossimPlanetLandCacheNode::setTexture(ossim_uint32 idx,
+                                          osg::ref_ptr<ossimPlanetImage> texture)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   
+   if(idx >= theTextureList.size())
+   {
+
+      if(idx == theTextureList.size())
+      {
+         theTextureList.push_back(texture.get());
+      }
+      else
+      {
+         std::vector<osg::ref_ptr<ossimPlanetImage> > tempVec = theTextureList;
+
+         theTextureList.resize(idx-(theTextureList.size()-1));
+         theTextureList.insert(theTextureList.begin(),
+                           tempVec.begin(),
+                           tempVec.end());
+         theTextureList[idx] = texture.get();
+      }
+   }
+   else
+   {
+      theTextureList[idx] = texture.get();
+   }
+
+   adjustSize();
+   protectedAccess();
+}
+
+void ossimPlanetLandCacheNode::clearTextures()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+
+   theTextureList.clear();
+   adjustSize();
+   protectedAccess();   
+}
+
+void ossimPlanetLandCacheNode::setElevation(osg::ref_ptr<ossimPlanetImage> elevation)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theElevation = elevation.get();
+   adjustSize();
+}
+
+void ossimPlanetLandCacheNode::setLandCache(ossimPlanetLandCache* landCache)
+{
+   theLandCache = landCache;
+}
+
+ossim_uint64 ossimPlanetLandCacheNode::getNodeSizeInBytes()const
+{
+   return theNodeSizeInBytes;
+}
+
+void ossimPlanetLandCacheNode::estimateSize()
+{
+   theNodeSizeInBytes = (sizeof(osg::Timer_t)+sizeof(OpenThreads::Mutex)+sizeof(theId)+sizeof(theNodeSizeInBytes)+
+                         sizeof(theExtents)+sizeof(theTextureList)+sizeof(theElevation)+sizeof(theLandCache));
+
+   if(theElevation.valid())
+   {
+      theNodeSizeInBytes += theElevation->getTotalSizeInBytes();
+   }
+   
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theTextureList.size();++idx)
+   {
+      if(theTextureList[idx].valid())
+      {
+         theNodeSizeInBytes += theTextureList[idx]->getTotalSizeInBytes();
+      }
+   }
+}                         
+
+void ossimPlanetLandCacheNode::adjustSize()
+{
+   if(theLandCache)
+   {
+      theLandCache->theCurrentCacheSize -= theNodeSizeInBytes;
+      estimateSize();
+      theLandCache->theCurrentCacheSize += theNodeSizeInBytes;
+      theLandCache->shrinkCache();
+   }
+   else
+   {
+      estimateSize();
+   }
+}
+
+ossimPlanetLandCache::ossimPlanetLandCache(ossim_uint64 maxCacheSize, ossim_uint64 minCacheSize)
+{
+   theMinCacheSize = minCacheSize;
+   theMaxCacheSize = maxCacheSize;
+}
+
+bool ossimPlanetLandCache::addNode(ossimPlanetLandCacheNode* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(!node) return false;
+   if(theMaxCacheSize < node->getNodeSizeInBytes()) return false;
+      
+   ossimPlanetLandCacheType::iterator iter = theCacheMap.find(node->getId());
+
+   if(iter != theCacheMap.end())
+   {
+      iter->second = node;
+      iter->second->access();
+   }
+   else
+   {
+      node->setLandCache(this);
+      theCacheMap.insert(std::make_pair(node->getId(),
+                                        node));
+      theCurrentCacheSize += node->getNodeSizeInBytes();
+   }
+
+   shrinkCache();
+   
+   return true;
+}
+
+ossimPlanetLandCacheNode* ossimPlanetLandCache::getNode(ossim_uint64 id, bool allocateNewNodeIfNotPresent)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(theMaxCacheSize == 0) return 0;
+   ossimPlanetLandCacheType::iterator iter = theCacheMap.find(id);
+   if(iter != theCacheMap.end())
+   {
+      iter->second->access();
+      
+      return iter->second.get();
+   }
+   if(allocateNewNodeIfNotPresent)
+   {
+      ossimPlanetLandCacheNode* newNode = new ossimPlanetLandCacheNode(this, id);
+
+      addNode(newNode);
+
+      return newNode;
+   }
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetLandCacheNode> ossimPlanetLandCache::removeNode(ossim_uint64 id)
+{
+   osg::ref_ptr<ossimPlanetLandCacheNode> result;
+   ossimPlanetLandCacheType::iterator iter = theCacheMap.find(id);
+
+   if(iter != theCacheMap.end())
+   {
+      result = iter->second;
+   }
+
+   return result.get();
+}
+
+void ossimPlanetLandCache::setCacheSize(ossim_uint64 maxCacheSize, ossim_uint64 minCacheSize)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theMaxCacheSize = ossim::max(maxCacheSize, minCacheSize);
+   theMinCacheSize = ossim::min(maxCacheSize, minCacheSize);
+   protectedShrinkCache();
+}
+
+ossim_uint64 ossimPlanetLandCache::getCacheSize()const
+{
+   return theMaxCacheSize;
+}
+
+void ossimPlanetLandCache::shrinkCache()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   protectedShrinkCache();
+}
+void ossimPlanetLandCache::clearCache()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theCacheMap.clear();
+   theCurrentCacheSize = 0;
+}
+
+void ossimPlanetLandCache::clearAllWithinExtents(osg::ref_ptr<ossimPlanetExtents> extents)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimPlanetLandCacheType::iterator iter = theCacheMap.begin();
+
+   while(iter != theCacheMap.end())
+   {
+      if(iter->second->getExtents())
+      {
+         if(iter->second->getExtents()->intersects(*extents))
+         {
+            ossimPlanetLandCacheType::iterator currentIter = iter;
+            ++iter;
+            theCurrentCacheSize -= currentIter->second->getNodeSizeInBytes();
+            theCacheMap.erase(currentIter);
+         }
+         else
+         {
+            ++iter;
+         }
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+}
+
+void ossimPlanetLandCache::clearTexturesWithinExtents(osg::ref_ptr<ossimPlanetExtents> extents)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimPlanetLandCacheType::iterator iter = theCacheMap.begin();
+
+   while(iter != theCacheMap.end())
+   {
+      if(iter->second->getExtents())
+      {
+         if(iter->second->getExtents()->intersects(*extents))
+         {
+            theMutex.unlock();
+            iter->second->clearTextures();
+            theMutex.lock();
+         }            
+      }
+      ++iter;
+   }
+}
+
+
+void ossimPlanetLandCache::protectedShrinkCache()
+{
+   if((theCurrentCacheSize > theMaxCacheSize)&&theCacheMap.size() > 0)
+   {
+      osg::Timer_t timeStamp;
+      while((theCurrentCacheSize > theMinCacheSize)&&(theCacheMap.size() > 0))
+      {
+         ossimPlanetLandCacheType::iterator iter = theCacheMap.begin();
+         ossimPlanetLandCacheType::iterator smallestTimeStampIter = iter;
+         timeStamp = iter->second->timeStamp();
+
+         ++iter;
+         while(iter != theCacheMap.end())
+         {
+            if(iter->second->timeStamp() < timeStamp)
+            {
+               smallestTimeStampIter = iter;
+               timeStamp = iter->second->timeStamp();
+            }
+            
+            ++iter;
+         }
+
+         if(smallestTimeStampIter!=theCacheMap.end())
+         {
+            theCurrentCacheSize -= smallestTimeStampIter->second->getNodeSizeInBytes();
+            theCacheMap.erase(smallestTimeStampIter);
+         }
+      }
+   }
+   if(theCacheMap.size() == 0)
+   {
+      theCurrentCacheSize = 0;
+   }   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLandCullCallback.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLandCullCallback.cpp
new file mode 100644
index 0000000..75a91f7
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLandCullCallback.cpp
@@ -0,0 +1,481 @@
+#include <ossimPlanet/ossimPlanetLandCullCallback.h>
+#include <ossimPlanet/ossimPlanetPagedLandLod.h>
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <osgUtil/CullVisitor>
+#include <osgUtil/IntersectVisitor>
+#include <ossim/base/ossimDrect.h>
+#include <osg/LineSegment>
+
+ossimPlanetLandCullCallback::ossimPlanetLandCullCallback()
+   :osg::NodeCallback(),
+    theFreezeRequestFlag(false),
+    theCullingFlag(true),
+    theSplitMetric(3.0),
+    theSplitPriorityType(ossimPlanetLandPriorityType_LINE_OF_SITE_INTERSECTION),
+    theLineOfSiteValidFlag(false)
+{
+}
+
+void ossimPlanetLandCullCallback::setLineOfSite(const osg::Vec3d& lineOfSite)
+{
+   theLineOfSite = lineOfSite;
+   theLineOfSiteValidFlag = false;
+   if((!ossim::isnan(theLineOfSite[0]))&&
+      (!ossim::isnan(theLineOfSite[1]))&&
+      (!ossim::isnan(theLineOfSite[2])))
+   {
+      theLineOfSiteValidFlag = true;
+   }
+}
+
+void ossimPlanetLandCullCallback::setLineOfSiteValidFlag(bool flag)
+{
+   theLineOfSiteValidFlag = flag;
+}
+
+bool ossimPlanetLandCullCallback::isLineOfSiteValid()const
+{
+   return theLineOfSiteValidFlag;
+}
+
+void ossimPlanetLandCullCallback::setSplitMetricRatio(double ratio)
+{
+   theSplitMetric = ratio;
+}
+
+double ossimPlanetLandCullCallback::getSplitMetricRatio()const
+{
+   return theSplitMetric;
+}
+
+void ossimPlanetLandCullCallback::setSplitPriorityType(ossimPlanetPriorityType priorityType)
+{
+   theSplitPriorityType = priorityType;
+}
+
+ossimPlanetPriorityType ossimPlanetLandCullCallback::getSplitPriorityType()const
+{
+   return theSplitPriorityType;
+}
+
+void ossimPlanetLandCullCallback::setCullingFlag(bool flag)
+{
+   theCullingFlag = flag;
+}
+
+bool ossimPlanetLandCullCallback::getCullingFlag()const
+{
+   return theCullingFlag;
+}
+
+void ossimPlanetLandCullCallback::setFreezeRequestFlag(bool flag)
+{
+   theFreezeRequestFlag = flag;
+}
+
+bool ossimPlanetLandCullCallback::getFreezRequestFlag()const
+{
+   return theFreezeRequestFlag;
+}
+
+void ossimPlanetLandCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+   ossimPlanetPagedLandLod* n = dynamic_cast<ossimPlanetPagedLandLod*>(node);
+   if(n)
+   {
+      applyStandardCull(n, nv);
+   }   
+}
+
+void ossimPlanetLandCullCallback::applyStandardCull(ossimPlanetPagedLandLod* n, osg::NodeVisitor* nv)
+{
+   osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
+   if(n->theRefreshType == ossimPlanetLandRefreshType_PRUNE)
+   {
+      if(n->getNumChildren() > 0)
+      {
+         if(n->getChild(0))
+         {
+            n->getChild(0)->accept(*nv);
+         }
+      }
+
+      return;
+   }
+   if(!cullVisitor)
+   {
+      if(n->isLeaf())
+      {
+         n->getChild(0)->accept(*nv);
+      }
+      else
+      {
+         traverse(n, nv);
+      }
+      return;
+   }
+	const osg::BoundingSphere& bs = n->getBound();
+   bool canCull = true;
+//    bool canCull = n->theLevel >0;//theCullingFlag;
+   n->theRemoveChildrenFlag = false;
+   bool addChildrenFlag = false;
+   double ratio    = theSplitMetric;
+
+   // let's always keep level 0.
+   //
+//    if(n->theLevel < 1) ratio = 99999.0;
+   
+   n->theRemoveChildrenFlag = false;
+   osg::Vec3 real_eye = cullVisitor->getEyeLocal();
+
+   double fov_y, aspect_ratio, z_near, z_far;
+   cullVisitor->getProjectionMatrix()->getPerspective(fov_y, aspect_ratio, z_near, z_far );
+   
+   osg::Vec3d apparent_eye = real_eye;
+   // osg::Vec3d down_eye     = real_eye;
+
+   if( theLineOfSiteValidFlag )
+   {
+        osg::Vec3d look_vector = theLineOfSite - real_eye;
+
+        double opposite = look_vector.length() * tan( osg::DegreesToRadians(fov_y/2.0) );
+        double camera_dist = opposite / tan( osg::DegreesToRadians(50.0/2.0) );
+
+        apparent_eye = theLineOfSite - (look_vector * (camera_dist / look_vector.length()));
+   }
+
+    double radius = bs.radius();
+//    double radius   = (n->theCullNode->boundingBox()->radius());
+//    double distance = n->theCullNode->eyeDistance();
+    double real_distance = (real_eye-bs.center()).length();
+    double apparent_distance = (apparent_eye-bs.center()).length();
+    double distance = min( apparent_distance, real_distance ); // this will keep around tiles close to the eye
+
+//    double pixelSize = cullVisitor->clampedPixelSize(bs);
+    n->theCulledFlag = false;
+   if(canCull)
+   {
+      n->theCullNode->accept(*nv);
+      n->theCulledFlag = n->theCullNode->isCulled();
+   }
+   
+   if((distance < radius*ratio))
+//    if(pixelSize >= 512)
+   {
+      if(n->getNumChildren() < 5)
+      {
+         addChildrenFlag  = true;
+      }
+   }
+    else if( distance > 2*radius*ratio )
+//    else if(pixelSize < 256)
+   {
+      n->theRemoveChildrenFlag = true;
+   }
+   if(addChildrenFlag && ((n->theLevel+1)>n->theMaxLevel))
+   {
+      addChildrenFlag = false;
+   }
+   double     priority = 0.0;
+   osg::Vec3d priorityPoint = apparent_eye;
+
+   
+   if((theSplitPriorityType==ossimPlanetLandPriorityType_LINE_OF_SITE_INTERSECTION)&&theLineOfSiteValidFlag)
+   {
+      priorityPoint = theLineOfSite;
+   }
+   
+   priority = (priorityPoint-bs.center()).length();
+   priority *= 1<<n->theLevel;
+   if(priority > 0.0)
+   {
+      priority = 1.0/priority;
+   }
+   else
+   {
+      priority = 1.0/FLT_EPSILON;
+   }
+   ossimString postFixRefreshType = "";
+   if( (n->theRefreshType&ossimPlanetLandRefreshType_GEOM)&&
+       (n->theRefreshType&ossimPlanetLandRefreshType_TEXTURE))
+   {
+      postFixRefreshType = "_GEOM_TEXTURE";
+   }
+   else if(n->theRefreshType&ossimPlanetLandRefreshType_GEOM)
+   {
+      postFixRefreshType = "_GEOM";
+   }
+   else if(n->theRefreshType&ossimPlanetLandRefreshType_TEXTURE)
+   {
+      postFixRefreshType = "_TEXTURE";
+      
+   }
+   if(!postFixRefreshType.empty()&&!theFreezeRequestFlag)
+   {
+      if(n->isLeaf())
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+postFixRefreshType,
+                                                                   cullVisitor->getNodePath(),
+                                                                   9999999*priority*((std::pow(2.0, (double)n->theLevel))),
+                                                                   nv->getFrameStamp(),
+                                                                   n->theRequestRef,
+                                                                   0);
+      }
+      else
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+postFixRefreshType,
+                                                                   cullVisitor->getNodePath(),
+                                                                   priority*((std::pow(2.0, (double)n->theLevel))),
+                                                                   nv->getFrameStamp(),
+                                                                   n->theRequestRef,
+                                                                   0);
+      }
+      addChildrenFlag = false;
+      
+   }
+
+   if(addChildrenFlag&&!n->theCulledFlag&&!n->theRemoveChildrenFlag)
+   {
+      ossim_uint32 idx = 0;
+      
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockChildList(n->theChildCullNodeListMutex);
+      ossim_uint32 cullCount = 0;
+      for(idx = 0; ((idx < n->theChildCullNodeList.size())&&n->theChildCullNodeList[idx].valid()); ++idx)
+      {
+         n->theChildCullNodeList[idx]->accept(*cullVisitor);
+
+         if(n->theChildCullNodeList[idx]->isCulled())
+         {
+            ++cullCount;
+         }
+      }
+      if(idx >= n->theChildCullNodeList.size())
+      {
+         addChildrenFlag = cullCount != n->theChildCullNodeList.size();
+      }
+   }
+   int childIdx = n->thePagedLodList.size();
+   std::string requestString = ((n->getNumChildren() < 5)&&(n->thePagedLodList.size()<4))?n->theRequestNameList[childIdx+1]:"";
+   if(!theFreezeRequestFlag&&
+      (requestString!= "")&&
+      cullVisitor->getDatabaseRequestHandler())
+   {
+      if(!n->theRemoveChildrenFlag &&
+         addChildrenFlag&&
+         !n->theCulledFlag&&
+         (n->getNumChildren() < 5))
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(requestString,
+                                                                   cullVisitor->getNodePath(),
+                                                                   priority,
+                                                                   nv->getFrameStamp(),
+                                                                   n->theRequestRefChildList[childIdx]);
+      }
+   }
+   if(!n->isLeaf())
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 1; idx < n->getNumChildren(); ++idx)
+      {
+         if(n->getChild(idx))
+         {
+            n->getChild(idx)->accept(*nv);
+         }
+      }
+//       if(n->areAllChildrenCulled(true)&&!n->theCulledFlag)
+//       {
+//          if(n->getChild(0))
+//          {
+//             n->getChild(0)->accept(*nv);
+//          }
+//       }
+   }
+   else
+   {
+      if(n->getNumChildren() > 0)
+      {
+         if(n->getChild(0))
+         {
+            if(!n->theCulledFlag)
+            {
+               n->getChild(0)->accept(*nv);
+            }
+         }
+      }
+   }
+}
+
+#if 0
+void ossimPlanetLandCullCallback::applyOrthoCull(ossimPlanetPagedLandLod* n,
+                                                 osg::NodeVisitor* nv)
+{
+   //OpenThreads::ScopedLock<OpenThreads::Mutex> lock(n->theMutex);
+
+   osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
+   if(n->theRefreshType == ossimPlanetLandRefreshType_PRUNE)
+   {
+      if(n->getNumChildren() > 0)
+      {
+         if(n->getChild(0))
+         {
+            n->getChild(0)->accept(*nv);
+         }
+      }
+      cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+"_GEOM",
+                                                                n,
+                                                                99999999,
+                                                                nv->getFrameStamp());
+      return;
+   }
+   if(!cullVisitor) return;
+   n->theCulledFlag = false;
+   bool addChildrenFlag = false;
+   n->theRemoveChildrenFlag = false;
+   double distance=0.0;
+   osg::Matrix wm = cullVisitor->getWindowMatrix();
+
+   const osg::RefMatrix& m = *(cullVisitor->getMVPW());
+   double x = cullVisitor->getViewport()->x();
+   double y = cullVisitor->getViewport()->y();
+   double w = cullVisitor->getViewport()->width();
+   double h = cullVisitor->getViewport()->height();
+   if(w < 1) w = 1;
+   if(h < 1) h = 1;
+   ossimDrect viewportRect(x,
+                           y,
+                           x + (w-1),
+                           y + (h-1));
+   wm = osg::Matrixd::inverse(*cullVisitor->getProjectionMatrix());
+
+   osg::Vec3d center = (osg::Vec3d(0.0,0.0, 1.0)*wm);
+   osg::Vec3d projectedCenter = (n->theCenterPoint*m);
+   distance = (center-n->getBound().center()).length();
+//    distance = (center-n->getBound().center()).length()/(sqrt(180.0*180.0 + 90.0*90.0));
+//    
+//    distance = (osg::Vec2d(projectedCenter[0],
+//                           projectedCenter[1]) -
+//                osg::Vec2d(w/2.0,
+//                           h/2.0)).length();
+   
+   osg::Vec3d ulView = n->theUlPoint*m;
+   osg::Vec3d urView = n->theUrPoint*m;
+   osg::Vec3d lrView = n->theLrPoint*m;
+   osg::Vec3d llView = n->theLlPoint*m;
+   ossimDpt ulViewDpt(ulView[0], ulView[1]);
+   ossimDpt urViewDpt(urView[0], urView[1]);
+   ossimDpt lrViewDpt(lrView[0], lrView[1]);
+   ossimDpt llViewDpt(llView[0], llView[1]);
+   ossimDrect rect(ulViewDpt,
+                   urViewDpt,
+                   lrViewDpt,
+                   llViewDpt);
+   
+   n->theCulledFlag = !rect.intersects(viewportRect);
+   
+   float pixelSize = ossim::max(rect.width(), rect.height());
+   if(pixelSize >= 512)
+   {
+      if(n->isLeaf())
+      {
+         addChildrenFlag = true;
+      }
+   }
+   else if(pixelSize < 256)
+   {
+//       if(!n->isLeaf())
+      {
+         n->theRemoveChildrenFlag = true;
+      }
+   }
+   
+   distance *= 1<<n->theLevel;
+   double priority = 0.0;
+   if(distance > 0.0)
+   {
+      priority = 1.0/distance;
+   }
+   else
+   {
+      priority = 1.0/FLT_EPSILON;
+   }
+   if((n->theRefreshType == ossimPlanetLandRefreshType_GEOM)&&(!n->theCulledFlag))
+   {
+      cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+"_GEOM",
+                                                                n,
+                                                                priority,
+                                                                nv->getFrameStamp());
+   }
+   else if((n->theRefreshType == ossimPlanetLandRefreshType_TEXTURE)&&(!n->theCulledFlag))
+   {
+      cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+"_TEXTURE",
+                                                                n,
+                                                                priority,
+                                                                nv->getFrameStamp());
+   }
+   std::string requestString = ((n->getNumChildren() < 5)&&(n->thePagedLodList.size()<4))?n->theRequestNameList[n->thePagedLodList.size()+1]:"";
+//   std::string requestString = (n->getNumChildren() < 5)?n->getRequestName(n->getNumChildren()):"";
+   if((requestString!= "")&&
+      cullVisitor->getDatabaseRequestHandler())
+   {
+      if((n->theRefreshType == ossimPlanetLandRefreshType_GEOM)&&(!n->theCulledFlag))
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+"_GEOM",
+                                                                   n,
+                                                                   priority,
+                                                                   nv->getFrameStamp());
+      }
+      else if((n->theRefreshType == ossimPlanetLandRefreshType_TEXTURE)&&(!n->theCulledFlag))
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(n->theRequestNameList[0]+"_TEXTURE",
+                                                                   n,
+                                                                   priority,
+                                                                   nv->getFrameStamp());
+      }
+      if(!n->theRemoveChildrenFlag &&
+         addChildrenFlag&&
+         !n->theCulledFlag&&
+         (n->getNumChildren() < 5))
+      {
+         cullVisitor->getDatabaseRequestHandler()->requestNodeFile(requestString,
+                                                                   n,
+                                                                   priority,
+                                                                   nv->getFrameStamp());
+      }
+      else if((n->theCulledFlag)&&
+              (n->isLeaf())&&
+              (n->getNumChildren()>1))
+      {
+			ossimPlanetDatabasePager* pager = dynamic_cast<ossimPlanetDatabasePager*>(cullVisitor->getDatabaseRequestHandler());
+          if(pager)
+          {
+             pager->invalidateRequest(requestString);
+          }
+      }
+   }
+   if(!n->theCulledFlag)
+   {
+      if(n->getNumChildren() >4)
+      {
+         ossim_uint32 idx = 0;
+         for(idx = 1; idx < n->getNumChildren(); ++idx)
+         {
+            if(n->getChild(idx))
+            {
+               n->getChild(idx)->accept(*nv);
+            }
+         }
+      }
+      else
+      {
+         if(n->getNumChildren() > 0)
+         {
+            if(n->getChild(0))
+            {
+               n->getChild(0)->accept(*nv);
+            }
+         }
+      }
+   }
+}
+#endif
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLandReaderWriter.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLandReaderWriter.cpp
new file mode 100644
index 0000000..476edaa
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLandReaderWriter.cpp
@@ -0,0 +1,1864 @@
+#include <ossimPlanet/ossimPlanetLandReaderWriter.h>
+#include <ossimPlanet/ossimPlanetPlaneGrid.h>
+#include <ossimPlanet/ossimPlanetCubeGrid.h>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include <osg/CullFace>
+#include <osg/Program>
+#include <osg/Uniform>
+#include <osgUtil/SmoothingVisitor>
+#include <osgUtil/GLObjectsVisitor>
+#include <osgUtil/Optimizer>
+#include <osgUtil/CullVisitor>
+#include <osg/PagedLOD>
+#include <osgUtil/SmoothingVisitor>
+#include <osgUtil/TriStripVisitor>
+#include <osgDB/Registry>
+#include <OpenThreads/ScopedLock>
+#include <ossimPlanet/ossimPlanetBoundingBox.h>
+#include <ossimPlanet/ossimPlanetLandTextureRequest.h>
+#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <ossim/elevation/ossimElevManager.h>
+// #include <ossimPlanet/ossimPlanetElevationGrid.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetPagedLandLod.h>
+#include <ossimPlanet/ossimPlanetTexture2D.h>
+#include <ossim/base/ossimDrect.h>
+#include <ossim/base/ossimDpt.h>
+#include <ossim/base/ossimEndian.h>
+#include <osgUtil/Simplifier>
+#include <ossim/base/ossimGeoidManager.h>
+
+static ossim_uint32 landReaderWriterId = 0;
+
+ossimPlanetLandReaderWriter::ossimPlanetLandReaderWriter()
+   :theId(landReaderWriterId++)
+{  
+   theLandType = ossimPlanetLandType_NORMALIZED_ELLIPSOID;
+   theMaxLevelDetail    = 18;
+   theHeightExag        = 1.0;
+   theElevationPatchSize= 17;
+   theElevationEnabledFlag   = true;
+   theMultiTextureEnableFlag = false;
+   theMipMappingFlag = true;
+   theGrid          = new ossimPlanetCubeGrid;
+   theElevationGrid = new ossimPlanetCubeGrid;
+}
+
+const char* ossimPlanetLandReaderWriter::className()const
+{
+   return "ossimPlanetLandReaderWriter";
+}
+
+osgDB::ReaderWriter::ReadResult ossimPlanetLandReaderWriter::readNode(const std::string& filename, const Options* /* options */ )const
+{
+
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(!theModel.valid()) return 0;
+  // std::cout << "ossimPlanetLandReaderWriter::readNode filename = " << filename << std::endl;
+   osgDB::ReaderWriter::ReadResult result = 0;
+   if(filename == "") return result;
+   ossim_uint32 level;
+   ossim_uint32 row;
+   ossim_uint32 col;
+   ossim_uint32 id;
+   ossimPlanetLandReaderWriterGeomType geomType = ossimPlanetLandReaderWriterGeomType_NONE;
+
+   if(!extractValues(filename,
+                     level,
+                     row,
+                     col,
+                     id,
+                     geomType))
+   {
+      return result;
+   }
+//    std::cout << "level = " << level << std::endl;
+   if(id != theId)
+   {
+      return result;
+   }
+   osg::Vec3d centerPoint;
+   osg::Vec3d ulPoint;
+   osg::Vec3d urPoint;
+   osg::Vec3d lrPoint;
+   osg::Vec3d llPoint;
+   osg::Vec3d centerNormal;
+   osg::Vec3d ulNormal;
+   osg::Vec3d urNormal;
+   osg::Vec3d lrNormal;
+   osg::Vec3d llNormal;
+   osg::ref_ptr<ossimPlanetBoundingBox> box = new ossimPlanetBoundingBox;
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+//    unsigned int w = theUtility.getTileWidth();
+//    unsigned int h = theUtility.getTileHeight();
+   theGrid->getLatLonBounds(minLat,
+                            minLon,
+                            maxLat,
+                            maxLon,
+                            level,
+                            row, // row 
+                            col);
+   ossim_uint64 tileId = theGrid->getId(level, row, col);
+   osg::ref_ptr<ossimPlanetLandCacheNode> cacheNode = theLandCache->getNode(tileId, true);
+   if(cacheNode.valid())
+   {
+      double dx, dy;
+      theGrid->getPixelScaleAsMeters(dx, dy, level, row, col);
+      double scale = (dx+dy)*.5;
+      ossimPlanetExtents* extents = new ossimPlanetExtents;
+      extents->setMinMaxLatLon(minLat, minLon, maxLat, maxLon);
+      extents->setMinMaxScale(scale*.5, scale*2.0);
+      
+      cacheNode->setExtents(extents);
+   }
+   
+   ossimPlanetImage::ossimPlanetImageStateType textureState = ossimPlanetImage::ossimPlanetImageStateType_LOADED;
+   osg::ref_ptr<ossimPlanetImage> elevationGrid;
+
+   std::vector<osg::ref_ptr<osg::Texture2D> > textures;
+   newTexture(textures,
+              level,
+              row,
+              col,
+              textureState);
+   
+   if(geomType & ossimPlanetLandReaderWriterGeomType_TEXTURE)
+   {
+      ossimPlanetLandTextureRequest* landRequest = new ossimPlanetLandTextureRequest(level, row, col, textures);
+      osgUtil::GLObjectsVisitor v;
+      landRequest->setTextureState(textureState);
+      
+      landRequest->accept(v);
+      
+      return landRequest;
+   }
+   if(geomType & (ossimPlanetLandReaderWriterGeomType_GEOM|ossimPlanetLandReaderWriterGeomType_LOD))
+   {
+      elevationGrid = newElevation(level, row, col);
+   }
+   osg::ref_ptr<ossimPlanetPagedLandLod> pagedLod;
+   if(geomType & ossimPlanetLandReaderWriterGeomType_LOD)
+   {
+      pagedLod = new  ossimPlanetPagedLandLod(level, row, col, filename);
+   }
+   osg::ref_ptr<ossimPlanetBoundingBox> boundingBox = new ossimPlanetBoundingBox;
+   bool useClusterCulling = false;
+   osg::Vec3d clusterControlPoint ;
+   osg::Vec3d clusterCenterNormal;
+   double minDotProduct;
+   double maxClusterCullingRadius;
+   osg::ref_ptr<osg::MatrixTransform> trans = newGeometry(level,
+                                                          row,
+                                                          col,
+                                                          textures,
+                                                          elevationGrid,
+                                                          *boundingBox,
+                                                          useClusterCulling,
+                                                          clusterControlPoint,
+                                                          clusterCenterNormal,
+                                                          minDotProduct,
+                                                          maxClusterCullingRadius);
+   std::vector<ossimPlanetBoundingBox> childrenBounds;
+   
+   if(!pagedLod.valid())
+   {
+      ossimPlanetLandTextureRequest* landRequest = new ossimPlanetLandTextureRequest(level, row, col, textures);
+      landRequest->setTextureState(textureState);
+//       landRequest->setTransform(trans);
+      landRequest->setCullCallback(theCullNodeCallback.get());
+      initSupportAttributes(level,
+                            row,
+                            col,
+                            centerPoint,
+                            ulPoint,
+                            urPoint,
+                            lrPoint,
+                            llPoint,
+                            centerNormal,
+                            ulNormal,
+                            urNormal,
+                            lrNormal,
+                            llNormal,
+                            *box,
+                            childrenBounds,
+                            *trans);
+      landRequest->setCenterPoint(centerPoint);
+      landRequest->setUlPoint(ulPoint);
+      landRequest->setUrPoint(urPoint);
+      landRequest->setLrPoint(lrPoint);
+      landRequest->setLlPoint(llPoint);
+      landRequest->setCenterNormal(centerNormal);
+      landRequest->setUlNormal(ulNormal);
+      landRequest->setUrNormal(urNormal);
+      landRequest->setLrNormal(lrNormal);
+      landRequest->setLlNormal(llNormal);
+//       if(level == 0)
+//       {
+//          landRequest->setBoundingBox(box);
+//       }
+//       else
+//       {
+      landRequest->setBoundingBox(boundingBox);
+//       }
+//       landRequest->setChildrenBounds(childrenBounds);
+//       osgUtil::GLObjectsVisitor v;
+      
+//       landRequest->accept(v);
+
+//       if(useClusterCulling)
+//       {
+//          landRequest->setClusterCullValues(useClusterCulling,
+//                                            clusterControlPoint,
+//                                            clusterCenterNormal,
+//                                            minDotProduct,
+//                                            maxClusterCullingRadius);
+//       }
+      return landRequest;
+   }
+
+   if(theGrid->getNumberOfFaces() <3)
+   {
+      ossimPlanetGridUtility::GridPoint centerGridPoint;
+      
+      theGrid->getCenterGridPoint(centerGridPoint, level, row, col);
+      
+      theGrid->getLatLon(centerPoint, centerGridPoint);
+      if(centerPoint[0] > 60.0)
+      {
+         pagedLod->theMaxLevel = ((minLat > 80.0)?4:99999999);
+      }
+      else if(centerPoint[0] < -60)
+      {
+         pagedLod->theMaxLevel = ((maxLat < -80.0)?4:99999999);
+      }
+      else
+      {
+         pagedLod->theMaxLevel = 99999999;
+      }
+   }
+//    pagedLod->theTransform = trans.get();
+
+   osg::ref_ptr<osg::Geode> geode = dynamic_cast<osg::Geode*>(trans->getChild(0));
+   if(geode.valid())
+   {
+//      geode->getDrawable(0)->setDrawCallback(new ossimPlanetPagedLandDrawableCallback(pagedLod.get()));
+//      geode->getDrawable(0)->setDrawCallback(new ossimPlanetPagedLandDrawableCallback(level, row, col));
+   }
+   
+   initSupportAttributes(level,
+                         row,
+                         col,
+                         centerPoint,
+                         ulPoint,
+                         urPoint,
+                         lrPoint,
+                         llPoint,
+                         centerNormal,
+                         ulNormal,
+                         urNormal,
+                         lrNormal,
+                         llNormal,
+                         *box,
+                         childrenBounds,
+                         *trans);
+   pagedLod->theGeode = geode;
+   pagedLod->theCenterPoint = centerPoint;
+   pagedLod->theUlPoint = ulPoint;
+   pagedLod->theUrPoint = urPoint;
+   pagedLod->theLrPoint = lrPoint;
+   pagedLod->theLlPoint = llPoint;
+   pagedLod->theCenterNormal = centerNormal;
+   pagedLod->theUlNormal = ulNormal;
+   pagedLod->theUrNormal = urNormal;
+   pagedLod->theLrNormal = lrNormal;
+   pagedLod->theLlNormal = llNormal;
+
+   pagedLod->theCullNode = new ossimPlanetPagedLandLodCullNode(boundingBox,
+                                                               useClusterCulling,
+                                                               clusterControlPoint,
+                                                               clusterCenterNormal,
+                                                               minDotProduct,
+                                                               maxClusterCullingRadius);
+   pagedLod->theCullNode->setMatrix(trans->getMatrix());
+   
+   int face = theGrid->getFace(level, row, col);
+   ossim_uint64 wide;
+   ossim_uint64 high;
+   ossim_uint64 originX = col;
+//   ossim_uint64 originY = row;
+   
+   theGrid->getNumberOfTilesWideHighPerFace(wide, high, level);
+
+   originX -= face*wide;
+   theGrid->getNumberOfTilesWideHighPerFace(wide, high, level+1);
+   
+   pagedLod->setCullCallback(theCullNodeCallback.get());
+   pagedLod->addChild(trans.get());
+
+    
+   pagedLod->setRequestName(0,
+                            createDbString(level,
+                                           row,
+                                           col));
+   if(textureState == ossimPlanetImage::ossimPlanetImageStateType_NEEDS_LOADING)
+   {
+      pagedLod->setRefreshType(ossimPlanetLandRefreshType_TEXTURE);
+   }
+   if(level+1 <= theMaxLevelDetail)
+   {
+      pagedLod->setRequestName(1,
+                               createDbString(level+1,
+                                              row<<1,
+                                              (originX<<1)+(face*wide)));
+      pagedLod->setRequestName(2,
+                               createDbString(level+1,
+                                              row<<1,
+                                              ((originX<<1) + 1)+(face*wide)));
+      pagedLod->setRequestName(3,
+                               createDbString(level+1,
+                                              (row<<1)+1,
+                                              ((originX<<1)+1)+(face*wide)));
+      pagedLod->setRequestName(4,
+                               createDbString(level+1,
+                                              (row<<1)+1,
+                                              (originX<<1)+(face*wide)));
+   }
+   else
+   {
+      pagedLod->setRequestName(1,
+                               "");
+      pagedLod->setRequestName(2,
+                               "");
+      pagedLod->setRequestName(3,
+                               "");
+      pagedLod->setRequestName(4,
+                               "");
+   }
+   
+//    osgUtil::GLObjectsVisitor v;
+   
+//    pagedLod->accept(v);
+//    osgUtil::Optimizer opt; 
+//    opt.optimize(pagedLod.get());
+
+//    osgUtil::SmoothingVisitor smooth;
+
+//    pagedLod->accept(smooth);
+   return pagedLod.get();
+}
+
+
+// osgDB::ReaderWriter::ReadResult ossimPlanetLandReaderWriter::local_readNode(const std::string& filename,
+//                                                                           const Options* options)const
+// {
+// }
+
+bool ossimPlanetLandReaderWriter::extractValues(const std::string& filename,
+                                              ossim_uint32 &level,
+                                              ossim_uint32 &row,
+                                              ossim_uint32 &col,
+                                              ossim_uint32 &id,
+                                              ossimPlanetLandReaderWriterGeomType &geomType)const
+{
+   ossimString tempString = filename;
+   tempString = tempString.substitute("_", "\n", true);
+
+   std::istringstream in(tempString);
+   ossim_uint32 numberOfValuesFound = 0;
+   geomType = ossimPlanetLandReaderWriterGeomType_NONE;
+   while(!in.fail())
+   {
+      ossimString tempLine;
+      
+      std::getline(in, tempLine.string());
+      tempLine = tempLine.upcase();
+	  if (tempLine.begin() == tempLine.end()) continue;
+
+      if(tempLine == "TEXTURE")
+      {
+         geomType = (ossimPlanetLandReaderWriterGeomType)(geomType | ossimPlanetLandReaderWriterGeomType_TEXTURE);
+      }
+      else if(tempLine == "GEOM")
+      {
+         geomType = (ossimPlanetLandReaderWriterGeomType)(geomType | ossimPlanetLandReaderWriterGeomType_GEOM);
+      }
+      else if((*tempLine.begin()) == 'L')
+      {
+         tempLine = tempLine.substitute("L", "");
+         level = tempLine.toUInt32();
+         ++numberOfValuesFound;
+      }
+      else if((*tempLine.begin()) == 'Y')
+      {
+         tempLine = tempLine.substitute("Y", "");
+         row = tempLine.toUInt32();
+         ++numberOfValuesFound;
+      }
+      else if((*tempLine.begin()) == 'X')
+      {
+         tempLine = tempLine.substitute("X", "");
+         col = tempLine.toUInt32();
+         ++numberOfValuesFound;
+      }
+      else if(((*tempLine.begin()) == 'I')&&
+              ((*(tempLine.begin()+1)) == 'D'))
+      {
+         tempLine = tempLine.substitute("ID", "");
+         id = tempLine.toUInt32();
+         ++numberOfValuesFound;
+      }
+   }
+   if(!geomType)
+   {
+      geomType = ossimPlanetLandReaderWriterGeomType_LOD;
+   }
+   return (numberOfValuesFound == 4);
+}
+
+std::string ossimPlanetLandReaderWriter::createDbString(ossim_uint32 level,
+                                                        ossim_uint64 row,
+                                                        ossim_uint64 col)const
+{
+   std::stringstream out;
+   
+   out << "L"<<level<<"_X"<<col<<"_Y"<<row<<"_ID"<<theId;
+
+   return out.str();
+}
+
+#if 0
+void ossimPlanetLandReaderWriter::setLandType(ossimPlanetLandType landType)
+{
+   theLandType = landType;
+   switch(theLandType)
+   {
+      case ossimPlanetLandType_NORMALIZED_ELLIPSOID:
+      {
+         theModel = new ossimPlanetNormalizedEllipsoidModel;
+         break;
+      }
+      case ossimPlanetLandType_ELLIPSOID:
+      {
+         theModel = new ossimPlanetEllipsoidModel;
+         break;
+      }
+#if 0
+      case ossimPlanetLandType_FLAT:
+      {
+         osg::ref_ptr<ossimPlanetFlatLandModel> theFlatLandModel = new ossimPlanetFlatLandModel;
+         theModel = theFlatLandModel.get();
+         theFlatLandModel->changeNormalModel(new ossimPlanetNormalizedEllipsoidLandModel);
+         
+         break;
+      }
+      case ossimPlanetLandType_ORTHOFLAT:
+      {
+         setElevationEnabledFlag(false);
+         osg::ref_ptr<ossimPlanetFlatLandModel> theFlatLandModel = new ossimPlanetFlatLandModel;
+         theModel = theFlatLandModel.get();
+         theFlatLandModel->changeNormalModel(new ossimPlanetNormalizedEllipsoidLandModel);
+         break;
+      }
+#endif
+      default:
+      {
+         break;
+      }
+   }
+}
+#endif
+
+void ossimPlanetLandReaderWriter::setModel(ossimPlanetGeoRefModel* geoModel)
+{
+   theModel = geoModel;
+}
+
+void ossimPlanetLandReaderWriter::setLandNodeCullCallback(ossimPlanetLandCullCallback* callback)
+{
+   theCullNodeCallback = callback; 
+}
+
+bool ossimPlanetLandReaderWriter::getElevationEnabledFlag()const
+{
+   return theElevationEnabledFlag;
+}
+
+void ossimPlanetLandReaderWriter::setElevationEnabledFlag(bool elevationFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theElevationEnabledFlag = elevationFlag;
+   
+}
+
+ossim_float64 ossimPlanetLandReaderWriter::getHeightExag()const
+{
+   return theHeightExag;
+}
+
+void ossimPlanetLandReaderWriter::setHeightExag(ossim_float64 exag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theHeightExag = exag;
+}
+
+
+ossim_uint32 ossimPlanetLandReaderWriter::getElevationPatchSize()const
+{
+   return theElevationPatchSize;
+}
+
+void ossimPlanetLandReaderWriter::setElevationPatchSize(ossim_uint32 patchSize)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theElevationPatchSize = patchSize;
+   if(!(theElevationPatchSize&1))
+   {
+      theElevationPatchSize += 1;
+   }
+   
+}
+
+
+ossim_uint32 ossimPlanetLandReaderWriter::getMaxLevelDetail()const
+{
+   return theMaxLevelDetail;
+}
+
+void ossimPlanetLandReaderWriter::setMaxLevelDetail(ossim_uint32 maxLevelDetail)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theMaxLevelDetail = maxLevelDetail;
+}
+
+ossimFilename ossimPlanetLandReaderWriter::getElevationCacheDir()const
+{
+   return theElevationCacheDir;
+}
+
+
+void ossimPlanetLandReaderWriter::setElevationCacheDir(const ossimFilename& cacheDir)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theElevationCacheDir = cacheDir;
+}
+
+void ossimPlanetLandReaderWriter::setGridUtility(ossimPlanetGridUtility* grid)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theGrid = grid; 
+}
+
+const ossimPlanetGridUtility* ossimPlanetLandReaderWriter::gridUtility()const
+{
+   return theGrid.get();
+}
+
+void ossimPlanetLandReaderWriter::setReferenceLayer(osg::ref_ptr<ossimPlanetTextureLayerGroup> reference)
+{
+   theReferenceLayer = reference;
+}
+
+void ossimPlanetLandReaderWriter::setOverlayLayers(osg::ref_ptr<ossimPlanetTextureLayerGroup> overlays)
+{
+   theOverlayLayers = overlays;
+}
+
+void ossimPlanetLandReaderWriter::setMipMappingFlag(bool flag)
+{
+   theMipMappingFlag = flag;
+}
+
+bool ossimPlanetLandReaderWriter::getMipMappingFlag()const
+{
+   return theMipMappingFlag;
+}
+
+void ossimPlanetLandReaderWriter::setMultiTextureEnableFlag(bool flag)
+{
+   theMultiTextureEnableFlag = flag;
+}
+
+bool ossimPlanetLandReaderWriter::getMultiTextureEnableFlag()const
+{
+   return theMultiTextureEnableFlag;
+}
+
+void ossimPlanetLandReaderWriter::setLandCache(osg::ref_ptr<ossimPlanetLandCache> landCache)
+{
+   theLandCache = landCache.get();
+}
+
+void ossimPlanetLandReaderWriter::setElevationDatabase(osg::ref_ptr<ossimPlanetElevationDatabaseGroup> databaseGroup)
+{
+   theElevationDatabase = databaseGroup.get();
+}
+
+osg::ref_ptr<ossimPlanetElevationDatabaseGroup> ossimPlanetLandReaderWriter::getElevationGroup()
+{
+   return theElevationDatabase.get();
+}
+
+const osg::ref_ptr<ossimPlanetElevationDatabaseGroup> ossimPlanetLandReaderWriter::getElevationGroup()const
+{
+   return theElevationDatabase.get();
+}
+
+
+void ossimPlanetLandReaderWriter::newTexture(std::vector<osg::ref_ptr<osg::Texture2D> >& textureList,
+                                             ossim_uint32 level,
+                                             ossim_uint32 row,
+                                             ossim_uint32 col,
+                                             ossimPlanetImage::ossimPlanetImageStateType& textureState)const
+{
+   osg::ref_ptr<ossimPlanetLandCacheNode> cacheNode;
+   if(theLandCache.valid())
+   {
+      cacheNode = theLandCache->getNode(theGrid->getId(level, row, col), true);
+   }
+   textureList.clear();
+   osg::ref_ptr<ossimPlanetTextureLayer> currentLayer = theReferenceLayer.get();
+   if(!currentLayer.valid()) return;
+   ossim_uint32 size = theOverlayLayers.valid()?theOverlayLayers->numberOfLayers():0;
+   if(!theMultiTextureEnableFlag) size = 0;
+   ossim_uint32 idx = 0;
+//    for(idx = 0; idx < size; ++idx)
+   do
+   {
+      osg::ref_ptr<ossimPlanetImage> planetTexture;
+      if(cacheNode.valid()&&cacheNode->getTexture(idx))
+      {
+//          std::cout << "IN CACHE!" << std::endl;
+         planetTexture = cacheNode->getTexture(idx);
+      }
+      else
+      {
+//          std::cout << "NOT IN CACHE!" << std::endl;
+         planetTexture = currentLayer->getTexture(level, row, col, *theGrid);         
+      }
+      if(!planetTexture.valid())
+      {
+         if(!theBlankTexture.valid())
+         {
+           ossim_uint32 w=256, h=256;
+           osg::ref_ptr<ossimPlanetImage> tempImage = new ossimPlanetImage;
+           osg::Image::AllocationMode allocMode = osg::Image::USE_NEW_DELETE;
+           ossim_uint32 sizeInBytes = w*h*4;
+           unsigned char *buf = new unsigned char[sizeInBytes];
+           memset(buf, 0, sizeInBytes);
+           tempImage->setImage(w, h, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, buf, allocMode);
+           theBlankTexture = new ossimPlanetTexture2D;
+           theBlankTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
+           theBlankTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
+           theBlankTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+           theBlankTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+           theBlankTexture->setDataVariance(osg::Object::STATIC);
+           theBlankTexture->setImage(planetTexture.get());
+           theBlankTexture->setUnRefImageDataAfterApply(false);
+         }
+         textureList.push_back(theBlankTexture.get());
+      }
+      else if(planetTexture.valid())
+//       if(planetTexture.valid())
+      {
+         //planetTexture->scaleImage(planetTexture->s(),planetTexture->t(),planetTexture->r(),GL_UNSIGNED_SHORT_5_6_5);
+         osg::ref_ptr<ossimPlanetTexture2D> tempGlTexture= new ossimPlanetTexture2D;
+         if(theMipMappingFlag)
+         {
+            tempGlTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_LINEAR);
+         }
+         else
+         {
+            tempGlTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+         }
+         tempGlTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+         tempGlTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+         tempGlTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+         tempGlTexture->setDataVariance(osg::Object::STATIC);
+
+
+         tempGlTexture->setImage(planetTexture.get());
+         tempGlTexture->setUnRefImageDataAfterApply(true);
+#if defined(OSSIMPLANET_USE_DXT1)
+         tempGlTexture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT1_COMPRESSION);
+#elif defined(OSSIMPLANET_USE_DXT3)
+         tempGlTexture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION);
+#elif defined(OSSIMPLANET_USE_DXT5)
+         tempGlTexture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT5_COMPRESSION);
+#endif
+         textureList.push_back(tempGlTexture.get());
+      }
+      if(idx < size)
+      {
+         currentLayer = theOverlayLayers->layer(idx);
+         ++idx;
+      }
+      else
+      {
+         currentLayer = 0;
+      }
+   }while(currentLayer.valid());
+}
+   
+osg::ref_ptr<osg::MatrixTransform> ossimPlanetLandReaderWriter::newGeometry(ossim_uint32 level,
+                                                                            ossim_uint32 row,
+                                                                            ossim_uint32 col,
+                                                                            std::vector<osg::ref_ptr<osg::Texture2D> >& textures,
+                                                                            osg::ref_ptr<ossimPlanetImage> elevationGrid,
+                                                                            ossimPlanetBoundingBox& box,
+                                                                            bool& useClusterCullingCallback,
+                                                                            osg::Vec3d& clusterControlPoint,
+                                                                            osg::Vec3d& clusterCenterNormal,
+                                                                            double& minDotProduct,
+                                                                            double& maxClusterCullingRadius)const
+{
+//    double minLat;
+//    double minLon;
+//    double maxLat;
+//    double maxLon;
+//    theGrid->getLatLonBounds(level,
+//                             row, // row 
+//                             col, // col
+//                             minLat,
+//                             minLon,
+//                             maxLat,
+//                             maxLon);
+   osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array;
+   osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array;
+   osg::ref_ptr<osg::Vec2Array> tcoords = new osg::Vec2Array;
+//    double minLat, minLon;
+//    double maxLat, maxLon;
+//   unsigned int tempIdx = 0;
+//    double x, y, z;
+   
+   osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
+   
+   osg::ref_ptr<osg::MatrixTransform> matrixTransform = new osg::MatrixTransform;
+   osg::Matrixd localToWorld;
+   osg::Matrixd worldToLocal;
+
+   
+
+//    matrixTransform->setMatrix(localToWorld);
+//    worldToLocal = matrixTransform->getInverseMatrix();
+
+   createPoints(level,
+                row,
+                col,
+                elevationGrid,
+                verts.get(),
+                norms.get(),
+                tcoords.get(),
+                localToWorld,
+                box,
+                useClusterCullingCallback,
+                clusterControlPoint,
+                clusterCenterNormal,
+                minDotProduct,
+                maxClusterCullingRadius);
+   
+   matrixTransform->setMatrix(localToWorld);
+   worldToLocal = matrixTransform->getInverseMatrix();
+   
+   osg::ref_ptr<osg::UIntArray> vindices = new osg::UIntArray;
+   ossim_uint32 numColumns = (theElevationPatchSize);
+   ossim_uint32 numRows = numColumns;
+
+   ossim_uint32 c = 0, ei=0;
+#if 1
+   osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES));
+   osg::Geometry::PrimitiveSetList primSetList;
+   ossim_uint32 i = 0;
+   ossim_uint32 j = 0;
+   for(i = 1; i < numRows;i+=2)
+   {
+      for(j = 1; j < numColumns;j+=2)
+      {
+         ossim_uint32 i00 = (i)*numColumns + j;
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numColumns+1));
+         drawElements.push_back(i00 - (numColumns));
+         
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numColumns));
+         drawElements.push_back(i00 - (numColumns-1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numColumns-1));
+         drawElements.push_back(i00 + 1);
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + 1);
+         drawElements.push_back(i00 + (numColumns+1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numColumns+1));
+         drawElements.push_back(i00 + (numColumns));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numColumns));
+         drawElements.push_back(i00 + (numColumns-1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numColumns-1));
+         drawElements.push_back(i00 - 1);
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - 1);
+         drawElements.push_back(i00 - (numColumns+1));
+      }
+   }
+   primSetList.push_back(&drawElements);
+	geom->setPrimitiveSetList(primSetList);
+   //smoothGeometry();
+#endif
+#if 0
+
+   osg::Geometry::PrimitiveSetList primSetList;// ( numRows>>1*numCols>>1 );
+   ossim_uint32 i = 0;
+   ossim_uint32 j = 0;
+   for(i = 1; i < numRows;i+=2)
+   {
+      for(j = 1; j < numColumns;j+=2)
+      {
+         ossim_uint32 i00 = (i)*numColumns + j;
+         osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_FAN));
+#if 0
+         drawElements.push_back(i00);
+
+         drawElements.push_back(i00 - (numColumns+1));
+         drawElements.push_back(i00 - (numColumns-1));
+
+         drawElements.push_back(i00 + (numColumns+1));
+         drawElements.push_back(i00 + (numColumns-1));
+
+         drawElements.push_back(i00 - (numColumns+1));
+#endif
+#if 1
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numColumns+1));
+         drawElements.push_back(i00 - (numColumns));
+         drawElements.push_back(i00 - (numColumns-1));
+         
+         drawElements.push_back(i00 + 1);
+         
+         drawElements.push_back(i00 + (numColumns+1));
+         drawElements.push_back(i00 + (numColumns));
+         drawElements.push_back(i00 + (numColumns-1));
+         
+         drawElements.push_back(i00 - 1);
+         
+         drawElements.push_back(i00 - (numColumns+1));
+#endif    
+         primSetList.push_back(&drawElements);
+      }
+   }
+
+	geom->setPrimitiveSetList(primSetList);
+#endif
+#if 0
+	osg::Geometry::PrimitiveSetList primSetList;// ( numColumns - 1 );
+	//unsigned int length ( 2 * numRows );
+	ossim_uint32 elementIdx = 0;
+   unsigned int i,j;
+	for (i = 0; i < numRows-1; ++i )
+	{
+		elementIdx = 0;
+		osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP));
+		// Loop through all the columns.
+		for (j = 0; j < numColumns; ++j )
+		{
+         unsigned short i10 = (i+1)*(numColumns)+j;
+         unsigned short i00 = (i)*(numColumns)+j;
+			drawElements.push_back(i10);
+         drawElements.push_back(i00);
+		}
+		
+		// Define the primitive.
+		primSetList.push_back(&drawElements);
+	}
+	geom->setPrimitiveSetList(primSetList);
+#endif
+   geom->setVertexArray(verts.get());
+   geom->setNormalArray(norms.get());
+   geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+   osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
+   color->push_back(osg::Vec4(1.0,
+                              1.0,
+                              1.0,
+                              1.0));
+   geom->setColorBinding(osg::Geometry::BIND_OVERALL);
+   geom->setColorArray(color.get());
+   
+   osgUtil::SmoothingVisitor sv;
+   sv.smooth(*geom);  // this will replace the normal vector with a new one
+   
+   // now we have to reassign the normals back to the orignal pointer.
+   norms = dynamic_cast<osg::Vec3Array*>(geom->getNormalArray());
+   
+   if(theLandType != ossimPlanetLandType_ORTHOFLAT)
+   {
+      unsigned int numPointsInBody = numColumns*numRows;
+      unsigned int numVerticesInSkirt = numColumns*2 + numRows*2;
+      
+      // top strip
+      osg::DrawElementsUShort& drawElementsQuad = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,
+                                                                                2*numVerticesInSkirt));
+//                                                                          2*numVerticesInSkirt+2));
+      geom->addPrimitiveSet(&drawElementsQuad);
+      ei=0;
+//      int firstSkirtVertexIndex = numPointsInBody;
+      osgUtil::Simplifier::IndexList pointsToProtectDuringSimplification;
+      
+//    bool topPoleFlag    = ((90.0 - std::abs(maxLat) ) <= DBL_EPSILON)&&(level > 4);   
+//    bool bottomPoleFlag = ((90.0 - std::abs(minLat) ) <= DBL_EPSILON)&&(level > 4);   
+      // do top skirt
+      //
+      //      for(c=0;c<numColumns-1;++c)
+      for(c=0;c<numColumns-1;++c)
+      {
+         unsigned short i0 = c;
+         unsigned short i1 = numPointsInBody + c;
+         drawElementsQuad[ei++] = i0;
+         drawElementsQuad[ei++] = i1;
+//       if(!topPoleFlag)
+         {
+            pointsToProtectDuringSimplification.push_back(i0);
+            pointsToProtectDuringSimplification.push_back(i1);
+         }
+      }
+      // do right skirt
+      ossim_uint32 startInteriorIdx = numColumns-1;
+      ossim_uint32 startSkirtIdx    = numPointsInBody + numColumns;
+      for(c=0;c<numRows;++c)
+      {
+         unsigned short i0 = startInteriorIdx + numColumns*c;
+         unsigned short i1 = startSkirtIdx + c;
+         {
+            drawElementsQuad[ei++] = i0;
+            drawElementsQuad[ei++] = i1;
+         }
+         pointsToProtectDuringSimplification.push_back(i0);
+         pointsToProtectDuringSimplification.push_back(i1);      
+      }
+      
+      startInteriorIdx = (numRows-1)*numColumns + (numColumns-1);
+      startSkirtIdx =  numPointsInBody + numColumns + numRows;
+      // do bottom skirt
+      //
+      for(c=0;c<numColumns;++c)
+      {
+         unsigned short i0 = startInteriorIdx - c;
+         unsigned short i1 = startSkirtIdx + c;
+         drawElementsQuad[ei++] = i0;
+         drawElementsQuad[ei++] = i1;
+//       if(!bottomPoleFlag)
+         {
+            pointsToProtectDuringSimplification.push_back(i0);
+            pointsToProtectDuringSimplification.push_back(i1);
+         }
+      }
+      
+      // do left skirt
+      startInteriorIdx = numRows*(numColumns-1);
+      startSkirtIdx    = numPointsInBody + 2*numColumns + numRows;
+   
+      for(c=0;c<numRows;++c)
+      {
+         unsigned short i0 = startInteriorIdx - numColumns*c;
+         unsigned short i1 = startSkirtIdx + c;
+         drawElementsQuad[ei++] = i0;
+         drawElementsQuad[ei++] = i1;
+         pointsToProtectDuringSimplification.push_back(i0);
+         pointsToProtectDuringSimplification.push_back(i1);
+      }
+   }
+   
+//    unsigned int numVerticesInBody = numColumns*numRows;
+//     unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
+//     unsigned int numVertices = numVerticesInBody+numVerticesInSkirt;
+//    unsigned int numVertices = numVerticesInBody;
+#if 0
+    unsigned int numVerticesInBody = numColumns*numRows;
+//     unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0;
+//     unsigned int numVertices = numVerticesInBody+numVerticesInSkirt;
+    unsigned int numVertices = numVerticesInBody;
+
+
+   if (norms.valid() && norms->size()!=numVertices) norms->resize(numVertices);
+#endif
+   osg::ref_ptr<osg::StateSet> dstate = geom->getOrCreateStateSet();
+   osg::ref_ptr<osg::CullFace> cullFace = new osg::CullFace;
+
+
+   
+   dstate->setAttributeAndModes(cullFace.get(),
+                                osg::StateAttribute::ON);
+
+   if(textures.size())
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < textures.size(); ++idx)
+      {
+         if(textures[idx].valid())
+         {
+            dstate->setTextureAttributeAndModes(idx, textures[idx].get(),
+                                                osg::StateAttribute::ON);
+         }
+      }
+   }
+//    else if(textures.size())
+//    {
+//       dstate->setTextureAttributeAndModes(idx, textures[0].get(),
+//                                           osg::StateAttribute::ON);
+      
+//    }
+//   geom->setVertexArray(verts.get());
+//   geom->setNormalArray(norms.get());
+//   geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+   
+   
+   geom->setTexCoordArray( 0, tcoords.get());   
+   geom->setSupportsDisplayList(false);
+   
+#if 0 // simplifier
+//    unsigned int targetMaxNumVertices = numVertices-1;
+//    float sample_ratio = (numVertices <= targetMaxNumVertices) ? 1.0f : (float)targetMaxNumVertices/(float)numVertices;
+//    if(topPoleFlag||bottomPoleFlag)
+   {
+      float sample_ratio = .5;
+      osgUtil::Simplifier simplifier(sample_ratio,
+                                     (geom->getBound().radius());///theModel->getNormalizationScale()));
+      
+      simplifier.setDoTriStrip(false);
+      simplifier.setSmoothing(false);
+      
+//    simplifier.simplify(*geom, pointsToProtectDuringSimplification);  // this will replace the normal vector with a new one
+      simplifier.simplify(*geom,pointsToProtectDuringSimplification);  // this will replace the normal vector with a new one
+   }
+#endif
+//   osgUtil::TriStripVisitor tsv;
+//   tsv.setMinStripSize(3);
+//   tsv.stripify(*geom);
+
+   osg::ref_ptr<osg::Geode> geode = new osg::Geode;
+//    osgUtil::TriStripVisitor v;
+
+//    v.apply(*geode.get());
+//    osgUtil::SmoothingVisitor::smooth(*(geom.get()));
+   matrixTransform->addChild(geode.get());
+   geode->addDrawable(geom.get());
+   geom->setUseVertexBufferObjects(true);
+   //geom->setFastPathHint(true);
+  // geom->setUseDisplayList(false);
+   matrixTransform->dirtyBound();
+   geom->dirtyBound();
+   matrixTransform->getBound();
+   geom->getBound();
+   
+   return matrixTransform;
+}
+void ossimPlanetLandReaderWriter::createPoints(ossim_uint32 level,
+                                               ossim_uint32 row,
+                                               ossim_uint32 col,
+                                               osg::ref_ptr<ossimPlanetImage> elevationGrid,
+                                               osg::Vec3Array *verts,
+                                               osg::Vec3Array *norms,
+                                               osg::Vec2Array *tcoords,
+                                               osg::Matrixd& localToWorld,
+                                               ossimPlanetBoundingBox& box,
+                                               bool& useClusterCullingCallback,
+                                               osg::Vec3d& clusterControlPoint,
+                                               osg::Vec3d& clusterCenterNormal,
+                                               double& minDotProduct,
+                                               double& maxClusterCullingRadius)const
+{
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   ossim_uint32 rows = theElevationPatchSize;
+   ossim_uint32 cols = rows;
+
+   theGrid->createGridPoints(points,
+                             level,
+                             row,
+                             col,
+                             rows,
+                             cols);
+   
+   osg::Vec3d centerPoint;
+   osg::Vec3d centerNormal;
+   ossim_float32* grid = 0;
+   ossim_uint32 idx = 0;
+   osg::Vec3d ul;
+   osg::Vec3d lr;
+   osg::Vec3d ur;
+   osg::Vec3d ll;
+   osg::Vec3d upAxis;
+   osg::Vec3d rightAxis;
+   osg::Vec3d norm1, norm2;
+   osg::Matrixd inverseLocalToWorld;
+   ossim_uint32 numberOfPoints = points.size();
+   if(elevationGrid.valid())
+   {
+      grid = (ossim_float32*)elevationGrid->data();
+   }
+   
+//    if(grid)
+//    {
+//       for(idx = 0; idx < numberOfPoints; ++idx)
+//       {
+//          (*grid) *= theHeightExag;
+//          ++grid;
+//       }
+//    }
+   if(elevationGrid.valid())
+   {
+      grid = (ossim_float32*)elevationGrid->data();
+   }
+   
+   ossimPlanetGridUtility::GridPoint centerGridPoint;
+
+   theGrid->getCenterGridPoint(centerGridPoint, level, row, col);
+   
+   theGrid->getLatLon(centerPoint, centerGridPoint);
+   theGrid->getLatLon(ul, points[0]);
+   theGrid->getLatLon(ur, points[cols-1]);
+   theGrid->getLatLon(lr, points[points.size()-1]);
+   theGrid->getLatLon(ll, points[(rows-1)*cols]);
+#if 1
+   osg::Matrixd lsrMatrix;
+   theModel->lsrMatrix(centerPoint,
+                       lsrMatrix);
+   localToWorld  = lsrMatrix;
+   centerNormal = osg::Vec3d(lsrMatrix(2, 0),
+                             lsrMatrix(2, 1),
+                             lsrMatrix(2, 2));
+   rightAxis = osg::Vec3d(lsrMatrix(0, 0),
+                          lsrMatrix(0, 1),
+                          lsrMatrix(0, 2));
+   upAxis    = osg::Vec3d(lsrMatrix(1, 0),
+                          lsrMatrix(1, 1),
+                          lsrMatrix(1, 2));
+#endif
+//    theModel->lsrMatrix(centerPoint, localToWorld);
+   theModel->forward(osg::Vec3d(centerPoint),
+                     centerPoint);
+   theModel->forward(osg::Vec3d(ul),
+                     ul);
+   theModel->forward(osg::Vec3d(ur),
+                     ur);
+   theModel->forward(osg::Vec3d(lr),
+                     lr);
+   theModel->forward(osg::Vec3d(ll),
+                     ll);
+   
+//    theModel->computeLocalToWorldTransform(centerPoint, localToWorld);
+   inverseLocalToWorld.invert(localToWorld);
+
+
+   osg::Vec2d normalDistance(0.0,0.0);
+   osg::Vec2d rightDistance(0.0,0.0);
+   osg::Vec2d upDistance(0.0,0.0);
+   
+   double h = 0.0;
+   osg::Vec3d groundPlaneNormal  = centerNormal;
+   osg::Vec3d groundPlaneCenter  = centerPoint;
+   osg::Vec3d p1;
+   double minDelta = 0.0, maxDelta = 0.0;
+   useClusterCullingCallback = level > 0;
+   minDotProduct = 1.0;
+   double maxClusterCullingHeight = 0.0;      
+   maxClusterCullingRadius = 0.0;
+   clusterCenterNormal = centerNormal;
+
+   
+   osg::Vec3d latLonPoint;
+   osg::Vec3d deltaP;
+   double upDelta = 0.0;
+   double rightDelta = 0.0;
+   double normDelta  = 0.0;
+   
+   for(idx = 0; idx < numberOfPoints; ++idx)
+   {
+      tcoords->push_back(osg::Vec2d(points[idx].theLocalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                    points[idx].theLocalGridPoint[ossimPlanetGridUtility::GRIDY]));
+      
+      if(grid)
+      {
+         h = (*grid);//*theHeightExag;
+         
+         ++grid;
+      }
+      else
+      {
+         h = 0.0;
+      }
+
+      theGrid->getLatLon(latLonPoint, points[idx]);
+      if(h > maxDelta) maxDelta = h;
+      if(h < minDelta) minDelta = h;
+      latLonPoint[ossimPlanetGridUtility::HGT] = h;
+      h /= theModel->getNormalizationScale();
+      theModel->forward(latLonPoint, p1);
+
+      deltaP     = (p1-groundPlaneCenter);
+      upDelta    = deltaP*upAxis;
+      rightDelta = deltaP*rightAxis;
+      normDelta  = deltaP*groundPlaneNormal;
+      
+      if(normDelta < normalDistance[1]) normalDistance[1] = normDelta;
+      if(normDelta > normalDistance[0]) normalDistance[0] = normDelta;
+      if(upDelta < upDistance[1]) upDistance[1] = upDelta; 
+      if(upDelta > upDistance[0]) upDistance[0] = upDelta;
+      if(rightDelta < rightDistance[1]) rightDistance[1] = rightDelta; 
+      if(rightDelta > rightDistance[0]) rightDistance[0] = rightDelta;
+      theModel->normal(p1,
+                       norm1);
+      
+      double product = deltaP*groundPlaneNormal;
+      if(product > maxDelta) maxDelta = product;
+      if(product < minDelta) minDelta = product;
+      
+      if (useClusterCullingCallback)
+      {
+         osg::Vec3 dv = p1 - centerPoint;
+         double d = sqrt(dv.x()*dv.x() + dv.y()*dv.y() + dv.z()*dv.z());
+         double globeRadius = 1.0;
+         double theta = acos( globeRadius/ (globeRadius + fabs(h) ));
+         double phi = 2.0 * asin (d*0.5/globeRadius); // d/globeRadius;
+         double beta = theta+phi;
+         double cutoff = osg::PI_2;
+         //my_notify(osg::INFO)<<"theta="<<theta<<"\tphi="<<phi<<" beta "<<beta<<std::endl;
+         if (phi<cutoff && beta<cutoff)
+         {
+            double localDotProduct = -sin(theta + phi);
+            double localM = globeRadius*( 1.0/ cos(theta+phi) - 1.0);
+            double localRadius = static_cast<float>(globeRadius * tan(beta)); // beta*globeRadius;
+            minDotProduct = osg::minimum(minDotProduct, localDotProduct);
+            maxClusterCullingHeight = osg::maximum(maxClusterCullingHeight,localM);      
+            maxClusterCullingRadius = osg::maximum(maxClusterCullingRadius,localRadius);
+         }
+         else
+         {
+            //my_notify(osg::INFO)<<"Turning off cluster culling for wrap around tile."<<std::endl;
+            useClusterCullingCallback = false;
+         }
+      }
+      
+      p1 = p1*inverseLocalToWorld;
+      norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+      norm1.normalize();
+      verts->push_back(p1);
+      norms->push_back(norm1);
+   }
+   clusterControlPoint = centerPoint + centerNormal*maxClusterCullingHeight;
+
+   clusterControlPoint = clusterControlPoint*inverseLocalToWorld;
+   clusterCenterNormal = osg::Matrixd::transform3x3(localToWorld,clusterCenterNormal);
+   box.extrude(groundPlaneCenter,
+               upAxis,
+               rightAxis,
+               groundPlaneNormal,
+               upDistance,
+               rightDistance,
+               normalDistance);
+   box.transform(inverseLocalToWorld);
+
+//#if 0
+// ------------------- Now let's do the skirt -------------------------
+
+   ossim_uint32 colIdx = 0;
+   ossim_uint32 rowIdx = 0;
+   if(theLandType != ossimPlanetLandType_ORTHOFLAT)
+   {
+      // top skirt points
+      double scale = .02;
+      double defaultSkirtLength = box.radius()*scale;
+      grid = 0;
+      if(elevationGrid.valid())
+      {
+         grid = (ossim_float32*)elevationGrid->data();
+      }
+      double minHeight = 99999999999.0;
+      double maxDeltaHeight = -999999999999.0, minDeltaHeight = 9999999999999.0;
+      double deltaHeight=defaultSkirtLength;
+      if(grid)
+      {
+         for(colIdx = 0; colIdx < cols; ++colIdx)
+         {
+            if(maxDeltaHeight < *grid) maxDeltaHeight = *grid;
+            if(minDeltaHeight > *grid) minDeltaHeight = *grid;
+//             double value = (*grid -defaultSkirtLength)*theHeightExag;
+//             if(value < minHeight) minHeight = value;
+            ++grid;
+         }
+         grid = (ossim_float32*)elevationGrid->data();
+         deltaHeight = ossim::max(defaultSkirtLength, ((maxDeltaHeight-minDeltaHeight)));//*theHeightExag));
+      }
+//       std::cout << "deltaHeight = " << deltaHeight <<  "\n";
+//       if(elevationGrid.valid())
+//       {
+//          grid = (ossim_float32*)elevationGrid->data();
+//       }
+      for(colIdx = 0; colIdx < cols; ++colIdx)
+      {
+         tcoords->push_back(osg::Vec2d(points[colIdx].theLocalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                       points[colIdx].theLocalGridPoint[ossimPlanetGridUtility::GRIDY]));
+      
+         theGrid->getLatLon(latLonPoint, points[colIdx]);
+         if(grid)
+         {
+//            latLonPoint[2] = minHeight;
+            latLonPoint[2] = *grid - deltaHeight;
+            theModel->forward(latLonPoint,
+                              p1);
+            ++grid;
+         }
+         else
+         {
+            latLonPoint[2] = -defaultSkirtLength;
+            theModel->forward(latLonPoint,
+                              p1);
+         }
+         theModel->normal(p1,
+                          norm1);
+         p1 = p1*inverseLocalToWorld;
+         
+         norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+         norm1.normalize();
+         verts->push_back(p1);
+         norms->push_back(norm1);
+      }
+      // right skirt
+      maxDeltaHeight = -999999999999.0, minDeltaHeight = 9999999999999.0;
+      if(elevationGrid.valid())
+      {
+         grid = (((ossim_float32*)elevationGrid->data())+(cols-1));
+      }
+      minHeight = 99999999999.0;
+      ossimPlanetGridUtility::GridPoint* pointsPtr = &points.front() + cols;
+      if(grid)
+      {
+         for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+         {
+//             double value = (*grid -defaultSkirtLength)*theHeightExag;
+            if(maxDeltaHeight < *grid) maxDeltaHeight = *grid;
+            if(minDeltaHeight > *grid) minDeltaHeight = *grid;
+//             if(value < minHeight) minHeight = value;
+            grid+=(cols);
+         }
+         grid = (((ossim_float32*)elevationGrid->data())+(cols-1));
+         deltaHeight = ossim::max(defaultSkirtLength, ((maxDeltaHeight-minDeltaHeight)));//*theHeightExag));
+      }
+
+      pointsPtr = &points.front() + cols-1;
+      for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+      {
+         tcoords->push_back(osg::Vec2d(pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                       pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDY]));
+         theGrid->getLatLon(latLonPoint, *pointsPtr);
+         if(grid)
+         {
+//             latLonPoint[2] = minHeight;
+            latLonPoint[2] = *grid - deltaHeight;
+//            latLonPoint[2] = (*grid -defaultSkirtLength)*theHeightExag;
+            theModel->forward(latLonPoint,
+                              p1);
+            grid+=(cols);
+         }
+         else
+         {
+            theModel->forward(osg::Vec3d(latLonPoint[ossimPlanetGridUtility::LAT],
+                                         latLonPoint[ossimPlanetGridUtility::LON], -defaultSkirtLength),
+                              p1);
+         }
+         
+         theModel->normal(p1,
+                          norm1);
+         p1 = p1*inverseLocalToWorld;
+         
+         norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+         norm1.normalize();
+         verts->push_back(p1);
+         norms->push_back(norm1);
+         pointsPtr += (cols);
+      }
+      
+      pointsPtr = &points.front() + (rows)*(cols) - 1;
+
+      // bottom skirt points
+      maxDeltaHeight = -999999999999.0, minDeltaHeight = 9999999999999.0;
+      if(elevationGrid.valid())
+      {
+         grid = (((ossim_float32*)elevationGrid->data())+(((rows)*(cols))-1));
+      }
+      minHeight = 99999999999.0;
+      if(grid)
+      {
+         for(colIdx = 0; colIdx < cols; ++colIdx)
+         {
+//             double value = (*grid -defaultSkirtLength)*theHeightExag;
+            if(maxDeltaHeight < *grid) maxDeltaHeight = *grid;
+            if(minDeltaHeight > *grid) minDeltaHeight = *grid;
+//             if(value < minHeight) minHeight = value;
+            --grid;
+         }
+         deltaHeight = ossim::max(defaultSkirtLength, ((maxDeltaHeight-minDeltaHeight)));//*theHeightExag));
+         grid = (((ossim_float32*)elevationGrid->data())+(((rows)*(cols))-1));
+      }
+      for(colIdx = 0; colIdx < cols; ++colIdx)
+      {
+         tcoords->push_back(osg::Vec2d(pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                       pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDY]));
+         theGrid->getLatLon(latLonPoint, *pointsPtr);
+         if(grid)
+         {
+//             latLonPoint[2] = minHeight;
+            latLonPoint[2] = *grid - deltaHeight;
+            theModel->forward(latLonPoint,
+                              p1);
+            --grid;
+         }
+         else
+         {
+            theModel->forward(osg::Vec3d(latLonPoint[ossimPlanetGridUtility::LAT],
+                                         latLonPoint[ossimPlanetGridUtility::LON],
+                                         -defaultSkirtLength),
+                              p1);
+         }
+         
+         theModel->normal(p1,
+                          norm1);
+         p1 = p1*inverseLocalToWorld;
+         
+         norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+         norm1.normalize();
+         verts->push_back(p1);
+         norms->push_back(norm1);
+         --pointsPtr;
+      }
+      
+
+      
+      // left skirt
+      maxDeltaHeight = -999999999999.0, minDeltaHeight = 9999999999999.0;
+      grid = 0;
+//       pointsPtr = (&points.front() + ((rows)*(cols+1)));
+      pointsPtr = (&points.front() + ((rows-1)*(cols)));
+      if(elevationGrid.valid())
+      {
+         grid = (((ossim_float32*)elevationGrid->data())+((rows-1)*(cols)));
+      }
+      minHeight = 99999999999.0;
+      if(grid)
+      {
+         for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+         {
+            if(maxDeltaHeight < *grid) maxDeltaHeight = *grid;
+            if(minDeltaHeight > *grid) minDeltaHeight = *grid;
+//             double value = (*grid -defaultSkirtLength)*theHeightExag;
+//             if(value < minHeight) minHeight = value;
+            grid-=(cols);
+         }
+         deltaHeight = ossim::max(defaultSkirtLength, ((maxDeltaHeight-minDeltaHeight)));//*theHeightExag));
+         grid = (((ossim_float32*)elevationGrid->data())+((rows-1)*(cols)));
+      }
+      for(rowIdx = 0; rowIdx < rows; ++rowIdx)
+      {
+         tcoords->push_back(osg::Vec2d(pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                       pointsPtr->theLocalGridPoint[ossimPlanetGridUtility::GRIDY]));
+         theGrid->getLatLon(latLonPoint, *pointsPtr);
+         if(grid)
+         {
+            latLonPoint[2] = *grid - deltaHeight;
+            theModel->forward(latLonPoint,
+                              p1);
+//             grid-=(cols+1);
+         }
+         else
+         {
+            theModel->forward(osg::Vec3d(latLonPoint[0], latLonPoint[1], -defaultSkirtLength),
+                              p1);
+         }
+         
+         theModel->normal(p1,
+                          norm1);
+         p1 = p1*inverseLocalToWorld;
+         
+         norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+         norm1.normalize();
+         verts->push_back(p1);
+         norms->push_back(norm1);
+         pointsPtr-=(cols);
+      }
+   }
+//#endif
+}
+
+void ossimPlanetLandReaderWriter::initSupportAttributes(ossim_uint32 level,
+                                                      ossim_uint32 row,
+                                                      ossim_uint32 col,
+                                                      osg::Vec3d& centerPoint,
+                                                      osg::Vec3d& ulPoint,
+                                                      osg::Vec3d& urPoint,
+                                                      osg::Vec3d& lrPoint,
+                                                      osg::Vec3d& llPoint,
+                                                      osg::Vec3d& centerNormal,
+                                                      osg::Vec3d& ulNormal,
+                                                      osg::Vec3d& urNormal,
+                                                      osg::Vec3d& lrNormal,
+                                                      osg::Vec3d& llNormal,
+                                                      ossimPlanetBoundingBox& box,
+                                                      std::vector<ossimPlanetBoundingBox>& childrenBounds,
+                                                      const osg::MatrixTransform& transform)const
+{
+   ossimPlanetGridUtility::GridPoint point;
+   osg::Vec3d ul, ur, lr, ll, latLon;
+   theGrid->getLatLonCorners(ul, ur, lr, ll, level, row, col);
+   
+//    double minLat, minLon, maxLat, maxLon;
+//    const osg::Matrixd& worldToLocal = transform.getInverseMatrix();
+//    theGrid->getLatLonBounds(level,
+//                             row,
+//                             col,
+//                             minLat,
+//                             minLon,
+//                             maxLat,
+//                             maxLon);
+   theModel->forward(ul,
+                     ulPoint);
+
+//    lod->theUlPoint = lod->theUlPoint*worldToLocal;
+   
+   theModel->forward(ur,
+                     urPoint);
+
+//    lod->theUrPoint = lod->theUrPoint*worldToLocal;
+
+   theModel->forward(lr,
+                     lrPoint);
+//    lod->theLrPoint = lod->theLrPoint*worldToLocal;
+
+   theModel->forward(ll,
+                     llPoint);
+//    lod->theLlPoint = lod->theLlPoint*worldToLocal;
+
+   theGrid->getCenterGridPoint(point,
+                               level,
+                               row,
+                               col);
+   theGrid->getLatLon(latLon,
+                      point);
+   theModel->forward(latLon,
+                     centerPoint);
+//    lod->theCenterPoint = lod->theCenterPoint*worldToLocal;
+
+   theModel->normal(ulPoint,
+                    ulNormal);
+//    lod->theUlNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theUlNormal);
+
+   theModel->normal(urPoint,
+                    urNormal);
+//    lod->theUrNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theUrNormal);
+   theModel->normal(lrPoint,
+                    lrNormal);
+//    lod->theLrNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theLrNormal);
+   theModel->normal(llPoint,
+                    llNormal);
+//    lod->theLlNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theLlNormal);
+   theModel->normal(centerPoint,
+                    centerNormal);
+//    lod->theCenterNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theCenterNormal);
+
+   osg::Vec3d center = (ulPoint +
+                        urPoint +
+                        lrPoint +
+                        llPoint)*.25;
+   osg::Vec3d delta  = (center-centerPoint);
+   double normalizedMax = (6000.0*theHeightExag);///theModel->getNormalizationScale();
+   double distance  = delta.length() + normalizedMax;
+   double distance2 = -distance;
+
+   switch(theLandType)
+   {
+      case ossimPlanetLandType_ORTHOFLAT:
+      case ossimPlanetLandType_FLAT:
+      {
+         distance = 0;
+         distance2 = 0;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   box.extrude(ulPoint,
+               urPoint,
+               lrPoint,
+               llPoint,
+               centerNormal,
+               osg::Vec2d(distance, distance2));
+   childrenBounds.resize(4);
+   ossim_uint32 nextRow = row<<1;
+   ossim_uint32 nextCol = col<<1;
+   createBounds(level+1,
+                nextRow,
+                nextCol,
+                childrenBounds[0],
+                transform);
+   createBounds(level+1,
+                nextRow,
+                nextCol+1,
+                childrenBounds[1],
+                transform);
+   createBounds(level+1,
+                nextRow+1,
+                nextCol+1,
+                childrenBounds[2],
+                transform);
+   createBounds(level+1,
+                nextRow+1,
+                nextCol,
+                childrenBounds[3],
+                transform);
+}
+
+void ossimPlanetLandReaderWriter::createBounds(ossim_uint32 level,
+                                             ossim_uint32 row,
+                                             ossim_uint32 col,
+                                             ossimPlanetBoundingBox& bounds,
+                                             const osg::MatrixTransform& /* transform */ )const
+{
+   osg::Vec3d ulPoint, urPoint, lrPoint, llPoint, centerPoint;
+   osg::Vec3d centerNormal;
+//   double minLat, minLon, maxLat, maxLon;
+   osg::Vec3d ul, ur, lr, ll, latLon;
+   ossimPlanetGridUtility::GridPoint point;
+   theGrid->getLatLonCorners(ul, ur, lr, ll, level, row, col);
+//    const osg::Matrixd& worldToLocal = transform.getInverseMatrix();
+//    theGrid->getLatLonBounds(level,
+//                               row,
+//                               col,
+//                               minLat,
+//                               minLon,
+//                               maxLat,
+//                               maxLon);
+   theModel->forward(ul,
+                     ulPoint);
+
+//    lod->theUlPoint = lod->theUlPoint*worldToLocal;
+   
+   theModel->forward(ur,
+                     urPoint);
+
+//    lod->theUrPoint = lod->theUrPoint*worldToLocal;
+
+   theModel->forward(lr,
+                     lrPoint);
+//    lod->theLrPoint = lod->theLrPoint*worldToLocal;
+
+   theModel->forward(ll,
+                     llPoint);
+//    lod->theLlPoint = lod->theLlPoint*worldToLocal;
+
+   theGrid->getCenterGridPoint(point,
+                               level,
+                               row,
+                               col);
+   theGrid->getLatLon(latLon,
+                      point);
+   
+   theModel->forward(latLon,
+                     centerPoint);
+//    lod->theCenterPoint = lod->theCenterPoint*worldToLocal;
+
+   theModel->normal(centerPoint,
+                    centerNormal);
+//    lod->theCenterNormal = osg::Matrixd::transform3x3(worldToLocal, lod->theCenterNormal);
+
+   osg::Vec3d center = (ulPoint +
+                        urPoint +
+                        lrPoint +
+                        llPoint)*.25;
+   osg::Vec3d delta  = (center-centerPoint);
+   double normalizedMax = (6000.0*theHeightExag);///theModel->getNormalizationScale();
+   double distance = delta.length() + normalizedMax;
+   double distance2 = distance;
+
+   switch(theLandType)
+   {
+      case ossimPlanetLandType_ORTHOFLAT:
+      case ossimPlanetLandType_FLAT:
+      {
+         distance = 0;
+         distance2 = 0;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   bounds.extrude(ulPoint,
+                  urPoint,
+                  lrPoint,
+                  llPoint,
+                  centerNormal,
+                  osg::Vec2d(distance, distance2));
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetLandReaderWriter::newElevation(ossim_uint32 level,
+                                                                         ossim_uint32 row,
+                                                                         ossim_uint32 col)const
+{
+   osg::ref_ptr<ossimPlanetImage> grid;
+   osg::ref_ptr<ossimPlanetLandCacheNode> cacheNode;
+
+   if(theLandCache.valid())
+   {
+      cacheNode = theLandCache->getNode(theGrid->getId(level, row, col), true);
+   }
+
+   if(!theElevationEnabledFlag)
+   {
+      return grid;
+   }
+
+   if(cacheNode.valid())
+   {
+      grid = cacheNode->getElevation();
+   }
+   if(grid.valid())
+   {
+      return grid;
+   }
+   
+   ossim_uint32 rows = theElevationPatchSize;
+   ossim_uint32 cols = rows;
+   theElevationGrid->setTileWidthHeight(theElevationPatchSize, theElevationPatchSize);
+
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   theElevationGrid->createGridPoints(points,
+                                      level,
+                                      row,
+                                      col,
+                                      rows,
+                                      cols);
+   grid = theElevationDatabase->getTexture(level, row, col, *theElevationGrid);
+   if(grid.valid())
+   {
+      ossim_float32* gridPtr = (ossim_float32*)grid->data();
+
+      ossim_uint32 idx = 0;
+      ossim_uint32 area = grid->s()*grid->t();
+      osg::Vec3d latLonPoint;
+      for(;idx < area; ++idx)
+      {
+         theElevationGrid->getLatLon(latLonPoint, points[idx]);
+         double offset = theModel->getGeoidOffset(latLonPoint[0],
+                                                  latLonPoint[1]);
+         if(*gridPtr == OSSIMPLANET_NULL_HEIGHT)
+         {
+            *gridPtr = offset;
+         }
+         else
+         {
+            *gridPtr = (*gridPtr)*theHeightExag + offset;
+         }
+         ++gridPtr;
+      }
+   }
+
+   return grid;
+
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetLandReaderWriter::getCachedElevation(ossim_uint32 level,
+                                                                               ossim_uint32 row,
+                                                                               ossim_uint32 col)const
+{
+   osg::ref_ptr<ossimPlanetImage> result;
+   std::ostringstream tempStream;
+
+   if(!theElevationEnabledFlag) return result;
+   if(theElevationCacheDir!= "")
+   {
+      tempStream << "L" << level<<"_X"<<col<<"_Y"<<row<<".elev";
+      ossimFilename filename;
+      
+      filename = theElevationCacheDir.dirCat(tempStream.str().c_str());
+      if(filename.exists())
+      {
+         ossimEndian endian;
+		 std::ifstream inFile(filename.c_str(),std::ios::in|std::ios::binary);
+         ossim_uint8 endianFlag;
+         ossim_uint32 w;
+         ossim_uint32 h;
+         ossimByteOrder byteOrder;
+         if(inFile.good())
+         {
+            inFile.read((char*)(&endianFlag), 1);
+            inFile.read((char*)(&w), 4);
+            inFile.read((char*)(&h), 4);
+            
+            byteOrder = (ossimByteOrder)endianFlag;
+            if(endian.getSystemEndianType() != byteOrder)
+            {
+               endian.swap(&w, 4);
+               endian.swap(&h, 4);
+            }
+            
+            result = new ossimPlanetImage;
+            result->allocateImage(w, h, 1, GL_LUMINANCE, GL_FLOAT);//new ossimPlanetElevationGrid(w, h);
+            ossim_float32* data = (ossim_float32*)result->data();
+            
+            inFile.read((char*)data, w*h*sizeof(ossim_float32));
+            
+            if(endian.getSystemEndianType() != byteOrder)
+            {
+               endian.swap(data, w*h);
+            }
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimPlanetLandReaderWriter::writeElevationToCache(ossim_uint32 level,
+                                                      ossim_uint32 row,
+                                                      ossim_uint32 col,
+                                                      osg::ref_ptr<ossimPlanetImage> elevation)const
+{
+   if(theElevationCacheDir!= "")
+   {
+      if(theElevationCacheDir.exists())
+      {
+         std::ostringstream tempStream;
+         ossimEndian endian;
+         tempStream << "L" << level<<"_X"<<col<<"_Y"<<row<<".elev";
+         ossimFilename filename;
+         filename = theElevationCacheDir.dirCat(tempStream.str().c_str());
+         
+         std::ofstream oFile(filename.c_str(),
+			 std::ios::out|std::ios::binary);
+         ossim_uint8 endianType = (ossim_uint8)endian.getSystemEndianType();
+         ossim_uint32 w = elevation->getWidth();
+         ossim_uint32 h = elevation->getHeight();
+         ossim_float32* data = (ossim_float32*)elevation->data();
+         if(oFile.good())
+         {
+            oFile.write((char*)&endianType, 1);
+            oFile.write((char*)&w, 4);
+            oFile.write((char*)&h, 4);
+            oFile.write((char*)data, sizeof(ossim_float32)*w*h);
+         }
+      }
+   }
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLatLonHud.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLatLonHud.cpp
new file mode 100644
index 0000000..7a420e6
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLatLonHud.cpp
@@ -0,0 +1,506 @@
+#include <iostream>
+#include <sstream>
+#include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <osg/StateSet>
+#include <osg/Matrixd>
+#include <osg/Material>
+#include <osg/Projection>
+#include <osg/MatrixTransform>
+#include <osg/LineWidth>
+#include <osg/PolygonMode>
+#include <osgUtil/CullVisitor>
+#include <osgUtil/IntersectVisitor>
+#include <OpenThreads/ScopedLock>
+#include <ossim/base/ossimDms.h>
+#include <osgGA/EventVisitor>
+
+class ossimPlanetLatLonHudUpdateCallback : public osg::NodeCallback
+{
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         ossimPlanetLatLonHud* n = dynamic_cast<ossimPlanetLatLonHud*>(node);
+         if(n)
+         {
+            if(n->enableFlag())
+            {
+               n->traverse(*nv);
+            }
+            return;
+         }
+         traverse(node, nv);
+      }
+};
+
+ossimPlanetLatLonHud::ossimPlanetLatLonHud()
+{
+   setUpdateCallback(new ossimPlanetLatLonHudUpdateCallback);
+   theInitializedFlag = false;
+   theAutoUpdateFlag = true;
+   theFontName = "arial.ttf";
+   theFont = osgText::readFontFile(theFontName.c_str());
+   theFontChanged = true;
+
+   theCharacterSize = 16;
+   theCharacterSizeDirtyFlag = true;
+   theLookLabel  = "Look At:  ";
+   theEyeLabel   = "Eye:      ";
+   theRangeLabel = "Range:    ";
+   theLatDisplayString = "dd.ddddddddddddC";
+   theLonDisplayString = "ddd.ddddddddddddC";
+
+   theCompass = new ossimPlanetCompass;
+   theCompass->setRotateByViewMatrix(true);
+   theCompass->buildCompass();
+   theCompass->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(), 
+                                                   osg::StateAttribute::PROTECTED); // don't allow to go to wireframe
+
+   theViewportChangedFlag = false;
+}
+
+void ossimPlanetLatLonHud::traverse(osg::NodeVisitor& nv)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(!theEnableFlag) return;
+   bool traverseChildren = theViewport.valid();
+   if(!thePlanet)
+   {
+      thePlanet = ossimPlanet::findPlanet(this);
+   }
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!theInitializedFlag)
+         {
+            initialize();
+         }
+         if(theViewportChangedFlag&&theViewport.valid())
+         {
+            theCameraNode->setProjectionMatrix(osg::Matrix::ortho2D(theViewport->x(),
+                                                                    theViewport->width(),
+                                                                    theViewport->y(),
+                                                                    theViewport->height()));
+            theViewportChangedFlag = false;
+            setRedrawFlag(true);
+         }
+         if(theAutoUpdateFlag&&thePlanet)
+         {
+ //           osg::Vec3d latLonHeight    = thePlanet->getLineOfSiteLatLonHeightPoint();
+ //           osg::Vec3d nadir           = thePlanet->getNadirLatLonHeightPoint();
+
+ //           theLatLonHeight[0] = latLonHeight[0];
+ //           theLatLonHeight[1] = latLonHeight[1];
+ //           theNadirLatLonHeight[0] = nadir[0];
+ //           theNadirLatLonHeight[1] = nadir[1];
+         }
+         if(theViewport.valid())
+         {
+            updatePosition();
+            Group::traverse(nv);            
+         }
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         if(!theInitializedFlag) return;
+         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(cullVisitor)
+         {
+            double x = cullVisitor->getViewport()->x();
+            double y = (int)cullVisitor->getViewport()->y();
+            double w = (int)cullVisitor->getViewport()->width();
+            double h = (int)cullVisitor->getViewport()->height();
+            if(!theViewport.valid())
+            {
+               theViewport = new osg::Viewport(x,y,w,h);
+               theViewportChangedFlag = true;
+            }
+            else
+            {
+               if( !ossim::almostEqual(theViewport->x(), x)||
+                   !ossim::almostEqual(theViewport->y(), y)||
+                   !ossim::almostEqual(theViewport->width(), w)||
+                   !ossim::almostEqual(theViewport->height(), h))
+               {
+                  theViewport->setViewport(x,y,w,h);
+                  setRedrawFlag(true);
+                  theViewportChangedFlag = true;
+               }
+            }
+         }
+         if(traverseChildren)
+         {
+            Group::traverse(nv);
+         }
+         break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+         if(ev)
+         {
+            ossimPlanetViewer* viewer = dynamic_cast<ossimPlanetViewer*>(ev->getActionAdapter());
+            if(viewer&&viewer->currentCamera()&&viewer->currentLookAt())
+            {
+               theNadirLatLon[0] = viewer->currentCamera()->lat(); 
+               theNadirLatLon[1] = viewer->currentCamera()->lon(); 
+               theNadirLatLon[2] = viewer->currentCamera()->altitude(); 
+               theAltitude = viewer->currentCamera()->altitude(); 
+               theLineOfSiteLatLon[0] = viewer->currentLookAt()->lat(); 
+               theLineOfSiteLatLon[1] = viewer->currentLookAt()->lon(); 
+               theLineOfSiteLatLon[2] = viewer->currentLookAt()->altitude(); 
+               if(theModel.valid())
+               {
+                  theModel->ellipsoidalToMsl(theNadirLatLon);
+                  theModel->ellipsoidalToMsl(theLineOfSiteLatLon);
+               }
+               theRange = viewer->currentLookAt()->range(); 
+               if(viewer->model())
+               {
+                  theAltitude -= viewer->model()->getGeoidOffset(theNadirLatLon[0],theNadirLatLon[1]);
+               }
+               if(theCompass.valid())
+               {
+                  theCompass->setHeading(viewer->currentCamera()->heading());
+                  theCompass->setPitch(viewer->currentCamera()->pitch());
+                  theCompass->setRoll(viewer->currentCamera()->roll());
+               }
+            }
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+}
+
+void ossimPlanetLatLonHud::initialize()
+{   
+   theCrosshairColor  = osg::Vec4d(1.0,1.0,1.0,0.6);
+   theTextColor       = osg::Vec4d(1.0,1.0,1.0,0.6);
+   theGeode     = new osg::Geode();
+   theCrosshair = new osg::Geometry;
+   theCrosshairLineWidth = new osg::LineWidth(3);
+   osg::StateSet* stateset = theGeode->getOrCreateStateSet();
+   stateset->setMode(GL_LIGHTING,
+                     osg::StateAttribute::OFF);
+//   stateset->setMode(GL_COLOR_MATERIAL,
+//                     osg::StateAttribute::OFF);
+   stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+   stateset->setRenderBinDetails(11,"RenderBin");
+   stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+   stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   stateset->setAttribute(theCrosshairLineWidth.get(),osg::StateAttribute::ON);
+   stateset->setAttribute(new osg::PolygonMode(), 
+                          osg::StateAttribute::PROTECTED); // don't allow to go to wireframe
+   
+   theLookText         = new osgText::Text;
+   theEyeText          = new osgText::Text;
+   theRangeText        = new osgText::Text;
+   
+   theLookText->setBackdropType(osgText::Text::OUTLINE);
+   theEyeText->setBackdropType(osgText::Text::OUTLINE);
+   theRangeText->setBackdropType(osgText::Text::OUTLINE);
+   
+   
+   theGeode->addDrawable(theLookText.get());
+   theGeode->addDrawable(theEyeText.get());
+   theGeode->addDrawable(theRangeText.get());
+   theGeode->addDrawable(theCrosshair.get());
+
+   theCameraNode = new osg::CameraNode;
+   
+//    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
+   theCameraNode->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+   theCameraNode->setProjectionMatrix(osg::Matrix::ortho2D(0,1024,0,1024));
+   theCameraNode->setViewMatrix(osg::Matrix::identity());
+   theCameraNode->setClearMask(GL_DEPTH_BUFFER_BIT);
+   theCameraNode->setRenderOrder(osg::CameraNode::POST_RENDER);
+   theCameraNode->addChild(theGeode.get());
+   
+//    theProjection = new osg::Projection;
+//    theProjection->setMatrix(osg::Matrix::ortho2D(0,1024,0,1024));
+//    theProjection->addChild(modelview_abs);
+
+   
+   addChild(theCameraNode.get());
+
+   theLookText->setSupportsDisplayList(false);
+   theEyeText->setSupportsDisplayList(false);
+   theRangeText->setSupportsDisplayList(false);
+   theCrosshair->setSupportsDisplayList(false);
+
+   theGeode->setStateSet(stateset);
+
+   theCameraNode->addChild(theCompass.get());
+   
+   
+   theInitializedFlag = true;
+}
+
+void ossimPlanetLatLonHud::updatePosition()
+{
+   char tempBuf[255];
+   if(theCompass.valid())
+   {
+      theCompass->setPosition(osg::Vec3d(theViewport->width()-128,
+                                         theViewport->height()-128,
+                                         0.0));
+      theCompass->setScale(128);
+      //      if(thePlanet)
+      //      {
+      //         theCompass->setHeading(thePlanet->hpr()[0]);
+      //        theCompass->setPitch(thePlanet->hpr()[1]);
+      //        theCompass->setRoll(thePlanet->hpr()[2]);
+      //     }
+   }
+   if(ossim::isnan(theLineOfSiteLatLon[0]) ||
+      ossim::isnan(theLineOfSiteLatLon[1]))
+   {
+      theLookText->setText(theLookLabel + "NaN");
+      //      theLonText->setText(theLookLabel + "NaN");
+   }
+   else
+   {
+      ossimDms latDms(theLineOfSiteLatLon[0]);
+      ossimDms lonDms(theLineOfSiteLatLon[1], false);
+      ossimString text = (theLookLabel + latDms.toString(theLatDisplayString.c_str()) + ", " 
+                          + lonDms.toString(theLonDisplayString.c_str())+ ", " 
+                          + ossimString::toString(theLineOfSiteLatLon[2]));
+      theLookText->setText(text);
+   }
+   if(ossim::isnan(theNadirLatLon[0]) ||
+      ossim::isnan(theNadirLatLon[1]))
+   {
+      theEyeText->setText(theLookLabel + "NaN");
+      //      theLonText->setText(theLookLabel + "NaN");
+   }
+   else
+   {
+      ossimDms latDms(theNadirLatLon[0]);
+      ossimDms lonDms(theNadirLatLon[1], false);
+      ossimString text = (theEyeLabel + latDms.toString(theLatDisplayString.c_str()) + ", " 
+                          + lonDms.toString(theLonDisplayString.c_str())+ ", " 
+                          + ossimString::toString(theNadirLatLon[2]));
+      theEyeText->setText(text);
+   }
+   if(!ossim::isnan(theRange))
+   {
+      sprintf(tempBuf,"%lf meters", theRange);
+      theRangeText->setText((theRangeLabel + tempBuf).c_str());
+   }
+   else
+   {
+      sprintf(tempBuf,"%s", "NaN");
+      theRangeText->setText((theRangeLabel + tempBuf).c_str());
+   }
+   if((theFont.valid())&&
+      (theFontChanged))
+   {
+      theLookText->setFont(theFont.get());
+      theEyeText->setFont(theFont.get());
+      theRangeText->setFont(theFont.get());
+      
+//      theLonText->setFont(theFont.get());
+//      theHeightText->setFont(theFont.get());
+//      theLineOfSiteText->setFont(theFont.get());
+      theFontChanged = false;
+   }
+   if(theCharacterSizeDirtyFlag)
+   {
+      theLookText->setCharacterSize(theCharacterSize);
+      theEyeText->setCharacterSize(theCharacterSize);
+      theRangeText->setCharacterSize(theCharacterSize);
+//      theLonText->setCharacterSize(theCharacterSize);
+//      theHeightText->setCharacterSize(theCharacterSize);
+//      theLineOfSiteText->setCharacterSize(theCharacterSize);
+//      theCharacterSizeDirtyFlag = false;
+   }
+   double ulx = theViewport->x();
+   double uly = theViewport->y();
+   double x = ulx;
+   double y = uly;
+   double w = theViewport->width();
+   double h = theViewport->height();
+
+   osg::BoundingBox bb;
+
+//   bb = osg::BoundingBox();
+   osg::Vec3d pos = osg::Vec3d(x, y+5, 0.0);
+//   bb.expandBy(theRangeText->getBound());
+   bb = theRangeText->getBound();
+   theRangeText->setPosition(pos);
+   int height = (int)(bb.yMax() - bb.yMin()) + 5;
+   pos += osg::Vec3d(0.0,(height), 0.0);
+   theLookText->setPosition(pos);
+   bb = theLookText->getBound();
+//   bb.expandBy(theLookText->getBound());
+   height = (int)(bb.yMax() - bb.yMin()) + 5;
+   pos += osg::Vec3d(0.0,(height), 0.0);
+   theEyeText->setPosition(pos);
+
+   theLookText->setColor(theTextColor);
+   theEyeText->setColor(theTextColor);
+   theRangeText->setColor(theTextColor);
+   
+   osg::Vec2Array* vertices = 0;
+   osg::Vec4Array* colorArray = 0;
+   if(!theCrosshair->getVertexArray())
+   {
+      vertices = new osg::Vec2Array;
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      vertices->push_back(osg::Vec2(0.0,0.0));
+      theCrosshair->setVertexArray(vertices);
+      theCrosshair->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,8));
+      colorArray = new osg::Vec4Array;
+      colorArray->push_back(theCrosshairColor);
+      theCrosshair->setColorArray(colorArray);
+      theCrosshair->setColorBinding(osg::Geometry::BIND_OVERALL);
+   }
+   else
+   {
+      vertices = dynamic_cast<osg::Vec2Array*>(theCrosshair->getVertexArray());
+      colorArray = dynamic_cast<osg::Vec4Array*>(theCrosshair->getColorArray());
+      
+   }
+   if(colorArray)
+   {
+      (*colorArray)[0] = theCrosshairColor;
+   }
+   if(vertices)
+   {
+      int centerx = (int)(((double)ulx + (double)w/2));
+      int centery = (int)(((double)uly + (double)h/2));
+      
+      (*vertices)[0][0] = centerx - 20;
+      (*vertices)[0][1] = centery;
+      (*vertices)[1][0] = centerx - 5;
+      (*vertices)[1][1] = centery;
+      (*vertices)[2][0] = centerx + 5;
+      (*vertices)[2][1] = centery;
+      (*vertices)[3][0] = centerx + 20;
+      (*vertices)[3][1] = centery;
+      
+      (*vertices)[4][0] = centerx;
+      (*vertices)[4][1] = centery + 20;
+      (*vertices)[5][0] = centerx;
+      (*vertices)[5][1] = centery + 5;
+      (*vertices)[6][0] = centerx;
+      (*vertices)[6][1] = centery - 5;
+      (*vertices)[7][0] = centerx;
+      (*vertices)[7][1] = centery - 20;
+   }
+}
+
+osg::Vec4 ossimPlanetLatLonHud::getCrossHairColor()const
+{
+   return theCrosshairColor;
+}
+
+osg::Vec4 ossimPlanetLatLonHud::getTextColor()const
+{
+   return theTextColor;
+}
+
+void ossimPlanetLatLonHud::setCrosshairColor(const osg::Vec4& color)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theCrosshairColor = color;
+}
+
+void ossimPlanetLatLonHud::setFont(const ossimString& fontFile)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theFontChanged = theFontName != fontFile;
+   theFontName = fontFile;
+   theFont = osgText::readFontFile(fontFile.c_str());
+}
+
+void ossimPlanetLatLonHud::setTextColor(const osg::Vec4& color)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theTextColor = color;
+}
+
+void ossimPlanetLatLonHud::setLatDisplayString(const ossimString& latDisplayString)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theLatDisplayString = latDisplayString;
+}
+
+void ossimPlanetLatLonHud::setLonDisplayString(const ossimString& lonDisplayString)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theLonDisplayString = lonDisplayString;
+}
+
+void ossimPlanetLatLonHud::setCharacterSize(float size)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theCharacterSizeDirtyFlag = size != theCharacterSize;
+   theCharacterSize = size;
+   
+}
+
+void ossimPlanetLatLonHud::setViewport(osg::ref_ptr<osg::Viewport> viewport)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theViewport = viewport;
+}
+
+void ossimPlanetLatLonHud::setAutoUpdateFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theAutoUpdateFlag = flag;
+}
+
+void ossimPlanetLatLonHud::setCompassTexture(const ossimFilename& compass)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(theCompass.valid())
+   {
+      theCompass->setCompassTexture(compass);
+      theCompass->updateCompass();
+      setRedrawFlag(true);
+   }
+}
+
+#if 0
+void ossimPlanetLatLonHud::setCompassTexture(const ossimFilename& ring,
+                                             const ossimFilename& interior)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(theCompass.valid())
+   {
+      theCompass->setCompassTexture(ring, interior);
+      theCompass->updateCompass();
+      setRedrawFlag(true);
+   }
+}
+#endif
+
+void ossimPlanetLatLonHud::execute(const ossimPlanetAction& action)
+{
+#if 0
+   if(action.command() == "init")
+   {
+      ossimPlanetLayer::execute(action); // initialize the base.
+   }
+   else
+   {
+      ossimPlanetLayer::execute(action);
+   }
+#endif  
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLayer.cpp
new file mode 100644
index 0000000..81e5eac
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLayer.cpp
@@ -0,0 +1,226 @@
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetIdManager.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <osgGA/EventVisitor>
+#include <iostream>
+
+class ossimPlanetLayerFinder : public osg::NodeVisitor
+{
+public:
+   ossimPlanetLayerFinder()
+      :osg::NodeVisitor(NODE_VISITOR,
+                        TRAVERSE_ALL_CHILDREN)
+      {
+         thePlanetLayer = 0;
+      }
+
+   virtual void apply(osg::Node& node)
+      {
+         if(!thePlanetLayer)
+         {
+            thePlanetLayer = dynamic_cast<ossimPlanetLayer*>(&node);
+         }
+         else
+         {
+            return;
+         }
+         osg::NodeVisitor::apply(node);
+      }
+   
+   ossimPlanetLayer* thePlanetLayer;
+};
+
+class ossimPlanetLayerTraverseCallback : public osg::NodeCallback
+{
+public:
+   ossimPlanetLayerTraverseCallback()
+      {
+      }
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         if(node)
+         {
+            node->traverse(*nv);
+         }
+      }
+};
+
+ossimPlanetLayer::ossimPlanetLayer()
+   :thePlanet(0)
+{
+   setEventCallback(new ossimPlanetTraverseCallback);
+}
+
+ossimPlanetLayer::~ossimPlanetLayer()
+{
+   thePlanet = 0;
+}
+
+void ossimPlanetLayer::traverse(osg::NodeVisitor& nv)
+{
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         if(redrawFlag())
+         {
+            osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+            if(ev)
+            {
+               if(ev->getActionAdapter())
+               {
+                  ev->getActionAdapter()->requestRedraw();
+                  setRedrawFlag(false);
+               }
+            }
+         }
+         return;
+      }
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!thePlanet)
+         {
+            setPlanet(ossimPlanet::findPlanet(this));
+         }
+         break;
+      }
+      default:
+      {
+         
+      }
+   }
+   ossimPlanetNode::traverse(nv);
+}
+
+ossimPlanetLayer* ossimPlanetLayer::findLayer(osg::Node* startNode)
+{
+   osg::Node* rootNode        = startNode;
+   osg::Node* rootNonNullNode = startNode;
+
+   while(rootNode)
+   {
+      rootNonNullNode = rootNode;
+      ossimPlanetLayer* castNode = dynamic_cast<ossimPlanetLayer*>(rootNode);
+      if(castNode)
+      {
+         return castNode;
+      }
+      if(rootNode->getNumParents() > 0)
+      {
+         rootNode = rootNode->getParent(0);
+      }
+      else
+      {
+         rootNode = 0;
+      }
+   }
+   if(rootNonNullNode)
+   {
+      ossimPlanetLayerFinder finder;
+      rootNonNullNode->accept(finder);
+      return finder.thePlanetLayer;
+   }
+
+   return 0;
+}
+
+ossimPlanetLayer* ossimPlanetLayer::findLayer(osg::NodePath& currentNodePath)
+{
+   if(currentNodePath.empty())
+   {
+      return 0;
+   }
+   for(osg::NodePath::reverse_iterator itr = currentNodePath.rbegin();
+       itr != currentNodePath.rend();
+       ++itr)
+   {
+      ossimPlanetLayer* layer = dynamic_cast<ossimPlanetLayer*>(*itr);
+      if (layer) 
+      {
+         return layer;
+      }
+   }
+   
+   return 0;
+}
+
+void ossimPlanetLayer::execute(const ossimPlanetAction& action)
+{
+   
+#if 0
+   if(action.command() == "setReceiver")
+   {
+      if(action.argCount() == 1)
+      {
+         setPathnameAndRegister(action.arg(1));
+      }
+   }
+   else if(action.command() == "setEnableFlag")
+   {
+      if(action.argCount() == 1)
+      {
+         setEnableFlag(ossimString(action.arg(1)).toBool());
+      }
+   }
+   else if(action.command() == "setId")
+   {
+      if(action.argCount()==1)
+      {
+         setId(action.arg(1));
+      }
+   }
+   else if(action.command() == "setName")
+   {
+      if(action.argCount()==1)
+      {
+         setName(action.arg(1));
+      }
+   }
+   else if(action.command() == "setDescription")
+   {
+      if(action.argCount()==1)
+      {
+         setDescription(action.arg(1));
+      }
+   }
+   else if(action.command() == "init")
+   {
+      if(action.argCount() != 1) return;
+      
+      ossimString   objectName;
+      ossimString   objectArg;
+      ossim_uint32 idx = 1;
+      ossimPlanetAction nestedAction(":dummy dummy " + action.arg(1) );
+      for(idx = 1; idx <= nestedAction.argCount(); ++idx)
+      {
+         if(mkUtils::extractObjectAndArg(objectName,
+                                         objectArg,
+                                         nestedAction.arg(idx)))
+         {
+            if(objectName == "Name")
+            {
+               setName(objectArg);
+            }
+            else if(objectName == "Id")
+            {
+               setId(objectArg);
+            }
+            else if(objectName == "Description")
+            {
+               setDescription(objectArg);
+            }
+            else if(objectName == "ReceiverPath")
+            {
+               setPathnameAndRegister(objectArg);
+            }
+            else if(objectName == "Enable")
+            {
+               setEnableFlag(objectArg.toBool());
+            }
+         }
+      }
+   }
+#endif
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLayerFactory.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLayerFactory.cpp
new file mode 100644
index 0000000..5e17b8a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLayerFactory.cpp
@@ -0,0 +1,63 @@
+#include <ossimPlanet/ossimPlanetLayerFactory.h>
+#include <ossimPlanet/ossimPlanetLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetLatLonHud.h>
+#include <ossimPlanet/ossimPlanetSousaLayer.h>
+#include <ossimPlanet/ossimPlanetKmlLayer.h>
+#include <ossimPlanet/ossimPlanetAnnotationLayer.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+
+ossimPlanetLayerFactory* ossimPlanetLayerFactory::theInstance = 0;
+
+ossimPlanetLayerFactory::ossimPlanetLayerFactory()
+{
+   theInstance = this;
+}
+
+ossimPlanetLayerFactory::~ossimPlanetLayerFactory()
+{
+   theInstance = 0;
+}
+
+ossimPlanetLayerFactory* ossimPlanetLayerFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetLayerFactory;
+   }
+   
+   return theInstance;
+}
+
+ossimPlanetLayer* ossimPlanetLayerFactory::create(const ossimString& type)const
+{
+   if(type == "ossimPlanetLand")
+   {
+      return new ossimPlanetLand;
+   }
+   else if(type == "osismPlanetTerrain")
+   {
+      return new ossimPlanetTerrain;
+   }
+   else if(type == "ossimPlanetVideoLayer")
+   {
+   }
+   else if(type == "ossimPlanetLatLonHud")
+   {
+      return new ossimPlanetLatLonHud;
+   }
+   else if(type == "ossimPlanetSousaLayer")
+   {
+      return new ossimPlanetSousaLayer;
+   }
+   else if(type == "ossimPlanetKmlLayer")
+   {
+      return new ossimPlanetKmlLayer;
+   }
+	else if(type == "ossimPlanetAnnotationLayer")
+	{
+		return new ossimPlanetAnnotationLayer;
+	}
+   
+   return 0;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLayerRegistry.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLayerRegistry.cpp
new file mode 100644
index 0000000..0c27acc
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLayerRegistry.cpp
@@ -0,0 +1,89 @@
+#include <ossimPlanet/ossimPlanetLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetLayerFactory.h>
+#include <algorithm>
+ossimPlanetLayerRegistry* ossimPlanetLayerRegistry::theInstance = 0;
+ossimPlanetLayerRegistry::ossimPlanetLayerRegistry()
+{
+   theInstance = this;
+}
+
+ossimPlanetLayerRegistry::~ossimPlanetLayerRegistry()
+{
+   theInstance = 0;
+}
+
+ossimPlanetLayerRegistry* ossimPlanetLayerRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetLayerRegistry;
+      theInstance->registerFactory(ossimPlanetLayerFactory::instance());
+   }
+   
+   return theInstance;
+}
+
+void ossimPlanetLayerRegistry::finalize()
+{
+   if(theInstance)
+   {
+		theFactoryList.clear();
+		
+      delete theInstance;
+      theInstance = 0;
+   }
+}
+
+ossimPlanetLayer* ossimPlanetLayerRegistry::create(const ossimString& layerName)const
+{
+   ossimPlanetLayer* result = 0;
+   ossim_uint32 idx = 0;
+   theFactoryListMutex.readLock();
+   for(idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
+   {
+      result = theFactoryList[idx]->create(layerName);
+   }
+   theFactoryListMutex.readUnlock();
+   
+   return result;
+}
+
+void ossimPlanetLayerRegistry::registerFactory(ossimPlanetLayerFactoryBase* factory,
+															  bool insertFrontFlag)
+{
+   if(!hasFactory(factory))
+   {
+      theFactoryListMutex.writeLock();
+		if(!insertFrontFlag)
+		{
+			theFactoryList.push_back(factory);
+		}
+		else
+		{
+			theFactoryList.insert(theFactoryList.begin(), factory);
+		}
+      theFactoryListMutex.writeUnlock();
+   }
+}
+
+void ossimPlanetLayerRegistry::unregisterFactory(const ossimPlanetLayerFactoryBase* factory)
+{
+   theFactoryListMutex.writeLock();
+   FactoryListType::iterator iter = std::find(theFactoryList.begin(), 
+                                              theFactoryList.end(),
+                                              factory);
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+   theFactoryListMutex.writeUnlock();
+}
+
+bool ossimPlanetLayerRegistry::hasFactory(const ossimPlanetLayerFactoryBase* factory)const
+{
+   FactoryListType::const_iterator iter = std::find(theFactoryList.begin(), 
+                                                    theFactoryList.end(),
+                                                    factory);
+   
+   return (iter!=theFactoryList.end());
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLookAt.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLookAt.cpp
new file mode 100644
index 0000000..94fadf9
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLookAt.cpp
@@ -0,0 +1,48 @@
+#include <ossimPlanet/ossimPlanetLookAt.h>
+
+bool ossimPlanetLookAt::loadXml(ossimRefPtr<ossimXmlNode> xmlNode)
+{
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = xmlNode->getChildNodes();
+    ossim_uint32 idx;
+   ossim_uint32 upper=childNodes.size();
+
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+
+      if(tag == "latitude")
+      {
+         theLat = childNodes[idx]->getText().toDouble(); 
+      }
+      else if(tag == "longitude")
+      {
+         theLon = childNodes[idx]->getText().toDouble(); 
+      }
+      else if(tag == "altitude")
+      {
+         theAltitude = childNodes[idx]->getText().toDouble(); 
+      }
+      else if(tag == "range")
+      {
+         theRange = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "roll")
+      {
+         theRoll = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "tilt")
+      {
+         thePitch = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "heading")
+      {
+         theHeading = childNodes[idx]->getText().toDouble();
+      }
+      else if(tag == "altitudeMode")
+      {
+         theMode = modeFromString(childNodes[idx]->getText());
+      }
+   }
+   
+   return true;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetLsrSpaceTransform.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetLsrSpaceTransform.cpp
new file mode 100644
index 0000000..cc82ad4
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetLsrSpaceTransform.cpp
@@ -0,0 +1,210 @@
+#include <ossimPlanet/ossimPlanetLsrSpaceTransform.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/mkUtils.h>
+#include <osg/io_utils>
+
+ossimPlanetLsrSpaceTransform::ossimPlanetLsrSpaceTransform(ossimPlanetGeoRefModel* model)
+:theModel(model),
+theRedrawFlag(true)
+{
+   theScale[0] = theScale[1] = theScale[2] = 1.0;
+   theHpr[0] = theHpr[1] = theHpr[2] = 0.0;
+   _referenceFrame = RELATIVE_RF;
+}
+
+ossimPlanetLsrSpaceTransform::ossimPlanetLsrSpaceTransform(const ossimPlanetLsrSpaceTransform& src,const osg::CopyOp& copyop)
+:osg::Transform(src, copyop),
+theModel(src.theModel),
+theLatLonAltitude(src.theLatLonAltitude),
+theXYZ(src.theXYZ),
+theHpr(src.theHpr),
+theScale(src.theScale),
+theLocalToWorld(src.theLocalToWorld),
+theInvLocalToWorld(src.theInvLocalToWorld)
+{
+}
+
+void ossimPlanetLsrSpaceTransform::setMatrix(const osg::Matrix& m)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   dirtyBound();
+   theLocalToWorld = m;
+   theInvLocalToWorld.invert(m);
+   matrixToParameters(m);
+}
+
+void ossimPlanetLsrSpaceTransform::setModel(ossimPlanetGeoRefModel* model)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theModel = model;
+   parametersToMatrix();
+   dirtyBound();
+}
+
+void ossimPlanetLsrSpaceTransform::setHeadingPitchRoll(const osg::Vec3d& hpr)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theHpr = hpr;
+   parametersToMatrix();
+   dirtyBound();
+}
+
+void ossimPlanetLsrSpaceTransform::setLatLonAltitude(const osg::Vec3d& value)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theLatLonAltitude = value;
+   parametersToMatrix();
+   dirtyBound();
+}
+
+void ossimPlanetLsrSpaceTransform::setLatLonAltitudeMeanSeaLevel(const osg::Vec3d& value)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(theModel.valid())
+   {
+      theLatLonAltitude = value;
+      theModel->mslToEllipsoidal(theLatLonAltitude);
+   }
+   parametersToMatrix();
+   dirtyBound();
+}
+
+void ossimPlanetLsrSpaceTransform::setScale(const osg::Vec3d& value)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theScale = value;
+   parametersToMatrix();
+   dirtyBound();
+}
+
+void ossimPlanetLsrSpaceTransform::setXYZ(const osg::Vec3d& xyz)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(theModel.valid())
+   {
+      theXYZ = xyz;
+      theModel->inverse(xyz, theLatLonAltitude);
+   }
+   dirtyBound();
+   parametersToMatrix();
+}
+
+void ossimPlanetLsrSpaceTransform::traverse(osg::NodeVisitor& nv)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+        if(theRedrawFlag)
+         {
+            ossimPlanetNode* node = ossimPlanetNode::findNode(nv.getNodePath());
+            if(node)
+            {
+               node->setRedrawFlag(true);
+            }
+            theRedrawFlag = false;
+         }
+         if(!theModel.valid())
+         {
+            ossimPlanetLayer* layer = ossimPlanetLayer::findLayer(nv.getNodePath());
+            if(layer)
+            {
+               theModel = layer->model();
+            }
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   osg::Transform::traverse(nv);
+}
+
+void ossimPlanetLsrSpaceTransform::matrixToParameters(const osg::Matrix& inputM)
+{
+   if(theModel.valid())
+   {
+      osg::Matrixd m;
+      osg::Vec3d translation;
+      osg::Quat rotation;
+      osg::Quat s;
+      // deomcpose some of the parts we need
+      //
+      inputM.decompose(translation, rotation, theScale, s);
+
+      // no solve the relative heading pitch and roll to the
+      // tangent plane at the point translation
+      //
+      theXYZ = translation;
+      theModel->inverse(translation, theLatLonAltitude);
+      theModel->lsrMatrix(theLatLonAltitude, m);//, theOrientationMode);
+      mkUtils::matrixToHpr(theHpr, m, inputM);
+      theRedrawFlag = true;
+      notifyLsrSpaceChanged();
+      
+ //     std::cout << "hpr = " << theHpr            << std::endl;
+//      std::cout << "llh = " << theLatLonAltitude << std::endl;
+      
+   }
+}
+
+bool ossimPlanetLsrSpaceTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if (_referenceFrame==RELATIVE_RF)
+   {
+      matrix.preMult(theLocalToWorld);
+   }
+   else // absolute
+   {
+      matrix = theLocalToWorld;
+   }
+   return true;
+}
+
+bool ossimPlanetLsrSpaceTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if (_referenceFrame==RELATIVE_RF)
+   {
+      matrix.postMult(theInvLocalToWorld);
+   }
+   else // absolute
+   {
+      matrix = theInvLocalToWorld;
+   }
+   return true;
+}
+
+bool ossimPlanetLsrSpaceTransform::parametersToMatrix()
+{
+   if(theScale.x() == 0.0 || theScale.y() == 0.0 || theScale.z()==0.0) return false;
+   if(!theModel.valid()) return false;
+   osg::Matrixd m;
+   theModel->orientationLsrMatrix(m, theLatLonAltitude, theHpr[0], theHpr[1], theHpr[2]);//, theOrientationMode);
+   theLocalToWorld = osg::Matrixd::scale(osg::Vec3d(theScale[0], theScale[1], theScale[2]))*m;
+   theInvLocalToWorld.invert(theLocalToWorld);
+   theRedrawFlag = true;
+   notifyLsrSpaceChanged();
+   return true;
+}
+
+void ossimPlanetLsrSpaceTransform::notifyLsrSpaceChanged()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->lsrSpaceChanged(this);
+      }
+   }
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetManipulator.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetManipulator.cpp
new file mode 100644
index 0000000..e74ac0a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetManipulator.cpp
@@ -0,0 +1,806 @@
+#include <ossimPlanet/ossimPlanetManipulator.h>
+#include <ossimPlanet/ossimPlanetUtility.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <osg/Quat>
+#include <osg/Notify>
+#include <osgUtil/IntersectVisitor>
+#include <ossim/base/ossimEcefPoint.h>
+#include <ossim/base/ossimGpt.h>
+#include <osgUtil/IntersectVisitor>
+#include <ossimPlanet/ossimPlanetInteractionController.h>
+#include <ossim/base/ossimEnvironmentUtility.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+#include <osg/CoordinateSystemNode>
+#include <OpenThreads/ScopedLock>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+#include <osg/io_utils>
+
+
+#include <iostream>
+
+using namespace osg;
+using namespace osgGA;
+
+ossimPlanetManipulator::ossimPlanetManipulator() :
+    theNavigator(new ossimPlanetNavigator(new ossimPlanetPrimaryBody("earth_wgs84", 6378137.0, 6356752.3142, 86400, 5.9742e24, -180, 180))),
+    theNode(NULL),
+    theEventHandlingFlag(true),
+    theUseFrameEventForUpdateFlag(false),
+    theAutoCalculateIntersectionFlag(true),
+    thePlanet(0),
+    theFusionDistance(1.0)
+{
+//   theViewMatrixBuilder = new ossimPlanetViewMatrixBuilder();
+
+theViewMatrixBuilder = new ossimPlanetViewMatrixBuilder(new ossimPlanetEllipsoidModel());   
+
+   theFromNodeCallback  = new FromNodeCallback(theViewMatrixBuilder.get());
+   theToNodeCallback    = new ToNodeCallback(theViewMatrixBuilder.get());
+
+   theNavigator->setUseTimedUpdateFlag(true);
+   initializeDefaultBindings(":navigator");
+}
+
+void ossimPlanetManipulator::initializeDefaultBindings(const ossimString& pathName)
+{
+   setPathnameAndRegister(pathName.c_str());
+   
+   // define our valuators
+   ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+   iac->defineInteractionValuator("LAT", -1.0f, 1.0f);
+   iac->defineInteractionValuator("LON", -1.0f, 1.0f);
+   iac->defineInteractionValuator("ZOOM", -1.0f, 1.0f);
+   iac->defineInteractionValuator("PITCH", -1.0f, 1.0f);
+   iac->defineInteractionValuator("YAW", -1.0f, 1.0f);
+   
+   // initialize bindings
+   // ossimFilename path = ossimEnvironmentUtility::instance()->getUserOssimSupportDir();
+   // path = path.dirCat("planet");
+   // path = path.dirCat("binds.act");
+//   if(path.exists())
+//   {
+//      ossimPlanetActionRouter::instance()->executeFile(path);
+//   }
+//   else
+   {
+      ossimPlanetDestinationCommandAction(":iac tie x_mouse LON YAW").execute();
+      ossimPlanetDestinationCommandAction(":iac tie y_mouse LAT ZOOM PITCH").execute();
+      ossimPlanetDestinationCommandAction(":iac bind left_mousedown         {"+pathName+" rotatestart}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind left_mouseup           {"+pathName+" rotatestop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind middle_mousedown       {"+pathName+" losrotatestart}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind middle_mouseup         {"+pathName+" losrotatestop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind right_mousedown        {"+pathName+" loszoomstart}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind right_mouseup          {"+pathName+" loszoomstop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind shift_middle_mousedown {"+pathName+" zoomstart}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind shift_middle_mouseup   {"+pathName+" zoomstop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind shift_right_mousedown  {"+pathName+" lookstart}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind shift_right_mouseup    {"+pathName+" lookstop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind right_key              {"+pathName+" flystart -.015625 0.0}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind left_key               {"+pathName+" flystart .015625 0.0}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind up_key                 {"+pathName+" flystart 0.0 -.015625}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind down_key               {"+pathName+" flystart 0.0 .015625}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind u_key                  {"+pathName+" rotatenorth}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind U_key                  {"+pathName+" rotatenorthup}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind p_key                  {"+pathName+" printlatlonelev}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind P_key                  {"+pathName+" printlookcoordinates}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind z_key                  {"+pathName+" recordanimation}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind Z_key                  {"+pathName+" playanimation}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind space_key              {"+pathName+" reset}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind return_key             {"+pathName+" stop}").execute();
+      ossimPlanetDestinationCommandAction(":iac bind A_key                  {: manualaction}").execute();
+   }
+}
+
+
+
+void ossimPlanetManipulator::extractLookFromParameters(ossimXmlNode* node,
+                                                   double& lat,
+                                                   double& lon,
+                                                   double& alt,
+                                                   double& h,
+                                                   double& p,
+                                                   double& r)
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = thePlanet->model();
+
+
+
+   ossimString vref = node->getAttributeValue("vref");
+   ossimString value;
+
+	
+   
+
+   if(node->getChildTextValue(value, "longitude"))
+   {
+      lon = value.toDouble();
+   }
+
+   if(node->getChildTextValue(value, "latitude"))
+   {
+      lat = value.toDouble();
+   }
+
+   if(node->getChildTextValue(value, "altitude"))
+   {
+      alt = value.toDouble();
+      if(node->getChildTextValue(value, "altitudeMode"))
+      {
+         if(value.contains("relative"))
+         {
+            alt += model->getHeightAboveEllipsoid(lat, lon);
+         }
+
+         else if(value.contains("clamp"))
+         {
+            alt = model->getHeightAboveEllipsoid(lat, lon);
+         }
+         else if(value.contains("absolute"))
+         {
+            if(vref!="wgs84")
+            {
+               alt += model->getGeoidOffset(lat, lon);
+            }
+         }
+      }
+   }
+
+   if(node->getChildTextValue(value, "heading"))
+   {
+      h = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "pitch"))
+   {
+      p = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "roll"))
+   {
+      r = value.toDouble();
+   }
+}
+
+
+void ossimPlanetManipulator::execute(const ossimPlanetAction& a)
+{
+
+   //std::cout << "xxxx\n";
+   double lat_ = 0.0, lon_ = 0.0, altitude = 0.0 , heading = 0.0, pitch = 0.0, roll = 0.0;
+   ossimString command = a.command();
+   bool aircraft = false;
+   const ossimPlanetXmlAction* xmlAction = a.toXmlAction();
+   ossimXmlNode* lookFromNode = 0;
+
+   if(xmlAction)
+   {
+      const ossimXmlNode::ChildListType& children = xmlAction->xmlNode()->getChildNodes();
+      if(command == "Set")
+      {
+         	ossim_uint32 idx = 0;
+            for(;idx < children.size();++idx)
+            {
+            	if(children[idx]->getTag() == "LookFrom")
+               {
+         			ossimRefPtr<ossimXmlNode> node = children[idx];
+         			lookFromNode = (ossimXmlNode *)node->getChildNodes()[0].get();
+         			break;
+         		}
+         	}
+       }
+   }
+	if(lookFromNode)
+	{
+      extractLookFromParameters(lookFromNode,lat_,lon_,altitude,heading,pitch,roll);
+
+      viewMatrixBuilder()->setLookFrom(osg::Vec3d(lat_, lon_, altitude), osg::Vec3d(heading,pitch, roll), 1);
+      theNavigator->setRedrawFlag(true);
+
+   	aircraft = true;
+
+	}
+if(aircraft == false)
+{
+	if(theNavigator.valid())
+	{
+
+		theNavigator->execute(a);
+	}
+}
+}
+ossimPlanetManipulator::~ossimPlanetManipulator()
+{
+}
+
+
+void ossimPlanetManipulator::setNode(osg::Node* node)
+{
+   theNode = node;
+
+   if(theNode.valid())
+   {
+      thePlanet = ossimPlanet::findPlanet(theNode.get());//finder.thePlanet;
+      if(theNavigator.valid())
+      {
+         if(thePlanet)
+         {
+            theViewMatrixBuilder->setGeoRefModel(thePlanet->model().get());
+         }
+         theNavigator->setPlanet(thePlanet);
+      }
+   }
+}
+
+
+const osg::Node* ossimPlanetManipulator::getNode() const
+{
+    return theNode.get();
+}
+
+
+osg::Node* ossimPlanetManipulator::getNode()
+{
+    return theNode.get();
+}
+
+
+void ossimPlanetManipulator::getLatLonHgtHPR(double& lat, double& lon, double& hgt,
+                                             double& heading, double& pitch, double& roll)const
+{
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   lat     = theNavigator->lat();
+   lon     = theNavigator->lon();
+   hgt     = theNavigator->elev();
+   heading = theNavigator->orientation()[0];
+   pitch   = theNavigator->orientation()[1];
+   roll    = theNavigator->orientation()[2];
+}
+
+void ossimPlanetManipulator::solveLookAt(double losLat, double losLon, double losHeight,
+                                         double& heading, double& pitch, double& roll, double& range)const
+
+{
+   theNavigator->solveLookAt(losLat, losLon, losHeight, heading, pitch, roll, range);
+}
+
+void ossimPlanetManipulator::playRecording()
+{
+   theNavigator->playRecording();
+}
+
+void ossimPlanetManipulator::startRecording()
+{
+   theNavigator->startRecording();
+}
+
+void ossimPlanetManipulator::stopRecording()
+{
+   theNavigator->stopRecording();
+}
+
+void ossimPlanetManipulator::saveRecording(std::ostream& out)
+{
+   theNavigator->saveRecording(out);
+}
+
+bool ossimPlanetManipulator::loadRecording(std::istream& in)
+{
+   return theNavigator->loadRecording(in);
+}
+
+void ossimPlanetManipulator::setEventHandlingFlag(bool flag)
+{
+   theEventHandlingFlag = flag;
+}
+
+void ossimPlanetManipulator::setUseFrameEventForUpdateFlag(bool flag)
+{
+   theUseFrameEventForUpdateFlag = flag;
+   if(flag)
+   {
+      theNavigator->setUseTimedUpdateFlag(false);
+   }
+   else
+   {
+      theNavigator->setUseTimedUpdateFlag(true);
+   }
+}
+
+void ossimPlanetManipulator::setAutoCalculateIntersectionFlag(bool flag)
+{
+   theAutoCalculateIntersectionFlag = flag;
+}
+
+void ossimPlanetManipulator::setLosXYZ(const osg::Vec3d& losXYZ)
+{
+   if(theNavigator->canSetLineOfSite())
+   {
+      theNavigator->setLosXYZ(losXYZ);
+   }
+}
+
+void ossimPlanetManipulator::init(const GUIEventAdapter& ,GUIActionAdapter&)
+{
+}
+
+void ossimPlanetManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
+{
+   ossimPlanetDestinationCommandAction(":navigator reset").execute();
+   us.requestRedraw();
+}
+
+bool ossimPlanetManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
+{
+  updateViewMatrixNodes();
+    // XXX most of this belongs in ossimPlanetQT.
+   if(!theEventHandlingFlag)
+   {
+      return false;
+   }
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+
+   ossimString modKeyString;
+
+   if(ea.getModKeyMask() & GUIEventAdapter::MODKEY_SHIFT)
+   {
+      modKeyString += "shift_";
+   }
+   if(ea.getModKeyMask() & GUIEventAdapter::MODKEY_CTRL)
+   {
+      modKeyString += "ctrl_";
+   }
+   if(ea.getModKeyMask() & GUIEventAdapter::MODKEY_ALT)
+   {
+      modKeyString += "alt_";
+   }
+   if(ea.getModKeyMask() & GUIEventAdapter::MODKEY_META)
+   {
+      modKeyString += "meta_";
+   }
+   switch(ea.getEventType())
+   {
+      case GUIEventAdapter::FRAME:
+      {
+         osg::Vec3d pt;
+         bool validLos = calculateLineOfSiteLatLonHeight(pt);
+
+         if(validLos)//&&theNavigator->canSetLineOfSite()&&theNavigator->landModel().valid())
+         {
+            osg::Vec3d ptXYZ;
+            theNavigator->landModel()->forward(pt, ptXYZ);
+            theNavigator->setLosXYZ(ptXYZ);
+
+         }
+
+         if(theUseFrameEventForUpdateFlag)
+         {
+            if(theNavigator->needsContinuousUpdate()||theNavigator->redrawFlag())
+            {
+               theNavigator->update();
+            }
+         }
+
+         break;
+      }
+      case GUIEventAdapter::PUSH:
+      {
+         switch(ea.getButton())
+         {
+            case GUIEventAdapter::LEFT_MOUSE_BUTTON:
+            {
+               iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+               iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+               iac->executeBoundAction((modKeyString + "left_mousedown").c_str());
+               break;
+            }
+            case GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
+            {
+               iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+               iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+               iac->executeBoundAction((modKeyString + "middle_mousedown").c_str());
+               break;
+            }
+            case GUIEventAdapter::RIGHT_MOUSE_BUTTON:
+            {
+               iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+               iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+               iac->executeBoundAction((modKeyString + "right_mousedown").c_str());
+               break;
+            }
+         }
+         break;
+      }
+      case GUIEventAdapter::DOUBLECLICK:
+      {
+         switch(ea.getButton())
+         {
+            case GUIEventAdapter::LEFT_MOUSE_BUTTON:
+            {
+               break;
+            }
+            case GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
+            {
+               break;
+            }
+            case GUIEventAdapter::RIGHT_MOUSE_BUTTON:
+            {
+               break;
+            }
+         }
+      }
+      case GUIEventAdapter::RELEASE:
+      {
+         switch(ea.getButton())
+         {
+            case GUIEventAdapter::LEFT_MOUSE_BUTTON:
+            {
+               iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+               iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+               iac->executeBoundAction((modKeyString + "left_mouseup").c_str());
+               break;
+            }
+            case GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
+            {
+               iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+               iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+               iac->executeBoundAction((modKeyString + "middle_mouseup").c_str());
+              break;
+            }
+            case GUIEventAdapter::RIGHT_MOUSE_BUTTON:
+            {
+                iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+                iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+                iac->executeBoundAction((modKeyString + "right_mouseup").c_str());
+               break;
+            }
+         }
+         break;
+      }
+      case GUIEventAdapter::SCROLL:
+      {
+         switch(ea.getScrollingMotion())
+         {
+            case GUIEventAdapter::SCROLL_RIGHT:
+            {
+                ossimString s ="scroll_right";
+                s = modKeyString + s;
+                iac->executeBoundAction(s);
+               break;
+            }
+
+            case GUIEventAdapter::SCROLL_LEFT:
+            {
+               ossimString s ="scroll_left";
+               s = modKeyString + s;
+               iac->executeBoundAction(s);
+               break;
+            }
+            case GUIEventAdapter::SCROLL_UP:
+            {
+               break;
+            }
+            case GUIEventAdapter::SCROLL_DOWN:
+            {
+               break;
+            }
+            default:
+            {
+               break;
+            }
+         }
+         break;
+      }
+//      case GUIEventAdapter::MOVE:
+      case GUIEventAdapter::DRAG:
+      {
+         iac->updateInteractionValuators("x_mouse", ea.getXnormalized());
+         iac->updateInteractionValuators("y_mouse", ea.getYnormalized());
+         break;
+      }
+      case GUIEventAdapter::KEYDOWN:
+      {
+         ossimString s;
+         switch(ea.getKey())
+         {
+            case osgGA::GUIEventAdapter::KEY_Up:
+            {
+               us.requestRedraw();
+               s += "up";
+               break;
+            }
+            case osgGA::GUIEventAdapter::KEY_Down:
+            {
+               us.requestRedraw();
+
+               s += "down";
+               break;
+            }
+            case osgGA::GUIEventAdapter::KEY_Left:
+            {
+               us.requestRedraw();
+               s += "left";
+               break;
+            }
+            case osgGA::GUIEventAdapter::KEY_Right:
+            {
+               us.requestRedraw();
+               s += "right";
+               break;
+            }
+            case osgGA::GUIEventAdapter::KEY_Return:
+            {
+               s += "return";
+               us.requestRedraw();
+               break;
+            }
+            case ' ':
+            {
+               s+= "space";
+               us.requestRedraw();
+               break;
+            }
+            default:
+            {
+               s += (char)ea.getKey();
+               break;
+            }
+         }
+         if(s != "")
+         {
+            s+="_key";
+            modKeyString = modKeyString.substitute("shift_",
+                                                   "");
+            s = modKeyString + s;
+            iac->executeBoundAction(s);
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   if(theNavigator->needsContinuousUpdate())
+   {
+      us.requestRedraw();
+   }
+   if(theNavigator->redrawFlag())
+   {
+      us.requestRedraw();
+      theNavigator->setRedrawFlag(false);
+   }
+   if(!theUseFrameEventForUpdateFlag)
+   {
+      if(theNavigator->needsContinuousUpdate()||theNavigator->redrawFlag())
+      {
+         theNavigator->update();
+      }
+   }
+
+   return false;
+}
+
+void ossimPlanetManipulator::getUsage(osg::ApplicationUsage& /*usage*/) const
+{
+}
+
+void ossimPlanetManipulator::setLockToNode(osg::Node* node)
+{
+   theLockToNode = node;
+}
+
+void ossimPlanetManipulator::updateViewMatrixNodes()
+{
+  if(theViewMatrixBuilder->fromNode()!=theLockFromNode.get())
+  {
+     ossimPlanetViewMatrixBuilder::Visitor nv;
+     if(theLockFromNode.valid())
+     {
+        theLockFromNode->accept(nv);
+        if(nv.theLsrSpaceTransform.valid())
+        {
+           nv.theLsrSpaceTransform->removeCallback(theFromNodeCallback.get());
+        }
+     }
+     nv.reset();
+     // setup from node
+     //
+     theLockFromNode = theViewMatrixBuilder->fromNode();
+     if(theLockFromNode.valid())
+     {
+        theLockFromNode->accept(nv);
+        if(nv.theLsrSpaceTransform.valid())
+        {
+           nv.theLsrSpaceTransform->addCallback(theFromNodeCallback.get());
+        }
+        else
+        {
+           theLockFromNode = 0;
+        }
+     }
+  }
+  if(theViewMatrixBuilder->toNode()!=theLockToNode.get())
+  {
+     ossimPlanetViewMatrixBuilder::Visitor nv;
+     if(theLockToNode.valid())
+     {
+        theLockToNode->accept(nv);
+        if(nv.theLsrSpaceTransform.valid())
+        {
+           nv.theLsrSpaceTransform->removeCallback(theToNodeCallback.get());
+        }
+     }
+     nv.reset();
+     // setup from node
+     //
+     theLockToNode = theViewMatrixBuilder->toNode();
+     if(theLockToNode.valid())
+     {
+        theLockToNode->accept(nv);
+        if(nv.theLsrSpaceTransform.valid())
+        {
+           nv.theLsrSpaceTransform->addCallback(theToNodeCallback.get());
+        }
+        else
+        {
+           theLockToNode = 0;
+        }
+     }
+  }
+}
+
+bool ossimPlanetManipulator::calculateLineOfSiteLatLonHeight(osg::Vec3d& latLonHeight)
+{
+   bool hitFound = false;
+   if(theNode.valid()&&theNavigator->landModel())
+   {
+      osg::Matrixd m = getMatrix();
+
+      osg::BoundingSphere bs = theNode->getBound();
+      osgUtil::IntersectVisitor iv;
+
+      osg::Vec3d center;
+      osg::Vec3d look(- m(2,0),-m(2,1),-m(2,2));
+      osg::Vec3d eye(m(3,0),m(3,1),m(3,2));
+
+      center = eye + look*100.0;
+
+      osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
+      segLookVector->set(eye, center);
+      iv.addLineSegment(segLookVector.get());
+
+      theNode->accept(iv);
+      if (iv.hits())
+      {
+         osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
+         if (!hitList.empty())
+         {
+            osg::Vec3d intersection = hitList.front().getWorldIntersectPoint();
+
+            theNavigator->landModel()->inverse(intersection, latLonHeight);
+            hitFound = true;
+	    theFusionDistance = (eye-intersection).length();
+         }
+      }
+
+   }
+   return hitFound;
+}
+
+void ossimPlanetManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+//     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+    osg::Matrixd m;
+    m.invert(matrix);
+    if (!theNavigator->landModel().valid())
+        ossimPlanetDestinationCommandAction(":navigator reset").execute();
+    else
+        theNavigator->setViewParameters(m);
+}
+
+osg::Matrixd ossimPlanetManipulator::getMatrix() const
+{
+  if(theViewMatrixBuilder->isValid())
+  {
+      theNavigator->setViewParameters(theViewMatrixBuilder->viewMatrix());
+//std::cout << "theViewMatrixBuilder->viewMatrix()" << std::endl;
+      return theViewMatrixBuilder->viewMatrix();
+   }
+   else
+   {
+//std::cout << "theNavigator->viewMatrix()" << std::endl;
+      return theNavigator->viewMatrix();
+  }
+}
+
+osg::Matrixd ossimPlanetManipulator::getInverseMatrix() const
+{
+   if(theViewMatrixBuilder->isValid())
+   {
+      return theViewMatrixBuilder->inverseViewMatrix();
+   }
+   else
+   {
+      return osg::Matrix::inverse(theNavigator->viewMatrix());
+   }
+}
+
+osg::Vec3d ossimPlanetManipulator::eyePosition()const
+{
+   if(theViewMatrixBuilder->isValid())
+   {
+      osg::Vec3d(0,0,0)*theViewMatrixBuilder->viewMatrix();
+   }
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   return osg::Vec3d(0,0,0)*theNavigator->viewMatrix();
+}
+
+void ossimPlanetManipulator::updateNavigator()
+{
+    theNavigator->update();
+}
+
+void ossimPlanetManipulator::setLatitude(double value)
+{
+   theNavigator->setLatLonHeight(value, theNavigator->lon(), theNavigator->elev());
+}
+
+void ossimPlanetManipulator::setLongitude(double value)
+{
+   theNavigator->setLatLonHeight(theNavigator->lat(), value, theNavigator->elev());
+}
+
+void ossimPlanetManipulator::setAltitude(double value)
+{
+   theNavigator->setLatLonHeight(theNavigator->lat(), theNavigator->lon(), value);
+}
+
+void ossimPlanetManipulator::setLatitudeLongitudeAltitude(double lat, double lon, double alt)
+{
+   theNavigator->setLatLonHeight(lat, lon, alt);
+}
+
+void ossimPlanetManipulator::setPosition(const osg::Vec3d& pos)
+{
+   theNavigator->setLatLonHeight(pos[0], pos[1], pos[2]);
+}
+
+void ossimPlanetManipulator::setHeading(double value)
+{
+   theNavigator->setHpr(value, theNavigator->orientation()[1], theNavigator->orientation()[2]);
+}
+
+void ossimPlanetManipulator::setPitch(double value)
+{
+   theNavigator->setHpr(theNavigator->orientation()[0], value, theNavigator->orientation()[2]);
+}
+
+void ossimPlanetManipulator::setRoll(double value)
+{
+   theNavigator->setHpr(theNavigator->orientation()[0], theNavigator->orientation()[1], value);
+}
+
+void ossimPlanetManipulator::setHeadingPitchRoll(double h, double p, double r)
+{
+   theNavigator->setHpr(h, p, r);
+}
+
+void ossimPlanetManipulator::setOrientation(const osg::Vec3d& orien)
+{
+   theNavigator->setHpr(orien[0], orien[1], orien[2]);
+}
+
+void ossimPlanetManipulator::setPositionAndOrientation(double lat, double lon, double alt,
+                                                       double h, double p, double r)
+{
+   theNavigator->setLatLonHeight(lat, lon, alt);
+   theNavigator->setHpr(h, p, r);
+}
+
+void ossimPlanetManipulator::setPositionAndOrientation(const osg::Vec3d& pos,
+                                                       const osg::Vec3d& orien)
+{
+   theNavigator->setLatLonHeight(pos[0], pos[1], pos[2]);
+   theNavigator->setHpr(orien[0], orien[1], orien[2]);
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetNavigator.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetNavigator.cpp
new file mode 100644
index 0000000..2e71615
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetNavigator.cpp
@@ -0,0 +1,1460 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <math.h>
+#include <osg/Quat>
+#include <osg/Timer>
+#include <osg/io_utils>
+#include <ossim/base/ossimString.h>
+#include <ossimPlanet/ossimPlanetNavigator.h>
+#include <ossimPlanet/ossimPlanetPrimaryBody.h>
+#include <ossimPlanet/ossimPlanetInteractionController.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetActionRouter.h>
+
+static inline void adjustHeight(osg::Vec3d& input,
+										  ossimPlanetAltitudeMode mode,
+										  ossimPlanetGeoRefModel* modelTransform)
+{
+	switch(mode)
+	{
+		case ossimPlanetAltitudeMode_CLAMP_TO_GROUND:
+		{
+			input[2] = modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+		case ossimPlanetAltitudeMode_RELATIVE_TO_GROUND:
+		{
+			input[2]+=modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+		case ossimPlanetAltitudeMode_ABSOLUTE:
+		{
+			input[2] += modelTransform->getGeoidOffset(input[0], input[2]);
+			break;
+		}
+		default:
+		{
+			input[2] = modelTransform->getHeightAboveEllipsoid(input[0], input[1]);
+			break;
+		}
+	}
+}
+
+ossimPlanetNavigator::ossimPlanetNavigator(osg::ref_ptr<ossimPlanetPrimaryBody> p) :
+    pitchOffset_(0.0),
+    lat_(0.0),
+    lon_(-90.0),
+    zoomMin_(-4.2),         // earth about fills the screen here
+    fov_(50),
+    primary_(p),
+    rotating_(false),
+    zooming_(false),
+    zoominglos_(false),
+    looking_(false),
+    endLooking_(false),
+    gotoing_(false),
+    gotoingelev_(false),
+    gotoset_(false),
+    flying_(false),
+    losLookingFlag_(false),
+    losXYZValidFlag_(false),
+    updateRatePerSecond_(120),
+    lastUpdateTime_(osg::Timer::instance()->tick()),
+    gotoLookDuration_(4.0),
+    xFly_(0.0),
+    yFly_(0.0),
+    theAnimationMode(ossimPlanetNavigator::NAV_ANIMATION_NONE),
+    theAnimationPath(new osg::AnimationPath)
+{
+   thePlanet = 0;
+
+    // earth is above us, eliminates gimbal lock in looking.
+    eyexyz_.set(0.0, 0.0, zoomMin_);        // all the way out
+    eyehpr_.set(0.0, pitchOffset_, 0.0);    // looking down (up in pf coords) at earth
+    theUseTimedUpdateFlag = false;
+   setRedrawFlag(true);
+}
+
+ossimPlanetNavigator::~ossimPlanetNavigator()
+{
+}
+
+osg::Matrixd ossimPlanetNavigator::orientationLsrMatrix(double lat, double lon, double hgt, double h, double p, double r) const
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(!model.valid()) return osg::Matrixd();
+   osg::Matrixd output;
+   model->lsrMatrix(osg::Vec3d(lat, lon, hgt),
+                           output);
+   output(3,0) = 0.0;
+   output(3,1) = 0.0;
+   output(3,2) = 0.0;
+
+
+   NEWMAT::Matrix orien = ossimMatrix4x4::createRotationZMatrix(h, OSSIM_RIGHT_HANDED)*
+                          ossimMatrix4x4::createRotationXMatrix(p-pitchOffset(), OSSIM_LEFT_HANDED)*
+                          ossimMatrix4x4::createRotationYMatrix(r, OSSIM_LEFT_HANDED);
+   osg::Matrixd tempM(orien[0][0], orien[1][0], orien[2][0], 0.0,
+                      orien[0][1], orien[1][1], orien[2][1], 0.0,
+                      orien[0][2], orien[1][2], orien[2][2], 0.0,
+                      0.0, 0.0, 0.0, 1.0);
+
+   return tempM*output;
+}
+
+void ossimPlanetNavigator::setLatLonHeight(double lat, double lon, double height)
+{
+    lat_ = lat;
+    lon_ = lon;
+    eyexyz_.z() = ossim::clamp(-(1.0 + (height/primary_->radius(lat_))), zoomMin_, zoomMax_);
+}
+void ossimPlanetNavigator::setHpr(double h, double p, double r)
+{
+   eyehpr_.set(h,p,r);
+}
+
+double ossimPlanetNavigator::metersToCenter() const
+{
+    return -eyexyz_.z()*primary_->radius(lat());
+}
+
+void ossimPlanetNavigator::update()
+{
+    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(!model.valid()) return;
+    // cache initial values, we need them at the end to update idol
+    //double oldLat(lat()), oldLon(lon()), oldElev(elev());
+    //bool oldGotoing(gotoing_);
+
+    // get current logical valuators
+    ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+    float inputLat = iac->interactionValuatorValue("LAT") - baseInputLat_;
+    float inputLon = iac->interactionValuatorValue("LON") - baseInputLon_;
+    float inputZoom = iac->interactionValuatorValue("ZOOM") - baseInputZoom_;
+    float inputYaw = iac->interactionValuatorValue("YAW") - baseInputYaw_;
+    float inputPitch = iac->interactionValuatorValue("PITCH") - baseInputPitch_;
+	bool canUpdateNonTimedUpdates = true;
+	if(theUseTimedUpdateFlag)
+	{
+		double delta = osg::Timer::instance()->delta_s(lastUpdateTime_, osg::Timer::instance()->tick());
+		if(delta < 0.0)
+		{
+			// bad time tick so reset
+			lastUpdateTime_ = osg::Timer::instance()->tick();
+			return;
+		}
+		canUpdateNonTimedUpdates = (delta > (1.0/updateRatePerSecond_));
+	}
+#if 1
+    if (theAnimationMode == NAV_ANIMATION_PLAYBACK)
+    {
+
+        if (!rotating_ && !zooming_ && !losLookingFlag_ && !zoominglos_ && !flying_)
+        {
+            double t = osg::Timer::instance()->delta_s( theAnimationStartTime, osg::Timer::instance()->tick());
+            if (t >= 0.0)
+            {
+                osg::Matrixd m;
+                if (theAnimationPath->getMatrix(t, m))
+                {
+                    setViewParameters(m);
+                    return;
+                }
+                else
+                {
+                    theAnimationMode = NAV_ANIMATION_NONE;
+                }
+            }
+			  else
+			  {
+				  theAnimationStartTime = osg::Timer::instance()->tick();// need to reset the timer since went negative
+			  }
+        }
+        else
+        {
+            theAnimationMode = NAV_ANIMATION_NONE;
+        }
+    }
+#endif
+
+    if (canUpdateNonTimedUpdates)
+    {
+        lastUpdateTime_ = osg::Timer::instance()->tick();
+    }
+    if (zoominglos_ && losXYZValidFlag_ && model.valid())
+    {
+
+        osg::Matrixd eyeLsrMatrix = viewMatrix();
+        osg::Vec3d eye(eyeLsrMatrix(3,0), eyeLsrMatrix(3,1), eyeLsrMatrix(3,2));
+        osg::Vec3d posXYZ;
+        osg::Vec3d posLlh;
+        osg::Vec3d tempHpr;
+        osg::Vec3d deltaV = eye-losXYZ_;  //losXYZ-eye;
+        double distanceCurrent = deltaV.length();
+        double minDistance = 64.0/model->getNormalizationScale();
+        double distance = distanceCurrent + distanceCurrent*0.1*inputZoom;
+
+        if (distance < minDistance)
+        {
+            distance = minDistance;
+        }
+        deltaV.normalize();
+
+        posXYZ = losXYZ_ + deltaV*distance;
+
+        model->inverse(posXYZ, posLlh);
+
+        setLatLonHeight(posLlh[0], posLlh[1], posLlh[2]);//*model->getNormalizationScale());
+            osg::Matrixd localLsr;
+        model->lsrMatrix(posLlh, localLsr);
+
+        mkUtils::matrixToHpr(tempHpr, localLsr, eyeLsrMatrix);
+        eyehpr_ = tempHpr;
+        eyehpr_[2] = 0.0;
+        eyehpr_[0] = ossim::clamp(eyehpr_[0] , -180.0, 180.0);
+        eyehpr_[1] = ossim::clamp(eyehpr_[1] , 0.0, 180.0);
+    }
+    if (losLookingFlag_ && losXYZValidFlag_ && model.valid())
+    {
+        if (canUpdateNonTimedUpdates)
+        {
+
+            osg::Matrixd eyeLsrMatrix = viewMatrix();
+            osg::Vec3d eye(eyeLsrMatrix(3,0), eyeLsrMatrix(3,1), eyeLsrMatrix(3,2));
+            double distance = (losXYZ_ - eye).length();
+            eyeLsrMatrix(3,0) = 0.0;
+            eyeLsrMatrix(3,1) = 0.0;
+            eyeLsrMatrix(3,2) = 0.0;
+
+            double rotationZAmount = inputYaw*(10*M_PI/180.0);
+            double rotationPitchAmount = inputPitch*(10*M_PI/180.0);
+            // osg::Vec3d xn = osg::Vec3d(1.0, 0.0, 0.0);
+            osg::Vec3d zn = losXYZ_;
+            zn.normalize();
+            osg::Matrixd r = osg::Matrix::rotate(rotationZAmount, zn);
+            eyeLsrMatrix = eyeLsrMatrix*r;
+
+            eyeLsrMatrix = eyeLsrMatrix*osg::Matrix::rotate(rotationPitchAmount, osg::Vec3d(eyeLsrMatrix(0,0),
+                                                                                            eyeLsrMatrix(0,1),
+                                                                                            eyeLsrMatrix(0,2)));
+            osg::Vec3d newPoint = losXYZ_ + osg::Vec3d(eyeLsrMatrix(2, 0), eyeLsrMatrix(2, 1), eyeLsrMatrix(2, 2))*distance;
+            osg::Vec3d eyeLlh;
+            model->inverse(newPoint, eyeLlh);
+            setLatLonHeight(eyeLlh[0],
+                            eyeLlh[1],
+                            eyeLlh[2]);//*model->getNormalizationScale());
+
+                osg::Matrixd tempView = viewMatrix();
+            osg::Matrixd localLsr;
+            model->lsrMatrix(eyeLlh, localLsr);
+            osg::Vec3d tempHpr;
+            mkUtils::matrixToHpr(tempHpr, localLsr, eyeLsrMatrix);
+
+            eyehpr_[0] = ossim::clamp(tempHpr[0] , -180.0, 180.0);
+            eyehpr_[1] = ossim::clamp(tempHpr[1] , 0.0, 90.0);
+            eyehpr_[2] = 0.0;
+            // eyehpr_[2] = mkUtils::clamp(eyehpr_[2] , -180.0, 180.0);
+       }
+    }
+    if (flying_)
+    {
+        if (ossim::almostEqual(xFly_, 0.0) &&  ossim::almostEqual(yFly_, 0.0))
+        {
+            flying_ = false;
+        }
+        else if (canUpdateNonTimedUpdates)
+        {
+            float x = osg::DegreesToRadians(eyehpr_[0]);
+            float s = sin(x);
+            float c = cos(x);
+
+            updateLatLon(xFly_*c + yFly_*s, -xFly_*s + yFly_*c);
+            // updateLatLon(-xFly_*c + yFly_*s, xFly_*s - yFly_*c);
+        }
+    }
+    if (rotating_ && canUpdateNonTimedUpdates)
+    {
+        float x = osg::DegreesToRadians((eyehpr_[0]));// - 90.0));
+        float s = sin(x);
+        float c = cos(x);
+        updateLatLon(inputLon*c + inputLat*s, -inputLon*s + inputLat*c);
+        //  updateLatLon(xMouse*c - yMouse*s, xMouse*s + yMouse*c);
+        //  updateLatLon(xMouse, yMouse);
+        gotoing_ = false;
+        gotoset_ = false;
+        gotoingelev_ = false;
+    }
+
+    updateZoomParameters();
+
+    if (zooming_ && canUpdateNonTimedUpdates) {
+        double magic = 0.1;
+        eyexyz_.z() = ossim::clamp(eyexyz_.z() + zoomScaleInput(inputZoom)*magic, zoomMin_, zoomMax_);
+        // manual zoom neutralizes the zoom of any gotoing that we might be doing right now
+        targetStartLookZ_ = eyexyz_.z();
+        targetMidpointLookZ_ = eyexyz_.z();
+        targetLookZ_ = eyexyz_.z();
+    }
+    if (looking_ && canUpdateNonTimedUpdates)
+    {
+        double magic = 5.0;
+        eyehpr_[0] = ossim::wrap(eyehpr_[0] - inputYaw*fabsf(inputYaw)*magic, -180.0, 180.0);
+        eyehpr_[1] = ossim::clamp(eyehpr_[1] + inputPitch*fabsf(inputPitch)*magic, 0.0, 180.0);
+    }
+
+    if (gotoing_)
+    {
+        gotoingelev_ = false;
+        double delta = (osg::Timer::instance()->delta_s(gotoStartTime_, osg::Timer::instance()->tick())) / gotoLookDuration_;
+        if((delta < 1.0)&&(delta >= 0.0))
+        {
+            lon_ = ossim::lerp(delta, targetStartLon_, targetLon_);
+            lat_ = ossim::lerp(delta, targetStartLat_, targetLat_);
+            eyexyz_.z() = mkUtils::quaderp(delta, targetStartLookZ_, targetMidpointLookZ_, targetLookZ_);
+            eyehpr_[0] = ossim::lerp(delta, targetStartLookH_, targetLookH_);
+            //           eyehpr_[1] = mkUtils::lerp(delta, targetStartLookP_, targetLookP_);
+            eyehpr_[1] = mkUtils::quaderp(delta, targetStartLookP_, 0.0, targetLookP_);
+            eyehpr_[2] = ossim::lerp(delta, targetStartLookR_, targetLookR_);
+        }
+        else
+        {
+            lon_ = targetLon_;
+            lat_ = targetLat_;
+            eyexyz_.z() = targetLookZ_;
+            eyehpr_[0] = targetLookH_;
+            eyehpr_[1] = targetLookP_;
+            eyehpr_[2] = targetLookR_;
+            gotoing_    = false;
+        }
+    }
+#if 1
+    if (theAnimationMode == NAV_ANIMATION_RECORDING)
+    {
+        osg::Matrixd m = viewMatrix();
+        osg::Vec3d eye(m(3,0), m(3,1), m(3,2));
+        osg::Vec3d orient = orientation();
+        if (theAnimationPath->empty())
+        {
+            osg::Quat quat = m.getRotate();
+            osg::AnimationPath::ControlPoint cp(eye, quat);
+
+            theLastAnimationParameter.quat = quat;
+            theLastAnimationParameter.orientation = orient;
+            theLastAnimationParameter.eye = eye;
+            theAnimationPath->insert(0.0, cp);
+
+        }
+        else if (!ossim::almostEqual(eye[0], theLastAnimationParameter.eye[0]) ||
+                 !ossim::almostEqual(eye[1], theLastAnimationParameter.eye[1]) ||
+                 !ossim::almostEqual(eye[2], theLastAnimationParameter.eye[2]) ||
+                 !ossim::almostEqual(orient[0], theLastAnimationParameter.orientation[0]) ||
+                 !ossim::almostEqual(orient[1], theLastAnimationParameter.orientation[1]) ||
+                 !ossim::almostEqual(orient[2], theLastAnimationParameter.orientation[2]))
+        {
+            theAnimationPath->insert(osg::Timer::instance()->delta_s(theAnimationStartTime, osg::Timer::instance()->tick()),
+                                     osg::AnimationPath::ControlPoint(theLastAnimationParameter.eye,
+                                                                      theLastAnimationParameter.quat));
+
+            osg::Quat quat = m.getRotate();
+            osg::AnimationPath::ControlPoint cp(eye, quat);
+
+            theLastAnimationParameter.quat = quat;
+            theLastAnimationParameter.orientation = orient;
+            theLastAnimationParameter.eye = eye;
+            theAnimationPath->insert(osg::Timer::instance()->delta_s(theAnimationStartTime, osg::Timer::instance()->tick()), cp);
+        }
+    }
+#endif
+#if 0
+    // if our lat/lon/elev has changed, send it to the IDOL Browser Agent.
+    // note that "idolfederation" is a totally ad hoc name.
+    // XXX there should be a flag that determines if we should output this or not?
+    if (!oldGotoing && !gotoing_ && (oldLat != lat() || oldLon != lon() || oldElev != elev())) {
+        std::ostringstream out;
+        out.precision(16);
+        out << ":idolbridge gotolatlonelev " << lat() << " " << lon() << " " << elev();
+        ossimPlanetAction(out.str()).allExecute();
+    }
+#endif
+}
+
+osg::Vec3d ossimPlanetNavigator::centerOfInterest() const
+{
+    if (!gotoing_)
+        return osg::Vec3d(lat_, lon_, elev());
+    else
+        return osg::Vec3d(targetLat_, targetLon_, -targetLookZ_*primary_->equatorialRadius());
+}
+
+void ossimPlanetNavigator::updateZoomParameters()
+{
+    double r = primary_->radius(lat_)/primary_->equatorialRadius();
+    zoomMin_ = -4.2;         // earth about fills the screen here
+    zoomMax_ = 0.0; //  we will need to let current intersection of Line of site handle this if we could
+//     zoomMax_ = -1.000001*r;  // close enough
+    zoomScaleBaseline_ = r;
+
+    eyexyz_.z() = ossim::clamp(eyexyz_.z(), zoomMin_, zoomMax_);
+}
+
+void ossimPlanetNavigator::setViewParameters(const osg::Matrixd& m)
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model=landModel();
+   if (model.valid())
+   {
+      osg::Matrixd tempM;
+      osg::Vec3d translation;
+      osg::Vec3d scale;
+      osg::Quat rotation;
+      osg::Quat s;
+      osg::Vec3d latLonHeight;
+      osg::Vec3d hpr;
+      // deomcpose some of the parts we need
+      //
+      m.decompose(translation, rotation, scale, s);
+      model->inverse(translation, latLonHeight);
+      model->lsrMatrix(latLonHeight, tempM);
+      mkUtils::matrixToHpr(eyehpr_, tempM, m);
+      //std::cout << "HPR mkutils = " << eyehpr_ << std::endl;
+      setLatLonHeight(latLonHeight[0],
+                      latLonHeight[1],
+                      latLonHeight[2]);
+   }
+}
+
+void ossimPlanetNavigator::extractCameraParameters(ossimRefPtr<ossimXmlNode> node,
+                                                   double& lat,
+                                                   double& lon,
+                                                   double& alt,
+                                                   double& h,
+                                                   double& p,
+                                                   double& r)const
+{
+	osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   ossimString vref = node->getAttributeValue("vref");
+   ossimString value;
+   lat = lat_;
+   lon = lon_;
+   alt = elev();
+   h = eyehpr_[0];
+   p = eyehpr_[1];
+   r = eyehpr_[2];
+
+   if(node->getChildTextValue(value, "longitude"))
+   {
+      lon = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "latitude"))
+   {
+      lat = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "altitude"))
+   {
+      alt = value.toDouble();
+      if(node->getChildTextValue(value, "altitudeMode"))
+      {
+         if(value.contains("relative"))
+         {
+            alt += model->getHeightAboveEllipsoid(lat, lon);
+         }
+         else if(value.contains("clamp"))
+         {
+            alt = model->getHeightAboveEllipsoid(lat, lon);
+         }
+         else if(value.contains("absolute"))
+         {
+            if(vref!="wgs84")
+            {
+               alt += model->getGeoidOffset(lat, lon);
+            }
+         }
+      }
+   }
+   if(node->getChildTextValue(value, "heading"))
+   {
+      h = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "pitch"))
+   {
+      p = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "roll"))
+   {
+      r = value.toDouble();
+   }
+}
+
+void ossimPlanetNavigator::extractLookAtParameters(ossimRefPtr<ossimXmlNode> node,
+                                                   ossimPlanetLookAt& look)const
+{
+	osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   double lat=0.0;
+   double lon=0.0;
+   double altitude=0.0;
+   double h=0.0;
+   double p=0.0;
+   double r=0.0;
+   double range=0.0;
+   ossimString value;
+   ossimString vref = node->getAttributeValue("vref");
+   // solve current view as a lookat
+   solveLookAt(lat, lon, altitude, h, p, r, range);
+
+   if(node->getChildTextValue(value, "longitude"))
+   {
+      lon = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "latitude"))
+   {
+      lat = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "altitude"))
+   {
+      altitude = value.toDouble();
+      if(node->getChildTextValue(value, "altitudeMode"))
+      {
+         if(value.contains("relative"))
+         {
+            altitude += model->getHeightAboveEllipsoid(lat, lon);
+         }
+         else if(value.contains("clamp"))
+         {
+            altitude = model->getHeightAboveEllipsoid(lat, lon);
+         }
+         else if(value.contains("absolute"))
+         {
+            if(vref!="wgs84")
+            {
+               altitude += model->getGeoidOffset(lat, lon);
+            }
+         }
+      }
+   }
+   if(node->getChildTextValue(value, "heading"))
+   {
+      h = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "pitch"))
+   {
+      p = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "roll"))
+   {
+      r = value.toDouble();
+   }
+   if(node->getChildTextValue(value, "range"))
+   {
+      range = value.toDouble();
+   }
+   look.setAll(lat, lon, altitude,
+               h, p, r,
+               range, ossimPlanetAltitudeMode_ABSOLUTE);
+}
+
+void ossimPlanetNavigator::xmlExecute(const ossimPlanetXmlAction& a)
+{
+	osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   ossimString command = a.command();
+   const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();
+	if(command == "Set")
+	{
+		ossim_uint32 idx = 0;
+		for(;idx < children.size();++idx)
+		{
+			if(children[idx]->getTag() == "Camera")
+			{
+            double altitude = 0.0;
+
+            // get the altitude vertical frame of reference: msl or wgs84
+				extractCameraParameters(children[idx],
+                                    lat_,
+                                    lon_,
+                                    altitude,
+                                    eyehpr_[0],
+                                    eyehpr_[1],
+                                    eyehpr_[2]);
+
+            targetLon_ = lon_;
+            targetLat_ = lat_;
+            eyexyz_.z() = ossim::clamp(-altitude/primary_->radius(targetLat_) - 1.0, zoomMin_, zoomMax_);
+            targetLookZ_      = eyexyz_.z();
+            targetStartLookZ_ = eyexyz_.z();
+            targetLookH_      = eyehpr_[0];
+            targetLookP_      = eyehpr_[1];
+            targetLookR_      = eyehpr_[2];
+				setRedrawFlag(true);
+			}
+			else if(children[idx]->getTag() == "LookAt")
+			{
+            osg::Vec3d llh;
+            osg::Vec3d hpr;
+            ossimPlanetLookAt look;
+            extractLookAtParameters(children[idx],
+                                    look);
+            solveEyeGivenLocalSpaceAndRange(llh, hpr, osg::Vec3d(look.lat(), look.lon(), look.altitude()), osg::Vec3d(look.heading(),look.pitch(),look.roll()), look.range());
+            lon_ = llh[1];
+            targetLon_ = llh[1];
+            lat_ = llh[0];
+            targetLat_ = llh[0];
+            eyexyz_.z() = ossim::clamp(-llh[2]/primary_->radius(targetLat_) - 1.0, zoomMin_, zoomMax_);
+            targetLookZ_      = eyexyz_.z();
+            targetStartLookZ_ = eyexyz_.z();
+            eyehpr_[0]   = hpr[0];
+            targetLookH_ = eyehpr_[0];
+            eyehpr_[1]   = hpr[1];
+            targetLookP_ = eyehpr_[1];
+            eyehpr_[2]   = hpr[2];
+            targetLookR_ = eyehpr_[2];
+				setRedrawFlag(true);
+			}
+		}
+	}
+	else if(command == "Get")
+	{
+	}
+	else if(command == "FlyTo")
+	{
+		ossim_uint32 idx = 0;
+		for(;idx < children.size();++idx)
+		{
+			if(children[idx]->getTag() == "Camera")
+			{
+            double lat=0.0,lon=0.0;
+            double altitude = 0.0;
+            double h=0.0,p=0.0,r=0.0;
+            // get the altitude vertical frame of reference: msl or wgs84
+            extractCameraParameters(children[idx],
+                                    lat,
+                                    lon,
+                                    altitude,
+                                    h,
+                                    p,
+                                    r);
+            gotoLatLonElevHpr("", lat, lon, altitude,
+                              h,
+                              p,
+                              r);
+
+            setRedrawFlag(true);
+         }
+			else if(children[idx]->getTag() == "LookAt")
+			{
+            ossimPlanetLookAt look;
+            extractLookAtParameters(children[idx],
+                                    look);
+            gotoLookAt(look);
+         }
+      }
+	}
+}
+
+void ossimPlanetNavigator::destinationCommandExecute(const ossimPlanetDestinationCommandAction& a)
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(!model.valid()) return;
+   ossimString command = a.command();
+	if ("rotatestart" == command)
+	{
+	   setRedrawFlag(true);
+		rotating_ = true;
+		ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+		if(!losLookingFlag_) // only upate if not been initialize by someone else
+		{
+			baseInputLon_ = iac->interactionValuatorValue("LON");
+			baseInputLat_ = iac->interactionValuatorValue("LAT");
+		}
+	}
+	else if ("recordanimation" == command)
+	{
+	   setRedrawFlag(true);
+		startRecording();
+	}
+	else if ("playanimation" == command)
+	{
+	   setRedrawFlag(true);
+		playRecording();
+	}
+	else if ("stopanimation" == command)
+	{
+	   setRedrawFlag(true);
+		stopRecording();
+	}
+	else if ("saveanimation" == command)
+	{
+		if (a.argCount() == 1)
+		{
+			std::ofstream outFile(a.arg(1).c_str());
+			std::ostringstream outString;
+			outFile << "<animationPath>";
+			theAnimationPath->write(outString);
+			ossimString tempString = ossimString(outString.str().c_str()).substitute("\n", " ", true);
+			outFile << tempString << "</animationPath>";
+		}
+		else
+		{
+			a.printError("bad argument count");
+		}
+	}
+	else if ("rotatestop" == command)
+	{
+	   setRedrawFlag(true);
+		rotating_ = false;
+	}
+	else if ("losrotatestart" == command)
+	{
+		ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+		//         if(!rotating_)
+		//         {
+		//            baseInputLon_ = iac->interactionValuatorValue("LON");
+		//            baseInputLat_ = iac->interactionValuatorValue("LAT");
+		//         }
+		if(!looking_)
+		{
+			baseInputYaw_ = iac->interactionValuatorValue("YAW");
+			baseInputPitch_ = iac->interactionValuatorValue("PITCH");
+		}
+		losLookingFlag_ = true;
+		losXYZValidFlag_ = false;
+	}
+	else if ("losrotatestop" == command)
+	{
+	   setRedrawFlag(true);
+		losLookingFlag_ = false;
+		losXYZValidFlag_ = false;
+	}
+	else if ("loszoomstart" == command)
+	{
+	   setRedrawFlag(true);
+		ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+		if(!zooming_)
+		{
+			baseInputZoom_ = iac->interactionValuatorValue("ZOOM");
+		}
+		losXYZValidFlag_ = false;
+		zoominglos_ = true;
+	}
+	else if ("loszoomstop" == command)
+	{
+	   setRedrawFlag(true);
+		zoominglos_ = false;
+		losXYZValidFlag_ = false;
+	}
+	else if ("zoomstart" == command)
+	{
+	   setRedrawFlag(true);
+		ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+		if(!zoominglos_)
+		{
+			baseInputZoom_ = iac->interactionValuatorValue("ZOOM");
+		}
+		losXYZValidFlag_ = false;
+		zooming_ = true;
+	}
+	else if ("zoomstop" == command)
+	{
+	   setRedrawFlag(true);
+		zooming_ = false;
+	}
+	else if ("lookstart" == command)
+	{
+	   setRedrawFlag(true);
+		looking_ = true;
+		endLooking_ = false;
+		ossimPlanetInteractionController* iac = ossimPlanetInteractionController::instance();
+		if(!losLookingFlag_)
+		{
+			baseInputYaw_ = iac->interactionValuatorValue("YAW");
+			baseInputPitch_ = iac->interactionValuatorValue("PITCH");
+		}
+	}
+	else if ("los" == command)
+	{
+		if (a.argCount() == 3)
+		{
+			if (a.arg(1) == "nan" || a.arg(2) == "nan" || a.arg(3) == "nan")
+			{
+				losXYZValidFlag_ = false;
+			}
+		}
+		else if (a.argCount() == 0)
+		{
+			losXYZValidFlag_ = false;
+		}
+		else
+		{
+			a.printError("bad argument count");
+		}
+	}
+
+	else if ("lookstop" == command)
+	{
+	   setRedrawFlag(true);
+		looking_ = false;
+		endLooking_ = true;
+		endLookingStartTime_ =         osg::Timer::instance()->tick();
+	}
+	else if ("flystart" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 2)
+		{
+			if (!flying_)
+			{
+				flying_ = true;
+				xFly_ = mkUtils::asDouble(a.arg(1));
+				yFly_ = mkUtils::asDouble(a.arg(2));
+			}
+			else
+			{
+				xFly_ += mkUtils::asDouble(a.arg(1));
+				yFly_ += mkUtils::asDouble(a.arg(2));
+			}
+		}
+		else
+		{
+			a.printError("bad argument count");
+		}
+	}
+	else if ("gotolookat" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 7)
+		{
+			ossimPlanetLookAt info;
+
+			info.setAll(mkUtils::asDouble(a.arg(1)),// lat
+							mkUtils::asDouble(a.arg(2)),// lon
+							mkUtils::asDouble(a.arg(3)),// altitude
+							mkUtils::asDouble(a.arg(4)),// heading
+							mkUtils::asDouble(a.arg(5)),// pitch
+							mkUtils::asDouble(a.arg(6)),// roll
+							mkUtils::asDouble(a.arg(7)) // range
+							);
+			gotoLookAt(info);
+		}
+		else if (a.argCount() == 8)
+		{
+			ossimPlanetLookAt info;
+
+			info.setAll(mkUtils::asDouble(a.arg(1)),// lat
+							mkUtils::asDouble(a.arg(2)),// lon
+							mkUtils::asDouble(a.arg(3)),// altitude
+							mkUtils::asDouble(a.arg(4)),// heading
+							mkUtils::asDouble(a.arg(5)),// pitch
+							mkUtils::asDouble(a.arg(6)),// roll
+							mkUtils::asDouble(a.arg(7)),// range
+							ossimPlanetLookAt::modeFromString(a.arg(8))); // mode
+			gotoLookAt(info);
+		}
+		else
+		{
+			a.printError("bad argument count, the syntax is gotolookat <lat> <lon> <altitude> <heading> <pitch> <roll> <range> <altitudeMode>");
+		}
+	}
+	else if ("gotolatlon" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 2)
+			gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), elev(),
+									eyehpr_[0],
+									eyehpr_[1],
+									eyehpr_[2]);
+		else if (a.argCount() == 3)
+			gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)), elev(),
+									eyehpr_[0],
+									eyehpr_[1],
+									eyehpr_[2]);
+		else
+			a.printError("bad argument count");
+
+	}
+	else if ("zoomtolatlon" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 2)
+		{
+			gotoing_ = false;
+			lat_ = mkUtils::asDouble(a.arg(1));
+			lon_ = mkUtils::asDouble(a.arg(2));
+			targetLat_ = lat_;
+			targetLon_ = lon_;
+			targetLookH_ = eyehpr_[0];
+			targetLookP_ = eyehpr_[1];
+			targetLookR_ = eyehpr_[2];
+			targetLookZ_ = eyexyz_.z();
+		}
+		else if (a.argCount() == 3)
+		{
+			gotoing_ = false;
+			lat_ = mkUtils::asDouble(a.arg(2));
+			lon_ = mkUtils::asDouble(a.arg(3));
+			targetLat_ = lat_;
+			targetLon_ = lon_;
+			targetLookH_ = eyehpr_[0];
+			targetLookP_ = eyehpr_[1];
+			targetLookR_ = eyehpr_[2];
+			targetLookZ_ = eyexyz_.z();
+
+		}
+		else
+		{
+			a.printError("bad argument count");
+		}
+	}
+	else if ("gotolatlonelev" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 3)
+		{
+			gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)),
+									eyehpr_[0],
+									eyehpr_[1],
+									eyehpr_[2]);
+		}
+		else if (a.argCount() == 4)
+			gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)),
+									mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)),
+									eyehpr_[0],
+									eyehpr_[1],
+									eyehpr_[2]);
+		else
+			a.printError("bad argument count");
+
+	}
+	else if ("setlatlonelevhpr" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 6)
+		{
+			gotoing_  = false;
+			gotoset_  = false;
+			rotating_ = false;
+			zooming_  = false;
+			zoominglos_ = false;
+			gotoingelev_=false;
+			//              gotoing_ = false;
+			//              gotoset_ = true;
+
+			lat_ = mkUtils::asDouble(a.arg(1));
+			lon_ = mkUtils::asDouble(a.arg(2));
+			eyexyz_.z() = ossim::clamp(-mkUtils::asDouble(a.arg(3))/primary_->radius(targetLat_) - 1.0, zoomMin_, zoomMax_);
+			eyehpr_[0] =mkUtils::asDouble(a.arg(4));
+			eyehpr_[1] =mkUtils::asDouble(a.arg(5));
+			eyehpr_[2] =mkUtils::asDouble(a.arg(6));
+
+			targetLookZ_      = eyexyz_.z();
+			targetLookH_      = eyehpr_[0];
+			targetLookP_      = eyehpr_[1];
+			targetLookR_      = eyehpr_[2];
+			targetStartLookZ_ = eyexyz_.z();
+			setRedrawFlag(true);
+			//std::cout << "ossimPlanetNavigator: setlatlonelevhpr\n";
+		}
+		else
+			a.printError("bad argument count: should be setlatlonelevhpr <lat> <lon> <elev in meters> <heading> <pitch> <roll>");
+	}
+	//     else if ("gotolatlonelevh" == command)
+	//     {
+	//        if (a.argCount() == 4)
+	//        {
+	//           gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)),
+	//                             mkUtils::asDouble(a.arg(4)),
+	//                             eyehpr_[1],
+	//                             eyehpr_[2]);
+	//        }
+	//        else if (a.argCount() == 5)
+	//           gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)),
+	//                             mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)),
+	//                             mkUtils::asDouble(a.arg(5)),
+	//                             eyehpr_[1],
+	//                             eyehpr_[2]);
+	//        else
+	//           a.printError("bad argument count");
+
+	//     }
+	else if ("gotolatlonelevhpr" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 6)
+		{
+			gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)),
+									mkUtils::asDouble(a.arg(4)),
+									mkUtils::asDouble(a.arg(5)),
+									mkUtils::asDouble(a.arg(6)));
+		}
+		else if (a.argCount() == 7)
+			gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)),
+									mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)),
+									mkUtils::asDouble(a.arg(5)),
+									mkUtils::asDouble(a.arg(6)),
+									mkUtils::asDouble(a.arg(7)));
+		else
+			a.printError("bad argument count");
+
+	}
+	else if ("gotolatlonnadir" == command)
+	{
+		if (a.argCount() == 2)
+		{
+			gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), elev(),
+									0.0, pitchOffset_, 0.0);
+		}
+		else if (a.argCount() == 3)
+			gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)),
+									mkUtils::asDouble(a.arg(3)), elev(),
+									0.0, pitchOffset_, 0.0);
+		else
+			a.printError("bad argument count");
+
+	}
+	else if ("gotolatlonelevnadir" == command)
+	{
+	   setRedrawFlag(true);
+		if (a.argCount() == 3)
+		{
+			gotoLatLonElevHpr("", mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)),
+									0.0, pitchOffset_, 0.0);
+		}
+		else if (a.argCount() == 4)
+			gotoLatLonElevHpr(a.arg(1), mkUtils::asDouble(a.arg(2)),
+									mkUtils::asDouble(a.arg(3)), mkUtils::asDouble(a.arg(4)),
+									0.0, pitchOffset_, 0.0);
+		else
+			a.printError("bad argument count");
+
+	}
+	else if ("printlatlonelev" == command)
+	{
+		cout << "lat = " << lat_ << "  lon = " << lon_ << "  elev = " << elev() << 'm' << endl;
+
+	} else if ("printlookcoordinates" == command) {
+		cout << "Look z: " << eyexyz_.z() << "    hpr: " << eyehpr_[0] << ' ' << eyehpr_[1] << ' ' << eyehpr_[2] << endl;
+
+	} else if ("gotoxyz" == command) {
+		eyexyz_.set(mkUtils::asDouble(a.arg(1)), mkUtils::asDouble(a.arg(2)), mkUtils::asDouble(a.arg(3)));
+		eyehpr_.set(0.0, pitchOffset_, 0.0);
+
+	} else if ("resetzoomlook" == command) {
+		eyexyz_.set(0.0, 0.0, zoomMin_);
+		eyehpr_.set(0.0, pitchOffset_, 0.0);
+		setRedrawFlag(true);
+
+	} else if ("rotatenorth" == command){
+	   setRedrawFlag(true);
+		if(losXYZValidFlag_&&model.valid())
+		{
+			osg::Vec3d llh;
+			osg::Vec3d newLlh;
+			osg::Vec3d xyz;
+			osg::Vec3d hpr;
+			osg::Vec3d newHpr;
+			double range;
+			osg::Vec3d tempHpr;
+
+			// first get the look at orientation
+			// rotated north
+			model->inverse(losXYZ_, llh);
+			solveLookAt(llh[0], llh[1], llh[2],
+							hpr[0], hpr[1], hpr[2],
+							range);
+
+
+			solveEyeGivenLocalSpaceAndRange(newLlh, newHpr, llh, osg::Vec3d(0.0, hpr[1], 0.0), range);
+
+			setLatLonHeight(newLlh[0], newLlh[1], newLlh[2]);
+			eyehpr_ = newHpr;
+			eyehpr_[2] = 0.0;
+			eyehpr_[0] = ossim::clamp(eyehpr_[0] , -180.0, 180.0);
+			eyehpr_[1] = ossim::clamp(eyehpr_[1] , 0.0, 180.0);
+		}
+
+	} else if ("rotatenorthup" == command){
+	   setRedrawFlag(true);
+		if(losXYZValidFlag_&&model.valid())
+		{
+			osg::Vec3d llh;
+			osg::Vec3d newLlh;
+			osg::Vec3d xyz;
+			osg::Vec3d hpr;
+			osg::Vec3d newHpr;
+			double range;
+			osg::Vec3d tempHpr;
+
+			// first get the look at orientation
+			// rotated north
+			model->inverse(losXYZ_, llh);
+			solveLookAt(llh[0], llh[1], llh[2],
+							hpr[0], hpr[1], hpr[2],
+							range);
+
+
+			solveEyeGivenLocalSpaceAndRange(newLlh, newHpr, llh, osg::Vec3d(0.0, pitchOffset_, 0.0), range);
+
+			setLatLonHeight(newLlh[0], newLlh[1], newLlh[2]);
+			eyehpr_ = newHpr;
+			eyehpr_[2] = 0.0;
+			eyehpr_[0] = ossim::clamp(eyehpr_[0] , -180.0, 180.0);
+			eyehpr_[1] = ossim::clamp(eyehpr_[1] , 0.0, 180.0);
+      }
+
+	} else if ("setgotolookduration" == command) {
+		if ((a.argCount() == 1)  &&  (mkUtils::asDouble(a.arg(1)) > 0.0)) {
+			gotoLookDuration_ = mkUtils::asDouble(a.arg(1));
+		} else {
+			a.printError("bad argument, need one float > 0");
+		}
+
+	}
+	else if ("reset" == command)
+	{
+		eyexyz_.set(0.0, 0.0, zoomMin_);
+		eyehpr_.set(0.0, pitchOffset_, 0.0);
+		lat_ = 0.0;
+		lon_ = -90.0;
+		rotating_ = false;
+		zooming_ = false;
+		looking_ = false;
+		endLooking_ = false;
+		gotoing_ = false;
+		gotoset_ = false;
+		gotoingelev_ = false;
+		flying_ = false;
+		losLookingFlag_ = false;
+		theAnimationMode = ossimPlanetNavigator::NAV_ANIMATION_NONE;
+		setRedrawFlag(true);
+   }
+	else if ("stop" == command)
+	{
+	   setRedrawFlag(true);
+		rotating_   = false;
+		zooming_    = false;
+		looking_    = false;
+		endLooking_ = false;
+		gotoing_    = false;
+		gotoset_    = false;
+		flying_     = false;
+		losLookingFlag_ = false;
+		theAnimationMode = ossimPlanetNavigator::NAV_ANIMATION_NONE;
+	}
+	else
+	{
+		a.printError("bad command");
+	}
+}
+
+
+void ossimPlanetNavigator::execute(const ossimPlanetAction &action)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   const ossimPlanetDestinationCommandAction* a = action.toDestinationCommandAction();
+   const ossimPlanetXmlAction* xml = action.toXmlAction();
+   // for now only support :destination command <args> style actions;
+   if(a)
+	{
+		destinationCommandExecute(*a);
+	}
+	else if(xml)
+	{
+		xmlExecute(*xml);
+	}
+}
+
+// protected
+
+void ossimPlanetNavigator::updateLatLon(float x, float y)
+{
+
+   lon_ = ossim::wrap(lon_ - zoomScaleInput(x), primary_->minLon(), primary_->maxLon());
+   lat_ -= zoomScaleInput(y);
+   if (lat_ > 90.0)
+   {
+      lat_ = ossim::clamp(90.0 - (lat_ - 90.0), -90.0, 90.0);
+      lon_ = ossim::wrap(lon_ + 180.0, primary_->minLon(), primary_->maxLon());
+      eyehpr_[0] = ossim::wrap(eyehpr_[0] + 180.0, -180.0, 180.0);
+   }
+   else if (lat_ < -90.0)
+   {
+      lat_ = ossim::clamp(-lat_ - 180.0, -90.0, 90.0);
+      lon_ = ossim::wrap(lon_ + 180.0, primary_->minLon(), primary_->maxLon());
+      eyehpr_[0] = ossim::wrap(eyehpr_[0] - 180.0, -180.0, 180.0);
+   }
+}
+
+double ossimPlanetNavigator::zoomScaleInput(float input) const
+{
+   return ossim::sgn(input)*input*input*(std::abs(-eyexyz_.z() - zoomScaleBaseline_));
+}
+
+void ossimPlanetNavigator::gotoLookAt(const ossimPlanetLookAt& lookInfo, bool animateFlag)
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(!model.valid()) return;
+   osg::Vec3d posLlh = osg::Vec3d(lookInfo.lat(), lookInfo.lon(), lookInfo.altitude());
+   osg::Matrixd eyeLsrMatrix = viewMatrix(posLlh[0], posLlh[1], posLlh[2], lookInfo.heading(), lookInfo.pitch(), lookInfo.roll());
+   
+   // now let's extrude to get the eye location then match so the eye location and lookat are good.
+   osg::Vec3d eye(eyeLsrMatrix(3,0), eyeLsrMatrix(3,1), eyeLsrMatrix(3,2));
+   osg::Vec3d zAxis(eyeLsrMatrix(2,0), eyeLsrMatrix(2,1), eyeLsrMatrix(2,2));
+   eye = eye + zAxis*(lookInfo.range()/model->getNormalizationScale());
+   
+   osg::Vec3d eyeLlh;
+   model->inverse(eye, eyeLlh);
+   
+   // now solve the lsr matrix
+   osg::Matrixd localLsr;
+   osg::Vec3d tempHpr;
+   model->lsrMatrix(eyeLlh, localLsr);
+   mkUtils::matrixToHpr(tempHpr, localLsr, eyeLsrMatrix);
+   
+   gotoLatLonElevHpr("",
+                     eyeLlh[0], eyeLlh[1], eyeLlh[2],
+                     tempHpr[0], tempHpr[1], tempHpr[2], 
+                     animateFlag);
+}
+
+void ossimPlanetNavigator::gotoLatLonElevHpr(const std::string& /*placeName*/,
+                                             double latitude,
+                                             double longitude,
+                                             double elevation,
+                                             double heading,
+                                             double pitch,
+                                             double roll,
+                                             bool animateFlag)
+{
+   
+   if(!animateFlag)
+   {
+      setLatLonHeight(latitude, longitude, elevation);
+      setHpr(heading, pitch, roll);
+   }
+   else
+   {
+      // This routine is excessively long, should fix that.
+      // Also it helps if you have the paper at PJM's desk to understand the math.
+      
+      if (!ossim::isnan(latitude) && !ossim::isnan(longitude) && !ossim::isnan(elevation) &&
+          !ossim::isnan(heading) && !ossim::isnan(pitch) && !ossim::isnan(roll))
+      {
+         // update() uses the following variables and targetMidpointLookZ_ to move us to the target
+         gotoing_ = true;
+         losLookingFlag_ = false;
+         gotoStartTime_ = osg::Timer::instance()->tick();   //SimClock::currentFrameTime();
+         targetStartLat_ = lat_;
+         targetStartLon_ = lon_;
+         targetStartLookH_ = eyehpr_[0];
+         targetStartLookP_ = eyehpr_[1];
+         targetStartLookR_ = eyehpr_[2];
+         targetLat_ = latitude;
+         targetLon_ = longitude;
+         targetLookH_ = heading;
+         targetLookP_ = pitch;
+         targetLookR_ = roll;
+         targetLookZ_ = ossim::clamp(-elevation/primary_->radius(lat_) - 1.0, zoomMin_, zoomMax_);
+         targetStartLookZ_ = eyexyz_.z();
+         
+         // the rest of this computes targetMidpointLookZ_ for all cases,
+         // so we get a nice zoom every time.
+         
+         // compute some stuff
+         double theta = 0.5*fov_;
+         double cosTheta = cos(osg::DegreesToRadians(theta));
+         float oldPhi = -1.0f; // init to "see whole globe";  angle from center of screen to edge of screen, angle vertex at globe center
+         double d = -eyexyz_.z();
+         double d2 = d*d;
+         double h = d*cosTheta - sqrt(d2*cosTheta*cosTheta - d2 + 1.0);
+         if (!ossim::isnan(h))
+         {
+            double l = d - 1.0;
+            double c = sqrt(l*l + h*h - 2.0*l*h*cosTheta);
+            oldPhi = 2.0*osg::RadiansToDegrees(atan(c / (2.0*sqrt(1.0 - 0.25*c*c))));
+         }
+         float angleDelta = max(fabs(targetLat_ - lat_), fabs(targetLon_ - lon_));   // cheesy
+         
+         // use that stuff to discern and handle the three cases
+         if (oldPhi <= 0.0f || angleDelta < oldPhi)
+         {
+            // we can already see the target, so don't zoom anywhere.
+            targetMidpointLookZ_ = targetStartLookZ_;
+            
+         }
+         else if (angleDelta < 90.0f)
+         {
+            // target on near side of earth but we're zoomed in too close to see it,
+            // so zoom out to see target
+            double phi = angleDelta + oldPhi;
+            double cosPhi = cos(osg::DegreesToRadians(phi));
+            double alpha = 180.0 - theta - phi;
+            double cosAlpha = cos(osg::DegreesToRadians(alpha));
+            double cos2Alpha = cosAlpha*cosAlpha;
+            double cos2AlphaRecip = 1.0/cos2Alpha;
+            
+            // solve the quadratic to get distance
+            pair<double, double> distance = mkUtils::quadraticRoots((cosPhi*cosPhi)/cos2Alpha - 1.0, 2.0*cosPhi - 2.0*cosPhi*cos2AlphaRecip, cos2AlphaRecip - 1.0);
+            if (!ossim::isnan(distance.first))
+            {
+               targetMidpointLookZ_ = -max(distance.first, distance.second);  // use higher elevation
+            }
+            else
+            {
+               targetMidpointLookZ_ = zoomMin_; // i don't think this case can happen, but if so take just us all the way out.
+            }
+            
+         }
+         else
+         {
+            // target on far side of earth, so zoom out to where earth just fills screen
+            targetMidpointLookZ_ = -(-1.0/(cosTheta*cosTheta - 1.0) + 1.0);
+         }
+      }
+      else
+      {
+         targetMidpointLookZ_ = (targetStartLookZ_ + targetLookZ_)*.5;
+      }
+      
+      targetMidpointLookZ_ = ossim::clamp(targetMidpointLookZ_, zoomMin_, zoomMax_);
+   }
+}
+
+osg::Matrixd ossimPlanetNavigator::viewMatrix(double lat, double lon, double hgt,
+                                              double h, double p, double r)const
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(model.valid())
+   {
+      osg::Vec3d xyz;
+      model->forward(osg::Vec3d(lat, lon, hgt),///model->getNormalizationScale()),
+                            xyz);
+      return orientationLsrMatrix(lat, lon, hgt, h, p, r)*osg::Matrixd::translate(xyz[0], xyz[1], xyz[2]);
+   }
+   return osg::Matrixd();
+}
+
+void ossimPlanetNavigator::solveLookAt(double losLat, double losLon, double losHeight,
+                                       double& heading, double& pitch, double& roll, double& range)const
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   if(!model.valid()) return;
+   osg::Vec3d eye;
+   osg::Matrixd eyeLsrMatrix(viewMatrix());
+   osg::Matrixd losLsrMatrix(orientationLsrMatrix(losLat, losLon, losHeight,
+                                                  0.0, 0.0, 0.0));
+   eye[0] = eyeLsrMatrix(3,0);
+   eye[1] = eyeLsrMatrix(3,1);
+   eye[2] = eyeLsrMatrix(3,2);
+   eyeLsrMatrix(3,0) = 0.0;
+   eyeLsrMatrix(3,1) = 0.0;
+   eyeLsrMatrix(3,2) = 0.0;
+
+   osg::Vec3d tempHpr;
+   mkUtils::matrixToHpr(tempHpr, losLsrMatrix, eyeLsrMatrix);
+   osg::Vec3d eyeXyz;
+   osg::Vec3d losXyz;
+   model->forward(osg::Vec3d(losLat, losLon, losHeight),
+                         losXyz);
+   range = (losXyz-eye).length()*model->getNormalizationScale();
+   heading = tempHpr[0];
+   pitch   = tempHpr[1];
+   roll    = tempHpr[2];
+}
+void ossimPlanetNavigator::solveEyeGivenLocalSpaceAndRange(osg::Vec3d& llh, // out lat lon height
+                                                           osg::Vec3d& hpr,  // output orientation
+                                                           const osg::Vec3d& localLlh,
+                                                           const osg::Vec3d& localHpr,
+                                                           double rangeInMeters)const
+{
+   osg::ref_ptr<ossimPlanetGeoRefModel> model = landModel();
+   osg::Matrixd m = viewMatrix(localLlh[0], localLlh[1], localLlh[2], localHpr[0], localHpr[1], localHpr[2]);
+   osg::Vec3d eye(m(3,0), m(3,1), m(3,2));
+   osg::Vec3d zAxis(m(2,0), m(2,1), m(2,2));
+   zAxis.normalize();
+
+   // now get the new eye position
+   // and solve the orientation
+   osg::Vec3d xyz = eye + zAxis*(rangeInMeters/model->getNormalizationScale());
+   model->inverse(xyz, llh);
+   osg::Matrixd newM = viewMatrix(llh[0], llh[1], llh[2], 0.0, 0.0, 0.0);
+   mkUtils::matrixToHpr(hpr, newM, m);
+}
+
+void ossimPlanetNavigator::playRecording()
+{
+   if(!theAnimationPath->getTimeControlPointMap().empty())
+   {
+      if(theAnimationMode == NAV_ANIMATION_RECORDING)
+      {
+         theAnimationPath->insert(osg::Timer::instance()->delta_s(theAnimationStartTime, osg::Timer::instance()->tick()),
+                                  osg::AnimationPath::ControlPoint(theLastAnimationParameter.eye,
+                                                                   theLastAnimationParameter.quat));
+
+      }
+      theAnimationMode  = NAV_ANIMATION_PLAYBACK;
+      theAnimationStartTime = osg::Timer::instance()->tick();
+      rotating_ = false;
+      zooming_ = false;
+      losLookingFlag_ = false;
+      zoominglos_ = false;
+      flying_ = false;
+   }
+   else
+   {
+      theAnimationMode  = NAV_ANIMATION_NONE;
+   }
+}
+
+void ossimPlanetNavigator::startRecording()
+{
+   theAnimationMode = NAV_ANIMATION_RECORDING;
+   theAnimationPath->getTimeControlPointMap().clear();
+   theAnimationStartTime = osg::Timer::instance()->tick();
+}
+
+void ossimPlanetNavigator::stopRecording()
+{
+   if(theAnimationMode == NAV_ANIMATION_RECORDING)
+   {
+      theAnimationPath->insert(osg::Timer::instance()->delta_s(theAnimationStartTime, osg::Timer::instance()->tick()),
+                               osg::AnimationPath::ControlPoint(theLastAnimationParameter.eye,
+                                                                theLastAnimationParameter.quat));
+
+   }
+   theAnimationMode  = NAV_ANIMATION_NONE;
+}
+
+void ossimPlanetNavigator::saveRecording(std::ostream& out)
+{
+   if(!theAnimationPath->getTimeControlPointMap().empty())
+   {
+      theAnimationPath->write(out);
+   }
+}
+
+bool ossimPlanetNavigator::loadRecording(std::istream& in)
+{
+   theAnimationPath->getTimeControlPointMap().clear();
+   theAnimationPath->read(in);
+   return !theAnimationPath->getTimeControlPointMap().empty();
+}
+
+void ossimPlanetNavigator::setUseTimedUpdateFlag(bool flag)
+{
+   theUseTimedUpdateFlag = flag;
+}
+
+osg::ref_ptr<ossimPlanetGeoRefModel> ossimPlanetNavigator::landModel()
+{
+	if(thePlanet)
+	{
+		return thePlanet->model();
+	}
+	return 0;
+}
+const osg::ref_ptr<ossimPlanetGeoRefModel> ossimPlanetNavigator::landModel()const
+{
+	if(thePlanet)
+	{
+		return thePlanet->model();
+	}
+	return 0;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetNode.cpp
new file mode 100644
index 0000000..56da321
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetNode.cpp
@@ -0,0 +1,350 @@
+#include <ossimPlanet/ossimPlanetNode.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <osgUtil/IntersectVisitor>
+#include <osgUtil/IntersectionVisitor>
+ossimPlanetNode::ossimPlanetNode()
+:theEnableFlag(true),
+theIntersectableFlag(true),
+theRedrawFlag(false),
+theLayer(0)
+{
+   setCullCallback(new ossimPlanetTraverseCallback);
+   setUpdateCallback(new ossimPlanetTraverseCallback);
+}
+
+ossimPlanetNode::~ossimPlanetNode()
+{
+   setUpdateCallback(0);
+   setCullCallback(0);
+   
+   notifyDestructing(this);
+   theCallbackList.clear();   
+}
+
+void ossimPlanetNode::remove(osg::Node* node)
+{
+	osg::ref_ptr<osg::Node> savedNode = node;
+   ossim_uint32 upperIdx = node->getParents().size();
+   if(upperIdx > 0)
+   {
+      ossim_uint32 idx = 0;
+      for(;idx < upperIdx;++idx)
+      {
+         osg::Group* group = node->getParent(idx)->asGroup();
+         if(group)
+         {
+            group->removeChild(node);
+         }
+      }
+   }
+}
+
+void ossimPlanetNode::traverse(osg::NodeVisitor& nv)
+{
+   if(!theLayer)
+   {
+      setLayer(ossimPlanetLayer::findLayer(nv.getNodePath()));
+   }
+   if(!intersectFlag()&&(dynamic_cast<osgUtil::IntersectVisitor*> (&nv) ||
+                         dynamic_cast<osgUtil::IntersectionVisitor*> (&nv)))
+   {
+      return;
+   }
+   
+   if(!enableFlag())
+   {
+      return;
+   }
+   osg::Group::traverse(nv);
+}
+
+void ossimPlanetNode::execute(const ossimPlanetAction& action)
+{
+   const ossimPlanetXmlAction* xmlAction = action.toXmlAction();
+   if(xmlAction&&xmlAction->xmlNode().valid())
+   {
+      ossimString command = action.command();
+      if(command == "Set")
+      {
+         ossim_uint32 idx = 0;
+         const ossimXmlNode::ChildListType& childNodes = xmlAction->xmlNode()->getChildNodes();
+			const ossimXmlNode::ChildListType* properties = 0;
+			// at this point we should just have a single object in the first child of the set
+			//
+			if(childNodes.size() == 1)
+			{
+				properties = &(childNodes[0]->getChildNodes());
+			}
+			if(!properties) return;
+         for(idx = 0;idx<properties->size();++idx)
+         {
+            ossimString tag = (*properties)[idx]->getTag();
+            if(tag=="name")
+            {
+               setName((*properties)[idx]->getText());
+            }
+            else if(tag == "description")
+            {
+               setDescription((*properties)[idx]->getText());
+            }
+            else if(tag == "id")
+            {
+               setId((*properties)[idx]->getText());
+            }
+            else if(tag == "receiverPath")
+            {
+               setPathnameAndRegister((*properties)[idx]->getText());
+            }
+         }
+      }
+   }
+}
+
+bool ossimPlanetNode::addChild( Node *child )
+{
+   bool result = osg::Group::addChild(child);
+   
+   if(result)
+   {
+      ossimPlanetNode* layerNode = dynamic_cast<ossimPlanetNode*>(child);
+      if(layerNode) layerNode->setLayer(ossimPlanetLayer::findLayer(child));
+      notifyAddChild(child);
+      setRedrawFlag(true);
+      nodeAdded(child);
+   }
+   
+   return result;
+}
+
+bool ossimPlanetNode::insertChild( unsigned int index, Node *child )
+{
+   bool result = osg::Group::insertChild(index, child);
+   
+   if(result)
+   {
+      ossimPlanetNode* layerNode = dynamic_cast<ossimPlanetNode*>(child);
+      if(layerNode) layerNode->setLayer(ossimPlanetLayer::findLayer(child));
+      notifyAddChild(child);
+      setRedrawFlag(true);
+      nodeAdded(child);
+   }
+   return result;
+}
+
+bool ossimPlanetNode::replaceChild( Node *origChild, Node* newChild )
+{
+   osg::ref_ptr<osg::Node> origChildSave = origChild;
+   osg::ref_ptr<osg::Node> newChildSave  = newChild;
+   bool result = osg::Group::replaceChild(origChild, newChild);
+   if(result)
+   {
+      ossimPlanetNode* layerNode = dynamic_cast<ossimPlanetNode*>(newChild);
+      if(layerNode)
+      {
+         layerNode->setLayer(ossimPlanetLayer::findLayer(this));
+      }
+      notifyAddChild(newChild);
+      notifyRemoveChild(origChild);
+      setRedrawFlag(true);
+      nodeRemoved(origChildSave.get());
+      nodeAdded(newChildSave.get());
+   }
+   
+   return result;
+}
+
+bool ossimPlanetNode::removeChildren(unsigned int pos,unsigned int numChildrenToRemove)
+{
+   if (pos<getNumChildren() && numChildrenToRemove>0)
+   {
+      unsigned int endOfRemoveRange = pos+numChildrenToRemove;
+      if (endOfRemoveRange>getNumChildren())
+      {
+         endOfRemoveRange=getNumChildren();
+      }
+      osg::Node* node = 0;
+      ossim_uint32 idx = pos;
+      for(;idx<endOfRemoveRange;++idx)
+      {
+         node = getChild(idx);
+         if(node)
+         {
+            notifyRemoveChild(node);
+            nodeRemoved(node);
+         }
+      }
+   }
+   bool result = osg::Group::removeChildren(pos, numChildrenToRemove);
+   if(result)
+   {
+      setRedrawFlag(true);
+   }
+   
+   return result;
+}
+
+void ossimPlanetNode::setRedrawFlag(bool flag)//(bool flag, bool passToParentFlag)
+{
+   bool changed = false;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePlanetNodeRedrawPropertyMutex);
+      changed = (theRedrawFlag != flag);
+      theRedrawFlag = flag;
+   }
+   if(flag)
+   {
+      ossimPlanetLayer* l = layer();
+      if(l&&(l!=this))
+      {
+         l->setRedrawFlag(flag);
+      }
+   }
+   if(changed&&flag)
+   {
+      notifyNeedsRedraw();
+   }
+      
+#if 0
+   if(!dynamic_cast<ossimPlanetLayer*>(this))
+   {
+      if(layer())
+      {
+         layer()->setRedrawFlag(flag, passToParentFlag);
+         return;
+      }
+   }
+   bool changed = false;
+   {
+      OpenThreads::ScopedWriteLock lock(thePlanetNodeRedrawPropertyMutex);
+      changed = (theRedrawFlag != flag);
+      theRedrawFlag = flag;
+   }
+   // notify just one time on Redraw flag set to true
+   if(changed)
+   {
+      if(flag)
+      {
+         notifyNeedsRedraw();
+      }
+      if(passToParentFlag)
+      {
+         //OpenThreads::ScopedReadLock lock(thePlanetNodePropertyMutex);
+         ossim_uint32 idx = 0;
+         ossim_uint32 idxMax = getNumParents();
+         for(idx = 0; idx < idxMax; ++idx)
+         {
+            ossimPlanetNode* layerNode = dynamic_cast<ossimPlanetNode*>(getParent(idx));
+            if(layerNode)
+            {
+               layerNode->setRedrawFlag(flag, passToParentFlag);
+            }
+         }
+      }
+   }
+#endif
+}
+
+
+ossimPlanetNode* ossimPlanetNode::findNode(osg::NodePath& currentNodePath)
+{
+   if(currentNodePath.empty())
+   {
+      return 0;
+   }
+   for(osg::NodePath::reverse_iterator itr = currentNodePath.rbegin();
+       itr != currentNodePath.rend();
+       ++itr)
+   {
+      ossimPlanetNode* node = dynamic_cast<ossimPlanetNode*>(*itr);
+      if (node) 
+      {
+         return node;
+      }
+   }
+   
+   return 0;
+}
+
+void ossimPlanetNode::notifyPropertyChanged(ossimPlanetNode* node, const ossimString& name)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->propertyChanged(node, name); 
+      }
+   }
+}
+
+void ossimPlanetNode::notifyDestructing(ossimPlanetNode* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->destructingNode(node); 
+      }
+   }   
+}
+
+void ossimPlanetNode::notifyNeedsRedraw()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->needsRedraw(this); 
+      }
+   }   
+}
+
+void ossimPlanetNode::notifyAddChild(osg::ref_ptr<osg::Node> node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->nodeAdded(node.get());
+      }
+   }
+}
+
+void ossimPlanetNode::notifyRemoveChild(osg::ref_ptr<osg::Node> node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->nodeRemoved(node.get());
+      }
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetNodeFactory.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetNodeFactory.cpp
new file mode 100644
index 0000000..0cbdcfa
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetNodeFactory.cpp
@@ -0,0 +1,35 @@
+#include <ossimPlanet/ossimPlanetNodeFactory.h>
+#include <ossimPlanet/ossimPlanetAnnotationLayerNode.h>
+
+ossimPlanetNodeFactory* ossimPlanetNodeFactory::theInstance = 0;
+
+ossimPlanetNodeFactory::ossimPlanetNodeFactory()
+{
+	theInstance = this;
+}
+
+ossimPlanetNodeFactory::~ossimPlanetNodeFactory()
+{
+	theInstance = 0;
+}
+
+
+ossimPlanetNodeFactory* ossimPlanetNodeFactory::instance()
+{	
+	if(!theInstance)
+	{
+		theInstance = new ossimPlanetNodeFactory;
+	}
+	
+	return theInstance;
+}
+
+ossimPlanetNode* ossimPlanetNodeFactory::create(const ossimString& type)const
+{	
+	if(type == "Placemark")
+	{
+		return new ossimPlanetAnnotationPlacemark;
+	}
+	return 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetNodeRegistry.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetNodeRegistry.cpp
new file mode 100644
index 0000000..723819f
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetNodeRegistry.cpp
@@ -0,0 +1,84 @@
+#include <ossimPlanet/ossimPlanetNodeRegistry.h>
+#include <ossimPlanet/ossimPlanetNodeFactory.h>
+#include <algorithm>
+ossimPlanetNodeRegistry* ossimPlanetNodeRegistry::theInstance = 0;
+ossim_uint32 ossimPlanetNodeRegistry::theInitializeCount           = 0;
+
+
+ossimPlanetNodeRegistry::ossimPlanetNodeRegistry()
+{
+	theInstance = this;
+}
+ossimPlanetNodeRegistry::~ossimPlanetNodeRegistry()
+{
+	theInstance = 0;
+}
+
+ossimPlanetNodeRegistry* ossimPlanetNodeRegistry::instance()
+{
+	if(!theInstance)
+	{
+		theInstance = new ossimPlanetNodeRegistry;
+		theInstance->registerFactory(ossimPlanetNodeFactory::instance());
+	}
+	
+	return theInstance;
+}
+
+void ossimPlanetNodeRegistry::finalize()
+{	
+}
+
+ossimPlanetNode* ossimPlanetNodeRegistry::create(const ossimString& type)const
+{
+	ossimPlanetNode* layerNode = 0;
+   theFactoryListMutex.readLock();
+	FactoryListType::const_iterator iter = theFactoryList.begin();
+	while((iter != theFactoryList.end())&&(!layerNode))
+	{
+		layerNode = (*iter)->create(type);
+		++iter;
+	}
+   theFactoryListMutex.readUnlock();
+	return layerNode;
+}
+
+bool ossimPlanetNodeRegistry::hasFactory(const ossimPlanetNodeFactoryBase* factory)const
+{
+	FactoryListType::const_iterator iter = std::find(theFactoryList.begin(),
+																	 theFactoryList.end(), 
+																	 factory);
+	return (iter != theFactoryList.end());
+}
+
+void ossimPlanetNodeRegistry::registerFactory(ossimPlanetNodeFactoryBase* factory,
+																	bool insertFrontFlag)
+{
+	if(!hasFactory(factory))
+	{
+      theFactoryListMutex.writeLock();
+		if(!insertFrontFlag)
+		{
+			theFactoryList.push_back(factory);
+		}
+		else
+		{
+			theFactoryList.insert(theFactoryList.begin(),
+										 factory);
+		}
+      theFactoryListMutex.writeUnlock();
+	}
+}
+
+void ossimPlanetNodeRegistry::unregisterFactory(const ossimPlanetNodeFactoryBase* factory)
+{
+   theFactoryListMutex.writeLock();
+	FactoryListType::iterator iter = std::find(theFactoryList.begin(),
+															 theFactoryList.end(), 
+															 factory);
+	if(iter!=theFactoryList.end())
+	{
+		theFactoryList.erase(iter);
+	}
+   theFactoryListMutex.writeUnlock();
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetOperation.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetOperation.cpp
new file mode 100644
index 0000000..383523c
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetOperation.cpp
@@ -0,0 +1,652 @@
+#include <ossimPlanet/ossimPlanetOperation.h>
+#include <iostream>
+#include <algorithm>
+const ossimPlanetOperation::Priority ossimPlanetOperation::PRIORITY_HIGHEST = 1.0/DBL_EPSILON;
+const ossimPlanetOperation::Priority ossimPlanetOperation::PRIORITY_LOWEST = 0.0;
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperation::nextDependency(bool recurseFlag)
+{
+   osg::ref_ptr<ossimPlanetOperation> result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theDependencyListMutex);
+   if(!recurseFlag)
+   {
+      if(theDependencyList.size()>0)
+      {
+         result = *theDependencyList.begin();
+         theDependencyList.erase(theDependencyList.begin());
+      }
+   }
+   else if(theDependencyList.size()>0)
+
+   {
+      
+      osg::ref_ptr<ossimPlanetOperation> prevOperation = (*theDependencyList.begin()).get();
+      osg::ref_ptr<ossimPlanetOperation> currentOperation = prevOperation;
+      
+      if(currentOperation.valid())
+      {
+         while(currentOperation->hasDependency())
+         {
+            prevOperation = currentOperation;
+            currentOperation = (*currentOperation->dependencyList().begin()).get();
+         }
+         result = currentOperation;
+         prevOperation->dependencyList().erase(prevOperation->dependencyList().begin());
+      }
+   }
+   
+   return result;
+}
+
+void ossimPlanetOperation::notifyReady()
+{	
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->ready(this);
+      }
+   }
+}
+void ossimPlanetOperation::notifyStarted()
+{	
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->started(this);
+      }
+   }
+}
+
+void ossimPlanetOperation::notifyFinished()
+{	
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->finished(this);
+      }
+   }
+}
+
+
+void ossimPlanetOperation::notifyCanceled()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->canceled(this);
+      }
+   }
+}
+
+void ossimPlanetOperation::notifyPriorityChanged()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->priorityChanged(this);
+      }
+   }
+}
+
+void ossimPlanetOperation::notifyPropertyChanged(const ossimString& name)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->propertyChanged(name, this);
+      }
+   }
+}
+
+ossimPlanetOperationQueue::ossimPlanetOperationQueue()
+{
+   setThreadSafeRefUnref(true);
+   theBlock = new ossimPlanetRefBlock;
+}
+
+ossimPlanetOperationQueue::~ossimPlanetOperationQueue()
+{
+}
+
+void ossimPlanetOperationQueue::add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   
+   if(guaranteeUniqueFlag)
+   {
+      if(findByPointer(operation) != theOperationQueue.end())
+      {
+         theBlock->set(true);
+         return;
+      }
+   }
+   theOperationQueue.push_back(operation);
+   
+   theBlock->set(true);
+}
+
+void ossimPlanetOperationQueue::removeStoppedOperations()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   ossimPlanetOperation::List::iterator iter = theOperationQueue.begin();
+   while(iter!=theOperationQueue.end())
+   {
+      if((*iter)->isStopped())
+      {
+         iter = theOperationQueue.erase(iter);
+      }
+      else
+      {
+         ++iter;
+      }
+   }
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationQueue::removeById(const ossimString& id)
+{   
+   osg::ref_ptr<ossimPlanetOperation> result;
+   if(id.empty()) return result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   ossimPlanetOperation::List::iterator iter = findById(id);
+   if(iter!=theOperationQueue.end())
+   {
+      result = *iter;
+      theOperationQueue.erase(iter);
+   }
+   
+   theBlock->set(!theOperationQueue.empty());
+   
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationQueue::removeByName(const ossimString& name)
+{   
+   osg::ref_ptr<ossimPlanetOperation> result;
+   if(name.empty()) return result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   ossimPlanetOperation::List::iterator iter = findByName(name);
+   if(iter!=theOperationQueue.end())
+   {
+      result = *iter;
+      theOperationQueue.erase(iter);
+   }
+   
+   theBlock->set(!theOperationQueue.empty());
+   
+   return result;
+}
+
+void ossimPlanetOperationQueue::remove(const ossimPlanetOperation* operation)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   ossimPlanetOperation::List::iterator iter = findByPointer(operation);
+   if(iter!=theOperationQueue.end())
+   {
+      theOperationQueue.erase(iter);
+   }
+   
+   theBlock->set(!theOperationQueue.empty());
+}
+
+void ossimPlanetOperationQueue::removeAllOperations()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   theOperationQueue.clear();
+   theBlock->set(false);
+}
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationQueue::nextOperation(bool blockIfEmptyFlag)
+{
+	theOperationQueueMutex.lock();
+	bool emptyFlag = theOperationQueue.empty();
+	theOperationQueueMutex.unlock();
+   if (blockIfEmptyFlag && emptyFlag)
+   {
+      theBlock->block();
+   }
+   osg::ref_ptr<ossimPlanetOperation> result;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   
+   if (theOperationQueue.empty())
+   {
+      theBlock->set(false);
+      return result;
+   }
+   
+   ossimPlanetOperation::List::iterator iter= theOperationQueue.begin();
+   while((iter != theOperationQueue.end())&&
+         (((*iter)->isStopped())))
+   {
+      iter = theOperationQueue.erase(iter);
+   }
+   if(iter != theOperationQueue.end())
+   {
+      result = *iter;
+      theOperationQueue.erase(iter);
+   }
+   theBlock->set(!theOperationQueue.empty());
+   return result;
+}
+
+ossimPlanetOperation::List::iterator ossimPlanetOperationQueue::findById(const ossimString& id)
+{
+   if(id.empty()) return theOperationQueue.end();
+   ossimPlanetOperation::List::iterator iter = theOperationQueue.begin();
+   while(iter != theOperationQueue.end())
+   {
+      if(id == (*iter)->id())
+      {
+         return iter;
+      }
+      ++iter;
+   }  
+   return theOperationQueue.end();
+}
+
+ossimPlanetOperation::List::iterator ossimPlanetOperationQueue::findByName(const ossimString& name)
+{
+   if(name.empty()) return theOperationQueue.end();
+   ossimPlanetOperation::List::iterator iter = theOperationQueue.begin();
+   while(iter != theOperationQueue.end())
+   {
+      if(name == (*iter)->name())
+      {
+         return iter;
+      }
+      ++iter;
+   }  
+   return theOperationQueue.end();
+}
+
+ossimPlanetOperation::List::iterator ossimPlanetOperationQueue::findByPointer(const ossimPlanetOperation* operation)
+{
+   return std::find(theOperationQueue.begin(),
+                    theOperationQueue.end(),
+                    operation);
+}
+
+ossimPlanetOperation::List::iterator ossimPlanetOperationQueue::findByNameOrPointer(const ossimPlanetOperation* operation)
+{
+   ossimString n = operation->name();
+   ossimPlanetOperation::List::iterator iter = theOperationQueue.begin();
+   while(iter != theOperationQueue.end())
+   {
+      if((*iter).get() == operation)
+      {
+         return iter;
+      }
+      else if((!n.empty())&&
+              (operation->name() == (*iter)->name()))
+      {
+         return iter;
+      }
+      ++iter;
+   }  
+   
+   return theOperationQueue.end();
+}
+
+bool ossimPlanetOperationQueue::hasOperation(ossimPlanetOperation* operation)
+{
+   ossimPlanetOperation::List::const_iterator iter = theOperationQueue.begin();
+   while(iter != theOperationQueue.end())
+   {
+      if(operation == (*iter).get())
+      {
+         return true;
+      }
+      ++iter;
+   }
+
+   return false;
+}
+
+
+void ossimPlanetOperationQueue::releaseOperationsBlock()
+{
+   theBlock->release();
+}
+
+bool ossimPlanetOperationQueue::empty()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+   return theOperationQueue.empty();
+}
+
+
+struct SortRequestFunctor
+{
+   bool operator() (const osg::ref_ptr<ossimPlanetOperation>& lhs,
+                    const osg::ref_ptr<ossimPlanetOperation>& rhs) const
+   {
+      return (lhs->priority()>rhs->priority());
+   }
+};
+
+ossimPlanetOperationPriorityQueue::ossimPlanetOperationPriorityQueue()
+{
+}
+
+ossimPlanetOperationPriorityQueue::~ossimPlanetOperationPriorityQueue()
+{
+   
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationPriorityQueue::nextOperation(bool blockIfEmptyFlag)
+{
+   // we will sort the queue and let the base pop the first element and process
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+      
+      theOperationQueue.sort(SortRequestFunctor());
+   }
+   
+   return ossimPlanetOperationQueue::nextOperation(blockIfEmptyFlag);
+}
+
+ossimPlanetOperationThreadQueue::ossimPlanetOperationThreadQueue(ossimPlanetOperationQueue* opq)
+: osg::Referenced(true),
+   theDoneFlag(false),
+   theOperationQueue(opq)
+{
+   if(!theOperationQueue.valid())
+   {
+      theOperationQueue = new ossimPlanetOperationQueue();
+   }
+}
+
+ossimPlanetOperationThreadQueue::~ossimPlanetOperationThreadQueue()
+{
+   cancel();
+}
+
+void ossimPlanetOperationThreadQueue::setOperationQueue(ossimPlanetOperationQueue* opq)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   
+   if (theOperationQueue == opq) return;
+   
+   theOperationQueue = opq;
+}
+
+void ossimPlanetOperationThreadQueue::setDone(bool done)
+{
+   if (theDoneFlag==done) return;
+   
+   theDoneFlag = done;
+   
+   if(theDoneFlag)
+   {
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+         if (theCurrentOperation.valid())
+         {
+            theCurrentOperation->release();
+         }
+      }
+      
+      if (theOperationQueue.valid()) theOperationQueue->releaseOperationsBlock();
+   }
+}
+
+
+int ossimPlanetOperationThreadQueue::cancel()
+{
+   int result = 0;
+   
+   removeAllOperations();
+
+   if( isRunning() )
+   {
+      
+      theDoneFlag = true;
+      
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+			if (theCurrentOperation.valid())
+			{
+				theCurrentOperation->cancel();
+			}
+         
+         if (theOperationQueue.valid()) 
+         {
+            theOperationQueue->releaseOperationsBlock();
+         }
+         
+         if (theOperationQueue.valid()) theOperationQueue->releaseOperationsBlock();
+      }
+      
+      // then wait for the the thread to stop running.
+      while(isRunning())
+      {
+         
+#if 1
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+            
+            if (theOperationQueue.valid()) 
+            {
+               theOperationQueue->releaseOperationsBlock();
+               // _operationQueue->releaseAllOperations();
+            }
+            
+            if (theOperationQueue.valid()) theOperationQueue->releaseOperationsBlock();
+         }
+#endif
+         OpenThreads::Thread::YieldCurrentThread();
+      }
+   }
+   
+   return result;
+}
+
+void ossimPlanetOperationThreadQueue::add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   osg::ref_ptr<ossimPlanetOperation> op = operation;
+   if (!theOperationQueue) return;
+   theOperationQueue->add(op.get(), guaranteeUniqueFlag);
+   if(!isRunning())
+   {
+      start();
+      while(!isRunning())
+      {
+         OpenThreads::Thread::YieldCurrentThread();
+      }
+   }
+}
+
+void ossimPlanetOperationThreadQueue::remove(ossimPlanetOperation* operation)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   if (theOperationQueue.valid()) theOperationQueue->remove(operation);
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationThreadQueue::removeByName(const ossimString& name)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   if (theOperationQueue.valid()) return theOperationQueue->removeByName(name);
+   
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationThreadQueue::removeById(const ossimString& id)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   if (theOperationQueue.valid()) return theOperationQueue->removeById(id);
+   
+   return 0;
+}
+
+void ossimPlanetOperationThreadQueue::removeAllOperations()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+   if (theOperationQueue.valid()) 
+	{
+		theOperationQueue->removeAllOperations();
+	}
+}
+
+void ossimPlanetOperationThreadQueue::cancelCurrentOperation()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+	if(theCurrentOperation.valid())
+	{
+		theCurrentOperation->cancel();
+	}
+}
+
+void ossimPlanetOperationThreadQueue::run()
+{
+   bool firstTime = true;
+   
+   do
+   {
+      // osg::notify(osg::NOTICE)<<"In thread loop "<<this<<std::endl;
+      osg::ref_ptr<ossimPlanetOperation> operation;
+      osg::ref_ptr<ossimPlanetOperationQueue> queue;
+      
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+         queue = theOperationQueue;
+      }
+      
+      operation = nextOperation();
+      
+      if (theDoneFlag) break;
+      
+      if (operation.valid())
+      {
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+            theCurrentOperation = operation;
+         }
+         
+         while(operation->hasDependency())
+         {
+            osg::ref_ptr<ossimPlanetOperation> dependency = operation->nextDependency();
+				if(!operation->isStopped())
+				{
+					dependency->start();
+				}
+         }
+			if(!operation->isStopped())
+			{
+				operation->start();
+			}
+         {            
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+            theCurrentOperation = 0;
+         }
+      }
+      
+      if (firstTime)
+      {
+         // do a yield to get round a peculiar thread hang when testCancel() is called 
+         // in certain cirumstances - of which there is no particular pattern.
+         YieldCurrentThread();
+         firstTime = false;
+      }
+   } while (!testCancel() && !theDoneFlag);
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationThreadQueue::nextOperation()
+{
+   return theOperationQueue->nextOperation(true);
+}
+
+ossimPlanetOperationMultiThreadQueue::ossimPlanetOperationMultiThreadQueue(ossim_uint32 numberOfThreads)
+:theOperationQueue(new ossimPlanetOperationQueue)
+{
+	ossim_uint32 idx = 0;
+	for(idx = 0; idx < numberOfThreads;++idx)
+	{
+		ossimPlanetOperationThreadQueue* threadQueue = new ossimPlanetOperationThreadQueue(theOperationQueue.get());
+		threadQueue->start();
+		theThreadQueueList.push_back(threadQueue);
+	}
+}
+
+ossimPlanetOperationMultiThreadQueue::~ossimPlanetOperationMultiThreadQueue()
+{
+	removeAllOperations();
+	cancelCurrentOperation();
+	ossim_uint32 idx = 0;
+	for(idx = 0; idx < theThreadQueueList.size();++idx)
+	{
+		theThreadQueueList[idx]->cancel();
+	}
+	theThreadQueueList.clear();
+}
+
+ossimPlanetOperationQueue* ossimPlanetOperationMultiThreadQueue::operationQueue() 
+{ 
+	return theOperationQueue.get(); 
+}
+
+/** Get the const OperationQueue. */
+const ossimPlanetOperationQueue* ossimPlanetOperationMultiThreadQueue::operationQueue() const 
+{ 
+	return theOperationQueue.get(); 
+}
+
+void ossimPlanetOperationMultiThreadQueue::add(ossimPlanetOperation* operation, bool guaranteeUniqueFlag)
+{
+	theOperationQueue->add(operation, guaranteeUniqueFlag);
+}
+
+/** Remove operation from OperationQueue.*/
+void ossimPlanetOperationMultiThreadQueue::remove(ossimPlanetOperation* operation)
+{
+	theOperationQueue->remove(operation);
+}
+
+/** Remove named operation from OperationQueue.*/
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationMultiThreadQueue::removeByName(const ossimString& name)
+{
+	return theOperationQueue->removeByName(name);
+}
+/** Remove named operation from OperationQueue.*/
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetOperationMultiThreadQueue::removeById(const ossimString& id)
+{
+	return theOperationQueue->removeById(id);
+}
+
+/** Remove all operations from OperationQueue.*/
+void ossimPlanetOperationMultiThreadQueue::removeAllOperations()
+{
+	theOperationQueue->removeAllOperations();
+}
+
+void ossimPlanetOperationMultiThreadQueue::cancelCurrentOperation()
+{
+	OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+	ossim_uint32 idx = 0;
+	for(idx = 0; idx < theThreadQueueList.size();++idx)
+	{
+		theThreadQueueList[idx]->cancelCurrentOperation();
+	}
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetOssimElevationDatabase.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimElevationDatabase.cpp
new file mode 100644
index 0000000..b82843f
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimElevationDatabase.cpp
@@ -0,0 +1,355 @@
+#include <ossimPlanet/ossimPlanetOssimElevationDatabase.h>
+#include <ossimPlanet/ossimPlanetGrid.h>
+
+ossimPlanetOssimElevationDatabase::ossimPlanetOssimElevationDatabase()
+:ossimPlanetElevationDatabase()
+{
+}
+
+ossimPlanetOssimElevationDatabase::ossimPlanetOssimElevationDatabase(const ossimPlanetOssimElevationDatabase& src)
+:ossimPlanetElevationDatabase(src),
+m_cellDatabaseFlag(src.m_cellDatabaseFlag),
+m_database(src.m_database)
+{
+}
+
+ossimPlanetOssimElevationDatabase::~ossimPlanetOssimElevationDatabase()
+{
+}
+
+ossimPlanetTextureLayer* ossimPlanetOssimElevationDatabase::dup()const
+{
+   return new ossimPlanetOssimElevationDatabase(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetOssimElevationDatabase::dupType()const
+{
+   return new ossimPlanetOssimElevationDatabase();
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimElevationDatabase::updateExtents()
+{
+   ossimPlanetTextureLayerStateCode result = ossimPlanetTextureLayer_VALID;
+   if(m_database.valid())
+   {
+      theExtents = new ossimPlanetExtents;
+      ossim_float64 meanGsd = m_database->getMeanSpacingMeters();
+      
+      if(ossim::isnan(meanGsd))
+      {
+         
+         theExtents->setMinMaxScale(meanGsd, meanGsd*64);//pow(2.0, 5.0));
+      }
+   }
+   else
+   {
+      result = ossimPlanetTextureLayer_NOT_OPENED;
+   }
+   theDirtyExtentsFlag = false;
+   return result;
+}
+
+void ossimPlanetOssimElevationDatabase::updateStats()const
+{
+   theStats->setTotalTextureSize(0);
+   theDirtyStatsFlag = false;
+}
+
+void ossimPlanetOssimElevationDatabase::resetStats()const
+{
+   theStats->setBytesTransferred(0);
+   theStats->setTotalTextureSize(0);
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimElevationDatabase::open(const std::string& location)
+{
+   return ossimPlanetTextureLayer_NOT_OPENED;
+}
+
+bool ossimPlanetOssimElevationDatabase::hasTexture(ossim_uint32 width,
+                                                   ossim_uint32 height,
+                                                   const ossimPlanetTerrainTileId& tileId,
+                                                   const ossimPlanetGrid& grid)
+{
+   if(!theEnableFlag||!theExtents.valid())
+   {
+      return false;
+   }
+   ossimPlanetGrid::GridBound bound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      ossimPlanetGrid::GridBound tileBound;
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return false;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   ossimPlanetGrid::ModelPoint minLatLon, maxLatLon;
+   grid.modelBound(tileId, minLatLon, maxLatLon);
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      return true;
+   }
+   
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetOssimElevationDatabase::getTexture(ossim_uint32 width,
+                                                                             ossim_uint32 height,
+                                                                             const ossimPlanetTerrainTileId& tileId,
+                                                                             const ossimPlanetGrid& grid,
+                                                                             ossim_int32 padding)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+
+   if(!theExtents.valid()) return 0;
+   
+   if(m_cellDatabaseFlag&&!grid.isPolar(tileId))
+   {
+     return getTextureCellDatabase(width, height, tileId, grid, padding);
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+      double minValue = 999999999.0;
+      double maxValue = -999999999.0;
+      for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         double h = m_database->getHeightAboveEllipsoid(ossimGpt((*optimizedOutPtr).y(), (*optimizedOutPtr).x()));
+         if(!ossim::isnan(h))
+         {
+            *bufPtr = h;
+         }
+         
+         ++bufPtr;
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+   
+   return texture;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetOssimElevationDatabase::getTextureCellDatabase(ossim_uint32 width,
+                                                                                         ossim_uint32 height,
+                                                                                         const ossimPlanetTerrainTileId& tileId,
+                                                                                         const ossimPlanetGrid& grid,
+                                                                                         ossim_int32 padding)
+
+{
+   ossimElevationCellDatabase* cellElevationDatabase = (ossimElevationCellDatabase*)m_database.get();
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+//   std::cout << "EXTENTS CHECK = " << gsd.y << " < " << theExtents->getMaxScale() << std::endl;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      ossim_float64 minModelX, minModelY, maxModelX, maxModelY;
+      minModelX = points[0].x();
+      maxModelX = minModelX;
+      minModelY = points[0].y();
+      maxModelY = minModelY;
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      ++optimizedOutPtr;
+      for(idxPts = 1; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         if(optimizedOutPtr->x() < minModelX) minModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->x() > maxModelX) maxModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->y() < minModelY) minModelY = optimizedOutPtr->y();
+         if(optimizedOutPtr->y() > maxModelY) maxModelY = optimizedOutPtr->y();
+      }
+      ossim_int32 wholeMinY = (ossim_int32)std::floor(minModelY);
+      ossim_int32 wholeMinX = (ossim_int32)std::floor(minModelX);
+      ossim_int32 wholeMaxY = (ossim_int32)std::floor(maxModelY);
+      ossim_int32 wholeMaxX = (ossim_int32)std::floor(maxModelX);
+      ossim_int32 lat = wholeMaxY;
+      ossim_int32 lon = wholeMinX;
+      
+      std::vector<ossimGpt> latLonOrigins;
+      
+      for(;lat >= wholeMinY; --lat)
+      {
+         lon = wholeMinX;
+         for(;lon <= wholeMaxX; ++lon)
+         {
+            ossimGpt gpt(lat, lon);
+            if(m_database->pointHasCoverage(gpt))
+            {
+               latLonOrigins.push_back(gpt);
+            }
+         }
+      }
+      
+      osg::Vec3d latLonPoint;
+      double minValue = 1.0/DBL_EPSILON -1;
+      double maxValue = -1.0/DBL_EPSILON +1;
+      if(latLonOrigins.size() == 0)
+      {
+         return 0;
+      }
+      ossim_uint32 idx  = 0;
+      ossim_uint32 numberOfFilesNeeded = latLonOrigins.size();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_uint32 numberNeeded = latLonOrigins.size();
+      for(idx = 0; idx < numberNeeded;++idx)
+      {
+         ossimRefPtr<ossimElevCellHandler> cellHandler = cellElevationDatabase->getOrCreateCellHandler(latLonOrigins[idx]);
+         if(cellHandler.valid())
+         {
+            ossimGrect grect = cellHandler->getBoundingGndRect();
+            ossim_float64 minLat = grect.ll().latd();
+            ossim_float64 minLon = grect.ll().lond();
+            ossim_float64 maxLat = grect.ur().latd();
+            ossim_float64 maxLon = grect.ur().lond();
+            ossim_float64 nullHeight = cellHandler->getNullHeightValue();
+            ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+            optimizedOutPtr = &points.front();
+            for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+            {
+               if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&
+                  (optimizedOutPtr->y() >= minLat)&&
+                  (optimizedOutPtr->y() <= maxLat)&&
+                  (optimizedOutPtr->x() >= minLon)&&
+                  (optimizedOutPtr->x() <= maxLon))
+               {
+                  double h = cellHandler->getHeightAboveMSL(ossimGpt(optimizedOutPtr->y(),
+                                                                     optimizedOutPtr->x()));
+                  if(!ossim::isnan(h)&&
+                     (h!=nullHeight))
+                  {
+                     if(theGeoRefModel.valid())
+                     {
+                        h+=theGeoRefModel->getGeoidOffset(optimizedOutPtr->y(), optimizedOutPtr->x());
+                     }
+                     *bufPtr = h;
+                     if(h < minValue)
+                     {
+                        minValue = h;
+                     }
+                     if(h > maxValue)
+                     {
+                        maxValue = h;
+                     }
+                  }
+               }
+               ++bufPtr;
+            }
+         }
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+   
+   return texture;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImage.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImage.cpp
new file mode 100644
index 0000000..53634a8
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImage.cpp
@@ -0,0 +1,43 @@
+#include <ossimPlanet/ossimPlanetOssimImage.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossim/imaging/ossimImageHandlerRegistry.h>
+#include <ossim/base/ossimRefPtr.h>
+#include <ossim/base/ossimIrect.h>
+#include <ossim/imaging/ossimImageData.h>
+#include <ossim/imaging/ossimImageHandler.h>
+
+ossimPlanetOssimImage::ossimPlanetOssimImage()
+{
+}
+ossimPlanetOssimImage::~ossimPlanetOssimImage()
+{
+}
+
+bool ossimPlanetOssimImage::loadFile(const std::string& inputFile,
+                                   ossimPlanetImage& image)
+{
+   if(theHandler.valid())
+   {
+      theHandler->close();
+      if(!theHandler->open(ossimFilename(inputFile)))
+      {
+         theHandler = 0;
+      }
+   }
+   ossimRefPtr<ossimImageData> data;
+   if(!theHandler.valid())
+   {
+       theHandler = ossimImageHandlerRegistry::instance()->open(ossimFilename(inputFile.c_str()));
+   }
+   if(theHandler.valid())
+   {
+      data = theHandler->getTile(theHandler->getBoundingRect());
+      if(data.valid())
+      {
+         image.fromOssimImage(data);
+         return true;
+      }
+   }
+
+   return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImageLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImageLayer.cpp
new file mode 100644
index 0000000..be25f28
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetOssimImageLayer.cpp
@@ -0,0 +1,1374 @@
+#include <ossimPlanet/ossimPlanetOssimImageLayer.h>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossim/imaging/ossimImageHandlerRegistry.h>
+#include <ossim/imaging/ossimBandSelector.h>
+#include <ossim/imaging/ossimScalarRemapper.h>
+#include <ossim/imaging/ossimNitfTileSource.h>
+#include <ossim/base/ossimScalarTypeLut.h>
+#include <ossim/support_data/ossimNitfImageHeader.h>
+#include <ossim/projection/ossimProjectionFactoryRegistry.h>
+#include <ossim/projection/ossimImageViewTransform.h>
+#include <ossim/projection/ossimImageViewProjectionTransform.h>
+#include <ossim/imaging/ossimFilterResampler.h>
+#include <ossim/imaging/ossimCacheTileSource.h>
+#include <ossim/imaging/ossimMeanMedianFilter.h>
+#include <ossimPlanet/mkUtils.h>
+#include <osg/io_utils>
+ossimPlanetOssimImageLayer::ossimPlanetOssimImageLayer()
+:theCut(0),
+ossimPlanetTextureLayer(),
+theHistogramRemapper(0),
+theHistogramStretchMode(ossimHistogramRemapper::STRETCH_UNKNOWN),
+theHistogramStretchEnableFlag(false),
+theCenterLat(0.0),
+theCenterLon(0.0),
+theLength(0.0)
+{
+   theViewInterface = 0;
+   theStateCode = ossimPlanetTextureLayer_NOT_OPENED;
+}
+
+ossimPlanetOssimImageLayer::ossimPlanetOssimImageLayer(const ossimPlanetOssimImageLayer& src)
+:ossimPlanetTextureLayer(src),
+theCut(0),
+theFilename(src.theFilename),
+theCenterLat(src.theCenterLat),
+theCenterLon(src.theCenterLon)
+{
+   theHistogramRemapper = 0;
+   if(src.theSource.valid())
+   {
+      theSource = (ossimImageHandler*)src.theSource->dup();
+   }
+   theViewInterface = 0;
+   theRenderer = 0;
+   theChain.clear();
+   theImageSpaceChain.clear();
+   theProjection = 0;
+   buildChain();
+}
+
+ossimPlanetOssimImageLayer::~ossimPlanetOssimImageLayer()
+{
+   if(theSource.valid())
+   {
+      theSource->disconnect();
+      theSource = 0;
+   }
+   theRenderer = 0;
+   clearChains();
+}
+void ossimPlanetOssimImageLayer::clearChains()
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theChain.size(); ++idx)
+   {
+      theChain[idx]->disconnect();
+      theChain[idx] = 0;
+   }
+   theChain.clear();
+   for(idx = 0; idx < theImageSpaceChain.size(); ++idx)
+   {
+      theImageSpaceChain[idx]->disconnect();
+      theImageSpaceChain[idx] = 0;
+   }
+   theImageSpaceChain.clear();
+   
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::openImage(const ossimFilename& filename,
+                                                                       ossim_int32 entryIdx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   theViewInterface = 0;
+   theFilename = "";
+   theSource = 0;
+   theRenderer = 0;
+   theCenterLat = 0.0;
+   theCenterLon = 0.0;
+   theLength    = 0.0;
+   theHistogramRemapper = 0;
+   theStateCode = ossimPlanetTextureLayer_VALID;
+   
+   ossimRefPtr<ossimImageHandler> source = (ossimImageHandlerRegistry::instance()->open(filename));
+   if(theOverviewFile.exists()&&source.valid())
+   {
+      source->openOverview(theOverviewFile);
+   }
+   if(source.valid()&&(entryIdx > -1))
+   {
+      if(!source->setCurrentEntry(entryIdx))
+      {
+         setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+         return theStateCode;
+      }
+   }
+   else if(!source.valid())
+   {
+      setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+      return theStateCode;
+   }
+   setState (setHandler(source) );
+   return theStateCode;
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::setCurrentEntry(ossim_int32 idx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   theViewInterface = 0;
+   theRenderer = 0;
+   theCenterLat = 0.0;
+   theCenterLon = 0.0;
+   theLength    = 0.0;
+   theHistogramRemapper = 0;
+   theStateCode = ossimPlanetTextureLayer_VALID;
+   
+   if(theSource.valid())
+   {
+      if(!theSource->setCurrentEntry(idx))
+      {
+         setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+         return theStateCode;
+      }
+   }
+   else
+   {
+      setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+      return theStateCode;
+   }
+   if(theOverviewFile.exists()&&theSource.valid())
+   {
+      theSource->openOverview(theOverviewFile);
+   }
+   setState(setHandler(theSource.get()));
+   return theStateCode;
+}
+
+ossim_uint32 ossimPlanetOssimImageLayer::getNumberOfEntries()const
+{
+   if(theSource.valid())
+   {
+      return theSource->getNumberOfEntries();
+   }
+   
+   return 0;   
+}
+
+void ossimPlanetOssimImageLayer::setOverviewFile(const ossimFilename& filename)
+{
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+      theOverviewFile = filename;
+      if(theSource.valid())
+      {
+         if(theOverviewFile.exists())
+         {
+            if(theSource->openOverview(theOverviewFile))
+            {
+               clearState(ossimPlanetTextureLayer_NO_OVERVIEWS);
+            }
+         }
+         else
+         {
+            theSource->closeOverview();
+         }
+         dirtyExtents();
+      }
+      notifyPropertyChanged("overviewFilename", this);
+	}
+	if(filename.exists())
+	{
+		notifyRefreshExtent(theExtents.get());
+	}
+}
+
+void ossimPlanetOssimImageLayer::setHistogramFile(const ossimFilename& file)
+{
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+      theHistogramFile = file;
+      if(theHistogramRemapper)
+      {
+         if(theHistogramRemapper->openHistogram(file))
+         {
+            theHistogramRemapper->setStretchMode(theHistogramStretchMode);
+            clearState(ossimPlanetTextureLayer_NO_HISTOGRAMS);
+         }
+         dirtyExtents();
+      }
+      notifyPropertyChanged("histogramFilename", this);
+	}
+	if(file.exists())
+	{
+		notifyRefreshExtent(theExtents.get());
+	}
+}
+
+void ossimPlanetOssimImageLayer::setHistogramStretchMode(const ossimString& mode)
+{
+   bool changed = false;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+      
+      if(mode == "None")
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::STRETCH_UNKNOWN;
+      }
+      else if(mode == "Linear Auto Min Max")
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::LINEAR_AUTO_MIN_MAX;
+      }
+      else if(mode == "1 Standard Deviation")
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::LINEAR_1STD_FROM_MEAN;
+      }
+      else if(mode == "2 Standard Deviation")
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::LINEAR_2STD_FROM_MEAN;
+      }
+      else if(mode == "3 Standard Deviation")
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::LINEAR_3STD_FROM_MEAN;
+      }
+      else
+      {
+         theHistogramStretchMode = ossimHistogramRemapper::STRETCH_UNKNOWN;
+      }
+      if(theHistogramRemapper)
+      {
+         changed = theHistogramRemapper->getStretchMode() != theHistogramStretchMode;
+         theHistogramRemapper->setStretchMode(theHistogramStretchMode);
+      }
+   }
+   if(changed)
+   {
+      notifyRefreshExtent(theExtents.get());
+   }
+}
+
+void ossimPlanetOssimImageLayer::setHistogramStretchEnableFlag(bool flag)
+{
+   bool changed = false;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+      if(theHistogramRemapper)
+      {
+         theHistogramStretchEnableFlag = flag;
+         if(flag != theHistogramRemapper->getEnableFlag())
+         {
+            theHistogramRemapper->setEnableFlag(theHistogramStretchEnableFlag);
+            changed = true;
+         }
+      }
+   }
+   if(changed)
+   {
+      notifyRefreshExtent(theExtents.get());
+   }
+}
+
+ossimString ossimPlanetOssimImageLayer::histogramStretchMode()const
+{
+	OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   switch(theHistogramStretchMode)
+   {
+      case ossimHistogramRemapper::STRETCH_UNKNOWN:
+      {
+         return "None";
+      }
+      case ossimHistogramRemapper::LINEAR_AUTO_MIN_MAX:
+      {
+         return "Linear Auto Min Max";
+      }
+      case ossimHistogramRemapper::LINEAR_1STD_FROM_MEAN:
+      {
+         return "1 Standard Deviation";
+      }
+      case ossimHistogramRemapper::LINEAR_2STD_FROM_MEAN:
+      {
+         return "2 Standard Deviation";
+      }
+      case ossimHistogramRemapper::LINEAR_3STD_FROM_MEAN:
+      {
+         return "3 Standard Deviation";
+      }
+		default:
+		{
+			break;
+		}
+   }
+   return "None";
+}
+
+void ossimPlanetOssimImageLayer::getHistogramStretchModes(std::vector<ossimString>& modes)
+{
+   modes.push_back("None");
+   modes.push_back("Linear Auto Min Max");
+   modes.push_back("1 Standard Deviation");
+   modes.push_back("2 Standard Deviation");
+   modes.push_back("3 Standard Deviation");
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::setHandler(ossimRefPtr<ossimImageHandler> handler)
+{
+   theFilename = "";
+   theSource = handler;
+   theRenderer = 0;
+   theCenterLat = 0.0;
+   theCenterLon = 0.0;
+   theLength    = 0.0;
+   
+   if(handler.valid())
+   {
+      theFilename = handler->getFilename();
+      if(name().empty())
+      {
+         ossimString name = theFilename.file();
+         
+         if(handler->getNumberOfEntries() > 1)
+         {
+            name +=  ": entry " + ossimString::toString(handler->getCurrentEntry());
+         }
+         setName(name);
+      }
+   }
+	
+   return buildChain();
+}
+
+ossimRefPtr<ossimImageHandler> ossimPlanetOssimImageLayer::getHandler()
+{
+   return theSource;
+}
+
+const ossimRefPtr<ossimImageHandler> ossimPlanetOssimImageLayer::getHandler()const
+{
+   return theSource;
+}
+
+double ossimPlanetOssimImageLayer::getApproximateHypotneusLength()const
+{
+   return theLength;
+}
+
+ossimPlanetTextureLayer* ossimPlanetOssimImageLayer::dup()const
+{
+   return new ossimPlanetOssimImageLayer(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetOssimImageLayer::dupType()const
+{
+   return new ossimPlanetOssimImageLayer;
+}
+
+ossimString ossimPlanetOssimImageLayer::getClassName()const
+{
+   return "ossimPlanetOssimImageLayer";
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::updateExtents()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   return updateExtentsNoMutex();
+}
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::updateExtentsNoMutex()
+{
+   if(!theDirtyExtentsFlag) return theStateCode;
+
+   clearState(ossimPlanetTextureLayerStateCode(ossimPlanetTextureLayer_NO_OVERVIEWS |
+                                               ossimPlanetTextureLayer_NO_GEOM |
+                                               ossimPlanetTextureLayer_NO_SOURCE_DATA));
+   theCenterLat = 0.0;
+   theCenterLon = 0.0;
+   theLength    = 0.0;
+   theInputProjection = 0;
+   if(theSource.valid())
+   {
+      double levels = theSource->getNumberOfDecimationLevels();
+      ossimRefPtr<ossimImageGeometry> geom = theSource->getImageGeometry();
+      theInputProjection = geom.valid()?geom->getProjection():0;
+      if(levels == 1)
+      {
+         setState(ossimPlanetTextureLayer_NO_OVERVIEWS);
+      }
+      
+      if(theInputProjection.valid())
+      {
+         
+         ossimGpt ulGpt;
+         ossimGpt urGpt;
+         ossimGpt lrGpt;
+         ossimGpt llGpt;
+         ossimGpt centerGpt;
+         
+         ossimIrect rect = theSource->getBoundingRect();
+         geom->localToWorld(rect.midPoint(),
+                                               centerGpt);
+         theCenterLat = centerGpt.latd();
+         theCenterLon = centerGpt.lond();
+         
+         geom->localToWorld(rect.ul(),
+                            ulGpt);
+         geom->localToWorld(rect.ur(),
+                            urGpt);
+         geom->localToWorld(rect.lr(),
+                            lrGpt);
+         geom->localToWorld(rect.ll(),
+                            llGpt);
+         ossimDpt metersPerPixel = geom->getMetersPerPixel();
+         theLength = ((rect.ul()-rect.lr()).length()*
+                      (metersPerPixel.y));
+         
+         ossim_uint32 levels = theSource->getNumberOfDecimationLevels();
+         ossim_uint32 stopLevels = levels;
+         ossim_uint32 idx = 0;
+#if 1
+         for(idx = 0; idx < levels; ++idx)
+         {
+            ossimIrect rect = theSource->getBoundingRect(idx);
+            if((rect.width()>16)||(rect.height()>16))
+            {
+               ++stopLevels;
+            }
+            else
+            {
+               break;
+            }
+         }
+#endif
+         theExtents->setMinMaxScale(metersPerPixel.y,
+                                    metersPerPixel.y*std::pow(2.0, (double)(stopLevels)));// clamp the zoom out though
+         theExtents->setMinMaxLatLon(mkUtils::clamp(ossim::min(ulGpt.latd(),ossim::min(urGpt.latd(),ossim::min(lrGpt.latd(),llGpt.latd()))), -90.0, 90.0),
+                                     mkUtils::clamp(ossim::min(ulGpt.lond(),ossim::min(urGpt.lond(),ossim::min(lrGpt.lond(),llGpt.lond()))), -180.0, 180.0),
+                                     mkUtils::clamp(ossim::max(ulGpt.latd(),ossim::max(urGpt.latd(),ossim::max(lrGpt.latd(),llGpt.latd()))), -90.0, 90.0),
+                                     mkUtils::clamp(ossim::max(ulGpt.lond(),ossim::max(urGpt.lond(),ossim::max(lrGpt.lond(),llGpt.lond()))), -180.0, 180.0));        
+         
+//         std::cout << theExtents->getMinLon() << ", " << theExtents->getMinLat() << ", " << theExtents->getMaxLon() << ", " << theExtents->getMaxLat() << std::endl;
+      }
+      else
+      {
+         setState(ossimPlanetTextureLayer_NO_GEOM);
+      }
+   }
+   else
+   {
+      setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+   }
+   theDirtyExtentsFlag = false;
+   updateStats();
+   
+   
+   return theStateCode;
+}
+
+void ossimPlanetOssimImageLayer::updateStats()const
+{
+   if(theSource.valid())
+   {
+      ossimIrect rect = theSource->getBoundingRect();
+      ossim_uint64 bands = theSource->getNumberOfInputBands();
+      ossimScalarType scalarType = theSource->getOutputScalarType();
+      ossim_uint64 w = rect.width();
+      ossim_uint64 h = rect.height();
+      ossim_uint64 scalarSizeInBytes = ossim::scalarSizeInBytes(scalarType); 
+      theStats->setTotalTextureSize(scalarSizeInBytes*w*h*bands);
+      
+      if(theSource->getNumberOfDecimationLevels()>1)
+      {
+         ossim_uint32 levels = theSource->getNumberOfDecimationLevels();
+         ossim_uint32 idx = 0;
+         for(idx=1; idx < levels; ++idx)
+         {
+            rect = theSource->getBoundingRect(idx);
+            w = rect.width();
+            h = rect.height();
+            theStats->setTotalTextureSize(theStats->totalTextureSize() +
+                                          scalarSizeInBytes*w*h*bands);
+            
+         }
+      }
+   }
+   theDirtyStatsFlag = false;
+}
+
+void ossimPlanetOssimImageLayer::resetStats()const
+{
+   updateStats();
+   theStats->setBytesTransferred(0);
+}
+
+ossimScalarType ossimPlanetOssimImageLayer::scalarType()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   if(theSource.valid())
+   {
+      return theSource->getOutputScalarType();
+   }
+   
+   return OSSIM_SCALAR_UNKNOWN;
+}
+
+bool ossimPlanetOssimImageLayer::hasTexture(ossim_uint32 width,
+                                            ossim_uint32 height,
+                                            const ossimPlanetTerrainTileId& tileId,
+                                            const ossimPlanetGrid& grid)
+{
+   if(!getEnableFlag())
+   {
+      return false;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   if(!theInputProjection.valid() ||
+      !theSource.valid())
+   {
+      return false;
+   }
+   osg::Vec2d metersPerPixel;
+   grid.getUnitsPerPixel(metersPerPixel, tileId, width, height, OSSIM_METERS);
+   ossimDpt metersGsd(metersPerPixel[0], metersPerPixel[1]);
+   if(theExtents.valid())
+   {
+      osg::ref_ptr<ossimPlanetExtents> extents = new ossimPlanetExtents;
+      if(grid.convertToGeographicExtents(tileId, *extents, width, height))
+      {
+         if(theExtents->intersectsLatLon(*extents)&&
+            theExtents->intersectsScale(*extents))
+         {
+            return true;
+         }
+      }
+   }
+
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetOssimImageLayer::getTexture(ossim_uint32 width,
+                                                                      ossim_uint32 height,
+                                                                      const ossimPlanetTerrainTileId& tileId,
+                                                                      const ossimPlanetGrid& grid,
+                                                                      ossim_int32 /*padding*/)
+{
+   if(!getEnableFlag())
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   if(!theInputProjection.valid() ||
+      !theSource.valid())
+   {
+      return 0;
+   }
+   
+   osg::ref_ptr<ossimPlanetExtents> tileExtents = new ossimPlanetExtents;
+   if(grid.convertToGeographicExtents(tileId, *tileExtents, width, height))
+   {
+      if(theExtents.valid())
+      {
+         if(!theExtents->intersectsLatLon(*tileExtents))
+         {
+            return 0;
+         }
+      }
+   }
+   osg::Vec2d unitsPerPixel;
+   osg::Vec2d metersPerPixel;
+   grid.getUnitsPerPixel(unitsPerPixel, tileId, width, height, OSSIM_DEGREES);
+   grid.getUnitsPerPixel(metersPerPixel, tileId, width, height, OSSIM_METERS);
+   ossimDpt gsd(unitsPerPixel[0], unitsPerPixel[1]);
+   ossimDpt metersGsd(metersPerPixel[0], metersPerPixel[1]);
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(metersGsd.y < theExtents->getMaxScale())
+   {
+//      std::cout << "LEVEL === " << tileId.level() << std::endl;
+      if(!grid.isPolar(tileId))
+      {
+         ossimIrect requestRect(0,
+                                0,
+                                width-1,
+                                height-1);
+//         theProjection->setDecimalDegreesPerPixel(ossimDpt(deltaLon,
+//                                                           deltaLat));
+         ossimGpt testUl(tileExtents->getMaxLat()-(gsd.y*.5), 
+                         tileExtents->getMinLon()+(gsd.x*.5));
+         theProjection->setDecimalDegreesPerPixel(ossimDpt(gsd.x,
+                                                           gsd.y));
+         theProjection->setUlTiePoints(testUl);
+         theProjection->update();
+         theViewInterface->setView(theImageGeometry.get());
+         theChain[0]->initialize();
+         
+         ossimRefPtr<ossimImageData> data;
+         data = theChain[0]->getTile(requestRect);
+         
+         if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+         {
+            addBytesTransferredStat(data->getSizeInBytes());
+            texture = new ossimPlanetImage(tileId);
+            convertToOsg(data.get(), texture.get());
+            texture->flipVertical();
+         }  
+      }
+      else
+      {
+      //   std::cout << "________________________" << std::endl;
+         ossimPlanetGrid::ModelPoints modelPoints;
+         grid.createModelPoints(tileId,
+                                width,
+                                height,
+                                modelPoints);
+         
+         //std::cout << "NEW WAY" << std::endl;
+         std::vector<osg::Vec2d> minMaxPairs;
+         grid.getInternationalDateLineCrossings(tileId, minMaxPairs);
+         ossim_uint32 size = minMaxPairs.size();
+         ossim_uint32 idx = 0;
+         double maxLon=0.0, minLon=0.0, maxLat=tileExtents->getMaxLat(), minLat=tileExtents->getMinLat();
+         for(idx = 0; idx < size; ++idx)
+         {
+            minLon = minMaxPairs[idx][0];
+            maxLon = minMaxPairs[idx][1];
+            
+            ossim_uint32 dx = (ossim_uint32)(((maxLon-minLon)/gsd.x));//+.5);
+            ossim_uint32 dy = (ossim_uint32)(((maxLat-minLat)/gsd.y));//+.5);
+            ossimIrect requestRect(0,
+                                   0,
+                                   dx-1,
+                                   dy-1);
+            ossimRefPtr<ossimImageData> data;
+            
+            ossim_float32 tiles = (double)requestRect.width()/(double)width;
+            ossim_uint32 nTiles = floor((double)requestRect.width()/(double)width);
+            ossim_float32 residualTile = tiles - nTiles;
+            ossim_uint32 tileX = 0;
+            theProjection->setDecimalDegreesPerPixel(gsd);
+#if 0
+            theProjection->setUlTiePoints(ossimGpt(maxLat-(gsd.y*.5), 
+                                                   minLon+(gsd.x*.5)));
+            theViewInterface->setView(theImageGeometry.get());
+            data = theChain[0]->getTile(requestRect);
+            theChain->initialize();
+            if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+            {
+               addBytesTransferredStat(data->getSizeInBytes());
+               if(!texture.valid())
+               {
+                  texture = new ossimPlanetImage(tileId);
+               }
+               
+               convertToOsg(data.get(),
+                            texture.get(),
+                            osg::Vec2d(minLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon,//deltaLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon,//deltaLon,
+                                       minLat),//deltaLat),
+                            osg::Vec2d(minLon,
+                                       minLat),//deltaLat),
+                            modelPoints,
+                            width,
+                            height);
+               
+            }
+#else
+            for(tileX = 0; tileX < nTiles; ++tileX)
+            {
+               ossimIpt origin(tileX*width, 0);
+               ossimIrect tempRect(0, 0, width - 1, dy-1);
+               
+               double tempMinLon = minLon     + gsd.x*(origin.x);
+               double tempMaxLon = tempMinLon + gsd.x*width;
+               theProjection->setUlTiePoints(ossimGpt(maxLat-(gsd.y*.5), 
+                                                      tempMinLon+(gsd.x*.5)));
+               theViewInterface->setView(theImageGeometry.get());
+               theChain[0]->initialize();
+               data = theChain[0]->getTile(tempRect);
+               if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+               {
+                  if(!texture.valid())
+                  {
+                     texture = new ossimPlanetImage(tileId);
+                  }
+                  
+                  convertToOsg(data.get(),
+                               texture.get(),
+                               osg::Vec2d(tempMinLon,
+                                          maxLat),
+                               osg::Vec2d(tempMaxLon,//deltaLon,
+                                          maxLat),
+                               osg::Vec2d(tempMaxLon,//deltaLon,
+                                          minLat),//deltaLat),
+                               osg::Vec2d(tempMinLon,
+                                          minLat),//deltaLat),
+                               modelPoints,
+                               width,
+                               height);
+                  
+               }
+               data = 0;
+            }
+            if(residualTile > FLT_EPSILON)
+            {
+               ossim_uint32 w = (residualTile*width);
+               ossimIpt origin(nTiles*width, 0);
+               ossimIrect tempRect(0, 0, w - 1, dy-1);
+               double tempMinLon = minLon + gsd.x*(origin.x);
+               double tempMaxLon = maxLon;
+               theProjection->setUlTiePoints(ossimGpt(maxLat,//-(deltaLat*.5), 
+                                                      tempMinLon));//+(deltaLon*.5)));
+               theViewInterface->setView(theImageGeometry.get());
+               theChain[0]->initialize();
+               data = theChain[0]->getTile(tempRect);
+               if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+               {
+                  if(!texture.valid())
+                  {
+                     texture = new ossimPlanetImage(tileId);
+                     if(texture->data())
+                     {
+                        memset(texture->data(), '\0', texture->getWidth()*texture->getHeight()*4);
+                     }
+                  }
+                  
+                  convertToOsg(data.get(),
+                               texture.get(),
+                               osg::Vec2d(tempMinLon,
+                                          maxLat),
+                               osg::Vec2d(tempMaxLon,//deltaLon,
+                                          maxLat),
+                               osg::Vec2d(tempMaxLon,//deltaLon,
+                                          minLat),//deltaLat),
+                               osg::Vec2d(tempMinLon,
+                                          minLat),//deltaLat),
+                               modelPoints,
+                               width,
+                               height);
+                  
+               }
+               data = 0;
+            }
+#endif
+         }
+      }
+   }
+   return texture;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetOssimImageLayer::getTexture(ossim_uint32 level,
+                                                                      ossim_uint64 row,
+                                                                      ossim_uint64 col,
+                                                                      const ossimPlanetGridUtility& utility)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   if(!getEnableFlag())
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theOssimImageLayerMutex);
+   
+   if(!theProjection.valid() ||
+      !theSource.valid())
+   {
+      return 0;
+   }
+   
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+   unsigned int w = utility.getTileWidth();
+   unsigned int h = utility.getTileHeight();
+   
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, // row 
+                           col);
+   if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+   {
+      return 0;
+   }
+   
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/h;
+   double deltaLon    = deltaX/w;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      if(utility.getFace(level, row, col)<4)
+      {
+         ossimIrect requestRect(0,
+                                0,
+                                w-1,
+                                h-1);
+         theProjection->setDecimalDegreesPerPixel(ossimDpt(deltaLon,
+                                                           deltaLat));
+         
+         theProjection->setUlGpt(ossimGpt(maxLat-deltaLat*.5, minLon+deltaLon*.5));
+         //theProjection->setUlGpt(ossimGpt(maxLat, minLon));
+         theViewInterface->setView(theImageGeometry.get());
+         ossimRefPtr<ossimImageData> data;
+          data = theChain[0]->getTile(requestRect);
+         
+         if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+         {
+            addBytesTransferredStat(data->getSizeInBytes());
+            texture = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                           level,
+                                           col,
+                                           row));
+            convertToOsg(data.get(), texture.get());
+            texture->flipVertical();
+         }  
+      }
+      else
+      {
+        // std::cout << "________________________________" << std::endl;
+         std::vector<ossimPlanetGridUtility::GridPoint> points;
+         utility.createGridPoints(points,
+                                  level,
+                                  row,
+                                  col,
+                                  w,
+                                  h);
+         osg::Vec3d llTemp;
+         utility.getLatLon(llTemp, points[0]);
+
+         std::vector<osg::Vec2d> minMaxPairs;
+         utility.getGeographicLonCrossings(minMaxPairs, level, row, col);
+         
+         ossim_uint32 size = minMaxPairs.size();
+         ossim_uint32 idx = 0;
+         //std::cout << "OLD WAY!" << std::endl;
+         for(idx = 0; idx < size; ++idx)
+         {
+            minLon = minMaxPairs[idx][0];
+            maxLon = minMaxPairs[idx][1];
+            //std::cout << "minLon = " << minLon << std::endl;
+            //std::cout << "maxLon = " << maxLon << std::endl;
+            
+            ossim_uint32 dx = (ossim_uint32)(((maxLon-minLon)/deltaLon));//+.5);
+            ossim_uint32 dy = (ossim_uint32)(((maxLat-minLat)/deltaLat));//+.5);
+            ossimDpt degreesPerPixel(deltaLon,
+                                     deltaLat);
+            //std::cout << "degrees per pix = " << degreesPerPixel << std::endl;
+            theProjection->setDecimalDegreesPerPixel(degreesPerPixel);
+            theProjection->setUlGpt(ossimGpt(maxLat-deltaLat*.5, minLon+deltaLon*.5));
+           // theProjection->setUlGpt(ossimGpt(maxLat, minLon));
+            //std::cout << "Ul tie = " << ossimGpt(maxLat, minLon) << std::endl;
+            theViewInterface->setView(theImageGeometry.get());
+            ossimIrect requestRect(0,
+                                   0,
+                                   dx-1,
+                                   dy-1);
+            ossimRefPtr<ossimImageData> data;
+            data = theChain[0]->getTile(requestRect);
+            if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+            {
+               addBytesTransferredStat(data->getSizeInBytes());
+               if(!texture.valid())
+               {
+                  texture = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                                                          level,
+                                                                          col,
+                                                                          row));
+               }
+               
+               convertToOsg(data.get(),
+                            texture.get(),
+                            osg::Vec2d(minLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon+deltaLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon+deltaLon,
+                                       minLat-deltaLat),
+                            osg::Vec2d(minLon,
+                                       minLat-deltaLat),
+                            points,
+                            utility,
+                            w,
+                            h);
+               
+            }
+         }
+      }
+   }
+   return texture;
+}
+
+void ossimPlanetOssimImageLayer::getCenterLatLonLength(double& centerLat,
+                                                       double& centerLon,
+                                                       double& length)const
+{
+   centerLat = theCenterLat;
+   centerLon = theCenterLon;
+   length    = theLength;
+}
+
+void ossimPlanetOssimImageLayer::setFilterType(const ossimString& filterType)
+{
+   ossimPlanetTextureLayer::setFilterType(filterType);
+   if(theRenderer.valid())
+   {
+      theRenderer->getResampler()->setFilterType(theFilterType);
+   }
+}
+
+bool ossimPlanetOssimImageLayer::isMultiEntry()const
+{
+   if(theSource.valid())
+   {
+      return (theSource->getNumberOfEntries() > 1);
+   }
+   
+   return false;
+}
+
+bool ossimPlanetOssimImageLayer::buildOverview()
+{
+   if(theSource.valid())
+   {
+      return theSource->buildOverview();
+   }
+   
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetOssimImageLayer::groupAllEntries()
+{
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> groupResult = new ossimPlanetTextureLayerGroup;
+   if(theSource.valid())
+   {
+      ossim_uint32 thisEntry = theSource->getCurrentEntry();
+      std::vector<ossim_uint32> entryList;
+      theSource->getEntryList(entryList);
+      
+      for(ossim_uint32 idx = 0; idx < entryList.size(); ++idx)
+      {
+         if(entryList[idx] != thisEntry)
+         {
+            osg::ref_ptr<ossimPlanetOssimImageLayer> layer = new ossimPlanetOssimImageLayer;         
+            ossimRefPtr<ossimImageHandler> handler = (ossimImageHandler*)theSource->dup();
+            handler->setCurrentEntry(entryList[idx]);
+            layer->setHandler(handler.get());
+				layer->dirtyExtents();
+				layer->updateExtents();
+            groupResult->addBottom(layer.get());
+         }
+      }
+      
+      groupResult->addTop(this);
+   }
+   return groupResult.get();
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetOssimImageLayer::buildChain()
+{
+   clearChains();
+   theHistogramRemapper = 0;
+   if(theSource.valid())
+   {
+      theChain.push_back(theSource.get());
+      //ossimMeanMedianFilter* expand = new ossimMeanMedianFilter;
+      //expand->setEnableFlag(true);
+      //expand->setWindowSize(3);
+      //expand->setFilterType(ossimMeanMedianFilter::OSSIM_MEAN_NULL_CENTER_ONLY);
+      //expand->setAutoGrowRectFlag(true);
+      //expand->connectMyInputTo(0, theChain[0].get());
+      //theChain.insert(theChain.begin(), expand);
+      if(theSource->getNumberOfOutputBands() > 3)
+      {
+         std::vector<ossim_uint32> outputBandList;
+         outputBandList.push_back(0);
+         outputBandList.push_back(1);
+         outputBandList.push_back(2);
+         ossimBandSelector* bandSelector = new ossimBandSelector;
+         bandSelector->setOutputBandList(outputBandList);
+         bandSelector->connectMyInputTo(0, theChain[0].get());
+         theChain.insert(theChain.begin(), bandSelector);
+         theImageSpaceChain.insert(theImageSpaceChain.begin(), bandSelector);
+      }
+      else if(theSource->getNumberOfOutputBands() <3)
+      {
+         std::vector<ossim_uint32> outputBandList;
+         outputBandList.push_back(0);
+         outputBandList.push_back(0);
+         outputBandList.push_back(0);
+         ossimBandSelector* bandSelector = new ossimBandSelector;
+         bandSelector->setOutputBandList(outputBandList);
+         bandSelector->connectMyInputTo(0, theChain[0].get());
+         
+         theChain.insert(theChain.begin(), bandSelector);
+         theImageSpaceChain.insert(theImageSpaceChain.begin(), bandSelector);
+     }
+      theHistogramRemapper = new ossimHistogramRemapper;
+      theHistogramRemapper->connectMyInputTo(0, theChain[0].get());
+      if(theHistogramFile.empty())
+      {
+         theHistogramFile = theSource->createDefaultHistogramFilename();
+      }
+      if(theHistogramFile.exists())
+      {
+         theHistogramRemapper->openHistogram(theHistogramFile);
+      }
+		else
+		{
+			setState(ossimPlanetTextureLayer_NO_HISTOGRAMS);
+		}
+      theHistogramRemapper->setStretchMode(theHistogramStretchMode);
+      theHistogramRemapper->setEnableFlag(theHistogramStretchEnableFlag);
+      theChain.insert(theChain.begin(), theHistogramRemapper);
+      theImageSpaceChain.insert(theImageSpaceChain.begin(), theHistogramRemapper);
+      theViewInterface = PTR_CAST(ossimViewInterface, theSource.get());
+      theImageGeometry = new ossimImageGeometry();
+  
+      ossimRefPtr<ossimRectangleCutFilter> theCut = new ossimRectangleCutFilter();
+      theCut->setRectangle(theSource->getBoundingRect());
+      theCut->connectMyInputTo(0, theChain[0].get());
+      theChain.insert(theChain.begin(), theCut.get());
+      
+
+      theProjection = new ossimLlxyProjection;
+     // theProjection = new ossimEquDistCylProjection;
+      
+      theImageGeometry->setProjection(theProjection.get());
+      if(!theViewInterface)
+      {
+         theRenderer = new ossimImageRenderer;
+         theViewInterface = theRenderer.get();
+         theRenderer->setView(theImageGeometry.get());
+         theRenderer->getResampler()->setFilterType(theFilterType);
+         
+         theRenderer->connectMyInputTo(0, theChain[0].get());
+         theChain.insert(theChain.begin(), theRenderer.get());
+         ossimImageViewTransform* ivt = theRenderer->getImageViewTransform();
+         if(ivt)
+         {
+            ossimImageViewProjectionTransform* projectionTransform = PTR_CAST(ossimImageViewProjectionTransform,
+                                                                              ivt);
+            if(projectionTransform)
+            {
+               ossimRefPtr<ossimImageGeometry> geom = projectionTransform->getImageGeometry();
+               if(geom.valid())
+               {
+                  ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection,
+                                                         geom->getProjection());
+                  if(mapProj)
+                  {
+                     mapProj->setElevationLookupFlag(false);
+                     theProjection->setElevationLookupFlag(false);
+                  }
+               }
+            }
+         }
+      }
+      else
+      {
+         theViewInterface->setView(theImageGeometry.get());
+      }
+      if(theSource->getOutputScalarType() != OSSIM_UINT8)
+      {
+         ossimScalarRemapper* scalarRemapper = new ossimScalarRemapper;
+         scalarRemapper->connectMyInputTo(0, theChain[0].get());
+         theChain.insert(theChain.begin(), scalarRemapper);
+         ossimScalarRemapper* scalarRemapper2 = new ossimScalarRemapper;
+         scalarRemapper2->connectMyInputTo(0, theImageSpaceChain[0].get());
+         theImageSpaceChain.insert(theImageSpaceChain.begin(), scalarRemapper2);
+      }
+//      theImageSpaceChain.insert(theImageSpaceChain.begin(), expand);
+      dirtyExtents();
+      updateExtentsNoMutex();
+   }
+   return theStateCode;
+}
+
+void ossimPlanetOssimImageLayer::getMetadata(ossimRefPtr<ossimXmlNode> metadata)const
+{
+   if(theSource.valid())
+   {
+      ossimScalarType scalarType = theSource->getOutputScalarType();
+      metadata->setTag("Layer");
+      metadata->addChildNode("entry",
+                             ossimString::toString(theSource->getCurrentEntry()));
+      metadata->addChildNode("url",
+                             ossimString("file://") + ossimString(theSource->getFilename()));
+      metadata->addChildNode("bits", ossimString::toString(ossim::scalarSizeInBytes(scalarType)*8));
+      ossimString scalarTypeString = ossimScalarTypeLut::instance()->getEntryString((ossim_int32)scalarType);
+      scalarTypeString = scalarTypeString.substitute("ossim_", "");
+      metadata->addChildNode("scalar", scalarTypeString);
+      metadata->addChildNode("PyramidLevels",
+                             ossimString::toString(theSource->getNumberOfDecimationLevels()));
+      ossim_uint32 idx    = 0;
+      ossim_uint32 idxMax = theSource->getNumberOfInputBands();
+      ossimRefPtr<ossimXmlNode> bandListNode = new  ossimXmlNode();
+      
+      bandListNode->setTag("Bands");
+      ossimRefPtr<ossimXmlNode> node = new ossimXmlNode();
+      node->setTag("Count");
+      node->setText(ossimString::toString(idxMax));
+      
+      bandListNode->addChildNode(node.get());
+      metadata->addChildNode(bandListNode.get());
+      for(idx = 0; idx < idxMax; ++idx)
+      {
+         ossimRefPtr<ossimXmlNode> bandNode = new  ossimXmlNode();
+         bandNode->setTag("Band");
+         bandNode->setText(ossimString::toString(idx));
+         bandNode->addChildNode("min", ossimString::toString(theSource->getMinPixelValue(idx)));
+         bandNode->addChildNode("max", ossimString::toString(theSource->getMaxPixelValue(idx)));
+         bandNode->addChildNode("null", ossimString::toString(theSource->getNullPixelValue(idx)));
+         
+         bandListNode->addChildNode(bandNode.get());
+      }
+      
+      std::vector<ossimRefPtr<ossimProperty> > properties;
+      theSource->getPropertyList(properties);
+      
+      ossimRefPtr<ossimXmlNode> nativeProperties = new ossimXmlNode;
+      
+      nativeProperties->setTag("NativeProperties");
+      
+      for(idx = 0; idx < properties.size(); ++idx)
+      {
+         ossimRefPtr<ossimXmlNode> xmlNode = properties[idx]->toXml();
+         if(xmlNode.valid())
+         {
+            nativeProperties->addChildNode(xmlNode.get());
+         }
+      }
+      
+      metadata->addChildNode(nativeProperties.get());
+      
+      ossimRefPtr<ossimXmlNode> modelNode = new  ossimXmlNode();
+      
+      modelNode->setTag("Model");
+      ossimKeywordlist kwl;
+      ossimRefPtr<ossimImageGeometry> geom = theSource->getImageGeometry();
+      if(geom.valid())
+      {
+         if(geom->getProjection())
+         {
+            geom->getProjection()->saveState(kwl);
+         }
+         ossimKeywordlist::KeywordMap::const_iterator iter = kwl.getMap().begin();
+         while(iter != kwl.getMap().end())
+         {
+            ossimRefPtr<ossimXmlNode> modelChildNode = new ossimXmlNode();
+            modelChildNode->setTag(iter->first);
+            modelChildNode->setText(iter->second);
+            modelNode->addChildNode(modelChildNode.get());
+            ++iter;
+         }
+         ossimString type = kwl.find(ossimKeywordNames::TYPE_KW);
+         
+         type = type.substitute("ossim", "");
+         
+         modelNode->setText(type);
+      }
+      metadata->addChildNode(modelNode.get());
+   }
+   
+}
+
+ossimRefPtr<ossimXmlNode> ossimPlanetOssimImageLayer::saveXml(bool /*recurseFlag*/)const
+{
+   ossimRefPtr<ossimXmlNode> result = ossimPlanetTextureLayer::saveXml();
+   
+   result->addChildNode("filename", theFilename);
+   if(theSource.valid())
+   {
+      result->addChildNode("entry", ossimString::toString(theSource->getCurrentEntry()));
+   }
+   if(!theOverviewFile.empty())
+   {
+      result->addChildNode("overviewFilename", theOverviewFile);
+   }
+   result->addChildNode("histogramStretchMode", histogramStretchMode());
+   result->addChildNode("histogramStretchEnabled", ossimString::toString(theHistogramStretchEnableFlag));
+   
+   return result;
+}
+
+bool ossimPlanetOssimImageLayer::loadXml(ossimRefPtr<ossimXmlNode> node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOssimImageLayerMutex);
+   blockCallbacks(true);
+   bool result = false;
+   ossimRefPtr<ossimXmlNode> filenameNode         = node->findFirstNode("filename");
+   ossimRefPtr<ossimXmlNode> overviewFilenameNode = node->findFirstNode("overviewFilename");
+   ossimRefPtr<ossimXmlNode> entryNode            = node->findFirstNode("entry");
+   ossimRefPtr<ossimXmlNode> histogramStretchMode = node->findFirstNode("histogramStretchMode");
+   ossimRefPtr<ossimXmlNode> histogramStretchEnabled = node->findFirstNode("histogramStretchEnabled");
+   if(overviewFilenameNode.valid())
+   {
+      setOverviewFile(ossimFilename(overviewFilenameNode->getText()));
+   }
+   else
+   {
+      setOverviewFile(ossimFilename(""));
+   }
+   result = ossimPlanetTextureLayer::loadXml(node);
+   if(histogramStretchEnabled.valid())
+   {
+      theHistogramStretchEnableFlag = histogramStretchEnabled->getText().toBool();
+   }
+   if(filenameNode.valid()&&result)
+   {
+      ossimFilename filename(filenameNode->getText());
+      ossim_int32 entryIdx = -1;
+      
+      if(entryNode.valid())
+      {
+         entryIdx = entryNode->getText().toInt32();
+      }
+      
+      openImage(filename, entryIdx);
+      result = !isStateSet(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+   }
+   else
+   {
+      setState(ossimPlanetTextureLayer_NO_SOURCE_DATA);
+      result = false;
+   }
+   if(histogramStretchMode.valid())
+   {
+      setHistogramStretchMode(histogramStretchMode->getText());
+   }
+   blockCallbacks(false);
+   notifyPropertyChanged("stateCode", this);
+   return result;
+}
+
+void ossimPlanetOssimImageLayer::initializeResamplePoints(const ossimPlanetTerrainTileId& tileId,
+                                                          const ossimPlanetGrid& grid,
+                                                          ossim_uint32 tileWidth,
+                                                          ossim_uint32 tileHeight,
+                                                          ResampleCorners& corners)
+{
+   ossimPlanetGrid::GridBound tileBound;
+   grid.bounds(tileId, tileBound);
+   ossimDrect tileBoundDrect = tileBound.toDrect();
+   
+   // need to add elevation lookups if the projection is affected by elevation
+   // We will do that in a bit after we get it working
+   //
+   // counter clockwise right handed lower left origin.  This will be openGL style texture
+   // ordering where 0, 0 is lower left
+   //
+   ossimPlanetGrid::ModelPoint p1, p2, p3, p4;
+   grid.globalGridToModel(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                     tileBoundDrect.ll().x,
+                                                     tileBoundDrect.ll().y),
+                          p1);
+   grid.globalGridToModel(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                     tileBoundDrect.lr().x,
+                                                     tileBoundDrect.lr().y),
+                          p2);
+   grid.globalGridToModel(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                     tileBoundDrect.ur().x,
+                                                     tileBoundDrect.ur().y),
+                          p3);
+   grid.globalGridToModel(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                     tileBoundDrect.ul().x,
+                                                     tileBoundDrect.ul().y),
+                          p4);
+   
+   ossimDpt imagePoint1, imagePoint2, imagePoint3, imagePoint4;
+   theInputProjection->worldToLineSample(ossimGpt(p1.y(), p1.x()),
+                                         imagePoint1);
+   theInputProjection->worldToLineSample(ossimGpt(p2.y(), p2.x()),
+                                         imagePoint2);
+   theInputProjection->worldToLineSample(ossimGpt(p3.y(), p3.x()),
+                                         imagePoint3);
+   theInputProjection->worldToLineSample(ossimGpt(p4.y(), p4.x()),
+                                         imagePoint4);
+   
+   osg::Vec2d gsd;
+   grid.widthHeightInModelSpace(tileId, gsd);
+   gsd[0]/=tileWidth;
+   gsd[1]/=tileHeight;
+   ossimDpt mpd = ossimGpt().metersPerDegree();
+   gsd[0] *= mpd.x;
+   gsd[1] *= mpd.y;
+   
+   ossimDpt metersPerPixel = theInputProjection->getMetersPerPixel();
+   ossimDpt decimationFactor;
+   decimationFactor.x = (metersPerPixel.y/gsd[0] + metersPerPixel.y/gsd[1])*.5;
+   decimationFactor.y = decimationFactor.x;
+   //double levels = theSource->getNumberOfDecimationLevels();
+   
+   double factor = 1.0;
+   ossim_uint32 resLevel = 0;
+   if(decimationFactor.x < 1.0)
+   {
+      // always use the higher level for now
+      while(factor*.5 > decimationFactor.x)
+      {
+         factor *= .5;
+         ++resLevel;
+      }
+   }
+   ResamplePoint resample1(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                      tileBoundDrect.ll().x,
+                                                      tileBoundDrect.ll().y),
+                           p1,
+                           imagePoint1,
+                           ossimDpt(0.0,0.0),
+                           decimationFactor,
+                           resLevel);
+   
+   ResamplePoint resample2(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                      tileBoundDrect.lr().x,
+                                                      tileBoundDrect.lr().y),
+                           p2,
+                           imagePoint2,
+                           ossimDpt(tileWidth-1,0),
+                           decimationFactor,
+                           resLevel);
+   ResamplePoint resample3(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                      tileBoundDrect.ur().x,
+                                                      tileBoundDrect.ur().y),
+                           p3,
+                           imagePoint3,
+                           ossimDpt(tileWidth-1,tileHeight-1),
+                           decimationFactor,
+                           resLevel);
+   ResamplePoint resample4(ossimPlanetGrid::GridPoint(tileId.face(),
+                                                      tileBoundDrect.ul().x,
+                                                      tileBoundDrect.ul().y),
+                           p4,
+                           imagePoint4,
+                           ossimDpt(0,tileHeight-1),
+                           decimationFactor,
+                           resLevel);
+   
+                        
+   corners.push(ResampleCorner(resample1, resample2, resample3, resample4));
+   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetPagedLandLod.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetPagedLandLod.cpp
new file mode 100644
index 0000000..a755d80
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetPagedLandLod.cpp
@@ -0,0 +1,505 @@
+#include <ossimPlanet/ossimPlanetPagedLandLod.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <OpenThreads/Mutex>
+#include <OpenThreads/ScopedLock>
+#include <osg/Geode>
+//#include <ossimPlanet/ossimPlanetDatabasePager.h>
+#include <osgUtil/CullVisitor>
+
+//#define OSGPLANET_ENABLE_ALLOCATION_COUNT
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static ossim_uint32 allocated = 0;
+#endif
+
+void ossimPlanetPagedLandLodCullNode::traverse(osg::NodeVisitor& nv)
+{
+   osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+   theCulledFlag = false;
+   if(!cullVisitor||!theBoundingBox.valid()) return;
+
+   
+   osg::Vec3d eye = cullVisitor->getEyeLocal();
+   osg::Vec3d eyeDirection = cullVisitor->getLookVectorLocal();
+   const osg::Polytope& frustum = cullVisitor->getCurrentCullingSet().getFrustum();
+   theEyeDistance = (eye-theBoundingBox->center()).length();
+   if(theUseClusterCulling)
+   {
+      if(theClusterCullingDeviation >= -1.0)
+      {
+         osg::Vec3d eyeCp = eye - theClusterCullingControlPoint;
+         double radius    = eyeCp.length();
+         
+         if (radius>=theClusterCullingRadius)
+         {
+            
+            double deviation = (eyeCp * theClusterCullingNormal)/radius;
+            
+            
+            theCulledFlag = (deviation < theClusterCullingDeviation);
+         }
+      }
+   }
+   if(!theCulledFlag)
+   {
+      if(theBoundingBox->isInFront(eye, eyeDirection))
+      {
+         theCulledFlag = !theBoundingBox->intersects(frustum);
+      }
+      else
+      {
+         theCulledFlag = true;
+      }
+   }
+}
+
+class ossimPlanetPagedLandLodTextureVisitor : public osg::NodeVisitor
+{
+public:
+   ossimPlanetPagedLandLodTextureVisitor(osg::ref_ptr<ossimPlanetLandTextureRequest> tex,
+                                       ossimPlanetPagedLandLod* lod)
+      :osg::NodeVisitor(NODE_VISITOR,
+                        TRAVERSE_ALL_CHILDREN),
+       theRequest(tex),
+       theLod(lod),
+       theHasTextureFlag(false)
+      {
+      }
+   virtual void apply(osg::Geode& node)
+      {
+         theHasTextureFlag = false;
+         if(node.getNumDrawables() > 0)
+         {
+            osg::Geometry* geom = (node.getDrawable(0)->asGeometry());
+            if(geom)
+            {
+               osg::StateSet* dstate = geom->getOrCreateStateSet();
+               if(dstate)
+               {
+                  ossim_uint32 size = dstate->getTextureAttributeList().size();
+                  ossim_uint32 idx = 0;
+                  // first remove all texture states befoe adding the new states.
+                  for(idx = 0; idx < size; ++idx)
+                  {
+                     dstate->removeTextureAttribute(idx,
+                                                    osg::StateAttribute::TEXTURE);
+                  }
+                  std::vector<osg::ref_ptr<osg::Texture2D> >& textures = theRequest->getTextures();
+                  if(textures.size())
+                  {
+                     for(idx = 0;idx < textures.size(); ++idx)
+                     {
+                        dstate->setTextureAttributeAndModes(idx, textures[idx].get(),
+                                                            osg::StateAttribute::ON);
+                        theHasTextureFlag = true;
+                     }
+                  }
+                  else
+                  {
+                     theHasTextureFlag = false;
+                     
+                  }
+               }
+            }
+         }
+      }
+   
+   bool hasTexture()const
+      {
+         return theHasTextureFlag;
+      }
+protected:   
+   osg::ref_ptr<ossimPlanetLandTextureRequest> theRequest;
+   ossimPlanetPagedLandLod* theLod;
+   bool theHasTextureFlag;
+};
+
+class ossimPlanetPagedLandLodUpdateCallback : public osg::NodeCallback
+{
+public:
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         ossimPlanetPagedLandLod* n = dynamic_cast<ossimPlanetPagedLandLod*>(node);
+         if(n)
+         {
+           // ossimPlanetDatabasePager* pager = dynamic_cast<ossimPlanetDatabasePager*>(nv->getDatabaseRequestHandler());
+            //OpenThreads::ScopedLock<OpenThreads::Mutex> lock(n->theMutex);
+            if(n->theRefreshType == ossimPlanetLandRefreshType_TEXTURE)
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(n->thePagedLodListMutex);
+               n->thePagedLodList.clear();
+            }
+            if(n->getNumChildren() > 0)
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(n->theTextureRequestMutex);
+               ossimPlanetPagedLandLodTextureVisitor visitor(n->theTextureRequest, n);
+               if(n->theTextureRequest.valid())
+               {
+                  if(n->theTextureRequest->getCullCallback().valid())
+                  {
+                     n->setCullCallback(n->theTextureRequest->getCullCallback().get());
+                  }
+                  if(n->theTextureRequest->getTransform().valid())
+                  {
+                     n->setChild(0, n->theTextureRequest->getTransform().get());
+                     n->theCulledFlag = false;
+                     n->theRemoveChildrenFlag = false;
+                     n->theCenterPoint = n->theTextureRequest->centerPoint();
+                     n->theUlPoint = n->theTextureRequest->ulPoint();
+                     n->theUrPoint = n->theTextureRequest->urPoint();
+                     n->theLrPoint = n->theTextureRequest->lrPoint();
+                     n->theLlPoint = n->theTextureRequest->llPoint();
+                     n->theCenterNormal = n->theTextureRequest->centerNormal();
+                     n->theUlNormal = n->theTextureRequest->ulNormal();
+                     n->theUrNormal = n->theTextureRequest->urNormal();
+                     n->theLrNormal = n->theTextureRequest->lrNormal();
+                     n->theLlNormal = n->theTextureRequest->llNormal();
+//                      if(n->theTextureRequest->boundingBox().valid())
+//                      {
+//                         n->theCullNode->setBoundingBox(n->theTextureRequest->boundingBox().get());
+//                      }
+                  }
+                  
+                  n->getChild(0)->accept(visitor);
+                  if(n->theTextureRequest->getTextureState() == ossimPlanetImage::ossimPlanetImageStateType_NEEDS_LOADING)
+                  {
+                     if(n->theRefreshType != ossimPlanetLandRefreshType_PRUNE)
+                     {
+                        n->theRefreshType = ossimPlanetLandRefreshType_TEXTURE;
+                     }
+                  }
+                  else
+                  {
+                     n->theRefreshType = ossimPlanetLandRefreshType_NONE;
+                  }
+                  n->dirtyBound();
+                  n->getBound();
+                  n->theTextureRequest = 0;
+                  ossimPlanetLand* land = n->landLayer();
+                  if(land)
+                  {
+                     land->pagedLodModified(n);
+                  }
+              }
+            }
+            ossim_uint32 numChildren = n->getNumChildren();
+            ossimPlanetLand* land = n->landLayer();
+            if(n->theRemoveChildrenFlag||
+               n->theCulledFlag||
+               n->areAllChildrenCulled()||
+               (n->theRefreshType == ossimPlanetLandRefreshType_PRUNE))
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(n->thePagedLodListMutex);
+               ossim_uint32 idx = 0;
+               if(numChildren > 1)
+               {
+                  for(idx = 1; idx < numChildren;++idx)
+                  {
+                     if(n->getChild(idx))
+                     {
+                        if(land)
+                        {
+                           land->pagedLodRemoved(n->getChild(idx));
+                        }
+#if 0
+                        if(pager)
+                        {
+                           pager->addToDeleteList(n->getChild(idx));
+                        }
+#endif
+                        //osg::Group* grp = dynamic_cast<osg::Group*>(n->getChild(idx));
+                        //if( grp ) pager->removeRequest( grp );
+                     }
+                  }
+                  
+                  n->removeChild(1, numChildren-1);
+               }
+
+               n->thePagedLodList.clear();
+               if(numChildren > 0)
+               {
+                  n->getChild(0)->accept(*nv);
+               }
+               if(n->theRefreshType == ossimPlanetLandRefreshType_PRUNE)
+               {
+                  n->theRefreshType = ossimPlanetLandRefreshType_NONE;
+               }
+               return;
+            }
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(n->thePagedLodListMutex);
+            if(n->thePagedLodList.size()==4)
+            {
+               if(n->getNumChildren() == 1) 
+               {
+                  for( unsigned int i = 0 ; i < n->thePagedLodList.size(); i++ )
+                  {
+                     n->insertChild(n->getNumChildren(), n->thePagedLodList[i].get());
+                  }
+                  
+                  if(n->getNumChildren() == 5)
+                  {
+                     n->thePagedLodList.clear();
+                  }
+               }
+               else
+               {
+                  n->thePagedLodList.clear();
+               }
+            }
+            ossim_uint32 idx =0;
+            for(idx = 0; idx < n->thePagedLodList.size(); ++idx)
+            {
+               n->thePagedLodList[idx]->accept(*nv);
+            }
+         }
+		 
+         traverse(node, nv);
+      }
+};
+
+ossimPlanetPagedLandLod::ossimPlanetPagedLandLod(ossim_uint32 level,
+                                                 ossim_uint32 row,
+                                                 ossim_uint32 col,
+                                                 const std::string& requestName)
+   :
+   theGeode(0),
+   theLevel(level),
+   theRow(row),
+   theCol(col),
+   theRequestNameList(5),
+   theCulledFlag(false),
+   theRemoveChildrenFlag(false),
+   theMaxLevel(99999999),
+   theChildCullNodeList(4)
+
+{
+   theRefreshType = ossimPlanetLandRefreshType_NONE;
+   theRequestNameList[0] = requestName;
+   setUpdateCallback( new ossimPlanetPagedLandLodUpdateCallback );
+   theCullNode = new ossimPlanetPagedLandLodCullNode();
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   ++allocated;
+   std::cout << "ossimPlanetPagedLandLod count: " << allocated << std::endl;
+#endif
+}
+
+ossimPlanetPagedLandLod::~ossimPlanetPagedLandLod()
+{
+   theGeode = 0;
+
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   --allocated;
+   std::cout << "ossimPlanetPagedLandLod count: " << allocated << std::endl;
+#endif
+}
+
+ossimPlanetPagedLandLod::ossimPlanetPagedLandLod(const ossimPlanetPagedLandLod& src,
+                                             const osg::CopyOp& copyop)
+   :osg::Group(src, copyop),
+    theLevel(src.theLevel),
+    theRow(src.theRow), 
+    theCol(src.theCol),
+    theRequestNameList(src.theRequestNameList),
+    theCulledFlag(src.theCulledFlag),
+    theRemoveChildrenFlag(src.theRemoveChildrenFlag),
+    theChildCullNodeList(4)
+{
+}
+
+bool ossimPlanetPagedLandLod::areAllChildrenLeaves()const
+{
+   if(getNumChildren()!=5) return false;
+   ossim_uint32 idx;
+   ossim_uint32 bounds = getNumChildren();
+   for(idx = 1; idx < bounds; ++idx)
+   {
+      const ossimPlanetPagedLandLod* lod = dynamic_cast<const ossimPlanetPagedLandLod*>(getChild(idx));
+      if(lod)
+      {
+         if(!lod->isLeaf()) return false;
+      }
+   }
+   
+   return true;
+}
+
+bool ossimPlanetPagedLandLod::hasCulledChildren()const
+{
+   if(getNumChildren()<2) return false;
+   ossim_uint32 idx = 0;
+   ossim_uint32 bounds = getNumChildren();
+   for(idx = 1; idx < bounds; ++idx)
+   {
+      const ossimPlanetPagedLandLod* lod = dynamic_cast<const ossimPlanetPagedLandLod*>(getChild(idx));
+      if(lod)
+      {
+         if(lod->getCulledFlag()) return true;
+      }
+   }
+
+   return false;   
+}
+
+bool ossimPlanetPagedLandLod::areAllChildrenCulled(bool applyToAddedChildrenOnly)const
+{
+   if(applyToAddedChildrenOnly)
+   {
+      if(getNumChildren()!=5) return false;
+   }
+   if(getNumChildren()==1) return false;
+   ossim_uint32 idx = 0;
+   ossim_uint32 bounds = getNumChildren();
+   for(idx = 1; idx < bounds; ++idx)
+   {
+      const ossimPlanetPagedLandLod* lod = dynamic_cast<const ossimPlanetPagedLandLod*>(getChild(idx));
+      if(lod)
+      {
+         if(!lod->getCulledFlag()) return false;
+      }
+   }
+
+   return true;
+}
+
+bool ossimPlanetPagedLandLod::addChild( Node *child )
+{
+//   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   if(!child) return false;
+	
+   ossimPlanetPagedLandLod* lod = dynamic_cast<ossimPlanetPagedLandLod*>(child);
+   ossimPlanetLandTextureRequest *request = dynamic_cast<ossimPlanetLandTextureRequest*>(child);
+   bool result = false;
+   if(lod)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePagedLodListMutex);
+      if(getNumChildren() >4)
+      {
+         return false;
+      }
+	     
+      if(thePagedLodList.size() < 4)
+      {
+         
+         if(lod->theRequestNameList[0] != theRequestNameList[thePagedLodList.size()+1])
+         {
+            return false;
+         }
+      }
+      else
+      {
+         return false;
+      }
+      
+      ossim_uint32 idx = thePagedLodList.size();
+      thePagedLodList.push_back(lod);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockChildList(theChildCullNodeListMutex);
+      theChildCullNodeList[idx] = new ossimPlanetPagedLandLodCullNode(*lod->theCullNode);
+      ossimPlanetLand* land = landLayer();
+      if(land)
+      {
+         land->pagedLodAdded(this, theChildCullNodeList[idx].get());
+      }
+      return true;
+   }
+   else if(request)
+   {
+      if((request->getLevel() == theLevel)&&
+         (request->getRow()   == theRow)&&
+         (request->getCol()   == theCol))
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTextureRequestMutex);
+         theTextureRequest = request;
+         ossimPlanetLand* land = landLayer();
+         if(land)
+         {
+            land->pagedLodModified(this);
+         }
+        
+         return true;
+      }
+      return false;
+   }
+   result = Group::addChild(child);
+   
+   return result;
+}
+
+void ossimPlanetPagedLandLod::traverse(osg::NodeVisitor& nv)
+{  
+   switch(nv.getTraversalMode())
+   {
+      case osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN:
+      {
+         if(isLeaf())
+         {
+            if(getChild(0))
+            {
+               getChild(0)->accept(nv);
+            }
+         }
+         else
+         {
+            ossim_uint32 idx = 0;
+            for(idx = 1; idx < getNumChildren(); ++idx)
+            {
+               getChild(idx)->accept(nv);
+            }
+         }
+         break;
+      }
+      default:
+      {
+         Group::traverse(nv);
+         break;
+      }
+  }
+}
+
+void ossimPlanetPagedLandLod::setRefreshType(ossimPlanetLandRefreshType refreshType)
+{
+   theRefreshType = refreshType;
+	if(theRefreshType != ossimPlanetLandRefreshType_NONE)
+	{
+		if(landLayer()) landLayer()->setRedrawFlag(true);
+		theTextureRequest = 0;
+	}
+}
+
+ossimPlanetLandRefreshType ossimPlanetPagedLandLod::refreshType()const
+{
+   return theRefreshType;
+}
+
+
+
+ossimPlanetLand* ossimPlanetPagedLandLod::landLayer()
+{
+   osg::Node* parentNode = this;
+   while(parentNode->getNumParents())
+   {
+      parentNode = parentNode->getParent(0);
+      ossimPlanetLand* landPtr = dynamic_cast<ossimPlanetLand*>(parentNode);
+      if(landPtr)
+      {
+         return landPtr;
+      }
+   }
+   
+   return 0;
+}
+
+const ossimPlanetLand* ossimPlanetPagedLandLod::landLayer()const
+{
+   const osg::Node* parentNode = this;
+   while(parentNode->getNumParents())
+   {
+      parentNode = parentNode->getParent(0);
+      const ossimPlanetLand* landPtr = dynamic_cast<const ossimPlanetLand*>(parentNode);
+      if(landPtr)
+      {
+         return landPtr;
+      }
+   }while(parentNode);
+
+   return 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetPlaneGrid.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetPlaneGrid.cpp
new file mode 100644
index 0000000..a27aabf
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetPlaneGrid.cpp
@@ -0,0 +1,73 @@
+#include <ossimPlanet/ossimPlanetPlaneGrid.h>
+#include <ossim/base/ossimCommon.h>
+
+ossim_uint32 ossimPlanetPlaneGrid::getNumberOfFaces()const
+{
+   return 2;// east and west hemispheres
+}
+
+void ossimPlanetPlaneGrid::getPixelScale(double& dx,
+                                         double& dy,
+                                         ossimUnitType& pixelScaleUnits,
+                                         ossim_uint32 level,
+                                         ossim_uint64 /*row*/,
+                                         ossim_uint64 /*col*/)const
+{
+   dx = 180.0*(1.0/(1<<level));
+   dy = dx;
+   dx/=theTileWidth;
+   dy/=theTileHeight;
+   pixelScaleUnits = OSSIM_DEGREES;
+}
+
+void ossimPlanetPlaneGrid::getGridPoint(ossimPlanetGridUtility::GridPoint& gridPoint,
+                                        const osg::Vec3d& latLon)const
+{
+   osg::Vec2d ll((ossim::clamp((double)latLon[ossimPlanetGridUtility::LAT],
+                               (double)-90.0, (double)90.0)+90)/180,
+                 (ossim::wrap((double)latLon[ossimPlanetGridUtility::LON],
+                              (double)-180.0, (double)180.0)+180)/360);
+
+   gridPoint.theFace = ll[ossimPlanetGridUtility::LON] < 0.0?0:1;
+   
+   gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = ll[ossimPlanetGridUtility::LAT];
+   if(gridPoint.theFace == 0)
+   {
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = ll[ossimPlanetGridUtility::LON]/.5;
+   }
+   else
+   {
+      gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = (ll[ossimPlanetGridUtility::LON]-.5)/.5;
+   }
+
+   gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX] = ossim::clamp(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDX],
+                                                                              0.0, 1.0);
+   gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY] = ossim::clamp(gridPoint.theGlobalGridPoint[ossimPlanetGridUtility::GRIDY],
+                                                                              0.0, 1.0);
+}
+
+
+void ossimPlanetPlaneGrid::getLatLon(osg::Vec3d& latLon,
+                                     const ossimPlanetGridUtility::GridPoint& gridPoint)const
+{
+   latLon[2] = 0.0;
+   switch(gridPoint.theFace)
+   {
+      case 0: // east hemisphere
+      {
+         latLon[0] = 90.0 - (180.0)*gridPoint.theGlobalGridPoint[1];
+         latLon[1] = gridPoint.theGlobalGridPoint[0]*180.0 - 180.0;
+         break;
+      }
+      case 1: // west hemisphere
+      {
+         latLon[0] = 90.0 - (180.0)*gridPoint.theGlobalGridPoint[1];
+         latLon[1] = gridPoint.theGlobalGridPoint[0]*180.0;
+         break;
+      }
+   }
+}
+
+
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetPointModel.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetPointModel.cpp
new file mode 100644
index 0000000..9dfb472
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetPointModel.cpp
@@ -0,0 +1,115 @@
+#include <ossimPlanet/ossimPlanetPointModel.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/mkUtils.h>
+#include <OpenThreads/ScopedLock>
+#include <ossim/base/ossimNotify.h>
+#include <osg/io_utils>
+
+ossimPlanetPointModel::ossimPlanetPointModel()
+:theNodeChangedFlag(false)
+{
+   theLsrSpaceCallback = new LsrSpaceCallback(this);
+   theLsrSpaceTransform = new ossimPlanetLsrSpaceTransform();
+   theLsrSpaceTransform->addCallback(theLsrSpaceCallback.get());
+   theLsrSpaceTransform->setUpdateCallback(new ossimPlanetTraverseCallback());
+}
+
+ossimPlanetPointModel::~ossimPlanetPointModel()
+{
+   if(theLsrSpaceTransform.valid())
+   {
+      theLsrSpaceTransform->removeCallback(theLsrSpaceCallback.get());
+   }
+}
+
+void ossimPlanetPointModel::traverse(osg::NodeVisitor& nv)
+{
+   if(!enableFlag()||!theNode.valid())
+   {
+      ossimPlanetAnnotationLayerNode::traverse(nv);
+      return;
+   }
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         setRedrawFlag(false); // let's reset the redraw notification
+         if(!theLsrSpaceTransform->model()&&layer()) theLsrSpaceTransform->setModel(layer()->model());
+         
+ //        if(checkPointers())
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePointModelPropertyMutex);
+            if(theNodeChangedFlag)
+            {
+               if(theLsrSpaceTransform->getNumChildren() > 0)
+               {
+                  theLsrSpaceTransform->removeChildren(0, theLsrSpaceTransform->getNumChildren());
+               }
+               theLsrSpaceTransform->addChild(theNode.get());
+               theNodeChangedFlag = false;
+           }
+         }
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   theLsrSpaceTransform->accept(nv);
+   ossimPlanetAnnotationLayerNode::traverse(nv);
+}
+
+void ossimPlanetPointModel::setNode(osg::Node* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePointModelPropertyMutex);
+   setRedrawFlag(true);
+  
+   theNode = node;
+   theNodeChangedFlag = true;
+}
+
+void ossimPlanetPointModel::copyLsrSpaceParameters(const ossimPlanetLsrSpaceTransform& lsr)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePointModelPropertyMutex);
+   // only need the martrix of the lsr space and all other parameters wil be derived from it.
+   theLsrSpaceTransform->copyParametersOnly(lsr);
+   setRedrawFlag(true);
+}
+
+void ossimPlanetPointModel::setLayer(ossimPlanetLayer* layer)
+{
+   ossimPlanetAnnotationLayerNode::setLayer(layer);
+   if(layer)
+   {
+      theLsrSpaceTransform->setModel(layer->model());
+      setRedrawFlag(true);
+   }
+}
+
+bool ossimPlanetPointModel::checkPointers()
+{
+   if(layer())
+   {
+      if(layer()->model())
+      {
+         return true;
+      }
+      else
+      {
+         ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetPointModel::checkPointers() ERROR: model is not found.  Try added the annotation layer to planet and add the PointModelNode to the annotation layer";
+      }
+   }
+   else
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetPointModel::checkPointers() ERROR: parent layer is not found.";
+   }
+   
+   return false;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetPredatorVideoLayerNode.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetPredatorVideoLayerNode.cpp
new file mode 100644
index 0000000..fe44211
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetPredatorVideoLayerNode.cpp
@@ -0,0 +1,936 @@
+#include <ossimPlanet/ossimPlanetPredatorVideoLayerNode.h>
+#include <iostream>
+#include <osgUtil/CullVisitor>
+#include <osgGA/EventVisitor>
+#include <osgGA/GUIActionAdapter>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetVideoLayer.h>
+#include <ossim/base/ossimMatrix4x4.h>
+#include <ossim/base/ossimLsrSpace.h>
+#include <sstream>
+#include <ossim/base/ossimDate.h>
+#include <ossim/elevation/ossimElevManager.h>
+
+class ossimPlanetPredatorVideoLayerNodeTraverseCallback : public osg::NodeCallback
+{
+public:
+   ossimPlanetPredatorVideoLayerNodeTraverseCallback()
+      {
+      }
+   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+      {
+         if(node)
+         {
+            node->traverse(*nv);
+         }
+      }
+};
+
+ossimPlanetFFMpegImageStream::ossimPlanetFFMpegImageStream()
+   :theBlock(new ossimPlanetRefBlock),
+    theFrameRate(0.0),
+    theSecondsToUpdate(0.0),
+    theEnableFlag(true)
+{
+   _status = osg::ImageStream::PAUSED;
+   _loopingMode = LOOPING;
+}
+
+ossimPlanetFFMpegImageStream::~ossimPlanetFFMpegImageStream()
+{
+}
+
+void ossimPlanetFFMpegImageStream::setVideo(ossimRefPtr<ossimPredatorVideo> video)
+{
+   if(isRunning())
+   {
+      cancel();
+   }
+   theVideo = video;
+   if(theVideo.valid())
+   {
+      theFrameRate = theVideo->videoFrameRate();
+      theSecondsToUpdate = 1.0/theFrameRate;
+      allocateImage(theVideo->imageWidth(),
+                    theVideo->imageHeight(),
+                    1,
+                    GL_RGB,
+                    GL_UNSIGNED_BYTE);  
+      memset(data(),
+             0,
+             theVideo->imageWidth()*
+             theVideo->imageHeight()*3);
+      dirty();
+      theDoneFlag = false;
+      pause();
+      theVideo->setFirstFrameFlag(false);
+   }
+}
+
+int ossimPlanetFFMpegImageStream::cancel()
+{
+   int result = 0;
+
+   if( isRunning() )
+   {
+      theDoneFlag = true;
+      // release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation.
+      theBlock->release();
+      
+      // then wait for the the thread to stop running.
+      while(isRunning())
+      {
+         OpenThreads::Thread::YieldCurrentThread();
+      }
+   }
+   
+   return result;
+}
+void ossimPlanetFFMpegImageStream::CoordinateInfo::setDescriptionToKlvMetadata()
+{
+   if(!theKlvTable.valid()) return;
+   ossimString value;
+   theDescription = "";
+   if(theKlvTable->valueAsString(value, KLV_KEY_ORGANIZATIONAL_PROGRAM_NUMBER))
+   {
+      theDescription += ("Orgnizational Program Number: " + value + "<br>");
+   }
+   ossimDate date;
+   if(theKlvTable->getDate(date, false))
+   {
+      std::stringstream temp;
+      temp << std::setw(4) << date.getYear() <<"-"
+      << std::setw(2) << std::setfill('0') << date.getMonth() << "-"
+      << std::setw(2) << std::setfill('0') << date.getDay() << " "
+      << std::setw(2) << std::setfill('0') << date.getHour() << ":"
+      << std::setw(2) << std::setfill('0') << date.getMin() << ":"
+      << std::setw(2) << std::setfill('0') << date.getSec() << "<br>";
+      theDescription += ("Date: " + temp.str());
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_MISSION_NUMBER))
+   {
+      theDescription += "Mission ID: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SECURITY_CLASSIFICATION_SET))
+   {
+      theDescription += "Security Classification: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CLASSIFICATION_COMMENT))
+   {
+      theDescription += "Classification Comment: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SECURITY_CAVEATS))
+   {
+      theDescription += "Security Caveats: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_ORIGINAL_PRODUCER_NAME))
+   {
+      theDescription += "Original Producer Name: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_PLATFORM_HEADING_ANGLE))
+   {
+      theDescription += "Platform Heading: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_PLATFORM_PITCH_ANGLE))
+   {
+      theDescription += "Platform Pitch: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_PLATFORM_ROLL_ANGLE))
+   {
+      theDescription += "Platform Roll: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_PLATFORM_DESIGNATION))
+   {
+      theDescription += "Designation: " + value + "<br>";
+   }
+   else if(theKlvTable->valueAsString(value, KLV_KEY_PLATFORM_DESIGNATION2))
+   {
+      theDescription += "Designation: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_IMAGE_SOURCE_SENSOR))
+   {
+      theDescription += "Image Source Sensor: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_IMAGE_COORDINATE_SYSTEM))
+   {
+      theDescription += "Coordinate System: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_LATITUDE))
+   {
+      theDescription += "Sensor Latitude: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_LONGITUDE))
+   {
+      theDescription += "Sensor Longitude: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_TRUE_ALTITUDE))
+   {
+      theDescription += "Sensor Altitude: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_HORIZONTAL_FOV))
+   {
+      theDescription += "Horizontal Field Of View: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_VERTICAL_FOV1))
+   {
+      theDescription += "Vertical Field Of View: " + value + "<br>";
+   }
+   else if(theKlvTable->valueAsString(value, KLV_KEY_SENSOR_VERTICAL_FOV2))
+   {
+      theDescription += "Vertical Field Of View: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_SLANT_RANGE))
+   {
+      theDescription += "Slant Range: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_OBLIQUITY_ANGLE))
+   {
+      theDescription += "Obliquity Angle: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_ANGLE_TO_NORTH))
+   {
+      theDescription += "Angle To North: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_TARGET_WIDTH))
+   {
+      theDescription += "Target Width: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_FRAME_CENTER_LATITUDE))
+   {
+      theDescription += "Frame Center Latitude: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_FRAME_CENTER_LONGITUDE))
+   {
+      theDescription += "Frame Center Longitude: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_FRAME_CENTER_ELEVATION))
+   {
+      theDescription += "Frame Center Elevation: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LATITUDE_POINT_1))
+   {
+      theDescription += "Corner Latitude 1: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LONGITUDE_POINT_1))
+   {
+      theDescription += "Corner Longitude 1: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LATITUDE_POINT_2))
+   {
+      theDescription += "Corner Latitude 2: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LONGITUDE_POINT_2))
+   {
+      theDescription += "Corner Longitude 2: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LATITUDE_POINT_3))
+   {
+      theDescription += "Corner Latitude 3: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LONGITUDE_POINT_3))
+   {
+      theDescription += "Corner Longitude 3: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LATITUDE_POINT_4))
+   {
+      theDescription += "Corner Latitude 4: " + value + "<br>";
+   }
+   if(theKlvTable->valueAsString(value, KLV_KEY_CORNER_LONGITUDE_POINT_4))
+   {
+      theDescription += "Corner Longitude 4: " + value + "<br>";
+   }
+   
+}
+
+void ossimPlanetFFMpegImageStream::run()
+{
+   if(!theVideo.valid()) return;
+   
+   while(!theDoneFlag)
+   {
+      theBlock->block();
+      if(theDoneFlag) return;
+      ossimRefPtr<ossimPredatorVideo::FrameInfo> frame = theVideo->nextFrame();
+      osg::Timer_t lastFrameTick;
+      lastFrameTick = osg::Timer::instance()->tick();
+      if(frame.valid())
+      {
+         memcpy(data(),
+                frame->rgbBuffer(),
+                frame->rgbBufferSizeInBytes());
+         dirty();
+         ossimRefPtr<ossimPredatorKlvTable> klvTable = frame->klvTable();
+         if(klvTable.valid())
+         {
+//             ossimPlanetFFMpegImageStream::CoordinateInfo coord;
+            ossim_float64 lat=0.0, lon=0.0, elev=0.0;
+            ossim_float64 flat=0.0, flon=0.0, felev=0.0;
+//             ossim_float32 h=0.0, p=0.0, r=0.0;
+            ossim_float32 obliquityAngle=0.0;
+//             ossim_float32 slantRange=0.0;
+//             ossim_float32 hfov=0.0;
+//             ossim_float32 vfov=0.0;
+            ossim_float32 targetWidthInMeters=1.0;
+            ossim_float32 angleToNorth=0.0;
+//             ossim_float32 roll=0.0;
+
+            // if we at least have a frame center and a target width let's go on that
+            
+            if(klvTable->getTargetWidthInMeters(targetWidthInMeters)&&
+               klvTable->getFrameCenter(flat, flon, felev))
+            {
+               osg::ref_ptr<CoordinateInfo> coordInfo = new CoordinateInfo;
+               coordInfo->theKlvTable = klvTable->dup();
+               coordInfo->theReferenceTime = theVideo->referenceTime();
+               coordInfo->theClock = theVideo->videoClock();
+               ossim_float32 slantRange=0.0;
+               ossimGpt pt1, pt2, pt3, pt4;
+
+               if(theModel.valid())
+               {
+                  felev = theModel->getHeightAboveEllipsoid(flat, flon);
+               }
+               else
+               {
+                  // this is a hack for now until I fix the model synching problem.
+                  //
+                  felev = ossimElevManager::instance()->getHeightAboveEllipsoid(ossimGpt(flat, flon));
+                  if(ossim::isnan(felev))
+                  {
+                     felev = 0;
+                  }
+               }
+               coordInfo->theFrameCenterLlhValidFlag = true;
+               coordInfo->theFrameCenterLlh = osg::Vec3d(flat, flon, felev);
+               coordInfo->theTargetWidthInMetersValidFlag = true;
+               coordInfo->theTargetWidthInMeters = targetWidthInMeters;
+               if(klvTable->getCornerPoints(pt1, pt2, pt3, pt4))
+               {
+                  coordInfo->theCornerPoints.resize(4);
+                  coordInfo->theCornerPoints[0] = osg::Vec3d(pt1.latd(), pt1.lond(), pt1.height());
+                  coordInfo->theCornerPoints[1] = osg::Vec3d(pt2.latd(), pt2.lond(), pt2.height());
+                  coordInfo->theCornerPoints[2] = osg::Vec3d(pt3.latd(), pt3.lond(), pt3.height());
+                  coordInfo->theCornerPoints[3] = osg::Vec3d(pt4.latd(), pt4.lond(), pt4.height());
+               }
+               else
+               {
+                  coordInfo->theCornerPoints.clear();
+               }
+               // now let's see if we can have full orientation.  This will be the best we can do fr now.
+               // The meta data doesn't seem to fit line of site.  So, we will get what we can and then rotate that
+               // into the platform center to frame center vector so at least the center pixel projects to the meta 
+               // data frame center.
+               //
+               if(klvTable->getSlantRange(slantRange))
+               {
+                  coordInfo->theSlantRange           = slantRange;
+               }
+               else
+               {
+                  coordInfo->theSlantRangeValidFlag = false;
+               }
+               if(klvTable->getAngleToNorth(angleToNorth)&&
+                  klvTable->getObliquityAngle(obliquityAngle)&&
+                  klvTable->getSensorPosition(lat, lon, elev))
+               {
+                  if(ossim::almostEqual(elev, 0.0)&&theModel.valid())
+                  {
+                     elev = theModel->getHeightAboveEllipsoid(lat, lon);
+                  }
+                  else if(theModel.valid())
+                  {
+                     elev += theModel->getGeoidOffset(lat, lon);
+                  }
+                  
+                  ossimGpt sensorGpt(lat, lon, elev);
+                  ossimGpt frameGpt(flat, flon, felev);
+                  osg::Matrixd orientationMatrix;
+                  
+                  ossimLsrSpace lsrSpace(sensorGpt,
+                                         angleToNorth);
+                  ossimMatrix4x4 lsrMatrix(lsrSpace.lsrToEcefRotMatrix());
+                  NEWMAT::Matrix orientation = (ossimMatrix4x4::createRotationXMatrix(obliquityAngle,
+                                                                                      OSSIM_LEFT_HANDED));
+                  ossimEcefPoint sensorEcefPosition      = sensorGpt;
+                  ossimEcefPoint frameCenterEcefPosition = frameGpt;
+                  ossimEcefVector zAxis = sensorEcefPosition - frameCenterEcefPosition;
+                  ossimEcefVector yCol(orientation[0][1],
+                                       orientation[1][1],
+                                       orientation[2][1]);
+                  ossimEcefVector xAxis = yCol.cross(zAxis);
+                  ossimEcefVector yAxis = zAxis.cross(xAxis);
+                  xAxis.normalize();
+                  yAxis.normalize();
+
+                  coordInfo->theOrientationMatrix(0, 0) = xAxis.x();
+                  coordInfo->theOrientationMatrix(0, 1) = xAxis.y();
+                  coordInfo->theOrientationMatrix(0, 2) = xAxis.z();
+                  coordInfo->theOrientationMatrix(1, 0) = yAxis.x();
+                  coordInfo->theOrientationMatrix(1, 1) = yAxis.y();
+                  coordInfo->theOrientationMatrix(1, 2) = yAxis.z();
+                  coordInfo->theOrientationMatrix(2, 0) = zAxis.x();
+                  coordInfo->theOrientationMatrix(2, 1) = zAxis.y();
+                  coordInfo->theOrientationMatrix(2, 2) = zAxis.z();
+
+                  coordInfo->theSensorPositionLlh[0] = lat;
+                  coordInfo->theSensorPositionLlh[1] = lon;
+                  coordInfo->theSensorPositionLlh[2] = elev;
+
+               }
+               else
+               {
+                  coordInfo->theOrientationMatrixValidFlag = false;
+               }
+               coordInfo->setDescriptionToKlvMetadata();
+               if(theCallback.valid())
+               {
+                  theCallback->coordinatesChanged(klvTable,
+                                                  coordInfo);
+               }
+            }
+         }
+      }
+      if(!frame.valid())
+      {
+         if(_loopingMode == NO_LOOPING)
+         {
+            theDoneFlag = true;
+         }
+         else
+         {
+//             theMutex.lock();
+            rewind();
+            if(theCallback.valid())
+            {
+               theCallback->referenceTimeChanged(0.0);
+            }
+//             theMutex.unlock();
+         }
+      }
+      else if(theCallback.valid())
+      {
+//          std::cout << "TIME CHANGE = " << getReferenceTime() << "\n";
+         theCallback->referenceTimeChanged(getReferenceTime());
+      }
+      // now delay based on frame rate
+      // we later need to add support for slow play and fast play and
+      // seeking.  For now we do constant source frame rate
+      //
+      double delta = osg::Timer::instance()->delta_s(lastFrameTick, osg::Timer::instance()->tick());
+      if((delta < theSecondsToUpdate)&&
+			(delta >= 0.0))
+      {
+         //double idolTime = theSecondsToUpdate-delta;
+         OpenThreads::Thread::microSleep(theSecondsToUpdate*1e6);
+      }
+      
+      updateThreadBlock();
+   }
+}
+
+void ossimPlanetFFMpegImageStream::play()
+{
+   _status = osg::ImageStream::PLAYING;
+   if (!isRunning())
+   {
+      if(theVideo.valid())
+      {
+         theDoneFlag = false;
+         theVideo->setFirstFrameFlag(false);
+         updateThreadBlock();
+         start();
+      }
+   }
+   updateThreadBlock();
+}
+
+void ossimPlanetFFMpegImageStream::pause()
+{
+   _status = ImageStream::PAUSED;
+   updateThreadBlock();
+}
+
+void ossimPlanetFFMpegImageStream::rewind()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   theVideo->setFirstFrameFlag(false);
+   theVideo->seek(0.0, ossimPredatorVideo::SEEK_ABSOLUTE);
+   updateThreadBlock();
+}
+
+void ossimPlanetFFMpegImageStream::quit(bool waitForThreadToExit)
+{
+   theDoneFlag = true;
+   if(waitForThreadToExit)
+   {
+      cancel();
+   }
+   else
+   {
+      // make sure we are not blocked
+      theBlock->release();
+   }
+}
+
+double ossimPlanetFFMpegImageStream::getLength() const
+{
+   return theVideo.valid()?theVideo->duration():0.0;
+}
+
+void ossimPlanetFFMpegImageStream::setReferenceTime(double t)
+{
+   // need to add the seeking based on time offset
+   //
+   if(theVideo.valid())
+   {
+      theVideo->seek(t, ossimPredatorVideo::SEEK_ABSOLUTE);
+      updateThreadBlock();
+   }
+}
+
+double ossimPlanetFFMpegImageStream::getReferenceTime()
+{
+   if(theVideo.valid())
+   {
+      return theVideo->referenceTime();
+   }
+   return 0.0;
+}
+
+void ossimPlanetFFMpegImageStream::setTimeMultiplier(double)
+{
+}
+
+double ossimPlanetFFMpegImageStream::getTimeMultiplier()
+{
+   return 0.0;
+}
+
+void ossimPlanetFFMpegImageStream::setVolume(float)
+{
+}
+
+float ossimPlanetFFMpegImageStream::getVolume()
+{
+   return 0.0;
+}
+
+ossimPlanetPredatorVideoLayerNode::ossimPlanetPredatorVideoLayerNode(ossimPlanetVideoLayer* layer)
+   :ossimPlanetVideoLayerNode(layer)
+{
+   
+   theAspect = 1.0;
+   theInvAspect = 1.0;
+   theGeometryFlag = false;
+   theCurrentFrame = new ossimPlanetFFMpegImageStream;
+   theCallback = new ossimPlanetPredatorVideoLayerNode::ImageStreamCallback(this);
+   theCurrentFrame->setCallback(theCallback.get());
+   setUpdateCallback(new ossimPlanetPredatorVideoLayerNodeTraverseCallback);
+   setEventCallback(new ossimPlanetPredatorVideoLayerNodeTraverseCallback);
+   setCullCallback(new ossimPlanetPredatorVideoLayerNodeTraverseCallback);
+   theCameraNode = new osg::CameraNode;
+   theSwitchNode = new osg::Switch;
+   theIcon = new ossimPlanetIconGeom;
+   theCameraNode = new osg::CameraNode;
+   theSharedGeode = new osg::Geode;
+   theCullFlag = false;
+   //    theIcon->setGeometry(osg::Vec3d(0.0,0.0,0.0),
+//                         osg::Vec3d(0.0, 0.0, 0.0),
+//                         osg::Vec3d(0.0, 0.0, 0.0));
+   theSharedGeode->addDrawable(theIcon.get());
+
+//    theGroup = new osg::Group;
+   theCameraNode->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+   theCameraNode->setViewMatrix(osg::Matrix::identity());
+   theCameraNode->setClearMask(GL_DEPTH_BUFFER_BIT);
+   theCameraNode->setRenderOrder(osg::CameraNode::POST_RENDER);
+   osg::StateSet* stateset = theCameraNode->getOrCreateStateSet();
+   stateset->setMode(GL_LIGHTING,
+                     osg::StateAttribute::OFF);
+//   stateset->setMode(GL_COLOR_MATERIAL,
+//                     osg::StateAttribute::OFF);
+   stateset->setMode(GL_DEPTH_TEST,
+                     osg::StateAttribute::OFF);
+   stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+   stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   theCameraNode->setStateSet(stateset);
+//    addChild(theCameraNode.get());
+   the2DMatrixTransform = new osg::MatrixTransform;
+   the2DMatrixTransform->addChild(theSharedGeode.get());
+   theCameraNode->addChild(the2DMatrixTransform.get());
+
+
+   // SETUP for billboard option
+   //
+   theBillboard = new ossimPlanetBillboardIcon;
+   theBillboardMatrixTransform = new osg::MatrixTransform;
+   theBillboardMatrixTransform->addChild(theBillboard.get());
+   stateset = theBillboard->getOrCreateStateSet();
+   stateset->setMode(GL_LIGHTING,
+                     osg::StateAttribute::OFF);
+//   stateset->setMode(GL_COLOR_MATERIAL,
+//                     osg::StateAttribute::OFF);
+   stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+//    stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   theBillboard->setStateSet(stateset);
+   theSwitchNode->addChild(theCameraNode.get());
+   theSwitchNode->addChild(theBillboardMatrixTransform.get());
+  
+   addChild(theSwitchNode.get());
+//   setRenderMode(ossimPlanetVideoLayerNode::RENDER_SCREEN);
+   setRenderMode(ossimPlanetVideoLayerNode::RENDER_BILLBOARD);
+   
+}
+
+ossimPlanetPredatorVideoLayerNode::~ossimPlanetPredatorVideoLayerNode()
+{
+   
+   theCurrentFrame->setCallback(0);
+   theCurrentFrame->cancel();
+}
+
+bool ossimPlanetPredatorVideoLayerNode::open(const ossimFilename& file)
+{
+   ossimRefPtr<ossimPredatorVideo> video = new ossimPredatorVideo;
+   
+   bool result = video->open(file);
+   if(!result)
+   {
+      video = 0;
+   }
+   else
+   {
+      setName(file.file().c_str());
+   }
+   setVideo(video.get());
+   return result;
+}
+
+void ossimPlanetPredatorVideoLayerNode::setVideo(ossimPredatorVideo* video)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePredatorTraverseMutex);
+   theCurrentFrame->cancel();
+
+   theGeometryFlag = false;
+   theVideo = video;
+   theLookAt = 0;
+   if(theVideo.valid())
+   {
+      theFrameRate = theVideo->videoFrameRate();
+      theSecondsToUpdate = 1.0/theFrameRate;
+      theCurrentFrame->setVideo(video);
+      theIcon->setTexture(theCurrentFrame.get());
+      osg::ref_ptr<osg::Vec3Array> coords = dynamic_cast<osg::Vec3Array*>(theIcon->getVertexArray());
+
+      the2DMatrixTransform->setMatrix(osg::Matrixd::scale(osg::Vec3d(theVideo->imageWidth(),
+                                                                     theVideo->imageHeight(),
+                                                                     1.0))*
+                                      osg::Matrixd::translate(osg::Vec3d(theVideo->imageWidth()*.5,
+                                                                         theVideo->imageHeight()*.5,
+                                                                         0.0)));
+      theAspect = (ossim_float64)theVideo->imageWidth()/(ossim_float64)theVideo->imageHeight();
+      theInvAspect = 1.0/theAspect;
+      theSharedTexture = new osg::Texture2D;
+      theSharedTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture2D::LINEAR);
+      theSharedTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture2D::LINEAR);
+      theSharedTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+      theSharedTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+      theSharedTexture->setWrap(osg::Texture2D::WRAP_R, osg::Texture2D::CLAMP_TO_EDGE);
+      theSharedTexture->setDataVariance(osg::Object::DYNAMIC);
+      theSharedTexture->setResizeNonPowerOfTwoHint(false);
+      theSharedTexture->setImage(theCurrentFrame.get());
+      theIcon->setTexture(theSharedTexture.get());
+      theViewportChangedFlag = false;
+
+      // set anything needed for the billboard on initialization
+      theBillboard->setGeom(theIcon.get());
+      theBillboard->setMinPixelSize(64);
+
+      setRedrawFlag(true);
+      theCurrentFrame->updateThreadBlock();
+      theCurrentFrame->start();
+      // force a reset on any icon geometries
+      setRenderMode(renderMode());
+   }
+}
+
+void ossimPlanetPredatorVideoLayerNode::pause()
+{
+   theCurrentFrame->pause();
+   setRedrawFlag(true);
+   
+}
+
+void ossimPlanetPredatorVideoLayerNode::rewind()
+{
+   theCurrentFrame->rewind();
+   setRedrawFlag(true);
+}
+
+void ossimPlanetPredatorVideoLayerNode::play()
+{
+   theCurrentFrame->play();
+   setRedrawFlag(true);
+}
+
+
+ossimPlanetVideoLayerNode::Status ossimPlanetPredatorVideoLayerNode::status()const
+{
+   switch(theCurrentFrame->getStatus())
+   {
+      case osg::ImageStream::PLAYING:
+      {
+         return ossimPlanetVideoLayerNode::STATUS_PLAYING;
+      }
+      case osg::ImageStream::PAUSED:
+      {
+         return ossimPlanetVideoLayerNode::STATUS_PAUSED;
+      }
+      default:
+      {
+         break;
+      }
+   }
+
+   return ossimPlanetVideoLayerNode::STATUS_NONE;
+}
+
+
+ossim_float64 ossimPlanetPredatorVideoLayerNode::duration()const
+{
+   return (ossim_float64)theCurrentFrame->getLength();
+}
+
+void ossimPlanetPredatorVideoLayerNode::setReferenceTime(ossim_float64 referenceTime)
+{
+   theCurrentFrame->setReferenceTime(referenceTime);
+   setRedrawFlag(true);
+}
+
+ossim_float64 ossimPlanetPredatorVideoLayerNode::referenceTime()const
+{
+   return theCurrentFrame->getReferenceTime();
+}
+
+void ossimPlanetPredatorVideoLayerNode::setRenderMode(ossimPlanetVideoLayerNode::RenderMode mode)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePredatorTraverseMutex);
+   if(mode == ossimPlanetVideoLayerNode::RENDER_OVERLAY)
+   {
+      std::cout << "ossimPlanetPredatorVideoLayerNode::setRenderMode: OVERLAY REDNERING NOT SUPPORTED YET!" << std::endl;
+      std::cout << "ossimPlanetPredatorVideoLayerNode::setRenderMode: DEFAULTING TO SCREEN MODE!" << std::endl;
+      mode = ossimPlanetVideoLayerNode::RENDER_SCREEN;
+   }
+   ossimPlanetVideoLayerNode::setRenderMode(mode);
+   switch(mode)
+   {
+      case ossimPlanetVideoLayerNode::RENDER_SCREEN:
+      {
+         theIcon->setGeometry(osg::Vec3d(-.5, .5, 0.0),
+                              osg::Vec3d(1.0, 0.0, 0.0),
+                              osg::Vec3d(0.0, -1.0, 0.0));
+         break;
+      }
+      case ossimPlanetVideoLayerNode::RENDER_BILLBOARD:
+      {
+         // change the geometry based on the render mode;
+         theIcon->setGeometry(osg::Vec3d(-.5*theAspect, 0.0, .5),
+                              osg::Vec3d(theAspect, 0.0, 0.0),
+                              osg::Vec3d(0.0, 0.0, -1.0));
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   theSwitchNode->setSingleChildOn((int)mode);
+}
+
+void ossimPlanetPredatorVideoLayerNode::traverse(osg::NodeVisitor& nv)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePredatorTraverseMutex);
+   bool traverseChildrenFlag = !theCullFlag&&theEnableFlag;
+   
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         ossimPlanet* planet = videoLayer()->planet();
+         osg::ref_ptr<ossimPlanetGeoRefModel> model = planet->model();
+         if(theCurrentFrame.valid())
+         {
+            if(!theCurrentFrame->model().valid())
+            {
+               theCurrentFrame->setModel(model.get());
+            }
+         }
+         if(!theEnableFlag)
+         {
+            break;
+         }
+         //bool needNewCoordinates = false;
+         osg::ref_ptr<ossimPlanetFFMpegImageStream::CoordinateInfo> coordInfo;
+         theCoordinateMutex.lock();
+         if(theCoordinates.valid())
+         {
+            coordInfo = theCoordinates->dup();
+            theCoordinates = 0;
+         }
+//          needNewCoordinates = theCoordinatesChangedFlag;
+//          theCoordinatesChangedFlag = false;
+         if(!theGeometryFlag)
+         {
+            osg::Matrixd localToWorld;
+            theBillboard->setGroundObjectSize(5000*
+                                              planet->model()->getInvNormalizationScale());
+            
+            model->lsrMatrix(osg::Vec3d(0, 0, 0),
+                             localToWorld);
+            theBillboardMatrixTransform->setMatrix(localToWorld);
+            theGeometryFlag = true;
+            theCullDistance = 10000*planet->model()->getInvNormalizationScale();
+            model->forward(osg::Vec3d(0.0,0.0,0.0), theFrameCenter);
+         }
+         theCoordinateMutex.unlock();
+         if(coordInfo.valid())
+         {
+            if(description()!=coordInfo->theDescription)
+            {
+               setDescription(coordInfo->theDescription);
+            }
+//             std::cout << "Updating coordinates!!" << std::endl;
+            if(planet&&
+               coordInfo->theFrameCenterLlhValidFlag&&
+               coordInfo->theOrientationMatrixValidFlag&&
+               coordInfo->theSlantRangeValidFlag)
+            {
+               
+               osg::Matrixd localToWorld;
+               ossim_float64 targetInMeters = coordInfo->theTargetWidthInMeters;
+               if(targetInMeters < 1.0)
+               {
+                  targetInMeters = 5000;
+               }
+               ossim_float64 cullTarget = (coordInfo->theSlantRange*
+                                           planet->model()->getInvNormalizationScale());
+               theBillboard->setGroundObjectSize(targetInMeters*
+                                           planet->model()->getInvNormalizationScale());
+               model->lsrMatrix(coordInfo->theFrameCenterLlh,
+                                localToWorld);
+               osg::Vec3d hpr;
+               mkUtils::matrixToHpr(hpr, localToWorld, coordInfo->theOrientationMatrix);
+
+               if(!theLookAt.valid())
+               {
+                  theLookAt = new ossimPlanetLookAt;
+               }
+               theLookAt->setAll(coordInfo->theFrameCenterLlh[0], coordInfo->theFrameCenterLlh[1], coordInfo->theFrameCenterLlh[2],
+                                 hpr[0], hpr[1], hpr[2],
+                                 coordInfo->theSlantRange,
+                                 ossimPlanetAltitudeMode_ABSOLUTE);
+               model->forward(coordInfo->theFrameCenterLlh, theFrameCenter);
+               theBillboardMatrixTransform->setMatrix(localToWorld);
+               theCullDistance = cullTarget*5;
+            }
+         }
+         if(theViewport.valid()&&theViewportChangedFlag)
+         {
+            theCameraNode->setProjectionMatrix(osg::Matrix::ortho2D(theViewport->x(),
+                                                                    theViewport->width(),
+                                                                    theViewport->y(),
+                                                                    theViewport->height()));
+            ossim_float64 dx = theViewport->width()*.5;
+            ossim_float64 dy = theViewport->height()*.5;
+            the2DMatrixTransform->setMatrix(osg::Matrixd::scale(osg::Vec3d(theVideo->imageWidth(),
+                                                                           theVideo->imageHeight(),
+                                                                           1.0))*
+                                            osg::Matrixd::translate(osg::Vec3d(theViewport->x() + dx,
+                                                                               theViewport->y() + dy,
+                                                                               0.0)));
+            theViewportChangedFlag = false;
+            setRedrawFlag(true);
+         }
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+//          if(!theEnableFlag)
+//          {
+//             break;
+//          }
+         
+         osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if(cullVisitor)
+         {
+            theCullFlag = nv.getDistanceToEyePoint(theFrameCenter, false) > theCullDistance;
+            traverseChildrenFlag = theEnableFlag&&!theCullFlag;
+            if(!theCullFlag)
+            {
+               double x = cullVisitor->getViewport()->x();
+               double y = (int)cullVisitor->getViewport()->y();
+               double w = (int)cullVisitor->getViewport()->width();
+               double h = (int)cullVisitor->getViewport()->height();
+               if(!theViewport.valid())
+               {
+                  theViewport = new osg::Viewport(x,y,w,h);
+                  theViewportChangedFlag = true;
+               }
+               else
+               {
+                  if( !ossim::almostEqual(theViewport->x(), x)||
+                      !ossim::almostEqual(theViewport->y(), y)||
+                      !ossim::almostEqual(theViewport->width(), w)||
+                      !ossim::almostEqual(theViewport->height(), h))
+                  {
+                     theViewport->setViewport(x,y,w,h);
+                     theViewportChangedFlag = true;
+                  }
+               }
+            }
+            break;
+         }
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+         if(ev)
+         {
+            const osgGA::EventVisitor::EventList& eventList = ev->getEvents();
+            osgGA::EventVisitor::EventList::const_iterator iter = eventList.begin();
+            if(eventList.size())
+            {
+               if(((*iter)->getEventType() == osgGA::GUIEventAdapter::FRAME))
+               {
+                  if(ev->getActionAdapter())
+                  {
+                     if(theRedrawFlag)
+                     {
+                        ev->getActionAdapter()->requestRedraw();
+                        theRedrawFlag = false;
+                     }
+                  }
+               }
+            }
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   theCurrentFrame->setEnableFlag(traverseChildrenFlag);
+   if(traverseChildrenFlag)
+   {
+      ossimPlanetVideoLayerNode::traverse(nv);
+   }
+}
+
+void ossimPlanetPredatorVideoLayerNode::updateIconGeometry()
+{
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetSceneView.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetSceneView.cpp
new file mode 100644
index 0000000..b78c0cc
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetSceneView.cpp
@@ -0,0 +1,214 @@
+#include <iostream>
+#include <osg/Projection>
+#include <ossimPlanet/ossimPlanetSceneView.h>
+#include <osg/LineSegment>
+#include <ossim/base/ossimConstants.h>
+
+
+ossimPlanetSceneView::ossimPlanetSceneView()
+{
+}
+
+// bool ossimPlanetSceneView::intersectScene(osg::Vec3d& intersection,
+//                                           const osg::Vec3d& startPt,
+//                                           const osg::Vec3d& endPt)
+// {
+//    if(!getSceneData()) return false;
+//    osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
+   
+//    osgUtil::IntersectVisitor iv;
+//    osg::Vec3d s = startPt;
+//    osg::Vec3d e = endPt;
+
+//    segLookVector->set(s, e);
+//    iv.addLineSegment(segLookVector.get());
+   
+//    getSceneData()->accept(iv);
+//    bool hitFound = false;
+//    if (iv.hits())
+//    {
+//       osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
+//       if (!hitList.empty())
+//       {
+//          intersection = hitList.front().getWorldIntersectPoint();
+         
+//          hitFound = true;
+//       }
+//    }
+
+//    return hitFound;
+// }
+
+bool ossimPlanetSceneView::pickObjects(osgUtil::IntersectVisitor::HitList& hits,
+                                       osg::Node* startNode,
+                                       double vx, double vy,
+                                       double /*startPointShift*/)
+{
+   osg::Node* rootNode = 0;
+   if(startNode)
+   {
+      rootNode = startNode;
+   }
+   else
+   {
+      rootNode = getSceneData();
+   }
+   osg::Matrixd proj   = getProjectionMatrix();
+   osg::Matrixd view   = getViewMatrix();
+   const osg::Viewport* viewport = getViewport();
+   osg::Matrixd projToWindow = viewport->computeWindowMatrix();
+   osg::Vec3d projPt(vx, vy, 1.0);
+   osg::Vec3d windowPt = projPt*projToWindow;
+   
+   osg::NodePathList parentNodePaths = rootNode->getParentalNodePaths(rootNode);
+   for(unsigned int i=0;i<parentNodePaths.size();++i)
+   {
+      osg::NodePath& nodePath = parentNodePaths[i];
+      
+      // remove the intersection node from the nodePath as it'll be accounted for
+      // in the PickVisitor traversal, so we don't double account for its transform.
+      if (!nodePath.empty()) nodePath.pop_back();  
+      
+      osg::Matrixd modelview(view);
+      // modify the view matrix so that it accounts for this nodePath's accumulated transform
+      if (!nodePath.empty()) modelview.preMult(computeLocalToWorld(nodePath));
+      
+      osgUtil::PickVisitor pick(viewport, proj, modelview, windowPt[0], windowPt[1]);
+      pick.setTraversalMask(0xffffffff);
+      rootNode->accept(pick);
+      
+      // copy all the hits across to the external hits list
+      for(osgUtil::PickVisitor::LineSegmentHitListMap::iterator itr = pick.getSegHitList().begin();
+          itr != pick.getSegHitList().end();
+          ++itr)
+      {
+         hits.insert(hits.end(), itr->second.begin(), itr->second.end());
+      }
+      
+   }
+
+   return !hits.empty();
+}
+ 
+bool ossimPlanetSceneView::intersectScene(osg::Node* startNode,
+                                          osg::Vec3d& intersectionPoint,
+                                          double vx, double vy,
+                                          double startPointShift)
+{
+   osgUtil::IntersectVisitor::HitList hits;
+   if(!pickObjects(hits, startNode, vx, vy, startPointShift))
+   {
+      return false;
+   }
+   intersectionPoint = hits.front().getWorldIntersectPoint();
+
+   return true;
+}
+
+// bool ossimPlanetSceneView::computeNadirIntersection(osg::Vec3d& intersectionPoint,
+//                                                   double startPointShift)
+// {
+//    osg::Vec3 eye(0,0,0);
+//    osg::Vec3 center(0,0,0);
+//    osg::Vec3 up(0,0,0);
+//    osg::Vec3d start;
+//    getViewMatrixAsLookAt(eye, center, up);
+//    osg::Vec3d direction = center-eye;
+//    direction.normalize();
+//    intersectionPoint = osg::Vec3d(0.0,0.0,0.0);
+//    start = eye + direction*startPointShift;
+//    return intersectScene(intersectionPoint,
+//                          start,
+//                          start + direction*(1.0/FLT_EPSILON));
+// }
+
+bool ossimPlanetSceneView::computeLineOfSiteIntersection(osg::Vec3d& intersectionPoint,
+                                                       double startPointShift)
+{
+   osg::Viewport* v = getViewport();
+   
+   if(v)
+   {
+      return intersectScene(0,
+                            intersectionPoint,
+                            (double)v->x() + v->width()/2.0,
+                            (double)v->y() + v->height()/2.0,
+                            startPointShift);
+   }
+
+   intersectionPoint = osg::Vec3d(0.0,0.0,0.0);
+   
+   return false;
+}
+
+// bool ossimPlanetSceneView::makeRay(osg::Vec3d& origin,
+//                                  osg::Vec3d& ray,
+//                                  double vx, double vy)
+// {
+//    osg::Vec3 eye(0,0,0);
+//    osg::Vec3 center(0,0,0);
+//    osg::Vec3 up(0,0,0);
+//    osg::Vec3 direction;
+//    double fov;
+//    double aspectRatio;
+//    double znear;
+//    double zfar;
+//    osg::Matrixd pm = getProjectionMatrix();
+//    ray[0] = 0;
+//    ray[1] = 0;
+//    ray[2] = 0;
+   
+//    if(!pm.getPerspective(fov, aspectRatio, znear, zfar))
+//    {
+//       return false;
+//    }
+//    getViewMatrixAsLookAt(eye, center, up, 1000.0);
+//    osg::Matrixd iv = getViewMatrix();
+   
+//    const osg::ref_ptr<osg::Viewport> viewport = getViewport();
+//    osg::Matrix wm;
+//    wm.invert(viewport->computeWindowMatrix());
+//    osg::Vec3d normalizedPoint = osg::Vec3d(vx,vy,0.0)*wm;
+
+//    double angleY = (fov*.5)*normalizedPoint[1];
+//    double angleX = (fov*.5)*normalizedPoint[0]*aspectRatio;
+// //    double angleX = (fov*.5)*normalizedPoint[0];
+// //    double angleY = (fov*.5)*normalizedPoint[1];
+//    direction = center - eye;
+//    direction.normalize();
+   
+//    osg::Vec3d crossVec = direction^up;
+//    osg::Vec3d newUp = crossVec^direction;
+//    osg::Matrixd m = (osg::Matrixd::rotate(-angleX*(M_PI/180.0), newUp)*
+//                      osg::Matrixd::rotate(angleY*(M_PI/180.0), crossVec));
+//    ray    = direction*m;
+//    origin = eye;
+
+//    return true;
+// }
+
+void ossimPlanetSceneView::getEyePosition(osg::Vec3d& eye)const
+{
+   osg::Vec3 eyeTemp(0,0,0);
+   osg::Vec3 center(0,0,0);
+   osg::Vec3 up(0,0,0);
+   
+   (const_cast<ossimPlanetSceneView*>(this))->getViewMatrixAsLookAt(eyeTemp, center, up);
+
+   eye[0] = eyeTemp[0];
+   eye[1] = eyeTemp[1];
+   eye[2] = eyeTemp[2];
+}
+
+void ossimPlanetSceneView::getLookDirection(osg::Vec3d& direction)const
+{
+   osg::Vec3 eyeTemp(0,0,0);
+   osg::Vec3 center(0,0,0);
+   osg::Vec3 up(0,0,0);
+   
+   (const_cast<ossimPlanetSceneView*>(this))->getViewMatrixAsLookAt(eyeTemp, center, up);
+
+   direction = (center-eyeTemp);
+
+   direction.normalize();
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetServerThread.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetServerThread.cpp
new file mode 100644
index 0000000..4b5a281
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetServerThread.cpp
@@ -0,0 +1,310 @@
+#include <ossimPlanet/ossimPlanetServerThread.h>
+#include <OpenThreads/ScopedLock>
+#include <iostream>
+#include <osg/Timer>
+
+ossimPlanetServerThread::ossimPlanetServerThread(ossim_uint32 maxQueueSize)
+   :thePollingRatePerSecond(60),
+    theMaxQueueSize(maxQueueSize),
+    theDoneFlag(false),
+    theStartedFlag(false),
+    theQueueMessagesFlag(false)
+{
+}
+
+ossimPlanetServerThread::~ossimPlanetServerThread()
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theChannelList.size();++idx)
+   {
+      if(theChannelList[idx].valid())
+      {
+         theChannelList[idx]->close();
+         theChannelList[idx] = 0;
+      }
+   }
+   theChannelList.clear();
+}
+
+void ossimPlanetServerThread::run()
+{
+   if(theStartedFlag) return;
+   theStartedFlag = true;
+   theDoneFlag    = false;
+   while(!theDoneFlag)
+   {
+      std::vector<char> buf(SG_IO_MAX_MSG_SIZE*2);
+      ossim_uint32 idx = 0;
+      std::string msg;
+      bool needToSleep = true;
+      theChannelListMutex.lock();
+      for(idx = 0; idx < theChannelList.size(); ++idx)
+      {
+         int bytesRead = theChannelList[idx]->readline(&buf.front(), buf.size()>>1);
+         if(bytesRead > 0)
+         {
+            needToSleep = false;
+            ossimString s(buf.begin(),
+                          buf.begin()+bytesRead);
+            s = s.trim();
+            if(s!="")
+            {
+               // let's first try to see if the message could be handled immediately
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerMutex);
+               ossim_uint32 idx = 0;
+               bool handledFlag = false;
+               for(idx = 0; ((idx < theMessageHandlerList.size())&&!handledFlag); ++idx)
+               {
+                  handledFlag = theMessageHandlerList[idx]->handleMessage(s, theChannelList[idx].get());
+               }
+
+               // if it was not handled then just add it to the message queue.  Someone may be monitoring
+               // the thread and do not have a message handler callback.
+               //
+               if(!handledFlag&&theQueueMessagesFlag)
+               {
+                  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageQueueMutex);
+                  theMessageQueue.push(s);
+                  if(theMessageQueue.size() > theMaxQueueSize)
+                  {
+                     theMessageQueue.pop();
+                  }
+               }
+            }
+         }
+      }
+      theChannelListMutex.unlock();
+
+      if(needToSleep)
+      {
+         unsigned int hz = (unsigned int)((1.0/thePollingRatePerSecond)/1.0e-6);
+         microSleep(hz);
+      }
+   }
+   theStartedFlag = false;
+}
+
+int ossimPlanetServerThread::cancel()
+{
+   theDoneFlag = true;
+   return OpenThreads::Thread::cancel();
+}
+
+void ossimPlanetServerThread::setQueueMessagesFlag(bool flag)
+{
+   theQueueMessagesFlag = flag;
+}
+
+bool ossimPlanetServerThread::getQueueMessagesFlag()const
+{
+   return theQueueMessagesFlag;
+}
+
+osg::ref_ptr<SGSocket> ossimPlanetServerThread::addServer(const ossimString& host,
+                                                          const ossimString& port,
+                                                          const ossimString& portType,
+                                                          char delimiter)
+{
+   osg::ref_ptr<SGSocket> result = new SGSocket(host, port, portType);
+   if(result->open(SG_IO_IN))
+   {
+      result->setReadlineDelimiter(delimiter);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChannelListMutex);
+      theChannelList.push_back(result);
+   }
+   else
+   {
+      result = 0;
+   }
+   if(result.valid())
+   {
+      if(theChannelList.size()&&!theStartedFlag)
+      {
+         start();
+      }
+   }
+   return result;
+}
+
+osg::ref_ptr<SGSocket> ossimPlanetServerThread::removeServer(ossim_uint32 idx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChannelListMutex);
+   osg::ref_ptr<SGSocket> result;
+   if(idx < theChannelList.size())
+   {
+      if(theChannelList[idx].valid())
+      {
+         theChannelList[idx]->close();
+         result = theChannelList[idx];
+         theChannelList.erase(theChannelList.begin()+idx);
+      }
+   }
+   if((theChannelList.size()==0)&&(theStartedFlag))
+   {
+      cancel();
+   }
+
+   return result;
+}
+
+osg::ref_ptr<SGSocket> ossimPlanetServerThread::removeServer(const ossimString& host,
+                                                             const ossimString& port)
+{
+   osg::ref_ptr<SGSocket> result;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChannelListMutex);
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theChannelList.size(); ++idx)
+      {
+         if((theChannelList[idx]->get_hostname() == host.string())&&
+            (theChannelList[idx]->get_port_str() == port.string()))
+         {
+            theChannelList[idx]->close();
+            result = theChannelList[idx];
+            theChannelList.erase(theChannelList.begin()+idx);
+
+            break;
+         }
+      }
+   }
+   if((theChannelList.size()==0)&&(theStartedFlag))
+   {
+      cancel();
+   }
+   
+   return result;
+}
+
+bool ossimPlanetServerThread::setServer(ossim_uint32 idx,
+                                        const ossimString& host,
+                                        const ossimString& port,
+                                        const ossimString& portType)
+{
+   bool result = false;
+   
+   if(idx < theChannelList.size())
+   {
+      if(theChannelList[idx].valid())
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChannelListMutex);
+//          delete theChannelList[idx];
+//          theChannelList[idx] = new SGSocket(host, port, portType);
+         theChannelList[idx]->setSocket(host, port, portType);
+         result = theChannelList[idx]->open(SG_IO_IN);
+      }
+   }
+   if(result)
+   {
+      if(theChannelList.size()&&!theStartedFlag)
+      {
+         start();
+      }
+   }
+   return result;
+}
+
+ossimString ossimPlanetServerThread::getPort(ossim_uint32 idx)const
+{
+   ossimString result;
+   
+   if(idx < theChannelList.size())
+   {
+      if(theChannelList[idx].valid())
+      {
+         result = theChannelList[idx]->get_port_str();
+      }      
+   }
+
+   return result;
+}
+
+ossimString ossimPlanetServerThread::getServer(ossim_uint32 idx)const
+{
+   ossimString result;
+   
+   if(idx < theChannelList.size())
+   {
+      if(theChannelList[idx].valid())
+      {
+         result = theChannelList[idx]->get_hostname();
+      }      
+   }
+
+   return result;
+}
+
+ossimString ossimPlanetServerThread::getPortType(ossim_uint32 idx)const
+{
+   ossimString result;
+   
+   if(idx < theChannelList.size())
+   {
+      if(theChannelList[idx].valid())
+      {
+         result = theChannelList[idx]->get_port_style();
+      }      
+   }
+
+   return result;
+}
+
+ossim_uint32 ossimPlanetServerThread::getNumberOfServers()const
+{
+   return theChannelList.size();
+}
+
+bool ossimPlanetServerThread::nextMessage(ossimString& msg)
+{
+   bool result = false;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageQueueMutex);
+   if(!theMessageQueue.empty())
+   {
+      msg = theMessageQueue.front();
+      theMessageQueue.pop();
+      result = true;
+   }
+
+   return result;
+}
+
+void ossimPlanetServerThread::addMessageHandler(osg::ref_ptr<ossimPlanetServerMessageHandler> messageHandler)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerMutex);
+   int idx = findMessageHandler(messageHandler.get());
+
+   if(idx < 0)
+   {
+      theMessageHandlerList.push_back(messageHandler.get());
+   }
+}
+
+void ossimPlanetServerThread::removeMessageHandler(osg::ref_ptr<ossimPlanetServerMessageHandler> messageHandler)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerMutex);
+   int idx = findMessageHandler(messageHandler.get());
+   if(idx >= 0)
+   {
+      theMessageHandlerList.erase(theMessageHandlerList.begin() + idx);
+   }
+}
+
+ossim_uint32 ossimPlanetServerThread::getNumberOfMessageHandlers()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMessageHandlerMutex);
+   return theMessageHandlerList.size();
+}
+
+int ossimPlanetServerThread::findMessageHandler(ossimPlanetServerMessageHandler* handler)const
+{
+
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theMessageHandlerList.size(); ++idx)
+   {
+      if(handler == theMessageHandlerList[idx].get())
+      {
+         return static_cast<int>(idx);
+      }
+   }
+
+   return -1;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetShaderProgramSetup.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetShaderProgramSetup.cpp
new file mode 100644
index 0000000..0b8a36e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetShaderProgramSetup.cpp
@@ -0,0 +1,17 @@
+#include <ossimPlanet/ossimPlanetShaderProgramSetup.h>
+
+osg::ref_ptr<osg::Uniform> ossimPlanetShaderProgramSetup::getUniform(const ossimString& name)
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theUniformList.size(); ++idx)
+   {
+      if(theUniformList[idx]->getName() == name.string())
+      {
+         return theUniformList[idx].get();
+      }
+   }
+
+   return 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetSocketNetworkConnection.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetSocketNetworkConnection.cpp
new file mode 100644
index 0000000..22330f7
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetSocketNetworkConnection.cpp
@@ -0,0 +1,186 @@
+
+//#include <assert.h>
+//#include <errno.h>
+#include <string> 
+//#include <netdb.h> 
+//#include <netinet/in.h> 
+//#include <unistd.h>
+//#include <sys/types.h> 
+//#include <sys/socket.h> 
+#include <ossimPlanet/ossimPlanetSocketNetworkConnection.h>
+#include <ossimPlanet/mkUtils.h>
+#include <ossimPlanet/ossimPlanetDestinationCommandAction.h>
+
+ossimPlanetSocketNetworkConnection::ossimPlanetSocketNetworkConnection(const std::string& hostname, int port, char delimiter) :
+    ossimPlanetNetworkConnection(hostname + ":" + mkUtils::asString(port)),
+    actionDelimiter_(delimiter)
+{
+   theSocket = new ossimPlanetSocketNetworkConnection::ossimPlanetNetSocketRef;
+   if(theSocket->open(true)) // make a tcp stream
+   {
+      theSocket->setBlocking(false);
+      if(theSocket->connect(hostname.c_str(), port) > 0)
+      {
+         error_ = "unable to connect socket";
+         
+      }
+   }
+   else
+   {
+      theSocket = 0;
+      error_ = "unable to create socket";
+   }
+
+#if 0
+    // create and connect the socket
+    socket_ = socket(AF_INET, SOCK_STREAM, 0);
+    if (socket_ >= 0) {
+	struct hostent* host = gethostbyname(hostname.c_str());
+	if (host != NULL) {
+	    // Initialize the socket address structure
+	    struct sockaddr_in connectAddress;
+	    memset(&connectAddress, 0, sizeof(connectAddress));
+	    memcpy((char *)&connectAddress.sin_addr, host->h_addr, host->h_length);
+	    connectAddress.sin_family = host->h_addrtype; // Should be AF_INET
+	    connectAddress.sin_port = htons((unsigned short)port);
+	    
+	    // try to connect, repeat if EINTRrupted, abort on any other failure
+	    while (connect(socket_, (struct sockaddr*)&connectAddress, sizeof(connectAddress)) < 0) {
+		if (errno != EINTR) {
+		    error_ = "unable to connect socket";
+		    break;
+		}
+	    }
+	} else {
+	    error_ = "cannot gethostbyname(\"" + hostname + "\") : " + hstrerror(h_errno);
+	}
+    } else {
+	error_ = "unable to create socket";
+    }
+    
+    timeout_.tv_sec = 0;
+    timeout_.tv_usec = 0;
+#endif
+}
+
+ossimPlanetSocketNetworkConnection::~ossimPlanetSocketNetworkConnection() 
+{
+   if(theSocket.valid())
+   {
+      theSocket->close();
+   }
+   theSocket = 0;
+#if 0
+    if (socket_ >= 0) {
+	close(socket_);
+	socket_ = -1;
+    }
+#endif
+}
+
+void ossimPlanetSocketNetworkConnection::send(const ossimPlanetAction& a, const std::string& /*destination*/) 
+{
+   ossimString code;
+   a.sourceCode(code);
+   if (outBuffer_.empty())
+   {
+      int bytesWritten = theSocket->send(code.c_str(), code.length());
+      if (bytesWritten != (int)code.length())
+      {
+         outBuffer_.append(code.substr(bytesWritten == -1 ? 0 : bytesWritten));
+         outBuffer_.append(1, actionDelimiter_);
+      }
+      else
+      {
+         if (theSocket->send(&actionDelimiter_, 1) != 1)
+         {
+            outBuffer_.append(1, actionDelimiter_);
+         }
+      }
+   }
+   else
+   {
+      outBuffer_.append(code.string());
+      outBuffer_.append(1, actionDelimiter_);
+      attemptToFlushOutBuffer();
+   }
+}
+
+void ossimPlanetSocketNetworkConnection::receive()
+{
+#if 1
+    if(theSocket.valid())
+    {
+       attemptToFlushOutBuffer();
+       std::vector<char> readBuffer(4096);
+       int bytesRead = theSocket->recv(&readBuffer.front(), readBuffer.size());
+       if (bytesRead > 0)
+       {
+          inBuffer_.append(readBuffer.begin(), readBuffer.begin() + bytesRead);
+       }
+       else if (bytesRead == -1)
+       {
+          //std::cerr << "ossimPlanetSocketNetworkConnection::receive() failed to read data. NetworkConnection::name() = " << name_ << std::endl;
+       }
+
+       for (ossim_int64 eoc = inBuffer_.find(actionDelimiter_); eoc != std::string::npos; eoc = inBuffer_.find(actionDelimiter_))
+       {
+          ossimPlanetDestinationCommandAction(inBuffer_.substr(0, eoc), 
+                                              "ossimPlanetSocketNetworkConnection-" + name_).execute();
+          inBuffer_.erase(0, eoc + 1);
+       }
+    }
+#endif
+}
+
+// protected
+
+inline void ossimPlanetSocketNetworkConnection::attemptToFlushOutBuffer()
+{
+   if (!outBuffer_.empty())
+   {
+       int bytesWritten = theSocket->send(outBuffer_.c_str(), outBuffer_.length());
+      
+      if (bytesWritten != -1)
+      {
+         outBuffer_.erase(0, bytesWritten);
+      }
+
+      if (outBuffer_.length() > 64*1024)
+      {
+//          std::cerr << "Warning: ossimPlanetSocketNetworkConnection " << name_ << " has " << outBuffer_.length() << " bytes of backed up outgoing Actions!" << std::endl;
+      }
+   }
+#if 0
+   if(!theSocket.valid()) return;
+   if (!outBuffer_.empty())
+   {
+      int bytesWritten = theSocket->send(outBuffer_.c_str(), outBuffer_.length());
+//       int bytesWritten = theSocket->write(outBuffer_.c_str(), outBuffer_.length());
+      
+      if (bytesWritten != -1)
+      {
+         outBuffer_.erase(0, bytesWritten);
+      }
+
+      if (outBuffer_.length() > 64*1024)
+      {
+         std::cerr << "Warning: ossimPlanetSocketNetworkConnection " << name_ << " has " << outBuffer_.length() << " bytes of backed up outgoing Actions!" << std::endl;
+      }
+   }
+#endif
+#if 0
+    assert(socket_ >= 0);
+
+    if (!outBuffer_.empty()) {
+        int bytesWritten = write(socket_, outBuffer_.c_str(), outBuffer_.length());
+        if (bytesWritten != -1)
+            outBuffer_.erase(0, bytesWritten);
+            
+        if (outBuffer_.length() > 64*1024)
+            std::cerr << "Warning: ossimPlanetSocketNetworkConnection " << name_ << " has " << outBuffer_.length() << " bytes of backed up outgoing Actions!" << std::endl;
+    }
+#endif
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetSousaLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetSousaLayer.cpp
new file mode 100644
index 0000000..65afeed
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetSousaLayer.cpp
@@ -0,0 +1,749 @@
+#include <ossimPlanet/ossimPlanetSousaLayer.h>
+#include <ossimPlanet/ossimPlanetAction.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetLand.h>
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossim/base/ossimNotify.h>
+#include <ossim/base/ossimCommon.h>
+#include <ossim/base/ossimPreferences.h>
+#include <osgGA/EventVisitor>
+#include <ostream>
+#include <ossim/base/ossimNotify.h>
+
+class ossimPlanetSousaLayer::ossimPlanetSousaXmlActionOperation : public ossimPlanetOperation
+{
+public:
+   ossimPlanetSousaXmlActionOperation(ossimPlanetSousaLayer* layer, ossimPlanetXmlAction* action)
+   :theLayer(layer),
+   theAction(action)
+   {
+   }
+protected:
+   virtual void run()
+   {
+      theLayer->threadedXmlExecute(*theAction);
+   }
+   ossimPlanetSousaLayer* theLayer;
+   osg::ref_ptr<ossimPlanetXmlAction> theAction;
+};
+
+ossimPlanetSousaLayer::ossimPlanetSousaLayer()
+:theConnectionName(""),
+ theConnectionIp(""),
+ theConnectionPort(""),
+ theConnectionPortType(""),
+theIoThreadReceiverName(":io"),
+theZuiInitializedFlag(false),
+theViewChangedFlag(false),
+theViewMessageRate(30), // default to 30 times per second
+theCameraTestDelay(0),
+theNeedToAddImageGroupFlag(true)
+{
+   theXmlActionThreadQueue = new ossimPlanetOperationThreadQueue();
+   theAnnotationLayer      = new ossimPlanetAnnotationLayer;
+	theNodeCallback         = new ossimPlanetNodeReraiseCallback(this);
+	theAnnotationLayer->addCallback(theNodeCallback.get());
+   ossimPlanetLayer::addChild(theAnnotationLayer.get());
+   theSousaImageGroup = new ossimPlanetTextureLayerGroup;
+   theSousaImageGroup->setName("OSSIM Socket Image Group");
+}
+
+ossimPlanetSousaLayer::~ossimPlanetSousaLayer()
+{
+   theXmlActionThreadQueue->removeAllOperations();
+   theXmlActionThreadQueue->cancelCurrentOperation();
+   theXmlActionThreadQueue = 0;
+	theAnnotationLayer->removeCallback(theNodeCallback.get());
+   theAnnotationLayer = 0;
+}
+
+
+void ossimPlanetSousaLayer::removeImage(const ossimString& name, const ossimString& id)
+{
+	if(!theSousaImageGroup.valid()) return;
+   osg::ref_ptr<ossimPlanetTextureLayer> namedLayer;
+	if(!name.empty()&&!id.empty())
+	{
+      namedLayer = theSousaImageGroup->findLayerByNameAndId(name, id);
+	}
+	else if(!name.empty())
+	{
+		namedLayer = theSousaImageGroup->findLayerByName(name);
+	}
+	else if(!id.empty())
+	{
+		namedLayer = theSousaImageGroup->findLayerById(id);
+	}
+	if(namedLayer.valid())
+	{
+		namedLayer->remove();
+	}
+}
+
+void ossimPlanetSousaLayer::setIdentity(const ossimString& tempUserName, 
+													 const ossimString& tempDomain)
+{
+	theUserName = tempUserName;
+	theDomain   = tempDomain;
+	sendIdentityMessage();
+}
+
+const ossimString& ossimPlanetSousaLayer::username()const
+{
+	return theUserName;
+}
+
+const ossimString& ossimPlanetSousaLayer::domain()const
+{
+	return theDomain;
+}
+
+void ossimPlanetSousaLayer::xmlExecute(const ossimPlanetXmlAction &a)
+{
+   if(theXmlActionThreadQueue.valid())
+   {
+      ossim_uint32 idx = 0;
+      std::string command = a.command();
+      if(command == "Add")
+      {
+         if(a.xmlNode().valid())
+         {
+            const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+            for(idx = 0;idx<children.size();++idx)
+            {
+               osg::ref_ptr<ossimPlanetXmlAction> action                  = a.duplicateChildAndMaintainAction(idx);
+               osg::ref_ptr<ossimPlanetSousaXmlActionOperation> operation = new ossimPlanetSousaXmlActionOperation(this, action.get());
+               
+               ossimString tag = children[idx]->getTag();
+               ossimString groupType = children[idx]->getAttributeValue("groupType");
+               if((tag == "Image")||
+                  (groupType=="groundTexture"))
+               {
+                  ossimString id = children[idx]->getChildTextValue("id");
+                  operation->setId(id);
+                  operation->setName("Adding id = " + id);
+                  theXmlActionThreadQueue->add(operation.get());
+               }
+               else if((tag == "Placemark")||
+                       (groupType == "feature"))
+               {
+                  ossimString id = children[idx]->getChildTextValue("id");
+                  ossimString name = children[idx]->getChildTextValue("name");
+                  operation->setId(id);
+                  operation->setName(name);
+                  theXmlActionThreadQueue->add(operation.get());
+               }
+               else if(tag == "Group")
+               {
+                  ossimString id = children[idx]->getChildTextValue("id");
+                  ossimString name = children[idx]->getChildTextValue("name");
+                  operation->setId(id);
+                  operation->setName(name);
+                  ossimString groupType = children[idx]->getAttributeValue("groupType");
+                  theXmlActionThreadQueue->add(operation.get());
+               }
+               else
+               {
+                  theXmlActionThreadQueue->add(operation.get());
+               }
+            }
+         }
+      }
+      else if(command == "Remove")
+      {
+         const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+         if(children.empty())
+         {
+            osg::ref_ptr<ossimPlanetXmlAction> action                  = (ossimPlanetXmlAction*)a.clone();
+            osg::ref_ptr<ossimPlanetSousaXmlActionOperation> operation = new ossimPlanetSousaXmlActionOperation(this, action.get());
+            ossimString id   = a.xmlNode()->getAttributeValue("id");
+            if(!id.empty())
+            {
+               theXmlActionThreadQueue->removeById(id).valid();
+            }
+            theXmlActionThreadQueue->add(operation.get());
+         }
+         else
+         {
+            for(idx = 0;idx<children.size();++idx)
+            {
+               osg::ref_ptr<ossimPlanetXmlAction> action                  = a.duplicateChildAndMaintainAction(idx);
+               osg::ref_ptr<ossimPlanetSousaXmlActionOperation> operation = new ossimPlanetSousaXmlActionOperation(this, action.get());
+               ossimString id   = children[idx]->getAttributeValue("id");
+               if(id.empty())
+               {
+                  id = children[idx]->getChildTextValue("id");
+               }
+               if(!id.empty())
+               {
+                  theXmlActionThreadQueue->removeById(id).valid();
+               }
+               theXmlActionThreadQueue->add(operation.get());
+            }
+         }
+      }
+      else if(command == "Set")
+      {
+         theXmlActionThreadQueue->add(new ossimPlanetSousaXmlActionOperation(this,(ossimPlanetXmlAction*)a.clone()));
+      }
+   }
+}
+
+void ossimPlanetSousaLayer::threadedXmlExecute(const ossimPlanetXmlAction &a)
+{
+  // OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theXmlActionThreadQueueMutex);
+
+	std::string command = a.command();
+	if(command == "Add")
+	{
+      if(a.xmlNode().valid())
+      {
+         ossim_uint32 idx = 0;
+         const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();  
+         for(idx = 0;idx<children.size();++idx)
+         {
+				ossimString tag = children[idx]->getTag();
+				ossimString groupType = children[idx]->getAttributeValue("groupType");
+				if(tag == "ClientSocket")
+				{
+					setClientSocket(children[idx].get());
+				}
+				else if((tag == "Image")||
+						  (groupType=="groundTexture"))
+				{
+					addImageLayer(children[idx].get());
+				}
+				else if((tag == "Placemark")||
+                    (groupType == "feature"))
+				{
+               if(theAnnotationLayer.valid())
+               {
+                  ossimRefPtr<ossimXmlNode> xmlAction = new ossimXmlNode;
+						
+                  ossimPlanetXmlAction tempAction;
+                  xmlAction->setTag("Add");
+                  xmlAction->addChildNode((ossimXmlNode*)children[idx]->dup());
+                  tempAction.setXmlNode(xmlAction.get());
+                  
+                  theAnnotationLayer->execute(tempAction);
+               }
+				}
+				else if(tag == "Identity")
+				{
+					ossimString username = children[idx]->getChildTextValue("username");
+					ossimString domain   = children[idx]->getChildTextValue("domain");
+					
+					setIdentity(username, domain);
+				}
+				else if(tag == "Group")
+				{
+               ossimString groupType = children[idx]->getAttributeValue("groupType");
+					if(groupType == "groundTexture")
+					{
+					}
+					else if(groupType == "feature")
+					{
+					}
+				}
+			}
+		}
+	}
+   else if(command == "Set")
+   {
+      ossim_uint32 idx = 0;
+      ossimString id;
+      ossimString name;
+      const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();
+      if(children.size() > 0)
+      {
+         for(idx = 0;idx<children.size();++idx)
+         {
+            ossimString tag = children[idx]->getTag();
+				if(tag == "ClientSocket")
+				{
+					setClientSocket(children[idx].get());
+				}
+            else if(tag == "Camera")
+            {
+					OpenThreads::ScopedLock<OpenThreads::Mutex> testDelayLock(theCameraTestDelayMutex);
+               // let's set a 2 frame delay just in case the draw thread is already in the process of visiting us. So on the second visit
+               // we will do a view chnge test
+               //
+               theCameraTestDelay = 10;
+               ossimRefPtr<ossimXmlNode> xmlActionNode = new ossimXmlNode;
+					ossimRefPtr<ossimXmlNode> dupNode = (ossimXmlNode*)(children[idx]->dup());
+					ossimPlanetXmlAction tempAction;
+					xmlActionNode->setTag("Set");
+					xmlActionNode->addAttribute("target", ":navigator");
+               xmlActionNode->addChildNode(dupNode.get());
+               tempAction.setXmlNode(xmlActionNode.get());
+					tempAction.execute();
+               setRedrawFlag(true);
+               theZuiInitializedFlag = true;
+            }
+				else if(tag == "Identity")
+				{
+					ossimString username = children[idx]->getChildTextValue("username");
+					ossimString domain   = children[idx]->getChildTextValue("domain");
+					
+					setIdentity(username, domain);
+				}
+				else if(tag == "viewMessageRate")
+				{
+					theViewMessageRate = children[idx]->getText().toDouble();
+				}
+            else if(tag =="Placemark")
+            {
+               ossimPlanetXmlAction tempAction;
+               ossimRefPtr<ossimXmlNode> xmlAction = new ossimXmlNode;
+               xmlAction->setTag("Set");
+               xmlAction->addChildNode((ossimXmlNode*)children[idx]->dup());
+               tempAction.setXmlNode(xmlAction.get());
+               theAnnotationLayer->execute(tempAction);
+            }
+            else
+            {
+               id   = a.xmlNode()->getAttributeValue("id");
+               if(!id.empty())
+               {
+                  ossimPlanetXmlAction tempAction;
+                  ossimRefPtr<ossimXmlNode> xmlAction = new ossimXmlNode;
+                  xmlAction->setTag("Set");
+                  xmlAction->addAttribute("id", id);
+                  xmlAction->addChildNode((ossimXmlNode*)children[idx]->dup());
+                  tempAction.setXmlNode(xmlAction.get());
+                  theAnnotationLayer->execute(tempAction);
+               }
+            }
+         }
+      }
+   }
+	else if(command == "Remove")
+	{
+      if(a.xmlNode().valid())
+      {
+			ossim_uint32 idx = 0;
+			ossimString id;
+			ossimString name;
+         const ossimXmlNode::ChildListType& children = a.xmlNode()->getChildNodes();
+			if(children.size() > 0)
+			{
+				for(idx = 0;idx<children.size();++idx)
+				{
+					ossimString tag = children[idx]->getTag();
+               // check attribute section first for searchables
+               name = children[idx]->getAttributeValue("name");
+               id   = children[idx]->getAttributeValue("id");
+               ossimString groupType   = children[idx]->getAttributeValue("groupType");
+               
+               if(name.empty()&&id.empty())
+               {
+                  name = children[idx]->getChildTextValue("name");
+                  id   = children[idx]->getChildTextValue("id");
+               }
+               
+					if((tag == "Image")||
+						(groupType == "groundTexture"))
+					{
+						removeImage(name, id);
+					}
+					else if(tag == "Placemark")
+					{
+                  if(theAnnotationLayer.valid())
+                  {
+                     ossimRefPtr<ossimXmlNode> xmlAction = new ossimXmlNode;
+                     ossimPlanetXmlAction tempAction;
+                     xmlAction->setTag("Remove");
+                     xmlAction->addChildNode((ossimXmlNode*)children[idx]->dup());
+                     tempAction.setXmlNode(xmlAction.get());
+                     theAnnotationLayer->execute(tempAction);
+                  }
+					}
+					else 
+					{
+						removeImage(name, id);
+						// do a generalized find and remove
+					}
+				}
+			}
+			else
+			{
+				name = "";
+				id   = "";
+				// do generalized remove if the Remove has an id attribute
+				//
+				// basically allow one to do <Remove id="....."/>
+				//
+				if(a.xmlNode()->getAttributeValue(id, "id")||
+					a.xmlNode()->getAttributeValue(name, "name"))
+				{
+					removeImage(name, id);
+				}
+            // wil also send to the Annotation layer to find the ID
+            //
+            if(theAnnotationLayer.valid())
+            {
+               theAnnotationLayer->execute(a);
+            }
+			}
+		}
+	}
+}
+
+void ossimPlanetSousaLayer::execute(const ossimPlanetAction &a)
+{
+   const ossimPlanetXmlAction* xmlAction = a.toXmlAction();
+
+	if(xmlAction)
+	{
+		xmlExecute(*xmlAction);
+	}
+}
+
+void ossimPlanetSousaLayer::closeConnections()
+{
+   std::ostringstream out;
+
+	if(!theConnectionName.empty())
+	{
+		out<< "<Remove target=\"" << theIoThreadReceiverName << "\"" << "id=\"" << theConnectionName <<":"<<theConnectionPort << "\"/>";
+	}
+	else
+	{
+		out<< "<Remove target=\"" << theIoThreadReceiverName << "\"" << "id=\"" << theConnectionIp <<":"<<theConnectionPort << "\"/>";
+	}
+   ossimPlanetXmlAction(out.str()).execute();
+
+   theConnectionName = "";
+   theConnectionIp = "";
+   theConnectionPort = "";
+   theConnectionPortType = "";
+	if(theAnnotationLayer.valid())
+	{
+		if(theAnnotationLayer->getNumChildren() > 0)
+		{
+			theAnnotationLayer->removeChild(0, theAnnotationLayer->getNumChildren());
+		}
+	}
+}
+
+void ossimPlanetSousaLayer::traverse(osg::NodeVisitor& nv)
+{
+	OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theUpdateMutex);
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!thePlanet)
+         {
+            thePlanet = ossimPlanet::findPlanet(this);
+         }
+         if(thePlanet)
+         {
+            if(theZuiInitializedFlag)
+            {
+               if(theViewChangedFlag)
+               {
+                  sendViewMessage();
+               }
+            }
+         }
+         break;
+      }
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
+         if(ev)
+         {
+            ossimPlanetViewer* viewer = dynamic_cast<ossimPlanetViewer*>(ev->getActionAdapter());
+            if(theNeedToAddImageGroupFlag)
+            {
+               viewer->addImageTexture(theSousaImageGroup.get());
+               theNeedToAddImageGroupFlag = false;
+            }
+            if(viewer&&viewer->currentCamera())
+            {
+               osg::Vec3d currentEye(viewer->currentCamera()->lat(),
+                                     viewer->currentCamera()->lon(),
+                                     viewer->currentCamera()->altitude());
+               osg::Vec3d currentHpr(viewer->currentCamera()->heading(),
+                                     viewer->currentCamera()->pitch(),
+                                     viewer->currentCamera()->roll());
+               OpenThreads::ScopedLock<OpenThreads::Mutex> testDelayLock(theCameraTestDelayMutex);
+               if(theCameraTestDelay>0)
+               {
+                  theEyePosition    = currentEye;
+                  theEyeOrientation = currentHpr;
+                  --theCameraTestDelay;
+                  setRedrawFlag(true);
+               }
+               else if(!ossim::almostEqual(theEyePosition[0], currentEye[0])||
+                       !ossim::almostEqual(theEyePosition[1], currentEye[1])||
+                       !ossim::almostEqual(theEyePosition[2], currentEye[2])||
+                       !ossim::almostEqual(theEyeOrientation[0], currentHpr[0])||
+                       !ossim::almostEqual(theEyeOrientation[1], currentHpr[1])||
+                       !ossim::almostEqual(theEyeOrientation[2], currentHpr[2]))
+               {
+                 theEyePosition    = currentEye;
+                  theEyeOrientation = currentHpr;
+                  if(!theViewChangedFlag)
+                  {
+                     theViewChangeStart = osg::Timer::instance()->tick();
+                  }
+                  theViewChangedFlag = true;
+               }
+               
+            }
+         }
+         
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   ossimPlanetLayer::traverse(nv);
+}
+
+void ossimPlanetSousaLayer::addImageLayer(const ossimXmlNode* imageObject)
+{
+	ossimString parentId    = imageObject->getAttributeValue("parentId");;
+
+#if 0
+	//ossimNotify(ossimNotifyLevel_WARN) << "Testing notifications" << std::endl;
+	if(!thePlanet) return;
+	osg::ref_ptr<ossimPlanetLand> land = thePlanet->land();
+	if(!land.valid())
+	{
+		return;
+	}
+	if(!land->referenceLayer().valid()) return;
+	osg::ref_ptr<ossimPlanetTextureLayerGroup> layerGroup;
+	osg::ref_ptr<ossimPlanetTextureLayer> namedLayer;
+	if(!parentId.empty())
+	{
+		namedLayer = land->referenceLayer()->findLayerById(parentId);
+	}
+	if(namedLayer.valid())
+	{
+		layerGroup = namedLayer->asGroup();
+	}
+	
+	if(!layerGroup.valid())
+	{
+		layerGroup = land->referenceLayer().get();
+	}
+	if(!layerGroup.valid())
+	{
+		return;
+	}
+#endif
+	osg::ref_ptr<ossimPlanetTextureLayerGroup> layerGroup = theSousaImageGroup.get();
+	osg::ref_ptr<ossimPlanetTextureLayer> namedLayer;
+	if(!parentId.empty())
+	{
+		namedLayer = layerGroup->findLayerById(parentId);
+	}
+	if(namedLayer.valid())
+	{
+		layerGroup = namedLayer->asGroup();
+	}
+	
+//	if(!layerGroup.valid())
+//	{
+//		layerGroup = land->referenceLayer().get();
+//	}
+	if(!layerGroup.valid())
+	{
+		return;
+	}
+	addImageToGroup(theSousaImageGroup.get(), imageObject);
+}
+
+void ossimPlanetSousaLayer::addImageToGroup(ossimPlanetTextureLayerGroup* group, const ossimXmlNode* imageObject)
+{
+	if(!group) return;
+	ossimString description = imageObject->getChildTextValue("description");
+	ossimString id          = imageObject->getChildTextValue("id");
+	ossimString name        = imageObject->getChildTextValue("name");
+	ossimFilename filename  = imageObject->getChildTextValue("filename").trim();
+	ossimString tag = imageObject->getTag();
+	if(tag=="Image")
+	{
+		// test if the filename for a mapping
+		if(theArchive.valid()&&
+			theArchive->archiveMappingEnabled() )
+		{
+			//ossimNotify(ossimNotifyLevel_WARN) << "Archive mapping is valid and enabled" << std::endl;
+			
+			filename = theArchive->matchPath(filename);
+			
+			//ossimNotify(ossimNotifyLevel_WARN) << "Archive Filename: " << filename << std::endl;
+			//ossimNotify(ossimNotifyLevel_WARN) << "Archive Result: " << result << std::endl;
+		}
+		//ossimNotify(ossimNotifyLevel_WARN) << "Testing the file: " << filename << std::endl;
+		if(!filename.empty()&&filename.exists())
+		{
+         if(!group->findLayerById(id))
+         {
+//            ossimNotify(ossimNotifyLevel_WARN) << "The file is not empty" << std::endl;
+//            ossimNotify(ossimNotifyLevel_WARN) << "Filename:" << filename << std::endl;
+            
+            osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(filename);
+            if(layer.valid())
+            {
+               layer->setId(id);
+               layer->setDescription(description);
+               layer->setName(name);
+               group->addTop(layer.get());
+            }
+         }
+         else
+         {
+//            ossimNotify(ossimNotifyLevel_WARN) << "Failed test and coudn't add image" << std::endl;
+         }
+      }
+      else
+      {
+//         ossimNotify(ossimNotifyLevel_INFO) << "Couldn't add file:" << filename <<"--"<< std::endl;
+      }
+	}
+	else if(tag == "Group")
+	{
+		const ossimXmlNode::ChildListType& children = imageObject->getChildNodes();
+		ossimPlanetTextureLayerGroup* newGroup = new ossimPlanetTextureLayerGroup;
+		newGroup->setId(id);
+		newGroup->setDescription(description);
+		newGroup->setName(name);
+		group->addTop(newGroup);
+		ossim_int32 idx = 0;
+		ossim_int32 n = (ossim_int32)children.size();
+		if(n > 0)
+		{
+			for(idx = n-1; idx >= 0;--idx)
+			{
+				addImageToGroup(newGroup, children[idx].get());
+			}
+		}
+	}
+}
+
+
+void ossimPlanetSousaLayer::setConnection(const ossimString& name,
+                                          const ossimString& ip,
+                                          const ossimString& port,
+                                          const ossimString& portType)
+{
+	closeConnections();
+   theConnectionName = name;
+   theConnectionIp = ip;
+   theConnectionPort = port;
+   theConnectionPortType = portType;
+   std::ostringstream out;
+   out
+   << "<Open target=\"" << theIoThreadReceiverName << "\">"
+   <<    "<ClientSocket>"
+   <<       "<name>" << name << "</name>"
+   <<       "<ip>"   << ip   << "</ip>"
+   <<       "<port>" << port << "</port>"
+   <<       "<portType>" << portType << "</portType>"
+   <<    "</ClientSocket>"
+   << "</Open>";
+   ossimPlanetXmlAction(out.str()).execute();
+	sendIdentityMessage();   
+}
+
+void ossimPlanetSousaLayer::setClientSocket(const ossimXmlNode* node)
+{
+   ossimString name, ip, port, portType;
+	node->getChildTextValue(name, "name");
+	node->getChildTextValue(ip, "ip");
+	node->getChildTextValue(port, "port");
+	node->getChildTextValue(portType, "portType");
+   setConnection(name, ip, port, portType);
+}
+
+void ossimPlanetSousaLayer::sendViewMessage()
+{
+	if(theViewMessageRate <FLT_EPSILON)
+	{
+		theViewChangedFlag = false;
+		return;
+	}
+	if(theConnectionIp.empty()&&theConnectionPort.empty()) return;
+	bool canSend = osg::Timer::instance()->delta_s(theViewChangeStart, osg::Timer::instance()->tick()) > (1.0/theViewMessageRate);
+	
+   if(canSend)
+   {
+      std::ostringstream out;
+      out
+      << "<SendMessage target='" << theIoThreadReceiverName << "'" << "ioTargetId='" << theConnectionName <<":"<<theConnectionPort << "'" << "id='" << "View'>"
+      <<   "<Set target=\":idolbridge\">"
+      <<     "<Camera vref=\"wgs84\">"
+      <<          "<longitude>" << ossimString::toString(theEyePosition[1]) << "</longitude>"
+      <<          "<latitude>" << ossimString::toString(theEyePosition[0]) << "</latitude>"
+      <<          "<altitude>" << ossimString::toString(theEyePosition[2]) << "</altitude>"
+      <<          "<heading>"<< ossimString::toString(theEyeOrientation[0])<<"</heading>"
+      <<          "<pitch>"<< ossimString::toString(theEyeOrientation[1])<<"</pitch>"
+      <<          "<roll>"<< ossimString::toString(theEyeOrientation[2])<<"</roll>"
+      <<          "<altitudeMode>absolute</altitudeMode>"
+      <<     "</Camera>"
+      <<   "</Set>"
+      << "</SendMessage>";
+      ossimPlanetXmlAction(out.str()).execute();
+		theViewChangedFlag = false;
+   }	
+	if(theViewChangedFlag)
+	{
+		setRedrawFlag(true);
+	}
+}
+
+void ossimPlanetSousaLayer::setArchive(osg::ref_ptr<ossimPlanetArchive> archive)
+{
+	theArchive = archive;
+}
+
+void ossimPlanetSousaLayer::sendIdentityMessage()
+{
+   if(!theConnectionIp.empty()&&
+      !theConnectionPort.empty())
+   {
+		std::ostringstream out;
+      std::ostringstream outIdentityConnectionHeader;
+      out
+      << "<SendMessage target=\"" << theIoThreadReceiverName << "\"" << "id=\"" << theConnectionName <<":"<<theConnectionPort << "\" forceSend=\"true\">"
+      <<   "<Set>"
+      <<     "<Identity>"
+      <<          "<username>" << theUserName << "</username>";
+		
+		if(!theDomain.empty())
+		{
+			out <<          "<domain>" << theDomain<< "</domain>";
+		}
+      out <<     "</Identity>"
+      <<   "</Set>"
+      << "</SendMessage>";
+      
+      outIdentityConnectionHeader
+      << "<Set target=\"" << theIoThreadReceiverName << "\"" << "id=\"" << theConnectionName <<":"<<theConnectionPort <<"\">"
+      <<   "<connectionHeader><![CDATA[<Set>"
+      <<     "<Identity>"
+      <<          "<username>" << theUserName << "</username>";
+		
+		if(!theDomain.empty())
+		{
+			outIdentityConnectionHeader <<          "<domain>" << theDomain<< "</domain>";
+		}
+      outIdentityConnectionHeader
+      <<     "</Identity>"
+      <<   "</Set>]]></connectionHeader>"
+      << "</Set>";
+      
+      ossimPlanetXmlAction(out.str()).execute();
+      ossimPlanetXmlAction(outIdentityConnectionHeader.str()).execute();
+	}
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetSrtmElevationDatabase.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetSrtmElevationDatabase.cpp
new file mode 100644
index 0000000..4c9389b
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetSrtmElevationDatabase.cpp
@@ -0,0 +1,804 @@
+#include <ossimPlanet/ossimPlanetSrtmElevationDatabase.h>
+#include <ossim/base/ossimFilename.h>
+#include <ossim/base/ossimDirectory.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/imaging/ossimImageHandlerRegistry.h>
+#include <ossim/imaging/ossimImageHandler.h>
+#include <ossim/support_data/ossimSrtmSupportData.h>
+#include <ossim/projection/ossimImageViewProjectionTransform.h>
+
+ossimPlanetSrtmElevationDatabase::ossimPlanetSrtmElevationDatabase()
+   :ossimPlanetElevationDatabase()
+{
+   theOpenFlag = false;
+   theLocation = "";
+   theMaxOpenFiles = 25;
+   theMinOpenFiles = 20;
+
+//    theRenderer = new ossimImageRenderer;
+//    theRenderer->getResampler()->setFilterType("bilinear");
+//    theProjection    = new ossimEquDistCylProjection;
+//    theNullHeightValue = -32768.0;
+}
+
+ossimPlanetSrtmElevationDatabase::ossimPlanetSrtmElevationDatabase(const ossimPlanetSrtmElevationDatabase& src)
+   :ossimPlanetElevationDatabase(src),
+    theLocation(src.theLocation),
+    theOpenFlag(src.theOpenFlag),
+    theMaxOpenFiles(src.theMaxOpenFiles),
+    theMinOpenFiles(src.theMinOpenFiles)
+{
+//    theMosaic   = new ossimOrthoImageMosaic;
+//    theRenderer = new ossimImageRenderer;
+//    theRenderer->getResampler()->setFilterType("bilinear");
+//    theProjection    = new ossimEquDistCylProjection;   
+}
+
+ossimPlanetSrtmElevationDatabase::~ossimPlanetSrtmElevationDatabase()
+{
+   
+}
+
+ossimPlanetTextureLayer* ossimPlanetSrtmElevationDatabase::dup()const
+{
+   return new ossimPlanetSrtmElevationDatabase(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetSrtmElevationDatabase::dupType()const
+{
+   return new ossimPlanetSrtmElevationDatabase;
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetSrtmElevationDatabase::updateExtents()
+{
+
+   theDirtyExtentsFlag = false;
+   return theStateCode;
+}
+
+void ossimPlanetSrtmElevationDatabase::updateStats()const
+{
+   theStats->setTotalTextureSize(0);
+   theDirtyStatsFlag = false;
+   
+}
+
+void ossimPlanetSrtmElevationDatabase::resetStats()const
+{
+   theStats->setBytesTransferred(0);
+   theStats->setTotalTextureSize(0);
+}
+
+
+ossimPlanetTextureLayerStateCode ossimPlanetSrtmElevationDatabase::open(const std::string& location)
+{
+   ossimFilename file(location);
+   bool result = false;
+   theLocation = "";
+   theExtents = new ossimPlanetExtents;
+
+   if(file.exists())
+   {
+      if(file.isDir())
+      {
+         ossimDirectory dir;
+
+         if(dir.open(file))
+         {
+            ossimFilename testFile;
+            if(dir.getFirst(testFile))
+            {
+               do
+               {
+                  ossimSrtmSupportData supportData;
+                  if(supportData.setFilename(testFile))
+                  {
+//                      double minLat = std::floor(supportData.getSouthwestLatitude());
+//                      double minLon = std::floor(supportData.getSouthwestLongitude());
+//                      double maxLat = minLat + 1.0;
+//                      double maxLon = minLon + 1.0;
+//                      if(!result)
+//                      {
+                     double metersPerPixel   = ossimGpt().metersPerDegree().y*supportData.getLatitudeSpacing();
+//                         theExtents->setMinMaxLatLon(minLat, minLon,
+//                                                     maxLat, maxLon);
+                     result = true;
+                     dirtyExtents(); // make sure parents are marked as dirty
+                     if((supportData.getNumberOfLines() == 3601)&&
+                        (supportData.getNumberOfSamples() == 3601))
+                     {
+                        theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 10));
+                        setName("SRTM1");
+                        setDescription("SRTM 30 meter elevation database");
+                     }
+                     else if((supportData.getNumberOfLines() == 1201)&&
+                             (supportData.getNumberOfSamples() == 1201))
+                     {
+                        theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 8));
+                        setName("SRTM3");
+                        setDescription("SRTM 90 meter elevation database");
+                     }
+                     else if( (supportData.getNumberOfLines() > 3601)&&
+                              (supportData.getNumberOfSamples() > 3601))
+                     {
+                        setName("SRTM");
+                        setDescription("SRTM elevation database");
+                        theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 8)); 
+                     }
+                     else
+                     {
+                        setName("SRTM");
+                        setDescription("SRTM elevation database");
+                        theExtents->setMinMaxScale(metersPerPixel, metersPerPixel*std::pow(2.0, 8));
+                     }
+//                      }
+//                      else
+//                      {
+//                         theExtents->combineMinMaxLatLon(minLat, minLon,
+//                                                         maxLat, maxLon);
+//                      }
+                  }
+               }while(dir.getNext(testFile)&&!result);
+            }
+         }
+      }
+   }
+   
+   theOpenFlag = result;
+   if(theOpenFlag)
+   {
+      theStateCode = ossimPlanetTextureLayer_VALID;
+      theLocation = location;
+   }
+   else
+   {
+      theStateCode = ossimPlanetTextureLayer_NO_SOURCE_DATA;
+   }
+   
+   return theStateCode;
+}
+
+bool ossimPlanetSrtmElevationDatabase::hasTexture(ossim_uint32 width,
+                                          ossim_uint32 height,
+                                          const ossimPlanetTerrainTileId& tileId,
+                                          const ossimPlanetGrid& grid)
+{
+   if(!theOpenFlag)
+   {
+      return false;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return false;
+   }
+   ossimPlanetGrid::GridBound bound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      ossimPlanetGrid::GridBound tileBound;
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return false;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   //double deltaLon    = (deltaXY[0])/(double)(width);
+   
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   ossimPlanetGrid::ModelPoint minLatLon, maxLatLon;
+   grid.modelBound(tileId, minLatLon, maxLatLon);
+   if((gsd.y >= theExtents->getMinScale()) &&
+      (gsd.y <= theExtents->getMaxScale()))
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points);
+      ossim_float64 minModelX, minModelY, maxModelX, maxModelY;
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      minModelX = points[0].x();
+      maxModelX = minModelX;
+      minModelY = points[0].y();
+      maxModelY = minModelY;
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      ++optimizedOutPtr;
+      for(idxPts = 1; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         if(optimizedOutPtr->x() < minModelX) minModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->x() > maxModelX) maxModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->y() < minModelY) minModelY = optimizedOutPtr->y();
+         if(optimizedOutPtr->y() > maxModelY) maxModelY = optimizedOutPtr->y();
+      }
+      ossim_int32 wholeMinY = (ossim_int32)std::floor(minModelY);
+      ossim_int32 wholeMinX = (ossim_int32)std::floor(minModelX);
+      ossim_int32 wholeMaxY = (ossim_int32)std::floor(maxModelY);
+      ossim_int32 wholeMaxX = (ossim_int32)std::floor(maxModelX);
+      
+      
+      ossim_int32 lat = wholeMaxY;
+      ossim_int32 lon = wholeMinX;
+      
+      
+      //    std::vector<ossimDpt> latLonOrigins;
+      std::vector<std::string> latLonOrigins;
+      
+      for(;lat >= wholeMinY; --lat)
+      {
+         lon = wholeMinX;
+         for(;lon <= wholeMaxX; ++lon)
+         {
+            ossimFilename filename = buildFilename(lat, lon);
+            if(filename != "")
+            {
+               return true;
+            }
+         }
+      }
+      
+   }
+   
+   return false;
+}
+osg::ref_ptr<ossimPlanetImage> ossimPlanetSrtmElevationDatabase::getTexture(ossim_uint32 width,
+                                                                            ossim_uint32 height,
+                                                                            const ossimPlanetTerrainTileId& tileId,
+                                                                            const ossimPlanetGrid& grid,
+                                                                            ossim_int32 padding)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+      ossimElevManager* manager = ossimElevManager::instance();
+      double minValue = 999999999.0;
+      double maxValue = -999999999.0;
+      for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         double h = manager->getHeightAboveEllipsoid(ossimGpt((*optimizedOutPtr).y(), (*optimizedOutPtr).x()));
+         if(!ossim::isnan(h))
+         {
+            *bufPtr = h;
+         }
+         
+         ++bufPtr;
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+#if 0
+   if(!theOpenFlag)
+   {
+      return 0;
+   }
+   
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   osg::ref_ptr<ossimPlanetImage> texture;
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   double deltaLon    = (deltaXY[0])/(double)(width);
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y < theExtents->getMaxScale())
+   {
+      ossimPlanetGrid::ModelPoints points;
+      grid.createModelPoints(tileId,
+                             width,
+                             height,
+                             points,
+                             padding);
+      ossim_float64 minModelX, minModelY, maxModelX, maxModelY;
+      ossim_uint32 idxPts = 0;
+      ossim_uint32 nPoints = points.size();
+      minModelX = points[0].x();
+      maxModelX = minModelX;
+      minModelY = points[0].y();
+      maxModelY = minModelY;
+      ossimPlanetGrid::ModelPoint* optimizedOutPtr = &points.front();
+      ++optimizedOutPtr;
+      for(idxPts = 1; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+      {
+         if(optimizedOutPtr->x() < minModelX) minModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->x() > maxModelX) maxModelX = optimizedOutPtr->x();
+         if(optimizedOutPtr->y() < minModelY) minModelY = optimizedOutPtr->y();
+         if(optimizedOutPtr->y() > maxModelY) maxModelY = optimizedOutPtr->y();
+      }
+      ossim_int32 wholeMinY = (ossim_int32)std::floor(minModelY);
+      ossim_int32 wholeMinX = (ossim_int32)std::floor(minModelX);
+      ossim_int32 wholeMaxY = (ossim_int32)std::floor(maxModelY);
+      ossim_int32 wholeMaxX = (ossim_int32)std::floor(maxModelX);
+      
+      
+      ossim_int32 lat = wholeMaxY;
+      ossim_int32 lon = wholeMinX;
+      
+      
+      //    std::vector<ossimDpt> latLonOrigins;
+      std::vector<std::string> latLonOrigins;
+      
+      for(;lat >= wholeMinY; --lat)
+      {
+         lon = wholeMinX;
+         for(;lon <= wholeMaxX; ++lon)
+         {
+            ossimFilename filename = buildFilename(lat, lon);
+            if(filename != "")
+            {
+               latLonOrigins.push_back(filename);
+            }
+         }
+      }
+      
+      osg::Vec3d latLonPoint;
+      double minValue = 1.0/DBL_EPSILON -1;
+      double maxValue = -1.0/DBL_EPSILON +1;
+      if(latLonOrigins.size() == 0)
+      {
+         return 0;
+      }
+      ossim_uint32 idx  = 0;
+      ossim_uint32 numberOfFilesNeeded = latLonOrigins.size();
+      texture = new ossimPlanetImage(tileId);
+      ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                     OSSIM_FLOAT32,
+                                                                     1,
+                                                                     width+2*padding,
+                                                                     height+2*padding);
+      compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+      compositeData->initialize();
+      texture->setPadding(padding);
+      for(idx = 0; idx < numberOfFilesNeeded;++idx)
+      {
+         osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> srtmFile = getInfo(latLonOrigins[idx]);
+         
+         if(srtmFile.valid())
+         {
+            ossim_float64 nullHeight = srtmFile->theSrtmHandler->getNullHeightValue();
+            ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+            optimizedOutPtr = &points.front();      
+            for(idxPts = 0; idxPts < nPoints; ++idxPts,++optimizedOutPtr)
+            {
+               if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&
+                  (optimizedOutPtr->y() >= srtmFile->theMinLat)&&
+                  (optimizedOutPtr->y() <= srtmFile->theMaxLat)&&
+                  (optimizedOutPtr->x() >= srtmFile->theMinLon)&&
+                  (optimizedOutPtr->x() <= srtmFile->theMaxLon))
+               {
+                  double h = srtmFile->theSrtmHandler->getHeightAboveMSL(ossimGpt(optimizedOutPtr->y(),
+                                                                              optimizedOutPtr->x()));
+                  if(!ossim::isnan(h)&&
+                     (h!=nullHeight))
+                  {
+                     if(theGeoRefModel.valid())
+                     {
+                        h+=theGeoRefModel->getGeoidOffset(optimizedOutPtr->y(), optimizedOutPtr->x());
+                     }
+                     *bufPtr = h;
+                     if(h < minValue)
+                     {
+                        minValue = h;
+                     }
+                     if(h > maxValue)
+                     {
+                        maxValue = h;
+                     }
+                  }   
+                  else
+                  {
+                     *bufPtr = 0;
+                  }
+               }
+               ++bufPtr;
+            }
+         }
+      }
+      compositeData->validate();
+      if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+      {
+         texture->fromOssimImage(compositeData, false);
+         if(minValue < maxValue)
+         {
+            texture->setMinMax(minValue, maxValue);
+         }
+      }
+      else
+      {
+         texture = 0;
+      }
+   }
+#endif
+   return texture;
+   
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetSrtmElevationDatabase::getTexture(ossim_uint32 level,
+                                                                            ossim_uint64 row,
+                                                                            ossim_uint64 col,
+                                                                            const ossimPlanetGridUtility& utility)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+
+   if(!theOpenFlag)
+   {
+      return 0;
+   }
+
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+   ossim_uint32 width = utility.getTileWidth();
+   ossim_uint32 height = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, 
+                           col);
+
+   if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+   {
+      return 0;
+   }
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/height;
+ //  double deltaLon    = deltaX/width;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(!theExtents->intersectsScale(gsd.y-FLT_EPSILON,
+                                  gsd.y+FLT_EPSILON))//gsd.y <= theExtents.theMaxGsd)
+   {
+      return 0;
+   }
+
+   double minSubRectLat = ossim::max(theExtents->getMinLat(),
+                                     minLat);
+   double minSubRectLon = ossim::max(theExtents->getMinLon(),
+                                     minLon);
+   double maxSubRectLat = ossim::min(theExtents->getMaxLat(),
+                                     maxLat);
+   double maxSubRectLon = ossim::min(theExtents->getMaxLon(),
+                                     maxLon);
+   ossim_int32 wholeMinLat = (ossim_int32)std::floor(minSubRectLat);
+   ossim_int32 wholeMinLon = (ossim_int32)std::floor(minSubRectLon);
+   ossim_int32 wholeMaxLat = (ossim_int32)std::floor(maxSubRectLat);
+   ossim_int32 wholeMaxLon = (ossim_int32)std::floor(maxSubRectLon);
+   
+
+   ossim_int32 lat = wholeMaxLat;
+   ossim_int32 lon = wholeMinLon;
+
+//   ossim_uint32 addedFiles = 0;
+
+//    std::vector<ossimDpt> latLonOrigins;
+   std::vector<std::string> latLonOrigins;
+
+   for(;lat >= wholeMinLat; --lat)
+   {
+      lon = wholeMinLon;
+      for(;lon <= wholeMaxLon; ++lon)
+      {
+         ossimFilename filename = buildFilename(lat, lon);
+         if(filename != "")
+         {
+            latLonOrigins.push_back(filename);
+         }
+      }
+   }
+
+   if(latLonOrigins.size() == 0)
+   {
+      return 0;
+   }
+   
+   ossim_uint32 idx  = 0;
+   ossim_uint32 numberOfFilesNeeded = latLonOrigins.size();
+   texture = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                                           level,
+                                                           col,
+                                                           row));
+   ossimRefPtr<ossimImageData> compositeData = new ossimImageData(0,
+                                                                  OSSIM_FLOAT32,
+                                                                  1,
+                                                                  width,
+                                                                  height);
+   compositeData->setNullPix(OSSIMPLANET_NULL_HEIGHT, 0);
+   compositeData->initialize();
+   std::vector<ossimPlanetGridUtility::GridPoint> points;
+   utility.createGridPoints(points,
+                            level,
+                            row,
+                            col,
+                            height,
+                            width);
+
+   ossim_uint32 idxPts = 0;
+   ossim_uint32 nPoints = points.size();
+   osg::Vec3d latLonPoint;
+   double minValue = 1.0/DBL_EPSILON -1;
+   double maxValue = -1.0/DBL_EPSILON +1;
+
+   for(idx = 0; idx < numberOfFilesNeeded;++idx)
+   {
+
+      osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> srtmFile = getInfo(latLonOrigins[idx]);
+
+      if(srtmFile.valid())
+      {
+         ossim_float32* bufPtr = (ossim_float32*)compositeData->getBuf();
+         for(idxPts = 0; idxPts < nPoints; ++idxPts)
+         {
+            utility.getLatLon(latLonPoint, points[idxPts]);
+            if((*bufPtr == OSSIMPLANET_NULL_HEIGHT)&&
+               (latLonPoint[0] >= srtmFile->theMinLat)&&
+               (latLonPoint[0] <= srtmFile->theMaxLat)&&
+               (latLonPoint[1] >= srtmFile->theMinLon)&&
+               (latLonPoint[1] <= srtmFile->theMaxLon))
+            {
+               utility.getLatLon(latLonPoint, points[idxPts]);
+               double h = srtmFile->theSrtmHandler->getHeightAboveMSL(ossimGpt(latLonPoint[0],
+                                                                               latLonPoint[1]));
+               if(!ossim::isnan(h))
+               {
+                  *bufPtr = h;
+                  if(*bufPtr < minValue)
+                  {
+                     minValue = *bufPtr;
+                  }
+                  if(*bufPtr > maxValue)
+                  {
+                     maxValue = *bufPtr;
+                  }
+               }   
+            }
+            ++bufPtr;
+         }
+      }
+   }
+   compositeData->validate();
+
+   
+   if(compositeData->getDataObjectStatus() != OSSIM_EMPTY)
+   {
+      texture->fromOssimImage(compositeData, false);
+
+      if(minValue < maxValue)
+      {
+         texture->setMinMax(minValue, maxValue);
+      }
+   }
+   else
+   {
+      texture = 0;
+   }
+   
+   return texture;
+}
+
+osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> ossimPlanetSrtmElevationDatabase::getInfo(const std::string& srtmName)
+{
+   SrtmFilePointerList::iterator iter = theFilePointers.find(srtmName);
+
+   if(iter != theFilePointers.end())
+   {
+      iter->second->theTimeStamp = osg::Timer::instance()->tick();
+
+      return iter->second;
+   }
+   osg::ref_ptr<SrtmInfo> info     = new SrtmInfo;
+   
+   ossimFilename srtmFile = ossimFilename(theLocation).dirCat(ossimFilename(srtmName));
+   ossimSrtmSupportData supportData;
+   if(supportData.setFilename(srtmFile))
+   {
+      info->theMinLat = std::floor(supportData.getSouthwestLatitude());
+      info->theMinLon = std::floor(supportData.getSouthwestLongitude());
+      info->theMaxLat = info->theMinLat + 1.0;
+      info->theMaxLon = info->theMinLon + 1.0;
+   }
+   else
+   {
+      return 0;
+   }
+   
+   info->theTimeStamp  = osg::Timer::instance()->tick();
+   info->theFilename   = srtmFile.string();
+   info->theSrtmHandler = new ossimSrtmHandler();
+   info->theSrtmHandler->open(srtmFile);
+   theFilePointers.insert(std::make_pair(srtmName, info));
+   shrinkFilePointers();
+
+   return info;
+}
+
+void ossimPlanetSrtmElevationDatabase::shrinkFilePointers()
+{
+   if(theFilePointers.size() <= theMaxOpenFiles) return;
+
+   const osg::Timer* timer = osg::Timer::instance();
+   
+   osg::Timer_t currentTime = timer->tick();
+
+   while((theFilePointers.size()>0) &&
+         (theFilePointers.size() > theMinOpenFiles))
+   {
+      SrtmFilePointerList::iterator iter = theFilePointers.begin();
+      SrtmFilePointerList::iterator currentLargestTimeDelta = iter;
+      double delta = 0.0;
+      while(iter!=theFilePointers.end())
+      {
+         double testDelta = timer->delta_m(currentLargestTimeDelta->second->theTimeStamp, currentTime);
+         if(testDelta > delta)
+         {
+            currentLargestTimeDelta = iter;
+            delta = testDelta;
+         }
+         ++iter;
+      }
+
+      if(currentLargestTimeDelta != theFilePointers.end())
+      {
+         theFilePointers.erase(currentLargestTimeDelta);
+      }
+   }
+}
+
+ossimFilename ossimPlanetSrtmElevationDatabase::buildFilename(double lat, double lon)const
+{
+   ossimFilename srtmFileBasename;
+
+   int ilat =  static_cast<int>(floor(lat));
+   if (ilat < 0)
+   {
+      srtmFileBasename = "S";
+   }
+   else
+   {
+      srtmFileBasename = "N";
+   }
+
+   ilat = abs(ilat);
+   std::ostringstream  os1;
+   
+   os1 << std::setfill('0') << std::setw(2) <<ilat;
+   
+   srtmFileBasename += os1.str().c_str();
+
+   int ilon = static_cast<int>(floor(lon));
+   
+   if (ilon < 0)
+   {
+      srtmFileBasename += "W";
+   }
+   else
+   {
+      srtmFileBasename += "E";
+   }
+
+   ilon = abs(ilon);
+   std::ostringstream  os2;
+   os2 << std::setfill('0') << std::setw(3) << ilon;
+   
+   srtmFileBasename += os2.str().c_str();
+   srtmFileBasename.setExtension(".hgt");
+
+   ossimFilename loc(theLocation);
+   if(!loc.dirCat(srtmFileBasename).exists())
+   {
+      srtmFileBasename.setExtension(".HGT");
+      if(!loc.dirCat(srtmFileBasename).exists())
+      {
+         srtmFileBasename = srtmFileBasename.downcase();
+         
+         if(!loc.dirCat(srtmFileBasename).exists())
+         {
+            srtmFileBasename = "";
+         }
+      }
+   }
+
+   return srtmFileBasename;
+}
+
+osg::ref_ptr<ossimPlanetSrtmElevationDatabase::SrtmInfo> ossimPlanetSrtmElevationDatabase::findSrtmInfo(const std::string& srtmName)
+{
+   SrtmFilePointerList::iterator iter = theFilePointers.find(srtmName);
+
+   if(iter != theFilePointers.end())
+   {
+      iter->second->theTimeStamp = osg::Timer::instance()->tick();
+      return iter->second;
+   }
+
+   return 0;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetStandardTextureLayerFactory.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetStandardTextureLayerFactory.cpp
new file mode 100644
index 0000000..5b1450b
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetStandardTextureLayerFactory.cpp
@@ -0,0 +1,207 @@
+#include <ossimPlanet/ossimPlanetStandardTextureLayerFactory.h>
+#include <ossimPlanet/ossimPlanetOssimImageLayer.h>
+#include <ossimPlanet/ossimPlanetWmsImageLayer.h>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <OpenThreads/ScopedLock>
+#include <ossim/base/ossimKeywordNames.h>
+#include <sstream>
+#include <wms/wmsUrl.h>
+
+ossimPlanetStandardTextureLayerFactory* ossimPlanetStandardTextureLayerFactory::theInstance=0;
+
+ossimPlanetStandardTextureLayerFactory::ossimPlanetStandardTextureLayerFactory()
+{
+   theInstance = this;
+}
+
+ossimPlanetStandardTextureLayerFactory* ossimPlanetStandardTextureLayerFactory::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetStandardTextureLayerFactory;
+   }
+
+   return theInstance;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetStandardTextureLayerFactory::createLayer(const ossimString& name, bool openAllEntriesFlag)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   osg::ref_ptr<ossimPlanetTextureLayer> result;
+
+   ossimFilename filename = name;
+   
+   if(filename.exists())
+   {
+      return createLayerFromFilename(filename, openAllEntriesFlag);
+   }
+   ossimKeywordlist kwl;
+   std::istringstream in(name);
+
+   if(kwl.parseStream(in))
+   {
+      return createLayerFromKwl(kwl);
+   }
+   if((name == "ossimPlaneTextureLayerGroup")||
+      (name == "group"))
+   {
+      return new ossimPlanetTextureLayerGroup;
+   }
+#ifndef OSGPLANET_WITHOUT_WMS
+   else if((name == "ossimPlanetWmsImageLayer")||
+           (name == "wms"))
+   {
+      return new ossimPlanetWmsImageLayer;
+   }
+#endif  
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetStandardTextureLayerFactory::createLayerFromFilename(const ossimFilename& name, bool openAllEntriesFlag)const
+{
+   osg::ref_ptr<ossimPlanetOssimImageLayer> imageLayer = new ossimPlanetOssimImageLayer;
+   imageLayer->openImage(name);
+   if(!imageLayer->isStateSet(ossimPlanetTextureLayer_NO_SOURCE_DATA))
+   {
+      if(openAllEntriesFlag&&imageLayer->isMultiEntry())
+			
+      {
+			return imageLayer->groupAllEntries().get();			
+		}
+      else
+      {
+         return imageLayer.get();
+      }
+   }
+	
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetStandardTextureLayerFactory::createLayerFromKwl(const ossimKeywordlist& kwl,
+                                                                                                 const ossimString& prefix)const
+{
+   if(kwl.find(prefix, "archive0.type"))
+   {
+      return createLayerFromOldKwl(kwl, prefix);
+   }
+
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetStandardTextureLayerFactory::createLayerFromOldKwl(const ossimKeywordlist& kwl,
+                                                                                                    const ossimString& prefix)const
+{
+   osg::ref_ptr<ossimPlanetTextureLayerGroup> groupLayer = new ossimPlanetTextureLayerGroup;
+   
+   ossimString archiveKey;
+   ossimString archive = kwl.find(prefix, "archiv0.type");
+   unsigned int idx = 0;
+   bool done = false;
+   while(!done)
+   {
+      stringstream s;
+      s << "archive" << idx << ".";
+      archiveKey = s.str();
+
+      // we will need to move all this to an archive factory
+      // later.  For now we will hard code a local and remote archive
+      // creations here.
+      //
+      ossimString archiveType = kwl.find(prefix+archiveKey, "type");
+      if(archiveType == "local")
+      {
+         ossimString localPrefix = archiveKey;
+         osg::ref_ptr<ossimPlanetTextureLayerGroup> groupLocal = new ossimPlanetTextureLayerGroup;
+         int idx = 0;
+         ossimFilename file;
+         bool doneLocal = false;
+         while(!doneLocal)
+         {
+            std::stringstream out;
+            out << "file" << idx;
+            
+            file = kwl.find(localPrefix, out.str().c_str());
+            if((file!="")&&(file.exists()))
+            {
+               osg::ref_ptr<ossimPlanetOssimImageLayer> layer = new ossimPlanetOssimImageLayer;
+               layer->openImage(file);
+               if(!layer->isStateSet(ossimPlanetTextureLayer_NO_SOURCE_DATA)&&
+                  !layer->isStateSet(ossimPlanetTextureLayer_NO_GEOM))
+               {
+                  groupLocal->addBottom(layer.get());
+               }
+            }
+            else
+            {
+               doneLocal = true;
+            }
+            ++idx;
+         }
+         if(groupLocal->numberOfLayers() > 0)
+         {
+            groupLayer->addBottom(groupLocal.get());
+         }
+//          ossimPlanetTextureArchive* archive = new ossimPlanetOssimArchive;
+//          archive->loadState(kwl,
+//                             prefix+archiveKey);
+//          addArchive(archive);
+      }
+      else if(archiveType == "wms")
+      {
+#ifndef OSGPLANET_WITHOUT_WMS
+         osg::ref_ptr<ossimPlanetWmsImageLayer> layer = new ossimPlanetWmsImageLayer;
+
+         ossimString server = kwl.find(prefix+archiveKey, "server");
+         ossimString cache  = kwl.find(prefix+archiveKey, "cache_dir");
+
+         if(!server.empty())
+         {
+            layer->setServer(server);
+            if(!cache.empty())
+            {
+               layer->setCacheDirectory(cache);
+            }
+            groupLayer->addBottom(layer.get());
+            
+         }
+         
+//          ossimPlanetTextureArchive* archive = new ossimPlanetWmsArchive;
+
+//          archive->loadState(kwl,
+//                             prefix+archiveKey);
+//          addArchive(archive);
+#endif
+      }
+      else if(archiveType == "background_wms")
+      {
+#ifndef OSGPLANET_WITHOUT_WMS
+//          ossimPlanetTextureArchive* background = new ossimPlanetWmsArchive;
+//          background->addCallback(theArchiveCallback.get());
+//          background->loadState(kwl,
+//                                prefix+archiveKey);
+//          setBackgroundArchive(background);
+#endif
+      }
+      else if(archiveType == "background_local")
+      {
+//          ossimPlanetTextureArchive* background = new ossimPlanetOssimArchive;
+//          background->addCallback(theArchiveCallback.get());
+//          background->loadState(kwl,
+//                                prefix+archiveKey);
+//          setBackgroundArchive(background);
+      }
+      else
+      {
+         done = true;
+      }
+      
+      ++idx;
+   }
+
+   if(groupLayer->numberOfLayers() < 1)
+   {
+      groupLayer = 0;
+   }
+   
+   return groupLayer.get();
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTerrain.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrain.cpp
new file mode 100644
index 0000000..f3ae176
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrain.cpp
@@ -0,0 +1,1716 @@
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <OpenThreads/ScopedLock>
+#include <osg/NodeVisitor>
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossim/elevation/ossimElevSourceFactory.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <ossimPlanet/ossimPlanetTerrainGeometryTechnique.h>
+#include <ossimPlanet/ossimPlanetGeoRefModel.h>
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossimPlanet/ossimPlanetElevationRegistry.h>
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetOssimElevationDatabase.h>
+#include <osg/io_utils>
+#include <osg/GraphicsContext>
+#include <osgGA/EventVisitor>
+#include <osgUtil/IntersectionVisitor>
+#include <osgUtil/IntersectVisitor>
+#include <osgUtil/IncrementalCompileOperation>
+#include <stack>
+#include <set>
+
+struct ossimPlanetDatabasePagerCompileCompletedCallback : public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
+{
+    ossimPlanetDatabasePagerCompileCompletedCallback(ossimPlanetTerrain* terrain, ossimPlanetTileRequest* request)
+    :m_terrain(terrain), m_request(request){}
+
+   virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* /* compileSet */)
+    {
+      //std::cout << "COMPILE COMPLETED\n";
+      m_terrain->addRequestToReadyToApplyQueue(m_request.get());
+      return true;
+    }
+
+    osg::ref_ptr<ossimPlanetTerrain> m_terrain;
+    osg::ref_ptr<ossimPlanetTileRequest> m_request;
+};
+
+class ossimPlanetTerrain::TextureCallback : public ossimPlanetTextureLayerCallback
+{
+public:
+   TextureCallback(ossimPlanetTerrain* terrain)
+   :theTerrain(terrain)
+   {
+   }
+   
+   void setTerrain(ossimPlanetTerrain* value)
+   {
+      theTerrain = value;
+   }
+   virtual void refreshExtent(osg::ref_ptr<ossimPlanetExtents> extent)
+   {
+      if(theTerrain)
+      {
+         theTerrain->refreshImageLayers(extent.get());
+      }
+   }
+   virtual void layerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+   {
+      if(theTerrain)
+      {
+         refreshExtent(layer->getExtents().get());
+      }
+   }
+   virtual void layerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                             osg::ref_ptr<ossimPlanetTextureLayer> parent)
+   {
+      if(theTerrain)
+      {
+         // only refresh if it was originally enabled
+         if(layer->getEnableFlag())
+         {
+            osg::ref_ptr<ossimPlanetExtents> extents = new ossimPlanetExtents(*layer->getExtents());
+            if(parent.valid())
+            {
+               osg::ref_ptr<ossimPlanetExtents> parentExtents = parent->getExtents();
+               if(parentExtents.valid())
+               {
+                  extents->combineScale(parentExtents->getMinScale(),
+                                        parentExtents->getMaxScale());
+               }
+            }
+            refreshExtent(extents.get());
+         }
+      }         
+   }
+   virtual void propertyChanged(const ossimString& name,
+                                const ossimPlanetTextureLayer* object)
+   {
+      if(object&&name.contains("enable"))
+      {
+         if(object->getExtents().valid())
+         {
+            osg::ref_ptr<ossimPlanetExtents> extents = new ossimPlanetExtents(*object->getExtents());
+            const ossimPlanetTextureLayerGroup* parent = object->getParent(0);
+            if(parent)
+            {
+               osg::ref_ptr<ossimPlanetExtents> parentExtents = parent->getExtents();
+               if(parentExtents.valid())
+               {
+                  extents->combineScale(parentExtents->getMinScale(),
+                                        parentExtents->getMaxScale());
+               }
+            }
+            
+            refreshExtent(extents);
+         }
+      }
+   }
+   
+protected:
+   ossimPlanetTerrain* theTerrain;
+};
+
+
+class CountVisitor : public osg::NodeVisitor
+{
+public:
+   CountVisitor()
+   :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+   {
+      theCullCount = 0;
+      theNodeCount = 0;
+   }
+   virtual void apply(osg::Node& node)
+   {
+#if 0
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+      if(tile)
+      {
+         if(tile->culledFlag())
+         {
+            ++theCullCount;
+         }
+         ++theNodeCount;
+      }
+#else
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+      if(tile&&tile->culledFlag())
+      {
+         std::stack<ossimPlanetTerrainTile*> tileStack;
+         tileStack.push(tile);
+         ossimPlanetTerrainTile* current;
+         ossim_uint32 idx = 0;
+         while(!tileStack.empty()) 
+         {
+            current = tileStack.top();
+            tileStack.pop();
+            for(idx = 0; idx < current->getNumChildren();++idx)
+            {
+               ossimPlanetTerrainTile* t = (ossimPlanetTerrainTile*)current->getChild(idx);
+               if(t)
+               {
+                  tileStack.push(t);
+                  ++ theCullCount;
+                  ++theNodeCount;
+               }
+            }
+         }
+         ++theNodeCount;
+         ++theCullCount;
+         return;
+      }
+      if(tile)
+      {
+         ++theNodeCount;
+      }
+#endif
+      traverse(node);
+   }
+   ossim_uint32  theCullCount;
+   ossim_uint32  theNodeCount;
+};
+
+class GatherChildrenVisitor : public osg::NodeVisitor
+{
+public:
+   GatherChildrenVisitor()
+   :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+   {
+   }
+   typedef  std::stack<osg::ref_ptr<ossimPlanetTerrainTile> > TileStack;
+   virtual void apply(osg::Node& node)
+   {
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+      if(tile)
+      {
+         theGatheredChildren.push(tile);
+      }
+      traverse(node);
+   }
+   TileStack& gatheredChildren()
+   {
+      return theGatheredChildren;
+   }
+protected:
+   TileStack theGatheredChildren;
+};
+
+class RemoveChildrenFromGraphVisitor : public osg::NodeVisitor
+{
+public:
+   RemoveChildrenFromGraphVisitor(ossimPlanetTerrain* terrain, ossim_int64 frameNumber, ossim_int64 delta=2)
+   :osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+   theTerrain(terrain),
+   theFrameNumber(frameNumber),
+   theCullDelta(delta)
+   {
+   }
+   virtual void apply(osg::Node& node)
+   {
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+      if(tile)
+      {
+         if(ossim::abs((tile->frameNumber()-theFrameNumber)) > theCullDelta)
+         {
+            theTerrain->removeTerrainTileFromGraph(tile);
+            return;
+         }
+      }
+      traverse(node);
+   }
+   void setFrameNumber(ossim_int64 num)
+   {
+      theFrameNumber = num;
+   }
+   
+protected:
+   ossimPlanetTerrain* theTerrain;
+   ossim_int64 theFrameNumber;
+   ossim_int64 theCullDelta;
+};
+
+void ossimPlanetTerrain::UpdateTileCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+   traverse(node,nv);
+   update(dynamic_cast<ossimPlanetTerrainTile*>(node), nv);
+}
+
+void ossimPlanetTerrain::UpdateTileCallback::update(ossimPlanetTerrainTile* /* tile */,
+                                                    osg::NodeVisitor* /* nv */)
+{
+}
+
+void ossimPlanetTerrain::CullTileCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+   traverse(node,nv);
+}
+
+void ossimPlanetTerrain::CullTileCallback::cull(ossimPlanetTerrainTile* /* tile */,
+                                                osg::NodeVisitor* /* nv */)
+{
+}
+
+ossimPlanetTerrain::ossimPlanetTerrain()
+:theResetRootsFlag(true),
+theLastFrameNumber(-1),
+theTextureTileWidth(256),
+theTextureTileHeight(256),
+theElevationTileWidth(9),//2^n + 1
+theElevationTileHeight(9), //2^n + 1
+theSplitMergeLodScale(3.0),
+theElevationExaggeration(1.0),
+theMinimumTimeToCompilePerFrame(.003),// 3 milliseconds
+thePrecompileEnabledFlag(true),
+theElevationEnabledFlag(true),
+theFalseEyeFlag(false),
+theFalseEye(0.0,0.0,0.0),
+thePriorityPointFlag(false),
+thePriorityPoint(0.0,0.0,0.0)
+{
+   theElevationCacheShrinkOperation = new ossimPlanetImageCacheShrinkOperation;
+   theCacheShrinkThreadQueue = new ossimPlanetOperationThreadQueue;
+   theElevationLayer = new ossimPlanetElevationDatabaseGroup;
+   theElevationLayer->setFillNullWithGeoidOffsetFlag(true);
+   theElevationLayer->setGeoRefModel(theModel.get());
+   theLastApplyToGraphFrameNumber = -1;
+   theMaxNumberOfOperationsToApplyToGraphPerFrame = 5;
+   theTextureCallback = new ossimPlanetTerrain::TextureCallback(this);
+   theTerrainTechnique = new ossimPlanetTerrainGeometryTechnique();
+   theElevationQueue   = new ossimPlanetTileRequestThreadQueue;
+   theTextureQueue     = new ossimPlanetTileRequestThreadQueue;
+   theTextureLayers.push_back(new ossimPlanetTextureLayerGroup());
+   theTextureLayers[0]->addCallback(theTextureCallback.get());
+   theSplitQueue = new ossimPlanetTileRequestThreadQueue();
+   theMergeQueue = new ossimPlanetTileRequestQueue();
+   theMaxTimeToSplit = 0.0;
+   theMaxTimeToMerge = 2.5;
+   setGrid(new ossimPlanetAdjustableCubeGrid());
+   theSplitMergeMetricType = DISTANCE_METRIC;
+   theSplitPixelMetric = 8;
+   theMergePixelMetric = 4;
+   setCullAmountType(HIGH_CULL);
+}
+
+ossimPlanetTerrain::ossimPlanetTerrain(ossimPlanetGrid* grid)
+:theResetRootsFlag(true),
+theGrid(grid),
+theLastFrameNumber(-1),
+theTextureTileWidth(256),
+theTextureTileHeight(256),
+theElevationTileWidth(9),//2^n + 1
+theElevationTileHeight(9), //2^n + 1
+theSplitMergeLodScale(3.0),
+theElevationExaggeration(1.0),
+theMinimumTimeToCompilePerFrame(.003),// 3 milliseconds
+thePrecompileEnabledFlag(true),
+theElevationEnabledFlag(true),
+theFalseEyeFlag(false),
+theFalseEye(0.0,0.0,0.0),
+thePriorityPointFlag(false),
+thePriorityPoint(0.0,0.0,0.0)
+{
+   theElevationCacheShrinkOperation = new ossimPlanetImageCacheShrinkOperation;
+   theCacheShrinkThreadQueue = new ossimPlanetOperationThreadQueue;
+   theElevationLayer = new ossimPlanetElevationDatabaseGroup;
+   theElevationLayer->setFillNullWithGeoidOffsetFlag(true);
+   theElevationLayer->setGeoRefModel(theModel.get());
+   theLastApplyToGraphFrameNumber = -1;
+   theMaxNumberOfOperationsToApplyToGraphPerFrame= 5;
+   theTextureCallback = new ossimPlanetTerrain::TextureCallback(this);
+   theTerrainTechnique = new ossimPlanetTerrainGeometryTechnique();
+   theTextureLayers.push_back(new ossimPlanetTextureLayerGroup());
+   theTextureLayers[0]->addCallback(theTextureCallback.get());
+   theElevationQueue  = new ossimPlanetTileRequestThreadQueue;
+   theTextureQueue    = new ossimPlanetTileRequestThreadQueue;
+   
+   // make these support priority queues
+   //
+   theSplitQueue = new ossimPlanetTileRequestThreadQueue();
+   theMergeQueue = new ossimPlanetTileRequestQueue();
+   theMaxTimeToSplit = 0.0;
+   theMaxTimeToMerge = 2.5;
+   theSplitMergeMetricType = DISTANCE_METRIC;
+   theSplitPixelMetric = 8;
+   theMergePixelMetric = 4;
+   setCullAmountType(HIGH_CULL);
+}
+
+ossimPlanetTerrain::~ossimPlanetTerrain()
+{
+   theTextureLayers[0]->removeCallback(theTextureCallback.get());
+   
+   if(theElevationQueue.valid())
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockElevationQueue(theElevationQueueMutex);
+      theElevationQueue->removeAllOperations();
+      theElevationQueue->cancel();
+      theElevationQueue = 0;
+   }
+   if(theTextureQueue.valid())
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockTextureQueue(theTextureQueueMutex);
+      theTextureQueue->removeAllOperations();
+      theTextureQueue->cancel();
+      theTextureQueue = 0;
+   }
+   if(theSplitQueue.valid())
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockSplitQueue(theSplitQueueMutex);
+      theSplitQueue->removeAllOperations();
+      theSplitQueue->cancel();
+      theSplitQueue = 0;
+   }
+   if(theMergeQueue.valid())
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lockMergeQueue(theMergeQueueMutex);
+      theMergeQueue->removeAllOperations();
+      theMergeQueue = 0;
+   }
+
+   theNeedToCompileQueue.clear();
+   theReadyToApplyToGraphQueue.clear();
+   theReadyToApplyToGraphNewNodesQueue.clear();
+   
+   {
+      osg::Group::removeChildren(0, getNumChildren());
+      //OpenThreads::ScopedLock<OpenThreads::Mutex> lockTileSet(theTileSetMutex);
+      theTileSet.clear();
+   }
+   if(theElevationCache.valid())
+   {
+      theElevationCache->clean();
+      theElevationCache = 0;
+   }
+}
+
+void ossimPlanetTerrain::setTerrainTechnique(ossimPlanetTerrainTechnique* technique)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theResetRootsFlag = true;
+   theTerrainTechnique = technique;
+}
+
+ossimPlanetTerrainTechnique* ossimPlanetTerrain::newTechnique()
+{
+   ossimPlanetTerrainTechnique* result = 0;
+   
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->setGrid(theGrid.get());
+      if(thePlanet)
+      {
+         theTerrainTechnique->setModel(thePlanet->model().get());
+      }
+      result = (ossimPlanetTerrainTechnique*)theTerrainTechnique->clone(osg::CopyOp::SHALLOW_COPY);
+   }
+   
+   return result;
+}
+
+void ossimPlanetTerrain::setElevationEnabledFlag(bool flag)
+{
+   bool refresh = elevationEnabledFlag()!=flag;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theElevationEnabledFlag = flag;
+   }
+   if(refresh)
+   {
+      elevationLayer()->setEnableFlag(theElevationEnabledFlag);
+      theElevationCache->setEnabledFlag(flag);
+   }
+}
+
+bool ossimPlanetTerrain::elevationEnabledFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theElevationEnabledFlag;
+}
+
+void ossimPlanetTerrain::setDatabasePager(osgDB::DatabasePager* pager)
+{
+   thePager = pager;
+}
+
+void ossimPlanetTerrain::initElevation()
+{
+#if 1
+   ossim_uint32 numberOfDatabases = ossimElevManager::instance()->getNumberOfElevationDatabases();
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < numberOfDatabases; ++idx)
+   {
+      ossimRefPtr<ossimElevationDatabase> database = ossimElevManager::instance()->getElevationDatabase(idx);
+      if(database.valid())
+      {
+         ossimPlanetOssimElevationDatabase* planetDatabase = new ossimPlanetOssimElevationDatabase;
+         planetDatabase->setDatabase(database.get());
+         addElevation(planetDatabase);
+      }
+   }
+#else
+   ossim_uint32 idx = 0;
+   ossim_uint32 numberOfDatabases = ossimElevManager::instance()->getNumberOfElevationDatabases();
+   for(idx = 0; idx < numberOfDatabases; ++idx)
+   {
+      const ossimRefPtr<ossimElevationDatabase> database = ossimElevManager::instance()->getElevationDatabase(idx);
+      
+      if(database.valid())
+      {
+         ossimFilename directory = ossimFilename(database->getConnectionString());
+         addElevation(directory, false);
+      }
+   }
+   
+   if(theElevationLayer.valid())
+   {
+      theElevationLayer->sortByGsd();
+   }
+#endif
+}
+
+bool ossimPlanetTerrain::addElevation(const ossimFilename& file, bool sortFlag)
+{
+   osg::ref_ptr<ossimPlanetElevationDatabase> database = ossimPlanetElevationRegistry::instance()->openDatabase(file);
+   return addElevation(database.get(), sortFlag);
+}
+
+bool ossimPlanetTerrain::addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag)
+{
+   bool result = false;
+   if(database.valid()&&theElevationLayer.valid())
+   {
+      database->setGeoRefModel(theModel.get());
+      theElevationLayer->addBottom(database.get());
+      result = true;
+      if(sortFlag)
+      {
+         // make sure the highest accuracy is on top
+         theElevationLayer->sortByGsd();
+      }   
+   }
+   return result;
+}
+
+void ossimPlanetTerrain::setNumberOfTextureLayers(ossim_uint32 size)
+{
+   TextureLayers temp = theTextureLayers;
+   theTextureLayers.resize(size);
+   ossim_uint32 idx = 0;
+   ossim_uint32 minBound = ossim::min(size, (ossim_uint32)temp.size());
+   for(idx = 0; idx < minBound;++idx)
+   {
+      theTextureLayers[idx] = temp[idx];
+   }
+   resetImageLayers();
+}
+
+bool ossimPlanetTerrain::setTextureLayer(ossim_uint32 idx, 
+                                         ossimPlanetTextureLayer* layer)
+{
+   bool result = true;
+   if(idx < theTextureLayers.size())
+   {
+      if(theTextureLayers[idx].valid())
+      {
+         theTextureLayers[idx]->removeCallback(theTextureCallback.get());
+      }
+      theTextureLayers[idx] = layer;
+      if(layer)
+      {
+         layer->addCallback(theTextureCallback.get());
+      }
+      refreshImageLayers();
+   }
+   else if(idx == theTextureLayers.size())
+   {
+      theTextureLayers.push_back(layer);
+      if(layer)
+      {
+         layer->addCallback(theTextureCallback.get());
+      }
+      refreshImageLayers();
+   }
+   else 
+   {
+      result = false;
+   }
+   
+   return result;
+}
+
+ossim_uint32 ossimPlanetTerrain::numberOfTextureLayers()const
+{
+   return theTextureLayers.size();
+}
+
+ossimPlanetTextureLayer* ossimPlanetTerrain::textureLayer(ossim_uint32 idx)
+{
+   if(idx < theTextureLayers.size())
+   {
+      return theTextureLayers[idx].get(); 
+   }
+   
+   return 0;
+}
+
+ossimPlanetElevationDatabaseGroup* ossimPlanetTerrain::elevationLayer()
+{
+   return theElevationLayer.get();
+}
+
+const ossimPlanetElevationDatabaseGroup* ossimPlanetTerrain::elevationLayer()const
+{
+   return theElevationLayer.get();
+}
+
+void ossimPlanetTerrain::traverse(osg::NodeVisitor &nv)
+{
+   // first mark any tile for refresh
+   
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      if(theElevationCache.valid()&&theElevationCache->exceedsMaxCacheSize())
+      {
+         if(theElevationCacheShrinkOperation->referenceCount() == 1)
+         {
+            theElevationCacheShrinkOperation->reset();
+            theElevationCacheShrinkOperation->setCache(theElevationCache.get());
+            theCacheShrinkThreadQueue->add(theElevationCacheShrinkOperation.get());
+         }
+      }
+   }
+//   osgUtil::IntersectionVisitor* iv = dynamic_cast<osgUtil::IntersectionVisitor*>(&nv);
+//   if(iv)
+//   {
+//      iv->setUseKdTreeWhenAvailable(true);
+//   }
+//   osg::Timer_t tick = osg::Timer::instance()->tick();
+   int savedCullSettings = 0;
+   // int savedCullMask = 0;
+   osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+   if(cv)
+   {
+      // savedCullMask = cv->getCurrentCullingSet().getCullingMask();
+      savedCullSettings = cv->getCullingMode();
+      cv->getCurrentCullingSet().setCullingMask((osg::CullingSet::MaskValues)theCullSettings);
+      cv->setCullingMode(theCullSettings);
+   }
+   // bool frameNumberChanged = false;
+   
+   if(nv.getFrameStamp())
+   {
+      // frameNumberChanged = nv.getFrameStamp()->getFrameNumber() != theLastFrameNumber;
+      theLastFrameNumber = nv.getFrameStamp()->getFrameNumber();
+   }
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::EVENT_VISITOR:
+      {
+         return;
+      }
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         refreshExtents();
+         theTextureQueue->setCurrentFrameNumber(theLastFrameNumber);
+         theElevationQueue->setCurrentFrameNumber(theLastFrameNumber);
+         theSplitQueue->setCurrentFrameNumber(theLastFrameNumber);
+         theMergeQueue->setCurrentFrameNumber(theLastFrameNumber);
+         theTextureQueue->operationQueue()->removeStoppedOperations();
+         theElevationQueue->operationQueue()->removeStoppedOperations();
+         
+        // osg::Timer_t startTick = osg::Timer::instance()->tick();
+        // double delta =0.0;
+         if(resetRootsFlag())
+         {
+            buildRoot();
+         }
+         
+         bool needToRedraw =  (!theTextureQueue->empty()||
+                               !theElevationQueue->empty()||
+                               !theSplitQueue->empty());
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToApplyToGraphQueueMutex);
+            if(!theReadyToApplyToGraphQueue.empty()||
+               !theReadyToApplyToGraphNewNodesQueue.empty())
+            {
+               needToRedraw = true;
+            }
+         }
+         {
+            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNeedToCompileQueueMutex);
+            if(!theNeedToCompileQueue.empty())
+            {
+               needToRedraw = true;
+            }
+         }
+         if(needToRedraw)
+         {
+            setRedrawFlag(true); // request a new frame if not empty
+         }
+         pruneNeedToCompileAndAddToGraphThreadQueues();
+         removeTerrainChildren();
+         if(nv.getFrameStamp()&&(nv.getFrameStamp()->getFrameNumber()!=theLastApplyToGraphFrameNumber))
+         {
+            applyRequestsToGraph(1.25);
+            theLastApplyToGraphFrameNumber = nv.getFrameStamp()->getFrameNumber();
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+#if 0
+   ossim_uint32 idx = 0;
+   CountVisitor count;
+   for(idx = 0; idx < getNumChildren(); ++idx)
+   {
+      getChild(idx)->accept(count);
+   }
+   std::cout << "CULL COUNT ===== " << coun   std::cout << "NODE COUNT ===== " << count.theNodeCount << std::endl;
+t.theCullCount << std::endl;
+#endif
+   ossimPlanetLayer::traverse(nv);
+   if(cv)
+   {
+      cv->getCurrentCullingSet().setCullingMask((osg::CullingSet::MaskValues) savedCullSettings);
+      cv->setCullingMode( (osg::CullSettings::CullingModeValues) savedCullSettings);
+   }
+   //std::cout << "f = " << theCurrentFrameNumber << std::endl;
+   if((nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR))
+   {
+      
+      RemoveChildrenFromGraphVisitor visitor(this, nv.getFrameStamp()->getFrameNumber());
+      ossim_uint32 idx = 0;
+      ossim_uint32 maxIdx = getNumChildren();
+      for(idx = 0; idx < maxIdx; ++idx)
+      {
+         getChild(idx)->accept(visitor);
+      }
+   }
+}
+
+void ossimPlanetTerrain::setGrid(ossimPlanetGrid* grid)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   
+   theResetRootsFlag = true;
+   theGrid = grid;
+}
+
+const ossimPlanetGrid* ossimPlanetTerrain::grid()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theGrid.get();
+}
+
+ossimPlanetGrid* ossimPlanetTerrain::grid()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theGrid.get();
+}
+
+void ossimPlanetTerrain::removeTerrainTileFromGraph(ossimPlanetTerrainTile* tile)
+{
+   removeTerrainChildren(tile);
+}
+
+void ossimPlanetTerrain::removeTerrainChildren(ossimPlanetTerrainTile* tile)
+{
+   if(tile)
+   {
+      theChildrenToRemoveMutex.lock();
+      osg::ref_ptr<ossimPlanetTerrainTile> currentTile = tile;
+      // flatten graph to a single list of children
+      //
+      std::queue<osg::ref_ptr<ossimPlanetTerrainTile> > tiles;
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < currentTile->getNumChildren(); ++idx)
+      {
+         tiles.push((ossimPlanetTerrainTile*)currentTile->getChild(idx));
+      }
+      currentTile->removeChildren(0, currentTile->getNumChildren());
+      // now let's flatten the graph out and add to the remove tile list
+      //
+      while(!tiles.empty())
+      {
+         currentTile = tiles.front().get();
+         currentTile->cancelAllOperations();
+         tiles.pop();
+         //currentTile->setState(ossimPlanetTerrainTile::NEED_MERGING);
+         theChildrenToRemove.push_back(currentTile.get());
+         for(idx = 0; idx < currentTile->getNumChildren(); ++idx)
+         {
+            tiles.push((ossimPlanetTerrainTile*)currentTile->getChild(idx));
+         }
+         currentTile->removeChildren(0, currentTile->getNumChildren());
+      }
+      theChildrenToRemoveMutex.unlock();
+   }
+}
+
+void ossimPlanetTerrain::requestSplit(ossimPlanetTerrainTile* tile,
+                                      ossim_float64 priority,
+                                      const osg::FrameStamp* framestamp,
+                                      ossimPlanetOperation* request)
+{
+   if(theResetRootsFlag) return;
+   ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>(request);
+   if(tileRequest)
+   {
+      if(tileRequest->referenceCount() == 1)
+      {
+         tileRequest->setState(ossimPlanetOperation::READY_STATE);
+         tileRequest->setTimestampFirstRequest(framestamp->getReferenceTime());
+         tileRequest->setTile(tile);
+         theSplitQueue->add(tileRequest);
+      }
+      tileRequest->setPriority(priority);
+      tileRequest->setFrameNumberOfLastRequest(framestamp->getFrameNumber());
+      tileRequest->setTimestampLastRequest(framestamp->getReferenceTime());
+   }
+}
+
+void ossimPlanetTerrain::requestMerge(ossimPlanetTerrainTile* tile,
+                                      ossim_float64 priority,
+                                      const osg::FrameStamp* framestamp,
+                                      ossimPlanetOperation* request)
+{
+   ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>(request);
+   if(tileRequest)
+   {
+      tileRequest->reset();
+      tileRequest->setTile(tile);
+      tileRequest->setPriority(priority);
+      tileRequest->setFrameNumberOfLastRequest(framestamp->getFrameNumber());
+      theMergeQueue->add(tileRequest);
+   }
+   
+}
+
+void ossimPlanetTerrain::requestTexture(ossimPlanetTerrainTile* tile,
+                                        ossim_float64 priority,
+                                        const osg::FrameStamp* framestamp,
+                                        const std::vector<ossim_uint32>& indices,
+                                        ossimPlanetOperation* request)
+{
+   if(theResetRootsFlag) return;
+   ossimPlanetTextureRequest* tileRequest = dynamic_cast<ossimPlanetTextureRequest*>(request);
+   if(tileRequest)
+   {
+      if(tileRequest->referenceCount() == 1)
+      {
+         tileRequest->reset();
+         tileRequest->setTimestampFirstRequest(framestamp->getReferenceTime());
+         tileRequest->setTile(tile);
+         tileRequest->setTextureLayerIndices(indices);
+         theTextureQueue->add(tileRequest);
+      }
+      tileRequest->setPriority(priority);
+      tileRequest->setFrameNumberOfLastRequest(framestamp->getFrameNumber());
+      tileRequest->setTimestampLastRequest(framestamp->getReferenceTime());
+   }
+}
+
+void ossimPlanetTerrain::requestElevation(ossimPlanetTerrainTile* tile,
+                                          ossim_float64 priority,
+                                          const osg::FrameStamp* framestamp,
+                                          ossimPlanetOperation* request)
+{
+   if(theResetRootsFlag) return;
+   ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>(request);
+   if(tileRequest)
+   {
+      if(tileRequest->referenceCount() == 1)
+      {
+         tileRequest->reset();
+         tileRequest->setTile(tile);
+         tileRequest->setTimestampFirstRequest(framestamp->getReferenceTime());
+         theElevationQueue->add(tileRequest);
+      }
+      tileRequest->setPriority(priority);
+      tileRequest->setFrameNumberOfLastRequest(framestamp->getFrameNumber());
+      tileRequest->setTimestampLastRequest(framestamp->getReferenceTime());
+   }
+}
+
+void ossimPlanetTerrain::compileGLObjects(osg::State& state, double compileTime)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNeedToCompileQueueMutex);
+   osg::Timer_t startT = osg::Timer::instance()->tick();
+   double delta = 0.0;
+   double deltaNextTest = 0.0;
+   double diff = 0.0;
+   bool done = theNeedToCompileQueue.empty();
+   if(!done)
+   {
+      setRedrawFlag(true);
+   }
+   osg::RenderInfo renderInfo;
+   renderInfo.setState(&state);
+   while(!done)
+   {
+      // returns false if no more objects in the request need compiling
+      if(theNeedToCompileQueue.front()->compileObjects(renderInfo, compileTime))
+      {
+         addRequestToReadyToApplyQueue(theNeedToCompileQueue.front().get());
+         theNeedToCompileQueue.pop_front();
+      }
+      osg::Timer_t testT = osg::Timer::instance()->tick();
+      delta = osg::Timer::instance()->delta_s(startT, testT);
+      diff = delta - deltaNextTest;
+      if((delta > (compileTime-diff))||
+         theNeedToCompileQueue.empty())
+      {
+         done = true;
+      }
+      deltaNextTest = delta;
+   }
+}
+
+bool ossimPlanetTerrain::resetRootsFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theResetRootsFlag;
+}
+
+void ossimPlanetTerrain::buildRoot()
+{
+   if(!theGrid.valid()) return;
+   
+   theReadyToApplyToGraphQueue.clear();
+   theReadyToApplyToGraphNewNodesQueue.clear();
+   theNeedToCompileQueue.clear();
+   theSplitQueue->removeAllOperations();
+   theElevationQueue->removeAllOperations();
+   theTextureQueue->removeAllOperations();
+   bool hasActiveOperations = false;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMutex);
+      TileSet::iterator iter = theTileSet.begin();
+      while(iter != theTileSet.end())
+      {
+         (*iter)->cancelAllOperations();
+         if((*iter)->hasActiveOperations())
+         {
+            hasActiveOperations = true;
+         }
+         ++iter;
+      }
+      if(!hasActiveOperations)
+      {
+         theTileSet.clear();
+         removeChildren(0, getNumChildren());
+      }
+   }
+   if(!hasActiveOperations)
+   {
+      ossimPlanetGrid::TileIds rootIds;
+      theGrid->getRootIds(rootIds);
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < rootIds.size(); ++idx)
+      {
+         ossimPlanetTerrainTile* tile = new ossimPlanetTerrainTile(rootIds[idx]);
+         tile->setTerrain(this);
+         tile->init();
+         addChild(tile);
+      }
+      theResetRootsFlag = false;
+      setRedrawFlag(true);
+   }      
+}
+
+ossimPlanetTerrain* ossimPlanetTerrain::findTerrain(osg::NodePath& currentNodePath)
+{
+   if(currentNodePath.empty())
+   {
+      return 0;
+   }
+   for(osg::NodePath::reverse_iterator itr = currentNodePath.rbegin();
+       itr != currentNodePath.rend();
+       ++itr)
+   {
+      ossimPlanetTerrain* ts = dynamic_cast<ossimPlanetTerrain*>(*itr);
+      if (ts) 
+      {
+         return ts;
+      }
+   }
+   
+   return 0;
+}
+
+double ossimPlanetTerrain::maxTimeToSplit()const
+{
+   return theMaxTimeToSplit;
+}
+
+double ossimPlanetTerrain::maxTimeToMerge()const
+{
+   return theMaxTimeToMerge;
+}
+void ossimPlanetTerrain::registerTile(ossimPlanetTerrainTile* tile)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMutex);
+      if(tile)
+      {
+         theTileSet.insert(tile);
+      }
+   }
+}
+
+void ossimPlanetTerrain::unregisterTile(ossimPlanetTerrainTile* tile)
+{
+   {   
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMutex);
+      TileSet::iterator iter = theTileSet.find(tile);
+      if(iter != theTileSet.end())
+      {
+         theTileSet.erase(iter);
+      }
+   }
+}
+ossimPlanetTerrainTile* ossimPlanetTerrain::findTile(const ossimPlanetTerrainTileId& id)
+{
+#if 0
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMapMutex);
+   TileSetMap::iterator iter = theTileSetMap.find(id);
+   if(iter != theTileSetMap.end())
+   {
+      return iter->second;
+   }
+#endif
+   return 0;
+}
+const ossimPlanetTerrainTile* ossimPlanetTerrain::findTile(const ossimPlanetTerrainTileId& id)const
+{
+#if 0
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMapMutex);
+   TileSetMap::const_iterator iter = theTileSetMap.find(id);
+   if(iter != theTileSetMap.end())
+   {
+      return iter->second;
+   }
+#endif
+   return 0;
+}
+
+void ossimPlanetTerrain::refreshImageAndElevationLayers(ossimPlanetExtents* extents)
+{
+   refreshImageLayers(extents);
+   refreshElevationLayers(extents);
+#if 0
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMutex);
+   TileSet::iterator iter = theTileSet.begin();
+   bool imageIntersects     = true;
+   bool elevationIntersects = true;
+   osg::ref_ptr<ossimPlanetExtents> imageExtent = new ossimPlanetExtents;
+   osg::ref_ptr<ossimPlanetExtents> elevExtent = new ossimPlanetExtents;
+   ossim_uint32 idx;
+   while(iter != theTileSet.end())
+   {
+      ossim_uint32 bound = (*iter)->numberOfImageLayers();
+      if(extents)
+      {
+         theGrid->convertToGeographicExtents((*iter)->tileId(),
+                                             *imageExtent,
+                                             textureTileWidth(),
+                                             textureTileHeight());
+         theGrid->convertToGeographicExtents((*iter)->tileId(),
+                                             *elevExtent,
+                                             elevationTileWidth(),
+                                             elevationTileHeight());
+         
+         if(extents->intersectsLatLon(*imageExtent.get())&&
+            extents->intersectsScale(*imageExtent.get()))
+         {
+            imageIntersects = true;
+         }
+         else
+         {
+            imageIntersects = false;
+         }
+         
+         if(extents->intersectsLatLon(*elevExtent.get()))
+         {
+            elevationIntersects = true;
+         }
+         else
+         {
+            elevationIntersects = false;
+         }
+      }
+      if(elevationIntersects)
+      {
+         (*iter)->elevationLayer()->setRefreshFlag(true);
+         (*iter)->elevationLayer()->setNoMoreDataFlag(false);
+      }
+      
+      if(imageIntersects)
+      {
+         for(idx = 0; idx < bound; ++idx)
+         {
+            (*iter)->imageLayer(idx)->setRefreshFlag(true);
+            (*iter)->imageLayer(idx)->setNoMoreDataFlag(false);
+            if(textureLayer(idx)&&((*iter)->tileId().level()>0))
+            {
+               bool hasDataFlag = textureLayer(idx)->hasTexture(textureTileWidth(), 
+                                                                textureTileHeight(), 
+                                                                (*iter)->tileId(), 
+                                                                *grid());
+               (*iter)->imageLayer(idx)->setNoMoreDataFlag(!hasDataFlag);
+            }
+         }
+      }
+      ++iter;
+   }
+   setRedrawFlag(true);
+#endif
+}
+
+void ossimPlanetTerrain::refreshImageLayers(ossimPlanetExtents* extents)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshExtentsMutex);
+   if(theRefreshImageExtent.valid())
+   {
+      if(extents)
+      {
+         theRefreshImageExtent->combine(extents);
+      }
+   }
+   else if(extents)
+   {
+      theRefreshImageExtent = new ossimPlanetExtents(*extents); 
+   }
+   else
+   {
+      theRefreshImageExtent = new ossimPlanetExtents();
+   }
+   setRedrawFlag(true);
+}
+
+void ossimPlanetTerrain::refreshElevationLayers(ossimPlanetExtents* extents)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshExtentsMutex);
+   if(theRefreshElevationExtent.valid())
+   {
+      if(extents)
+      {
+         theRefreshElevationExtent->combine(extents);
+      }
+   }
+   else if(extents)
+   {
+      theRefreshElevationExtent = new ossimPlanetExtents(*extents); 
+   }
+   else
+   {
+      theRefreshElevationExtent = new ossimPlanetExtents();
+   }
+   setRedrawFlag(true);
+}
+
+
+void ossimPlanetTerrain::refreshExtents()
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theRefreshExtentsMutex);
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theTileSetMutex);
+      if(!theRefreshElevationExtent.valid()&&
+         !theRefreshImageExtent.valid())
+      {
+         return;
+      }
+      ossim_uint32 idx = 0;
+      TileSet::iterator iter = theTileSet.begin();
+      osg::ref_ptr<ossimPlanetExtents> tileExtent = new ossimPlanetExtents;
+      while(iter != theTileSet.end())
+      {
+         theGrid->convertToGeographicExtents((*iter)->tileId(),
+                                             *tileExtent,
+                                             textureTileWidth(),
+                                             textureTileHeight());
+         if(theRefreshImageExtent.valid())
+         {
+            if(theRefreshImageExtent->intersectsLatLon(*tileExtent.get()))//&&
+//               theRefreshImageExtent->intersectsScale(*tileExtent.get()))
+            {
+               (*iter)->textureRequest()->cancel();
+               ossim_uint32 bound = (*iter)->numberOfImageLayers();
+               for(idx = 0; idx < bound; ++idx)
+               {
+                  (*iter)->imageLayer(idx)->setRefreshFlag(true);
+                  (*iter)->imageLayer(idx)->setNoMoreDataFlag(false);
+                  if(textureLayer(idx)&&((*iter)->tileId().level()>0))
+                  {
+                     bool hasDataFlag = textureLayer(idx)->hasTexture(textureTileWidth(), 
+                                                                      textureTileHeight(), 
+                                                                      (*iter)->tileId(), 
+                                                                      *grid());
+                     (*iter)->imageLayer(idx)->setNoMoreDataFlag(!hasDataFlag);
+                  }
+               }
+            }
+         }
+         if(theRefreshElevationExtent.valid())
+         {
+            if(theRefreshElevationExtent->intersectsLatLon(*tileExtent.get()))
+            {
+               (*iter)->elevationRequest()->cancel();
+               (*iter)->elevationLayer()->setRefreshFlag(true);
+               (*iter)->elevationLayer()->setNoMoreDataFlag(false);
+               if(elevationLayer()&&((*iter)->tileId().level()>0))
+               {
+#if 0
+                  bool hasDataFlag = elevationLayer()->hasTexture(elevationTileWidth(), 
+                                                                  elevationTileHeight(), 
+                                                                  (*iter)->tileId(), 
+                                                                  *grid());
+                  (*iter)->elevationLayer()->setNoMoreDataFlag(!hasDataFlag);
+#else
+                  (*iter)->elevationLayer()->setNoMoreDataFlag(false);
+#endif
+               }
+            }
+         }
+         
+         ++iter;
+      }
+      
+      theRefreshElevationExtent = 0;
+      theRefreshImageExtent     = 0;
+   }
+   setRedrawFlag(true);
+}
+
+void ossimPlanetTerrain::resetImageLayers()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTileSetMutex);
+   TileSet::iterator iter = theTileSet.begin();
+   while(iter != theTileSet.end())
+   {
+      ossim_uint32 idx   = 0;
+      ossim_uint32 bound = (*iter)->numberOfImageLayers();
+      for(idx = 0; idx < bound; ++idx)
+      {
+         (*iter)->resetImageLayers();
+      }
+      ++iter;
+   }
+   setRedrawFlag(true);
+}
+
+void ossimPlanetTerrain::resetGraph()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theResetRootsFlag = true;
+}
+
+void ossimPlanetTerrain::setModel(ossimPlanetGeoRefModel* model)
+{
+   ossimPlanetLayer::setModel(model);
+   if(theElevationLayer.valid())
+   {
+      theElevationLayer->setGeoRefModel(model);
+   }
+}
+
+void ossimPlanetTerrain::addRequestToReadyToApplyQueue(ossimPlanetTileRequest* request)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToApplyToGraphQueueMutex);
+   if(dynamic_cast<ossimPlanetSplitRequest*>(request))
+   {
+      theReadyToApplyToGraphNewNodesQueue.push_back(request);
+   }
+   else
+   {
+      theReadyToApplyToGraphQueue.push_back(request);
+   }
+   setRedrawFlag(true);
+}
+
+void ossimPlanetTerrain::addRequestToNeedToCompileQueue(ossimPlanetTileRequest* request)
+{
+   if(thePager.valid())
+   {
+
+      osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet = new osgUtil::IncrementalCompileOperation::CompileSet();
+      osgUtil::IncrementalCompileOperation* compileOperation = thePager->getIncrementalCompileOperation();
+      if(compileOperation&&!compileOperation->getContextSet().empty())
+      {
+            //osgUtil::StateToCompile stateToCompile(osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES);
+            //compileSet->buildCompileMap(compileOperation->getContextSet());
+         request->populateCompileSet(compileOperation->getContextSet(), *compileSet.get());
+         compileSet->_compileCompletedCallback = new ossimPlanetDatabasePagerCompileCompletedCallback(this, request);
+         compileOperation->add(compileSet.get(), false);
+      }
+      else
+      {
+         addRequestToReadyToApplyQueue(request);
+      }
+      //std::cout << compileOperation << std::endl;
+
+   }
+ }
+
+void ossimPlanetTerrain::applyRequestsToGraph(double maxTime)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToApplyToGraphQueueMutex);
+   if(theReadyToApplyToGraphQueue.empty()&&theReadyToApplyToGraphNewNodesQueue.empty()) return;
+   osg::ref_ptr<ossimPlanetTileRequest> request;
+   bool doneFlag = false;
+   ossim_uint32 operationCount = 0;
+   osg::Timer_t startTick = osg::Timer::instance()->tick();
+   while(!doneFlag)
+   {
+      if(!theReadyToApplyToGraphQueue.empty())
+      {
+      //  theReadyToApplyToGraphQueue.sort(ossimPlanetTileRequest::SortFunctor());
+        if((*theReadyToApplyToGraphQueue.begin())->isRequestCurrent(theTextureQueue->currentFrameNumber()))
+         {
+            (*theReadyToApplyToGraphQueue.begin())->applyToGraph();
+            ++operationCount;
+            theReadyToApplyToGraphQueue.pop_front();
+         }
+         else
+         {
+            theReadyToApplyToGraphQueue.pop_front();
+         }
+      }
+#if 1
+      if(!theReadyToApplyToGraphNewNodesQueue.empty())
+      {
+        //theReadyToApplyToGraphNewNodesQueue.sort(ossimPlanetTileRequest::SortFunctor());
+         if((*theReadyToApplyToGraphNewNodesQueue.begin())->isRequestCurrent(theTextureQueue->currentFrameNumber()))
+         {
+            (*theReadyToApplyToGraphNewNodesQueue.begin())->applyToGraph();
+            ++operationCount;
+            theReadyToApplyToGraphNewNodesQueue.pop_front();
+         }
+         else
+         {
+            theReadyToApplyToGraphNewNodesQueue.pop_front();
+         }
+      }
+#endif
+      double delta = osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick());
+#if 1
+      doneFlag = ((theReadyToApplyToGraphQueue.empty()&&theReadyToApplyToGraphNewNodesQueue.empty())||
+                  (delta > maxTime)||
+                  (operationCount>=theMaxNumberOfOperationsToApplyToGraphPerFrame));
+#else
+      doneFlag = ((theReadyToApplyToGraphQueue.empty())||
+                  (delta > maxTime)||
+                  (operationCount>=theMaxNumberOfOperationsToApplyToGraphPerFrame));
+#endif
+   }
+   setRedrawFlag(true);
+}
+
+
+void ossimPlanetTerrain::pruneNeedToCompileAndAddToGraphThreadQueues()
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToApplyToGraphQueueMutex);
+      ossimPlanetTileRequest::List::iterator iter = theReadyToApplyToGraphQueue.begin();
+      while(iter != theReadyToApplyToGraphQueue.end())
+      {
+         if(((*iter)->state() == ossimPlanetOperation::CANCELED_STATE)||
+            (!(*iter)->isRequestCurrent(theTextureQueue->currentFrameNumber())))
+         {
+            iter = theReadyToApplyToGraphQueue.erase(iter);
+         }
+         else
+         {
+            ++iter;
+         }
+      }
+   }
+#if 1
+   {
+      
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theReadyToApplyToGraphQueueMutex);
+      ossimPlanetTileRequest::List::iterator iter = theReadyToApplyToGraphNewNodesQueue.begin();
+      while(iter != theReadyToApplyToGraphNewNodesQueue.end())
+      {
+         if(((*iter)->state() == ossimPlanetOperation::CANCELED_STATE)||
+            (!(*iter)->isRequestCurrent(theTextureQueue->currentFrameNumber())))
+         {
+            iter = theReadyToApplyToGraphNewNodesQueue.erase(iter);
+         }
+         else
+         {
+            ++iter;
+         }
+      }
+   }
+#endif
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theNeedToCompileQueueMutex);
+      ossimPlanetTileRequest::List::iterator iter = theNeedToCompileQueue.begin();
+      while(iter != theNeedToCompileQueue.end())
+      {
+         if(((*iter)->state() == ossimPlanetOperation::CANCELED_STATE)||
+            (!(*iter)->isRequestCurrent(theTextureQueue->currentFrameNumber())))
+         {
+            iter = theNeedToCompileQueue.erase(iter);
+         }
+         else
+         {
+            ++iter;
+         }
+      }
+   }
+}
+
+void ossimPlanetTerrain::removeTerrainChildren(double maxTime)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenToRemoveMutex);
+   osg::Timer_t startTick = osg::Timer::instance()->tick();
+   //   osgUtil::GLObjectsVisitor visitor(osgUtil::GLObjectsVisitor::RELEASE_DISPLAY_LISTS|
+   //                                     osgUtil::GLObjectsVisitor::RELEASE_STATE_ATTRIBUTES);
+   RemoveChildrenList::iterator iter = theChildrenToRemove.begin();
+   while(iter!=theChildrenToRemove.end())
+   {
+      if((*iter)->hasActiveOperations())
+      {
+         (*iter)->cancelAllOperations();
+         ++iter;
+      }
+      else
+      {
+         (*iter)->releaseGLObjects();
+         iter = theChildrenToRemove.erase(iter);
+      }
+      double delta = osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick());
+      if(delta > maxTime)
+      {
+         break;
+      }
+   }
+   if(theChildrenToRemove.size()>0)
+   {
+      iter = theChildrenToRemove.begin();
+      //std::cout << "_____________" << std::endl;
+      while(iter!=theChildrenToRemove.end())
+      {
+         //std::cout << (*iter)->tileId() << std::endl;
+         // std::cout << "elevationRequest = " << (*iter)->elevationRequest()->referenceCount() << std::endl;
+         // std::cout << "textureRequest = " << (*iter)->textureRequest()->referenceCount() << std::endl;
+         // std::cout << "splitRequest = " << (*iter)->splitRequest()->referenceCount() << std::endl;
+         ++iter;
+      }
+      //std::cout << "Elevation queue size = " << theElevationQueue->operationQueue()->size() << std::endl;
+      //std::cout << "List size = " << theChildrenToRemove.size() << std::endl;
+   }
+}
+
+void ossimPlanetTerrain::setMaxNumberOfOperationsToApplyToGraphPerFrame(ossim_uint32 value)
+{
+   theMaxNumberOfOperationsToApplyToGraphPerFrame = value;
+}
+
+void ossimPlanetTerrain::setCullAmountType(CullAmountType cullAmount)
+{
+   switch(cullAmount)
+   {
+      case NO_CULL:
+      {
+         theCullSettings = osg::CullSettings::NO_CULLING;
+         break;
+      }
+      case LOW_CULL:
+      {
+         theCullSettings = osg::CullSettings::SMALL_FEATURE_CULLING;
+         break;
+      }
+      case MEDIUM_LOW_CULL:
+      {
+         theCullSettings = static_cast<osg::CullSettings::CullingModeValues>(osg::CullSettings::SMALL_FEATURE_CULLING|
+                                                                             osg::CullSettings::CLUSTER_CULLING);
+         break;
+      }
+      case MEDIUM_CULL:
+      {
+         theCullSettings = static_cast<osg::CullSettings::CullingModeValues>(osg::CullSettings::SMALL_FEATURE_CULLING|
+                                                                             osg::CullSettings::CLUSTER_CULLING|
+                                                                             osg::CullSettings::VIEW_FRUSTUM_SIDES_CULLING);
+         break;
+      }
+      case MEDIUM_HIGH_CULL:
+      {
+         theCullSettings = static_cast<osg::CullSettings::CullingModeValues>(osg::CullSettings::SMALL_FEATURE_CULLING|
+                                                                             osg::CullSettings::CLUSTER_CULLING|
+                                                                             osg::CullSettings::VIEW_FRUSTUM_CULLING);
+         break;
+      }
+      case HIGH_CULL:
+      {
+         theCullSettings = static_cast<osg::CullSettings::CullingModeValues>(osg::CullSettings::ENABLE_ALL_CULLING);
+         break;
+      }
+   }
+   setRedrawFlag(true);
+}
+void ossimPlanetTerrain::setTextureTileSize(ossim_uint32 width,
+                                            ossim_uint32 height)
+{
+   theTextureTileWidth  = width;
+   theTextureTileHeight = height;
+}
+
+ossim_uint32 ossimPlanetTerrain::textureTileWidth()const
+{
+   return theTextureTileWidth;
+}
+
+ossim_uint32 ossimPlanetTerrain::textureTileHeight()const
+{
+   return theTextureTileHeight;
+}
+
+void ossimPlanetTerrain::setElevationTileSize(ossim_uint32 width,
+                                              ossim_uint32 height)
+{
+   theElevationTileWidth = width|1; // make sure that it's odd number
+   theElevationTileHeight = height|1; // make sure that it's an odd number
+}
+ossim_uint32 ossimPlanetTerrain::elevationTileWidth()const
+{
+   return theElevationTileWidth;
+}
+
+ossim_uint32 ossimPlanetTerrain::elevationTileHeight()const
+{
+   return theElevationTileHeight;
+}
+
+void ossimPlanetTerrain::setElevationDensityType(ElevationDensityType type)
+{
+   switch(type)
+   {
+      case LOW_ELEVATION_DENSITY:
+      {
+         setElevationTileSize(9, 9);
+         break;
+      }
+      case MEDIUM_LOW_ELEVATION_DENSITY:
+      {
+         setElevationTileSize(17, 17);
+         break;
+      }
+      case MEDIUM_ELEVATION_DENSITY:
+      {
+         setElevationTileSize(33, 33);
+         break;
+      }
+      case MEDIUM_HIGH_ELEVATION_DENSITY:
+      {
+         setElevationTileSize(65, 65);
+         break;
+      }
+      case HIGH_ELEVATION_DENSITY:
+      {
+         setElevationTileSize(129, 129);
+         break;
+      }
+   }
+   if(theElevationCache.valid())
+   {
+      theElevationCache->clean();
+   }
+}
+
+void ossimPlanetTerrain::setTextureDensityType(TextureDensityType type)
+{
+   switch(type)
+   {
+      case LOW_TEXTURE_DENSITY:
+      {
+         setTextureTileSize(64, 64);
+         break;
+      }
+      case MEDIUM_LOW_TEXTURE_DENSITY:
+      {
+         setTextureTileSize(128, 128);
+         break;
+      }
+      case MEDIUM_TEXTURE_DENSITY:
+      {
+         setTextureTileSize(256, 256);
+         break;
+      }
+      case MEDIUM_HIGH_TEXTURE_DENSITY:
+      {
+         setTextureTileSize(512, 512);
+         break;
+      }
+      case HIGH_TEXTURE_DENSITY:
+      {
+         setTextureTileSize(1024, 1024);
+         break;
+      }
+   }
+}
+
+ossimPlanetTerrain::ElevationDensityType ossimPlanetTerrain::elevationDensityType()const
+{
+   ossim_int32 size = ossim::max(elevationTileHeight(), elevationTileWidth());
+   
+   if(size <=9)
+   {
+      return LOW_ELEVATION_DENSITY;
+   }
+   else if(size <=17)
+   {
+      return MEDIUM_LOW_ELEVATION_DENSITY;
+   }
+   else if(size <=33)
+   {
+      return MEDIUM_ELEVATION_DENSITY;
+   }
+   else if(size <=64)
+   {
+      return MEDIUM_HIGH_ELEVATION_DENSITY;
+   }
+   
+   return HIGH_ELEVATION_DENSITY;
+}
+
+ossimPlanetTerrain::TextureDensityType ossimPlanetTerrain::textureDensityType()const
+{
+   ossim_int32 size = ossim::max(textureTileWidth(), textureTileHeight());
+   
+   if(size <=64)
+   {
+      return LOW_TEXTURE_DENSITY;
+   }
+   else if(size <=128)
+   {
+      return MEDIUM_LOW_TEXTURE_DENSITY;
+   }
+   else if(size <=256)
+   {
+      return MEDIUM_TEXTURE_DENSITY;
+   }
+   else if(size <=512)
+   {
+      return MEDIUM_HIGH_TEXTURE_DENSITY;
+   }
+   
+   return HIGH_TEXTURE_DENSITY;
+}
+
+void ossimPlanetTerrain::setSplitMergePixelMetricParameters(ossim_float64 mergeMetric,
+                                                            ossim_float64 splitMetric)
+{
+  theSplitPixelMetric = splitMetric;
+  theMergePixelMetric = mergeMetric;
+}
+
+void ossimPlanetTerrain::setSplitMergeMetricType(SplitMergeMetricType type)
+{
+  theSplitMergeMetricType = type;
+}
+
+ossimPlanetTerrain::SplitMergeMetricType ossimPlanetTerrain::splitMergeMetricType()const
+{
+  return theSplitMergeMetricType;
+}
+
+ossim_float64 ossimPlanetTerrain::splitPixelMetric()const
+{
+  return theSplitPixelMetric;
+}
+
+ossim_float64 ossimPlanetTerrain::mergePixelMetric()const
+{
+  return theMergePixelMetric;
+
+}
+
+void ossimPlanetTerrain::setSplitMergeSpeedType(SplitMergeSpeedType type)
+{
+   switch(type)
+   {
+      case LOW_SPEED:
+      {
+         setSplitMergeLodScale(1.5);
+         theSplitPixelMetric = 16;
+         theMergePixelMetric = 8;
+         break;
+      }
+      case MEDIUM_LOW_SPEED:
+      {
+         setSplitMergeLodScale(3.0);
+         theSplitPixelMetric = 10;
+         theMergePixelMetric = 5;
+         break;
+      }
+      case MEDIUM_SPEED:
+      {
+         setSplitMergeLodScale(5.0);
+         theSplitPixelMetric = 8;
+         theMergePixelMetric = 4;
+         break;
+      }
+      case MEDIUM_HIGH_SPEED:
+      {
+         setSplitMergeLodScale(6.5);
+         theSplitPixelMetric = 6;
+         theMergePixelMetric = 3;
+         break;
+      }
+      case HIGH_SPEED:
+      {
+         setSplitMergeLodScale(8.0);
+         theSplitPixelMetric = 4;
+         theMergePixelMetric = 2;
+         break;
+      }
+   }
+}
+
+
+void ossimPlanetTerrain::setSplitMergeLodScale(ossim_float64 ratio)
+{
+   theSplitMergeLodScale = ratio;
+}
+
+ossim_float64 ossimPlanetTerrain::splitMergeLodScale()const
+{
+   return theSplitMergeLodScale;
+}
+
+void ossimPlanetTerrain::setElevationExaggeration(ossim_float64 exaggeration)
+{
+   theElevationExaggeration = exaggeration;
+}
+
+ossim_float64 ossimPlanetTerrain::elevationExaggeration()const
+{
+   return theElevationExaggeration;
+}
+
+void ossimPlanetTerrain::setMinimumTimeToCompilePerFrameInSeconds(double timeInSeconds)
+{
+   theMinimumTimeToCompilePerFrame = timeInSeconds;
+}
+
+ossim_float64 ossimPlanetTerrain::minimumTimeToCompilePerFrame()const
+{
+   return theMinimumTimeToCompilePerFrame;
+}
+
+void ossimPlanetTerrain::setPrecompileEnabledFlag(bool flag)
+{
+   thePrecompileEnabledFlag = flag;
+}
+
+bool ossimPlanetTerrain::precompileEnabledFlag()const
+{
+   return thePrecompileEnabledFlag;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainGeometryTechnique.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainGeometryTechnique.cpp
new file mode 100644
index 0000000..ddc49fd
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainGeometryTechnique.cpp
@@ -0,0 +1,1744 @@
+#include <ossimPlanet/ossimPlanetTerrainGeometryTechnique.h>
+#include <ossimPlanet/ossimPlanetTerrainTile.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetTexture2D.h>
+#include <ossimPlanet/ossimPlanet.h>
+#include <iostream>
+#include <osg/io_utils>
+#include <osg/Timer>
+#include <osg/CullFace>
+#include <osgDB/Registry>
+#include <osgUtil/SmoothingVisitor>
+#include <osgUtil/TriStripVisitor>
+#include <queue>
+#include <osgUtil/IntersectionVisitor>
+#include <osgUtil/Simplifier>
+
+void ossimPlanetTerrainGeometryTechnique::UpdateChildTextureVisitor::apply(osg::Node& node)
+{
+   ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(&node);
+   if(tile)
+   {
+      ossimPlanetTerrainGeometryTechnique* technique = (ossimPlanetTerrainGeometryTechnique*)tile->terrainTechnique();
+      if(technique)
+      {
+         BufferData& buffer = technique->readOnlyBuffer();
+         if(buffer.theGeode.valid())
+         {
+            if(!tile->imageLayer(theIdx)->image()||
+               (tile->imageLayer(theIdx)->noMoreDataFlag()&&
+                tile->imageLayer(theIdx)->refreshFlag())) // no valid image then set to the best parent texture and keep going
+            {
+               osg::StateSet* stateset = buffer.theGeode->getOrCreateStateSet();
+               stateset->setTextureAttributeAndModes(theIdx, theTexture.get(), osg::StateAttribute::ON);
+               technique->updateTextureMatrix(stateset, theIdx, tile->tileId(),  theTexture->tileId());
+               traverse(node);
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::CullNode::traverse(osg::NodeVisitor& nv)
+{
+   osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+   theCulledFlag = false;
+   
+   if(!cv) return;
+   const osg::Vec3d& center = theBoundingBox->center();
+   double radius = theBoundingBox->radius();
+   thePixelSize = cv->clampedPixelSize(center, radius);
+   osg::Vec3d eye = cv->getEyeLocal();
+   osg::Vec3d eyeDirection = cv->getLookVectorLocal();
+   const osg::Polytope& frustum = cv->getCurrentCullingSet().getFrustum();
+   theEyeDistance = (eye-theBoundingBox->center()).length();
+   theEyeToVolumeDistance = (theEyeDistance - theBoundingBox->radius());
+   if(theEyeToVolumeDistance < theBoundingBox->radius()) theEyeToVolumeDistance = FLT_EPSILON;
+#if 1
+   // do cluster cull if enabled
+   //
+   if (cv->getCullingMode() & osg::CullSettings::CLUSTER_CULLING)
+   {
+      if(theClusterCullingDeviation >= -1.0)
+      {
+         // let's use the bounding box center instead of the cluster center
+         // seems to be more stable right now to do it this way.
+         //
+         //osg::Vec3d eyeCp = eye - center;
+         osg::Vec3d eyeCp = eye - theClusterCullingControlPoint;
+         double radius    = eyeCp.length();
+         
+         if (radius>=theClusterCullingRadius)
+         {
+            double deviation = (eyeCp * theClusterCullingNormal)/radius;
+            
+            theCulledFlag = (deviation < theClusterCullingDeviation);
+         }
+      }
+   }
+#endif
+   theWithinFrustumFlag = true;
+   if(theBoundingBox->isInFront(eye, eyeDirection))
+   {
+      theWithinFrustumFlag = theBoundingBox->intersects(frustum);
+   }
+   else
+   {
+      theWithinFrustumFlag = false;
+   }
+   
+   if((cv->getCullingMode()&osg::CullSettings::VIEW_FRUSTUM_CULLING)&&!theCulledFlag)
+   {
+      theCulledFlag = !theWithinFrustumFlag;
+   }
+}
+
+osg::BoundingSphere ossimPlanetTerrainGeometryTechnique::CullNode::computeBound() const
+{
+   osg::BoundingSphere bsphere(theBoundingBox->center(),
+                               theBoundingBox->radius());
+   if (!bsphere.valid()) return bsphere;
+   
+   // note, NULL pointer for NodeVisitor, so compute's need
+   // to handle this case gracefully, normally this should not be a problem.
+   osg::Matrix l2w;
+   
+   computeLocalToWorldMatrix(l2w,NULL);
+   
+   osg::Vec3d xdash = bsphere._center;
+   xdash.x() += bsphere._radius;
+   xdash = xdash*l2w;
+   
+   osg::Vec3d ydash = bsphere._center;
+   ydash.y() += bsphere._radius;
+   ydash = ydash*l2w;
+   
+   osg::Vec3d zdash = bsphere._center;
+   zdash.z() += bsphere._radius;
+   zdash = zdash*l2w;
+   
+   
+   bsphere._center = bsphere._center*l2w;
+   
+   xdash -= bsphere._center;
+   double len_xdash = xdash.length();
+   
+   ydash -= bsphere._center;
+   double len_ydash = ydash.length();
+   
+   zdash -= bsphere._center;
+   double len_zdash = zdash.length();
+   
+   bsphere._radius = len_xdash;
+   if (bsphere._radius<len_ydash) bsphere._radius = len_ydash;
+   if (bsphere._radius<len_zdash) bsphere._radius = len_zdash;
+   
+   return bsphere;
+   
+}
+
+ossimPlanetTerrainGeometryTechnique::ossimPlanetTerrainGeometryTechnique()
+:ossimPlanetTerrainTechnique()
+{
+}
+
+ossimPlanetTerrainGeometryTechnique::ossimPlanetTerrainGeometryTechnique(const ossimPlanetTerrainGeometryTechnique& src,
+                                                                         const osg::CopyOp& copyop)
+:ossimPlanetTerrainTechnique(src, copyop)
+{
+}
+
+ossimPlanetTerrainGeometryTechnique::~ossimPlanetTerrainGeometryTechnique()
+{
+   BufferData& buffer = readOnlyBuffer();
+   buffer.theTransform = 0;
+   buffer.theGeode = 0;
+   buffer.theGeometry = 0;
+   buffer.theClusterCullingCallback = 0;
+   buffer.theCullNode = 0;
+   
+   buffer = writeBuffer();
+   buffer.theTransform = 0;
+   buffer.theGeode = 0;
+   buffer.theGeometry = 0;
+   buffer.theClusterCullingCallback = 0;
+   buffer.theCullNode = 0;
+}
+
+void ossimPlanetTerrainGeometryTechnique::setTerrainTile(ossimPlanetTerrainTile* tile)
+{
+   if(tile)
+   {
+      tile->setCullingActive(false);
+   }
+   ossimPlanetTerrainTechnique::setTerrainTile(tile);
+}
+
+void ossimPlanetTerrainGeometryTechnique::swapBuffers()
+{
+   //std::swap(theCurrentReadOnlyBuffer,theCurrentWriteBuffer);
+}
+
+void ossimPlanetTerrainGeometryTechnique::update(osgUtil::UpdateVisitor* uv)
+{
+   BufferData& buffer = readOnlyBuffer();
+   if (theTerrainTile) 
+   {
+      updateRequests(*uv);
+      // let's immediately initialize a level 0 tile
+      //
+      if(theTerrainTile->tileId().level() == 0)
+      {
+         if(!readOnlyBuffer().theGeometry.valid())
+         {
+            theTerrainTile->init();
+         }
+      }
+      if(buffer.theTransform.valid())
+      {
+         buffer.theTransform->accept(*uv);
+      }
+      theTerrainTile->osg::Group::traverse(*uv);
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::cull(osgUtil::CullVisitor* cv)
+{
+   BufferData& buffer = readOnlyBuffer();
+   
+   if(isCulled(buffer,cv))
+   {
+      return;
+   }
+   theTerrainTile->updateFrameAndTimeStamps(cv->getFrameStamp());
+   thePriorityPoint = cv->getEyeLocal();
+   theAdjustedEye   = cv->getEyeLocal();
+
+   if(theTerrainTile->terrain())
+   {
+     if(theTerrainTile->terrain()->falseEyeFlag())
+     {
+       theAdjustedEye = theTerrainTile->terrain()->falseEye();
+       thePriorityPoint = theAdjustedEye;
+     }
+     else if(theTerrainTile->terrain()->priorityPointFlag())
+     {
+       thePriorityPoint = theTerrainTile->terrain()->priorityPoint();
+     }
+   }
+
+   bool addChildren            = false;
+   bool removeChildren         = false;
+   
+   if(theTerrainTile->terrain()->splitMergeMetricType() == ossimPlanetTerrain::DISTANCE_METRIC)
+   {
+      double splitMergeLodScale = theTerrainTile->terrain()->splitMergeLodScale();
+      double ratio = splitMergeLodScale*thePatchBound.radius();
+      double distance = (theAdjustedEye - thePatchBound.center()).length();
+      removeChildren = distance  > ratio;
+      addChildren = (distance < ratio)&&isLeaf();
+   }
+   else
+   {
+      osg::Vec2d deltaXY;
+      theTerrainTile->terrain()->grid()->widthHeightInModelSpace(theTerrainTile->tileId(), deltaXY);
+      //ossim_float64 maxSize =.5*(deltaXY[0] + deltaXY[1]);
+      ossim_float64 maxSize =ossim::min(deltaXY[0], deltaXY[1]);
+      ossim_float64 averageMeters = ossimGpt().metersPerDegree().y* sqrt(2.0*maxSize*maxSize);
+      ossim_float64 averageRadius = averageMeters*theTerrainTile->terrain()->model()->getInvNormalizationScale();
+      ossim_float64 pixelSize     = cv->clampedPixelSize(thePatchBound.center(), averageRadius);
+      ossim_float64 pixelWidth    = ossim::max(theTerrainTile->terrain()->textureTileWidth(),
+                                               theTerrainTile->terrain()->textureTileHeight());
+      ossim_float64 mergeWidth = pixelWidth*theTerrainTile->terrain()->mergePixelMetric();
+      ossim_float64 splitWidth = pixelWidth*theTerrainTile->terrain()->splitPixelMetric();
+      
+      if(pixelSize < mergeWidth)
+      {
+         removeChildren = true;
+      }
+      else if(pixelSize > splitWidth)
+      {
+         addChildren = isLeaf();
+      }
+   }
+   // we can only add children if the previous buffered cull setting are not culled for 
+   // all child nodes and if we don't have all the children and if we are not culled
+   //
+   if(addChildren)
+   {
+      if(theTerrainTile->tileId().level() > 17)
+      {
+         addChildren = false;
+      }
+      else
+      {
+         theTerrainTile->terrain()->requestSplit(theTerrainTile,
+                                                 splitPriority(),
+                                                 cv->getFrameStamp(),
+                                                 theTerrainTile->splitRequest());
+         
+      }
+   }
+   if(isLeaf()||removeChildren)
+   {
+      if (buffer.theTransform.valid())
+      {
+         buffer.theTransform->accept(*cv);
+      }
+   }
+   else 
+   {
+      theTerrainTile->osg::Group::traverse(*cv);
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::updateRequests(osg::NodeVisitor& nv)
+{
+   // ossimPlanetTerrainTile* parentTile = theTerrainTile->parentTile();
+   bool canRequest = true;
+   // we need to loop this and add requests for multi textures.
+   //
+   // if(isLeaf())
+   if(canRequest)
+   {
+      std::vector<ossim_uint32> textureIndices;
+      ossimPlanetTerrainTile* current = theTerrainTile;
+      // bool doneImage = false;
+      bool doneElevation = false;
+      if(current)
+      {
+         ossim_uint32 imageLayerCount = current->numberOfImageLayers();
+         ossim_uint32 imageLayerIdx = 0;
+         for(imageLayerIdx = 0; imageLayerIdx < imageLayerCount; ++imageLayerIdx)
+         {
+            ossimPlanetTerrainImageLayer* layer = current->imageLayer(imageLayerIdx);
+            if(layer&&
+               (!layer->noMoreDataFlag())&&
+               (!layer->image()||
+                (layer->image()->tileId().level() != current->tileId().level())||
+                (layer->refreshFlag())))
+            {
+               textureIndices.push_back(imageLayerIdx);
+               // doneImage = true;
+            }
+         }
+         if(textureIndices.size() > 0)
+         {
+            theTerrainTile->terrain()->requestTexture(current,
+                                                      current->terrainTechnique()->texturePriority(),
+                                                      nv.getFrameStamp(),
+                                                      textureIndices,
+                                                      current->textureRequest());
+         }
+         ossimPlanetTerrainImageLayer* elevLayer = current->elevationLayer();
+         if(!doneElevation&&
+            elevLayer&&
+            (!elevLayer->noMoreDataFlag())&&
+            (!elevLayer->image()||
+             (elevLayer->image()->tileId().level()!=current->tileId().level())||
+             (elevLayer->refreshFlag())))
+         {
+            theTerrainTile->terrain()->requestElevation(current,
+                                                        current->terrainTechnique()->elevationPriority(),
+                                                        nv.getFrameStamp(),
+                                                        current->elevationRequest());
+            doneElevation = true;
+         }
+      }
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::traverse(osg::NodeVisitor& nv)
+{
+   // if app traversal update the frame count.
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
+         if (uv)
+         {
+            update(uv);
+            return;
+         }        
+         break;
+      }
+      case osg::NodeVisitor::CULL_VISITOR:
+      {
+         osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+         if (cv)
+         {
+            cull(cv);
+            return;
+         }
+         break;
+      }
+      default:
+      {
+         BufferData& buffer = readOnlyBuffer();
+         if(nv.getTraversalMode() == osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
+         {
+            if(isLeaf())
+            {
+               if(buffer.theTransform.valid())
+               {
+                  buffer.theTransform->accept(nv);
+               }
+               return;
+            }
+         }
+         else
+         {
+            if(buffer.theTransform.valid())
+            {
+               buffer.theTransform->accept(nv);
+            }
+         }
+         break;
+      }
+   }
+   theTerrainTile->osg::Group::traverse(nv);
+}
+
+void averageNormal(osg::Vec3d& center,
+                   osg::Vec3d& normal,
+                   const osg::Vec3d& p0,
+                   const osg::Vec3d& p1,
+                   const osg::Vec3d& p2,
+                   const osg::Vec3d& p3)
+{
+   center = (p0+p1+p2+p3)*.25;
+   osg::Vec3d delta1, delta2;
+   delta1 = (p0-center);
+   delta2 = (p1-center);
+   delta1.normalize();
+   delta2.normalize();
+   normal = delta1^delta2;
+   delta1 = (p1-center);
+   delta2 = (p2-center);
+   delta1.normalize();
+   delta2.normalize();
+   normal += (delta1^delta2);
+   delta1 = (p2-center);
+   delta2 = (p3-center);
+   delta1.normalize();
+   delta2.normalize();
+   normal += (delta1^delta2);
+   delta1 = (p3-center);
+   delta2 = (p0-center);
+   delta1.normalize();
+   delta2.normalize();
+   normal += (delta1^delta2);
+   
+   normal.normalize();
+}
+
+void ossimPlanetTerrainGeometryTechnique::buildMesh(ossimPlanetTerrainTile* /* optionalParent */)
+{
+   if(!theModel.valid()||!theGrid.valid()||!theTerrainTile||!theTerrainTile->terrain()) return;
+   BufferData& buffer = writeBuffer();
+   osg::ref_ptr<ossimPlanetImage> elevationImage = theTerrainTile->elevationLayer()->image();
+   //ossim_float32* elevationData = 0;
+   ossim_float64 skirtScale = .08;
+   unsigned int numRows = theTerrainTile->terrain()->elevationTileHeight();
+   unsigned int numCols = theTerrainTile->terrain()->elevationTileWidth();
+   ossim_int32 padding = 0;
+   if(elevationImage.valid())
+   {
+      //elevationData = (ossim_float32*)elevationImage->data();
+      numCols = elevationImage->widthWithoutPadding();
+      numRows = elevationImage->heightWithoutPadding();
+      padding = elevationImage->padding();
+   }
+   //std::cout << "w,h,pad = " << numCols <<", " << numRows << ", " << padding << "\n";
+   buffer.theGeode = new osg::Geode;
+   buffer.theTransform = new osg::MatrixTransform;
+   buffer.theGeometry = new osg::Geometry;
+   buffer.theGeode->addDrawable(buffer.theGeometry.get());
+   buffer.theClusterCullingCallback = new osg::ClusterCullingCallback();
+   osg::Geometry* geometry = buffer.theGeometry.get();
+   
+   buffer.theTransform->addChild(buffer.theGeode.get());
+   buffer.theGeode->addDrawable(buffer.theGeometry.get());
+   
+   
+   unsigned int numVerticesInBody = numCols*numRows;
+   unsigned int numVertices       = numVerticesInBody;
+   ossimPlanetGrid::GridBound tileBound;
+   theGrid->bounds(theTerrainTile->tileId(), tileBound);
+   osg::Vec2d metersPerPixel;
+   theGrid->getUnitsPerPixel(metersPerPixel, theTerrainTile->tileId(), numCols, numRows, OSSIM_METERS);
+   
+   ossim_uint32 rowIdx=0,colIdx=0;
+   
+   // This is the grid model point.  For this technique it should be lon, lat and height format
+   // stored in x, y, z
+   //
+   ossimPlanetGrid::ModelPoint centerModel;
+   theGrid->centerModel(theTerrainTile->tileId(), centerModel);
+   osg::Matrixd localToWorld;
+   // for our lsr let's always use te ellipsoid height of 0.  This will make things easier later
+   //
+   theModel->lsrMatrix(osg::Vec3d(centerModel.y(),
+                                  centerModel.x(),
+                                  0.0),//centerModel.z()),
+                       localToWorld);
+   osg::Matrixd inverseLocalToWorld;
+   inverseLocalToWorld.invert(localToWorld);
+   theModel->forward(osg::Vec3d(centerModel.y(), centerModel.x(), centerModel.z()), 
+                     buffer.theCenterPatch);
+   osg::Vec3d centerNormal, rightAxis, upAxis;
+   centerNormal = osg::Vec3d(localToWorld(2, 0),
+                             localToWorld(2, 1),
+                             localToWorld(2, 2));
+   rightAxis = osg::Vec3d(localToWorld(0, 0),
+                          localToWorld(0, 1),
+                          localToWorld(0, 2));
+   upAxis    = osg::Vec3d(localToWorld(1, 0),
+                          localToWorld(1, 1),
+                          localToWorld(1, 2));
+   osg::Vec2d normalDistance(0.0,0.0);
+   osg::Vec2d rightDistance(0.0,0.0);
+   osg::Vec2d upDistance(0.0,0.0);
+   double upDelta = 0.0;
+   double rightDelta = 0.0;
+   double normDelta  = 0.0;
+   osg::Vec3d deltaP(0.0,0.0,0.0);
+   osg::ref_ptr<osg::Vec2Array> tcoords = new osg::Vec2Array;
+ 	tcoords->reserve(numVertices);
+   geometry->setTexCoordArray( 0, tcoords.get());   
+   
+   osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
+   vertices->reserve(numVertices);
+   geometry->setVertexArray(vertices.get());
+   
+   // allocate and assign normals
+   osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
+   normals->reserve(numVertices);
+   osg::ref_ptr<osg::Vec3Array> skirtNormals = new osg::Vec3Array;
+   skirtNormals->reserve(numVertices);
+   geometry->setNormalArray(normals.get());
+   geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+   
+   // allocate and assign color
+   osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
+   (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
+   
+   geometry->setColorArray(colors.get());
+   geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
+   
+   ossimPlanetGrid::ModelPoint modelPoint;
+   osg::Vec3d norm1;
+   osg::Vec3d xyz;
+   osg::Vec3d localXYZ;
+   ossimPlanetGrid::LocalNdcPoint localPoint;
+   const ossimPlanetTerrainTileId tileId = theTerrainTile->tileId();
+   typedef std::vector<int> Indices;
+   Indices indices(numVertices, -1);
+   osg::Vec3d centerBox = buffer.theCenterPatch;
+   ossim_uint32 elevIdx = 0;
+   // double minHeight = 1.0/FLT_EPSILON;
+   // double maxHeight = -minHeight;
+   double elevationExaggeration = theTerrainTile->terrain()->elevationExaggeration();
+   if(elevationImage.valid()&&(elevationImage->hasMinMax()))
+   {
+      // minHeight = (elevationImage->minValue()[0]*elevationExaggeration)*theModel->getInvNormalizationScale();
+      // maxHeight = (elevationImage->maxValue()[0]*elevationExaggeration)*theModel->getInvNormalizationScale();
+   }
+   else
+   {
+      // minHeight = 0.0;
+      // maxHeight = 0.0;
+   }
+#if 0
+   std::cout << "minHeight = " << minHeight << std::endl;
+   std::cout << "maxHeight = " << maxHeight << std::endl;
+   std::cout << "w = " << numCols << std::endl;
+   std::cout << "h = " << numRows << std::endl;
+   std::cout << "padding = " << padding << std::endl;
+#endif
+   ossim_uint32 baseIdx = 0;
+   unsigned int iv = 0;
+   double txInc = 1.0/(numCols-1.0);
+   double tyInc = 1.0/(numRows-1.0);
+   double ty = 0.0;
+   osgUtil::Simplifier::IndexList pointsToProtect;
+   for(rowIdx = 0; rowIdx < numRows;++rowIdx)
+   {
+      double tx = 0.0;
+      localPoint.setY(ty);//(double)(rowIdx)/(double)(numRows-1));
+      for(colIdx = 0; colIdx < numCols;++colIdx)
+      {
+         // if(elevationData)
+         if(elevationImage.valid())
+         {
+            double h = elevationImage->elevationValue(colIdx+padding, rowIdx+padding);
+            if((h == OSSIMPLANET_NULL_HEIGHT)||
+               (ossim::isnan(h)))
+            {
+               h = 0;
+            }
+            else
+            {
+               h*=elevationExaggeration;
+            }
+            //            if(h < minHeight) minHeight = h;
+            //            if(h > maxHeight) maxHeight = h;
+            localPoint.setZ(h);
+         }
+         //rowIdx*numCols + colIdx;
+         indices[iv] = vertices->size();
+         if((colIdx == 0)||(rowIdx==0)||(rowIdx==(numRows-1)) || (colIdx == (numCols-1)))
+         {
+            pointsToProtect.push_back(indices[iv]);
+         }
+         localPoint.setX(tx);//(double)(colIdx)/(double)(numCols-1));
+         tcoords->push_back(osg::Vec2d(tx, ty));//osg::Vec2d(localPoint.x(), localPoint.y()));
+         theGrid->localNdcToModel(tileId, localPoint, modelPoint);
+         osg::Vec3d llh(modelPoint.y(), modelPoint.x(), modelPoint.z());
+         theModel->forward(llh, xyz);
+#if 1
+         deltaP     = (xyz-centerBox);
+         upDelta    = deltaP*upAxis;
+         rightDelta = deltaP*rightAxis;
+         normDelta  = deltaP*centerNormal;
+         
+         if(normDelta < normalDistance[1]) normalDistance[1] = normDelta;
+         if(normDelta > normalDistance[0]) normalDistance[0] = normDelta;
+         if(upDelta < upDistance[1]) upDistance[1] = upDelta; 
+         if(upDelta > upDistance[0]) upDistance[0] = upDelta;
+         if(rightDelta < rightDistance[1]) rightDistance[1] = rightDelta; 
+         if(rightDelta > rightDistance[0]) rightDistance[0] = rightDelta;
+#endif
+         localXYZ = xyz*inverseLocalToWorld;
+         (*vertices).push_back(localXYZ);
+         theModel->normal(xyz,
+                          norm1);
+         osg::Vec3d tempNorm(norm1);
+         norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+         norm1.normalize();
+         // first push gravitational normal for skirts so they point straight down
+         (*skirtNormals).push_back(norm1);
+         
+         // now calculate a perturbed normal using the elevation grids
+         //
+         if(elevationImage.valid())
+         {
+            osg::Vec2d normDeltas;
+            osg::Matrixd tempLocalToWorld;
+            theModel->lsrMatrix(osg::Vec3d(llh[0],
+                                           llh[1],
+                                           llh[2]),
+                                tempLocalToWorld);
+            osg::Vec3d xAxis(tempLocalToWorld(0,0), tempLocalToWorld(0,1), tempLocalToWorld(0,2));
+            osg::Vec3d yAxis(tempLocalToWorld(1,0), tempLocalToWorld(1,1), tempLocalToWorld(1,2));
+            osg::Vec3d zAxis(tempLocalToWorld(2,0), tempLocalToWorld(2,1), tempLocalToWorld(2,2));
+            osg::Matrixd composite = tempLocalToWorld*inverseLocalToWorld;
+            normDeltas = elevationImage->deltas(colIdx+padding, rowIdx+padding);
+            normDeltas = normDeltas*elevationExaggeration;
+            normDeltas[0]/=(metersPerPixel[0]);
+            normDeltas[1]/=(metersPerPixel[1]);
+            normDeltas[0] *=theModel->getInvNormalizationScale();
+            normDeltas[1] *=theModel->getInvNormalizationScale();
+            tempNorm = osg::Vec3d(-normDeltas[0], -normDeltas[1], theModel->getInvNormalizationScale());
+            tempNorm.normalize();
+            norm1 = zAxis*tempNorm[2] + xAxis*tempNorm[0] + yAxis*tempNorm[1];
+            norm1 = osg::Matrixd::transform3x3(localToWorld, norm1);
+            norm1.normalize();
+         }
+         // push perturbed normal.
+         (*normals).push_back(norm1);
+#if 0      
+         deltaP     = (centerBox-centerBox);
+         upDelta    = deltaP*upAxis;
+         rightDelta = deltaP*rightAxis;
+         normDelta  = deltaP*centerNormal;
+         
+         if(normDelta < normalDistance[1]) normalDistance[1] = normDelta;
+         if(normDelta > normalDistance[0]) normalDistance[0] = normDelta;
+         if(upDelta < upDistance[1]) upDistance[1] = upDelta; 
+         if(upDelta > upDistance[0]) upDistance[0] = upDelta;
+         if(rightDelta < rightDistance[1]) rightDistance[1] = rightDelta; 
+         if(rightDelta > rightDistance[0]) rightDistance[0] = rightDelta;
+#endif
+         ++elevIdx;
+         ++iv;
+         tx+=txInc;
+      }
+      ty += tyInc;
+   }
+#if 0
+   osg::Vec3d bbp0 = (*vertices)[0];
+   osg::Vec3d bbp1 = (*vertices)[numCols-1];
+   osg::Vec3d bbp2 = (*vertices)[(numRows-1)*numCols + numCols-1];
+   osg::Vec3d bbp3 = (*vertices)[(numRows-1)*numCols];
+   osg::Vec3d bboxCenter;
+   osg::Vec3d bboxNormal;
+   osg::Vec2d bboxNormalDistance;
+   bboxNormalDistance[0] = 0.0;
+   bboxNormalDistance[1] = 0.0;
+   
+   averageNormal(bboxCenter, bboxNormal,
+                 bbp0,
+                 bbp1,
+                 bbp2,
+                 bbp3);
+   ossim_uint32 idx = 0;
+   osg::Vec3d tempPoint;
+   double projValue = 0.0;
+   for(idx = 0; idx < (*vertices).size();++idx)
+   {
+      tempPoint = osg::Vec3d((*vertices)[idx])-bboxCenter;
+      projValue = tempPoint*bboxNormal;
+      if(projValue > bboxNormalDistance[0]) bboxNormalDistance[0] = projValue;
+      if(projValue < bboxNormalDistance[1]) bboxNormalDistance[1] = projValue;
+   }
+#endif
+   osg::ref_ptr<ossimPlanetBoundingBox> box = new ossimPlanetBoundingBox();
+   //   box->extrude(bbp0, 
+   //                bbp1, 
+   //                bbp2, 
+   //                bbp3,
+   //                bboxNormal, 
+   //                bboxNormalDistance);
+   box->extrude(centerBox,//buffer.theCenterPatch,
+                upAxis,
+                rightAxis,
+                centerNormal,
+                upDistance,
+                rightDistance,
+                normalDistance);
+   // double defaultDeltaHeight = fabs(normalDistance[0] - normalDistance[1]);
+   box->transform(inverseLocalToWorld);
+   
+   buffer.theTransform->setMatrix(localToWorld);
+   
+   // now lit's do the skirt if enabled
+   // for now it's always enabled but will add a flag later to turn it off and 
+   // on
+   //
+   osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*skirtNormals));
+   // let do bottom part
+   //
+   
+   osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES));
+   osg::Geometry::PrimitiveSetList primSetList;
+   ossim_uint32 i = 0;
+   ossim_uint32 j = 0;
+   
+#if 0
+   for(j = 0; j < numRows-1;++j)
+   {
+      for(i = 0; i < numCols-1; ++i)
+      {
+         int i00;
+         int i01;
+         i00 = j*numCols + i;
+         i01 = i00+numCols;
+         
+         int i10 = i00+1;
+         int i11 = i01+1;
+         
+         // remap indices to final vertex positions
+         i00 = indices[i00];
+         i01 = indices[i01];
+         i10 = indices[i10];
+         i11 = indices[i11];
+         
+         if(i!=j)
+         {
+            drawElements.push_back(i10);
+            drawElements.push_back(i01);
+            drawElements.push_back(i00);
+            
+            drawElements.push_back(i10);
+            drawElements.push_back(i11);
+            drawElements.push_back(i01);
+         }
+         else
+         {
+            drawElements.push_back(i01);
+            drawElements.push_back(i00);
+            drawElements.push_back(i11);
+            
+            drawElements.push_back(i00);
+            drawElements.push_back(i10);
+            drawElements.push_back(i11);
+         }
+         
+      }
+   }
+#else
+   for(i = 1; i < numRows;i+=2)
+   {
+      for(j = 1; j < numCols;j+=2)
+      {
+         ossim_uint32 i00 = (i)*numCols + j;
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numCols+1));
+         drawElements.push_back(i00 - (numCols));
+         
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numCols));
+         drawElements.push_back(i00 - (numCols-1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - (numCols-1));
+         drawElements.push_back(i00 + 1);
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + 1);
+         drawElements.push_back(i00 + (numCols+1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numCols+1));
+         drawElements.push_back(i00 + (numCols));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numCols));
+         drawElements.push_back(i00 + (numCols-1));
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 + (numCols-1));
+         drawElements.push_back(i00 - 1);
+         
+         drawElements.push_back(i00);
+         drawElements.push_back(i00 - 1);
+         drawElements.push_back(i00 - (numCols+1));
+      }
+   }
+#endif
+   primSetList.push_back(&drawElements);
+	geometry->setPrimitiveSetList(primSetList);
+   //osgUtil::Simplifier simplifier(.8);
+   //simplifier.simplify(*geometry, pointsToProtect);
+   geometry->dirtyBound();
+   geometry->getBound();
+   thePatchBound = buffer.theTransform->getBound();
+   ossimPlanetGrid::ModelPoint centerModelPoint;
+   theGrid->centerModel(theTerrainTile->tileId(), centerModelPoint);
+   theModel->latLonHeightToXyz(osg::Vec3d(centerModelPoint.y(), centerModelPoint.x(), 0.0), theCenterGrid);
+
+   buffer.theClusterCullingCallback->computeFrom(geometry);
+   //smoothGeometry();
+   buffer.theCullNode = new CullNode(theTerrainTile->tileId(),
+                                     box.get(),
+                                     buffer.theClusterCullingCallback->getControlPoint(),
+                                     buffer.theClusterCullingCallback->getNormal(),
+                                     (double)buffer.theClusterCullingCallback->getDeviation(),
+                                     (double)buffer.theClusterCullingCallback->getRadius());
+   buffer.theCullNode->setMatrix(buffer.theTransform->getMatrix());
+   buffer.theCullNode->dirtyBound();
+   ossim_uint32 c = 0;
+   ossim_uint32 r = 0;
+   ossim_float32 bottomSkirtHeight = buffer.theTransform->getBound().radius()*skirtScale;
+   ossim_float32 rightSkirtHeight  = bottomSkirtHeight;
+   ossim_float32 topSkirtHeight    = bottomSkirtHeight;
+   ossim_float32 leftSkirtHeight   = bottomSkirtHeight;
+   
+#if 0
+   if(elevationData)
+   {
+      // bottom variance
+      ossim_int32 i = indices[numCols>>1]; // index of original vertex of grid
+      osg::Vec3d centerEdgeNormal = (*normals)[i];
+      osg::Vec3d centerControlPoint = (*vertices)[i];
+      ossim_float32 heightValue = 0.0;
+      minHeight = 1.0/FLT_EPSILON;
+      maxHeight = -minHeight;
+      ossim_float32 heightVariance = 0.0;
+      for(c = 0; c < numCols; ++c)
+      {
+         i = indices[c]; // index of original vertex of grid
+         heightValue = ((*vertices)[i]-centerControlPoint)*centerEdgeNormal;
+         if(maxHeight < heightValue) maxHeight = heightValue;
+         if(minHeight > heightValue) minHeight = heightValue;
+      }
+      heightVariance = (maxHeight-minHeight);///theModel->getNormalizationScale();
+      bottomSkirtHeight = heightVariance;//ossim::max(bottomSkirtHeight, heightVariance);
+      
+      // right variance
+      //
+      minHeight = 1.0/FLT_EPSILON;
+      maxHeight = -minHeight;
+      baseIdx = numCols-1;
+      i = indices[baseIdx + numCols*(numRows>>1)];
+      centerEdgeNormal = (*normals)[i];
+      centerControlPoint = (*vertices)[i];
+      for(r = 0; r < numRows; ++r)
+      {
+         i = indices[baseIdx]; // index of original vertex of grid
+         heightValue = ((*vertices)[i]-centerControlPoint)*centerEdgeNormal;
+         if(maxHeight < heightValue) maxHeight = heightValue;
+         if(minHeight > heightValue) minHeight = heightValue;
+         baseIdx+=numCols;
+      }
+      heightVariance = (maxHeight-minHeight);///theModel->getNormalizationScale();
+      rightSkirtHeight = heightVariance;//ossim::max(rightSkirtHeight, heightVariance);
+      
+      // top variance
+      //
+      minHeight = 1.0/FLT_EPSILON;
+      maxHeight = -minHeight;
+      baseIdx = numCols*(numRows-1);
+      i = indices[baseIdx + (numCols>>1)];
+      centerEdgeNormal = (*normals)[i];
+      centerControlPoint = (*vertices)[i];
+      for(c = 0; c < numCols; ++c)
+      {
+         i = indices[baseIdx]; // index of original vertex of grid
+         heightValue = ((*vertices)[i]-centerControlPoint)*centerEdgeNormal;
+         if(maxHeight < heightValue) maxHeight = heightValue;
+         if(minHeight > heightValue) minHeight = heightValue;
+         ++baseIdx;
+      }
+      heightVariance = (maxHeight-minHeight);
+      topSkirtHeight = heightVariance;//ossim::max(topSkirtHeight, heightVariance);
+      
+      // left variance
+      //
+      minHeight = 1.0/FLT_EPSILON;
+      maxHeight = -minHeight;
+      baseIdx = 0;
+      i = indices[baseIdx + numCols*(numRows>>1)];
+      centerEdgeNormal   = (*normals)[i];
+      centerControlPoint = (*vertices)[i];
+      for(r = 0; r < numRows; ++r)
+      {
+         i = indices[baseIdx]; // index of original vertex of grid
+         heightValue = ((*vertices)[i]-centerControlPoint)*centerEdgeNormal;
+         if(maxHeight < heightValue) maxHeight = heightValue;
+         if(minHeight > heightValue) minHeight = heightValue;
+         baseIdx += numCols;
+      }
+      heightVariance = (maxHeight-minHeight);
+      leftSkirtHeight = heightVariance;//ossim::max(leftSkirtHeight, heightVariance);
+   }
+#endif
+   ossim_uint32 skirtFlags = computeSkirtFlags(theTerrainTile->tileId());
+   if(skirtFlags&BOTTOM_SKIRT)
+   {
+      // let's do the bottom skirt first
+      //
+      r = 0;
+      for(c = 0; c < numCols; ++c)
+      {
+         ossim_uint32 idx = c;//numCols+c;
+         ossim_int32 orig_i = indices[idx]; // index of original vertex of grid
+         unsigned int new_i = vertices->size(); // index of new index of added skirt point
+         osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*bottomSkirtHeight;
+         (*vertices).push_back(new_v);
+         (*normals).push_back((*normals)[orig_i]);
+         
+         tcoords->push_back((*tcoords)[orig_i]);
+         if(((c % 2) == 0)&&
+            (c>0))
+         {
+            drawElements.push_back(indices[idx-2]);
+            drawElements.push_back(new_i-2);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(indices[idx-1]);
+            drawElements.push_back(indices[idx-2]);
+            
+            drawElements.push_back(indices[idx-1]);
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(new_i);
+            
+            drawElements.push_back(new_i);
+            drawElements.push_back(indices[idx]);
+            drawElements.push_back(indices[idx-1]);
+         }
+      }
+   }
+   if(skirtFlags&RIGHT_SKIRT)
+   {
+      // now let's do right Skirt
+      //
+      baseIdx = numCols-1;
+      for(r = 0; r < numRows; ++r)
+      {
+         ossim_int32 orig_i = indices[baseIdx]; // index of original vertex of grid
+         unsigned int new_i = vertices->size(); // index of new index of added skirt point
+         osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*rightSkirtHeight;
+         (*vertices).push_back(new_v);
+         (*normals).push_back((*normals)[orig_i]);
+         tcoords->push_back((*tcoords)[orig_i]);
+         if(((r % 2) == 0)&&
+            (r>0))
+         {
+            drawElements.push_back(indices[baseIdx-(numCols<<1)]);
+            drawElements.push_back(new_i-2);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(indices[baseIdx-numCols]);
+            drawElements.push_back(indices[baseIdx-(numCols<<1)]);
+            
+            drawElements.push_back(indices[baseIdx-numCols]);
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(new_i);
+            
+            drawElements.push_back(new_i);
+            drawElements.push_back(indices[baseIdx]);
+            drawElements.push_back(indices[baseIdx-numCols]);
+         }         
+         baseIdx+=numCols;
+      }
+   }
+   
+   if(skirtFlags&TOP_SKIRT)
+   {
+      // top skirt
+      baseIdx = numCols*(numRows-1);
+      for(c = 0; c < numCols; ++c)
+      {
+         ossim_int32 orig_i = indices[baseIdx]; // index of original vertex of grid
+         unsigned int new_i = vertices->size(); // index of new index of added skirt point
+         osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*topSkirtHeight;
+         (*vertices).push_back(new_v);
+         (*normals).push_back((*normals)[orig_i]);
+         tcoords->push_back((*tcoords)[orig_i]);
+         if(((c % 2) == 0)&&
+            (c>0))
+         {
+            drawElements.push_back(indices[baseIdx-2]);
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(new_i-2);
+            
+            drawElements.push_back(indices[baseIdx-2]);
+            drawElements.push_back(indices[baseIdx-1]);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(indices[baseIdx-1]);
+            drawElements.push_back(new_i);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(indices[baseIdx]-1);
+            drawElements.push_back(indices[baseIdx]);
+            drawElements.push_back(new_i);
+         }
+         
+         ++baseIdx;
+      }
+   }
+   
+   if(skirtFlags&LEFT_SKIRT)
+   {
+      // now do left skirt
+      //
+      baseIdx = 0;
+      for(r = 0; r < numRows; ++r)
+      {
+         ossim_int32 orig_i = indices[baseIdx]; // index of original vertex of grid
+         unsigned int new_i = vertices->size(); // index of new index of added skirt point
+         osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*leftSkirtHeight;
+         (*vertices).push_back(new_v);
+         (*normals).push_back((*normals)[orig_i]);
+         tcoords->push_back((*tcoords)[orig_i]);
+         if(((r % 2) == 0)&&
+            (r>0))
+         {
+            drawElements.push_back(indices[baseIdx-(numCols<<1)]);
+            drawElements.push_back(new_i-1);
+            drawElements.push_back(new_i-2);
+            
+            drawElements.push_back(indices[baseIdx-(numCols<<1)]);
+            drawElements.push_back(indices[baseIdx-numCols]);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(indices[baseIdx-numCols]);
+            drawElements.push_back(new_i);
+            drawElements.push_back(new_i-1);
+            
+            drawElements.push_back(indices[baseIdx-numCols]);
+            drawElements.push_back(indices[baseIdx]);
+            drawElements.push_back(new_i);
+         }    
+         baseIdx += numCols;
+      }
+   }
+#if 0
+   osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES));
+   osg::Geometry::PrimitiveSetList primSetList;
+   ossim_uint32 i = 0;
+   ossim_uint32 j = 0;
+   ossim_uint32 i00 = 0;
+   ossim_uint32 i01 = 0;
+   ossim_uint32 i10 = 0;
+   ossim_uint32 i11 = 0;
+   bool swapOrientation = theTerrainTile->tileId().face() > 3;
+   for(j = 0; j < numRows-1;++j)
+   {
+      for(i = 0; i < numCols-1;++i)
+      {
+         //         if (swapOrientation)
+         //         {
+         //            i01 = j*numCols + i;
+         //            i00 = i01+numCols;
+         //         }
+         //         else
+         //         {
+         i00 = j*numCols + i;
+         i01 = i00+numCols;
+         //         }
+         i10 = i00+1;
+         i11 = i01+1;
+         //         i00 = indices[i00];
+         //         i01 = indices[i01];
+         //         i10 = indices[i10];
+         //         i11 = indices[i11];
+         if(!swapOrientation)
+         {
+            drawElements.push_back(i01);
+            drawElements.push_back(i00);
+            drawElements.push_back(i11);
+            
+            drawElements.push_back(i00);
+            drawElements.push_back(i10);
+            drawElements.push_back(i11);
+         }
+         else
+         {
+            drawElements.push_back(i01);
+            drawElements.push_back(i00);
+            drawElements.push_back(i10);
+            
+            drawElements.push_back(i01);
+            drawElements.push_back(i10);
+            drawElements.push_back(i11);
+            
+         }
+      }
+   }
+   primSetList.push_back(&drawElements);
+	geometry->setPrimitiveSetList(primSetList);
+#endif
+   
+   //smoothGeometry();
+   osg::ref_ptr<osg::CullFace> cullFace = new osg::CullFace;
+   geometry->getOrCreateStateSet()->setAttributeAndModes(cullFace.get(),
+                                                         osg::StateAttribute::ON);
+   //   if(theCullSettings&osg::CullSettings::CLUSTER_CULLING)
+   //   {
+   //      geometry->setCullCallback(buffer.theClusterCullingCallback.get());
+   //   }
+   geometry->setUseVertexBufferObjects(true);
+   geometry->setUseDisplayList(false);
+//   geometry->setFastPathHint(true);
+   
+   
+   if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
+       osgDB::Registry::instance()->getKdTreeBuilder())
+   {
+      
+      
+      //osg::Timer_t before = osg::Timer::instance()->tick();
+      //osg::notify(osg::NOTICE)<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
+      osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
+      buffer.theGeode->accept(*builder);
+      //std::cout << "BUILT!!" << std::endl;
+      //osg::Timer_t after = osg::Timer::instance()->tick();
+      //osg::notify(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
+   }
+   
+   buffer.theGeode->dirtyBound();
+   buffer.theTransform->dirtyBound();
+   buffer.theGeometry->dirtyBound();
+   buffer.theTransform->getBound();
+#if 0   
+   ossimPlanetTerrainTile* parent = optionalParent?optionalParent:theTerrainTile->parentTile();
+   if(theTerrainTile)
+   {
+      theTerrainTile->dirtyBound();
+      theTerrainTile->getBound();
+   }
+   // now copy cull node settings to the parent so it's always cached
+   //
+   if(parent)
+   {
+      ((ossimPlanetTerrainGeometryTechnique*)(parent->terrainTechnique()))->setChildCullParameters(theTerrainTile,
+                                                                                                   buffer.theCullNode);
+   }
+#endif
+}
+
+ossimPlanetTexture2D* ossimPlanetTerrainGeometryTechnique::findNearestActiveParentTexture(ossim_uint32 imageLayerIdx, 
+                                                                                          ossimPlanetTerrainTile* optionalParent)
+{
+   if(!theTerrainTile) return 0;
+   ossimPlanetTerrainTile* parent = optionalParent?optionalParent:theTerrainTile->parentTile();
+   ossimPlanetTerrainGeometryTechnique* currentTechnique = 
+   dynamic_cast<ossimPlanetTerrainGeometryTechnique*>(parent?parent->terrainTechnique():0);
+   ossimPlanetTexture2D* result = 0;
+   while(!result&&currentTechnique)
+   {
+      BufferData& buffer = currentTechnique->readOnlyBuffer();
+      if(buffer.theTransform.valid())
+      {
+         osg::StateSet* stateset = buffer.theGeode->getStateSet();
+         if(stateset)
+         {
+            result = dynamic_cast<ossimPlanetTexture2D*>(stateset->getTextureAttribute(imageLayerIdx, 
+                                                                                       osg::StateAttribute::TEXTURE));
+            
+            //               if(!result->getImage())
+            //               {
+            //                  result = 0;
+            //               }
+         }
+         parent = parent->parentTile();
+         if(parent)
+         {
+            currentTechnique = dynamic_cast<ossimPlanetTerrainGeometryTechnique*>(parent->terrainTechnique());
+         }
+         else
+         {
+            currentTechnique = 0;
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimPlanetTerrainGeometryTechnique::applyColorLayers(ossimPlanetTerrainTile* optionalParent)
+{
+   if(!theTerrainTile) return;
+   BufferData& buffer = writeBuffer();
+   if(!buffer.theTransform.valid()) return;
+   typedef std::map<ossimPlanetTerrainLayer*, osg::ref_ptr<osg::Texture> > LayerToTextureMap;
+   LayerToTextureMap layerToTextureMap;
+   
+   ossim_uint32 imageLayerIdx = 0;
+   for(imageLayerIdx=0; imageLayerIdx<theTerrainTile->numberOfImageLayers(); ++imageLayerIdx)
+   {
+      ossimPlanetTerrainImageLayer* imageLayer = theTerrainTile->imageLayer(imageLayerIdx);
+      if (!imageLayer) continue;
+      osg::ref_ptr<ossimPlanetImage> image = imageLayer->image();
+      
+      osg::ref_ptr<ossimPlanetTexture2D> borrowedTexture = 0;
+      if (!image) 
+      {
+         borrowedTexture = findNearestActiveParentTexture(imageLayerIdx, optionalParent);
+         //std::cout << theTerrainTile->tileId().level() << " TRYING TO BORROW\n";
+         //std::cout << borrowedTexture.get() << std::endl;
+         // borrow gl texture from parent
+         //
+         if(!borrowedTexture) continue;
+      }
+      osg::ref_ptr<osg::StateSet> stateset = buffer.theGeode->getOrCreateStateSet();
+      osg::ref_ptr<ossimPlanetTexture2D> texture2D = borrowedTexture.get();//borrowedTexture.valid()?borrowedTexture.get():
+      //dynamic_cast<ossimPlanetTexture2D*>(layerToTextureMap[imageLayer].get());
+      imageLayer->setDirtyFlag(false);
+      
+      if(!texture2D)
+      {
+         texture2D = dynamic_cast<ossimPlanetTexture2D*>(stateset->getTextureAttribute(imageLayerIdx, 
+                                                                                       osg::StateAttribute::TEXTURE));
+         if(!texture2D)
+         {
+            texture2D = newImageLayerTexture(imageLayerIdx);
+            imageLayer->setDirtyFlag(false);
+         }
+         else if(image.valid())
+         {
+            if(texture2D->tileId().level()!=image->tileId().level())
+            {
+               texture2D = newImageLayerTexture(imageLayerIdx);
+               imageLayer->setDirtyFlag(false);
+            }
+         }
+      }
+      if(texture2D.valid()&&!borrowedTexture.valid())
+      {
+         texture2D->setFilter(osg::Texture::MIN_FILTER, imageLayer->minFilter());
+         texture2D->setFilter(osg::Texture::MAG_FILTER, imageLayer->magFilter());
+      }
+      //layerToTextureMap[imageLayer] = texture2D.get();
+      stateset->setTextureAttributeAndModes(imageLayerIdx, texture2D.get(), osg::StateAttribute::ON);
+      
+      updateTextureMatrix(stateset.get(), imageLayerIdx, theTerrainTile->tileId(),  texture2D->tileId());
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::applyTransparency(ossimPlanetTerrainTile* /* optionalParent */)
+{
+   BufferData& buffer = writeBuffer();
+   
+   bool containsTransparency = false;
+   ossim_uint32 colorLayerIdx = 0;
+   for(colorLayerIdx=0; colorLayerIdx<theTerrainTile->numberOfImageLayers(); ++colorLayerIdx)
+   {
+      ossimPlanetTerrainImageLayer* colorLayer = theTerrainTile->imageLayer(colorLayerIdx);
+      if (!colorLayer) continue;
+      
+      osg::ref_ptr<osg::Image> image = colorLayer->image();
+      if (image.valid())
+      {
+         containsTransparency = image->isImageTranslucent();
+         break;
+      }        
+   }
+   
+   if (containsTransparency&&buffer.theGeode.valid())
+   {
+      osg::StateSet* stateset = buffer.theGeode->getOrCreateStateSet();
+      stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
+      stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::init(ossimPlanetTerrainTile* optionalParent)
+{
+   if(!theTerrainTile) return;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildNodeCullParametersMutex);
+      if(!theChildNodeCullParameters.size())
+      {
+         theChildNodeCullParameters.resize(4);
+      }
+   }
+   if(!readOnlyBuffer().theTransform.valid()) // we need to do a full init and swap
+   {
+      buildMesh(optionalParent);
+      applyColorLayers(optionalParent);
+      applyTransparency(optionalParent);
+      swapBuffers();
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::childAdded(ossim_uint32 pos)
+{
+   ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(theTerrainTile->getChild(pos));
+   
+   if(tile)
+   {
+      // ossimPlanetTerrainGeometryTechnique* technique = dynamic_cast<ossimPlanetTerrainGeometryTechnique*>(tile->terrainTechnique());
+      
+      // now lets default to a lower resolution texture for
+      // any image layers that have not been initialized
+      //
+      ossim_uint32 idx = 0;
+      ossim_uint32 numberOfImageLayers = tile->numberOfImageLayers();
+      for(idx = 0; idx < numberOfImageLayers;++idx)
+      {
+         ossimPlanetTerrainImageLayer* layer = tile->imageLayer(idx);
+         if(layer&&!layer->image())
+         {
+            ossimPlanetTexture2D* texture = findNearestActiveParentTexture(idx, tile);
+            if(texture)
+            {
+               UpdateChildTextureVisitor childTextureVisitor(texture, idx);
+               tile->accept(childTextureVisitor);
+            }
+         }
+      }
+   }
+   
+   
+   //   theTerrainTile->dirtyBound();
+   //   theTerrainTile->getBound();
+   
+}
+
+void ossimPlanetTerrainGeometryTechnique::merge()
+{
+   if(!theTerrainTile) return;
+   
+   ossimPlanetTerrainTile::MergeTestVisitor visitor(true);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theTerrainTile->getNumChildren();++idx)
+   {
+      theTerrainTile->getChild(idx)->accept(visitor);
+   }
+   if(visitor.canMerge())
+   {
+      theTerrainTile->removeChildren(0, theTerrainTile->getNumChildren());
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::removeCulledChildren()
+{
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = theChildNodeCullParameters.size();
+   for(idx = 0; idx < bound; ++idx)
+   {
+      if(theChildNodeCullParameters[idx].valid())
+      {
+         
+         ossimPlanetTerrainTile* tile = theTerrainTile->child(theChildNodeCullParameters[idx]->tileId());
+         if(tile&&theChildNodeCullParameters[idx]->isCulled())
+         {
+            theTerrainTile->removeChild(tile);
+         }
+      }
+   }
+}
+
+bool ossimPlanetTerrainGeometryTechnique::hasCulledChildren()const
+{
+   if(theTerrainTile->getNumChildren() < 1) return false;
+   ossim_uint32 idx = 0;
+   ossim_uint32 bounds = theTerrainTile->getNumChildren();
+   for(idx = 0; idx < bounds; ++idx)
+   {
+      const ossimPlanetTerrainTile* tile = dynamic_cast<const ossimPlanetTerrainTile*>(theTerrainTile->getChild(idx));
+      if(tile)
+      {
+         if(tile->culledFlag()) return true;
+      }
+   }
+   
+   return false;   
+}
+
+
+bool ossimPlanetTerrainGeometryTechnique::isChildCulled(ossim_uint32 childIdx)const
+{
+   if(theChildNodeCullParameters[childIdx].valid())
+   {
+      return theChildNodeCullParameters[childIdx]->isCulled();
+   }
+   
+   return false;
+}
+
+double ossimPlanetTerrainGeometryTechnique::texturePriority()const
+{
+   if(!theTerrainTile) return 0.0;
+   
+   // const BufferData& buffer = readOnlyBuffer();
+   double result = 0.0;
+   // double distance = 0.0;
+  // result = (thePriorityPoint - thePatchBound.center()).length();
+
+   result =(thePriorityPoint-theCenterGrid).length();
+
+   result = -result;
+
+    return result;
+}
+
+double ossimPlanetTerrainGeometryTechnique::elevationPriority()const
+{
+   return texturePriority();
+}
+
+double ossimPlanetTerrainGeometryTechnique::mergePriority()const
+{
+   return texturePriority();
+}
+
+double ossimPlanetTerrainGeometryTechnique::splitPriority()const
+{
+   return texturePriority();
+}
+
+void ossimPlanetTerrainGeometryTechnique::smoothGeometry()
+{
+   BufferData& buffer = writeBuffer();
+   
+   if (buffer.theGeometry.valid())
+   {
+      osgUtil::SmoothingVisitor smoother;
+      smoother.smooth(*buffer.theGeometry);
+   }
+}
+
+osg::BoundingSphere ossimPlanetTerrainGeometryTechnique::computeBound() const
+{
+   const BufferData& buffer = readOnlyBuffer();
+   if(buffer.theTransform.valid())
+   {
+      return readOnlyBuffer().theTransform->getBound();
+   }
+   return osg::BoundingSphere(osg::Vec3d(0.0,0.0,0.0), -1);
+   
+}
+
+bool ossimPlanetTerrainGeometryTechnique::isCulled(BufferData& buffer, osgUtil::CullVisitor* cv)const
+{
+   if(cv->getCullingMode() == osg::CullSettings::NO_CULLING) return false;
+   
+   buffer.theCullNode->accept(*cv);
+   bool result = buffer.theCullNode->isCulled();
+   if(!result)
+   {
+      result = cv->isCulled(thePatchBound);
+   }
+   return result;
+}
+
+void ossimPlanetTerrainGeometryTechnique::setChildCullParameters(ossimPlanetTerrainTile* tile,
+                                                                 osg::ref_ptr<CullNode> cullNode)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildNodeCullParametersMutex);
+      
+      if(theChildNodeCullParameters.size() != 4)
+      {
+         theChildNodeCullParameters.resize(4);
+      }
+      ossim_uint32 idx = childIndex(tile->tileId());
+      // this is a quad tree so look at eve odd values.
+      //
+      if(idx < theChildNodeCullParameters.size())
+      {
+         theChildNodeCullParameters[idx] = cullNode.get();
+      }      
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::markOnlyNeededChildImageLayersDirty()
+{
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = theTerrainTile->getNumChildren();
+   
+   for(idx = 0; idx < bound; ++idx)
+   {
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(theTerrainTile->getChild(idx));
+      if(tile)
+      {
+         ossim_uint32 idxLayer = 0;
+         ossim_uint32 imageLayerBound = tile->numberOfImageLayers();
+         for(idxLayer = 0; idxLayer < imageLayerBound; ++idxLayer)
+         {
+            //if(theTerrainTile->imageLayer(idxLayer)->isDirty())
+            {
+               osg::ref_ptr<ossimPlanetImage> image = tile->imageLayer(idxLayer)->image();
+               
+               // if he is borrowing from a parent Texture make sure he get's reset
+               //
+               if(!image || (image->tileId().level()!=tile->tileId().level()))
+               {
+                  tile->imageLayer(idxLayer)->setDirtyFlag(true);
+               }
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::updateElevationMesh()
+{
+   BufferData& buffer = writeBuffer();
+   osg::ref_ptr<osg::StateSet> stateset;
+   if(buffer.theGeode.valid())
+   {
+      stateset = buffer.theGeode->getStateSet();
+   }
+   buildMesh();
+   if(stateset.valid())
+   {
+      if(stateset.valid()&&buffer.theGeode.valid())
+      {
+         buffer.theGeode->setStateSet(stateset.get());
+      }
+   }
+}
+
+ossimPlanetTexture2D* ossimPlanetTerrainGeometryTechnique::newImageLayerTexture(ossim_uint32 imageLayerIdx)
+{
+   ossimPlanetTexture2D* texture2D = new ossimPlanetTexture2D;
+   osg::ref_ptr<ossimPlanetImage> image;
+   ossimPlanetTerrainImageLayer* layer =0;
+   if(theTerrainTile)
+   {
+      layer = theTerrainTile->imageLayer(imageLayerIdx);
+      if(layer)
+      {
+         image = layer->image();
+      }
+   }
+   if(image.valid())
+   {
+      texture2D->setImage(image.get());
+   }
+   // texture2D->setMaxAnisotropy(16.0f);
+   texture2D->setResizeNonPowerOfTwoHint(false);
+   if(layer)
+   {
+      texture2D->setFilter(osg::Texture2D::MIN_FILTER,layer->minFilter());
+      texture2D->setFilter(osg::Texture2D::MAG_FILTER,layer->magFilter());
+   }
+   texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
+   texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
+   texture2D->setDataVariance(osg::Object::DYNAMIC);
+   texture2D->setUnRefImageDataAfterApply(false);
+   
+   return texture2D;
+}
+
+void ossimPlanetTerrainGeometryTechnique::compileGlObjects(osg::State* state)
+{
+   BufferData& buffer = readOnlyBuffer();
+   if(buffer.theGeode.valid())
+   {
+      ossimPlanetTerrainTechnique::CompileObjects visitor;
+      visitor.setState(state);
+      buffer.theTransform->accept(visitor);
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::setImageLayerTexture(ossimPlanetTexture2D* texture, 
+                                                               ossim_uint32 imageLayerIdx)
+{
+   BufferData& buffer = readOnlyBuffer();
+   if(texture&&buffer.theGeode.valid())
+   {
+      osg::StateSet* stateset = buffer.theGeode->getOrCreateStateSet();
+      if(texture->tileId().level() == theTerrainTile->tileId().level())
+      {
+         ossimPlanetImage* image = dynamic_cast<ossimPlanetImage*>(texture->getImage());
+         if(image)
+         {
+            ossimPlanetTerrainImageLayer* imageLayer = theTerrainTile->imageLayer(imageLayerIdx);
+            if(imageLayer)
+            {
+               imageLayer->setImage(image);
+               imageLayer->setDirtyFlag(false);
+               imageLayer->setRefreshFlag(false);
+            }
+         }
+      }
+      if(stateset)
+      {
+         stateset->setTextureAttributeAndModes(imageLayerIdx, texture, osg::StateAttribute::ON);
+         updateTextureMatrix(stateset, imageLayerIdx, theTerrainTile->tileId(),  texture->tileId());
+      }
+      UpdateChildTextureVisitor visitor(texture, imageLayerIdx);
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theTerrainTile->getNumChildren();++idx)
+      {
+         theTerrainTile->getChild(idx)->accept(visitor);
+      }
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::updateTextureMatrix(osg::StateSet* stateset, 
+                                                              ossim_uint32 imageLayerIdx,
+                                                              const ossimPlanetTerrainTileId& startId,
+                                                              const ossimPlanetTerrainTileId& endId)
+{
+   if(startId.level() != endId.level())
+   {
+      osg::Matrixd texMat;
+      solveTextureMatrixMappingToParent(startId, endId, texMat);
+      osg::TexMat* texMatAttribute = new osg::TexMat(texMat);
+      stateset->setTextureAttributeAndModes(imageLayerIdx, texMatAttribute, osg::StateAttribute::ON);
+   }
+   else
+   {
+      stateset->removeTextureAttribute(imageLayerIdx, osg::StateAttribute::TEXMAT);
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::setElevationMeshFrom(ossimPlanetTerrainTile* tile)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTerrainTileMutex);
+   
+   if(tile&&theTerrainTile)
+   {
+      ossimPlanetTerrainGeometryTechnique* geometryTechnique = dynamic_cast<ossimPlanetTerrainGeometryTechnique*>(tile->terrainTechnique());
+      osg::ref_ptr<ossimPlanetImage> elevation = tile->elevationLayer()->image();
+      if(geometryTechnique)
+      {
+         BufferData& bufferFrom = geometryTechnique->readOnlyBuffer();
+         
+         BufferData& bufferTo = writeBuffer();
+         
+         if(bufferFrom.theTransform.valid())
+         {
+            if(theTerrainTile->elevationLayer()&&elevation.valid())
+            {
+               theTerrainTile->elevationLayer()->setImage(elevation.get());
+               theTerrainTile->elevationLayer()->setDirtyFlag(false);
+               theTerrainTile->elevationLayer()->setRefreshFlag(false);
+            }
+            bufferTo.theClusterCullingCallback = bufferFrom.theClusterCullingCallback;
+            osg::ref_ptr<osg::StateSet> bufferToTransformStateSet = bufferTo.theTransform->getStateSet();
+            osg::ref_ptr<osg::StateSet> bufferToGeometryStateSet = bufferTo.theGeometry->getStateSet();
+            osg::ref_ptr<osg::StateSet> bufferToGeodeStateSet = bufferTo.theGeode->getStateSet();
+            
+            bufferTo.theTransform = bufferFrom.theTransform;
+            bufferTo.theGeometry  = bufferFrom.theGeometry;
+            bufferTo.theGeode     = bufferFrom.theGeode;
+            bufferTo.theCenterPatch = bufferFrom.theCenterPatch;
+            bufferTo.theClusterCullingCallback = bufferFrom.theClusterCullingCallback;
+            
+            bufferTo.theTransform->setStateSet(bufferToTransformStateSet.get());
+            bufferTo.theGeometry->setStateSet(bufferToGeometryStateSet.get());
+            bufferTo.theGeode->setStateSet(bufferToGeodeStateSet.get());
+            
+            if(theTerrainTile)
+            {
+               theTerrainTile->dirtyBound();
+               theTerrainTile->getBound();
+            }
+            // now copy cull node settings to the parent so it's always cached
+            //
+            // ossimPlanetTerrainTile* parent = theTerrainTile->parentTile();
+            swapBuffers();
+            // markOnlyNeededChildImageLayersDirty();
+         }
+      }
+   }
+}
+
+void ossimPlanetTerrainGeometryTechnique::vacantChildIds(TileIdList& ids)const
+{
+   ossimPlanetTerrainTechnique::vacantChildIds(ids);
+}
+
+ossim_uint32 ossimPlanetTerrainGeometryTechnique::computeSkirtFlags(const ossimPlanetTerrainTileId& /* childId */)const
+{
+#if 1
+   return LEFT_SKIRT|RIGHT_SKIRT|BOTTOM_SKIRT|TOP_SKIRT;
+#else   
+   if(childId.level() == 0) return LEFT_SKIRT|RIGHT_SKIRT|BOTTOM_SKIRT|TOP_SKIRT;
+   ossim_uint32 result = NO_SKIRT;
+   switch(childIndex(childId))
+   {
+      case BOTTOM_LEFT: // bottom Left quadrant
+      {
+         result = BOTTOM_SKIRT|LEFT_SKIRT;
+         break;
+      }
+      case BOTTOM_RIGHT: // bottom right
+      {
+         result = BOTTOM_SKIRT|RIGHT_SKIRT;
+         break;
+      }
+      case TOP_LEFT: // top left child
+      {
+         result = TOP_SKIRT|LEFT_SKIRT;
+         break;
+      }
+      case TOP_RIGHT: // top right child
+      {
+         result = TOP_SKIRT|RIGHT_SKIRT;
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   return result;
+#endif
+}
+
+void ossimPlanetTerrainGeometryTechnique::releaseGLObjects(osg::State* state)
+{
+   BufferData& buffer = readOnlyBuffer();
+   if(buffer.theTransform.valid())
+   {
+      buffer.theTransform->releaseGLObjects(state);
+      buffer.theGeode->releaseGLObjects(state);
+      buffer.theGeometry->releaseGLObjects(state);
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainLayer.cpp
new file mode 100644
index 0000000..5335a3d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainLayer.cpp
@@ -0,0 +1 @@
+#include <ossimPlanet/ossimPlanetTerrainLayer.h>
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTechnique.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTechnique.cpp
new file mode 100644
index 0000000..8231bfb
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTechnique.cpp
@@ -0,0 +1,343 @@
+#include <ossimPlanet/ossimPlanetTerrainTechnique.h>
+#include <ossimPlanet/ossimPlanetTerrainTile.h>
+#include <queue>
+#include <osg/Timer>
+#include <osg/Geometry>
+#if ((OSG_VERSION_INT)>182)
+#define USE_OLD_VBO_COMPILE 0
+#else
+#define USE_OLD_VBO_COMPILE 1
+#endif
+
+void ossimPlanetTerrainTechnique::CompileObjects::apply(osg::Drawable& drawable)
+{
+   osg::Geometry* geometry = drawable.asGeometry();
+   if(geometry)
+   { 
+      osg::Geometry::ArrayList arrayList;
+      geometry->getArrayList(arrayList);
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < arrayList.size();++idx)
+      {
+#if 0
+         if(arrayList[idx]->getVertexBufferObject())
+         {
+            arrayList[idx]->getVertexBufferObject()->compileBuffer(*_renderInfo.getState());
+         }
+#endif
+//         if(arrayList[idx]->getVertexBufferObject())
+//         {
+//            osg::GLBufferObject* glBufferObj = arrayList[idx]->getVertexBufferObject()->getOrCreateGLBufferObject(_renderInfo.getState()->getContextID());
+//            if(glBufferObj&&glBufferObj->isDirty())
+//            {
+//               glBufferObj->compileBuffer();
+//            }
+     }
+ //     }
+   }
+   osgUtil::GLObjectsVisitor::apply(drawable);
+}
+
+void ossimPlanetTerrainTechnique::CompileObjects::apply(osg::Node& node)
+{
+   if (node.getStateSet())
+   {
+      apply(*(node.getStateSet()));
+   }
+   
+   traverse(node);
+}
+void ossimPlanetTerrainTechnique::CompileObjects::apply(osg::Geode& node)
+{
+   if (node.getStateSet())
+   {
+      apply(*(node.getStateSet()));
+   }
+   for(unsigned int i=0;i<node.getNumDrawables();++i)
+   {
+      osg::Drawable* drawable = node.getDrawable(i);
+      if (drawable)
+      {
+         apply(*drawable);
+         if (drawable->getStateSet())
+         {
+            apply(*(drawable->getStateSet()));
+         }
+      }
+   }
+   
+   // now let's compile all buffer objects
+   //
+   
+}
+
+void ossimPlanetTerrainTechnique::CompileObjects::apply(osg::StateSet& stateset)
+{
+   if (_stateSetAppliedSet.count(&stateset)!=0) return;
+   _stateSetAppliedSet.insert(&stateset);
+   
+   if (_mode & COMPILE_STATE_ATTRIBUTES && _renderInfo.getState())
+   {
+      osg::StateSet::AttributeList& attributeList = stateset.getAttributeList();
+      for(osg::StateSet::AttributeList::const_iterator itr = attributeList.begin();
+          itr!=attributeList.end();
+          ++itr)
+      {
+         itr->second.first->compileGLObjects(*_renderInfo.getState());
+      }
+      
+      for (unsigned i = 0;
+           i < stateset.getTextureAttributeList().size();
+           ++i)
+      {
+         const osg::Texture* texture
+         = dynamic_cast<const osg::Texture*>(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE));
+         if (texture && (texture->getTextureParameterDirty(_renderInfo.getContextID())||(texture->getTextureObject(_renderInfo.getContextID())==0)))
+         {
+            texture->compileGLObjects(*_renderInfo.getState());
+         }
+      }
+   }
+   if (_mode & CHECK_BLACK_LISTED_MODES)
+   {
+      stateset.checkValidityOfAssociatedModes(*_renderInfo.getState());
+   }
+}
+
+ossimPlanetTerrainTechnique::ossimPlanetTerrainTechnique()
+:theTerrainTile(0)
+{
+   setThreadSafeRefUnref(true);
+}
+ossimPlanetTerrainTechnique::ossimPlanetTerrainTechnique(const ossimPlanetTerrainTechnique& src,
+                                                         const osg::CopyOp& /* copyop */)
+:
+   theModel(src.theModel.get()), // this is just shared
+   theGrid(src.theGrid.get()),   // this is just shared
+   theTerrainTile(0)             // can't duplicate this
+{
+}
+
+ossimPlanetTerrainTechnique::~ossimPlanetTerrainTechnique()
+{
+}
+
+void ossimPlanetTerrainTechnique::setTerrainTile(ossimPlanetTerrainTile* tile)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theTerrainTileMutex);
+   theTerrainTile = tile;
+   if(theTerrainTile)
+   {
+      theTerrainTile->setCullCallback(new ossimPlanetTerrainTechnique::CullCallback());
+   }
+}
+
+void ossimPlanetTerrainTechnique::init(ossimPlanetTerrainTile* /* optionalParent */)
+{
+}
+
+void ossimPlanetTerrainTechnique::update(osgUtil::UpdateVisitor* uv)
+{
+   if (theTerrainTile) theTerrainTile->osg::Group::traverse(*uv);
+}
+
+void ossimPlanetTerrainTechnique::cull(osgUtil::CullVisitor* cv)
+{
+   if (theTerrainTile) theTerrainTile->osg::Group::traverse(*cv);
+}
+
+void ossimPlanetTerrainTechnique::traverse(osg::NodeVisitor& nv)
+{
+   if (!theTerrainTile) return;
+   
+   // if app traversal update the frame count.
+   if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
+   {
+      osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
+      if (uv)
+      {
+         update(uv);
+         return;
+      }        
+      
+   }
+   else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
+   {
+      osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
+      if (cv)
+      {
+         cull(cv);
+         return;
+      }
+   }
+   
+   // otherwise fallback to the Group::traverse()
+   theTerrainTile->osg::Group::traverse(nv);
+}
+
+bool ossimPlanetTerrainTechnique::isLeaf()const
+{
+   if(theTerrainTile)
+   {
+      return (theTerrainTile->getNumChildren() != 4);
+   }
+   
+   return true;
+}
+
+bool ossimPlanetTerrainTechnique::areAllChildrenLeaves()const
+{
+   if(!theTerrainTile) return false;
+   if(theTerrainTile->getNumChildren()!=4) return false;
+   ossim_uint32 idx;
+   ossim_uint32 bounds = theTerrainTile->getNumChildren();
+   for(idx = 1; idx < bounds; ++idx)
+   {
+      const ossimPlanetTerrainTile* tile = dynamic_cast<const ossimPlanetTerrainTile*>(theTerrainTile->getChild(idx));
+      if(tile)
+      {
+         if(!tile->terrainTechnique()->isLeaf()) return false;
+      }
+   }
+   
+   return true;
+}
+
+void ossimPlanetTerrainTechnique::vacantChildIds(TileIdList& ids)const
+{
+   if(!theTerrainTile)
+   {
+      return;
+   }
+   ossim_uint32 idx = 0;
+   const ossimPlanetTerrainTileId& srcId = theTerrainTile->tileId();
+   ossim_uint32 nextLevel = srcId.level()+1;
+   for(idx = 0; idx < 4; ++idx)
+   {
+      ossim_uint32 xOrigin=srcId.x()<<1;
+      ossim_uint32 yOrigin=srcId.y()<<1;
+      if(idx == 1)
+      {
+         ++xOrigin;
+      }
+      else if(idx == 2)
+      {
+         ++yOrigin;
+      }
+      else if(idx == 3)
+      {
+         ++xOrigin;
+         ++yOrigin;
+      }
+      ossimPlanetTerrainTileId tileId(srcId.face(),
+                                      nextLevel,
+                                      xOrigin,
+                                      yOrigin);     
+      if(!theTerrainTile->child(tileId))
+      {
+         ids.push_back(tileId);
+      }
+   }
+}
+
+void ossimPlanetTerrainTechnique::merge()
+{
+   if(theTerrainTile)
+   {
+      // we really need to go through the sub tree and free each one or 
+      // remove from parent
+      //
+   }
+}
+
+ossim_uint32 ossimPlanetTerrainTechnique::childIndex(const ossimPlanetTerrainTileId& tileId)const
+{
+   return (((tileId.y()&1)<<1)|
+           (tileId.x()&1));
+}
+
+void ossimPlanetTerrainTechnique::childTreePosition(const ossimPlanetTerrainTileId& tileId,
+                                                    ossim_uint32& x, ossim_uint32& y)const
+{
+   x = tileId.x()&1;
+   y = tileId.y()&1;
+}
+      
+void ossimPlanetTerrainTechnique::solveTextureMatrixMappingToParent(const ossimPlanetTerrainTileId& tileId,
+                                                                    osg::Matrixd& m)const
+{
+   switch(childIndex(tileId))
+   {
+         // during our split routine an index of 0 is the bottom left child and origin is 0,0 in parent
+         // we basically map local space 0 to 1 ro parent 0 to .5 for both x and y direction.
+         //
+      case 0: 
+      {
+         m.set(0.5, 0.0, 0.0, 0.0,
+               0.0, 0.5, 0.0, 0.0,
+               0.0, 0.0, 1.0, 0.0,
+               0.0, 0.0, 0.0, 1.0);
+         break;
+      }
+         // during our split routine an index of 1 is the bottom right child and origin is .5,0 in parent
+         // so we map local space 0 to 1 along x to .5 to 1 in parent for the x axis and we map
+         // y axis to 0 to .5
+         //
+      case 1:
+      {
+         m.set(0.5, 0.0, 0.0, 0.0,
+               0.0, 0.5, 0.0, 0.0,
+               0.0, 0.0, 1.0, 0.0,
+               0.5, 0.0, 0.0, 1.0);
+         break;
+      }
+         
+         // during our split routine an index of 0 is the top left child and origin is 0,.5 in parent
+         // so we map local space 0 to 1 along x to 0 to .5 in parent for the x axis and we map
+         // y axis to .5 to 1
+         //
+      case 2:
+      {
+         m.set(0.5, 0.0, 0.0, 0.0,
+               0.0, 0.5, 0.0, 0.0,
+               0.0, 0.0, 1.0, 0.0,
+               0.0, 0.5, 0.0, 1.0);
+         break;
+      }
+         // during our split routine an index of 0 is the top right child and origin is .5,.5 in parent
+         // so we map local space 0 to 1 along both axis to .5 to 1 in parent.
+         //
+      case 3:
+      {
+         m.set(0.5, 0.0, 0.0, 0.0,
+               0.0, 0.5, 0.0, 0.0,
+               0.0, 0.0, 1.0, 0.0,
+               0.5, 0.5, 0.0, 1.0);
+         break;
+      }      
+   }
+}
+
+void ossimPlanetTerrainTechnique::solveTextureMatrixMappingToParent(const ossimPlanetTerrainTileId& startId,
+                                                                    const ossimPlanetTerrainTileId& endId,
+                                                                    osg::Matrixd& m)const
+{
+   m.makeIdentity();
+   if(startId.level() != 0)
+   {
+      if(startId.level() > endId.level())
+      {
+         osg::Matrixd mParent;
+         ossimPlanetTerrainTileId currentId = startId;
+         while(currentId.level() != endId.level())
+         {
+            solveTextureMatrixMappingToParent(currentId, mParent);
+            m*=mParent;
+            currentId.setId(currentId.face(),
+                            currentId.level()-1,
+                            currentId.x()>>1,
+                            currentId.y()>>1);
+         }
+      }
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTile.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTile.cpp
new file mode 100644
index 0000000..412d7d3
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTerrainTile.cpp
@@ -0,0 +1,359 @@
+#include <ossimPlanet/ossimPlanetTerrainTile.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <OpenThreads/ScopedLock>
+#include <osg/io_utils>
+
+//#define OSGPLANET_ENABLE_ALLOCATION_COUNT
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static OpenThreads::Mutex objectCountMutex;
+static ossim_uint32 terrainTileCount = 0;
+#endif
+ossimPlanetTerrainTile::ossimPlanetTerrainTile()
+:osg::Group(),
+theTerrain(0),
+theCulledFlag(false),
+theFrameNumber(0),
+theTimeStamp(0.0),
+theSimTimeStamp(0.0)
+{
+   setDataVariance(osg::Object::DYNAMIC);
+   theSplitRequest     = new ossimPlanetSplitRequest();
+   theTextureRequest   = new ossimPlanetTextureRequest();
+   theElevationRequest = new ossimPlanetElevationRequest();
+   setThreadSafeRefUnref(true);
+   setUpdateCallback(new ossimPlanetTraverseCallback);
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++terrainTileCount;
+   std::cout << "ossimPlanetTerrainTile count = " << terrainTileCount << std::endl;
+#endif
+}
+
+ossimPlanetTerrainTile::ossimPlanetTerrainTile(const ossimPlanetTerrainTileId& value)
+:osg::Group(),
+theId(value),
+theTerrain(0),
+theCulledFlag(false),
+theFrameNumber(0),
+theTimeStamp(0.0),
+theSimTimeStamp(0.0)
+{
+   setDataVariance(osg::Object::DYNAMIC);
+   theSplitRequest     = new ossimPlanetSplitRequest();
+   theTextureRequest   = new ossimPlanetTextureRequest();
+   theElevationRequest = new ossimPlanetElevationRequest();
+   
+   setUpdateCallback(new ossimPlanetTraverseCallback);
+   setThreadSafeRefUnref(true);
+   //setCullingActive(false); // we will do our own culling
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++terrainTileCount;
+   std::cout << "ossimPlanetTerrainTile count = " << terrainTileCount << std::endl;
+#endif
+}
+ossimPlanetTerrainTile::~ossimPlanetTerrainTile()
+{
+   if(theTerrain)
+   {
+      theTerrain->unregisterTile(this);
+   }
+   setCullCallback(0);
+   setTerrain(0);
+   theTerrainTechnique->setTerrainTile(0);
+   theTerrainTechnique = 0;
+   theGrid = 0;
+   theElevationLayer = 0;
+   theImageLayers.clear();
+   theTerrain = 0;
+   theSplitRequest     = 0;
+   theTextureRequest   = 0;
+   theElevationRequest = 0;
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   --terrainTileCount;
+   std::cout << "ossimPlanetTerrainTile count = " << terrainTileCount << std::endl;
+#endif
+}
+
+void ossimPlanetTerrainTile::init(ossimPlanetTerrainTile* optionalParentOverride)
+{
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->init(optionalParentOverride);
+   }
+}
+
+void ossimPlanetTerrainTile::traverse(osg::NodeVisitor& nv)
+{
+   if(!theTerrain)
+   {
+      setTerrain(ossimPlanetTerrain::findTerrain(nv.getNodePath()));
+   }
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->traverse(nv);
+   }
+   else
+   {
+      osg::Group::traverse(nv);
+   }
+}
+void ossimPlanetTerrainTile::setTerrainTechnique(ossimPlanetTerrainTechnique* terrainTechnique)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theTerrainTechnique = terrainTechnique;
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->setTerrainTile(this);
+   }
+}
+
+void ossimPlanetTerrainTile::copyCommonParameters(ossimPlanetTerrainTile* src)
+{
+   if(src)
+   {
+      setTerrain(src->terrain());
+   }
+}
+
+void ossimPlanetTerrainTile::setTileId(const ossimPlanetTerrainTileId& value)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theId = value;
+}
+
+void ossimPlanetTerrainTile::setTerrain(ossimPlanetTerrain* value)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(theTerrain)
+   {
+      theTerrain->unregisterTile(this);
+   }
+   theTerrain = value;
+   if(theTerrain)
+   {
+      theTerrainTechnique = theTerrain->newTechnique();
+      theTerrainTechnique->theTerrainTile = this;
+      theGrid = theTerrain->grid();
+      theTerrain->registerTile(this);
+      
+      resetImageLayers();
+      resetElevationLayer();
+   }
+}
+
+ossimPlanetTerrain* ossimPlanetTerrainTile::terrain()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theTerrain;
+}
+
+const ossimPlanetTerrain* ossimPlanetTerrainTile::terrain()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theTerrain;
+}
+
+void ossimPlanetTerrainTile::resetImageLayers()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   ossim_uint32 idx;
+  if(numberOfImageLayers()!= theTerrain->numberOfTextureLayers())
+  {
+      setNumberOfImageLayers(theTerrain->numberOfTextureLayers());
+   }
+   for(idx = 0; idx < theImageLayers.size(); ++idx)
+   {
+      if(!theImageLayers[idx].valid())
+      {
+         theImageLayers[idx] = new ossimPlanetTerrainImageLayer();
+      }
+      theImageLayers[idx]->setImage(0);
+   }
+}
+
+void ossimPlanetTerrainTile::resetElevationLayer()
+{
+   if(!elevationLayer())
+   {
+      theElevationLayer = new ossimPlanetTerrainImageLayer();
+   }
+   //theElevationLayer->setRowsColumns(9,9);
+   theElevationLayer->setImage(0);
+}
+   
+void ossimPlanetTerrainTile::setNumberOfImageLayers(ossim_uint32 n)
+{
+
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+
+   if(n==0)
+   {
+      theImageLayers.clear();
+   }
+   else
+   {
+      theImageLayers.resize(n);
+   }
+}
+
+ossim_uint32 ossimPlanetTerrainTile::numberOfImageLayers()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return (ossim_uint32)theImageLayers.size();
+}
+
+bool ossimPlanetTerrainTile::imageLayersDirty()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theImageLayers.size();++idx)
+   {
+      if(theImageLayers[idx].get())
+      {
+         if(theImageLayers[idx]->isDirty())
+         {
+            return true;
+         }
+      }
+   }
+   
+   return false;
+}
+
+ossimPlanetTerrainImageLayer* ossimPlanetTerrainTile::imageLayer(ossim_uint32 idx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   
+   ossimPlanetTerrainImageLayer* result = 0;
+   if(idx <theImageLayers.size())
+   {
+      result = theImageLayers[idx].get();
+   }
+   
+   return result;
+}
+
+ossimPlanetTerrainImageLayer* ossimPlanetTerrainTile::elevationLayer()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theElevationLayer.get();
+}
+
+ossim_int32 ossimPlanetTerrainTile::indexOfChild(const ossimPlanetTerrainTileId& id)
+{
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = getNumChildren();
+   for(idx = 0; idx < bound;++idx)
+   {
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(getChild(idx));
+      if(tile&&(tile->tileId()==id))
+      {
+         return (ossim_int32)idx;
+      }
+   }
+   return -1;
+}
+
+ossimPlanetTerrainTile* ossimPlanetTerrainTile::child(const ossimPlanetTerrainTileId& id)
+{
+   ossim_uint32 idx = 0;
+   ossim_uint32 bound = getNumChildren();
+   for(idx = 0; idx < bound;++idx)
+   {
+      ossimPlanetTerrainTile* tile = dynamic_cast<ossimPlanetTerrainTile*>(getChild(idx));
+      if(tile&&(tile->tileId()==id))
+      {
+         return tile;
+      }
+   }
+   return 0;
+
+}
+
+void ossimPlanetTerrainTile::cancelAllOperations()
+{
+   theElevationRequest->cancel();
+   theSplitRequest->cancel();
+   theTextureRequest->cancel();
+}
+
+bool ossimPlanetTerrainTile::hasActiveOperations()const
+{
+   return ((theElevationRequest->referenceCount() > 1)||
+           (theSplitRequest->referenceCount() > 1)||
+           (theTextureRequest->referenceCount() > 1));
+}
+
+ossimPlanetTerrainTile* ossimPlanetTerrainTile::parentTile()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(getNumParents() < 1) return 0;
+   return dynamic_cast<ossimPlanetTerrainTile*>(getParent(0));
+}
+
+const ossimPlanetTerrainTile* ossimPlanetTerrainTile::parentTile()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(getNumParents() < 1) return 0;
+   return dynamic_cast<const ossimPlanetTerrainTile*>(getParent(0));
+}
+
+void ossimPlanetTerrainTile::vacantChildIds(ossimPlanetTerrainTechnique::TileIdList& ids)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->vacantChildIds(ids);
+   }
+}
+
+void ossimPlanetTerrainTile::merge()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->merge();
+   }
+   terrain()->setRedrawFlag(true);
+}
+
+osg::BoundingSphere ossimPlanetTerrainTile::computeBound() const
+{
+   if(theTerrainTechnique.valid())
+   {
+      return theTerrainTechnique->computeBound();
+   }
+   return osg::BoundingSphere(osg::Vec3d(0,0,0), -1);
+}
+
+void ossimPlanetTerrainTile::setCulledFlag(bool culled)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theCulledFlag = culled;
+}
+
+bool ossimPlanetTerrainTile::culledFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theCulledFlag;
+}
+void ossimPlanetTerrainTile::releaseGLObjects(osg::State* state)
+{
+   osg::Group::releaseGLObjects(state);
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->releaseGLObjects(state);
+   }
+}
+
+void ossimPlanetTerrainTile::childInserted(unsigned int pos)
+{
+   if(theTerrainTechnique.valid())
+   {
+      theTerrainTechnique->childAdded(pos);
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTexture2D.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTexture2D.cpp
new file mode 100644
index 0000000..6ebf626
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTexture2D.cpp
@@ -0,0 +1,83 @@
+#include <iostream>
+#include <ossimPlanet/ossimPlanetTexture2D.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <OpenThreads/ScopedLock>
+#include <osg/DisplaySettings>
+//#define OSGPLANET_ENABLE_ALLOCATION_COUNT
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+static OpenThreads::Mutex objectCountMutex;
+static ossim_uint32 textureCount = 0;
+#endif
+
+ossimPlanetTexture2D::ossimPlanetTexture2D(const ossimPlanetTerrainTileId& id)
+
+   :osg::Texture2D(),
+   theTileId(id)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++textureCount;
+   std::cout << "ossimPlanetTexture2D count = " << textureCount << "\n";
+#endif
+}
+
+ossimPlanetTexture2D::ossimPlanetTexture2D(osg::Image* image, 
+                                           const ossimPlanetTerrainTileId& id)
+   :osg::Texture2D(image),
+   theTileId(id)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++textureCount;
+   std::cout << "ossimPlanetTexture2D count = " << textureCount << "\n";
+#endif   
+}
+ossimPlanetTexture2D::ossimPlanetTexture2D(ossimPlanetImage* image)
+:osg::Texture2D(image),
+theTileId(image?image->tileId():ossimPlanetTerrainTileId())
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++textureCount;
+   std::cout << "ossimPlanetTexture2D count = " << textureCount << "\n";
+#endif   
+}
+
+ossimPlanetTexture2D::ossimPlanetTexture2D(const ossimPlanetTexture2D& text,const osg::CopyOp& copyop)
+   :osg::Texture2D(text, copyop)
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+   ++textureCount;
+   std::cout << "ossimPlanetTexture2D count = " << textureCount << "\n";
+#endif   
+}
+
+ossimPlanetTexture2D::~ossimPlanetTexture2D()
+{
+#ifdef OSGPLANET_ENABLE_ALLOCATION_COUNT
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(objectCountMutex);
+  --textureCount;
+   std::cout << "ossimPlanetTexture2D count = " << textureCount << "\n";
+#endif
+}
+
+void ossimPlanetTexture2D::setImage(ossimPlanetImage* image)
+{
+   if(image)
+   {
+      setId(image->tileId());
+   }
+   
+   osg::Texture2D::setImage(image);
+}
+
+void ossimPlanetTexture2D::setId(const ossimPlanetTerrainTileId& id)
+{
+   theTileId = id;
+}
+
+const ossimPlanetTerrainTileId& ossimPlanetTexture2D::tileId()const
+{
+   return theTileId;
+}
\ No newline at end of file
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayer.cpp
new file mode 100644
index 0000000..01ba201
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayer.cpp
@@ -0,0 +1,1641 @@
+#include <ossimPlanet/ossimPlanetTextureLayer.h>
+#include <algorithm>
+#include <osg/Vec2d>
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetIdManager.h>
+#include <ossim/base/ossimNotify.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/base/ossimDrect.h>
+#include <ossim/base/ossimLine.h>
+#include <algorithm>
+
+ossimPlanetTextureLayer::ossimPlanetTextureLayer()
+   :osg::Referenced(),
+    theName(""),
+    theDescription("ossimPlanetTextureLayer"),
+    theId(),
+    theEnableFlag(true),
+    theTransparentColorFlag(false),
+    theTransparentColorVector(3),
+//     theFilterType("bilinear"),
+    theFilterType("bilinear"),
+    theDirtyExtentsFlag(true),
+    theDirtyStatsFlag(true),
+    theStateCode(ossimPlanetTextureLayer_VALID)
+
+{
+//    theLookAt = new ossimPlanetLookAt();
+//    theLookAt->setRange(7000000);
+   theExtents = new ossimPlanetExtents();
+   theStats   = new ossimPlanetTextureLayer::Stats();
+   theTransparentColorVector[0] = 0;
+   theTransparentColorVector[1] = 0;
+   theTransparentColorVector[2] = 0;
+   
+   theBrightness = 0.0;
+   theContrast   = 1.0;
+   theOpacity    = 1.0;
+}
+
+ossimPlanetTextureLayer::ossimPlanetTextureLayer(const ossimPlanetTextureLayer& src)
+   :osg::Referenced(),
+    theName(src.theName),
+    theDescription(src.theDescription),
+    theId(src.theId),
+    theExtents(src.theExtents->clone()),
+    theEnableFlag(src.theEnableFlag),
+    theTransparentColorFlag(src.theTransparentColorFlag),
+    theTransparentColorVector(src.theTransparentColorVector),
+    theFilterType(src.theFilterType),
+    theDirtyExtentsFlag(src.theDirtyExtentsFlag),
+    theDirtyStatsFlag(src.theDirtyStatsFlag),
+    theStateCode(src.theStateCode),
+    theBrightness(src.theBrightness),
+    theContrast(src.theContrast),
+    theOpacity(src.theOpacity)
+{
+//    std::cout << "ossimPlanetTextureLayer::ossimPlanetTextureLayer ERROR: NEED TO DO PARENT LIST COPY!!!!!" << std::endl;
+}
+
+ossimPlanetTextureLayer::~ossimPlanetTextureLayer()
+{
+   
+}
+
+ossimString ossimPlanetTextureLayer::getClassName()const
+{
+   return "ossimPlanetTextureLayer";
+}
+
+void ossimPlanetTextureLayer::dirtyExtents()
+{
+   // already dirty
+   if(theDirtyExtentsFlag) return;
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theParentListMutex);
+   theDirtyExtentsFlag = true;
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      theParentList[idx]->dirtyExtents();
+   }
+}
+
+void ossimPlanetTextureLayer::setDirtyExtentsFlag(bool flag)
+{
+   theDirtyExtentsFlag = flag;
+}
+
+void ossimPlanetTextureLayer::dirtyStats()
+{
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theParentListMutex);
+   theDirtyStatsFlag = true;
+
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      theParentList[idx]->dirtyStats();
+   }
+}
+
+void ossimPlanetTextureLayer::addBytesTransferredStat(ossim_uint64 bytesTransferred)const
+{
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theParentListMutex);
+   theStats->setBytesTransferred(theStats->bytesTransferred() + bytesTransferred);
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      theParentList[idx]->addBytesTransferredStat(bytesTransferred);
+   }
+}
+
+void ossimPlanetTextureLayer::clearState(ossimPlanetTextureLayerStateCode stateCode)const
+{
+   ossim_uint32 temp = (ossim_uint32)theStateCode;
+
+   temp &= (~((ossim_uint32)stateCode));
+
+   theStateCode = (ossimPlanetTextureLayerStateCode)temp;
+}
+
+void ossimPlanetTextureLayer::setState(ossimPlanetTextureLayerStateCode stateCode)const
+{
+   theStateCode = (ossimPlanetTextureLayerStateCode)(theStateCode|stateCode);
+   notifyPropertyChanged("stateCode", this);
+}
+   
+ossimPlanetTextureLayerStateCode ossimPlanetTextureLayer::getStateCode()const
+{
+   return theStateCode;
+}
+
+bool ossimPlanetTextureLayer::isStateSet(ossimPlanetTextureLayerStateCode stateCode)const
+{
+   return (theStateCode & stateCode);
+}
+
+const osg::ref_ptr<ossimPlanetExtents>  ossimPlanetTextureLayer::getExtents()const
+{
+   return theExtents.get();
+}
+
+osg::ref_ptr<ossimPlanetExtents>  ossimPlanetTextureLayer::getExtents()
+{
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+
+   return theExtents.get();
+}
+
+
+
+const osg::ref_ptr<ossimPlanetTextureLayer::Stats> ossimPlanetTextureLayer::getStats()const
+{
+   if(theDirtyStatsFlag)
+   {
+      updateStats();
+      theDirtyStatsFlag = false;
+   }
+   return theStats;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer::Stats>  ossimPlanetTextureLayer::getStats()
+{
+   if(theDirtyStatsFlag)
+   {
+      updateStats();
+      theDirtyStatsFlag = false;
+   }
+   return theStats;
+}
+
+
+void ossimPlanetTextureLayer::setExtents(osg::ref_ptr<ossimPlanetExtents> extents)
+{
+   theExtents = extents;
+   dirtyExtents();
+   theDirtyExtentsFlag = false;
+}
+
+void ossimPlanetTextureLayer::getDateRange(ossimDate& minDate,
+                                           ossimDate& maxDate)const
+{
+   minDate = theExtents->getMinDate();
+   maxDate = theExtents->getMaxDate();
+}
+
+const osg::ref_ptr<ossimPlanetLookAt> ossimPlanetTextureLayer::getLookAt()const
+{
+   return theLookAt.get();
+}
+
+void ossimPlanetTextureLayer::setLookAt(osg::ref_ptr<ossimPlanetLookAt> lookAt)
+{
+   theLookAt = lookAt.get();
+}
+
+double ossimPlanetTextureLayer::getApproximateHypotneusLength()const
+{
+   return ((osg::Vec2d(theExtents->getMaxLat(),
+                       theExtents->getMinLon())-
+            osg::Vec2d(theExtents->getMinLat(),
+                       theExtents->getMaxLon())).length() *
+           ossimGpt().metersPerDegree().x);
+}
+
+void ossimPlanetTextureLayer::getCenterLatLonLength(double& centerLat,
+                                                    double& centerLon,
+                                                    double& length)const
+{
+   length = ((osg::Vec2d(theExtents->getMaxLat(), theExtents->getMinLon())-
+              osg::Vec2d(theExtents->getMinLat(), theExtents->getMaxLon())).length() *
+             ossimGpt().metersPerDegree().x);
+   centerLat = (theExtents->getMinLat()+theExtents->getMaxLat())*.5;
+   centerLon = (theExtents->getMinLon()+theExtents->getMaxLon())*.5;
+}
+
+ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::asGroup()
+{
+   return 0;
+}
+
+const ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::asGroup()const
+{
+   return 0;
+}
+
+ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::getParent(ossim_uint32 idx)
+{
+   return parent(idx);
+}
+
+const ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::getParent(ossim_uint32 idx)const
+{
+   return parent(idx);
+}
+
+ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::parent(ossim_uint32 idx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+
+   if(idx < theParentList.size())
+   {
+      return theParentList[idx];
+   }
+   
+   return 0;
+}
+
+const ossimPlanetTextureLayerGroup* ossimPlanetTextureLayer::parent(ossim_uint32 idx)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+
+   if(idx < theParentList.size())
+   {
+      return theParentList[idx];
+   }
+   
+   return 0;
+}
+
+bool ossimPlanetTextureLayer::hasParent(ossimPlanetTextureLayerGroup* parent)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      if(theParentList[idx] == parent)
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+void ossimPlanetTextureLayer::addParent(ossimPlanetTextureLayerGroup* parent)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      if(theParentList[idx] == parent)
+      {
+         return;
+      }
+   }
+
+   theParentList.push_back(parent);
+}
+
+void ossimPlanetTextureLayer::removeParent(ossimPlanetTextureLayerGroup* parent)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theMutex);
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      if(theParentList[idx] == parent)
+      {
+         theParentList.erase(theParentList.begin()+idx);
+      }
+   }
+}
+
+void ossimPlanetTextureLayer::detachFromParents()
+{
+   ossim_uint32 idx = 0;
+
+   theMutex.lock();
+   ossimPlanetTextureLayerParentList parentList = theParentList;
+   theParentList.clear();
+   theMutex.unlock();
+   for(idx = 0; idx < parentList.size(); ++idx)
+   {
+      parentList[idx]->removeLayer(this);
+   }
+}
+
+const ossimString& ossimPlanetTextureLayer::id()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theId;
+}
+
+void ossimPlanetTextureLayer::setId(const ossimString& id)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theId = id;
+   }
+   notifyPropertyChanged("id", this);
+}
+
+void ossimPlanetTextureLayer::setEnableFlag(bool flag)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theEnableFlag = flag;  
+   }
+   notifyPropertyChanged("enableFlag", this);
+}
+
+bool ossimPlanetTextureLayer::getEnableFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theEnableFlag;
+}
+
+bool ossimPlanetTextureLayer::enableFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theEnableFlag;
+}
+
+void ossimPlanetTextureLayer::setName(const ossimString& name)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theName = name;
+   }
+   notifyPropertyChanged("name", this);
+}
+
+const ossimString& ossimPlanetTextureLayer::getName()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theName;
+}
+
+const ossimString& ossimPlanetTextureLayer::name()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theName;
+}
+
+void ossimPlanetTextureLayer::setDescription(const ossimString& description)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+      theDescription = description;
+   }
+   notifyPropertyChanged("description", this);
+}
+
+const ossimString& ossimPlanetTextureLayer::getDescription()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theDescription;
+}
+
+const ossimString& ossimPlanetTextureLayer::description()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theDescription;
+}
+
+bool ossimPlanetTextureLayer::getTransparentColorFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theTransparentColorFlag;
+}
+
+void ossimPlanetTextureLayer::setTransparentColorFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theTransparentColorFlag = flag;
+}
+
+const ossimPlanetTextureLayer::TransparentColorType& ossimPlanetTextureLayer::getTransparentColor()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theTransparentColorVector;
+}
+
+void ossimPlanetTextureLayer::setTransparentColor(unsigned int r,
+                                                  unsigned int g,
+                                                  unsigned int b)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theTransparentColorVector[0] = r;
+   theTransparentColorVector[1] = g;
+   theTransparentColorVector[2] = b;
+}
+
+ossimPlanetImage* ossimPlanetTextureLayer::applyBrightnessContrast(ossimPlanetImage* image, bool duplicateFlag)const
+{
+  ossimPlanetImage* result = image;
+  if(((brightness() != 0.0)||
+      (contrast() != 1.0))&&image)
+  {
+    if(duplicateFlag)
+    {
+      result = new ossimPlanetImage(*image);
+    }
+    result->applyBrightnessContrast(brightness(), contrast());
+  }
+
+  return result;
+}
+
+/*
+void ossimPlanetTextureLayer::mergeImage(ossimPlanetImage* result,
+                                         const ossimPlanetImage* source,
+                                         ossim_float32 sourceOpacity)const
+{
+   if(!result || !source) return;
+   
+   unsigned int w    = result->s();
+   unsigned int h    = result->t();
+   unsigned int area = w*h;
+   unsigned int idx  = 0;
+
+   unsigned char* destBuf = result->data();
+   const unsigned char* srcBuf  = source->data();
+
+   if(sourceOpacity == 1.0)
+   {
+     for(idx = 0; idx < area; ++idx)
+     {
+        if(srcBuf[3] == 255)
+        {
+           destBuf[0] = srcBuf[0];
+           destBuf[1] = srcBuf[1];
+           destBuf[2] = srcBuf[2];
+           destBuf[3] = 255;
+        }
+        else if(srcBuf[3] > 0)
+        {
+           float normalizedValue = (srcBuf[3]/255.0);
+
+           destBuf[0] = static_cast<unsigned char>(destBuf[0]*(1-normalizedValue) + srcBuf[0]*normalizedValue);
+           destBuf[1] = static_cast<unsigned char>(destBuf[1]*(1-normalizedValue) + srcBuf[1]*normalizedValue);
+           destBuf[2] = static_cast<unsigned char>(destBuf[2]*(1-normalizedValue) + srcBuf[2]*normalizedValue);
+           destBuf[3] = 255;
+        }
+        destBuf += 4;
+        srcBuf  += 4;
+     }
+   }
+   else
+   {
+     for(idx = 0; idx < area; ++idx)
+     {
+        if(srcBuf[3] ==255)
+        {
+           destBuf[0] = srcBuf[0]*(1-sourceOpacity) + destBuf[0]*(sourceOpacity);
+           destBuf[1] = srcBuf[1]*(1-sourceOpacity) + destBuf[1]*(sourceOpacity);
+           destBuf[2] = srcBuf[2]*(1-sourceOpacity) + destBuf[2]*(sourceOpacity);
+           destBuf[3] = 255;
+        }
+        else if(srcBuf[3] > 0)
+        {
+           float normalizedValue = (srcBuf[3]/255.0)*sourceOpacity;
+
+           destBuf[0] = static_cast<unsigned char>(destBuf[0]*(1-normalizedValue) + srcBuf[0]*normalizedValue);
+           destBuf[1] = static_cast<unsigned char>(destBuf[1]*(1-normalizedValue) + srcBuf[1]*normalizedValue);
+           destBuf[2] = static_cast<unsigned char>(destBuf[2]*(1-normalizedValue) + srcBuf[2]*normalizedValue);
+           destBuf[3] = 255;
+        }
+        destBuf += 4;
+        srcBuf  += 4;
+     }
+   }
+}
+*/
+void ossimPlanetTextureLayer::mergeImage(ossimPlanetImage* result,
+                                         const ossimPlanetImage* source,
+                                         ossim_float32 sourceOpacity)const
+{
+   if(!result || !source) return;
+   
+   unsigned int w    = result->s();
+   unsigned int h    = result->t();
+   unsigned int area = w*h;
+   unsigned int idx  = 0;
+ 
+   unsigned char* destBuf = result->data();
+   const unsigned char* srcBuf  = source->data();
+ 
+   if(sourceOpacity == 1.0)
+   {
+     for(idx = 0; idx < area; ++idx)
+     {
+        if(srcBuf[3] == 255)
+        {
+           destBuf[0] = srcBuf[0];
+           destBuf[1] = srcBuf[1];
+           destBuf[2] = srcBuf[2];
+           destBuf[3] = 255;
+        }
+        else if(srcBuf[3] > 0)
+        {
+           float alpha = 255 - (1 - srcBuf[3]/255.0) * (255-destBuf[3]);
+           float normalizedValue = srcBuf[3]/alpha;
+ 
+           destBuf[0] = static_cast<unsigned char>(srcBuf[0]*normalizedValue + destBuf[0]*(1-normalizedValue));
+           destBuf[1] = static_cast<unsigned char>(srcBuf[1]*normalizedValue + destBuf[1]*(1-normalizedValue));
+           destBuf[2] = static_cast<unsigned char>(srcBuf[2]*normalizedValue + destBuf[2]*(1-normalizedValue));
+           destBuf[3] = static_cast<unsigned char>(alpha);
+        }
+        destBuf += 4;
+        srcBuf  += 4;
+     }
+   }
+   else if(sourceOpacity > 0.0)
+   {
+     for(idx = 0; idx < area; ++idx)
+     {
+        if(srcBuf[3] > 0)
+        {
+           float alpha = 255 - (1 - srcBuf[3]* sourceOpacity /255.0) * (255-destBuf[3]);
+           float normalizedValue = srcBuf[3]/alpha;
+ 
+           destBuf[0] = static_cast<unsigned char>(srcBuf[0]*normalizedValue + destBuf[0]*(1-normalizedValue));
+           destBuf[1] = static_cast<unsigned char>(srcBuf[1]*normalizedValue + destBuf[1]*(1-normalizedValue));
+           destBuf[2] = static_cast<unsigned char>(srcBuf[2]*normalizedValue + destBuf[2]*(1-normalizedValue));
+           destBuf[3] = static_cast<unsigned char>(alpha);
+        }
+ 
+        destBuf += 4;
+        srcBuf  += 4;
+     }
+   }
+}
+ 
+bool ossimPlanetTextureLayer::insertAlpha(osg::ref_ptr<ossimPlanetImage> texture,
+                                          float initialAlphaValue)const
+{
+   GLint internalFormat = texture->getInternalTextureFormat();
+   unsigned int w = texture->s();
+   unsigned int h = texture->t();
+   unsigned int area = w*h;
+   unsigned char* data = texture->data();
+   unsigned char alpha = static_cast<unsigned char>(initialAlphaValue*255.0);
+   if((internalFormat != GL_RGB)&&
+      (internalFormat != GL_RGBA))
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetTextureArchive::insertAlpha: ERROR image not an RGB image format" << std::endl;
+      
+      return false;
+   }
+   
+   if(internalFormat == GL_RGB)
+   {
+      unsigned char* newData = new unsigned char[area*4];
+      unsigned char* newDataPtr = newData;
+      for(unsigned int idx = 0; idx < area;++idx)
+      {
+         newDataPtr[0] = data[0];
+         newDataPtr[1] = data[1];
+         newDataPtr[2] = data[2];
+         newDataPtr[3] = alpha;
+         newDataPtr+=4;
+         data+=3;
+      }
+      texture->setImage(w, h, 1,
+                        GL_RGBA,
+                        GL_RGBA,
+                        GL_UNSIGNED_BYTE,
+                        newData,
+                        osg::Image::USE_NEW_DELETE);
+                                
+   }
+   else // copy over existing alpha since already have alpha
+   {
+      for(unsigned int idx = 0; idx < area;++idx)
+      {
+         data[3] = alpha;
+         data+=4;
+      }
+      
+   }
+   texture->dirty();
+   
+   return true;
+}
+
+bool ossimPlanetTextureLayer::insertAlpha(osg::ref_ptr<ossimPlanetImage> texture)const
+{
+   if(!theTransparentColorFlag)
+   {
+      return insertAlpha(texture, 1.0);
+   }
+   
+   GLint internalFormat = texture->getInternalTextureFormat();
+   unsigned int w = texture->s();
+   unsigned int h = texture->t();
+   unsigned int area = w*h;
+   unsigned char* data = texture->data();
+   if((internalFormat != GL_RGB)&&
+      (internalFormat != GL_RGBA))
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetTextureArchive::insertAlpha: ERROR image not an RGB image format" << std::endl;
+      
+      return false;
+   }
+   const unsigned char* transparentColor = &theTransparentColorVector.front();
+   
+   if(internalFormat == GL_RGB)
+   {
+      unsigned char* newData = new unsigned char[area*4];
+      unsigned char* newDataPtr = newData;
+      for(unsigned int idx = 0; idx < area;++idx)
+      {
+         newDataPtr[0] = data[0];
+         newDataPtr[1] = data[1];
+         newDataPtr[2] = data[2];
+         if((newDataPtr[0] == transparentColor[0])&&
+            (newDataPtr[1] == transparentColor[1])&&
+            (newDataPtr[2] == transparentColor[2]))
+         {
+            newDataPtr[3] = 0;
+         }
+         else
+         {
+            newDataPtr[3] = 255;
+         }
+         newDataPtr+=4;
+         data+=3;
+      }
+      texture->setImage(w, h, 1,
+                        GL_RGBA,
+                        GL_RGBA,
+                        GL_UNSIGNED_BYTE,
+                        newData,
+                        osg::Image::USE_NEW_DELETE);
+   }
+   else // copy over existing alpha since already have alpha
+   {
+      for(unsigned int idx = 0; idx < area;++idx)
+      {
+         if((data[0] == transparentColor[0])&&
+            (data[1] == transparentColor[1])&&
+            (data[2] == transparentColor[2]))
+         {
+            data[3] = 0;
+         }
+         data+=4;
+      }
+      
+   }
+   texture->dirty();
+   texture->setPixelStatus();
+   
+   return true;
+}
+
+void ossimPlanetTextureLayer::addTransparent(osg::ref_ptr<ossimPlanetImage> texture)const
+{
+   if(!theTransparentColorFlag) return;
+   const unsigned char* transparentColor = &theTransparentColorVector.front();
+   GLint internalFormat = texture->getInternalTextureFormat();
+   unsigned int w = texture->s();
+   unsigned int h = texture->t();
+   unsigned int area = w*h;
+   unsigned char* data = texture->data();
+   if((internalFormat != GL_RGBA))
+   {
+      ossimNotify(ossimNotifyLevel_WARN) << "ossimPlanetTextureArchive::addTransparent: ERROR image not an RGBA image format" << std::endl;
+      
+      return;
+   }
+   for(unsigned int idx = 0; idx < area;++idx)
+   {
+      if((data[0] == transparentColor[0])&&
+         (data[1] == transparentColor[1])&&
+         (data[2] == transparentColor[2]))
+      {
+         data[3] = 0;
+      }
+      data+=4;
+   }
+   texture->dirty();
+}
+
+
+
+void ossimPlanetTextureLayer::setFilterType(const ossimString& filterType)
+{
+   theFilterType = filterType;
+}
+
+const ossimString& ossimPlanetTextureLayer::getFilterTypeAsString()const
+{
+   return theFilterType;
+}
+
+// void ossimPlanetTextureLayer::addCallback(osg::ref_ptr<ossimPlanetTextureLayer::Callback> callback)
+// {
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackMutex);
+   
+//    ossimPlanetTextureLayer::CallbackList::iterator iter = std::find(theCallbackList.begin(), theCallbackList.end(), callback);
+//    if(iter == theCallbackList.end())
+//    {
+//       theCallbackList.push_back(callback);
+//    }
+// }
+
+// void ossimPlanetTextureLayer::removeCallback(osg::ref_ptr<ossimPlanetTextureLayer::Callback> callback)
+// {
+//    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackMutex);
+//    ossimPlanetTextureLayer::CallbackList::iterator iter = std::find(theCallbackList.begin(), theCallbackList.end(), callback);
+//    if(iter != theCallbackList.end())
+//    {
+//       theCallbackList.erase(iter);
+//    }   
+// }
+
+
+void ossimPlanetTextureLayer::notifyRefreshExtent(osg::ref_ptr<ossimPlanetExtents> extent)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->refreshExtent(extent);
+      }
+   }
+}
+
+void ossimPlanetTextureLayer::notifyLayerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->layerAdded(layer);
+      }
+   }
+}
+
+
+void ossimPlanetTextureLayer::notifyLayerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                                                 osg::ref_ptr<ossimPlanetTextureLayer> parent)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->layerRemoved(layer, parent);
+      }
+   }   
+}
+
+
+void ossimPlanetTextureLayer::notifyPropertyChanged(const ossimString& name,
+                                                    const ossimPlanetTextureLayer* layer)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx;
+   for(idx =0; idx < theCallbackList.size(); ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->propertyChanged(name, layer);
+      }
+   }   
+}
+
+void ossimPlanetTextureLayer::resetLookAt()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   double lat, lon, len;
+   getCenterLatLonLength(lat, lon, len);
+
+   theLookAt = new ossimPlanetLookAt;
+   
+   theLookAt->setLat(lat);
+   theLookAt->setLon(lon);
+   theLookAt->setRange(len);
+}
+
+void ossimPlanetTextureLayer::convertToOsg(ossimImageData* data,
+                                           ossimPlanetImage* image)const
+{
+   if(data->getScalarType() == OSSIM_UINT8)
+   {
+      ossim_uint32 w = data->getWidth();
+      ossim_uint32 h = data->getHeight();
+      ossim_uint32 area = w*h;
+      ossim_uint32 idx = 0;
+      unsigned char* buf = new unsigned char[area*4];
+      unsigned char* bufPtr = buf;
+      
+      unsigned char* b1 = NULL; 
+      unsigned char* b2 = NULL; 
+      unsigned char* b3 = NULL; 
+      unsigned char np1 = 0;
+      unsigned char np2 = 0;
+      unsigned char np3 = 0;
+      
+      if(data->getNumberOfBands()< 3)
+      {
+         b1 = (unsigned char*)data->getBuf(0);
+         b2 = (unsigned char*)data->getBuf(0);
+         b3 = (unsigned char*)data->getBuf(0);
+         np1 = (unsigned char)data->getNullPix(0);
+         np2 = (unsigned char)data->getNullPix(0);
+         np3 = (unsigned char)data->getNullPix(0);
+      }
+      else
+      {
+         b1 = (unsigned char*)data->getBuf(0);
+         b2 = (unsigned char*)data->getBuf(1);
+         b3 = (unsigned char*)data->getBuf(2);
+         np1 = (unsigned char)data->getNullPix(0);
+         np2 = (unsigned char)data->getNullPix(1);
+         np3 = (unsigned char)data->getNullPix(2);
+      }
+      
+      if(!theTransparentColorFlag)
+      {
+         for(idx = 0; idx < area; ++idx)
+         {
+            if((*b1==np1)&&
+               (*b2==np2)&&
+               (*b3==np3))
+            {
+               bufPtr[3] = 0;
+            }
+            else
+            {
+               bufPtr[3] = 255;
+            }
+            bufPtr[0] = *b1;
+            bufPtr[1] = *b2;
+            bufPtr[2] = *b3;
+            bufPtr +=4;
+            ++b1;
+            ++b2;
+            ++b3;
+         }
+      }
+      else
+      {
+         const unsigned char* transparentColor = &theTransparentColorVector.front();
+         for(idx = 0; idx < area; ++idx)
+         {
+            if(((*b1==np1)&&
+                (*b2==np2)&&
+                (*b3==np3))||
+               ((*b1==transparentColor[0])&&
+             (*b2==transparentColor[1])&&
+                (*b3==transparentColor[2])))
+            {
+               bufPtr[3] = 0;
+            }
+            else
+            {
+               bufPtr[3] = 255;
+            }
+            bufPtr[0] = *b1;
+            bufPtr[1] = *b2;
+            bufPtr[2] = *b3;
+            bufPtr +=4;
+            ++b1;
+            ++b2;
+            ++b3;
+         }
+         
+      }
+      
+      image->setImage(w,
+                      h,
+                      1,
+                      GL_RGBA,
+                      GL_RGBA,
+                      GL_UNSIGNED_BYTE,
+                      buf,
+                      osg::Image::USE_NEW_DELETE);
+//    image->flipVertical();
+      image->setPixelStatus();
+   }
+}
+
+void ossimPlanetTextureLayer::convertToOsg(ossimImageData* data,
+                                           ossimPlanetImage* image,
+                                           const osg::Vec2d& ulInput,
+                                           const osg::Vec2d& /*urInput*/,
+                                           const osg::Vec2d& lrInput,
+                                           const osg::Vec2d& /*llInput*/,
+                                           ossimPlanetGrid::ModelPoints& outputGridPoints,
+                                           ossim_uint32 outputWidth,
+                                           ossim_uint32 outputHeight)const
+{
+   ossim_uint32 inputW = data->getWidth();
+   ossim_uint32 inputH = data->getHeight();
+   ossim_uint32 w = outputWidth;
+   ossim_uint32 h = outputHeight;
+   ossim_uint32 area = w*h;
+   ossim_uint32 idx = 0;
+   unsigned char* buf;
+   osg::Vec3d latLon;
+   unsigned char* b1 = NULL; 
+   unsigned char* b2 = NULL; 
+   unsigned char* b3 = NULL; 
+   unsigned char np1 = 0;
+   unsigned char np2 = 0;
+   unsigned char np3 = 0;
+   bool bufExists = (image->data()!=0);
+   
+   if(!bufExists)
+   {
+      buf = new unsigned char[area*4];
+      memset(buf, '\0', area*4);
+   }
+   else
+   {
+      buf = image->data();
+   }
+   unsigned char* bufPtr = buf;
+   if(data->getNumberOfBands()< 3)
+   {
+      b1 = (unsigned char*)data->getBuf(0);
+      b2 = (unsigned char*)data->getBuf(0);
+      b3 = (unsigned char*)data->getBuf(0);
+      np1 = (unsigned char)data->getNullPix(0);
+      np2 = (unsigned char)data->getNullPix(0);
+      np3 = (unsigned char)data->getNullPix(0);
+   }
+   else
+   {
+      b1 = (unsigned char*)data->getBuf(0);
+      b2 = (unsigned char*)data->getBuf(1);
+      b3 = (unsigned char*)data->getBuf(2);
+      np1 = (unsigned char)data->getNullPix(0);
+      np2 = (unsigned char)data->getNullPix(1);
+      np3 = (unsigned char)data->getNullPix(2);
+   }
+   
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+   
+   osg::Vec2d inputT;
+   ossim_uint32 inputIdx = 0;
+   osg::Vec2d tempDelta;
+   double deltaInputX = std::fabs(lrInput[0] - ulInput[0]);
+   double deltaInputY = std::fabs(lrInput[1] - ulInput[1]);
+   if(!theTransparentColorFlag)
+   {
+      for(y = 0; y < h; ++y)
+      {
+         bufPtr = buf + y*w*4;
+         
+         for(x = 0; x < w; ++x, bufPtr += 4)
+         {
+            latLon[0] = outputGridPoints[idx].y();
+            latLon[1] = outputGridPoints[idx].x();
+            tempDelta[0] = latLon[1] - ulInput[0];
+            tempDelta[1] = ulInput[1] - latLon[0];
+            tempDelta[0]/=deltaInputX;
+            tempDelta[1]/=deltaInputY;
+            
+            ossim_float32 xf = tempDelta[0]*inputW;
+            ossim_float32 yf = tempDelta[1]*inputH;
+            ossim_int32 xi = (ossim_int32)(xf);
+            ossim_int32 yi = (ossim_int32)(yf);
+            if(xi == -1) xi++;
+            if(yi == -1) yi++;
+            if(xi == inputW) xi--;
+            if(yi == inputH) yi--;
+            if((xi>=0)&&
+               (xi<(int)inputW)&&
+               (yi>=0)&&
+               (yi<(int)inputH))
+            {
+               //             if(xi < 0) xi =0;
+               //             if(xi >= inputW) xi = inputW-1;
+               //             if(yi < 0) yi = 0;
+               //             if(yi >= inputH) yi = inputH-1;
+               inputIdx = yi*inputW + xi;
+               if((b1[inputIdx]==np1)&&
+                  (b2[inputIdx]==np2)&&
+                  (b3[inputIdx]==np3))
+               {
+                  bufPtr[3] = 0;
+                  bufPtr[0] = b1[inputIdx];
+                  bufPtr[1] = b2[inputIdx];
+                  bufPtr[2] = b3[inputIdx];
+               }
+               else
+               {
+                  
+                  bufPtr[3] = 255;
+                  ossim_int32 urx = xi+1;
+                  ossim_int32 lry = yi+1;
+                  
+                  if(urx >= (int)inputW) urx = inputW-1;
+                  if(lry >= (int)inputH) lry = inputH-1;
+                  
+                  double xt0 = xf - xi;
+                  double yt0 = yf - yi;
+                  double xt1 = 1-xt0;
+                  double yt1 = 1-yt0;
+                  double w00 = xt1*yt1;
+                  double w01 = xt0*yt1;
+                  double w10 = xt1*yt0;
+                  double w11 = xt0*yt0;
+                  
+                  int uridx = yi*inputW + urx;
+                  int lridx = lry*inputW + urx;
+                  int llidx = lry*inputW + xi;
+                  
+                  ossim_float32 wsum = w00 + w01 + w10 + w11;
+                  wsum = 1.0/wsum;
+                  bufPtr[0] = (unsigned char)((b1[inputIdx]*w00 + b1[uridx]*w01 + b1[llidx]*w10+b1[lridx]*w11)*wsum);
+                  bufPtr[1] = (unsigned char)((b2[inputIdx]*w00 + b2[uridx]*w01 + b2[llidx]*w10+b2[lridx]*w11)*wsum);
+                  bufPtr[2] = (unsigned char)((b3[inputIdx]*w00 + b3[uridx]*w01 + b3[llidx]*w10+b3[lridx]*w11)*wsum);
+                  //                   bufPtr[1] = b2[inputIdx];
+                  //                   bufPtr[2] = b3[inputIdx];
+                  bufPtr[3] = 255;
+                  
+               }
+            }
+            ++idx;
+         }
+      }
+   }
+   else
+   {
+      const unsigned char* transparentColor = &theTransparentColorVector.front();
+      for(y = 0; y < h; ++y)
+      {
+         bufPtr = buf + y*w*4;
+         
+         for(x = 0; x < w; ++x, bufPtr += 4)
+         {
+            latLon[0] = outputGridPoints[idx].y();
+            latLon[1] = outputGridPoints[idx].x();
+            tempDelta[0] = latLon[1] - ulInput[0];
+            tempDelta[1] = ulInput[1] - latLon[0];
+            tempDelta[0]/=deltaInputX;
+            tempDelta[1]/=deltaInputY;
+            
+            ossim_float32 xf = tempDelta[0]*inputW;
+            ossim_float32 yf = tempDelta[1]*inputH;
+            ossim_int32 xi = (ossim_int32)(xf);
+            ossim_int32 yi = (ossim_int32)(yf);
+            if(xi == -1) xi++;
+            if(yi == -1) yi++;
+            if(xi == inputW) xi--;
+            if(yi == inputH) yi--;
+            if((xi>=0)&&
+               (xi<(int)inputW)&&
+               (yi>=0)&&
+               (yi<(int)inputH))
+            {
+               
+               //             if(xi < 0) xi =0;
+               //             if(xi >= inputW) xi = inputW-1;
+               //             if(yi < 0) yi = 0;
+               //             if(yi >= inputH) yi = inputH-1;
+               inputIdx = yi*inputW + xi;
+               
+               if(((b1[inputIdx]==np1)&&
+                   (b2[inputIdx]==np2)&&
+                   (b3[inputIdx]==np3))||
+                  ((b1[inputIdx]==transparentColor[0])&&
+                   (b2[inputIdx]==transparentColor[1])&&
+                   (b3[inputIdx]==transparentColor[2])))
+               {
+                  bufPtr[3] = 0;
+               }
+               else
+               {
+                  bufPtr[3] = 255;
+                  ossim_int32 urx = xi+1;
+                  ossim_int32 lry = yi+1;
+                  
+                  if(urx >= (int)inputW) urx = inputW-1;
+                  if(lry >= (int)inputH) lry = inputH-1;
+                  
+                  double xt0 = xf - xi;
+                  double yt0 = yf - yi;
+                  double xt1 = 1-xt0;
+                  double yt1 = 1-yt0;
+                  double w00 = xt1*yt1;
+                  double w01 = xt0*yt1;
+                  double w10 = xt1*yt0;
+                  double w11 = xt0*yt0;
+                  
+                  int uridx = yi*inputW + urx;
+                  int lridx = lry*inputW + urx;
+                  int llidx = lry*inputW + xi;
+                  
+                  ossim_float32 wsum = w00 + w01 + w10 + w11;
+                  wsum = 1.0/wsum;
+                  bufPtr[0] = (unsigned char)((b1[inputIdx]*w00 + b1[uridx]*w01 + b1[llidx]*w10+b1[lridx]*w11)*wsum);
+                  bufPtr[1] = (unsigned char)((b2[inputIdx]*w00 + b2[uridx]*w01 + b2[llidx]*w10+b2[lridx]*w11)*wsum);
+                  bufPtr[2] = (unsigned char)((b3[inputIdx]*w00 + b3[uridx]*w01 + b3[llidx]*w10+b3[lridx]*w11)*wsum);
+                  //                   bufPtr[1] = b2[inputIdx];
+                  //                   bufPtr[2] = b3[inputIdx];
+                  bufPtr[3] = 255;
+               }
+            }
+            ++idx;
+         }
+      }
+   }
+   if(!bufExists)
+   {
+      image->setImage(w,
+                      h,
+                      1,
+                      GL_RGBA,
+                      GL_RGBA,
+                      GL_UNSIGNED_BYTE,
+                      buf,
+                      osg::Image::USE_NEW_DELETE);
+   }
+   image->setPixelStatus();
+}
+
+
+
+void ossimPlanetTextureLayer::convertToOsg(ossimImageData* data,
+                                           ossimPlanetImage* image,
+                                           const osg::Vec2d& ulInput,
+                                           const osg::Vec2d& /*urInput*/,
+                                           const osg::Vec2d& lrInput,
+                                           const osg::Vec2d& /*llInput*/,
+                                           std::vector<ossimPlanetGridUtility::GridPoint>& outputGridPoints,
+                                           const ossimPlanetGridUtility& utility,
+                                           ossim_uint32 outputWidth,
+                                           ossim_uint32 outputHeight)const
+{
+   ossim_uint32 inputW = data->getWidth();
+   ossim_uint32 inputH = data->getHeight();
+   ossim_uint32 w = outputWidth;
+   ossim_uint32 h = outputHeight;
+   ossim_uint32 area = w*h;
+   ossim_uint32 idx = 0;
+   unsigned char* buf;
+   osg::Vec3d latLon;
+   unsigned char* b1 = NULL; 
+   unsigned char* b2 = NULL; 
+   unsigned char* b3 = NULL; 
+   unsigned char np1 = 0;
+   unsigned char np2 = 0;
+   unsigned char np3 = 0;
+   bool bufExists = (image->data()!=0);
+
+   if(!bufExists)
+   {
+      buf = new unsigned char[area*4];
+      memset(buf, '\0', area*4);
+   }
+   else
+   {
+      buf = image->data();
+   }
+   unsigned char* bufPtr = buf;
+   if(data->getNumberOfBands()< 3)
+   {
+      b1 = (unsigned char*)data->getBuf(0);
+      b2 = (unsigned char*)data->getBuf(0);
+      b3 = (unsigned char*)data->getBuf(0);
+      np1 = (unsigned char)data->getNullPix(0);
+      np2 = (unsigned char)data->getNullPix(0);
+      np3 = (unsigned char)data->getNullPix(0);
+   }
+   else
+   {
+      b1 = (unsigned char*)data->getBuf(0);
+      b2 = (unsigned char*)data->getBuf(1);
+      b3 = (unsigned char*)data->getBuf(2);
+      np1 = (unsigned char)data->getNullPix(0);
+      np2 = (unsigned char)data->getNullPix(1);
+      np3 = (unsigned char)data->getNullPix(2);
+   }
+  
+   ossim_uint32 y = 0;
+   ossim_uint32 x = 0;
+
+   osg::Vec2d inputT;
+   ossim_uint32 inputIdx = 0;
+   osg::Vec2d tempDelta;
+   double deltaInputX = std::fabs(lrInput[0] - ulInput[0]);
+   double deltaInputY = std::fabs(lrInput[1] - ulInput[1]);
+   if(!theTransparentColorFlag)
+   {
+      for(y = 0; y < h; ++y)
+      {
+         bufPtr = buf + y*w*4;
+         
+         for(x = 0; x < w; ++x, bufPtr += 4)
+         {
+            utility.getLatLon(latLon, outputGridPoints[idx]);
+            tempDelta[0] = latLon[ossimPlanetGridUtility::LON] - ulInput[0];
+            tempDelta[1] = ulInput[1] - latLon[ossimPlanetGridUtility::LAT];
+            tempDelta[0]/=deltaInputX;
+            tempDelta[1]/=deltaInputY;
+
+            ossim_float32 xf = tempDelta[0]*inputW;
+            ossim_float32 yf = tempDelta[1]*inputH;
+            ossim_int32 xi = (ossim_int32)(xf);
+            ossim_int32 yi = (ossim_int32)(yf);
+
+            if((xi>=0)&&
+               (xi<(int)inputW)&&
+               (yi>=0)&&
+               (yi<(int)inputH))
+            {
+//             if(xi < 0) xi =0;
+//             if(xi >= inputW) xi = inputW-1;
+//             if(yi < 0) yi = 0;
+//             if(yi >= inputH) yi = inputH-1;
+               inputIdx = yi*inputW + xi;
+               if((b1[inputIdx]==np1)&&
+                  (b2[inputIdx]==np2)&&
+                  (b3[inputIdx]==np3))
+               {
+                  bufPtr[3] = 0;
+                  bufPtr[0] = b1[inputIdx];
+                  bufPtr[1] = b2[inputIdx];
+                  bufPtr[2] = b3[inputIdx];
+               }
+               else
+               {
+                  
+                  bufPtr[3] = 255;
+                  ossim_int32 urx = xi+1;
+                  ossim_int32 lry = yi+1;
+                  
+                  if(urx >= (int)inputW) urx = inputW-1;
+                  if(lry >= (int)inputH) lry = inputH-1;
+                  
+                  double xt0 = xf - xi;
+                  double yt0 = yf - yi;
+                  double xt1 = 1-xt0;
+                  double yt1 = 1-yt0;
+                  double w00 = xt1*yt1;
+                  double w01 = xt0*yt1;
+                  double w10 = xt1*yt0;
+                  double w11 = xt0*yt0;
+
+                  int uridx = yi*inputW + urx;
+                  int lridx = lry*inputW + urx;
+                  int llidx = lry*inputW + xi;
+                  
+                  ossim_float32 wsum = w00 + w01 + w10 + w11;
+                  wsum = 1.0/wsum;
+                  bufPtr[0] = (unsigned char)((b1[inputIdx]*w00 + b1[uridx]*w01 + b1[llidx]*w10+b1[lridx]*w11)*wsum);
+                  bufPtr[1] = (unsigned char)((b2[inputIdx]*w00 + b2[uridx]*w01 + b2[llidx]*w10+b2[lridx]*w11)*wsum);
+                  bufPtr[2] = (unsigned char)((b3[inputIdx]*w00 + b3[uridx]*w01 + b3[llidx]*w10+b3[lridx]*w11)*wsum);
+//                   bufPtr[1] = b2[inputIdx];
+//                   bufPtr[2] = b3[inputIdx];
+                  bufPtr[3] = 255;
+
+               }
+            }
+            ++idx;
+         }
+      }
+   }
+   else
+   {
+      const unsigned char* transparentColor = &theTransparentColorVector.front();
+      for(y = 0; y < h; ++y)
+      {
+         bufPtr = buf + y*w*4;
+         
+         for(x = 0; x < w; ++x, bufPtr += 4)
+         {
+            utility.getLatLon(latLon, outputGridPoints[idx]);
+            tempDelta[0] = latLon[ossimPlanetGridUtility::LON] - ulInput[0];
+            tempDelta[1] = ulInput[1] - latLon[ossimPlanetGridUtility::LAT];
+            //osg::Vec2d(latLon[1], latLon[0])-ulInput;
+//             tempDelta[0] = tempDelta[0];
+//             tempDelta[1] = tempDelta[1];
+            tempDelta[0]/=deltaInputX;
+            tempDelta[1]/=deltaInputY;
+
+            ossim_float32 xf = tempDelta[0]*inputW;
+            ossim_float32 yf = tempDelta[1]*inputH;
+            ossim_int32 xi = (ossim_int32)(xf);
+            ossim_int32 yi = (ossim_int32)(yf);
+            if((xi>=0)&&
+               (xi<(int)inputW)&&
+               (yi>=0)&&
+               (yi<(int)inputH))
+            {
+               
+//             if(xi < 0) xi =0;
+//             if(xi >= inputW) xi = inputW-1;
+//             if(yi < 0) yi = 0;
+//             if(yi >= inputH) yi = inputH-1;
+               inputIdx = yi*inputW + xi;
+               
+               if(((b1[inputIdx]==np1)&&
+                   (b2[inputIdx]==np2)&&
+                   (b3[inputIdx]==np3))||
+                  ((b1[inputIdx]==transparentColor[0])&&
+                   (b2[inputIdx]==transparentColor[1])&&
+                   (b3[inputIdx]==transparentColor[2])))
+               {
+                  bufPtr[3] = 0;
+               }
+               else
+               {
+                  bufPtr[3] = 255;
+                  ossim_int32 urx = xi+1;
+                  ossim_int32 lry = yi+1;
+                  
+                  if(urx >= (int)inputW) urx = inputW-1;
+                  if(lry >= (int)inputH) lry = inputH-1;
+                  
+                  double xt0 = xf - xi;
+                  double yt0 = yf - yi;
+                  double xt1 = 1-xt0;
+                  double yt1 = 1-yt0;
+                  double w00 = xt1*yt1;
+                  double w01 = xt0*yt1;
+                  double w10 = xt1*yt0;
+                  double w11 = xt0*yt0;
+
+                  int uridx = yi*inputW + urx;
+                  int lridx = lry*inputW + urx;
+                  int llidx = lry*inputW + xi;
+
+                  ossim_float32 wsum = w00 + w01 + w10 + w11;
+                  wsum = 1.0/wsum;
+                  bufPtr[0] = (unsigned char)((b1[inputIdx]*w00 + b1[uridx]*w01 + b1[llidx]*w10+b1[lridx]*w11)*wsum);
+                  bufPtr[1] = (unsigned char)((b2[inputIdx]*w00 + b2[uridx]*w01 + b2[llidx]*w10+b2[lridx]*w11)*wsum);
+                  bufPtr[2] = (unsigned char)((b3[inputIdx]*w00 + b3[uridx]*w01 + b3[llidx]*w10+b3[lridx]*w11)*wsum);
+//                   bufPtr[1] = b2[inputIdx];
+//                   bufPtr[2] = b3[inputIdx];
+                  bufPtr[3] = 255;
+               }
+            }
+            ++idx;
+         }
+      }
+   }
+   if(!bufExists)
+   {
+      image->setImage(w,
+                      h,
+                      1,
+                      GL_RGBA,
+                      GL_RGBA,
+                      GL_UNSIGNED_BYTE,
+                      buf,
+                      osg::Image::USE_NEW_DELETE);
+   }
+//    image->flipVertical();
+   image->setPixelStatus();
+}
+
+OpenThreads::Mutex& ossimPlanetTextureLayer::mutex()
+{
+   return theMutex;
+}
+
+void ossimPlanetTextureLayer::getMetadata(ossimRefPtr<ossimXmlNode> /*metadata*/)const
+{
+   return;
+}
+
+ossimRefPtr<ossimXmlNode> ossimPlanetTextureLayer::saveXml(bool /*recurseFlag*/)const
+{
+   ossimXmlNode* node = new ossimXmlNode();
+   node->setTag(getClassName());
+   node->addChildNode("name", getName());
+   node->addChildNode("description", getDescription());
+   node->addChildNode("id", theId);
+   node->addChildNode("enableFlag", ossimString::toString(theEnableFlag));
+
+   ossimXmlNode* transparentColorNode = new ossimXmlNode;
+   transparentColorNode->setTag("transparentColor");
+   transparentColorNode->addChildNode("enableFlag", ossimString::toString(theTransparentColorFlag));
+   transparentColorNode->addChildNode("color", (ossimString::toString(theTransparentColorVector[0])+ " " +
+                                                ossimString::toString(theTransparentColorVector[1])+ " " +
+                                                ossimString::toString(theTransparentColorVector[2])));
+   node->addChildNode(transparentColorNode);
+   node->addChildNode("filterType", theFilterType);
+   if(theExtents.valid())
+   {
+      node->addChildNode(theExtents->saveXml().get());
+   }
+   if(theLookAt.valid())
+   {
+      node->addChildNode(theLookAt->saveXml().get());
+   }
+   
+   return node;
+}
+
+bool ossimPlanetTextureLayer::loadXml(ossimRefPtr<ossimXmlNode> node)
+{
+   if(!node.valid()) return false;
+   const vector<ossimRefPtr<ossimXmlNode> >& childNodes = node->getChildNodes();
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = childNodes.size();
+   for(idx = 0; idx < upper; ++idx)
+   {
+      ossimString tag = childNodes[idx]->getTag();
+      if(tag == "name")
+      {
+         theName = childNodes[idx]->getText();
+      }
+      else if(tag == "description")
+      {
+         theDescription = childNodes[idx]->getText();
+      }
+      else if(tag == "id")
+      {
+         theId = childNodes[idx]->getText();
+      }
+      else if(tag == "enableFlag")
+      {
+         theEnableFlag = childNodes[idx]->getText().toBool();
+      }
+      else if(tag == "transparentColor")
+      {
+         ossimString temp;
+         
+         if(childNodes[idx]->getChildTextValue(temp, "enableFlag"))
+         {
+            theTransparentColorFlag = temp.toBool();
+         }
+         if(childNodes[idx]->getChildTextValue(temp, "color"))
+         {
+            int r,g,b;
+            istringstream in(temp);
+            in>>r>>g>>b;
+            theTransparentColorVector[0] = (unsigned char)r;
+            theTransparentColorVector[1] = (unsigned char)g;
+            theTransparentColorVector[2] = (unsigned char)b;
+         }
+      }
+      else if(tag == "filterType")
+      {
+         theFilterType = childNodes[idx]->getText();
+      }
+      else if(tag == "ossimPlanetLookAt")
+      {
+         theLookAt = new ossimPlanetLookAt;
+         theLookAt->loadXml(childNodes[idx]);
+      }
+   }
+
+   return true;
+}
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerByName(const ossimString& layerName,
+                                                                  bool /*recurseFlag*/)
+{
+   if(layerName == name())
+   {
+      return this;
+   }
+
+   return 0;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerByName(const ossimString& layerName,
+                                                                        bool /*recurseFlag*/)const
+{
+   if(layerName == name())
+   {
+      return this;
+   }
+
+   return 0;
+}
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerByNameAndId(const ossimString& layerName,
+                                                                       const ossimString& id)
+{
+   if((name() == layerName)&&
+      (this->id()   == id))
+   {
+      return this;
+   }
+
+   return 0;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerByNameAndId(const ossimString& layerName,
+                                                                             const ossimString& id)const
+{
+   if((name() == layerName)&&
+      (this->id()   == id))
+   {
+      return this;
+   }
+
+   return 0;
+}
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerById(const ossimString& id,
+                                                                bool /*recurseFlag*/)
+{
+   if(this->id() == id) return this;
+   return 0;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayer::findLayerById(const ossimString& id,
+                                                                      bool /*recurseFlag*/)const
+{
+   if(this->id() == id) return this;
+   return 0;
+}
+  
+void ossimPlanetTextureLayer::remove()
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theParentList.size(); ++idx)
+   {
+      ossimPlanetTextureLayerGroup* p = parent(idx);
+      p->removeLayer(this);
+   }
+}
+
+ossim_float32 ossimPlanetTextureLayer::brightness()const
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  return theBrightness;
+}
+
+ossim_float32 ossimPlanetTextureLayer::contrast()const
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  return theContrast;
+}
+
+ossim_float32 ossimPlanetTextureLayer::opacity()const
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  return theOpacity;
+}
+
+/**
+ * Allows one to enable brightness contrast settings.
+ */
+void ossimPlanetTextureLayer::setBrightnessContrast(ossim_float32 brightnessValue,
+                                                    ossim_float32 contrastValue,
+                                                    bool notifyFlag)
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  theBrightness = brightnessValue;
+  theContrast   = contrastValue;
+  if(notifyFlag)
+  {
+    notifyRefreshExtent(getExtents().get());
+  }
+}
+
+void ossimPlanetTextureLayer::setBrightness(ossim_float32 brightnessValue,
+                                            bool notifyFlag)
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  theBrightness = brightnessValue;
+  if(notifyFlag)
+  {
+    notifyRefreshExtent(getExtents().get());
+  }
+}
+
+void ossimPlanetTextureLayer::setContrast(ossim_float32 contrastValue,
+                                          bool notifyFlag)
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  theContrast   = contrastValue;
+  if(notifyFlag)
+  {
+    notifyRefreshExtent(getExtents().get());
+  }
+}
+
+/**
+ * Allows one to set the opacity.
+ *
+ * @param opacityValue value of 1.0 is fully opaque and a value of 0 is fully transparent
+ */
+void ossimPlanetTextureLayer::setOpacity(ossim_float32 opacityValue,
+                                         bool notifyFlag)
+{
+  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+  theOpacity = opacityValue;
+
+  if(notifyFlag)
+  {
+    notifyRefreshExtent(getExtents().get());
+  }
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerGroup.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerGroup.cpp
new file mode 100644
index 0000000..3128632
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerGroup.cpp
@@ -0,0 +1,1086 @@
+#include <ossimPlanet/ossimPlanetTextureLayerGroup.h>
+#include <algorithm>
+#include <stack>
+#include <queue>
+#include <ossim/base/ossimDrect.h>
+#include <ossim/base/ossimGpt.h>
+
+
+class ossimPlanetTextureLayerListener : public ossimPlanetTextureLayerCallback
+{
+public:
+   ossimPlanetTextureLayerListener(ossimPlanetTextureLayer* layer)
+      :theLayer(layer)
+      {
+      }
+
+   void setLayer(ossimPlanetTextureLayer* layer)
+      {
+         theLayer = layer;
+      }
+   virtual void layerAdded(osg::ref_ptr<ossimPlanetTextureLayer> layer)
+      {
+         if(theLayer)
+         {
+            theLayer->notifyLayerAdded(layer);
+         }
+      }
+   virtual void refreshExtent(osg::ref_ptr<ossimPlanetExtents> extent)
+      {
+         if(theLayer)
+         {
+            theLayer->notifyRefreshExtent(extent);            
+         }
+      }
+   virtual void layerRemoved(osg::ref_ptr<ossimPlanetTextureLayer> layer,
+                             osg::ref_ptr<ossimPlanetTextureLayer> parent)
+      {
+         if(theLayer)
+         {
+            theLayer->notifyLayerRemoved(layer, parent);
+         }
+      }
+   virtual void propertyChanged(const ossimString& name,
+                                const ossimPlanetTextureLayer* object)
+   {
+      if(theLayer)
+      {
+         theLayer->notifyPropertyChanged(name, object);
+      }
+   }
+protected:
+   ossimPlanetTextureLayer* theLayer;
+};
+
+ossimPlanetTextureLayerGroup::ossimPlanetTextureLayerGroup()
+:theBackgroundColor(1.0,1.0,1.0,1.0),
+theFillEmptyNullTileMaxLevel(-1),
+theFillTranslucentPixelsWithBackgroundEnabled(false)
+{
+   theName        = "ossimPlanetTextureLayerGroup";
+   theDescription = "ossimPlanetTextureLayerGroup";
+   theChildListener = new ossimPlanetTextureLayerListener(this);
+}
+
+ossimPlanetTextureLayerGroup::ossimPlanetTextureLayerGroup(const ossimPlanetTextureLayerGroup& src)
+   :ossimPlanetTextureLayer(src)
+{
+   
+   theChildListener = new ossimPlanetTextureLayerListener(this);
+   if(&src != this)
+   {
+      ossim_uint32 idx = 0;
+      
+      for(idx = 0; idx < src.theChildrenList.size(); ++idx)
+      {
+         if(src.theChildrenList[idx].valid())
+         {
+            osg::ref_ptr<ossimPlanetTextureLayer> layer = src.theChildrenList[idx]->dup();
+            addBottom(layer.get());
+         }
+         else
+         {
+            // empty for now.  Not sure if we want to push a null layer
+         }
+      }
+   }
+   
+   theBackgroundColor = src.theBackgroundColor;
+   theFillEmptyNullTileMaxLevel = src.theFillEmptyNullTileMaxLevel;
+   
+   theFillTranslucentPixelsWithBackgroundEnabled = src.theFillTranslucentPixelsWithBackgroundEnabled;
+}
+
+ossimPlanetTextureLayerGroup::~ossimPlanetTextureLayerGroup()
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theChildrenList.size();++idx)
+   {
+      theChildrenList[idx]->removeCallback(theChildListener);
+      theChildrenList[idx]->removeParent(this);
+   }
+}
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::dup()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   return new ossimPlanetTextureLayerGroup(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::dupType()const
+{
+   return new ossimPlanetTextureLayerGroup();
+}
+
+ossimString ossimPlanetTextureLayerGroup::getClassName()const
+{
+   return "ossimPlanetTextureLayerGroup";
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetTextureLayerGroup::updateExtents()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   theStateCode = ossimPlanetTextureLayer_VALID;
+   ossim_uint32 idx;
+   for(idx = 0; idx < theChildrenList.size(); ++idx)
+   {
+     theStateCode = (ossimPlanetTextureLayerStateCode)(theStateCode|theChildrenList[idx]->updateExtents());
+
+      const osg::ref_ptr<ossimPlanetExtents> extents = theChildrenList[idx]->getExtents();
+
+      if(idx != 0)
+      {
+         theExtents->combine(extents.get());
+      }
+      else
+      {
+         theExtents = extents->clone();
+      }
+
+   }
+   theDirtyExtentsFlag = false;
+   
+   return theStateCode;
+}
+
+void ossimPlanetTextureLayerGroup::updateStats()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theChildrenListMutex);
+   theStats->setTotalTextureSize(0);
+   theStats->setBytesTransferred(0);
+   ossim_uint32 idx;
+   for(idx = 0; idx < theChildrenList.size(); ++idx)
+   {
+      theChildrenList[idx]->updateStats();
+      osg::ref_ptr<ossimPlanetTextureLayer::Stats> stats = theChildrenList[idx]->getStats();
+      theStats->setBytesTransferred(theStats->bytesTransferred() + stats->bytesTransferred());
+      theStats->setTotalTextureSize(theStats->totalTextureSize() + stats->totalTextureSize());
+   }
+   theDirtyStatsFlag = false;
+}
+
+void ossimPlanetTextureLayerGroup::resetStats()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(theChildrenListMutex);
+   ossim_uint32 idx;
+   theStats->setBytesTransferred(0);
+   theStats->setTotalTextureSize(0);
+   for(idx = 0; idx < theChildrenList.size(); ++idx)
+   {
+      osg::ref_ptr<ossimPlanetTextureLayer::Stats> stats = theChildrenList[idx]->getStats();
+      theStats->setTotalTextureSize(theStats->totalTextureSize() + stats->totalTextureSize());
+   }
+}
+
+bool ossimPlanetTextureLayerGroup::hasTexture(ossim_uint32 width,
+                                              ossim_uint32 height,
+                                              const ossimPlanetTerrainTileId& tileId,
+                                              const ossimPlanetGrid& grid)
+{
+   if(!theEnableFlag)
+   {
+      return false;
+   }
+   if(tileId.level() == 0) return true;
+
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   
+   if(theExtents.valid())
+   {
+      osg::ref_ptr<ossimPlanetExtents> extents = new ossimPlanetExtents;
+      if(grid.convertToGeographicExtents(tileId, *extents, width, height))
+      {
+         if(!theExtents->intersectsLatLon(*extents)&&
+            !theExtents->intersectsScale(*extents))
+         {
+            return false;
+         }
+      }
+   }
+   else
+   {
+      return false;
+   }
+   
+   bool result = false;
+   ossim_uint32 idx = 0;
+   for(idx = 0; ((idx < theChildrenList.size())&&!result); ++idx)
+   {
+      if(theChildrenList[idx]->hasTexture(width, height, tileId, grid))
+      {
+         result = true;
+      }
+   }
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetTextureLayerGroup::getTexture(ossim_uint32 width,
+                                                                        ossim_uint32 height,
+                                                                        const ossimPlanetTerrainTileId& tileId,
+                                                                        const ossimPlanetGrid& grid,
+                                                                        ossim_int32 padding)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   osg::ref_ptr<ossimPlanetExtents> tileExtents = new ossimPlanetExtents;
+   if(grid.convertToGeographicExtents(tileId, *tileExtents, width, height))
+   {
+      if(theExtents.valid())
+      {
+         if(!theExtents->intersectsLatLon(*tileExtents)&&
+            !theExtents->intersectsScale(*tileExtents))
+         {
+            return 0;
+         }
+      }
+   }
+   ossim_uint32 idx = 0;
+   osg::ref_ptr<ossimPlanetImage> result;
+   ossim_float32 opacity = 1.0;
+   if(theChildrenList.size() == 1)
+   {
+     result = theChildrenList[idx]->getTexture(width, height, tileId, grid);
+   }
+   else
+   {
+     for(idx = 0; idx < theChildrenList.size(); ++idx)
+     {
+        if(theChildrenList[idx].valid()&&(theChildrenList[idx]->opacity() > 0.0))
+        {
+           osg::ref_ptr<ossimPlanetImage> image = theChildrenList[idx]->getTexture(width, height, tileId, grid);
+
+           if(image.valid())
+           {
+
+             ossimPlanetImage::ossimPlanetImagePixelStatus pixelStatus = image->getPixelStatus();
+              if(result.valid())
+              {
+                // use previous opacity for merging
+                 //mergeImage(image.get(), result.get(), 1.0 - opacity);
+                 mergeImage(image.get(), result.get(), opacity);
+                 // update opacity
+                 opacity = theChildrenList[idx]->opacity();
+                 result = image;
+                 result->getPixelStatus();
+                 pixelStatus = result->getPixelStatus();
+                 if((pixelStatus == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)&&
+                     (opacity == 1.0))
+                 {
+                   // we are finished
+                    break;
+                 }
+              }
+              else
+              {
+                opacity = theChildrenList[idx]->opacity();
+                if((opacity == 1.0) &&
+                    (pixelStatus == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL))
+                {
+                  result = image;
+                  break;
+                }
+                else
+                {
+                  result = (ossimPlanetImage*)image->clone(osg::CopyOp::DEEP_COPY_ALL);
+                }
+              }// end if result.valid()
+           }// end if image.valid()
+        }
+     }
+   }
+   if(result.get())
+   {
+      result = applyBrightnessContrast(result.get(), true);
+   }
+   if((!result.valid()&&((ossim_int32)tileId.level()<=theFillEmptyNullTileMaxLevel))||
+      (result.valid()&&result->getPixelStatus()==ossimPlanetImage::ossimPlanetImagePixelStatus_EMPTY))
+   {
+      ossim_uint32 area = width*height;
+      unsigned char* newData = new unsigned char[area*4];
+      ossim_uint8 r = static_cast<ossim_uint8>(theBackgroundColor[0]*255);
+      ossim_uint8 g = static_cast<ossim_uint8>(theBackgroundColor[1]*255);
+      ossim_uint8 b = static_cast<ossim_uint8>(theBackgroundColor[2]*255);
+      ossim_uint8 a = static_cast<ossim_uint8>(theBackgroundColor[3]*255);
+      if(r==g&&r==b&&r==a)
+      {
+         memset(newData, r, area*4);
+      }
+      else
+      {
+         ossim_uint32 idx = 0;
+         unsigned char* newDataPtr = newData;
+         for(idx = 0; idx < area; ++idx,newDataPtr+=4)
+         {
+            newDataPtr[0] = r;
+            newDataPtr[1] = g;
+            newDataPtr[2] = b;
+            newDataPtr[3] = a;
+         }
+      }
+      result = new ossimPlanetImage();
+      result->setImage(width, height, 1,
+                        GL_RGBA,
+                        GL_RGBA,
+                        GL_UNSIGNED_BYTE,
+                        newData,
+                       osg::Image::USE_NEW_DELETE);
+   }
+   else if(result.valid()&&theFillTranslucentPixelsWithBackgroundEnabled)
+   {
+      ossimPlanetImage::ossimPlanetImagePixelStatus pixelStatus = result->getPixelStatus();
+      if(pixelStatus != ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+      {
+         unsigned char* dataPtr = result->data();
+         ossim_uint32 area = result->width()*result->height();
+         ossim_uint32 idx = 0;
+         ossim_uint8 r = static_cast<ossim_uint8>(theBackgroundColor[0]*255);
+         ossim_uint8 g = static_cast<ossim_uint8>(theBackgroundColor[1]*255);
+         ossim_uint8 b = static_cast<ossim_uint8>(theBackgroundColor[2]*255);
+         ossim_uint8 a = static_cast<ossim_uint8>(theBackgroundColor[3]*255);
+         for(idx = 0; idx < area;++idx,dataPtr+=4)
+         {
+            if(dataPtr[3] < 1)
+            {
+               dataPtr[0] = r;
+               dataPtr[1] = g;
+               dataPtr[2] = b;
+               dataPtr[3] = a;
+            }
+         }
+         result->setPixelStatus();
+      }
+
+   }
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetTextureLayerGroup::getTexture(ossim_uint32 level,
+                                                                        ossim_uint64 row,
+                                                                        ossim_uint64 col,
+                                                                        const ossimPlanetGridUtility& utility)
+{
+   if(!theEnableFlag)
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   ossim_uint32 idx = 0;
+   osg::ref_ptr<ossimPlanetImage> result;
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+//   unsigned int w = utility.getTileWidth();
+   unsigned int h = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row, 
+                           col );
+   if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+   {
+      return 0;
+   }
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/h;
+//   double deltaLon    = deltaX/w;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   if(gsd.y>theExtents->getMaxScale())//!theExtents->intersectsScale(gsd.y,
+       //                            gsd.y))
+   {
+      return 0;
+   }
+      
+   for(idx = 0; idx < theChildrenList.size(); ++idx)
+   {
+      if(theChildrenList[idx].valid())
+      {
+         const osg::ref_ptr<ossimPlanetExtents> extents = theChildrenList[idx]->getExtents();
+         
+         if(extents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+         {
+            osg::ref_ptr<ossimPlanetImage> image = theChildrenList[idx]->getTexture(level, row, col, utility);
+            if(image.valid())
+            {
+               if(result.valid())
+               {
+                  mergeImage(image.get(), result.get());
+                  result = image;
+                  result->setPixelStatus();
+                  if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                  {
+                     return result;
+                  }
+               }
+               else
+               {
+                  result = (ossimPlanetImage*)image->clone(osg::CopyOp::DEEP_COPY_ALL);
+                  if(result->getPixelStatus() == ossimPlanetImage::ossimPlanetImagePixelStatus_FULL)
+                  {
+                     return result;
+                  }
+               }
+            }
+         }
+      }
+   }
+   
+   return result;
+}
+
+ossimPlanetTextureLayerGroup* ossimPlanetTextureLayerGroup::asGroup()
+{
+   return this;
+}
+
+const ossimPlanetTextureLayerGroup* ossimPlanetTextureLayerGroup::asGroup()const
+{
+   return this;
+}
+
+bool ossimPlanetTextureLayerGroup::swapLayers(osg::ref_ptr<ossimPlanetTextureLayer> layer1, 
+                                              osg::ref_ptr<ossimPlanetTextureLayer> layer2,
+                                              bool notifyFlag)
+{
+   ossim_int32 idx1 = findLayerIndex(layer1.get());
+   ossim_int32 idx2 = findLayerIndex(layer2.get());
+   
+   if(idx1 < 0 || idx2 < 0) return false;
+   
+   return swapLayers(idx1, idx2, notifyFlag);
+}
+
+bool ossimPlanetTextureLayerGroup::swapLayers(ossim_uint32 idx1, ossim_uint32 idx2, bool notifyFlag)
+{
+   if((idx1 < theChildrenList.size())&&
+      (idx2 < theChildrenList.size()))
+   {
+      std::swap(theChildrenList[idx1], theChildrenList[idx2]);
+      if(notifyFlag)
+      {
+         if(theChildrenList[idx1]->getExtents().valid()&&
+            theChildrenList[idx2]->getExtents().valid())
+         {
+            osg::ref_ptr<ossimPlanetExtents> extent = new ossimPlanetExtents(*theChildrenList[idx1]->getExtents());
+            extent->combine(theChildrenList[idx2]->getExtents().get());
+            notifyRefreshExtent(extent);
+         }
+      }
+      
+      return true;
+   }
+   
+   return false;
+}
+
+bool ossimPlanetTextureLayerGroup::replaceLayer(ossim_uint32 idx,
+                                                osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                                bool notifyFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+    bool result = false;
+    if(layer.valid()&&idx < theChildrenList.size())
+    {
+       if(!containsLayerNoMutex(layer))
+       {
+          if(theChildrenList[idx].valid())
+          {
+             theChildrenList[idx]->removeCallback(theChildListener);
+             theChildrenList[idx]->removeParent(this);
+          }
+          layer->addParent(this);
+          layer->addCallback(theChildListener);
+          theChildrenList[idx] = layer.get();
+          dirtyExtents();
+          dirtyStats();
+          result = true;
+          if(notifyFlag)
+          {
+             notifyLayerAdded(layer);
+          }
+       }
+    }
+    
+    return result;
+}
+
+bool ossimPlanetTextureLayerGroup::addTop(osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                          bool notifyFlag)
+{
+   if(layer.get() == this) return false;
+//   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   bool result = false;
+   
+   if(layer.valid())
+   {
+      if(!containsLayer(layer))
+      {
+         layer->addParent(this);
+         layer->addCallback(theChildListener);
+         theChildrenListMutex.lock();
+         theChildrenList.insert(theChildrenList.begin(), layer);
+         theChildrenListMutex.unlock();
+         dirtyExtents(); // notify parent layers
+         dirtyStats();
+         result = true;
+         if(notifyFlag)
+         {
+            notifyLayerAdded(layer);
+         }
+      }
+   }
+
+   return result;
+}
+
+bool ossimPlanetTextureLayerGroup::addBeforeIdx(ossim_uint32 idx,
+                                                osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                                bool notifyFlag)
+{
+   bool result = false;
+
+   theChildrenListMutex.lock();
+   if((idx < theChildrenList.size())&&(!containsLayerNoMutex(layer)))
+   {
+      layer->addParent(this);
+      layer->addCallback(theChildListener);
+      theChildrenList.insert(theChildrenList.begin()+idx, layer);
+      theChildrenListMutex.unlock();
+     dirtyExtents();
+      dirtyStats();
+      result = true;
+      if(notifyFlag)
+      {
+         notifyLayerAdded(layer);   
+      }
+   }
+   else
+    {
+      theChildrenListMutex.unlock();
+    }
+
+   return result;
+}
+
+bool ossimPlanetTextureLayerGroup::addBeforeLayer(const osg::ref_ptr<ossimPlanetTextureLayer> beforeLayer,
+                                                  osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd, 
+                                                  bool notifyFlag)
+{
+   return addBeforeIdx(findLayerIndex(beforeLayer),
+                       layerToAdd,
+                       notifyFlag);
+}
+
+bool ossimPlanetTextureLayerGroup::addAfterIdx(ossim_int32 idx,
+                                               osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                               bool notifyFlag)
+{
+   bool result = false;
+   
+   theChildrenListMutex.lock();
+   if(containsLayerNoMutex(layer))
+   {
+      return result;
+   }
+   if(idx == -1)
+   {
+      layer->addParent(this);
+      layer->addCallback(theChildListener);
+      theChildrenList.insert(theChildrenList.begin(), layer);
+      theChildrenListMutex.unlock();
+      dirtyExtents();
+      dirtyStats();
+      result = true;
+      if(notifyFlag)
+      {
+         notifyLayerAdded(layer);   
+      }
+   }
+   else if(idx < theChildrenList.size())
+   {
+      layer->addParent(this);
+      layer->addCallback(theChildListener);
+      theChildrenList.insert(theChildrenList.begin()+idx+1, layer);
+      theChildrenListMutex.unlock();
+      dirtyExtents();
+      dirtyStats();
+      result = true;
+      if(notifyFlag)
+      {
+         notifyLayerAdded(layer);   
+      }
+   }
+   else if(idx == theChildrenList.size())
+   {
+      layer->addParent(this);
+      layer->addCallback(theChildListener);
+      theChildrenList.push_back(layer.get());
+      theChildrenListMutex.unlock();
+      dirtyExtents();
+      dirtyStats();
+      result = true;
+      if(notifyFlag)
+      {
+         notifyLayerAdded(layer);   
+      }
+   }
+   else
+   {
+     theChildrenListMutex.unlock();
+   }
+   return result;
+}
+
+bool ossimPlanetTextureLayerGroup::addAfterLayer(const osg::ref_ptr<ossimPlanetTextureLayer> afterLayer,
+                                                 osg::ref_ptr<ossimPlanetTextureLayer> layerToAdd, 
+                                                 bool notifyFlag)
+{
+   return addAfterIdx(findLayerIndex(afterLayer),
+                      layerToAdd,
+                      notifyFlag);
+}
+
+bool ossimPlanetTextureLayerGroup::addBottom(osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                             bool notifyFlag)
+{
+   bool result = false;
+   if(layer.valid())
+   {
+      if(!containsLayerNoMutex(layer))
+      {
+         layer->addParent(this);
+         layer->addCallback(theChildListener);
+         theChildrenListMutex.lock();
+         theChildrenList.push_back(layer);
+         theChildrenListMutex.unlock();
+         dirtyExtents();
+         dirtyStats();
+         result = true;
+         if(notifyFlag)
+         {
+            notifyLayerAdded(layer);   
+         }
+      }
+   }
+
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetTextureLayerGroup::removeLayer(ossim_uint32 idx, 
+                                                                                bool notifyFlag)
+{
+   theChildrenListMutex.lock();
+   osg::ref_ptr<ossimPlanetTextureLayer> layer = removeLayerNoMutex(idx, false);
+   theChildrenListMutex.unlock();   
+   if(notifyFlag)
+   {
+      notifyLayerRemoved(layer, this);
+   }
+   return layer.get();
+}
+
+void ossimPlanetTextureLayerGroup::removeLayers(ossim_uint32 idx, ossim_uint32 length, 
+                                                bool notifyFlag)
+{
+  std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > layerList;
+  {
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   layerList = removeLayersNoMutex(idx, length, false);
+  }
+  if(notifyFlag)
+  {
+    ossim_uint32 tempIdx = layerList.size();
+     for(tempIdx = 0; tempIdx < layerList.size();++tempIdx)
+     {
+        notifyLayerRemoved(layerList[tempIdx].get(), this);
+     }
+  }
+
+}
+
+bool ossimPlanetTextureLayerGroup::removeLayer(osg::ref_ptr<ossimPlanetTextureLayer> layer, 
+                                               bool notifyFlag)
+{
+   theChildrenListMutex.lock();
+   bool result = removeLayerNoMutex(layer, false);
+   theChildrenListMutex.unlock();   
+   if(notifyFlag)
+   {
+      notifyLayerRemoved(layer, this);
+   }
+   return result;
+}
+
+
+ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerByName(const ossimString& layerName,
+                                                                       bool recurseFlag)
+{
+   std::queue<ossimPlanetTextureLayer*> tempQueue;
+   
+   if(name() == layerName) return this;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; (idx < theChildrenList.size());++idx)
+   {
+      if(theChildrenList[idx]->name() == layerName) return theChildrenList[idx].get();
+      if(theChildrenList[idx]->asGroup()&&recurseFlag)
+      {
+         tempQueue.push(theChildrenList[idx].get());
+      }
+   }
+   ossimPlanetTextureLayer* result = 0;
+
+   while(!tempQueue.empty()&&!result)
+   {
+      result = tempQueue.front()->findLayerByName(layerName, recurseFlag);
+      tempQueue.pop();
+   }
+   
+   return result;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerByName(const ossimString& layerName,
+                                                                             bool recurseFlag)const
+{
+   std::queue<const ossimPlanetTextureLayer*> tempQueue;
+   
+   if(theName == layerName) return this;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; (idx < theChildrenList.size());++idx)
+   {
+      if(theChildrenList[idx]->name() == layerName) return theChildrenList[idx].get();
+      if(theChildrenList[idx]->asGroup()&&recurseFlag)
+      {
+         tempQueue.push(theChildrenList[idx].get());
+      }
+   }
+   const ossimPlanetTextureLayer* result = 0;
+
+   while(!tempQueue.empty()&&!result)
+   {
+      result = tempQueue.front()->findLayerByName(layerName, recurseFlag);
+      tempQueue.pop();
+   }
+   
+   return result;
+}
+ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerByNameAndId(const ossimString& layerName,
+                                                                            const ossimString& id)
+{
+   ossimPlanetTextureLayer* layer = this;
+   if(layer->name() != layerName)
+   {
+      layer = findLayerByName(layerName, true);
+   }
+   if(layer)
+   {
+      return layer->findLayerById(id, true);
+   }
+   
+   return 0;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerByNameAndId(const ossimString& layerName,
+                                                                                  const ossimString& id)const
+{
+   const ossimPlanetTextureLayer* layer = this;
+   if(layer->name() != layerName)
+   {
+      layer = findLayerByName(layerName, true);
+   }
+   if(layer)
+   {
+      return layer->findLayerById(id, true);
+   }
+   return 0;
+}
+ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerById(const ossimString& layerId,
+                                                                     bool recurseFlag)
+{
+   std::queue<ossimPlanetTextureLayer*> tempQueue;
+   
+   if(theId == layerId) return this;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; (idx < theChildrenList.size());++idx)
+   {
+      if(theChildrenList[idx]->id() == layerId) return theChildrenList[idx].get();
+      if(theChildrenList[idx]->asGroup()&&recurseFlag)
+      {
+         tempQueue.push(theChildrenList[idx].get());
+      }
+   }
+   ossimPlanetTextureLayer* result = 0;
+
+   while(!tempQueue.empty()&&!result)
+   {
+      result = tempQueue.front()->findLayerById(layerId, recurseFlag);
+      tempQueue.pop();
+   }
+   
+   return result;
+}
+
+const ossimPlanetTextureLayer* ossimPlanetTextureLayerGroup::findLayerById(const ossimString& layerId,
+                                                                           bool recurseFlag)const
+{
+   std::queue<const ossimPlanetTextureLayer*> tempQueue;
+   
+   if(theId == layerId) return this;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   ossim_uint32 idx = 0;
+   for(idx = 0; (idx < theChildrenList.size());++idx)
+   {
+      if(theChildrenList[idx]->id() == layerId) return theChildrenList[idx].get();
+      if(theChildrenList[idx]->asGroup()&&recurseFlag)
+      {
+         tempQueue.push(theChildrenList[idx].get());
+      }
+   }
+   const ossimPlanetTextureLayer* result = 0;
+
+   while(!tempQueue.empty()&&!result)
+   {
+      result = tempQueue.front()->findLayerById(layerId, recurseFlag);
+      tempQueue.pop();
+   }
+   
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetTextureLayerGroup::removeLayerNoMutex(ossim_uint32 idx, bool notifyFlag)
+{
+   osg::ref_ptr<ossimPlanetTextureLayer> result;
+   if(idx < theChildrenList.size())
+   {
+      result = theChildrenList[idx];
+      result->removeParent(this);
+      result->removeCallback(theChildListener);
+      theChildrenList.erase(theChildrenList.begin()+idx);
+      dirtyExtents();
+      dirtyStats();
+   }
+   if(notifyFlag)
+   {
+      notifyLayerRemoved(result, this);
+   }
+   return result;
+}
+
+std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > ossimPlanetTextureLayerGroup::removeLayersNoMutex(ossim_uint32 idx, ossim_uint32 length, bool notifyFlag)
+{
+  std::vector<osg::ref_ptr<ossimPlanetTextureLayer> > layerList;
+  if(idx >= theChildrenList.size()) return layerList;
+   ossim_uint32 endIdx = idx;
+   ossim_uint32 maxCount = ossim::min(idx+length, (ossim_uint32)theChildrenList.size());
+   for(endIdx = idx; endIdx <maxCount ; ++endIdx)
+   {
+      theChildrenList[endIdx]->removeParent(this);
+      theChildrenList[endIdx]->removeCallback(theChildListener);
+      layerList.push_back(theChildrenList[endIdx]);
+   }
+   theChildrenList.erase(theChildrenList.begin() + idx,
+                         theChildrenList.begin() + maxCount);
+   dirtyExtents();
+   dirtyStats();
+	ossim_uint32 tempIdx = 0;
+
+	return layerList;
+}
+
+bool ossimPlanetTextureLayerGroup::removeLayerNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer, bool notifyFlag)
+{
+
+   ossim_int32 idx = findLayerIndexNoMutex(layer);
+   if(idx > -1)
+   {
+      return removeLayerNoMutex((ossim_uint32)idx, notifyFlag).valid();
+   }
+
+   return false;
+}
+
+ossim_int32 ossimPlanetTextureLayerGroup::findLayerIndexNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const
+{
+   ossim_uint32 idx = 0;
+   for(idx = 0; idx < theChildrenList.size(); ++idx)
+   {
+      if(theChildrenList[idx].get() == layer.get())
+      {
+         return (ossim_int32)idx;
+      }
+   }
+   
+   return -1;
+   
+}
+
+ossim_int32 ossimPlanetTextureLayerGroup::findLayerIndex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   return findLayerIndexNoMutex(layer);
+}
+
+bool ossimPlanetTextureLayerGroup::containsLayer(osg::ref_ptr<ossimPlanetTextureLayer> layer)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   return containsLayerNoMutex(layer);
+}
+
+ossim_uint32 ossimPlanetTextureLayerGroup::numberOfLayers()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   return theChildrenList.size();
+}
+
+const osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetTextureLayerGroup::layer(ossim_uint32 idx)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   if(idx < theChildrenList.size())
+   {
+      return theChildrenList[idx];
+   }
+
+   return 0;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetTextureLayerGroup::layer(ossim_uint32 idx)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+   if(idx < theChildrenList.size())
+   {
+      return theChildrenList[idx];
+   }
+
+   return 0;
+}
+
+static bool gsdCmp( osg::ref_ptr<ossimPlanetTextureLayer> a, osg::ref_ptr<ossimPlanetTextureLayer> b )
+{
+   osg::ref_ptr<ossimPlanetExtents> aExtents = a->getExtents();
+   osg::ref_ptr<ossimPlanetExtents> bExtents = b->getExtents();
+
+   double aScale = aExtents->getMinScale();
+   double bScale = bExtents->getMinScale();
+   
+   if(aScale > 0.0)
+   {
+      if(bScale > 0.0)
+      {
+         return aScale < bScale;
+      }
+   }
+   else if(bScale > 0.0)
+   {
+      return false;
+   }
+
+   return true;
+}
+
+
+void ossimPlanetTextureLayerGroup::setFillNullOrEmptyTileMaxLevel(ossim_int32 maxLevel)
+{
+   theFillEmptyNullTileMaxLevel = maxLevel;
+}
+
+void ossimPlanetTextureLayerGroup::setBackgroundColor(const osg::Vec4f& color)
+{
+   theBackgroundColor = color;
+}
+
+void ossimPlanetTextureLayerGroup::setFillTranslucentPixelsWithBackground(bool on)
+{
+   theFillTranslucentPixelsWithBackgroundEnabled = on;
+}
+
+void ossimPlanetTextureLayerGroup::sortByGsd()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theChildrenListMutex);
+
+   std::sort(theChildrenList.begin(),
+             theChildrenList.end(),
+             gsdCmp);
+}
+
+bool ossimPlanetTextureLayerGroup::containsLayerNoMutex(osg::ref_ptr<ossimPlanetTextureLayer> layer)const
+{
+   std::stack<const ossimPlanetTextureLayerGroup* >tempStack;
+//   ossim_uint32 idx = 0;
+   tempStack.push(this);
+
+   while(!tempStack.empty())
+   {
+      const ossimPlanetTextureLayerGroup* current = tempStack.top();
+      tempStack.pop();
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < current->theChildrenList.size(); ++idx)
+      {
+         if(current->theChildrenList[idx].get() == layer.get())
+         {
+           return true;
+         }
+         if(current->theChildrenList[idx].valid())
+         {
+            if(current->theChildrenList[idx]->asGroup())
+            {
+               tempStack.push(current->theChildrenList[idx]->asGroup());
+            }
+         }
+      }
+   }   
+
+   return false;   
+}
+
+ossimRefPtr<ossimXmlNode> ossimPlanetTextureLayerGroup::saveXml(bool recurseFlag)const
+{
+   ossimRefPtr<ossimXmlNode> result = ossimPlanetTextureLayer::saveXml(recurseFlag);
+   
+   if(recurseFlag)
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theChildrenList.size(); ++idx)
+      {
+         ossimRefPtr<ossimXmlNode> node = theChildrenList[idx]->saveXml().get();
+         result->addChildNode(node.get());
+      }
+   }
+
+   return result;
+}
+
+bool ossimPlanetTextureLayerGroup::loadXml(ossimRefPtr<ossimXmlNode> node)
+{
+   std::cout << "ossimPlanetTextureLayerGroup::loadXml: NOT IMPLEMENTED YET!!!" << std::endl;
+   return ossimPlanetTextureLayer::loadXml(node);
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerRegistry.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerRegistry.cpp
new file mode 100644
index 0000000..09f3ec3
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTextureLayerRegistry.cpp
@@ -0,0 +1,105 @@
+#include <algorithm>
+
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <ossimPlanet/ossimPlanetStandardTextureLayerFactory.h>
+#include <OpenThreads/ScopedLock>
+#include <iostream>
+
+ossimPlanetTextureLayerRegistry* ossimPlanetTextureLayerRegistry::theInstance = 0;
+
+ossimPlanetTextureLayerRegistry::ossimPlanetTextureLayerRegistry()
+{
+   theInstance    = this;
+   destroyingFlag = true;
+}
+
+ossimPlanetTextureLayerRegistry::~ossimPlanetTextureLayerRegistry()
+{
+   destroyingFlag = true;
+
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theFactoryList.size(); ++idx)
+   {
+      delete theFactoryList[idx];
+      theFactoryList[idx] = 0;
+   }
+   
+   theInstance = 0;
+   
+}
+
+ossimPlanetTextureLayerRegistry* ossimPlanetTextureLayerRegistry::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetTextureLayerRegistry;
+      theInstance->registerFactory(ossimPlanetStandardTextureLayerFactory::instance());
+   }
+
+   return theInstance;
+}
+
+void ossimPlanetTextureLayerRegistry::registerFactory(ossimPlanetTextureLayerFactory* factory)
+{
+   theFactoryListMutex.writeLock();
+   if(!containsFactory(factory))
+   {
+      theFactoryList.push_back(factory);
+   }
+   theFactoryListMutex.writeUnlock();
+}
+
+void ossimPlanetTextureLayerRegistry::registerFactoryToFront(ossimPlanetTextureLayerFactory* factory)
+{
+   theFactoryListMutex.writeLock();
+   if(!containsFactory(factory))
+   {
+      theFactoryList.insert(theFactoryList.begin(), factory);
+   }
+   theFactoryListMutex.writeUnlock();
+}
+
+void ossimPlanetTextureLayerRegistry::unregisterFactory(ossimPlanetTextureLayerFactory* factory)
+{
+   if(destroyingFlag) return;
+   theFactoryListMutex.writeLock();
+   
+   std::vector<ossimPlanetTextureLayerFactory*>::iterator iter = std::find(theFactoryList.begin(),
+                                                                                         theFactoryList.end(),
+                                                                                         factory);
+
+   if(iter != theFactoryList.end())
+   {
+      theFactoryList.erase(iter);
+   }
+   theFactoryListMutex.writeUnlock();
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetTextureLayerRegistry::createLayer(const ossimString& name, bool openAllEntriesFlag)const
+{
+   ossim_uint32 idx=0;
+   osg::ref_ptr<ossimPlanetTextureLayer>   result;
+   theFactoryListMutex.readLock();
+   for(idx = 0; ((idx < theFactoryList.size())&&(!result.valid()));++idx)
+   {
+      result = theFactoryList[idx]->createLayer(name, openAllEntriesFlag);
+   }
+   theFactoryListMutex.readUnlock();
+   return result;
+}
+
+bool ossimPlanetTextureLayerRegistry::containsFactory(ossimPlanetTextureLayerFactory* factory)const
+{
+   ossim_uint32 idx = 0;
+
+   for(idx = 0; idx < theFactoryList.size(); ++idx)
+   {
+      if(theFactoryList[idx] == factory)
+      {
+         return true;
+      }
+   }
+
+   return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetThread.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetThread.cpp
new file mode 100644
index 0000000..7ce9520
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetThread.cpp
@@ -0,0 +1,77 @@
+#include <ossimPlanet/ossimPlanetThread.h>
+#include <ossimPlanet/ossimPlanetThreadPool.h>
+
+ossimPlanetThread::ossimPlanetThread()
+{
+   theImplementation = 0;
+   theThreadPool     = 0;
+   theRetainThreadFlag = false;
+}
+
+void ossimPlanetThread::run()
+{
+   if(theImplementation)
+   {
+      theImplementation->run();
+      if(theThreadPool&&!theRetainThreadFlag)
+      {
+         theThreadPool->makeAvailable(this);
+      }
+   }
+}
+
+int ossimPlanetThread::cancel()
+{
+   if(theImplementation)
+   {
+      theImplementation->cancel();
+      while(isRunning())
+      {
+         OpenThreads::Thread::YieldCurrentThread();
+      }
+   }
+   
+   return 0;
+}
+
+void ossimPlanetThread::updateThreadBlock()
+{
+   if(theImplementation)
+   {
+      theImplementation->updateThreadBlock();
+   }
+}
+
+void ossimPlanetThread::setImplementation(ossimPlanetThreadImp* implementation)
+{
+   if(theImplementation)
+   {
+      theImplementation->setThread(0);
+      theImplementation->cancel();
+   }
+   theImplementation = implementation;
+   if(theImplementation)
+   {
+      theImplementation->setThread(this);
+   }
+}
+
+void ossimPlanetThread::setThreadPool(ossimPlanetThreadPool* threadPool)
+{
+   theThreadPool = threadPool;
+}
+
+ossimPlanetThreadImp* ossimPlanetThread::implementation()
+{
+   return theImplementation;
+}
+
+const ossimPlanetThreadImp* ossimPlanetThread::implementation()const
+{
+   return theImplementation;
+}
+
+void ossimPlanetThread::setRetainThreadFlag(bool flag)
+{
+   theRetainThreadFlag = flag;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetThreadImp.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetThreadImp.cpp
new file mode 100644
index 0000000..27deb20
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetThreadImp.cpp
@@ -0,0 +1,33 @@
+#include <ossimPlanet/ossimPlanetThreadImp.h>
+#include <ossimPlanet/ossimPlanetThread.h>
+ossimPlanetThreadImp::~ossimPlanetThreadImp()
+{
+   
+}
+
+int ossimPlanetThreadImp::cancel()
+{
+   setDoneFlag(true);
+   updateThreadBlock();
+   return 0;
+}
+
+void ossimPlanetThreadImp::setDoneFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theImpMutex);
+   theDoneFlag = flag;
+}
+
+bool ossimPlanetThreadImp::doneFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theImpMutex);
+   return theDoneFlag;
+}
+
+void ossimPlanetThreadImp::threadPooled()
+{
+}
+
+void ossimPlanetThreadImp::updateThreadBlock()
+{
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetThreadPool.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetThreadPool.cpp
new file mode 100644
index 0000000..1ec4d3c
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetThreadPool.cpp
@@ -0,0 +1,84 @@
+#include <ossimPlanet/ossimPlanetThreadPool.h>
+#include <ossimPlanet/ossimPlanetThread.h>
+#include <algorithm>
+#include <iostream>
+#include <OpenThreads/ScopedLock>
+unsigned int ossimPlanetThreadPool::theMaxThreads = 32;
+
+osg::ref_ptr<ossimPlanetThreadPool> ossimPlanetThreadPool::theInstance = 0;
+osg::ref_ptr<ossimPlanetThreadPool> ossimPlanetThreadPool::instance()
+{
+   if(!theInstance)
+   {
+      theInstance = new ossimPlanetThreadPool;
+   }
+   return theInstance;
+}
+
+ossimPlanetThreadPool::ossimPlanetThreadPool()
+{
+   theInstance = this;
+}
+
+unsigned int ossimPlanetThreadPool::totalThreads()const
+{
+   return theAvailableList.size()+theUnavailableList.size();
+}
+
+
+void ossimPlanetThreadPool::makeAvailable(osg::ref_ptr<ossimPlanetThread> thread)
+{
+   ossimPlanetThreadImp* imp = thread->implementation();
+   bool pooled = false;
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theListMutex);
+      std::vector<osg::ref_ptr<ossimPlanetThread> >::iterator iter = std::find(theUnavailableList.begin(),
+                                                                             theUnavailableList.end(),
+                                                                             thread);
+      if(iter!=theUnavailableList.end())
+      {
+         pooled = true;
+         theUnavailableList.erase(iter);
+         thread->setImplementation(0);
+         theAvailableList.push_back(thread);
+      }
+   }
+   if(pooled)
+   {
+      imp->threadPooled();
+   }
+         
+   
+}
+
+osg::ref_ptr<ossimPlanetThread> ossimPlanetThreadPool::nextAvailable()
+{
+   osg::ref_ptr<ossimPlanetThread> thread = NULL;
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theListMutex);
+   if(theAvailableList.size() < 1)
+   {
+      if(totalThreads() < theMaxThreads)
+      {
+         osg::ref_ptr<ossimPlanetThread> thread = new ossimPlanetThread;
+         thread->setThreadPool(this);
+         theAvailableList.push_back(thread);
+      }
+      else
+      {
+         return thread;
+      }
+   }
+   if(theAvailableList.size() > 0)
+   {
+      thread = theAvailableList[theAvailableList.size()-1];
+      theAvailableList.pop_back();
+      theUnavailableList.push_back(thread);
+   }
+
+   return thread;
+}
+
+void ossimPlanetThreadPool::setMaxThread(int maxThreads)
+{
+  theMaxThreads = maxThreads;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetTileRequest.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetTileRequest.cpp
new file mode 100644
index 0000000..4abe45a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetTileRequest.cpp
@@ -0,0 +1,864 @@
+#include <ossimPlanet/ossimPlanetTileRequest.h>
+#include <ossimPlanet/ossimPlanetTerrainTile.h>
+#include <ossimPlanet/ossimPlanetTerrainLayer.h>
+#include <ossimPlanet/ossimPlanetTerrain.h>
+#include <ossimPlanet/ossimPlanetCubeGrid.h>
+#include <osgUtil/GLObjectsVisitor>
+#include <osg/Timer>
+
+#if (((OPENSCENEGRAPH_MAJOR_VERSION<2) || (OPENSCENEGRAPH_MAJOR_VERSION==2 && (OPENSCENEGRAPH_MINOR_VERSION<8 || (OPENSCENEGRAPH_MINOR_VERSION==8 && OPENSCENEGRAPH_PATCH_VERSION<=2)))))
+#   define USE_OLD_VBO_COMPILE 0
+#else
+#   define USE_OLD_VBO_COMPILE 1
+#endif
+void ossimPlanetTileRequest::FindCompileableGLObjectsVisitor::apply(osg::Node& node)
+{
+   apply(node.getStateSet());
+   
+   traverse(node);
+}
+
+void ossimPlanetTileRequest::FindCompileableGLObjectsVisitor::apply(osg::Geode& geode)
+{
+   apply(geode.getStateSet());
+   
+   for(unsigned int i=0;i<geode.getNumDrawables();++i)
+   {
+      apply(geode.getDrawable(i));
+   }
+   
+   traverse(geode);
+}
+
+void ossimPlanetTileRequest::FindCompileableGLObjectsVisitor::apply(osg::StateSet* stateset)
+{
+   if (stateset)
+   {
+      bool compileStateSet = false;
+      for(unsigned int i=0;i<stateset->getTextureAttributeList().size();++i)
+      {
+         osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
+         // Has this texture already been encountered?
+         if (texture && !theTextureSet.count(texture))
+         {
+         //   if (texture->getTextureParameterDirty(theContextId)||
+         //       (texture->getTextureObject(theContextId)==0))
+            {
+               theDataToCompile.textures.insert(texture);
+            }
+         }
+      }
+   }
+}
+
+void ossimPlanetTileRequest::FindCompileableGLObjectsVisitor::apply(osg::Drawable* drawable)
+{
+   if (theDrawableSet.count(drawable))
+      return;
+   
+   apply(drawable->getStateSet());
+ 
+   if(drawable->getUseVertexBufferObjects())
+   {
+      const osg::Geometry* geometry = drawable->asGeometry();
+      if(geometry)
+      { 
+         osg::Geometry::ArrayList arrayList;
+         geometry->getArrayList(arrayList);
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < arrayList.size();++idx)
+         {
+            if(arrayList[idx]->getVertexBufferObject())
+            {
+//               if(arrayList[idx]->getVertexBufferObject()->isDirty(theContextId))
+               {
+//	               theDataToCompile.vbos.insert(arrayList[idx]->getVertexBufferObject());
+               }
+            }
+         }
+      }
+   }
+}
+
+ossimPlanetTileRequest::ossimPlanetTileRequest(ossimPlanetTerrainTile* tile)
+{
+   setThreadSafeRefUnref(true);
+   setTile(tile);
+}
+
+void ossimPlanetTileRequest::setTile(ossimPlanetTerrainTile* tile)
+{
+   theTile = tile;
+   if(theTile.valid())
+   {
+      theTileId  = theTile->tileId();
+      theTerrain = theTile->terrain();
+   }
+}
+ossimPlanetTerrainTile* ossimPlanetTileRequest::tile()
+{
+   return theTile.get();
+}
+
+const ossimPlanetTerrainTile* ossimPlanetTileRequest::tile()const
+{
+   return theTile.get();
+}
+
+bool ossimPlanetTileRequest::compileObjects(osg::RenderInfo& renderInfo, 
+                                            double availableTimeInSeconds)
+{
+   return true; // we have finished
+}
+
+bool ossimPlanetTileRequest::populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                osgUtil::IncrementalCompileOperation::CompileSet& compileSet)
+{
+   return true;
+}
+
+ossimPlanetTileRequestQueue::ossimPlanetTileRequestQueue(bool sortFlag)
+:theCurrentFrameNumber(0),
+theSortFlag(sortFlag)
+{
+   
+}
+
+void ossimPlanetTileRequestQueue::sort()
+{
+   if(theSortFlag)
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+      theOperationQueue.sort(ossimPlanetTileRequest::SortFunctor());
+   }
+}
+
+osg::ref_ptr<ossimPlanetOperation> ossimPlanetTileRequestQueue::nextOperation(bool blockIfEmptyFlag)
+{
+   {
+      OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+      ossimPlanetOperation::List::iterator iter = theOperationQueue.begin();
+      ossimPlanetOperation::List::iterator endIter = theOperationQueue.end();
+      
+      while(iter != endIter)
+      {
+         // std::cout << "CHECKING STOPPED!!!!!!!!!!!!!!!!"<< std::endl;
+         ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>((*iter).get());
+         if(!tileRequest->isRequestCurrent(theCurrentFrameNumber)||tileRequest->isStopped())
+         {
+            iter = theOperationQueue.erase(iter);
+         }
+         else
+         {
+            ++iter;
+         }
+      }
+   }
+   if(theSortFlag)
+   {
+      sort();
+   }
+   osg::ref_ptr<ossimPlanetOperation> operation = ossimPlanetOperationQueue::nextOperation(blockIfEmptyFlag).get();
+   while(operation.valid())
+   {
+      ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>(operation.get());
+      if(!tileRequest)
+      {
+         return operation;
+      }
+      if(tileRequest->isRequestCurrent(theCurrentFrameNumber)&&!tileRequest->isStopped())
+      {
+         return operation;
+      }
+      operation = 0;
+      operation = ossimPlanetOperationQueue::nextOperation(blockIfEmptyFlag).get();
+   }
+   
+   return 0;
+}
+
+void ossimPlanetTileRequestQueue::add(ossimPlanetTileRequest* request)
+{
+   if(request)
+   {
+      if(request->referenceCount() == 1)
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theOperationQueueMutex);
+         request->setState(ossimPlanetOperation::READY_STATE);
+         theOperationQueue.push_back(request);
+      }
+   }
+}
+
+void ossimPlanetTileRequestThreadQueue::add(ossimPlanetTileRequest* request)
+
+{
+   if(request)
+   {
+      if(request->referenceCount() == 1)
+      {
+         ossimPlanetOperationThreadQueue::add(request);
+      }
+   }
+}
+void ossimPlanetTileRequestThreadQueue::run()
+{
+   bool firstTime = true;
+   
+   do
+   {
+      // osg::notify(osg::NOTICE)<<"In thread loop "<<this<<std::endl;
+      osg::ref_ptr<ossimPlanetOperation> operation;
+      osg::ref_ptr<ossimPlanetOperationQueue> queue;
+      
+      {
+         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+         queue = theOperationQueue;
+      }
+      operation = queue->nextOperation(true);
+      
+      if (theDoneFlag) break;
+      
+      if (operation.valid())
+      {
+         ossimPlanetTileRequest* request = dynamic_cast<ossimPlanetTileRequest*>(operation.get());
+         if(request&&request->isRequestCurrent(theCurrentFrameNumber))
+         {
+            {
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+               theCurrentOperation = operation;
+            }
+            
+            if(operation->state() == ossimPlanetOperation::READY_STATE)
+            {
+               operation->start();
+               if(operation->state() != ossimPlanetOperation::CANCELED_STATE)
+               {
+                  ossimPlanetTileRequest* tileRequest = dynamic_cast<ossimPlanetTileRequest*>(operation.get());
+                  if(tileRequest)
+                  {
+                     osg::ref_ptr<ossimPlanetTerrainTile> tile = tileRequest->tile();
+                     if(tile.valid())
+                     {
+                        if(tileRequest->needsToCompile())
+                        {
+
+                           tile->terrain()->addRequestToNeedToCompileQueue(tileRequest);
+                        }
+                        else
+                        {
+                           tile->terrain()->addRequestToReadyToApplyQueue(tileRequest);
+                        }
+                     }
+                  }
+               }
+            }
+            {            
+               OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theThreadMutex);
+               theCurrentOperation = 0;
+            }
+         }
+         operation = 0;
+      }
+      
+      if (firstTime)
+      {
+         // do a yield to get round a peculiar thread hang when testCancel() is called 
+         // in certain cirumstances - of which there is no particular pattern.
+         YieldCurrentThread();
+         firstTime = false;
+      }
+   } while (!testCancel() && !theDoneFlag);
+}
+
+#if 0
+void ossimPlanetTerrain::TileRequestThreadQueue::applyToGraph(double availableTime)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theFinishedOperationsListMutex);
+   osg::Timer_t startTick = osg::Timer::instance()->tick();
+   bool doneFlag = theFinishedOperationsList.empty();
+   ossim_uint32 operationCount = 0;
+   while(!doneFlag)
+   {
+      theFinishedOperationsList.sort(SortRequestFunctor());
+      (*theFinishedOperationsList.begin())->applyToGraph();
+      theFinishedOperationsList.erase(theFinishedOperationsList.begin());
+      ++operationCount;
+      double delta = osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick());
+      doneFlag = (theFinishedOperationsList.empty()||
+                  (delta > availableTime)||
+                  (operationCount >=theMaxNumberOfOperationsToApply));
+   }
+}
+#endif
+
+ossimPlanetSplitRequest::ossimPlanetSplitRequest(ossimPlanetTerrainTile* tile)
+:ossimPlanetTileRequest(tile)
+{
+   if(tile)
+   {
+      tile->vacantChildIds(theNeededChildrenList);
+   }
+   
+}
+
+
+void ossimPlanetSplitRequest::run()
+{
+   theNewTiles.clear();
+   if((theNeededChildrenList.size()>0)&&(state()!=CANCELED_STATE)&&(theTile.valid()))
+   {
+      ossim_uint32 idx = 0;
+      osg::ref_ptr<ossimPlanetTerrainImageLayer> elevationLayer = theTile->elevationLayer();
+      if(!elevationLayer)
+      {
+         return;
+      }
+      ossim_uint32 textureWidth    = theTile->terrain()->textureTileWidth();
+      ossim_uint32 textureHeight   = theTile->terrain()->textureTileHeight();
+      ossim_uint32 elevationWidth  = theTile->terrain()->elevationTileWidth();
+      ossim_uint32 elevationHeight = theTile->terrain()->elevationTileHeight();
+      osg::ref_ptr<ossimPlanetImage> inputElevationImage = elevationLayer->image();
+      osg::ref_ptr<ossimPlanetImage> scaledImage;
+      //               elevationImage = new ossimPlanetImage(inputElevationImage->tileId());
+      //               elevationImage->allocateImage(inputElevationImage->widthWithoutPadding(), 
+      //                                             inputElevationImage->heightWithoutPadding(), 
+      //                                             1, 
+      //                                             inputElevationImage->getPixelFormat(), 
+      //                                             inputElevationImage->getDataType(), 
+      //                                             inputElevationImage->getPacking());
+      //               elevationImage->setPadding(0);
+      
+      if(inputElevationImage.valid())
+      {
+         if(inputElevationImage->padding() > 0)
+         {
+            // strip padding for scaling
+            //
+            osg::ref_ptr<ossimPlanetImage> tempImage = new ossimPlanetImage(*inputElevationImage);
+            tempImage->stripPadding();
+            inputElevationImage = tempImage;
+         }
+         
+         scaledImage = inputElevationImage->scaleImagePowerOf2();
+     }
+      if(theNeededChildrenList.size() > 0)
+      {
+         ossimPlanetTerrainTile* newTile = new ossimPlanetTerrainTile(theNeededChildrenList[idx]);
+         newTile->setTerrain(theTerrain.get());
+         ossim_uint32 idx2 = 0;
+         for(idx2 = 0; idx2 < newTile->numberOfImageLayers(); ++idx2)
+         {
+            if(theTile->imageLayer(idx2) && newTile->imageLayer(idx2))
+            {
+#if 1
+               bool hasDataFlag = newTile->terrain()->textureLayer(idx2)->hasTexture(textureWidth, 
+                                                                                     textureHeight,
+                                                                                     newTile->tileId(), 
+                                                                                     *theTile->grid());
+               newTile->imageLayer(idx2)->setNoMoreDataFlag(!hasDataFlag);//theTile->imageLayer(idx2)->noMoreDataFlag());
+#else
+               newTile->imageLayer(idx2)->setNoMoreDataFlag(theTile->imageLayer(idx2)->noMoreDataFlag());
+#endif
+               
+            }
+         }
+         osg::ref_ptr<ossimPlanetImage> elevationImage;
+         osg::ref_ptr<ossimPlanetImageCache> cache = theTile->terrain()->elevationCache();
+         if(cache.valid())
+         {
+            elevationImage = cache->get(newTile->tileId());
+         }
+         // interpolate elevation if it's present
+         //
+         if(!elevationImage.valid())
+         {
+            if(inputElevationImage.valid())
+            {
+               bool hasDataFlag = newTile->terrain()->elevationLayer()->hasTexture(elevationWidth, 
+                                                                                   elevationHeight,
+                                                                                   newTile->tileId(), 
+                                                                                   *theTile->grid());
+//               ossim_uint32 xLength = inputElevationImage->s()>>1;
+//               ossim_uint32 yLength = inputElevationImage->t()>>1;
+               ossim_uint32 x;
+               ossim_uint32 y;
+               theTile->terrainTechnique()->childTreePosition(theNeededChildrenList[idx], x, y);
+               
+#if 1
+               x=x*(scaledImage->getWidth()*.5)  - x*scaledImage->padding();
+               y=y*(scaledImage->getHeight()*.5) - y*scaledImage->padding();
+//               elevationImage = new ossimPlanetImage(inputElevationImage->tileId());
+//               elevationImage->allocateImage(inputElevationImage->widthWithoutPadding(), 
+//                                             inputElevationImage->heightWithoutPadding(), 
+//                                             1, 
+//                                             inputElevationImage->getPixelFormat(), 
+//                                             inputElevationImage->getDataType(), 
+//                                             inputElevationImage->getPacking());
+//               elevationImage->setPadding(0);
+               elevationImage = new ossimPlanetImage(*inputElevationImage.get());
+               scaledImage->copyTo(x, y, elevationImage.get());
+#else
+               elevationImage = new ossimPlanetImage(*inputElevationImage.get());
+               x=x*(elevationImage->getWidth()*.5) - x*elevationImage->padding();
+               y=y*(elevationImage->getHeight()*.5) - y*elevationImage->padding();
+               elevationImage->copySubImageAndInsertPointsPowerOf2(x,
+                                                                   y,
+                                                                   elevationImage->getWidth(),
+                                                                   elevationImage->getHeight(),
+                                                                   inputElevationImage.get());
+#endif
+//               std::cout << "scaled w, h = " << scaledImage->getWidth() << ", " << scaledImage->getHeight() << std::endl;
+//               std::cout << "w, h = " << inputElevationImage->getWidth() << ", " << inputElevationImage->getHeight() << std::endl;
+//               std::cout << "x, y = " << x << ", " << y << std::endl;
+               
+               newTile->elevationLayer()->setImage(elevationImage.get());
+            }
+            //     newTile->elevationLayer()->setNoMoreDataFlag(!hasDataFlag);//theTile->elevationLayer()->noMoreDataFlag());
+            newTile->elevationLayer()->setNoMoreDataFlag(theTile->elevationLayer()->noMoreDataFlag());
+         }
+         else
+         {
+            newTile->elevationLayer()->setImage(elevationImage.get());
+            newTile->elevationLayer()->setNoMoreDataFlag(theTile->elevationLayer()->noMoreDataFlag());
+         }
+         newTile->init();
+         theNewTiles.push_back(newTile);
+      }
+   }
+}
+
+bool ossimPlanetSplitRequest::populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                                osgUtil::IncrementalCompileOperation::CompileSet& compileSet)
+{
+  if((state()!=CANCELED_STATE)&&theNewTiles.size()&&theTile.valid())
+   {
+      if(theDataToCompile.textures.empty()&&
+         theDataToCompile.vbos.empty())
+      {
+         FindCompileableGLObjectsVisitor visitor(theDataToCompile,
+                                                 theTerrain.get(),
+                                                 0);
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < theNewTiles.size() ; ++idx)
+         {
+            theNewTiles[idx]->accept(visitor);
+         }
+      }
+      if(!theDataToCompile.textures.empty())
+      {
+          for(osgUtil::IncrementalCompileOperation::ContextSet::iterator itr = contexts.begin();
+              itr != contexts.end();
+              ++itr)
+          {
+            ++compileSet._numberCompileListsToCompile;
+
+            osgUtil::IncrementalCompileOperation::CompileList& cl = compileSet._compileMap[*itr];
+
+            for(TextureSetList::iterator iter = theDataToCompile.textures.begin();
+               iter!=theDataToCompile.textures.end();++iter)
+            {
+               cl.add((*iter).get());
+            }
+         }
+      }
+   }
+   return true;
+}
+bool ossimPlanetSplitRequest::compileObjects(osg::RenderInfo& renderInfo, 
+                                             double availableTimeInSeconds)
+{
+ //  osg::Timer_t tick = osg::Timer::instance()->tick();
+   if((state()!=CANCELED_STATE)&&theNewTiles.size()&&theTile.valid()&&renderInfo.getState())
+   {
+      if(theDataToCompile.textures.empty()&&
+         theDataToCompile.vbos.empty())
+      {
+         FindCompileableGLObjectsVisitor visitor(theDataToCompile,
+                                                 theTerrain.get(),
+                                                 renderInfo.getState()->getContextID());
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < theNewTiles.size() ; ++idx)
+         {
+            theNewTiles[idx]->accept(visitor);
+         }
+      }
+      // do textures first
+      while(!theDataToCompile.textures.empty())
+      {
+         (*theDataToCompile.textures.begin())->compileGLObjects(*renderInfo.getState());
+         theDataToCompile.textures.erase(theDataToCompile.textures.begin());
+      }
+      while(!theDataToCompile.vbos.empty())
+      {
+#if 0
+#if USE_OLD_VBO_COMPILE
+       (*theDataToCompile.vbos.begin())->compileBuffer(*renderInfo.getState());
+#else
+         osg::GLBufferObject* glBufferObj = (*theDataToCompile.vbos.begin())->getOrCreateGLBufferObject(renderInfo.getState()->getContextID());
+
+         if(glBufferObj&&glBufferObj->isDirty())
+         {
+            glBufferObj->compileBuffer();
+         }
+#endif
+#endif
+         theDataToCompile.vbos.erase(theDataToCompile.vbos.begin());
+
+      }
+   }
+   if(state()==CANCELED_STATE)
+   {
+      theNewTiles.clear();
+   }
+   
+   return true;
+//   if(osg::Timer::instance()->delta_m(tick, osg::Timer::instance()->tick()) > 1.0)
+//   {
+//      std::cout << "ossimPlanetTextureRequest::compile: TOO LONG!!!!" << std::endl;
+//   }
+}
+
+
+void ossimPlanetSplitRequest::applyToGraph()
+{
+   if((state()!=CANCELED_STATE)&&
+       theTile.valid()&&theNewTiles.size())//&&(theTile->state() ==  ossimPlanetTerrainTile::NEED_SPLITTING))
+   {
+      ossim_uint32 idx = 0;
+      for(idx = 0; idx < theNewTiles.size();++idx)
+      {
+         theTile->addChild(theNewTiles[idx].get());
+      }
+   }
+   theNewTiles.clear();
+}
+
+void ossimPlanetSplitRequest::setTile(ossimPlanetTerrainTile* tile)
+{
+   ossimPlanetTileRequest::setTile(tile);
+   theNeededChildrenList.clear();
+   if(tile)
+   {
+      tile->vacantChildIds(theNeededChildrenList);
+   }
+}
+
+ossimPlanetTextureRequest::ossimPlanetTextureRequest()
+:ossimPlanetTileRequest(){
+}
+
+ossimPlanetTextureRequest::ossimPlanetTextureRequest(ossimPlanetTerrainTile* tile, 
+                                                   ossim_uint32 imageLayerIdx)
+:ossimPlanetTileRequest(tile)
+{
+   setImageLayerIdx(imageLayerIdx);
+}
+
+void ossimPlanetTextureRequest::setTextureLayerIndices(const std::vector<ossim_uint32>& values)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   ossim_uint32 idx;
+   theResultList.clear();
+   for(idx = 0; idx < values.size();++idx)
+   {
+      theResultList.insert(std::make_pair(values[idx], Result()));
+   }
+}
+
+void ossimPlanetTextureRequest::run()
+{
+   if(theTile.valid()&&theTerrain.valid())
+   {
+      if(state() != CANCELED_STATE)
+      {
+         ossim_uint32 w,h;
+         w = theTile->terrain()->textureTileWidth();
+         h = theTile->terrain()->textureTileHeight();
+         
+         const ossimPlanetTerrainTileId& tileId = theTile->tileId();
+         TextureResultMap::iterator iter = theResultList.begin();
+         while(iter!=theResultList.end())
+         {
+            osg::ref_ptr<ossimPlanetTerrainImageLayer> imageLayer = theTile->imageLayer(iter->first);
+            osg::ref_ptr<ossimPlanetTextureLayer> layer = theTerrain->textureLayer(iter->first);
+            if(layer.valid())
+            {
+               iter->second.theImage = layer->getTexture(w,
+                                                         h,
+                                                         tileId,
+                                                         *theTile->grid());
+               if(iter->second.theImage.valid())
+               {
+                  iter->second.theImage->setId(tileId);
+                  iter->second.theTexture = theTile->terrainTechnique()->newImageLayerTexture(iter->first);
+                  iter->second.theTexture->setImage(iter->second.theImage.get());
+               }
+            }
+            ++iter;
+         }
+      }
+   }
+}
+
+
+bool ossimPlanetTextureRequest::compileObjects(osg::RenderInfo& renderInfo, 
+                                               double availableTimeInSeconds)
+{
+   osg::Timer_t tick = osg::Timer::instance()->tick();
+   TextureResultMap::iterator iter = theResultList.begin();
+   while(iter!=theResultList.end())
+   {
+      if((state()!=CANCELED_STATE)&&
+         iter->second.theTexture.get()&&
+         theTile.valid()&&renderInfo.getState())
+      {
+         if ((iter->second.theTexture->getTextureParameterDirty(renderInfo.getState()->getContextID()))||
+             (iter->second.theTexture->getTextureObject(renderInfo.getState()->getContextID())==0))
+         {
+            iter->second.theTexture->compileGLObjects(*renderInfo.getState());
+         }
+      }
+      //double delta = osg::Timer::instance()->delta_s(tick, osg::Timer::instance()->tick());
+      ++iter;
+   }
+      
+   return true; // no more compilation required
+}
+
+bool ossimPlanetTextureRequest::populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                                osgUtil::IncrementalCompileOperation::CompileSet& compileSet)
+{
+  if((state()!=CANCELED_STATE))
+   {
+      if(!theResultList.empty())
+      {
+          for(osgUtil::IncrementalCompileOperation::ContextSet::iterator itr = contexts.begin();
+              itr != contexts.end();
+              ++itr)
+          {
+            ++compileSet._numberCompileListsToCompile;
+
+            osgUtil::IncrementalCompileOperation::CompileList& cl = compileSet._compileMap[*itr];
+            TextureResultMap::iterator iter = theResultList.begin();
+            while(iter!=theResultList.end())
+            {
+               cl.add(iter->second.theTexture.get());
+               ++iter;
+            }
+         }
+
+      }
+   }
+   return true;
+}
+
+
+void ossimPlanetTextureRequest::applyToGraph()
+{
+   //std::cout << " ossimPlanetTerrain::TextureRequest::applyToGraph() entered...." << std::endl;
+   if(state()!=CANCELED_STATE)
+   {
+      TextureResultMap::iterator iter = theResultList.begin();
+      while(iter!=theResultList.end()&&theTile.valid())
+      {
+         
+         if(iter->second.theTexture.valid())
+         {
+            theTile->terrainTechnique()->setImageLayerTexture(iter->second.theTexture.get(), iter->first);
+         }
+         else
+         {
+            if(theTile->imageLayer(iter->first))
+            {
+               theTile->imageLayer(iter->first)->setNoMoreDataFlag(true);
+            }
+         }
+         ++iter;
+      }
+   }
+}
+
+ossimPlanetElevationRequest::ossimPlanetElevationRequest()
+:ossimPlanetTileRequest()
+{
+}
+
+ossimPlanetElevationRequest::ossimPlanetElevationRequest(ossimPlanetTerrainTile* tile,
+                                                         ossim_uint32 width,
+                                                         ossim_uint32 height)
+:ossimPlanetTileRequest(tile)
+{
+}
+
+void ossimPlanetElevationRequest::run()
+{
+   theNewMesh = 0;
+   theImage   = 0;
+   theDataToCompile.textures.clear();
+   theDataToCompile.vbos.clear();
+   ossim_int32 padding = 1;
+   if(theTile.valid()&&theTile->grid()&&theTile->terrain())
+   {
+      if(state() != CANCELED_STATE)
+      {
+         ossim_uint32 w, h;
+         w = theTile->terrain()->elevationTileWidth();
+         h = theTile->terrain()->elevationTileHeight();
+         osg::ref_ptr<ossimPlanetTerrainImageLayer> imageLayer = theTile->elevationLayer();
+         osg::ref_ptr<ossimPlanetTextureLayer> elevLayer = theTile->terrain()->elevationLayer();
+         if(imageLayer.valid()&&elevLayer.valid())
+         {
+            osg::ref_ptr<ossimPlanetImageCache> cache = theTile->terrain()->elevationCache();
+            if(cache.valid())
+            {
+               theImage = cache->get(theTile->tileId());
+            }
+//            if(elevLayer->hasTexture(w,
+//                                     h,
+//                                    theTile->tileId(),
+//                                    *theTile->grid()) || (theTile->tileId().level()==0))
+            {
+               const ossimPlanetTerrainTileId& tileId = theTile->tileId();
+               if(!theImage)
+               {
+                  theImage = elevLayer->getTexture(w,
+                                                   h,
+                                                   theTile->tileId(),
+                                                   *theTile->grid(),
+                                                   padding);
+                  if(cache.valid())
+                  {
+                     cache->addOrUpdate(theImage.get());
+                  }
+               }
+               if(theImage.valid())
+               {
+                  theImage->setId(tileId);
+                  
+                  theNewMesh = new ossimPlanetTerrainTile(theTile->tileId());
+                  theNewMesh->copyCommonParameters(theTile.get());
+                  //imageLayer->setImage(theImage.get());
+                  //imageLayer->setRefreshFlag(false);
+                  theNewMesh->elevationLayer()->setImage(theImage.get());
+                  theNewMesh->init();
+               }
+               else
+               {
+                  //std::cout << "NO ELEVATION" << std::endl;
+               }
+            }
+#if 0
+            else
+            {
+               if(theTile->parentTile())
+               {
+                  osg::ref_ptr<ossimPlanetImage> img = theTile->parentTile()->elevationLayer()->image();
+                  if(img.valid())
+                  {
+                     // we will do it the way the split does it
+                     //
+                     std::cout << "WE CAN SPLIT!!!!" << std::endl;
+                  }
+                  else
+                  {
+                     std::cout << "WE CAN'T SPLIT!!!!" << std::endl;
+                  }
+               }
+               else
+               {
+                  std::cout << "NO PARENT WE CAN'T SPLIT!!!!" << std::endl;
+               }
+            }
+#endif
+         }
+      }
+   }
+}
+
+bool ossimPlanetElevationRequest::compileObjects(osg::RenderInfo& renderInfo, 
+                                                 double availableTimeInSeconds)
+{
+   if(!renderInfo.getState()||!theNewMesh.valid()) return true; // no more to compile
+   if(theDataToCompile.textures.empty()&&
+      theDataToCompile.vbos.empty())
+   {
+      FindCompileableGLObjectsVisitor visitor(theDataToCompile,
+                                              theTerrain.get(),
+                                              renderInfo.getState()->getContextID());
+      theNewMesh->accept(visitor);
+   }
+   // do textures first
+   while(!theDataToCompile.textures.empty())
+   {
+      (*theDataToCompile.textures.begin())->compileGLObjects(*renderInfo.getState());
+      theDataToCompile.textures.erase(theDataToCompile.textures.begin());
+   }
+   while(!theDataToCompile.vbos.empty())
+   {
+#if 0
+#if USE_OLD_VBO_COMPILE
+       (*theDataToCompile.vbos.begin())->compileBuffer(*renderInfo.getState());
+#else
+      osg::GLBufferObject* glBufferObj = (*theDataToCompile.vbos.begin())->getOrCreateGLBufferObject(renderInfo.getState()->getContextID());
+      if(glBufferObj&&glBufferObj->isDirty())
+      {
+         glBufferObj->compileBuffer();
+      }
+#endif
+#endif
+      theDataToCompile.vbos.erase(theDataToCompile.vbos.begin());
+   }
+//   osg::Timer_t tick = osg::Timer::instance()->tick();
+   if(state()==CANCELED_STATE)
+   {
+      theNewMesh = 0;
+   }  
+   return true; // no more to compile
+}
+bool ossimPlanetElevationRequest::populateCompileSet(osgUtil::IncrementalCompileOperation::ContextSet& contexts, 
+                                                osgUtil::IncrementalCompileOperation::CompileSet& compileSet)
+{
+  if((state()!=CANCELED_STATE))
+   {
+      if(theDataToCompile.textures.empty()&&
+         theDataToCompile.vbos.empty())
+      {
+         FindCompileableGLObjectsVisitor visitor(theDataToCompile,
+                                                 theTerrain.get(),
+                                                 0);
+         theNewMesh->accept(visitor);
+      }
+      if(!theDataToCompile.textures.empty())
+      {
+         ossim_uint32 idx = 0;
+          for(osgUtil::IncrementalCompileOperation::ContextSet::iterator itr = contexts.begin();
+              itr != contexts.end();
+              ++itr)
+          {
+            ++compileSet._numberCompileListsToCompile;
+
+            osgUtil::IncrementalCompileOperation::CompileList& cl = compileSet._compileMap[*itr];
+
+            // do textures first
+            for(TextureSetList::iterator iter = theDataToCompile.textures.begin();
+               iter!=theDataToCompile.textures.end();++iter)
+            {
+               cl.add((*iter).get());
+            }
+         }
+      }
+   }
+   return true;
+}
+
+void ossimPlanetElevationRequest::applyToGraph()
+{
+   if((state()!=CANCELED_STATE)&&theTile.valid()&&theImage.valid()&&theNewMesh.valid())
+   {
+      osg::ref_ptr<ossimPlanetTerrainImageLayer> imageLayer = theTile->elevationLayer();
+      theTile->terrainTechnique()->setElevationMeshFrom(theNewMesh.get());
+   }
+   theNewMesh = 0;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetUtility.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetUtility.cpp
new file mode 100644
index 0000000..bf22f5d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetUtility.cpp
@@ -0,0 +1,129 @@
+#include "ossimPlanet/ossimPlanetUtility.h"
+#include <math.h>
+
+void ossimPlanetUtility::ellipsoidToXYZ( const osg::EllipsoidModel& model,
+                                       double latitude, double longitude, double height,
+                                       double &x, double &y, double &z)
+{
+   model.convertLatLongHeightToXYZ(latitude,
+                                   longitude,
+                                   height,
+                                   x,
+                                   y,
+                                   z);
+   x/=model.getRadiusEquator();
+   y/=model.getRadiusEquator();
+   z/=model.getRadiusEquator();
+}
+
+osg::Vec3d ossimPlanetUtility::normal(const osg::EllipsoidModel& model,
+                                    double x, double y, double z)
+{
+   double bSquared = model.getRadiusPolar()/model.getRadiusEquator();
+   bSquared *= bSquared;
+   return osg::Vec3d((2.0*x),
+                     (2.0*y),
+                     (2.0*z)/bSquared);
+}
+
+void ossimPlanetUtility::XYZToEllipsoid(const osg::EllipsoidModel& model,
+                                      double x, double y, double z,
+                                      double& latitude, double& longitude, double& height)
+{
+   x*=model.getRadiusEquator();
+   y*=model.getRadiusEquator();
+   z*=model.getRadiusEquator();
+   model.convertXYZToLatLongHeight(x,
+                                   y,
+                                   z,
+                                   latitude,
+                                   longitude,
+                                   height);
+}
+
+bool ossimPlanetUtility::intersectsEllipsoid(const osg::EllipsoidModel& model,
+                                           osg::Vec3d& intersection,
+                                           const osg::Vec3d& start,
+                                           const osg::Vec3d& end)
+{
+   osg::Vec3d startPoint = start;//*model.getRadiusEquator();
+   osg::Vec3d endPoint   = end;//*model.getRadiusEquator();
+   /*
+    *Compute ellipsoid quadratics:
+    */
+//   double A = model.getRadiusEquator();
+//   double B = model.getRadiusPolar();
+     // double A = 1.0;
+    double B = model.getRadiusPolar()/model.getRadiusEquator();
+//   double A_squared = A*A;
+   double A_squared = 1.0;
+   double B_squared = (B*B);
+   osg::Vec3d direction = endPoint-startPoint;
+   direction.normalize();
+//   startPoint = startPoint + direction*.00001;
+   
+   //***
+   // get the origin and direction of ray:
+   //***
+
+   //***
+   // Solve the coefficents of the quadratic formula
+   //***
+   double a = ((direction[0] * direction[0])/A_squared) +
+              ((direction[1] * direction[1])/A_squared) +
+              ((direction[2] * direction[2])/B_squared);
+
+   double b = 2.0*( ((startPoint.x()*direction.x())/A_squared) +
+                    ((startPoint.y()*direction.y())/A_squared) +
+                    ((startPoint.z()*direction.z())/B_squared) );
+
+   double c = ((startPoint.x()*startPoint.x())/A_squared) +
+              ((startPoint.y()*startPoint.y())/A_squared) +
+              ((startPoint.z()*startPoint.z())/B_squared) - 1.0;
+   
+   //***
+   // solve the quadratic
+   //***
+   double root = b*b - 4*a*c;
+   double t;
+   if(root < 0.0)
+   {
+      return false;
+   }
+   else
+   {
+      double squareRoot = sqrt(root);
+      double t1 = (-b + squareRoot ) / (2.0*a);
+      double t2 = (-b - squareRoot ) / (2.0*a);
+
+      //***
+      // sort t1 and t2 and take the nearest intersection if they
+      // are in front of the ray.
+      //***
+      if(t2 < t1)
+      {
+         double temp = t1;
+         t1 = t2;
+         t2 = temp;
+      }     
+
+       if(t1 > 0.0)
+          t = t1;
+       else
+          t = t2;
+   }
+
+   //***
+   // Now apply solved t to ray to extrapolate correct distance to intersection
+   //***
+   bool rtnval = false;
+   if (t >= 0)
+   {
+      rtnval = true;
+      intersection  = start + direction*t;
+//      intersection = intersection*(1.0/model.getRadiusEquator());
+   }
+      
+   return rtnval; 
+   
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetVideoLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetVideoLayer.cpp
new file mode 100644
index 0000000..f3934d0
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetVideoLayer.cpp
@@ -0,0 +1,46 @@
+#include <ossimPlanet/ossimPlanetVideoLayer.h>
+#ifdef OSSIMPLANET_ENABLE_PREDATOR
+#include <ossimPlanet/ossimPlanetPredatorVideoLayerNode.h>
+#endif
+#include <ossimPlanet/ossimPlanet.h>
+#include <iostream>
+
+void ossimPlanetVideoLayer::traverse(osg::NodeVisitor& nv)
+{
+   if(!theEnableFlag) return;
+   
+   switch(nv.getVisitorType())
+   {
+      case osg::NodeVisitor::UPDATE_VISITOR:
+      {
+         if(!thePlanet)
+         {
+            thePlanet = ossimPlanet::findPlanet(this);
+         }
+         break;
+      }
+      default:
+      {
+         break;
+      }
+   }
+   
+   ossimPlanetLayer::traverse(nv);
+}
+
+bool ossimPlanetVideoLayer::add(const ossimFilename& file)
+{
+#ifdef OSSIMPLANET_ENABLE_PREDATOR
+   // later we will stage in a background thread but for now we will just open here for testing
+   // until we get the drawing working
+   //
+   osg::ref_ptr<ossimPlanetPredatorVideoLayerNode> node = new ossimPlanetPredatorVideoLayerNode(this);
+
+   if(node->open(file))
+   {
+      addChild(node.get());
+      return true;
+   }
+#endif
+   return false;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetViewMatrixBuilder.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetViewMatrixBuilder.cpp
new file mode 100644
index 0000000..892e4fb
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetViewMatrixBuilder.cpp
@@ -0,0 +1,615 @@
+
+#include <ossimPlanet/ossimPlanetViewMatrixBuilder.h>
+#include <ossimPlanet/ossimPlanetLsrSpaceTransform.h>
+#include <ossimPlanet/ossimPlanetPointModel.h>
+#include <ossimPlanet/mkUtils.h>
+#include <osg/io_utils>
+ossimPlanetViewMatrixBuilder::Visitor::Visitor()
+:osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+{
+}
+void ossimPlanetViewMatrixBuilder::Visitor::apply(osg::Node& node)
+{
+   ossimPlanetPointModel* pointModel = dynamic_cast<ossimPlanetPointModel*>(&node);
+   if(pointModel)
+   {
+      thePointModel        = pointModel;
+      theLsrSpaceTransform = thePointModel->lsrSpace();
+      return;
+   }
+   else
+   {
+      ossimPlanetLsrSpaceTransform* lsrSpace = dynamic_cast<ossimPlanetLsrSpaceTransform*>(&node);
+      if(lsrSpace)
+      {
+         theLsrSpaceTransform = lsrSpace;
+         return;
+      }
+   }
+   
+   traverse(node);
+}
+
+ossimPlanetViewMatrixBuilder::ossimPlanetViewMatrixBuilder(ossimPlanetGeoRefModel* geoRefModel)
+:theModel(geoRefModel),
+theLookAxis(LOOK_AXIS_Y),
+theFromInformationSetFlag(false),
+theFromNode(0),
+theFromPositionLLH(osg::Vec3d(0.0,0.0,0.0)),
+theFromRelativeHpr(osg::Vec3d(0.0,0.0,0.0)),
+theFromRelativeOrientationFlags(ALL_ORIENTATION),
+theFromHpr(osg::Vec3d(0.0,0.0,0.0)),
+theFromRange(0.0),
+theToInformationSetFlag(false),
+theToNode(0),
+theToPositionLLH(osg::Vec3d(0.0,0.0,0.0)),
+theToDisplacement(osg::Vec3d(0.0,0.0,0.0)),
+theToRange(0.0),
+theAttitudeHpr(osg::Vec3d(0.0,0.0,0.0)),
+theRange(0.0),
+theViewMatrix(osg::Matrixd()),
+theInverseViewMatrix(osg::Matrixd()),
+theComputeViewMatrixFlag(false)
+{
+   
+}
+
+ossimPlanetViewMatrixBuilder::ossimPlanetViewMatrixBuilder(const osg::Matrixd& m, ossimPlanetGeoRefModel* geoRefModel)
+:theModel(geoRefModel),
+theLookAxis(LOOK_AXIS_Y),
+theFromInformationSetFlag(false),
+theFromNode(0),
+theFromPositionLLH(osg::Vec3d(0.0,0.0,0.0)),
+theFromRelativeHpr(osg::Vec3d(0.0,0.0,0.0)),
+theFromRelativeOrientationFlags(ALL_ORIENTATION),
+theFromHpr(osg::Vec3d(0.0,0.0,0.0)),
+theFromRange(0.0),
+theToInformationSetFlag(false),
+theToNode(0),
+theToPositionLLH(osg::Vec3d(0.0,0.0,0.0)),
+theToDisplacement(osg::Vec3d(0.0,0.0,0.0)),
+theToRange(0.0),
+theAttitudeHpr(osg::Vec3d(0.0,0.0,0.0)),
+theRange(0.0),
+theViewMatrix(osg::Matrixd()),
+theInverseViewMatrix(osg::Matrixd()),
+theComputeViewMatrixFlag(false)
+{
+   setParametersByMatrix(m);
+}
+
+ossimPlanetViewMatrixBuilder::ossimPlanetViewMatrixBuilder(const ossimPlanetViewMatrixBuilder& src)
+:theModel(src.theModel),
+theLookAxis(src.theLookAxis),
+theFromInformationSetFlag(src.theFromInformationSetFlag),
+theFromNode(src.theFromNode),
+theFromPositionLLH(src.theFromPositionLLH),
+theFromRelativeHpr(src.theFromRelativeHpr),
+theFromRelativeOrientationFlags(src.theFromRelativeOrientationFlags),
+theFromHpr(src.theFromHpr),
+theFromRange(src.theFromRange),
+theFromDisplacement(src.theFromDisplacement),
+theToInformationSetFlag(src.theToInformationSetFlag),
+theToNode(src.theToNode),
+theToPositionLLH(src.theToPositionLLH),
+theToDisplacement(src.theToDisplacement),
+theToRange(src.theToRange),
+theAttitudeHpr(src.theAttitudeHpr),
+theRange(src.theRange),
+theViewMatrix(src.theViewMatrix),
+theInverseViewMatrix(src.theInverseViewMatrix),
+theComputeViewMatrixFlag(src.theComputeViewMatrixFlag)
+{
+}
+
+ossimPlanetViewMatrixBuilder::~ossimPlanetViewMatrixBuilder()
+{
+   
+}
+
+void ossimPlanetViewMatrixBuilder::setGeoRefModel(ossimPlanetGeoRefModel* model)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theModel = model;
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::updateFromLocalDisplacement(const osg::Vec3d& displacement)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theFromDisplacement = displacement;
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::setLookFromNodeOffset(osg::Node* node,
+                                                         const osg::Vec3d& hpr,
+                                                         double range,
+                                                         int relativeOrientationFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theFromInformationSetFlag = false;
+   theFromNode = node;
+   if(!node||!theModel.valid()) return;
+   
+   Visitor v;
+   node->accept(v);
+   theFromRange = range;
+   theFromRelativeOrientationFlags = static_cast<OrientationFlags>(relativeOrientationFlag);
+   theFromRelativeHpr = hpr;
+   theFromInformationSetFlag = false;
+   if(v.theLsrSpaceTransform.valid())
+   {
+      if(!theModel.valid())
+      {
+         theModel = v.theLsrSpaceTransform->model();
+      }
+      theFromInformationSetFlag = true;
+      theFromPositionLLH = osg::Vec3d(v.theLsrSpaceTransform->lat(),
+                                      v.theLsrSpaceTransform->lon(),
+                                      v.theLsrSpaceTransform->altitude());
+      theFromHpr = v.theLsrSpaceTransform->headingPitchRoll();
+      
+      setComputeViewMatrixFlag(true);
+   }
+}
+
+void ossimPlanetViewMatrixBuilder::setLookFrom(const osg::Vec3d& llh,
+                                               const osg::Vec3d& hpr,
+                                               double range)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theFromNode = 0;
+   theFromRange = range; // we displace along the look
+   theFromPositionLLH = llh;
+   theFromInformationSetFlag = true;
+   theFromRelativeOrientationFlags = ALL_ORIENTATION;
+   theFromRelativeHpr = hpr;
+   theFromHpr = osg::Vec3d(0.0,0.0,0.0);
+   setComputeViewMatrixFlag(true);
+}
+
+osg::Vec3d ossimPlanetViewMatrixBuilder::computeFromOrientation()const
+{
+   osg::Vec3d hpr = theFromRelativeHpr;
+   if(theFromRelativeOrientationFlags&HEADING)
+   {
+      // we use the hpr of the node
+      hpr[0] += theFromHpr[0];
+   }
+   if(theFromRelativeOrientationFlags&PITCH)
+   {
+      // we use the hpr of the node
+      hpr[1] += theFromHpr[1];
+   }
+   if(theFromRelativeOrientationFlags&ROLL)
+   {
+      // we use the hpr of the node
+      hpr[2] += theFromHpr[2];
+   }
+   return hpr;
+}
+
+void ossimPlanetViewMatrixBuilder::setLookToNode(osg::Node* node)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theToNode = node;
+   theToInformationSetFlag = false;
+   if(node)
+   {
+      Visitor v;
+      node->accept(v);
+      if(v.theLsrSpaceTransform.valid())
+      {
+         theToPositionLLH = osg::Vec3d(v.theLsrSpaceTransform->lat(),
+                                       v.theLsrSpaceTransform->lon(),
+                                       v.theLsrSpaceTransform->altitude());
+         theToInformationSetFlag = true;
+      }
+      else
+      {
+         // for now set back to null since we can't do anything with it
+         theToNode = 0;
+      }
+   }
+   
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::setLookTo(const osg::Vec3d& llh)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theToNode = 0;
+   theToPositionLLH = llh;
+   theToInformationSetFlag = true;
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::setLookToLocalDisplacement(const osg::Vec3d& displacement)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theToDisplacement = displacement;
+   setComputeViewMatrixFlag(true);
+}
+void ossimPlanetViewMatrixBuilder::setLookToRange(double range)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theToRange = range;
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::setRange(double range)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   theRange = range;
+   setComputeViewMatrixFlag(true);
+}
+
+double ossimPlanetViewMatrixBuilder::range()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   return theRange;
+}
+
+bool ossimPlanetViewMatrixBuilder::extractCompositedLlhHprParameters(osg::Vec3d& llh,
+                                                                    osg::Vec3d& hpr)const
+{
+   // no calculate the HPR and position of the from
+   //
+   ossimPlanetViewMatrixBuilder thisBuilder(*this);
+   ossimPlanetViewMatrixBuilder tempBuilder(theModel.get());
+   thisBuilder.setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_NEGATIVE_Z);
+   osg::Matrixd m = thisBuilder.viewMatrix();
+   osg::Vec3d eyeXyz(m(3,0), m(3,1), m(3,2));
+   theModel->xyzToLatLonHeight(eyeXyz, llh);
+   tempBuilder.setLookAxis(ossimPlanetViewMatrixBuilder::LOOK_AXIS_NEGATIVE_Z);
+   tempBuilder.setLookFrom(llh, osg::Vec3d(0.0,0.0,0.0), 0.0);
+   osg::Matrixd lsrM = tempBuilder.viewMatrix();
+   osg::Vec3d newHpr;
+   mkUtils::matrixToHpr(newHpr, lsrM, m);
+   hpr = newHpr;
+   
+   return true;
+}
+
+void ossimPlanetViewMatrixBuilder::setParametersByMatrix(const osg::Matrixd& m)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(!theModel.valid())
+   {
+      // nothing to do
+      return;
+   }
+   theAttitudeHpr = osg::Vec3d(0.0,0.0,0.0);
+   theFromRelativeOrientationFlags = ALL_ORIENTATION;
+   theFromRelativeHpr        = osg::Vec3d(0.0,0.0,0.0);
+   theFromRange              = 0.0;
+   theFromDisplacement       = osg::Vec3d(0.0,0.0,0.0);
+   theToInformationSetFlag   = false;
+   theFromInformationSetFlag = true;
+   theToNode                 = 0;
+   theFromNode               = 0;
+   theToDisplacement         = osg::Vec3d(0.0,0.0,0.0);   
+   theToRange                = 0.0; 
+   theRange                  = 0.0;
+   // no calculate the HPR and position of the from
+   //
+   osg::Vec3d eyeXyz(m(3,0), m(3,1), m(3,2));
+   osg::Matrixd lsrM;
+   theModel->xyzToLatLonHeight(eyeXyz, theFromPositionLLH);
+   theModel->orientationLsrMatrix(lsrM, theFromPositionLLH, 0.0, 0.0, 0.0);
+   osg::Vec3d newHpr;
+   mkUtils::matrixToHpr(newHpr, lsrM, m);
+   newHpr[1] -= 90.0;
+   newHpr[1]  = ossim::wrap(newHpr[1], -180.0, 180.0);
+   theFromHpr = newHpr;
+   
+   
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::convertToAFromViewMatrix(bool flattenRangeFlag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(!theModel.valid())
+   {
+      // nothing to do
+      return;
+   }
+   if(flattenRangeFlag&&!theToInformationSetFlag)
+   {
+      if(theFromRange != 0.0)
+      {
+         osg::Vec3d savedAttitudeHpr = theAttitudeHpr;
+         theAttitudeHpr = osg::Vec3d(0.0,0.0,0.0);
+         setComputeViewMatrixFlag(true);
+         osg::Matrixd currentM = viewMatrix();
+         theAttitudeHpr = savedAttitudeHpr;
+         setComputeViewMatrixFlag(true);
+         osg::Matrixd lsrM;
+         osg::Vec3d eyeXyz(currentM(3,0), currentM(3,1), currentM(3,2));
+         osg::Vec3d eyeLlh;
+         theModel->xyzToLatLonHeight(eyeXyz, eyeLlh);
+         theModel->orientationLsrMatrix(lsrM, eyeLlh, 0.0, 0.0, 0.0);
+         theFromRange = 0.0;
+         theFromPositionLLH = eyeLlh;
+         osg::Vec3d newHpr;
+         mkUtils::matrixToHpr(newHpr, lsrM, currentM);
+         newHpr[1] -= 90.0;
+         newHpr[1]  = ossim::wrap(newHpr[1], -180.0, 180.0);
+         // newHpr[2] = 0.0;
+         theFromHpr = newHpr;
+      }
+   }
+   else
+   {
+      osg::Vec3d newHpr;
+      osg::Vec3d toXyz;
+      theModel->latLonHeightToXyz(theToPositionLLH, toXyz);
+      osg::Vec3d savedAttitudeHpr = theAttitudeHpr;
+      theAttitudeHpr = osg::Vec3d(0.0,0.0,0.0);
+      setComputeViewMatrixFlag(true);
+      osg::Matrixd currentM = viewMatrix();
+      theAttitudeHpr = savedAttitudeHpr;
+      setComputeViewMatrixFlag(true);
+      osg::Matrixd lsrM;
+      osg::Vec3d eyeXyz(currentM(3,0), currentM(3,1), currentM(3,2));
+      osg::Vec3d eyeLlh;
+      theModel->xyzToLatLonHeight(eyeXyz, eyeLlh);
+      
+      if(flattenRangeFlag)
+      {
+         theModel->orientationLsrMatrix(lsrM, eyeLlh, 0.0, 0.0, 0.0);
+         theFromRange = 0.0;
+         theFromPositionLLH = eyeLlh;
+      }
+      else
+      {
+         double range = theModel->calculateUnnormalizedLengthXyz(eyeXyz, toXyz);
+         theModel->orientationLsrMatrix(lsrM, theToPositionLLH, 0.0, 0.0, 0.0);
+         theFromRange = -range; // we displace along the look
+         theFromPositionLLH = theToPositionLLH;
+      }
+      mkUtils::matrixToHpr(newHpr, lsrM, currentM);
+      
+      
+      //   osg::Matrixd viewM = viewMatrix();
+      newHpr[1] -= 90.0;
+      newHpr[1]  = ossim::wrap(newHpr[1], -180.0, 180.0);
+      // newHpr[2] = 0.0;
+      theFromHpr = newHpr;
+   }
+   theFromRelativeOrientationFlags = ALL_ORIENTATION;
+   theFromRelativeHpr = osg::Vec3d(0.0,0.0,0.0);
+   theFromDisplacement = osg::Vec3d(0.0,0.0,0.0);
+   theToInformationSetFlag = false;
+   theFromInformationSetFlag = true;
+   theToNode = 0;
+   theFromNode = 0;
+   theRange = 0.0;
+   setComputeViewMatrixFlag(true);
+}
+
+void ossimPlanetViewMatrixBuilder::computeMatrices()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePropertyMutex);
+   if(!theModel) return;
+   // need to compute the view matrix
+   if(theFromInformationSetFlag)
+   {
+      osg::Matrixd tempM;
+      osg::Vec3d hpr = computeFromOrientation();
+      theModel->orientationLsrMatrix(tempM,
+                                     theFromPositionLLH,
+                                     hpr[0],
+                                     hpr[1],
+                                     hpr[2]);
+      osg::Vec3d xAxis(tempM(0,0), tempM(0,1), tempM(0,2));
+      osg::Vec3d yAxis(tempM(1,0), tempM(1,1), tempM(1,2));
+      osg::Vec3d zAxis(tempM(2,0), tempM(2,1), tempM(2,2));
+      osg::Vec3d eye(tempM(3,0),   tempM(3,1), tempM(3,2));
+      osg::Vec3d newEye;
+      if(!ossim::almostEqual(theFromDisplacement.length2(), 0.0, 1e-15))
+      {
+         osg::Matrixd displacementM;
+         
+         theModel->orientationLsrMatrix(displacementM,
+                                        theFromPositionLLH,
+                                        theFromHpr[0],
+                                        theFromHpr[1],
+                                        theFromHpr[2]);
+         
+         // we will only displace along the axis of the orientation matrix
+         // relative to the model to solve the new eye origin
+         //
+         osg::Vec3d displacement = theFromDisplacement*theModel->getInvNormalizationScale();
+         osg::Vec3d xAxis(displacementM(0,0), displacementM(0,1), displacementM(0,2));
+         osg::Vec3d yAxis(displacementM(1,0), displacementM(1,1), displacementM(1,2));
+         osg::Vec3d zAxis(displacementM(2,0), displacementM(2,1), displacementM(2,2));
+         osg::Vec3d eye(displacementM(3,0),   displacementM(3,1), displacementM(3,2));
+         newEye = (eye +
+                   xAxis*displacement[0]+
+                   yAxis*displacement[1]+
+                   zAxis*displacement[2]);
+      }
+      else
+      {
+         newEye = eye;
+      }
+      osg::Vec3d lookVector;
+      osg::Vec3d upAxis;
+      switch(theLookAxis)
+      {
+         case LOOK_AXIS_X:
+         {
+            lookVector = (newEye + xAxis) - newEye;
+            upAxis = zAxis;
+            break;
+         }
+         case LOOK_AXIS_Y:
+         {
+            lookVector = (newEye + yAxis) - newEye;
+            upAxis = zAxis;
+            //std::cout << "HPR build = " << theFromHpr << std::endl;
+            break;
+         }
+         case LOOK_AXIS_Z:
+         {
+            lookVector = (newEye + zAxis) - newEye;
+            upAxis = yAxis;
+            break;
+         }
+         case LOOK_AXIS_NEGATIVE_X:
+         {
+            lookVector = (newEye - xAxis) - newEye;
+            upAxis = zAxis;
+            break;
+         }
+         case LOOK_AXIS_NEGATIVE_Y:
+         {
+            lookVector = (newEye - yAxis) - newEye;
+            upAxis = zAxis;
+            break;
+         }
+         case LOOK_AXIS_NEGATIVE_Z:
+         {
+            lookVector = (newEye - zAxis) - newEye;
+            upAxis = yAxis;
+            break;
+         }
+         default:
+         {
+            // for now we only support Y Axis;
+            lookVector = (newEye + zAxis) - newEye;
+            upAxis = yAxis;
+            break;
+         }
+      }
+      lookVector.normalize();
+      
+      // now displace along the look axis a range value
+      //
+      newEye = newEye + lookVector*(theModel->getInvNormalizationScale()*theFromRange);
+      
+      // now let's make a look at based on the orientation axis and the final eye
+      // position. We should have the center displacment and range integrated into
+      // the final look
+      //
+      if(!theToInformationSetFlag)
+      {
+         if(!ossim::almostEqual(theRange, 0.0))
+         {
+            newEye = newEye + lookVector*(theModel->getInvNormalizationScale()*theRange);
+            theInverseViewMatrix.makeLookAt(newEye, newEye + lookVector, upAxis);
+         }
+         else
+         {
+            theInverseViewMatrix.makeLookAt(newEye, newEye + lookVector, upAxis);
+         }
+         theViewMatrix.invert(theInverseViewMatrix);
+      }
+      else
+      {
+         osg::Vec3d toXyz;
+         theModel->latLonHeightToXyz(theToPositionLLH, toXyz);
+         
+         double delta = (newEye-toXyz).length();
+         // sanity check
+         //
+         if(ossim::almostEqual(0.0,delta))
+         {
+            if(!ossim::almostEqual(theRange, 0.0))
+            {
+               newEye = newEye + lookVector*(theModel->getInvNormalizationScale()*theRange);
+               theInverseViewMatrix.makeLookAt(newEye, newEye + lookVector, upAxis);
+            }
+            else
+            {
+               theInverseViewMatrix.makeLookAt(newEye, newEye + lookVector, upAxis);
+            }
+            theViewMatrix.invert(theInverseViewMatrix);
+         }
+         else
+         {
+            upAxis = zAxis;
+            lookVector = toXyz-newEye;
+            lookVector.normalize();
+         
+            if(!ossim::almostEqual(theToDisplacement.length2(), 0.0, 1e-15)||
+               !ossim::almostEqual(theToRange,0.0,1e-15)||
+               !ossim::almostEqual(theRange, 0.0, 1e-15))
+            {
+               osg::Vec3d displacement = theToDisplacement*theModel->getInvNormalizationScale();
+               double range = (theToRange+theRange)*theModel->getInvNormalizationScale();
+ //              double range = (theToRange)*theModel->getInvNormalizationScale();
+               theInverseViewMatrix.makeLookAt(newEye, toXyz, upAxis);
+               theViewMatrix.invert(theInverseViewMatrix);
+               osg::Vec3d xAxis(theViewMatrix(0,0), theViewMatrix(0,1), theViewMatrix(0,2));
+               osg::Vec3d yAxis(theViewMatrix(1,0), theViewMatrix(1,1), theViewMatrix(1,2));
+               osg::Vec3d zAxis(-theViewMatrix(2,0), -theViewMatrix(2,1), -theViewMatrix(2,2));
+               osg::Vec3d eye(theViewMatrix(3,0),   theViewMatrix(3,1), theViewMatrix(3,2));
+               newEye = (eye +
+                         xAxis*displacement[0]+
+                         yAxis*displacement[1]+
+                         zAxis*(displacement[2]+range));
+            }
+            theInverseViewMatrix.makeLookAt(newEye, toXyz, upAxis);
+            
+            theViewMatrix.invert(theInverseViewMatrix);
+         }
+         // create a forward vector to the desired look point
+      }
+      
+      if(!ossim::almostEqual(theAttitudeHpr.length2(), 0.0, 1e-15))
+      {
+         // now let's apply the final orientation matrix
+         // we will see if we can integrate further in the chain so we can limit the number
+         // of inverts we have to do.
+         //
+         xAxis = upAxis^lookVector;
+         zAxis = xAxis^lookVector;
+         
+         osg::Matrixd rot;
+         rot.makeIdentity();
+         rot.makeRotate(osg::DegreesToRadians(theAttitudeHpr[0]), zAxis, // heading
+                        osg::DegreesToRadians(theAttitudeHpr[1]), xAxis, // pitch
+                        osg::DegreesToRadians(theAttitudeHpr[2]), lookVector); // roll
+         osg::Matrixd result(theViewMatrix);
+         mkUtils::mult3x3(result, theViewMatrix, rot);
+         theViewMatrix = result;
+         theInverseViewMatrix.invert(theViewMatrix);
+      }
+
+   }
+#if 0 // debug stuff
+   {
+      osg::Vec3d xAxis(theInverseViewMatrix(0,0), theInverseViewMatrix(0,1), theInverseViewMatrix(0,2));
+      osg::Vec3d yAxis(theInverseViewMatrix(1,0), theInverseViewMatrix(1,1), theInverseViewMatrix(1,2));
+      osg::Vec3d zAxis(theInverseViewMatrix(2,0), theInverseViewMatrix(2,1), theInverseViewMatrix(2,2));
+      std::cout << "INVERSE x = " << xAxis << std::endl;
+      std::cout << "INVERSE Y = " << yAxis << std::endl;
+      std::cout << "INVERSE z = " << zAxis << std::endl;
+   }
+#endif
+   theComputeViewMatrixFlag = false;
+}
+
+
+const osg::Matrix& ossimPlanetViewMatrixBuilder::viewMatrix()const
+{
+   if(computeViewMatrixFlag())
+   {
+      computeMatrices();
+   }
+   
+   return theViewMatrix;
+}
+
+const osg::Matrix& ossimPlanetViewMatrixBuilder::inverseViewMatrix()const
+{
+   if(computeViewMatrixFlag())
+   {
+      computeMatrices();
+   }
+   
+   return theInverseViewMatrix;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetViewer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetViewer.cpp
new file mode 100644
index 0000000..afb1842
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetViewer.cpp
@@ -0,0 +1,1127 @@
+#include <ossimPlanet/ossimPlanetViewer.h>
+#include <ossimPlanet/ossimPlanetLookAt.h>
+#include <ossimPlanet/ossimPlanetManipulator.h>
+
+#include <ossimPlanet/ossimPlanetTextureLayerRegistry.h>
+#include <osg/CoordinateSystemNode>
+#include <osg/io_utils>
+#include <OpenThreads/ScopedLock>
+#include <osgUtil/IncrementalCompileOperation>
+
+class ossimPlanetViewerFindNodesVisitor : public osg::NodeVisitor
+{
+public:
+   ossimPlanetViewerFindNodesVisitor(const ossimString& id,
+                                     ossimPlanetViewer::PlanetNodeList* nodeList,
+                                     bool findFirstNodeOnlyFlag=false)
+   :osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
+   theListIsSharedFlag(true),
+   theFindFirstNodeOnlyFlag(findFirstNodeOnlyFlag),
+   theId(id),
+   theNodeList(nodeList)
+   {
+      theNodeList->clear();
+   }
+   ossimPlanetViewerFindNodesVisitor(const ossimString& id,
+                                     bool findFirstNodeOnlyFlag=false)
+   :theListIsSharedFlag(false),
+   theFindFirstNodeOnlyFlag(findFirstNodeOnlyFlag),
+   theId(id),
+   theNodeList(new ossimPlanetViewer::PlanetNodeList)
+   {
+      
+   }
+   virtual ~ossimPlanetViewerFindNodesVisitor()
+   {
+      if(!theListIsSharedFlag&&theNodeList&&theNodeList)
+      {
+         delete theNodeList;
+      }
+      theNodeList = 0;
+   }
+   ossimPlanetViewer::PlanetNodeList* nodeList()
+   {
+      return theNodeList;
+   }
+   const ossimPlanetViewer::PlanetNodeList* nodeList()const
+   {
+      return theNodeList;
+   }
+   virtual void apply(osg::Node& node)
+   {
+      ossimPlanetNode* planetNode = dynamic_cast<ossimPlanetNode*>(&node);
+      
+      if(planetNode)
+      {
+         if(planetNode->id() == theId)
+         {
+            if(theNodeList)
+            {
+               theNodeList->push_back(planetNode);
+            }
+         }
+      }
+      // keep going even if we find a node
+      // if the flag is not set
+      //
+      if(theNodeList&&theNodeList->size() && !theFindFirstNodeOnlyFlag)
+      {
+         traverse(node);
+      }
+   }
+protected:
+   bool theListIsSharedFlag;
+   bool theFindFirstNodeOnlyFlag;
+   ossimString theId;
+   ossimPlanetViewer::PlanetNodeList* theNodeList;
+};
+
+class ossimPlanetViewer::InitializePointersVisitor : public osg::NodeVisitor
+{
+public:
+   InitializePointersVisitor(ossimPlanetViewer* viewer)
+   :osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
+   theViewer(viewer)
+   {
+      if(theViewer)
+      {
+         if(theViewer->thePlanet.valid())
+         {
+            theViewer->thePlanet->setComputeIntersectionFlag(true);
+            theViewer->thePlanet->removeCallback(theViewer->theCallback.get());
+         }
+         theViewer->thePlanet = 0;
+         theViewer->theTerrainLayer = 0;
+         theViewer->theAnnotationLayer = 0;
+      }
+   }
+   virtual void apply(osg::Node& node)
+   {
+      
+      if(theViewer)
+      {
+         ossimPlanet*                planet       = dynamic_cast<ossimPlanet*>(&node);
+         ossimPlanetLand*            landLayer       = dynamic_cast<ossimPlanetLand*>(&node);
+         ossimPlanetTerrain*         terrainLayer       = dynamic_cast<ossimPlanetTerrain*>(&node);
+         ossimPlanetAnnotationLayer* annotationLayer = dynamic_cast<ossimPlanetAnnotationLayer*>(&node);
+         ossimPlanetKmlLayer*        kmlLayer = dynamic_cast<ossimPlanetKmlLayer*>(&node);
+         if(planet)
+         {
+            if(!theViewer->thePlanet.valid())
+            {
+               theViewer->thePlanet = planet;
+               if(theViewer->theEphemerisLayer.valid())
+               {
+                  theViewer->theEphemerisLayer->setModel(planet->model().get());
+               }
+               if(theViewer->thePlanet.valid())
+               {
+                  // the viewer will manage setting a valid intersection point
+                  // for any who need it.  This is the current intersection for
+                  // current traverse.
+                  //
+                  theViewer->thePlanet->setComputeIntersectionFlag(false);
+                  theViewer->thePlanet->addCallback(theViewer->theCallback.get());
+               }
+            }
+         }
+         else if(kmlLayer)
+         {
+            theViewer->theKmlLayer = kmlLayer;
+         }
+         else if(annotationLayer)
+         {
+            theViewer->theAnnotationLayer = annotationLayer;
+         }
+         else if(terrainLayer)
+         {
+           theViewer->theTerrainLayer = terrainLayer;
+         }
+         else if(landLayer)
+         {
+            theViewer->theTerrainLayer = landLayer;
+         }
+         if(!theViewer->theAnnotationLayer.valid() ||
+            !(theViewer->theTerrainLayer.valid()||theViewer->thePlanet.valid()))
+         { 
+            traverse(node);
+         }
+      }
+   }
+   
+protected:  
+   ossimPlanetViewer* theViewer;
+};
+
+void ossimPlanetViewer::NodeListener::nodeAdded(osg::Node* node)
+{
+   ossimPlanetLand* land = dynamic_cast<ossimPlanetLand*>(node);
+   ossimPlanetTerrain* terrain = dynamic_cast<ossimPlanetTerrain*>(node);
+   if(land)
+   {
+      if(!theViewer->theTerrainLayer.valid())
+      {
+         theViewer->theTerrainLayer = land;
+      }
+   }
+   else if(terrain)
+   {
+      if(!theViewer->theTerrainLayer.valid())
+      {
+         theViewer->theTerrainLayer = terrain;
+      }
+   }
+   else 
+   {
+      ossimPlanetAnnotationLayer* annotationLayer = dynamic_cast<ossimPlanetAnnotationLayer*>(node);
+      if(annotationLayer)
+      {
+         if(!theViewer->theAnnotationLayer.valid())
+         {
+            theViewer->theAnnotationLayer = annotationLayer;
+         }
+      }
+      else
+      {
+         ossimPlanetKmlLayer* kmlLayer = dynamic_cast<ossimPlanetKmlLayer*>(node);
+         if(kmlLayer)
+         {
+            theViewer->theKmlLayer = kmlLayer;
+         }
+      }
+   }
+}
+
+void ossimPlanetViewer::NodeListener::nodeRemoved(osg::Node* node)
+{
+   if(node == theViewer->theTerrainLayer.get())
+   {
+      theViewer->theTerrainLayer = 0;
+   }
+   else if(node == theViewer->theAnnotationLayer.get())
+   {
+      theViewer->theAnnotationLayer = 0;
+   }
+}
+
+void ossimPlanetViewer::NodeListener::needsRedraw(ossimPlanetNode* node)
+{
+   if(theViewer)
+   {
+      theViewer->requestRedraw();
+   }
+}
+
+
+ossimPlanetNode* ossimPlanetViewer::PickObject::firstPlanetNode()
+{
+   ossimPlanetNode* result = 0;
+   if(theNodePath.empty()) return result;
+   ossim_int32 idx=0;
+   for(idx = theNodePath.size()-1; ((idx >=0)&&(!result)); --idx)
+   {
+      result = dynamic_cast<ossimPlanetNode*>(theNodePath[idx].get());
+   }
+   
+   return result;
+}
+
+#if 0
+void ossimPlanetViewer::Renderer::flushAndCompile(double currentElapsedFrameTime, 
+                                                  osgUtil::SceneView* sceneView, 
+                                                  osgDB::DatabasePager* databasePager, 
+                                                  osg::GraphicsThread* compileThread)
+{
+   osg::Timer_t t = osg::Timer::instance()->tick();
+   osgViewer::Renderer::flushAndCompile(currentElapsedFrameTime, sceneView, databasePager, compileThread);
+   double delta = osg::Timer::instance()->delta_s(t, osg::Timer::instance()->tick());
+   if(theCallback.valid())
+   {
+      theCallback->flushAndCompile(currentElapsedFrameTime + delta,
+                                   sceneView,
+                                   databasePager,
+                                   compileThread);
+   }
+}
+
+void ossimPlanetViewer::DrawCallback::operator () (osg::RenderInfo& renderInfo) const
+{
+   if(!theViewer) return;
+   if(theViewer->terrainLayer()&&renderInfo.getState())
+   {
+      //double delta = osg::Timer::instance()->delta_s(theViewer->theFrameStartTimeStamp, 
+      //                                               osg::Timer::instance()->tick());
+      theViewer->terrainLayer()->compileGLObjects(*renderInfo.getState(), 
+                                                  theViewer->terrainLayer()->minimumTimeToCompilePerFrame());
+   }
+}
+
+void ossimPlanetViewer::FlushAndCompileCallback::flushAndCompile(double currentElapsedFrameTime, 
+                                                                   osgUtil::SceneView* sceneView, 
+                                                                   osgDB::DatabasePager* databasePager, 
+                                                                   osg::GraphicsThread* compileThread)
+{
+   if(theViewer)
+   {
+      if(theViewer->terrainLayer())
+      {
+         // let's calculate based on target frame rate later.  For now give
+         // 2 milliseconds
+         //
+         theViewer->terrainLayer()->compileGLObjects(*(sceneView->getState()), .002);
+      }
+   }
+}
+#endif
+
+ossimPlanetViewer::ossimPlanetViewer()
+:osgViewer::Viewer()
+{
+   init();
+}
+
+ossimPlanetViewer::ossimPlanetViewer(osg::ArgumentParser& arguments)
+:osgViewer::Viewer(arguments)
+{
+   init();
+}
+
+ossimPlanetViewer::ossimPlanetViewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop)
+:osgViewer::Viewer(viewer, copyop)
+{
+   init();
+}
+
+ossimPlanetViewer::~ossimPlanetViewer()
+{
+   if(thePlanet.valid())
+   {
+      thePlanet->removeCallback(theCallback.get());
+   }
+   thePlanet = 0;
+}
+
+void ossimPlanetViewer::init()
+{
+   theRootNode = new osg::Group();
+   theRootNode->setUpdateCallback(new ossimPlanetTraverseCallback);
+   theRootNode->setEventCallback(new ossimPlanetTraverseCallback);
+   theRootNode->setCullCallback(new ossimPlanetTraverseCallback);
+   
+//   getCamera()->setPreDrawCallback(new ossimPlanetViewer::DrawCallback(this));
+   setThreadSafeRefUnref(true);
+   osgDB::DatabasePager* pager = osgDB::DatabasePager::create();
+   setDatabasePager(pager);
+   theUpdateVisitor = new ossimPlanetUpdateVisitor();
+   //theUpdateVisitor->setDatabaseRequestHandler(pager);
+   setUpdateVisitor(theUpdateVisitor.get());
+   theCallback = new ossimPlanetViewer::NodeListener(this);
+   theCurrentCamera = new ossimPlanetLookAt;
+   theCurrentLookAt = new ossimPlanetLookAt;
+   getCamera()->setClearColor(osg::Vec4(0.0,0.0,0.0,1.0));
+   //getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+   //getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);
+   //getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
+   theRedrawFlag          = false;
+   theContinousUpdateFlag = false;
+   theIntersectWithMasterIfNotWithinAnyViewFlag = false;
+   theCalculateNearFarRatioFlag = true;
+
+   //setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation());
+
+}
+
+void ossimPlanetViewer::setTerrainMaxNumberOfOperationsToApplyToGraphPerFrame(ossim_uint32 value)
+{
+   ossimPlanetTerrain* terrain = dynamic_cast<ossimPlanetTerrain*>(theTerrainLayer.get());
+   
+   if(terrain)
+   {
+      terrain->setMaxNumberOfOperationsToApplyToGraphPerFrame(value);
+   }
+}
+
+ossimPlanetManipulator* ossimPlanetViewer::planetManipulator()
+{
+   return dynamic_cast<ossimPlanetManipulator*>(getCameraManipulator());
+}
+
+ossimPlanetTerrain* ossimPlanetViewer::terrainLayer()
+{
+   return dynamic_cast<ossimPlanetTerrain*>(theTerrainLayer.get());
+}
+
+ossimPlanetAnnotationLayer* ossimPlanetViewer::annotationLayer()
+{
+   return theAnnotationLayer.get();
+}
+
+ossimPlanetKmlLayer* ossimPlanetViewer::kmlLayer()
+{
+   return theKmlLayer.get();
+}
+
+void ossimPlanetViewer::addEphemeris(ossim_uint32 memberBitMask)
+{
+   if(!theEphemerisLayer.valid())
+   {
+      if(getLight())
+      {
+         theSavedLight = (osg::Light*)getLight()->clone(osg::CopyOp::DEEP_COPY_ALL);
+      }
+      ossimPlanet* tempPlanet = new ossimPlanet;
+      tempPlanet->setComputeIntersectionFlag(false);
+      theEphemerisRoot = tempPlanet;
+      theEphemerisLayer = new ossimPlanetEphemeris();
+      theEphemerisLayer->setRoot(theRootNode.get());
+      theEphemerisLayer->setMembers(memberBitMask);
+//      planet()->addChild(theEphemerisLayer.get());
+      tempPlanet->addChild(theEphemerisLayer.get());
+      theRootNode->addChild(tempPlanet);
+      theEphemerisCamera = new osg::Camera;
+      theEphemerisCamera->setProjectionResizePolicy(getCamera()->getProjectionResizePolicy());
+      theEphemerisCamera->setClearColor(getCamera()->getClearColor());
+      theEphemerisCamera->setRenderOrder(osg::Camera::PRE_RENDER);
+      theEphemerisCamera->setRenderTargetImplementation( getCamera()->getRenderTargetImplementation() );
+      //      theEphemerisCamera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+      //      getCamera()->setClearMask(getCamera()->getClearMask() & ~GL_COLOR_BUFFER_BIT & ~GL_DEPTH_BUFFER_BIT);
+      theEphemerisCamera->setClearMask(GL_COLOR_BUFFER_BIT);
+      getCamera()->setClearMask(getCamera()->getClearMask() & ~GL_COLOR_BUFFER_BIT);
+      if(getCamera()->getViewport())
+      {
+         theEphemerisCamera->setViewport(new osg::Viewport(*getCamera()->getViewport()));
+      }
+      else
+      {
+         theEphemerisCamera->setViewport(new osg::Viewport());
+      }
+      addSlave(theEphemerisCamera.get(), false);
+      theEphemerisLayer->setCamera(theEphemerisCamera.get());
+      theEphemerisCamera->setEventCallback(new ossimPlanetTraverseCallback());
+      theEphemerisCamera->setUpdateCallback(new ossimPlanetTraverseCallback());
+      theEphemerisCamera->setCullCallback(new ossimPlanetTraverseCallback());
+      //theEphemerisCamera->addChild(theRootNode.get());
+      //getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+      //theEphemerisCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+      //double fov, aspectRatio, near, far;
+      //osg::Matrixd& m = getCamera()->getProjectionMatrix();
+      //m.getPerspective(fov, aspectRatio, near, far);
+      //theEphemerisCamera->setProjectionMatrixAsPerspective(fov, aspectRatio, .2, 5.0);
+      //getCamera()->setProjectionMatrixAsPerspective(fov, aspectRatio, .0000001, .2);
+   }
+}
+
+void ossimPlanetViewer::removeEphemeris()
+{
+   if(theEphemerisLayer.valid())
+   {
+      if(theRootNode->getNumChildren() > 1)
+      {
+         theRootNode->removeChild(1, theRootNode->getNumChildren());
+      }
+      theEphemerisLayer  = 0;
+      theEphemerisRoot   = 0;
+      int slaveCameraIdx = findSlaveIndexForCamera(theEphemerisCamera.get());
+      if(slaveCameraIdx >= 0)
+      {
+         removeSlave(slaveCameraIdx);
+         theEphemerisCamera = 0;
+      }
+      getCamera()->setClearMask(getCamera()->getClearMask()|GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+      //setLight(new osg::Light());
+      requestRedraw();
+   }
+}
+
+ossimPlanetEphemeris* ossimPlanetViewer::ephemeris()
+{
+   return theEphemerisLayer.get();
+}
+
+void ossimPlanetViewer::requestRedraw()
+{
+   setRedrawFlag(true);
+}
+
+void ossimPlanetViewer::requestContinuousUpdate(bool needed)
+{  
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+  theContinousUpdateFlag=needed;
+}
+
+void ossimPlanetViewer::requestWarpPointer(float x,float y)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   theWarpPointerFlag = true; theWarpX=x; theWarpY=y;
+}
+
+bool ossimPlanetViewer::getAndSetRedrawFlag(bool newValue)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   bool result = theRedrawFlag;
+   theRedrawFlag = newValue;
+   return result;
+}
+
+bool ossimPlanetViewer::getRedrawFlag()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   return theRedrawFlag;
+}
+
+void ossimPlanetViewer::setRedrawFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   theRedrawFlag=flag;
+}
+
+bool ossimPlanetViewer::redrawFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   return theRedrawFlag;
+}
+
+void ossimPlanetViewer::setContinuousUpdateFlag(bool flag)
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   theContinousUpdateFlag=flag;
+}
+
+bool ossimPlanetViewer::continuousUpdateFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   return theContinousUpdateFlag;
+}
+
+bool ossimPlanetViewer::warpPointerFlag()const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   return theWarpPointerFlag;
+}
+
+void ossimPlanetViewer::getWarpPoints(float& x, float& y)const
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theActionAdapterMutex);
+   x=theWarpX; 
+   y=theWarpY;
+}
+
+void ossimPlanetViewer::setSceneData(osg::Node* p)
+{
+   InitializePointersVisitor initializePointersVisitor(this);
+   theRootNode->removeChildren(0, theRootNode->getNumChildren());
+   if(p)
+   {
+      p->accept(initializePointersVisitor);
+      theRootNode->addChild(p);
+      if(theEphemerisLayer.valid())
+      {
+         ossimPlanet* tempPlanet = new ossimPlanet;
+         tempPlanet->addChild(theEphemerisLayer.get());
+         tempPlanet->setComputeIntersectionFlag(false);
+         theRootNode->addChild(tempPlanet);
+      }
+   }
+   osgViewer::Viewer::setSceneData(theRootNode.get());
+   requestRedraw();
+}
+
+ossimPlanet* ossimPlanetViewer::planet()
+{
+   return thePlanet.get();
+}
+
+const ossimPlanet* ossimPlanetViewer::planet()const
+{
+   return thePlanet.get();
+}
+
+const ossimPlanetGeoRefModel* ossimPlanetViewer::model()const
+{
+   if(thePlanet.get())
+   {
+      return thePlanet->model().get();
+   }
+   
+   return 0;
+}
+
+ossimPlanetGeoRefModel* ossimPlanetViewer::model()
+{
+   if(thePlanet.get())
+   {
+      return thePlanet->model().get();
+   }
+   
+   return 0;
+}
+
+void ossimPlanetViewer::advance(double simulationTime)
+{
+   theFrameStartTimeStamp = osg::Timer::instance()->tick();
+   osgViewer::Viewer::advance(simulationTime);
+}
+
+void ossimPlanetViewer::eventTraversal()
+{
+   osgViewer::Viewer::eventTraversal();
+}
+
+void ossimPlanetViewer::updateTraversal()
+{
+   ossimPlanetTerrain* terrain = dynamic_cast<ossimPlanetTerrain*>(terrainLayer());
+   if(terrain&&!terrain->getDatabasePager()) terrain->setDatabasePager(getDatabasePager());
+
+   if(!mkUtils::almostEqual(theCurrentViewMatrix,
+                            getCamera()->getViewMatrix()))
+   {
+      theCurrentViewMatrix        = getCamera()->getViewMatrix();
+      theCurrentViewMatrixInverse = theCurrentViewMatrix.inverse(theCurrentViewMatrix);
+      computeCurrentCameraInfo();
+      const ossimPlanetGeoRefModel* landModel = model();
+
+      // let's do a crude normalize distance to do an estimate NearFarRatio
+      //
+      if(getCamera()&&landModel&&theCurrentLookAt.valid()&&theCurrentCamera.valid()&&theCalculateNearFarRatioFlag)
+      {
+         double dist = ossim::min(theCurrentLookAt->range(),
+                                  theCurrentCamera->altitude())/osg::WGS_84_RADIUS_EQUATOR;
+         double t = log(1+dist);
+         t = ossim::clamp(t, 0.0, 1.0);
+         double ratio = .1*(t) + (.0000001)*(1.0-t);
+         getCamera()->setNearFarRatio(ossim::min(.001, ratio));
+      }
+      notifyViewChanged();
+   }
+   osgViewer::Viewer::updateTraversal();
+   if(theEphemerisCamera.valid())
+   {
+      if(theEphemerisCamera.valid())
+      {
+         theEphemerisCamera->setGraphicsContext(getCamera()->getGraphicsContext());
+         theEphemerisCamera->setRenderTargetImplementation( getCamera()->getRenderTargetImplementation() );
+      }
+      osg::Viewport* viewport    = getCamera()->getViewport();
+      osg::Viewport* ephViewport = theEphemerisCamera->getViewport();
+      if(viewport&&ephViewport)
+      {
+         if(!ossim::almostEqual(viewport->x(), ephViewport->x())||
+            !ossim::almostEqual(viewport->y(), ephViewport->y())||
+            !ossim::almostEqual(viewport->width(), ephViewport->width())||
+            !ossim::almostEqual(viewport->height(), ephViewport->height()))
+         {            
+            ephViewport->setViewport(viewport->x(), 
+                                     viewport->y(), 
+                                     viewport->width(), 
+                                     viewport->height());
+         }
+      }
+      theEphemerisCamera->setProjectionMatrix(getCamera()->getProjectionMatrix());
+      theEphemerisCamera->setViewMatrix(getCamera()->getViewMatrix());
+   }
+   bool databasePagerHasRequests = getDatabasePager()?getDatabasePager()->requiresUpdateSceneGraph():false;//||
+                                                       //getDatabasePager()->requiresCompileGLObjects()):false;
+   if(databasePagerHasRequests)
+   {
+      requestRedraw();
+   }
+   
+}
+
+bool ossimPlanetViewer::addAnnotation(osg::ref_ptr<ossimPlanetAnnotationLayerNode> annotation)
+{
+   bool result = false;
+   
+   if(theAnnotationLayer.valid())
+   {
+      result = theAnnotationLayer->addChild(annotation.get());
+   }
+   
+   return result;
+}
+
+bool ossimPlanetViewer::addImageTexture(osg::ref_ptr<ossimPlanetTextureLayer> imageTexture)
+{
+   bool result = false;
+   
+   if(theTerrainLayer.valid()&&imageTexture.valid())
+   {
+      ossimPlanetTerrain* terrain = dynamic_cast<ossimPlanetTerrain*>(theTerrainLayer.get());
+      if(terrain)
+      {
+         if(terrain->numberOfTextureLayers() > 0)
+         {
+            ossimPlanetTextureLayerGroup* group = terrain->textureLayer(0)->asGroup();
+            if(group)
+            {
+               result = group->addTop(imageTexture.get());
+            }
+         }
+      }
+      else
+      {
+         ossimPlanetLand* land = dynamic_cast<ossimPlanetLand*>(theTerrainLayer.get());
+         if(land)
+         {
+            result = land->referenceLayer()->addTop(imageTexture.get());
+         }
+      }
+   }
+   
+   return result;
+}
+
+osg::ref_ptr<ossimPlanetTextureLayer> ossimPlanetViewer::addImageTexture(const ossimString& file)
+{
+   osg::ref_ptr<ossimPlanetTextureLayer> layer = ossimPlanetTextureLayerRegistry::instance()->createLayer(file);
+   
+   if(!addImageTexture(layer.get()))
+   {
+      layer = 0;
+   }
+   
+   return layer.get();
+}
+
+bool ossimPlanetViewer::addElevation(osg::ref_ptr<ossimPlanetElevationDatabase> database, bool sortFlag)
+{
+   bool result = false;
+   
+   if(theTerrainLayer.valid()&&database.valid())
+   {
+      result = true;
+      ossimPlanetTerrain* terrain = dynamic_cast<ossimPlanetTerrain*>(theTerrainLayer.get());
+      if(terrain)
+      {
+         result = terrain->addElevation(database.get(), sortFlag);
+      }
+      else
+      {
+         ossimPlanetTerrain* land = dynamic_cast<ossimPlanetTerrain*>(theTerrainLayer.get());
+         if(land)
+         {
+            result = land->addElevation(database.get(), sortFlag);
+         }
+      }
+   }
+   
+   return result;
+}
+
+void ossimPlanetViewer::addKml(const ossimFilename& file)
+{
+   if(theKmlLayer.valid())
+   {
+      theKmlLayer->addKml(file);
+   }
+}
+
+void ossimPlanetViewer::computeCurrentCameraInfo()
+{
+   const ossimPlanetGeoRefModel* landModel = model();
+   if(!landModel) return;
+   
+   // First solve the camera in lat lon hgt and roll pitch heading format
+   //
+   osg::Matrixd eyeLsrMatrix;
+   osg::Vec3d eyeLlh;
+   osg::Vec3d hpr;
+   osg::Vec3d eye = osg::Vec3d(0.0,0.0,0.0)*theCurrentViewMatrixInverse;
+   landModel->inverse(eye, eyeLlh);
+   landModel->lsrMatrix(eyeLlh, eyeLsrMatrix);
+   mkUtils::matrixToHpr(hpr, eyeLsrMatrix, theCurrentViewMatrixInverse);
+   theCurrentCamera->setAll(eyeLlh[0], eyeLlh[1], eyeLlh[2],
+                            hpr[0], hpr[1], hpr[2],
+                            0.0, ossimPlanetAltitudeMode_ABSOLUTE);
+   
+   // now compute the current lookat point
+   // if no intersection then we will fake one by extruding a lookat range meters out
+   // from current line of site
+   osg::Vec3d llh;
+   osg::Viewport* viewPort = getCamera()->getViewport();
+   if(!viewPort) return;
+   double midX=(viewPort->x()+(viewPort->width()/2.0));
+   double midY=(viewPort->y()+(viewPort->height()/2.0));
+   
+   // if we do not intersect then use the range from the previous look at and create a point
+   if(!getLatLonHeightAtWindowCoordinate(llh, midX, midY))
+   {
+      osg::Vec3d origin, ray;
+      if(makeRayAtWindowCoordinate(origin, ray, midX, midY))
+      {
+         osg::Vec3d pt = origin + ray*(theCurrentLookAt->range()/landModel->getNormalizationScale());
+         landModel->inverse(pt, llh);
+      }
+   }
+   osg::Matrixd losLsrMatrix;
+   osg::Vec3d tempHpr;
+   landModel->orientationLsrMatrix(losLsrMatrix, llh, 0.0, 0.0, 0.0);
+   
+   mkUtils::matrixToHpr(tempHpr, losLsrMatrix, theCurrentViewMatrixInverse);
+   osg::Vec3d eyeXyz;
+   osg::Vec3d losXyz;
+   landModel->forward(llh, losXyz);
+   double range = (losXyz-eye).length()*landModel->getNormalizationScale();
+   
+   theCurrentLookAt->setAll(llh[0], llh[1], llh[2],
+                            tempHpr[0], tempHpr[1], tempHpr[2],
+                            range, ossimPlanetAltitudeMode_ABSOLUTE);
+   
+   
+#if 0  
+   if(thePlanet.valid())
+   {
+      thePlanet->setLookAt(theCurrentLookAt.get());
+      thePlanet->setEyePosition(theCurrentCamera.get());
+   }
+#endif
+   //   std::cout << "<lat,lon,hgt> = <" << theCurrentLookAt->lat() << ", " << theCurrentLookAt->lon() << ", " << theCurrentLookAt->altitude() << ">" << std::endl
+   //             << "<h, p, r>     = <" << theCurrentLookAt->heading() << ", " << theCurrentLookAt->pitch() << ", " << theCurrentLookAt->roll() << ">" << std::endl
+   //   << "range         =  " << theCurrentLookAt->range() << std::endl;
+}
+
+void ossimPlanetViewer::findNodesWithId(ossimPlanetViewer::PlanetNodeList& nodeList,
+                                        const ossimString& id)
+{
+   ossimPlanetViewerFindNodesVisitor visitor(id, &nodeList, false);
+   
+   if(getSceneData())
+   {
+      getSceneData()->accept(visitor);
+   }
+}
+
+osg::ref_ptr<ossimPlanetNode> ossimPlanetViewer::findFirstNodeWithId(const ossimString& id)
+{
+   osg::ref_ptr<ossimPlanetNode> result = 0;
+   ossimPlanetViewer::PlanetNodeList nodeList;
+   ossimPlanetViewerFindNodesVisitor visitor(id, &nodeList, true);
+   
+   if(getSceneData())
+   {
+      getSceneData()->accept(visitor);
+   }
+   
+   if(nodeList.size())
+   {
+      result = nodeList[0].get();
+   }
+   
+   return result;
+}
+
+bool ossimPlanetViewer::makeRayAtWindowCoordinate(osg::Vec3d& origin,
+                                                  osg::Vec3d& ray,
+                                                  double wx, double wy)
+{
+   float local_x = wx, local_y = wy;    
+   osg::Camera* camera = const_cast<osg::Camera*>(getCameraContainingPosition(wx, wy, local_x, local_y));
+   if (!camera) camera = getCamera();
+   return makeRayAtWindowCoordinate(origin, ray, camera, local_x, local_x);
+}
+
+bool ossimPlanetViewer::makeRayAtWindowCoordinate(osg::Vec3d& origin,
+                                                  osg::Vec3d& ray,
+                                                  osg::Camera* camera,
+                                                  double wx, double wy)
+{
+   osg::Vec3d eye(0.0,0.0,0.0);
+   osg::Vec3d center(0.0,0.0,0.0);
+   osg::Vec3d up(0.0,0.0,0.0);
+   osg::Vec3d direction;
+   double fov;
+   double aspectRatio;
+   double znear;
+   double zfar;
+   osg::Matrixd pm = camera->getProjectionMatrix();
+   ray[0] = 0;
+   ray[1] = 0;
+   ray[2] = 0;
+   
+   if(!pm.getPerspective(fov, aspectRatio, znear, zfar))
+   {
+      return false;
+   }
+   camera->getViewMatrixAsLookAt(eye, center, up, 1000.0);
+   osg::Matrixd iv = camera->getViewMatrix();
+   
+   const osg::ref_ptr<osg::Viewport> viewport = camera->getViewport();
+   osg::Matrix wm;
+   wm.invert(viewport->computeWindowMatrix());
+   osg::Vec3d normalizedPoint = osg::Vec3d(wx,wy,0.0)*wm;
+  
+   double angleY = (fov*.5)*normalizedPoint[1];
+   double angleX = (fov*.5)*normalizedPoint[0]*aspectRatio;
+   direction = center - eye;
+   direction.normalize();
+   osg::Vec3d crossVec = direction^up;
+   osg::Vec3d newUp = crossVec^direction;
+   osg::Matrixd m = (osg::Matrixd::rotate(-angleX*(M_PI/180.0), newUp)*
+                     osg::Matrixd::rotate(angleY*(M_PI/180.0), crossVec));
+   ray    = direction*m;
+   origin = eye;
+   
+   return true;
+}
+
+bool ossimPlanetViewer::pickAtWindowCoordinate(PickList& result,
+                                               double wx, double wy,
+                                               osg::Node::NodeMask traversalMask)
+{
+   result.clear();
+   
+   osgUtil::LineSegmentIntersector::Intersections intersections;
+   if (computeIntersections(wx, wy, intersections, traversalMask))
+   {
+      osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
+      
+      while(hitr != intersections.end())
+      {
+         osg::Vec3d wpt = hitr->getWorldIntersectPoint();
+         osg::Vec3d llh;
+         if(model())
+         {
+            model()->inverse(wpt, llh);
+         }
+         
+         result.push_back(new PickObject(hitr->nodePath, hitr->getLocalIntersectPoint(), hitr->getWorldIntersectPoint(), llh));
+         ++hitr;
+      }
+   }
+   
+   return !result.empty();
+}
+
+bool ossimPlanetViewer::getLatLonHeightAtWindowCoordinate(osg::Vec3d& llh,
+                                                          double wx, double wy,
+                                                          osg::Node::NodeMask traversalMask)
+{
+   bool resultFlag = false;
+   osgUtil::LineSegmentIntersector::Intersections intersections;
+   if (computeIntersections(wx, wy, intersections, traversalMask))
+   {
+      osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
+      
+      if(hitr != intersections.end())
+      {
+         osg::Vec3d wpt = hitr->getWorldIntersectPoint();
+         if(model())
+         {
+            model()->inverse(wpt, llh);
+            resultFlag = true;
+         }
+      }
+   }
+   
+   return resultFlag;
+}
+
+void ossimPlanetViewer::notifyViewChanged()
+{
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theCallbackListMutex);
+   if(theBlockCallbacksFlag) return;
+   ossim_uint32 idx = 0;
+   ossim_uint32 upper = theCallbackList.size();
+   
+   for(idx = 0; idx < upper; ++idx)
+   {
+      if(theCallbackList[idx]->enableFlag())
+      {
+         theCallbackList[idx]->viewChanged(this); 
+      }
+   }
+   
+}
+
+
+#if 0
+bool ossimPlanetViewer::AddHudOverlay(osg::ref_ptr<osg::Node> hudNode)
+{
+   bool result =  false;
+   if(thePlanet.valid())
+   {
+      result = true;
+      
+      hudNode->getOrCreateStateSet()->setRenderBinDetails(11,"RenderBin");
+      theHudOverlayList.push_back(hudNode.get());
+      
+      thePlanet->addChild(hudNode.get());
+   }
+   
+   return result;
+}
+
+ossim_uint32 ossimPlanetViewer::getNumberOfHudOverlays()const
+{
+   return static_cast<ossim_uint32>(theHudOverlayList.size());
+}
+#endif
+
+const osg::Camera* ossimPlanetViewer::forceAdjustToMasterCamera(float x, float y, float& local_x, float& local_y) const
+{
+   
+   const osg::Camera* result = _camera.get(); // get and use the master camera
+   if(!result) return 0;
+   const osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); 
+   const osgViewer::GraphicsWindow* gw = dynamic_cast<const osgViewer::GraphicsWindow*>(eventState->getGraphicsContext());
+   
+   bool view_invert_y = eventState->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
+   
+   double epsilon = 0.5;
+   
+   if (_camera->getGraphicsContext() &&
+       (!gw || _camera->getGraphicsContext()==gw) &&
+       _camera->getViewport())
+   {
+      const osg::Viewport* viewport = _camera->getViewport();
+      
+      double new_x = x;
+      double new_y = y;
+      
+      if (!gw)
+      {
+         new_x = static_cast<double>(_camera->getGraphicsContext()->getTraits()->width) * (x - eventState->getXmin())/(eventState->getXmax()-eventState->getXmin());
+         new_y = view_invert_y ?
+         static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (1.0 - (y- eventState->getYmin())/(eventState->getYmax()-eventState->getYmin())) :
+         static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (y - eventState->getYmin())/(eventState->getYmax()-eventState->getXmin());
+      }
+      
+      // lets still allow for valid camera positioning even if outside the frustum if no camera is found
+      if (viewport)
+      {
+         local_x = new_x;
+         local_y = new_y;
+         
+         result = _camera.get();
+      }
+   }
+   
+   return result;
+}
+
+#if 1
+/** Compute intersections between a ray through the specified master cameras window/eye coords and a specified node.
+ * Note, when a master cameras has slaves and no viewport itself its coordinate frame will be in clip space i.e. -1,-1 to 1,1,
+ * while if its has a viewport the coordintates will be relative to its viewport dimensions. 
+ * Mouse events handled by the view will automatically be attached into the master camera window/clip coords so can be passed
+ * directly on to the computeIntersections method. */
+bool ossimPlanetViewer::computeIntersections(float x,
+                                                     float y, 
+                                                     osgUtil::LineSegmentIntersector::Intersections& intersections,
+                                                     osg::Node::NodeMask traversalMask)
+{
+   if (!_camera.valid()) return false;
+   
+   float local_x, local_y = 0.0;    
+   const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
+   if (!camera)
+   {
+      if(theIntersectWithMasterIfNotWithinAnyViewFlag)
+      {
+         camera = forceAdjustToMasterCamera(x, y, local_x, local_y);
+         if(!camera) return false;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   osgUtil::LineSegmentIntersector::CoordinateFrame cf = camera->getViewport() ? osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION;
+   osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(cf, local_x, local_y);
+   osg::Vec3d adjustedStart(picker->getStart());
+#if 0
+   if(thePlanet.valid())
+   {
+      adjustedStart[2]-=(5*thePlanet->model()->getInvNormalizationScale());
+   }
+   picker->setStart(adjustedStart);
+#endif
+   osgUtil::IntersectionVisitor iv(picker.get());
+   iv.setTraversalMask(traversalMask);
+   iv.setUseKdTreeWhenAvailable(true);
+   
+   const_cast<osg::Camera*>(camera)->accept(iv);
+   
+   if (picker->containsIntersections())
+   {
+      intersections = picker->getIntersections();
+      return true;
+   }
+   intersections.clear();
+   return false;
+}
+
+/** Compute intersections between a ray through the specified master cameras window/eye coords and a specified nodePath's subgraph. */
+bool ossimPlanetViewer::computeIntersections(float x,
+                                                     float y, 
+                                                     const osg::NodePath& nodePath, 
+                                                     osgUtil::LineSegmentIntersector::Intersections& intersections,
+                                                     osg::Node::NodeMask traversalMask)
+{
+   if (!_camera.valid() || nodePath.empty()) return false;
+   
+   float local_x, local_y = 0.0;    
+   const osg::Camera* camera = getCameraContainingPosition(x, y, local_x, local_y);
+   if (!camera)
+   {
+      if(theIntersectWithMasterIfNotWithinAnyViewFlag)
+      {
+         camera = forceAdjustToMasterCamera(x, y, local_x, local_y);
+         if(!camera) return false;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   osg::Matrixd matrix;
+   if (nodePath.size()>1)
+   {
+      osg::NodePath prunedNodePath(nodePath.begin(),nodePath.end()-1);
+      matrix = osg::computeLocalToWorld(prunedNodePath);
+   }
+   
+   matrix.postMult(camera->getViewMatrix());
+   matrix.postMult(camera->getProjectionMatrix());
+   
+   double zNear = -1.0;
+   double zFar = 1.0;
+   if (camera->getViewport())
+   {
+      matrix.postMult(camera->getViewport()->computeWindowMatrix());
+      zNear = 0.0;
+      zFar = 1.0;
+   }
+   
+   osg::Matrixd inverse;
+   inverse.invert(matrix);
+   
+   osg::Vec3d startVertex = osg::Vec3d(local_x,local_y,zNear) * inverse;
+   osg::Vec3d endVertex = osg::Vec3d(local_x,local_y,zFar) * inverse;
+   
+   osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, startVertex, endVertex);
+   
+   osgUtil::IntersectionVisitor iv(picker.get());
+   iv.setTraversalMask(traversalMask);
+   nodePath.back()->accept(iv);
+   
+   if (picker->containsIntersections())
+   {
+      intersections = picker->getIntersections();
+      return true;
+   }
+   else
+   {
+      intersections.clear();
+      return false;
+   }
+}
+#endif
+
+void ossimPlanetViewer::execute(const ossimPlanetAction& /*action*/)
+{
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetVisitors.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetVisitors.cpp
new file mode 100644
index 0000000..c56d6ed
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetVisitors.cpp
@@ -0,0 +1,112 @@
+#include <ossimPlanet/ossimPlanetVisitors.h>
+#include <ossimPlanet/ossimPlanetLayer.h>
+#include <ossimPlanet/ossimPlanetNode.h>
+
+void ossimPlanetLayerNameIdSearchVisitor::apply(osg::Node& node)
+{
+   ossimPlanetLayer* layer = dynamic_cast<ossimPlanetLayer*>(&node);
+   ossimPlanetNode* layerNode = dynamic_cast<ossimPlanetNode*>(&node);
+   
+   if(theId.empty() && theName.empty()) return;
+   
+   if(layer)
+   {
+      if(!theName.empty()&&!theId.empty())
+      {
+         if((layer->name() == theName)&&
+            (layer->id() == theId))
+         {
+            theNode = &node;
+         }
+      }
+      else if(!theName.empty())
+      {
+         if(layer->name() == theName)
+         {
+            theNode = &node;
+         }
+         
+      }
+      else if(!theId.empty())
+      {
+         if(layer->id() == theId)
+         {
+            theNode = &node;
+         }
+      }
+   }
+   else if(layerNode)
+   {
+      if(!theName.empty()&&!theId.empty())
+      {
+         if((layerNode->name() == theName)&&
+            (layerNode->id() == theId))
+         {
+            theNode = &node;
+         }
+      }
+      else if(!theName.empty())
+      {
+         if(layerNode->name() == theName)
+         {
+            theNode = &node;
+         }
+         
+      }
+      else if(!theId.empty())
+      {
+         if(layerNode->id() == theId)
+         {
+            theNode = &node;
+         }
+      }
+   }
+   if(theNode.valid()) return;
+   traverse(node);
+};
+
+ossimPlanetUpdateVisitor::ossimPlanetUpdateVisitor()
+:osgUtil::UpdateVisitor(),
+theRedrawFlag(false)
+{
+   
+}
+
+void ossimPlanetUpdateVisitor::reset()
+{
+   theRedrawFlag = false;
+}
+
+bool ossimPlanetUpdateVisitor::redrawFlag()const
+{
+   return theRedrawFlag;
+}
+
+void ossimPlanetUpdateVisitor::apply(osg::Node& node)         
+{ 
+   ossimPlanetNode* n = dynamic_cast<ossimPlanetNode*>(&node);
+   if(n)
+   {
+      if(n->redrawFlag())
+      {
+         n->setRedrawFlag(false);
+         theRedrawFlag = true;
+      }
+   }
+   UpdateVisitor::apply(node);
+}
+
+void ossimPlanetUpdateVisitor::apply(osg::Group& node)        
+{ 
+   ossimPlanetNode* n = dynamic_cast<ossimPlanetNode*>(&node);
+   if(n)
+   {
+      if(n->redrawFlag())
+      {
+         n->setRedrawFlag(false);
+         theRedrawFlag = true;
+      }
+   }
+   UpdateVisitor::apply(node);
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetWmsClient.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetWmsClient.cpp
new file mode 100644
index 0000000..f766a13
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetWmsClient.cpp
@@ -0,0 +1,246 @@
+#ifndef OSGPLANET_WITHOUT_WMS
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <map>
+#include <ossimPlanet/ossimPlanetWmsClient.h>
+#include <ossimPlanet/ossimPlanetImage.h>
+#include <ossimPlanet/ossimPlanetJpegImage.h>
+#include <ossimPlanet/ossimPlanetOssimImage.h>
+#include <wms/wmsCurlMemoryStream.h>
+#include <wms/wmsMemoryStream.h>
+#include <wms/wmsClient.h>
+#include <ossim/imaging/ossimJpegTileSource.h>
+#include <ossim/imaging/ossimImageData.h>
+#include <ossim/base/ossimIrect.h>
+#include <osgDB/ReadFile>
+#include <osgDB/Input>
+#include <osgDB/Registry>
+#include <ossimPlanet/ossimPlanetJpegImage.h>
+
+ossimPlanetWmsClient::ossimPlanetWmsClient(const std::string& server,
+                                       const std::string& path)
+      :osg::Referenced(),
+       theServer(server),
+       thePath(path),
+       theImageType("image/jpeg"),
+       theVersion("1.1.1")
+{
+   theWmsClient = new wmsClient;
+   theImageReader = new ossimPlanetOssimImage;
+}
+ossimPlanetWmsClient::ossimPlanetWmsClient(const ossimPlanetWmsClient& src)
+	:osg::Referenced(),
+        theServer(src.theServer),
+	thePath(src.thePath),
+	theImageFormats(src.theImageFormats),
+	theImageType(src.theImageType),
+	theVersion(src.theVersion),
+        theAdditionalParameters(src.theAdditionalParameters),
+	theBackgroundColor(src.theBackgroundColor),
+	theTransparentFlag(src.theTransparentFlag)
+{
+
+}
+
+ossimPlanetWmsClient::~ossimPlanetWmsClient()
+{
+}
+
+void ossimPlanetWmsClient::setServer(const std::string& server)
+{
+   theServer = server;
+}
+
+void ossimPlanetWmsClient::setPath(const std::string& path)
+{
+   thePath = path;
+}
+
+void ossimPlanetWmsClient::setAdditionalParameters(const ossimString& additionalParameters)
+{
+   theAdditionalParameters = additionalParameters.string();
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetWmsClient::createImage(ossim_uint32 width,
+                                                             ossim_uint32 height,
+                                                             const double& minLat,
+                                                             const double& minLon,
+                                                             const double& maxLat,
+                                                             const double& maxLon,
+                                                             const std::string& filename)
+{
+   
+   
+   osg::ref_ptr<ossimPlanetImage> planetImage = NULL;
+   ossimFilename file = filename.c_str();
+   wmsRefPtr<wmsMemoryStream> s;
+   bool needToRetrieve = true;
+
+   if(file!= "")
+   {
+      planetImage = readLocalImage(file);
+      if(planetImage.valid())
+      {
+         return planetImage;
+      }
+   }
+   if(needToRetrieve)
+   {
+      wmsUrl tempUrl = theWmsClient->getMapUrl(theServer,
+                                               width,
+                                               height,
+                                               minLat,
+                                               minLon,
+                                               maxLat,
+                                               maxLon,
+                                               theImageType,
+                                               theVersion);
+//       std::cout << "ossimPlanetWmsClient::createImage: Server = " << tempUrl << std::endl;
+
+      std::string tempStr = tempUrl.url();
+      if(theBackgroundColor != "")
+      {
+         tempStr += ("&BGCOLOR="+theBackgroundColor);
+         if(theTransparentFlag)
+         {
+            tempStr += ("&TRANSPARENT=TRUE");
+         }
+         else
+         {
+            tempStr += ("&TRANSPARENT=FALSE");
+         }
+         if(theAdditionalParameters != "")
+         {
+            tempStr += "&"+theAdditionalParameters;
+         }
+      }
+//       std::cout << "ossimPlanetWmsClient::createImage: GETTING URL = " << tempStr << std::endl;
+      tempUrl = tempStr;
+      if(theWmsClient->get(tempUrl))
+      {
+         wmsRefPtr<wmsMemoryStream> memS = theWmsClient->getStream();
+         if(memS->getBufferSize()>0)
+         {
+            if(file!= "")
+            {
+               ofstream out(file.c_str(),
+                            ios::out|ios::binary);
+               if(out.good())
+               {
+                  out.write((char*)(memS->getBuffer()),
+                            memS->getBufferSize());
+                  out.close();
+                  planetImage = new ossimPlanetImage;
+                  ossimPlanetOssimImage inputImage;
+                  if(!inputImage.loadFile(file, *planetImage))
+                  {
+                     planetImage = 0;
+                  }
+               }
+            }
+            else
+            {
+               planetImage = new ossimPlanetImage;
+               if(planetImage.valid())
+               {
+                  ossimPlanetJpegImage jpegImage;
+                  if(!jpegImage.loadFile(*memS, *planetImage))
+                  {
+                     planetImage = 0;
+                  }
+               }
+               else
+               {
+                  std::cerr << "ERROR: ossimPlanetWmsClient::createImage allocating planetImage" << std::endl;
+                  planetImage = 0;
+               }
+            }
+         }
+         else
+         {
+            std::cerr << "ERROR: ossimPlanetWmsClient::createImage allocating osgMemoryStream" << std::endl;
+         }
+      }
+   }
+   
+   return planetImage;
+}
+
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetWmsClient::readLocalImage(const std::string& filename)const
+{
+   ossimFilename file = filename.c_str();
+   osg::ref_ptr<ossimPlanetImage> result;
+   if(file.exists())
+   {
+      result = new ossimPlanetImage;
+      bool readImage = false;
+//       ossimPlanetJpegImage jpegImage;
+//       if(jpegImage.loadFile(file, *result))
+//       {
+//          readImage = true;
+//       }
+      if(!readImage)
+      {
+//         ossimPlanetOssimImage inputImage;
+         if(!theImageReader->loadFile(file, *result))
+         {
+            result = 0;
+         }
+      }
+   }
+
+   return result;
+}
+
+void ossimPlanetWmsClient::setImageType(const std::string& imageType)
+{
+   if(imageType == "")
+   {
+      theImageType = "image/jpeg";
+   }
+   else
+   {
+      theImageType = imageType;
+   }
+}
+
+// void ossimPlanetWmsClient::setCacheDir(const std::string& cacheDir)
+// {
+//    theCacheDir = cacheDir;
+// }
+
+std::string ossimPlanetWmsClient::getImageType()const
+{
+   return theImageType;
+}
+   
+std::string ossimPlanetWmsClient::getServer()const
+{
+	return theServer;
+}
+
+std::string ossimPlanetWmsClient::getPath()const
+{
+	return thePath;
+}
+
+void ossimPlanetWmsClient::setTransparentFlag(bool flag)
+{
+   theTransparentFlag = flag;
+}
+
+void ossimPlanetWmsClient::setBackgroundColor(const std::string& color)
+{
+   theBackgroundColor = color;
+}
+
+
+// std::string ossimPlanetWmsClient::getCacheDir()const
+// {
+//    return theCacheDir;
+// }
+
+#endif
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetWmsImageLayer.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetWmsImageLayer.cpp
new file mode 100644
index 0000000..2a4458a
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetWmsImageLayer.cpp
@@ -0,0 +1,922 @@
+#include <ossimPlanet/ossimPlanetWmsImageLayer.h>
+#include <sstream>
+#include <ossimPlanet/ossimPlanetWmsClient.h>
+#include <ossim/imaging/ossimMemoryImageSource.h>
+#include <ossim/imaging/ossimJpegWriter.h>
+#include <wms/wmsCapabilitiesParser.h>
+#include <wms/wmsCapabilitiesRoot.h>
+#include <wms/wmsCapabilitiesState.h>
+#include <ossim/base/ossimGpt.h>
+#include <ossim/imaging/ossimImageWriterFactoryRegistry.h>
+
+ossimPlanetWmsImageLayer::ossimPlanetWmsImageLayer()
+   :ossimPlanetTextureLayer(),
+    theAutoCreateCacheFlag(true)
+
+{
+   theImageType = "image/jpeg";
+   
+   theTransparentColorFlag = true;
+   theBackgroundColor = "0x000000";
+   theTransparentFlag = false;
+   theWmsClient = new ossimPlanetWmsClient;
+}
+
+ossimPlanetWmsImageLayer::ossimPlanetWmsImageLayer(const ossimPlanetWmsImageLayer& src)
+   :ossimPlanetTextureLayer(src),
+    theImageType(src.theImageType),
+    theRawCapabilities(src.theRawCapabilities),
+    theCapabilitiesUrl(src.theCapabilitiesUrl),
+    theBackgroundColor(src.theBackgroundColor),
+    theTransparentFlag(src.theTransparentFlag),
+    theAdditionalParameters(src.theAdditionalParameters),
+    theProxyHost(src.theProxyHost),
+    theProxyPort(src.theProxyPort),
+    theProxyUser(src.theProxyUser),
+    theProxyPassword(src.theProxyPassword),
+    theAutoCreateCacheFlag(src.theAutoCreateCacheFlag)
+{
+   if(src.theWmsClient.valid())
+   {
+      theWmsClient = new ossimPlanetWmsClient(*(src.theWmsClient.get()));
+      theWmsClient->setProxyHost(theProxyHost);
+      theWmsClient->setProxyPort(theProxyPort);
+      theWmsClient->setProxyUser(theProxyUser);
+      theWmsClient->setProxyPassword(theProxyPassword);
+   }
+   else
+   {
+      theWmsClient = new ossimPlanetWmsClient;
+   }
+   theWmsClient->setProxyHost(theProxyHost);
+   theWmsClient->setProxyPort(theProxyPort);
+   theWmsClient->setProxyUser(theProxyUser);
+   theWmsClient->setProxyPassword(theProxyPassword);
+}
+
+ossimPlanetTextureLayer* ossimPlanetWmsImageLayer::dup()const
+{
+   return new ossimPlanetWmsImageLayer(*this);
+}
+
+ossimPlanetTextureLayer* ossimPlanetWmsImageLayer::dupType()const
+{
+   return new ossimPlanetWmsImageLayer;
+}
+
+ossimString ossimPlanetWmsImageLayer::getClassName()const
+{
+   return "ossimPlanetWmsImageLayer";
+}
+
+ossimPlanetTextureLayerStateCode ossimPlanetWmsImageLayer::updateExtents()
+{
+   theStateCode = ossimPlanetTextureLayer_VALID;
+   if(!theDirtyExtentsFlag) return theStateCode;
+
+   ossimString name = "LAYERS";
+   if(!theServer.contains(name))
+   {
+      name = "layers";
+      if(!theServer.contains(name))
+      {
+         return theStateCode;
+      }
+   }
+#if 1  
+   bool extentsSet = false;
+   double minLat, maxLat, minLon, maxLon;
+   ossimString after = theServer.after(name);
+   after = after.after("=");
+   after = after.trim();
+   double maxScale = 0.0;
+   double minScale = 0.0;
+   if(after!= "")
+   {
+      wmsRefPtr<wmsCapabilitiesParser> parser = new wmsCapabilitiesParser;
+      std::stringstream in(theRawCapabilities);
+      wmsRefPtr<wmsCapabilitiesRoot> root = parser->parse(in);
+
+      if(root.valid())
+      {
+         after = after.before("&");
+         std::vector<ossimString> splitList;
+         
+         after.split(splitList, ",");
+         ossim_uint32 idx = 0;
+         for(idx = 0; idx < splitList.size();++idx)
+         {
+            wmsRefPtr<wmsCapabilitiesState> node = root->getNodeGivenName(splitList[idx]);
+            if(node.valid())
+            {
+               node->getLatLonBoundingBox(minLat, minLon, maxLat, maxLon);
+               ossimString tempMaxScale = node->maxScaleHint();
+               ossimString tempMinScale = node->minScaleHint();
+               double scale = tempMaxScale.toDouble();
+
+               if(!tempMaxScale.empty())
+               {
+                  if(scale > maxScale)
+                  {
+                     maxScale = scale;
+                  }
+               }
+               if(!tempMinScale.empty())
+               {
+                  minScale = tempMinScale.toDouble();
+               }
+               if(!extentsSet)
+               {
+                  theExtents->setMinMaxLatLon(minLat, minLon, maxLat, maxLon);
+                  extentsSet = true;
+               }
+               else
+               {
+                  theExtents->combineMinMaxLatLon(minLat, minLon, maxLat, maxLon);
+               }
+            }
+         }
+         if(maxScale > 0.0)
+         {
+            theExtents->setMinMaxScale(minScale, maxScale);
+         }
+      }
+   }
+#endif
+   theDirtyExtentsFlag = false;
+   
+   return theStateCode;
+}
+
+
+void ossimPlanetWmsImageLayer::updateStats()const
+{
+   theStats->setTotalTextureSize(0);
+}
+
+void ossimPlanetWmsImageLayer::resetStats()const
+{
+   updateStats();
+   theStats->setBytesTransferred(0);
+}
+
+bool ossimPlanetWmsImageLayer::hasTexture(ossim_uint32 /* width */,
+                                          ossim_uint32 height,
+                                          const ossimPlanetTerrainTileId& tileId,
+                                          const ossimPlanetGrid& grid)
+{
+   ossimPlanetGrid::GridBound bound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      ossimPlanetGrid::GridBound tileBound;
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return false;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   //double deltaLon    = (deltaXY[0])/(double)(width);
+   
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   ossimPlanetGrid::ModelPoint minLatLon, maxLatLon;
+   grid.modelBound(tileId, minLatLon, maxLatLon);
+   if(gsd.y <= theExtents->getMaxScale())
+   {
+      return true;
+   }
+//   if((gsd.y >= theExtents->getMinScale()) &&
+//      (gsd.y <= theExtents->getMaxScale()))
+//   {
+//      return true;
+//   }
+   
+   return false;
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetWmsImageLayer::getTexture(ossim_uint32 width,
+                                                                    ossim_uint32 height,
+                                                                    const ossimPlanetTerrainTileId& tileId,
+                                                                    const ossimPlanetGrid& grid,
+                                                                    ossim_int32 /*padding*/)
+{
+   if(!getEnableFlag())
+   {
+      return 0;
+   }
+   if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theWmsArchiveMutex);
+   if(theServer == "")
+   {
+      return 0;
+   }
+   ossimPlanetGrid::GridBound bound;
+   ossimPlanetGrid::GridBound tileBound;
+   if(grid.findGridBound(tileId.face(),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMinLon(), theExtents->getMinLat()),
+                         ossimPlanetGrid::ModelPoint(theExtents->getMaxLon(), theExtents->getMaxLat()),
+                         bound))
+   {
+      grid.bounds(tileId,tileBound);
+      if(!tileBound.toDrect().intersects(bound.toDrect()))
+      {
+         return 0;
+      }
+   }
+   osg::Vec2d deltaXY;
+   grid.widthHeightInModelSpace(tileId, deltaXY);
+   double deltaLat    = (deltaXY[1])/(double)(height);
+   //double deltaLon    = (deltaXY[0])/(double)(width);
+   //std::cout << "Delta lat = "<<deltaLat << std::endl;
+   //std::cout << "Delta lon = "<<deltaLon << std::endl;
+   
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+   ossimPlanetGrid::ModelPoint minLatLon, maxLatLon;
+   grid.modelBound(tileId, minLatLon, maxLatLon);
+   
+   if(gsd.y > theExtents->getMaxScale())//!//theExtents->intersectsScale(gsd.y-FLT_EPSILON,
+      //                            gsd.y+FLT_EPSILON))//gsd.y <= theExtents.theMaxGsd)
+   {
+      return 0;
+   }
+   //std::cout << "Model bound = " << minLatLon << " , " << maxLatLon << std::endl;
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   std::stringstream file;
+   ossimFilename filename;
+   //   ossimPlanetWmsClient client(theAdjustedServer);
+   //   client.setImageType(theImageType);
+   
+   // bool hasCacheDir = false;
+   if((theCompleteCacheDirectory!="")&&
+      (!theCompleteCacheDirectory.exists())&&
+      (theAutoCreateCacheFlag))
+   {
+      theCompleteCacheDirectory.createDirectory();
+   }
+   if((theCompleteCacheDirectory != "")&&
+      theCompleteCacheDirectory.exists())
+   {
+      filename = theCompleteCacheDirectory;
+      file << "F" << tileId.face() << "_L" <<tileId.level() <<"_X"<<tileId.x()<<"_Y"<<tileId.y();
+      filename = filename.dirCat(file.str().c_str());
+      if(filename.exists())
+      {
+         texture = theWmsClient->readLocalImage(filename);
+      }
+      // hasCacheDir = true;
+   }
+   if(!texture.valid())
+   {
+      if(!grid.isPolar(tileId))
+      {
+         ossimFilename tempFile;
+         if(!filename.empty())
+         {
+            tempFile = filename+"_tmp";
+         }
+         texture = theWmsClient->createImage(width,
+                                           height,
+                                           minLatLon.y(),
+                                           minLatLon.x(),
+                                           maxLatLon.y(),
+                                           maxLatLon.x(),
+                                           tempFile);
+         if(texture.valid())
+         {
+            if(tempFile.exists())
+            {
+               tempFile.rename(filename);
+            }
+         }
+      }
+   }
+   if(texture.valid())
+   {
+      texture->flipVertical();
+   }
+
+   return texture.get();
+}
+
+osg::ref_ptr<ossimPlanetImage> ossimPlanetWmsImageLayer::getTexture(ossim_uint32 level,
+                                                                    ossim_uint64 row,
+                                                                    ossim_uint64 col,
+                                                                    const ossimPlanetGridUtility& utility)
+{
+   if(!getEnableFlag())
+   {
+      return 0;
+   }
+  if(theDirtyExtentsFlag)
+   {
+      updateExtents();
+   }
+   OpenThreads::ScopedLock<OpenThreads::Mutex> lock(theWmsArchiveMutex);
+   osg::ref_ptr<ossimPlanetImage> image = 0;
+
+   if(theServer == "")
+   {
+      return NULL;
+   }
+   double minLat;
+   double minLon;
+   double maxLat;
+   double maxLon;
+   ossim_uint32 w = utility.getTileWidth();
+   ossim_uint32 h = utility.getTileHeight();
+
+   utility.getLatLonBounds(minLat,
+                           minLon,
+                           maxLat,
+                           maxLon,
+                           level,
+                           row,
+                           col);
+  if(!theExtents->intersectsLatLon(minLat, minLon, maxLat, maxLon))
+  {
+     return 0;
+  }
+   double deltaX;
+   double deltaY;
+   utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+   
+   double deltaLat    = deltaY/h;
+//   double deltaLon    = deltaX/w;
+   ossimDpt gsd = ossimGpt().metersPerDegree();
+   gsd.y *= deltaLat;
+
+   osg::ref_ptr<ossimPlanetImage> texture = 0;
+   
+   if(gsd.y > theExtents->getMaxScale())//!//theExtents->intersectsScale(gsd.y-FLT_EPSILON,
+       //                            gsd.y+FLT_EPSILON))//gsd.y <= theExtents.theMaxGsd)
+   {
+      return 0;
+   }
+   std::stringstream file;
+   ossimFilename filename;
+//   ossimPlanetWmsClient client(theAdjustedServer);
+//   client.setImageType(theImageType);
+   
+   // bool hasCacheDir = false;
+   if((theCompleteCacheDirectory!="")&&
+      (!theCompleteCacheDirectory.exists())&&
+      (theAutoCreateCacheFlag))
+   {
+      theCompleteCacheDirectory.createDirectory();
+   }
+   if((theCompleteCacheDirectory != "")&&
+      theCompleteCacheDirectory.exists())
+   {
+      filename = theCompleteCacheDirectory;
+      file << "L" <<level <<"_X"<<col<<"_Y"<<row;
+      filename = filename.dirCat(file.str().c_str());
+      // hasCacheDir = true;
+   }
+   if(!image.valid())
+   {
+      if(filename.exists())
+      {
+         filename.remove();
+      }
+      if(utility.getFace(level, row, col)<4)
+      {
+         ossimFilename tempFile;
+         if(!filename.empty())
+         {
+            tempFile = filename+"_tmp";
+         }
+         image = theWmsClient->createImage(w,
+                                    h,
+                                    minLat,
+                                    minLon,
+                                    maxLat,
+                                    maxLon,
+                                    tempFile);
+         if(image.valid())
+         {
+            if(tempFile.exists())
+            {
+               tempFile.rename(filename);
+            }
+         }
+      }
+      else
+      {
+         double deltaX;
+         double deltaY;
+         utility.getWidthHeightInDegrees(deltaX, deltaY, level, row, col);
+         
+         std::vector<ossimPlanetGridUtility::GridPoint> points;
+         utility.createGridPoints(points,
+                                  level,
+                                  row,
+                                  col,
+                                  w,
+                                  h);
+         std::vector<osg::Vec2d> minMaxPairs;
+         utility.getGeographicLonCrossings(minMaxPairs, level, row, col);
+         
+         ossim_uint32 size = minMaxPairs.size();
+         ossim_uint32 idx = 0;
+         
+         for(idx = 0; idx < size; ++idx)
+         {
+            ossimFilename tempFile;
+            if(filename != "")
+            {
+               tempFile = ossimFilename(filename + "_" + ossimString::toString(idx));
+            }
+            minLon = minMaxPairs[idx][0];
+            maxLon = minMaxPairs[idx][1];
+            
+            double deltaLat    = deltaY/h;
+            double deltaLon    = deltaX/w;
+            //ossim_uint32 dx = (ossim_uint32)(((maxLon-minLon)/deltaLon));
+            //ossim_uint32 dy = (ossim_uint32)(((maxLat-minLat)/deltaLat));
+            ossimRefPtr<ossimImageData> data;
+            osg::ref_ptr<ossimPlanetImage> dataPlanetImage;
+
+            // need to fix this.  This is actually wrong for the polare faces to do it like this.  Note,
+            // the only WMS output projection that can do the world is geographic (that I know of),  We really
+            // need a polar projectino server that is comon amond all WMS's or can be queried for support.
+            // For now I will leave it.  But later I need to ad looping over all geographc tiles as yoou approach the
+            // pole.  This would force a slow hit.
+            dataPlanetImage = theWmsClient->createImage(w,//dx,
+                                                        h,//dy,
+                                                        minLat,
+                                                        minLon,
+                                                        maxLat,
+                                                        maxLon,
+                                                        tempFile);
+            if((tempFile!= "")&&tempFile.exists())
+            {
+               tempFile.remove();
+            }
+            if(dataPlanetImage.valid())
+            {
+               data = dataPlanetImage->toOssimImage();
+            }
+            else
+            {
+               data = 0;
+            }
+            if(data.valid()&&data->getBuf()&&(data->getDataObjectStatus()!=OSSIM_EMPTY))
+            {
+               if(!image.valid())
+               {
+                  image = new ossimPlanetImage(ossimPlanetTerrainTileId(0,
+                                                                        level,
+                                                                        row,
+                                                                        col));
+               }
+               convertToOsg(data.get(),
+                            image.get(),
+                            osg::Vec2d(minLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon+deltaLon,
+                                       maxLat),
+                            osg::Vec2d(maxLon+deltaLon,
+                                       minLat-deltaLat),
+                            osg::Vec2d(minLon,
+                                       minLat-deltaLat),
+                            points,
+                            utility,
+                            w,
+                            h);
+               
+            }
+         }
+         if(image.valid())
+         {
+            if(filename != "")
+            {
+               ossimPushNotifyFlags();
+               ossimSetNotifyFlag(ossimNotifyFlags_NONE);
+               ossimRefPtr<ossimImageData> data = image->toOssimImage();
+               ossimRefPtr<ossimMemoryImageSource> memSource = new ossimMemoryImageSource;
+               
+               memSource->setImage(data.get());
+               theWriter->disconnect();
+               theWriter->connectMyInputTo(0, memSource.get());
+               theWriter->setOutputName(filename.c_str());
+               theWriter->execute();
+               ossimPopNotifyFlags();
+            }
+         }
+      }
+      if(image.valid())
+      {
+         image->setState(ossimPlanetImage::ossimPlanetImageStateType_LOADED);
+      }
+   }
+   else
+   {
+      image->setState(ossimPlanetImage::ossimPlanetImageStateType_LOADED);
+   }
+   if(image.valid())
+   {
+      image->setId(ossimPlanetTerrainTileId(0, level, col, row));
+      if(image->getNumberOfComponents() == 3)
+      {
+         insertAlpha(image.get());
+      }
+      if(theTransparentColorFlag)
+      {
+         addTransparent(image.get());
+      }
+      image->setPixelStatus();
+      if(utility.getFace(level, row, col)<4)
+      {
+         image->flipVertical();
+      }
+   }
+   
+   return image;
+}
+
+void ossimPlanetWmsImageLayer::setServer(const std::string& serverString)
+{
+   theServer = serverString;
+
+   adjustServerString();
+
+   dirtyExtents();
+}
+
+const std::string& ossimPlanetWmsImageLayer::getServer()const
+{
+   return theServer;
+}
+
+void ossimPlanetWmsImageLayer::adjustServerString()
+{
+//    std::cout << "SERVER STRING START = " << theServer << std::endl;
+   theAdjustedServer = theServer;
+   ossimString name = "FORMAT";
+   if(!theAdjustedServer.contains(name))
+   {
+      name = "format";
+   }
+   ossimString::size_type startPos = theAdjustedServer.find(name.string());
+   if(startPos!=std::string::npos)//theServer.contains(name))
+   {
+      ossimString formatString = theAdjustedServer.after(name.string());
+      formatString = formatString.after("=");
+      formatString = formatString.trim();
+      if(formatString!="")
+      {
+         theImageType = formatString.before("&");
+      }
+      ossimString::size_type endPos = theAdjustedServer.find("&", startPos);//+name.length());
+      
+
+      if(endPos != std::string::npos)
+      {
+         endPos += 1;
+         theAdjustedServer.erase(theAdjustedServer.begin()+startPos, theAdjustedServer.begin()+endPos);
+      }
+      else
+      {
+         theAdjustedServer.erase(theAdjustedServer.begin()+startPos, theAdjustedServer.end());
+     }
+   }
+
+//    std::cout << "ADJUSTED 1: " << theAdjustedServer << std::endl;
+   // now just extract layers and styles so we can determine directory cache
+   //
+   name = "LAYERS";
+   if(!theAdjustedServer.contains(name))
+   {
+      name = "layers";
+   }
+   startPos = theAdjustedServer.find(name.string());
+   if(startPos!=std::string::npos)
+   {
+      ossimString value = theAdjustedServer.after(name.string());
+      value = value.after("=");
+      value = value.trim();
+      if(value!="")
+      {
+         value = value.before("&");
+      }
+      ossimString::size_type endPos = theAdjustedServer.find("&", startPos);//+name.length());
+      if(endPos != std::string::npos)
+      {
+         endPos += 1;
+      }
+      value.split(theLayers, ",");
+   }
+   // now just extract layers and styles so we can determine directory cache
+   //
+   name = "STYLES";
+   if(!theAdjustedServer.contains(name))
+   {
+      name = "styles";
+   }
+   startPos = theAdjustedServer.find(name.string());
+   if(startPos!=std::string::npos)
+   {
+      ossimString value = theAdjustedServer.after(name.string());
+      value = value.after("=");
+      value = value.trim();
+      if(value!="")
+      {
+         value = value.before("&");
+      }
+      ossimString::size_type endPos = theAdjustedServer.find("&", startPos);//+name.length());
+      if(endPos != std::string::npos)
+      {
+         endPos += 1;
+      }
+      value.split(theStyles, ",");
+   }
+
+   // make sure we reset the full path directory by forcing a call
+   // to set cache directory
+   setCacheDirectory(getCacheDirectory());
+
+   theImageType = theImageType.downcase();
+   theWriter = 0;
+   // let's use our plugin writer if it exists.  Seems to core dump on windows when using the GDAL png.
+//   if(theImageType.downcase() == "image/png")
+//   {
+//	   theWriter = ossimImageWriterFactoryRegistry::instance()->createWriter(ossimString("ossimPngWriter"));
+//   }
+   if(!theWriter.valid())
+   {
+	  theWriter = ossimImageWriterFactoryRegistry::instance()->createWriter(theImageType);
+   }
+   if(!theWriter.valid())
+   {
+      theWriter = new ossimJpegWriter;
+   }
+
+   if(!theAdjustedServer.empty())
+   {
+      if(!theAdjustedServer.contains("SRS=")&&
+         !theAdjustedServer.contains("srs="))
+      {
+         if(*(theAdjustedServer.begin() + theAdjustedServer.size()-1) != '&')
+         {
+             theAdjustedServer += "&";
+         }
+         theAdjustedServer += "SRS=EPSG:4326";
+      }
+      if(!theAdjustedServer.contains("SERVICE=")&&
+         !theAdjustedServer.contains("service="))
+      {
+         if(*(theAdjustedServer.begin() + theAdjustedServer.size()-1) != '&')
+         {
+             theAdjustedServer += "&";
+         }
+         theAdjustedServer += "SERVICE=WMS";
+         
+      }
+   }
+   theWmsClient->setServer(theAdjustedServer);
+   theWmsClient->setImageType(theImageType);
+}
+
+const std::string& ossimPlanetWmsImageLayer::getImageType()const
+{
+   return theImageType;
+}
+
+void ossimPlanetWmsImageLayer::setImageType(const std::string& imageType)
+{
+   theImageType = imageType;
+}
+
+const ossimFilename& ossimPlanetWmsImageLayer::getCacheDirectory()const
+{
+   return theCacheDirectory;
+}
+
+const ossimFilename& ossimPlanetWmsImageLayer::getCompleteCacheDirectory()const
+{
+   return theCompleteCacheDirectory;
+}
+
+void ossimPlanetWmsImageLayer::setCacheDirectory(const ossimFilename& cacheDir)
+{
+   theCacheDirectory = cacheDir;
+   theCompleteCacheDirectory=cacheDir;
+   if(!theCacheDirectory.empty())
+   {
+      wmsUrl url(theAdjustedServer.string());
+      ossimString server = ossimFilename(ossimString(url.server()).substitute(".", "_", true));
+	  server = server.substitute("/","_",true);
+	  server = server.substitute(":","_",true);
+
+      if(!server.empty())
+      {
+         theCompleteCacheDirectory = theCacheDirectory.dirCat(server);
+         if(theLayers.size() == 1)// if it's not a composite
+         {
+            theCompleteCacheDirectory = theCacheDirectory.dirCat(server);
+            theCompleteCacheDirectory = theCompleteCacheDirectory.dirCat(theLayers[0]);
+            if(theStyles.size()==1)
+            {
+               theCompleteCacheDirectory = theCompleteCacheDirectory.dirCat(theStyles[0]);
+           }
+         }
+      }
+	  if(!theCompleteCacheDirectory.exists())
+	  {
+		  theCompleteCacheDirectory.createDirectory(true);
+	  }
+   }
+}
+
+void ossimPlanetWmsImageLayer::setRawCapabilities(const ossimString& rawCapabilities)
+{
+   theRawCapabilities = rawCapabilities;
+   dirtyExtents();
+}
+
+const ossimString& ossimPlanetWmsImageLayer::getRawCapabilities()const
+{
+   return theRawCapabilities;
+}
+
+void ossimPlanetWmsImageLayer::setCapabilitiesUrl(const std::string& url)
+{
+   theCapabilitiesUrl = url;
+   dirtyExtents();
+
+}
+
+const std::string& ossimPlanetWmsImageLayer::getCapabilitiesUrl()const
+{
+   return theCapabilitiesUrl;
+}
+
+void ossimPlanetWmsImageLayer::setBackgroundColor(const ossimString& color)
+{
+   theBackgroundColor = color;
+}
+
+const ossimString& ossimPlanetWmsImageLayer::getBackgroundColor()const
+{
+   return theBackgroundColor;
+}
+
+void ossimPlanetWmsImageLayer::setTransparentFlag(bool flag)
+{
+   theTransparentFlag = flag;
+}
+
+bool ossimPlanetWmsImageLayer::getTransparentFlag()const
+{
+   return theTransparentFlag;
+}
+
+void ossimPlanetWmsImageLayer::setAdditionalParameters(const ossimString& additionalParameters)
+{
+   theAdditionalParameters = additionalParameters;
+   dirtyExtents();
+}
+
+const ossimString& ossimPlanetWmsImageLayer::getAdditionalParameters()const
+{
+   return theAdditionalParameters;
+}
+
+void ossimPlanetWmsImageLayer::setAutoCreateCacheFlag(bool value)
+{
+   theAutoCreateCacheFlag = value;
+}
+
+bool ossimPlanetWmsImageLayer::getAutoCreateCacheFlag()const
+{
+   return theAutoCreateCacheFlag;
+}
+   
+void ossimPlanetWmsImageLayer::clearDiskCache()
+{
+   if(theCompleteCacheDirectory.exists())
+   {
+      ossimFilename wildcardFiles = theCompleteCacheDirectory.dirCat(".*");
+      ossimFilename::wildcardRemove(wildcardFiles);
+   }
+}
+
+ossimRefPtr<ossimXmlNode> ossimPlanetWmsImageLayer::saveXml(bool /*recurse*/)const
+{
+   ossimRefPtr<ossimXmlNode> result = ossimPlanetTextureLayer::saveXml();
+
+   result->addChildNode("cacheDirectory", theCacheDirectory);
+   result->addChildNode("completeCacheDirectory", theCompleteCacheDirectory);
+   result->addChildNode("server", theServer);
+   result->addChildNode("imageType", theImageType);
+   result->addChildNode("capabilitiesUrl", theCapabilitiesUrl);
+   result->addChildNode("backgroundColor", theBackgroundColor);
+   result->addChildNode("transparentColorFlag", ossimString::toString(theTransparentFlag));
+   result->addChildNode("additionalParameters", theAdditionalParameters);
+   
+   result->addChildNode("proxyHost", theProxyHost);
+   result->addChildNode("proxyPort", theProxyPort);
+   result->addChildNode("proxyUser", theProxyUser);
+   result->addChildNode("proxyPassword", theProxyPassword);
+
+   return result.get();
+}
+
+bool ossimPlanetWmsImageLayer::loadXml(ossimRefPtr<ossimXmlNode> node)
+{
+   if(!ossimPlanetTextureLayer::loadXml(node)) return false;
+   
+   ossimRefPtr<ossimXmlNode> server               = node->findFirstNode("server");
+   ossimRefPtr<ossimXmlNode> imageType            = node->findFirstNode("imageType");
+   ossimRefPtr<ossimXmlNode> cacheDirectory       = node->findFirstNode("cacheDirectory");
+   ossimRefPtr<ossimXmlNode> capabilitiesUrl      = node->findFirstNode("capabilitiesUrl");
+   ossimRefPtr<ossimXmlNode> backgroundColor      = node->findFirstNode("backgroundColor");
+   ossimRefPtr<ossimXmlNode> transparentFlag      = node->findFirstNode("transparentFlag");
+   ossimRefPtr<ossimXmlNode> additionalParameters = node->findFirstNode("additionalParameters");
+   ossimRefPtr<ossimXmlNode> extents              = node->findFirstNode("ossimPlanetExtents");
+   ossimRefPtr<ossimXmlNode> lookAt               = node->findFirstNode("ossimPlanetLookAt");
+   ossimRefPtr<ossimXmlNode> proxyHost            = node->findFirstNode("proxyHost");
+   ossimRefPtr<ossimXmlNode> proxyPort            = node->findFirstNode("proxyPort");
+   ossimRefPtr<ossimXmlNode> proxyUser            = node->findFirstNode("proxyUser");
+   ossimRefPtr<ossimXmlNode> proxyPassword        = node->findFirstNode("proxyPassword");
+  
+   if(!transparentFlag.valid())
+   {
+      transparentFlag = node->findFirstNode("transparentColorFlag");
+   }
+   if(server.valid())
+   {
+      setServer(server->getText());
+   }
+   if(imageType.valid())
+   {
+      setImageType(imageType->getText());      
+   }
+   if(cacheDirectory.valid())
+   {
+      setCacheDirectory(cacheDirectory->getText());     
+   }
+   if(capabilitiesUrl.valid())
+   {
+      setCapabilitiesUrl(capabilitiesUrl->getText());      
+   }
+   if(backgroundColor.valid())
+   {
+      setBackgroundColor(backgroundColor->getText());      
+   }
+   if(transparentFlag.valid())
+   {
+      setTransparentFlag(transparentFlag->getText().toBool());
+   }
+   if(additionalParameters.valid())
+   {
+      setAdditionalParameters(additionalParameters->getText());      
+   }
+   if(extents.valid())
+   {
+      getExtents()->loadXml(extents.get());
+   }
+   if(proxyHost.valid())
+   {
+      setProxyHost(proxyHost->getText());
+   }
+   else
+   {
+      setProxyHost("");
+   }
+   if(proxyPort.valid())
+   {
+      setProxyPort(proxyPort->getText());
+   }
+   else
+   {
+      setProxyPort("");
+   }
+   if(proxyUser.valid())
+   {
+      setProxyUser(proxyUser->getText());
+   }
+   else
+   {
+      setProxyUser("");
+   }
+   if(proxyPassword.valid())
+   {
+      setProxyPassword(proxyPassword->getText());
+   }
+   else
+   {
+      setProxyPassword("");
+   }
+   return server.valid();
+}
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetXmlAction.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetXmlAction.cpp
new file mode 100644
index 0000000..f1dc094
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetXmlAction.cpp
@@ -0,0 +1,225 @@
+#include <ossimPlanet/ossimPlanetXmlAction.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <ossim/base/ossimXmlDocument.h>
+#include <sstream>
+
+ossimPlanetXmlAction::ossimPlanetXmlAction(const ossimString& code, 
+                                           const ossimString& originatingFederate)
+:ossimPlanetAction(originatingFederate)
+{
+   setSourceCode(code);
+}
+
+ossimPlanetXmlAction::ossimPlanetXmlAction(ossimRefPtr<ossimXmlNode> code, 
+                                           const ossimString& originatingFederate)
+:ossimPlanetAction(originatingFederate)
+{
+	setXmlNode(code);
+}
+
+void ossimPlanetXmlAction::setTarget(const ossimString& value)
+{
+	ossimPlanetAction::setTarget(value);
+	if(theXmlNode.valid())
+	{
+		if(theXmlNode->getAttributeValue("target") != value.c_str())
+		{
+			// add the attribute if not present already else change it
+			//
+			theXmlNode->setAttribute("target", value, true);
+			std::ostringstream out;
+			out << *theXmlNode;
+			theSourceCode = out.str();
+		}
+	}
+}
+
+void ossimPlanetXmlAction::setCommand(const ossimString& value)
+{
+	ossimPlanetAction::setCommand(value);
+	
+	// Update the tag value if the command changes.
+	if(theXmlNode.valid() &&(theXmlNode->getTag()!=value.c_str()))
+	{
+		theXmlNode->setTag(value);
+		std::ostringstream out;
+		out << *theXmlNode;
+		theSourceCode = out.str();
+	}
+}
+
+bool ossimPlanetXmlAction::setSourceCode(const ossimString& code)
+{
+   ossim_uint32 bytesRead = 0;
+   ossimRefPtr<ossimXmlNode> node = 0;
+   if(code[(size_t)0] == '<')
+   {
+      std::istringstream in(code);
+      if(code[(size_t)1] == '?')
+      {
+         ossimRefPtr<ossimXmlDocument> doc = new ossimXmlDocument;
+         if(doc->read(in))
+         {
+            node = doc->getRoot();
+         }
+      }
+      else
+      {
+         node = new ossimXmlNode;
+         if(!node->read(in))
+         {
+            node = 0;
+         }
+      }
+      bytesRead = in.tellg();
+   }
+   // now setup the sourcecode that was read in
+   //
+   if(bytesRead > 0)
+   {
+      theSourceCode = ossimString(code.begin(),
+                                  code.begin() + bytesRead);
+   }
+   
+   setXmlNode(node.get());
+   return node.valid();
+}
+
+void ossimPlanetXmlAction::setXmlNode(ossimRefPtr<ossimXmlNode> node)
+{
+   theXmlNode = node;
+   if(theXmlNode.valid())
+   {
+      ossimString value;
+      setCommand(theXmlNode->getTag());
+      if(theXmlNode->getAttributeValue(value, "target"))
+      {
+         setTarget(value);
+      }
+      else
+      {
+         setTarget("");
+      }
+      if(theXmlNode->getAttributeValue(value, "origin"))
+      {
+         setOrigin(value);
+      }
+      else
+      {
+         setOrigin("");
+      }
+      std::ostringstream out;
+      out << *theXmlNode;
+      theSourceCode = out.str();
+   }
+   else
+   {
+      setTarget("");
+      setOrigin("");
+      theSourceCode = "";
+   }
+}
+
+ossimString ossimPlanetXmlAction::id()const
+{
+	if(theXmlNode.valid())
+	{
+		return theXmlNode->getAttributeValue("id");
+	}
+	
+	return "";
+}
+
+ossimString ossimPlanetXmlAction::name()const
+{
+	if(theXmlNode.valid())
+	{
+		return theXmlNode->getAttributeValue("name");
+	}
+	
+	return "";
+}
+
+osg::ref_ptr<ossimPlanetXmlAction> ossimPlanetXmlAction::duplicateChildAndMaintainAction(ossim_uint32 childIdx)const
+{
+	osg::ref_ptr<ossimPlanetXmlAction> result;
+	if(theXmlNode.valid())
+	{
+		const ossimXmlNode::ChildListType& children = theXmlNode->getChildNodes();
+		if(childIdx < children.size())
+		{
+			ossimXmlNode::AttributeListType attributes;
+			theXmlNode->duplicateAttributes(attributes);
+			ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+			node->setAttributes(attributes);
+			node->addChildNode((ossimXmlNode*)children[childIdx]->dup());
+			node->setTag(theXmlNode->getTag());
+			result =  new ossimPlanetXmlAction(node, origin());
+			result->setTarget(target());
+		}
+	}	
+	
+	return result;
+}
+
+osg::ref_ptr<ossimPlanetXmlAction> ossimPlanetXmlAction::duplicateChildPropertiesAndMaintainAction(ossim_uint32 childIdx)const
+{
+	osg::ref_ptr<ossimPlanetXmlAction> result;
+	if(theXmlNode.valid())
+	{
+		const ossimXmlNode::ChildListType& children = theXmlNode->getChildNodes();
+		
+		if(childIdx < children.size())
+		{
+			ossimString value;
+			ossimXmlNode::ChildListType dupChildren;
+			ossimXmlNode::AttributeListType attributes;
+			theXmlNode->duplicateAttributes(attributes);
+			ossimRefPtr<ossimXmlNode> propertyNode = new ossimXmlNode;
+			children[childIdx]->duplicateChildren(dupChildren);
+			propertyNode->setAttributes(attributes);
+			propertyNode->setChildren(dupChildren);
+			propertyNode->setTag(command());
+
+			result = new ossimPlanetXmlAction(propertyNode,
+														 origin());
+		}	
+	}
+	
+	return result;
+}
+
+bool ossimPlanetXmlAction::hasChildren()const
+{
+	bool result = false;
+	
+	if(theXmlNode.valid())
+	{
+		return theXmlNode->getChildNodes().size();
+	}
+	
+	return false;
+}
+
+void ossimPlanetXmlAction::print(std::ostream& out)const
+{
+   if(theXmlNode.valid())
+   {
+      out << *theXmlNode;
+   }
+}
+
+void ossimPlanetXmlAction::read(std::istream& in)
+{
+   ossimRefPtr<ossimXmlNode> node = new ossimXmlNode;
+   if(node->read(in))
+   {
+      setXmlNode(theXmlNode.get());
+   }
+   else
+   {
+      setTarget(":");
+      setCommand("#syntaxerror");
+   }
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ossimPlanetYahooGeocoder.cpp b/ossimPlanet/src/ossimPlanet/ossimPlanetYahooGeocoder.cpp
new file mode 100644
index 0000000..f754507
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ossimPlanetYahooGeocoder.cpp
@@ -0,0 +1,87 @@
+#include <ossimPlanet/ossimPlanetYahooGeocoder.h>
+#include <wms/wmsCurlMemoryStream.h>
+#include <ossim/base/ossimXmlDocument.h>
+#include <ossim/base/ossimXmlNode.h>
+#include <sstream>
+
+void ossimPlanetYahooGeocoder::getLocationFromAddress(std::vector<osg::ref_ptr<ossimPlanetGeocoderLocation> >& result,
+                                                      const ossimString& location)const
+{
+   ossimString url = theUrl + "appid=" + theAppId +"&location="+location.substitute(" ", "+", true);
+   wmsCurlMemoryStream curl(url);
+
+   if(curl.download())
+   {
+      ossimXmlDocument xml;
+      ossimString buffer = curl.getStream()->getBufferAsString();
+      std::istringstream in(buffer);
+      if(xml.read(in))
+      {
+         std::vector<ossimRefPtr<ossimXmlNode> > nodes;
+         xml.findNodes("/ResultSet/Result",
+                       nodes);
+         if(nodes.size())
+         {
+            osg::ref_ptr<ossimPlanetGeocoderLocation> location = new ossimPlanetGeocoderLocation;
+            ossim_uint32 idx = 0;
+            for(idx = 0; idx < nodes.size(); ++idx)
+            {
+               ossimRefPtr<ossimXmlNode> lat     = nodes[idx]->findFirstNode("Latitude");
+               ossimRefPtr<ossimXmlNode> lon     = nodes[idx]->findFirstNode("Longitude");
+               ossimRefPtr<ossimXmlNode> zip     = nodes[idx]->findFirstNode("Zip");
+               ossimRefPtr<ossimXmlNode> city    = nodes[idx]->findFirstNode("City");
+               ossimRefPtr<ossimXmlNode> state   = nodes[idx]->findFirstNode("State");
+               ossimRefPtr<ossimXmlNode> address = nodes[idx]->findFirstNode("Address");
+               ossimRefPtr<ossimXmlNode> country = nodes[idx]->findFirstNode("Country");
+               if(lat.valid()&&lon.valid())
+               {
+                  ossimGpt gpt(lat->getText().toDouble(),
+                               lon->getText().toDouble());
+                  location->setLocation(gpt);
+                  ossimString name;
+
+                  if(address.valid())
+                  {
+                     name = address->getText().trim();
+                  }
+                  if(city.valid())
+                  {
+                     if(!name.empty())
+                     {
+                        name += ", ";
+                     }
+                     name += city->getText().trim();
+                  }
+                  if(state.valid())
+                  {
+                     if(!name.empty())
+                     {
+                        name += ", ";
+                     }
+                     name += state->getText().trim();
+                  }
+                  if(zip.valid())
+                  {
+                     if(!name.empty())
+                     {
+                        name += ", ";
+                     }
+                     name += zip->getText().trim();
+                  }
+                  if(country.valid())
+                  {
+                     if(!name.empty())
+                     {
+                        name += ", ";
+                     }
+                     name += country->getText().trim();
+                  }
+                  location->setName(name);
+                  
+                  result.push_back(location);
+               }
+            }
+         }
+      }
+   }
+}
diff --git a/ossimPlanet/src/ossimPlanet/sg_file.cpp b/ossimPlanet/src/ossimPlanet/sg_file.cpp
new file mode 100644
index 0000000..eff249e
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/sg_file.cpp
@@ -0,0 +1,143 @@
+// sg_file.cxx -- File I/O routines
+//
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_file.cpp 10536 2007-02-27 14:59:55Z gpotts $
+
+
+#include <ossimPlanet/compiler.h>
+#include <ossim/base/ossimNotify.h>
+#include STL_STRING
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#  include <io.h>
+#endif
+
+#include <ossimPlanet/sg_file.h>
+#include <string.h> // for strlen
+
+SG_USING_STD(string);
+
+
+SGFile::SGFile( const string &file) {
+    set_type( sgFileType );
+    file_name = file;
+    eof_flag = true;
+}
+
+
+SGFile::~SGFile() {
+}
+
+
+// open the file based on specified direction
+bool SGFile::open( const SGProtocolDir d ) {
+    set_dir( d );
+
+    if ( get_dir() == SG_IO_OUT ) {
+#if defined(_MSC_VER) || defined(__MINGW32__)
+        int mode = 00666;
+#else
+        mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+#endif
+	fp = ::open( file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode );
+    } else if ( get_dir() == SG_IO_IN ) {
+	fp = ::open( file_name.c_str(), O_RDONLY );
+    } else {
+//	SG_LOG( SG_IO, SG_ALERT, 
+//		"Error:  bidirection mode not available for files." );
+	return false;
+    }
+
+    if ( fp == -1 ) {
+// 	SG_LOG( SG_IO, SG_ALERT, "Error opening file: "	<< file_name );
+	return false;
+    }
+
+    eof_flag = false;
+    return true;
+}
+
+
+// read a block of data of specified size
+int SGFile::read( char *buf, int length ) {
+    // read a chunk
+    size_t result = ::read( fp, buf, length );
+    if ( length > 0 && result == 0 ) {
+        eof_flag = true;
+    }
+    return result;
+}
+
+
+// read a line of data, length is max size of input buffer
+int SGFile::readline( char *buf, int length ) {
+    // save our current position
+    int pos = lseek( fp, 0, SEEK_CUR );
+
+    // read a chunk
+    size_t result = ::read( fp, buf, length );
+    if ( length > 0 && result == 0 ) {
+        eof_flag = true;
+    }
+
+    // find the end of line and reset position
+    int i;
+    for ( i = 0; i < result && buf[i] != '\n'; ++i );
+    if ( buf[i] == '\n' ) {
+	result = i + 1;
+    } else {
+	result = i;
+    }
+    lseek( fp, pos + result, SEEK_SET );
+    
+    // just in case ...
+    buf[ result ] = '\0';
+
+    return result;
+}
+
+
+// write data to a file
+int SGFile::write( const char *buf, const int length ) {
+    int result = ::write( fp, buf, length );
+    if ( result != length ) {
+       ossimNotify(ossimNotifyLevel_WARN) << "Error writing data: " << file_name << std::endl;
+    }
+
+    return result;
+}
+
+
+// write null terminated string to a file
+int SGFile::writestring( const char *str ) {
+    int length = strlen( str );
+    return write( str, length );
+}
+
+
+// close the port
+bool SGFile::close() {
+    if ( ::close( fp ) == -1 ) {
+	return false;
+    }
+
+    eof_flag = true;
+    return true;
+}
diff --git a/ossimPlanet/src/ossimPlanet/sg_socket.cpp b/ossimPlanet/src/ossimPlanet/sg_socket.cpp
new file mode 100644
index 0000000..53da340
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/sg_socket.cpp
@@ -0,0 +1,494 @@
+// sg_socket.cxx -- Socket I/O routines
+//
+// Written by Curtis Olson, started November 1999.
+// Modified by Bernie Bright <bbright at bigpond.net.au>, May 2002.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_socket.cpp 11616 2007-08-15 18:23:33Z gpotts $
+
+#include <ossimPlanet/compiler.h>
+#include <ossim/base/ossimString.h>
+#if defined( sgi )
+#include <strings.h>
+#endif
+
+#include STL_IOSTREAM
+
+
+#include <ossimPlanet/sg_socket.h>
+
+bool SGSocket::init = false;
+
+SGSocket::SGSocket( const string& host, const string& port_, 
+		    const string& style )
+   :SGIOChannel(),
+    hostname(host),
+    port_str(port_),
+    save_len(0),
+    client(0),
+    is_tcp(false),
+    is_server(false),
+    first_read(false),
+    timeout(0),
+    theAutoGrowFlag(false)
+{
+   
+    if (!init)
+    {
+	netInit(NULL, NULL);	// plib-1.4.2 compatible
+	init = true;
+    }
+
+    save_buf.resize(2 * SG_IO_MAX_MSG_SIZE);
+    if ( style == "tcp" )
+    {
+	is_tcp = true;
+    }
+    else if ( style != "udp" )
+    {
+// 	SG_LOG( SG_IO, SG_ALERT,
+// 		"Error: SGSocket() unknown style = " << style );
+    }
+
+    set_type( sgSocketType );
+}
+
+SGSocket::SGSocket()
+   :SGIOChannel(),
+    hostname(""),
+    port_str(""),
+    save_len(0),
+    client(0),
+    is_tcp(false),
+    is_server(false),
+    first_read(false),
+    timeout(0),
+    theAutoGrowFlag(false)
+{
+   if (!init)
+   {
+      netInit(NULL, NULL);	// plib-1.4.2 compatible
+      init = true;
+   }
+   save_buf.resize(2 * SG_IO_MAX_MSG_SIZE);
+   set_type( sgSocketType );
+}
+
+SGSocket::~SGSocket()
+{
+    this->close();
+}
+
+void SGSocket::setSocket(const string& host, const string& port, const string& style)
+{
+   close();
+   hostname = host;
+   port_str = port;
+   save_len = 0;
+   is_tcp = false;
+   is_server = false;
+   first_read = false;
+   timeout = 0;
+
+   if ( style == "tcp" )
+   {
+      is_tcp = true;
+   }
+   else if ( style != "udp" )
+   {
+   }
+}
+
+void SGSocket::setSocket(const string& host, int port, const string& style)
+{
+   close();
+   hostname = host;
+   port_str = ossimString::toString(port).string();
+   save_len = 0;
+   is_tcp = false;
+   is_server = false;
+   first_read = false;
+   timeout = 0;
+
+   if ( style == "tcp" )
+   {
+      is_tcp = true;
+   }
+   else if ( style != "udp" )
+   {
+   }
+}
+
+bool
+SGSocket::make_server_socket()
+{
+    if (!sock.open( is_tcp ))
+    {
+//         SG_LOG( SG_IO, SG_ALERT, 
+//                 "Error: socket() failed in make_server_socket()" );
+	return false;
+    }
+
+    if (sock.bind( "", port ) < 0)
+    {
+// 	SG_LOG( SG_IO, SG_ALERT,
+// 		"Error: bind() failed in make_server_socket()" );
+	sock.close();
+        return false;
+    }
+
+    return true;
+}
+
+
+bool
+SGSocket::make_client_socket()
+{
+    if (!sock.open( is_tcp ))
+    {
+//         SG_LOG( SG_IO, SG_ALERT, 
+//                 "Error: socket() failed in make_client_socket()" );
+	return false;
+    }
+
+    if (sock.connect( hostname.c_str(), port ) < 0)
+    {
+// 	SG_LOG( SG_IO, SG_ALERT, 
+// 		"Error: connect() failed in make_client_socket()" );
+	sock.close();
+        return false;
+    }
+
+    return true;
+}
+
+// If specified as a server (in direction for now) open the master
+// listening socket.  If specified as a client (out direction), open a
+// connection to a server.
+bool
+SGSocket::open( SGProtocolDir direction )
+{
+    set_dir( direction );
+
+    is_server = is_tcp &&
+	(direction == SG_IO_IN || direction == SG_IO_BI);
+
+    if ( port_str == "" || port_str == "any" ) {
+	port = 0; 
+    } else {
+	port = atoi( port_str.c_str() );
+    }
+    
+    if (direction == SG_IO_IN)
+    {
+	// this means server for now
+
+	// Setup socket to listen on.  Set "port" before making this
+	// call.  A port of "0" indicates that we want to let the os
+	// pick any available port.
+	if (!make_server_socket())
+	{
+// 	    SG_LOG( SG_IO, SG_ALERT, "SG_IO_IN socket creation failed" );
+	    return false;
+	}
+
+	if ( !is_tcp )
+	{
+	    // Non-blocking UDP
+	    nonblock();
+	}
+	else
+	{
+	    // Blocking TCP
+	    // Specify the maximum length of the connection queue
+	    sock.listen( SG_MAX_SOCKET_QUEUE );
+	}
+
+    }
+    else if (direction == SG_IO_OUT)
+    {
+	// this means client for now
+
+	if (!make_client_socket())
+	{
+// 	    SG_LOG( SG_IO, SG_ALERT, "SG_IO_OUT socket creation failed" );
+	    return false;
+	}
+
+	if ( !is_tcp )
+	{
+	    // Non-blocking UDP
+	    nonblock();
+	}
+    }
+    else if (direction == SG_IO_BI && is_tcp)
+    {
+	// this means server for TCP sockets
+
+	// Setup socket to listen on.  Set "port" before making this
+	// call.  A port of "0" indicates that we want to let the os
+	// pick any available port.
+	if (!make_server_socket())
+	{
+// 	    SG_LOG( SG_IO, SG_ALERT, "SG_IO_BI socket creation failed" );
+	    return false;
+	}
+	// Blocking TCP
+	// Specify the maximum length of the connection queue
+	sock.listen( SG_MAX_SOCKET_QUEUE );
+    }
+    else
+    {
+// 	SG_LOG( SG_IO, SG_ALERT, 
+// 		"Error:  bidirection mode not available for UDP sockets." );
+	return false;
+    }
+
+    first_read = false;
+
+    return true;
+}
+
+
+// read data from socket (server)
+// read a block of data of specified size
+int
+SGSocket::read( char *buf, int length )
+{
+    if (sock.getHandle() == -1 &&
+	(client == 0 || client->getHandle() == -1))
+    {
+//        std::cout << "HERE!!!!!" << std::endl;
+	return 0;
+    }
+
+    // test for any input available on sock (returning immediately, even if
+    // nothing)
+    int result = poll();
+
+    if (result > 0)
+    {
+       if (is_tcp && is_server)
+	{
+            result = client->recv( buf, length );
+        }
+        else
+        {
+            result = sock.recv( buf, length );
+        }
+
+	if ( result != length )
+	{
+// 	    SG_LOG( SG_IO, SG_INFO, 
+// 		    "Warning: read() not enough bytes." );
+	}
+    }
+
+    return result;
+}
+
+
+// read a line of data, length is max size of input buffer
+int
+SGSocket::readline( char *buf, int /*length*/ )
+{
+   bool noMoreDataFlag = false;
+    if (sock.getHandle() == -1 &&
+	(client == 0 || client->getHandle() == -1))
+    {
+	return 0;
+    }
+    // test for any input read on sock (returning immediately, even if
+    // nothing)
+    int result = this->poll();
+    if (result > 0)
+    {
+	// read a chunk, keep in the save buffer until we have the
+	// requested amount read
+
+       if (is_tcp && is_server)
+	{
+           char *buf_ptr = &save_buf.front() + save_len;
+           result = client->recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
+
+	    if ( result > 0 )
+	    {
+		first_read = true;
+	    }
+	    save_len += result;
+
+            if(result < 0)
+            {
+               delete client;
+               client = 0;
+               noMoreDataFlag = true;
+            }
+	    // Try and detect that the remote end died.  This
+	    // could cause problems so if you see connections
+	    // dropping for unexplained reasons, LOOK HERE!
+	    else if (result == 0 && save_len == 0 && first_read == true)
+	    {
+// 		SG_LOG( SG_IO, SG_ALERT, 
+// 			"Connection closed by foreign host." );
+               delete client;
+               client = 0;
+	    }
+            else if( (result == 0) && (first_read))
+            {
+               noMoreDataFlag = true;
+            }
+	}
+	else
+	{
+           char *buf_ptr = &save_buf.front() + save_len;
+           result = sock.recv( buf_ptr, SG_IO_MAX_MSG_SIZE - save_len );
+           save_len += result;
+	}
+    }
+    // look for the end of line in save_buf
+    int i;
+    for ( i = 0; ((i < save_len) && (save_buf[i] != theReadlineDelimiter)); ++i );
+    if (save_buf[i] == theReadlineDelimiter )
+    {
+	result = i + 1;
+    }
+    else if(noMoreDataFlag)
+    {
+       if(save_len < 0)
+       {
+          save_len = 0;
+          result = 0;
+       }
+       else
+       {
+          result = save_len;
+       }
+    }
+    else
+    {
+	// no delimeter yet
+	return 0;
+    }
+
+    // we found a delimeter
+
+    // copy to external buffer
+    strncpy( buf, &save_buf.front(), result );
+    buf[result] = '\0';
+
+    // shift save buffer
+    //memmove( save_buf+, save_buf+, ? );
+    for ( i = result; i < save_len; ++i )
+    {
+	save_buf[ i - result ] = save_buf[i];
+    }
+//     save_len -= result;
+    save_len = 0;
+
+    return result;
+}
+
+
+// write data to socket (client)
+int
+SGSocket::write( const char *buf, const int length )
+{
+    netSocket* s = client == 0 ? &sock : client;
+    if (s->getHandle() == -1)
+    {
+	return 0;
+    }
+
+    bool error_condition = false;
+
+    if ( s->send( buf, length ) < 0 )
+    {
+// 	SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
+	error_condition = true;
+    }
+
+    if ( error_condition ) {
+	return 0;
+    }
+
+    return length;
+}
+
+
+// write null terminated string to socket (server)
+int SGSocket::writestring( const char *str )
+{
+    int length = strlen( str );
+    return this->write( str, length );
+}
+
+
+// close the port
+bool SGSocket::close()
+{
+   if(client)
+   {
+      delete client;
+      client = 0;
+   }
+
+   sock.close();
+
+   return true;
+}
+
+
+// configure the socket as non-blocking
+bool
+SGSocket::nonblock()
+{
+    if (sock.getHandle() == -1) {
+	return false;
+    }
+
+    sock.setBlocking( false );
+    return true;
+}
+
+int
+SGSocket::poll()
+{
+    netSocket* readers[2];
+
+    readers[0] = client != 0 ? client : &sock;
+    readers[1] = 0;
+
+    netSocket* writers[1];
+    writers[0] = 0;
+
+    int result = netSocket::select( readers, writers, timeout );
+
+    if (result > 0 && is_server && client == 0)
+    {
+	// Accept a new client connection
+	netAddress addr;
+	int new_fd = sock.accept( &addr );
+// 	SG_LOG( SG_IO, SG_INFO, "Accepted connection from "
+// 		<< addr.getHost() << ":" << addr.getPort() );
+	client = new netSocket();
+	client->setHandle( new_fd );
+	return 0;
+    }
+
+    return result;
+}
diff --git a/ossimPlanet/src/ossimPlanet/sg_socket_udp.cpp b/ossimPlanet/src/ossimPlanet/sg_socket_udp.cpp
new file mode 100644
index 0000000..9a0e245
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/sg_socket_udp.cpp
@@ -0,0 +1,200 @@
+// sg_socket.cxx -- Socket I/O routines
+//
+// Written by Curtis Olson, started November 1999.
+//
+// Copyright (C) 1999  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// 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 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id: sg_socket_udp.cpp 11618 2007-08-15 18:48:57Z gpotts $
+
+#include <ossimPlanet/compiler.h>
+
+#if defined( sgi )
+#include <strings.h>
+#endif
+
+
+#include <ossimPlanet/sg_socket_udp.h>
+
+
+SGSocketUDP::SGSocketUDP( const string& host, const string& port ) :
+    hostname(host),
+    port_str(port),
+    save_len(0)
+{
+    set_valid( false );
+}
+
+
+SGSocketUDP::~SGSocketUDP() {
+}
+
+
+// If specified as a server (in direction for now) open the master
+// listening socket.  If specified as a client (out direction), open a
+// connection to a server.
+bool SGSocketUDP::open( const SGProtocolDir d ) {
+    set_dir( d );
+
+    if ( ! sock.open( false ) ) {	// open a UDP socket
+// 	SG_LOG( SG_IO, SG_ALERT, "error opening socket" );
+	return false;
+    }
+
+    if ( port_str == "" || port_str == "any" ) {
+	port = 0; 
+    } else {
+	port = atoi( port_str.c_str() );
+    }
+    
+    // client_connections.clear();
+
+    if ( get_dir() == SG_IO_IN ) {
+	// this means server
+
+	// bind ...
+	if ( sock.bind( hostname.c_str(), port ) == -1 ) {
+// 	    SG_LOG( SG_IO, SG_ALERT, "error binding to port" << port_str );
+	    return false;
+	}
+    } else if ( get_dir() == SG_IO_OUT ) {
+	// this means client
+
+	// connect ...
+	if ( sock.connect( hostname.c_str(), port ) == -1 ) {
+// 	    SG_LOG( SG_IO, SG_ALERT,
+// 		    "error connecting to " << hostname << port_str );
+	    return false;
+	}
+    } else {
+// 	SG_LOG( SG_IO, SG_ALERT, 
+// 		"Error:  bidirection mode not available for UDP sockets." );
+	return false;
+    }
+
+    set_valid( true );
+
+    return true;
+}
+
+
+// read data from socket (server)
+// read a block of data of specified size
+int SGSocketUDP::read( char *buf, int /*length*/ ) {
+    if ( ! isvalid() ) {
+	return 0;
+    }
+
+    int result;
+
+    if ( (result = sock.recv(buf, SG_IO_MAX_MSG_SIZE, 0)) >= 0 ) {
+	buf[result] = '\0';
+	// printf("msg received = %s\n", buf);
+    }
+
+    return result;
+}
+
+
+// read a line of data, length is max size of input buffer
+int SGSocketUDP::readline( char *buf, int /*length*/ ) {
+    if ( ! isvalid() ) {
+	return 0;
+    }
+
+    // cout << "sock = " << sock << endl;
+
+    char *buf_ptr = save_buf + save_len;
+    int result = sock.recv(buf_ptr, SG_IO_MAX_MSG_SIZE, 0);
+    // printf("msg received = %s\n", buf);
+    save_len += result;
+
+    // look for the end of line in save_buf
+    int i;
+    for ( i = 0; i < save_len && save_buf[i] != '\n'; ++i );
+    if ( save_buf[i] == '\n' ) {
+	result = i + 1;
+    } else {
+	// no end of line yet
+	// cout << "no eol found" << endl;
+	return 0;
+    }
+    // cout << "line length = " << result << endl;
+
+    // we found an end of line
+
+    // copy to external buffer
+    strncpy( buf, save_buf, result );
+    buf[result] = '\0';
+    // cout << "sg_socket line = " << buf << endl;
+    
+    // shift save buffer
+    for ( i = result; i < save_len; ++i ) {
+	save_buf[ i - result ] = save_buf[i];
+    }
+    save_len -= result;
+
+    return result;
+}
+
+
+// write data to socket (client)
+int SGSocketUDP::write( const char *buf, const int length ) {
+    if ( ! isvalid() ) {
+	return 0;
+    }
+
+    bool error_condition = false;
+
+    if ( sock.send( buf, length, 0 ) < 0 ) {
+// 	SG_LOG( SG_IO, SG_WARN, "Error writing to socket: " << port );
+	error_condition = true;
+	return 0;
+    }
+
+    return length;
+}
+
+
+// write null terminated string to socket (server)
+int SGSocketUDP::writestring( const char *str ) {
+    if ( !isvalid() ) {
+	return 0;
+    }
+
+    int length = strlen( str );
+    return write( str, length );
+}
+
+
+// close the port
+bool SGSocketUDP::close() {
+    if ( !isvalid() ) {
+	return 0;
+    }
+
+    sock.close();
+
+    return true;
+}
+
+
+// configure the socket as non-blocking
+bool SGSocketUDP::setBlocking( bool value ) {
+    sock.setBlocking( value );
+
+    return true;
+}
diff --git a/ossimPlanet/src/ossimPlanet/ul.cpp b/ossimPlanet/src/ossimPlanet/ul.cpp
new file mode 100644
index 0000000..0ce529d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ul.cpp
@@ -0,0 +1,544 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ul.cxx 2129 2007-10-16 00:45:26Z fayjf $
+*/
+
+
+#include <ossimPlanet/ul.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef UL_MSVC
+#include <direct.h>
+#else
+#include <dirent.h>
+#endif
+
+#ifdef UL_MSVC
+#define SLASH "\\"
+#else
+#define SLASH "/"
+#endif
+
+
+struct _ulDir
+{
+  char dirname [ UL_NAME_MAX+1 ];
+  ulDirEnt curr ;
+
+#ifdef UL_MSVC
+  WIN32_FIND_DATA data ;
+  HANDLE hFind ;
+  bool first ;
+  bool done ;
+#else
+  DIR *dirp ;
+#endif
+} ;
+
+
+void ulInit ()
+{
+}
+
+
+ulDir* ulOpenDir ( const char* dirname )
+{
+  ulDir* dir = new ulDir;
+  if ( dir != NULL )
+  {
+    strcpy( dir->dirname, dirname ) ;
+
+#ifdef UL_MSVC
+    char search[_MAX_PATH];
+    strcpy(search,dirname);
+    
+    //munch the directory seperator
+    int len = strlen(search);
+    if ( len>0 && strchr("/\\",search[len-1]) )
+      search[len-1] = 0;
+    
+    //add the wildcard
+    strcat(search,"/*.*");
+    
+    dir->first = true;
+    dir->done = false;
+    dir->hFind = FindFirstFile(search, &dir->data);
+    if (dir->hFind == INVALID_HANDLE_VALUE)
+    {
+      delete dir;
+      dir = NULL;
+    }
+#else
+    dir->dirp = opendir(dirname) ;
+
+    if ( dir->dirp == NULL )
+    {
+      delete dir ;
+      dir = NULL ;
+    }
+#endif
+  }
+  return dir;
+}
+
+
+ulDirEnt* ulReadDir ( ulDir* dir )
+{
+  //read the next entry from the directory
+#ifdef UL_MSVC
+  //update state
+  if ( dir->first )
+    dir->first = false ;
+  else if ( !dir->done && !FindNextFile(dir->hFind,&dir->data) )
+    dir->done = true ;
+  if ( dir->done )
+    return NULL ;
+
+  strcpy( dir->curr.d_name, dir->data.cFileName ) ;
+#else
+  struct dirent* direntp = readdir( dir->dirp );
+  if ( !direntp )
+    return NULL ;
+
+  strcpy( dir->curr.d_name, direntp->d_name );
+#endif
+
+  //determine if this entry is a directory
+#ifdef UL_MSVC
+  dir->curr.d_isdir = ( dir->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0;
+ #else
+  char path[ 1000 + UL_NAME_MAX+1 ];
+  sprintf( path, "%s/%s", dir->dirname, dir->curr.d_name );
+  struct stat buf ;
+  if ( stat(path,&buf) == 0 )
+    dir->curr.d_isdir = (buf.st_mode & S_IFDIR) != 0 ;
+  else
+    dir->curr.d_isdir = false ;
+#endif
+
+  return( &dir->curr ) ;
+}
+
+
+
+void ulCloseDir ( ulDir* dir )
+{
+  if ( dir != NULL )
+  {
+#ifdef UL_MSVC
+    FindClose(dir->hFind);
+#else
+    closedir ( dir->dirp ) ;
+#endif
+    delete dir ;
+  }
+}
+
+bool ulFileExists ( const char *fileName )
+{
+#ifdef UL_MSVC
+  struct _stat buf ;
+
+  if ( _stat ( fileName, &buf ) < 0 )
+    return false ;
+
+  return ((S_IFREG & buf.st_mode ) !=0) ;
+#else
+  struct stat buf ;
+
+  if ( stat ( fileName, &buf ) < 0 )
+    return false ;
+
+  return ((S_ISREG ( buf.st_mode )) != 0) ;
+#endif
+}
+
+char* ulMakePath( char* path, const char* dir, const char* fname )
+{
+  if ( fname )
+  {
+    if ( !ulIsAbsolutePathName (fname) &&
+       dir != NULL && dir[0] != '\0' )
+    {
+      strcpy ( path, dir ) ;
+      strcat ( path, SLASH ) ;
+      strcat ( path, fname ) ;
+    }
+    else
+      strcpy ( path, fname ) ;
+  }
+  else
+     path [0] = 0 ;
+  return( path );
+}
+
+
+static int recursiveFindFileInSubDirs ( char * filenameOutput, 
+						const char * tPath,  const char * tfnameInput ) 
+{
+  int bFound = FALSE;
+  char tempString [ 1024 ];
+
+	ulMakePath ( filenameOutput, tPath, tfnameInput ) ;
+
+	if ( ulFileExists ( filenameOutput ) )
+		return TRUE;
+
+	ulDir* dirp = ulOpenDir(tPath);
+
+	if ( dirp != NULL )
+	{
+		ulDirEnt* dp;
+
+		while ( ! bFound && ((dp = ulReadDir(dirp)) != NULL ) )
+		{
+      // I am doing recursive ulOpenDir/ulReadDirs here.
+      // I know this works under Windo$.
+      if ( dp->d_isdir &&
+           strcmp( dp->d_name, ".") != 0 &&
+           strcmp( dp->d_name, "..") != 0 )
+      {
+        ulMakePath ( tempString, tPath, dp->d_name) ;
+        bFound = recursiveFindFileInSubDirs ( filenameOutput,
+                                              tempString, tfnameInput );
+      }
+      
+		}
+		ulCloseDir ( dirp ) ;
+	}
+
+	return bFound;
+}
+    
+
+
+void ulFindFile( char *filenameOutput, const char *path, 
+											  const char * tfnameInput, const char *sAPOM ) 
+/*
+  adds tfnameInput to the path and puts this into the buffer filenameOutput.
+  sAPOM is used iff path contains "$(APOM)"
+
+  handles special chars in path:
+
+  ";;" is replaced by ";"
+  "$$" is replaced by "$"
+  "$(APOM)" is replaced by sAPOM
+
+  If there are ";" in path, the path-variable is interpreted as several
+  paths "segments", delimited by ";". The first file found by this function
+  is returned.
+
+  It looks from left to right.
+
+  A segment may end in $(...). ulFindFile will then look in in this
+  path and recursively in all the sub-paths
+ 
+  Some examples:
+ 
+  for loading *.MDl-models, it is very nice to set the texture path to
+
+  $(APOM);$(APOM)/texture;$(APOM)/../texture
+
+  This consits of three segments and tells ulFindFile to look in the 
+  path of the model, in a subpath texture and in a path texture "besides"
+  the path of the model. Some *.mdl-models are shipped in a directory which
+  conatins a "texture"-directory, a "Model"-directory and others. In this
+  case you find the texture in $(APOM)/../texture
+ 
+  Another example: You have all your textures in a directory-structure
+  under /roomplan.  For example brick is under /roomplan/bricks, wood is
+  under /roomplan/wood, oak is under /roomplan/wood/oak. Then you should
+  use the following texture path:
+
+  "/roomplan/$(...)"
+ 
+  If you dont want all of the bells and whistles, just call:
+  _ssgMakePath ( filenameOutput, path, tfnameInput ) ;
+*/ 
+ 
+{
+  
+  char temp_texture_path[1024], *s_ptr, *s_ptr1, *current_path;
+  
+  strncpy(temp_texture_path, path, 1024);
+  current_path = temp_texture_path;
+  s_ptr = temp_texture_path;
+
+  while ( *s_ptr != 0 )
+  {
+    if ( *s_ptr == ';' )
+    {
+    if ( s_ptr [ 1 ] == ';' )
+      {
+    // replace ";;" with ";"
+        s_ptr1 = ++s_ptr; // both pointers on second ";"
+
+        while ( *s_ptr1 != 0)
+        {  s_ptr1 [ 0 ] = s_ptr1 [ 1 ];
+          s_ptr1++;
+        }
+      }
+      else
+      {
+    // found a single ';'. This delimits paths
+        *s_ptr++ = 0;
+        ulMakePath ( filenameOutput, current_path, tfnameInput ) ;
+
+        if ( ulFileExists ( filenameOutput ) )
+          return; // success!
+
+        // this path doesnt hold the texture. Try next one
+        current_path = s_ptr;
+      }
+    }
+    else if ( *s_ptr == '$' )
+    { 
+      if ( s_ptr [ 1 ] == '$' )
+      {
+        // replace "$$" with "$"
+        s_ptr1 = ++s_ptr; // both pointers on second "$"
+
+        while ( *s_ptr1 != 0)
+        {
+          s_ptr1 [ 0 ] = s_ptr1 [ 1 ];
+          s_ptr1++;
+        }
+      }
+      else
+      if ( 0 == strncmp( s_ptr, "$(APOM)", strlen("$(APOM)" ) ) )
+      {
+         // replace "$(APOM)" by sAPOM
+        char temp_buffer[1024];
+        * s_ptr = 0;
+        s_ptr += strlen ( "$(APOM)" );
+        strcpy ( temp_buffer, s_ptr );
+        strcat ( current_path, sAPOM);
+        s_ptr = & current_path [ strlen(current_path) ] ; // onto the 0
+        strcat ( current_path, temp_buffer );
+      }
+      else
+      if ( 0 == strncmp( s_ptr, "$(...)", strlen("$(...)" ) ) )
+      {  
+        //strcpy(temp_texture_path_for_recursion, current_path);
+
+        char * nextPath=s_ptr;
+        nextPath += strlen("$(...)" );
+
+        while (*nextPath != 0 )
+        {
+          if ( *nextPath == ';' )
+          {
+            if ( nextPath[1] == ';' )
+              nextPath++; // so its "add 2 " togehter with the ++ further down
+            else
+            {
+              *nextPath = 0;
+              break; // breaks the while
+            }
+          }
+          nextPath++;
+        }
+
+        // This segment of the path ends with a 0 now
+        // *****
+
+        char tPath [ 1024 ];
+        strcpy ( tPath, current_path ) ;
+        tPath [ (long) (s_ptr - current_path) ] = 0;
+        
+        // So, lets recurse into the sub-dirs:
+        // Here I just assume that the "$(...)" is the last thing in
+        // this segment
+
+        if ( recursiveFindFileInSubDirs ( filenameOutput,
+                                          tPath, tfnameInput ) )
+          return ; // success
+
+        // *****
+        // we handled the path-segment current_path containing the $(...) and 
+        // didnt find the file, so go on to the nect segment
+
+        current_path = nextPath; // points to a 0 if this was the last segment
+        s_ptr = current_path;
+      }  
+      else
+        s_ptr++;
+    }
+    else // neither ';' nor '$'
+      s_ptr++;
+  }
+
+  ulMakePath ( filenameOutput, current_path, tfnameInput ) ; // pfusch? kludge?
+}
+
+///////////////////// string handling ///////////////////////////////
+
+/*
+  Strdup is *evil* - use this instead...
+*/
+
+char *ulStrDup ( const char *s )
+{
+  int s_sz = strlen ( s ) + 1 ;
+  char *ret = new char [ s_sz ] ;
+
+  memcpy ( ret, s, s_sz ) ;
+  return ret ;
+}
+
+
+
+// string comparisons that are *not* case sensitive:
+
+/*
+
+ 
+  I'm sick of half the machines on the planet supporting
+  strncasecmp and the other half strnicmp - so here is my own
+  offering.
+
+  **** ATTENTION ****
+  WK: If you used strnicmp, make sure you realise the completely 
+  changed meaning of the return value - 0 means not equal!
+*/
+
+int ulStrNEqual ( const char *s1, const char *s2, int len )
+{
+  int l1 = (s1==NULL) ? 0 : strlen ( s1 ) ;
+  int l2 = (s2==NULL) ? 0 : strlen ( s2 ) ;
+
+  if ( l1 > len ) l1 = len ;
+
+  if ( l2 < l1 || l1 < len )
+    return FALSE ;
+
+  for ( int i = 0 ; i < l1 ; i++ )
+  {
+    char c1 = s1[i] ;
+    char c2 = s2[i] ;
+
+    if ( c1 == c2 )
+     continue ;
+
+    if ( c1 >= 'a' && c1 <= 'z' )
+      c1 = c1 - ('a'-'A') ;
+
+    if ( c2 >= 'a' && c2 <= 'z' )
+      c2 = c2 - ('a'-'A') ;
+
+    if ( c1 != c2 )
+     return FALSE ;
+  }
+
+  return TRUE ;
+}
+
+
+/*
+  I'm sick of half the machines on the planet supporting
+  strcasecmp and the other half stricmp - so here is my own
+  offering.
+
+  **** ATTENTION ****
+  WK: If you used stricmp, make sure you realise the completely 
+  changed meaning of the return value - 0 means not equal!
+*/
+
+int ulStrEqual ( const char *s1, const char *s2 )
+{
+  int l1 = (s1==NULL) ? 0 : strlen ( s1 ) ;
+  int l2 = (s2==NULL) ? 0 : strlen ( s2 ) ;
+
+  if ( l1 != l2 ) return FALSE ;
+
+  for ( int i = 0 ; i < l1 ; i++ )
+  {
+    char c1 = s1[i] ;
+    char c2 = s2[i] ;
+
+    if ( c1 == c2 )
+     continue ;
+
+    if ( c1 >= 'a' && c1 <= 'z' )
+      c1 -= ('a'-'A') ;
+
+    if ( c2 >= 'a' && c2 <= 'z' )
+      c2 -= ('a'-'A') ;
+
+    if ( c1 != c2 )
+      return FALSE ;
+  }
+
+  return TRUE ;
+}
+
+
+int ulIsAbsolutePathName ( const char *pathname )
+{
+  /*
+    Is this an absolute pathname or a relative one?
+  */
+ 
+  if ( (pathname == NULL) || (pathname [0] == 0) )
+    return FALSE;
+
+#ifdef UL_MSVC
+ 
+  /*
+    Under WinDOS, it's an absolute path if it starts
+    with a slash *or* if it starts with a drive letter,
+    a colon and a slash.
+  */
+
+  return ( pathname[0] == SLASH[0] || pathname[0] == '/' ) ||
+         (
+           (
+             ( pathname[0] >= 'a' && pathname[0] <= 'z' ) ||
+             ( pathname[0] >= 'A' && pathname[0] <= 'Z' )
+           ) &&
+           pathname[1] == ':' &&
+           ( pathname[2] == SLASH[0] || pathname[2] == '/' )
+         ) ;
+#elif defined(UL_MACINTOSH)
+  return (pathname [0] != ':' && strchr( pathname, ':') != NULL );
+#else
+  return pathname [0] == SLASH[0] ;
+#endif
+}
+
+
+char *ulGetCWD ( char *result, int maxlength )
+{
+  /*
+    Return the current working directory into 'result' - which
+    has enough space for 'maxlength-1' characters and a '\0'.
+  */
+
+#ifdef UL_MSVC
+  return _getcwd ( result, maxlength ) ;
+#else
+  return getcwd ( result, maxlength ) ;
+#endif
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ulClock.cpp b/ossimPlanet/src/ossimPlanet/ulClock.cpp
new file mode 100644
index 0000000..972bc8d
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ulClock.cpp
@@ -0,0 +1,117 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ulClock.cxx 1735 2002-12-01 18:21:48Z sjbaker $
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ossimPlanet/ul.h>
+
+#ifdef UL_CYGWIN
+  typedef long long _int64;
+  #define LARGEINTEGER _int64
+#endif
+
+#ifndef UL_WIN32
+#  include <sys/time.h>
+#endif
+
+#include <time.h>
+
+#ifdef UL_WIN32
+
+double ulClock::res ;
+int ulClock::perf_timer = -1;
+
+void ulClock::initPerformanceTimer ()
+{
+  if ( perf_timer == -1 )
+  {
+    /* Use Performance Timer if it's available, mmtimer if not.  */
+
+    __int64 frequency ;
+
+    perf_timer = QueryPerformanceFrequency ( (LARGE_INTEGER *) & frequency ) ;
+
+    if ( perf_timer )
+    {
+      res = 1.0 / (double) frequency ;
+      perf_timer = 1 ;
+    }
+  }
+}
+#endif
+
+double ulClock::getRawTime () const
+{
+#ifdef UL_WIN32
+
+  /* Use Performance Timer if it's available, mmtimer if not.  */
+
+  if ( perf_timer )
+  {
+    __int64 t ;
+ 
+    QueryPerformanceCounter ( (LARGE_INTEGER *) &t ) ;
+ 
+    return res * (double) t ;
+  }
+ 
+  return (double) timeGetTime() * 0.001 ;
+
+#else
+  timeval tv ;
+
+  gettimeofday ( & tv, NULL ) ;
+
+  return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0 ;
+#endif
+}
+
+
+void ulClock::update ()
+{
+  now = getRawTime() - start ;
+
+  delta = now - last_time ;
+
+  /*
+    KLUDGE: If the frame rate drops below ~5Hz, then
+            control will be very difficult.  It's
+            actually easier to give up and slow
+            down the action. max_delta defaults to
+            200ms for that reason.
+
+    KLUDGE: If update is called very rapidly, then
+            delta can be zero which causes some
+            programs to div0. So we'll clamp to
+            a millionth of a second.
+  */
+
+  if ( delta >  max_delta ) delta = max_delta ;
+  if ( delta <= 0.0 ) delta = 0.0000001 ;
+
+  last_time = now ;
+}
+
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ulError.cpp b/ossimPlanet/src/ossimPlanet/ulError.cpp
new file mode 100644
index 0000000..2eb50a7
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ulError.cpp
@@ -0,0 +1,90 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ulError.cxx 1967 2004-10-02 12:20:43Z wolfram_kuss $
+*/
+
+
+#include <ossimPlanet/ul.h>
+
+static char            _ulErrorBuffer [ 1024 ] = { '\0' } ;
+static ulErrorCallback _ulErrorCB = 0 ;
+
+static const char* _ulSeverityText [ UL_MAX_SEVERITY ] =
+{
+  "DEBUG",
+  "WARNING",
+  "FATAL",
+};
+ 
+
+void ulSetError ( enum ulSeverity severity, const char *fmt, ... )
+{
+  va_list argp;
+  va_start ( argp, fmt ) ;
+  vsprintf ( _ulErrorBuffer, fmt, argp ) ;
+  va_end ( argp ) ;
+ 
+  if ( _ulErrorCB )
+  {
+    (*_ulErrorCB)( severity, _ulErrorBuffer ) ;
+  }
+  else
+  {
+    fprintf ( stderr, "%s: %s\n",
+       _ulSeverityText[ severity ], _ulErrorBuffer ) ;
+    if ( severity == UL_FATAL )
+    {
+#ifdef WIN32
+      // A Windows user that does not start the program from the command line
+      // will not see output to stderr
+      ::MessageBox(0, _ulErrorBuffer, "fatal error!:", 0);
+#endif
+      exit (1) ;
+    }
+  }
+}
+ 
+
+char* ulGetError ( void )
+{
+  return _ulErrorBuffer ;
+}
+ 
+
+void ulClearError ( void )
+{
+  _ulErrorBuffer [0] = 0 ;
+}
+ 
+
+ulErrorCallback ulGetErrorCallback ( void )
+{
+  return _ulErrorCB ;
+}
+ 
+
+void ulSetErrorCallback ( ulErrorCallback cb )
+{
+  _ulErrorCB = cb ;
+}
+
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ulLinkedList.cpp b/ossimPlanet/src/ossimPlanet/ulLinkedList.cpp
new file mode 100644
index 0000000..0664d10
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ulLinkedList.cpp
@@ -0,0 +1,272 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+     For further information visit http://plib.sourceforge.net
+
+     $Id: ulLinkedList.cxx 1568 2002-09-02 06:05:49Z sjbaker $
+*/
+
+
+#include <ossimPlanet/ulLocal.h>
+
+void ulLinkedList::unlinkNode ( ulListNode *prev, ulListNode *node )
+{
+  /* Is this the first node ? */
+  if ( prev == NULL )
+    head = node -> getNext () ;
+  else
+    prev -> setNext ( node -> getNext () ) ;
+
+  /* Is this the last node ? */
+  if ( node -> getNext () == NULL )
+    tail = prev ;
+}
+
+
+int ulLinkedList::getNodePosition ( void *data ) const
+{
+  ulListNode *curr = head ;
+  int pos = 0 ;
+
+  while ( curr != NULL )
+  {
+    if ( curr -> getData () == data )
+      return pos ;
+
+    pos++ ;
+    curr = curr -> getNext () ;
+  }
+
+  return -1 ;
+}
+
+
+void ulLinkedList::appendNode ( void *data )
+{
+  ulListNode *new_node = new ulListNode ( data, NULL ) ;
+
+  if ( head == NULL )
+    head = new_node ;
+  else
+    tail -> setNext ( new_node ) ;
+
+  tail = new_node ;
+
+  if ( ++nnodes > 1 )
+    sorted = false ;
+}
+
+void ulLinkedList::insertNode ( void *data, int pos )
+{
+  if ( pos == 0 )
+  {
+    head = new ulListNode ( data, head ) ;
+
+    if ( tail == NULL )
+      tail = head ;
+  }
+  else
+  {
+    if ( ! isValidPosition ( pos ) )
+      return ;
+    else
+    {
+      ulListNode *prev = head ;
+
+      while ( --pos > 0 )
+        prev = prev -> getNext () ;
+
+      prev -> setNext ( new ulListNode ( data, prev -> getNext () ) ) ;
+    }
+  }
+
+  if ( ++nnodes > 1 )
+    sorted = false ;
+}
+
+
+int ulLinkedList::insertSorted ( void *data, ulCompareFunc comparefn )
+{
+  if ( comparefn != NULL )
+  {
+    if ( sorted )
+    {
+      int pos = 0 ;
+
+      if ( head == NULL )
+        head = tail = new ulListNode ( data, NULL ) ;
+      else
+      {
+        ulListNode *curr = head, *prev = NULL ;
+
+        while ( (*comparefn)( curr -> getData (), data ) < 0 )
+        {
+          prev = curr ;
+          curr = curr -> getNext () ;
+
+          pos++ ;
+
+          if ( curr == NULL )
+          {
+            tail = new ulListNode ( data, curr ) ;
+            prev -> setNext ( tail ) ;
+
+            nnodes++ ;
+            return pos ;
+          }
+        }
+
+        if ( prev == NULL )
+          head = new ulListNode ( data, head ) ;
+        else
+          prev -> setNext ( new ulListNode ( data, curr ) ) ;
+      }
+
+      nnodes++ ;
+      return pos ;
+    }
+    else
+      ulSetError ( UL_WARNING,
+                   "ulLinkedList::insertSorted: This is not a sorted list !" ) ;
+  }
+
+  return -1 ;
+}
+
+
+void ulLinkedList::removeNode ( void *data )
+{
+  ulListNode *curr = head, *prev = NULL ;
+
+  while ( curr != NULL )
+  {
+    if ( curr -> getData () == data )
+    {
+      unlinkNode ( prev, curr ) ;
+
+      delete curr ;
+
+      if ( --nnodes <= 0 )
+        sorted = true ;
+
+      return ;
+    }
+
+    prev = curr ;
+    curr = curr -> getNext () ;
+  }
+
+  ulSetError ( UL_WARNING, "ulLinkedList::removeNode: No such node" ) ;
+}
+
+void * ulLinkedList::removeNode ( int pos )
+{
+  if ( ! isValidPosition ( pos ) )
+    return NULL ;
+
+  ulListNode *curr = head, *prev = NULL ;
+
+  while ( pos-- > 0 )
+  {
+    prev = curr ;
+    curr = curr -> getNext () ;
+  }
+
+  unlinkNode ( prev, curr ) ;
+
+  void *datap = curr -> getData () ;
+
+  delete curr ;
+
+  if ( --nnodes <= 1 )
+    sorted = true ;
+
+  return datap ;
+}
+
+
+void * ulLinkedList::getNodeData ( int pos ) const
+{
+  if ( ! isValidPosition ( pos ) )
+    return NULL ;
+
+  ulListNode *node ;
+
+  if ( pos == nnodes - 1 )
+    node = tail ;
+  else
+  {
+    node = head ;
+
+    while ( pos-- > 0 )
+      node = node -> getNext () ;
+  }
+
+  return node -> getData () ;
+}
+
+
+void * ulLinkedList::forEach ( ulIterateFunc fn, void *user_data ) const
+{
+  if ( fn != NULL )
+  {
+    ulListNode *curr ;
+
+    for ( curr = head ; curr != NULL ; curr = curr -> getNext () )
+    {
+      if ( (*fn)( curr -> getData (), user_data ) == false )
+        return curr -> getData () ;
+    }
+  }
+
+  return NULL ;
+}
+
+
+void ulLinkedList::empty ( ulIterateFunc destroyfn, void *user_data )
+{
+  ulListNode *curr = head ;
+
+  if ( destroyfn != NULL )
+  {
+    while ( curr != NULL )
+    {
+      ulListNode *next = curr -> getNext () ;
+
+      (*destroyfn) ( curr -> getData (), user_data ) ;
+
+      delete curr ;
+      curr = next ;
+    }
+  }
+  else
+  {
+    while ( curr != NULL )
+    {
+      ulListNode *next = curr -> getNext () ;
+
+      delete curr ;
+      curr = next ;
+    }
+  }
+
+  head = tail = NULL ;
+  nnodes = 0 ;
+  sorted = true ;
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/ulList.cpp b/ossimPlanet/src/ossimPlanet/ulList.cpp
new file mode 100644
index 0000000..418db54
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ulList.cpp
@@ -0,0 +1,109 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net
+ 
+     $Id: ulList.cxx 1732 2002-11-30 00:41:50Z sjbaker $
+*/
+ 
+ 
+#include <ossimPlanet/ul.h>
+ 
+                                                                                
+ulList::ulList ( int init )
+{
+  total = 0 ;
+  next = 0 ;
+  entity_list = new void * [ limit = (init <= 0) ? 1 : init ] ;
+}                                                                               
+
+ 
+ulList::~ulList (void)
+{
+  removeAllEntities () ;
+  delete [] entity_list ;
+}
+
+
+void ulList::addEntity ( void *entity )
+{
+  sizeChk () ;
+  entity_list [ total++ ] = entity ;
+}
+
+
+void ulList::addEntityBefore ( int i, void *entity )
+{
+  sizeChk () ;
+  memmove ( &entity_list[i+1], &entity_list[i], sizeof(void *) * (total-i) ) ;
+  entity_list [ i ] = entity ;
+  total++ ;
+}
+
+
+void ulList::sizeChk (void)
+{
+  /* Room for one more Entity? */
+ 
+  if ( total >= limit )
+  {
+    limit += limit ;
+    void **nlist = new void * [ limit ] ;
+    memmove ( nlist, entity_list, sizeof(void *) * total ) ;
+    delete [] entity_list ;
+    entity_list = nlist ;
+  }
+}
+ 
+ 
+int ulList::searchForEntity ( void *entity ) const
+{
+  for ( unsigned int i = 0 ; i < total ; i++ )
+    if ( entity_list [ i ] == entity )
+      return (int) i ;
+ 
+  return -1 ;
+}
+                                                                                 
+void ulList::removeAllEntities ()
+{
+  while ( total > 0 )
+    removeEntity ( (unsigned int) 0 ) ;
+}
+ 
+void ulList::removeEntity ( unsigned int n )
+{
+  memmove ( &(entity_list[n]), &(entity_list[n+1]),
+                               sizeof(void *) * (total-n-1) ) ;
+  total-- ;
+ 
+  if ( next >= n )
+    next-- ;
+}
+                                                                                
+
+ 
+void ulList::replaceEntity ( unsigned int n, void *new_entity )
+{
+  if ( n >= 0 )
+    entity_list [ n ] = new_entity;
+  else
+    addEntity ( new_entity ) ;
+}
+
+
diff --git a/ossimPlanet/src/ossimPlanet/ulRTTI.cpp b/ossimPlanet/src/ossimPlanet/ulRTTI.cpp
new file mode 100644
index 0000000..11c9ac0
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/ulRTTI.cpp
@@ -0,0 +1,109 @@
+/*
+     PLIB - A Suite of Portable Game Libraries
+     Copyright (C) 1998,2002  Steve Baker
+ 
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Library General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later version.
+ 
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Library General Public License for more details.
+ 
+     You should have received a copy of the GNU Library General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ 
+     For further information visit http://plib.sourceforge.net                  */
+
+
+#include <ossimPlanet/ulRTTI.h>
+
+/* Originally written by: Alexandru C. Telea <alext at win.tue.nl> */
+
+
+static const ulRTTITypeinfo *RTTI_base_null_type [] = { 0 } ;
+
+const ulRTTITypeinfo* ulRTTIdyntypeid::a[] = { 0 } ;
+
+const ulRTTITypeinfo ulRTTITypeinfo::null_type ( "NULL", RTTI_base_null_type,
+                                                 0, 0 ) ;
+
+
+ulRTTITypeinfo::ulRTTITypeinfo ( const char *name, const ulRTTITypeinfo *bb[],
+                                 void* (*f1)(int,void*),void* (*f2)() )
+{
+  /* Create default ulRTTITypeinfo */
+  n = ulStrDup ( name ) ;
+
+  b       = bb ; /* ns = 0 ; subtypes = 0 ; */
+
+  cast    = f1 ; /* Attach casting func  */
+  new_obj = f2 ; /* Attach creation func */
+
+  for ( int i = 0 ; b[i] ; i++ )
+  /* Add this as subtype to all its basetypes */
+    /* REMARK: Harmless const castaway */
+    ((ulRTTITypeinfo**)b)[i]->add_subtype ( this ) ;
+}
+
+ulRTTITypeinfo::~ulRTTITypeinfo ()
+{
+  delete [] n ;
+  for ( int i = 0 ; b[i] ; i++ )
+  /* Del this subtype from all its basetypes */
+    /* REMARK: Harmless const castaway */
+    ((ulRTTITypeinfo**)b)[i]->del_subtype ( this ) ;
+}
+
+void ulRTTITypeinfo::add_subtype ( const ulRTTITypeinfo *t )
+/*
+  Adds t as last ulRTTITypeinfo in the 'subtypes' list. For this, the list is
+  realloc'd with one extra entry.
+*/
+{
+  const ulRTTITypeinfo **ptr = new const ulRTTITypeinfo*[ns+1] ;
+  int i ; for ( i = 0 ; i < ns ; i++ ) ptr[i] = subtypes[i] ;
+  ptr[i] = t ;
+  ns++ ;
+  delete[] subtypes ;
+  subtypes = ptr ;
+}
+
+void ulRTTITypeinfo::del_subtype ( const ulRTTITypeinfo* t )
+/* Searches for t in the subtypes list of this and removes it, if found. */
+{
+  int i ; for ( i = 0 ; i < ns && subtypes[i] != t ; i++ ) ;
+  if ( i < ns )
+    for(; i < ns-1 ; i++ ) subtypes[i] = subtypes[i+1] ;
+}
+
+void * ulRTTITypeinfo::create ( const ulRTTITypeinfo* bt, const char *c ) const
+/*
+  Tries to create an obj of type-name given by char*. Searches for this type
+  in the type-DAG rooted by this, creates it and returns it as cast to 'bt',
+  where bt is either this or a direct base of this.
+*/
+{
+  void *p = NULL ; int i ;
+
+  if ( !strcmp ( c, n ) ) /* Want to create an obj of this type ? */
+    /* Yes, do it if this type is instantiable. */
+    p = (new_obj) ? new_obj () : 0 ;
+  else  /* No, try with subclasses... */
+    for ( i = 0 ; i < ns &&
+          !( ( p = subtypes[i]->create ( this, c ) ) ) ; i++ ) ;
+  /* Succeeded creating on ith subclass branch ? */
+  if ( !p ) return 0 ; /* Couldn't create it in any way, abort. */
+  if ( bt == this )
+    i = -1 ; /* Must cast to this's own type (i==-1) */
+  else
+    /* Search to which base of this we should cast */
+    for ( i = 0 ; b[i] && b[i] != bt ; i++ ) ;
+
+   /* Found: cast to ith base of this */
+   return cast(i,p) ; /* Cast to ith base of to this, return as void* */
+}
+
diff --git a/ossimPlanet/src/ossimPlanet/unzip.c b/ossimPlanet/src/ossimPlanet/unzip.c
new file mode 100644
index 0000000..5f1e7b4
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/unzip.c
@@ -0,0 +1,1630 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   Read unzip.h for more info
+*/
+
+/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+compatibility with older software. The following is from the original crypt.c. Code
+woven in by Terry Thorsen 1/2003.
+*/
+/*
+  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  (the contents of which are also included in zip.h) for terms of use.
+  If, for some reason, all these files are missing, the Info-ZIP license
+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
+
+  The encryption/decryption parts of this source code (as opposed to the
+  non-echoing password parts) were originally written in Europe.  The
+  whole source package can be freely distributed, including from the USA.
+  (Prior to January 2000, re-export from the US was a violation of US law.)
+ */
+
+/*
+  This encryption code is a direct transcription of the algorithm from
+  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+  file (appnote.txt) is distributed with the PKZIP program (even in the
+  version without encryption capabilities).
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include <ossimPlanet/unzip.h>
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+#    define CASESENSITIVITYDEFAULT_NO
+#  endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+
+
+const char unz_copyright[] =
+   " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info_internal_s
+{
+    uLong offset_curfile;/* relative offset of local header 4 bytes */
+} unz_file_info_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+    char  *read_buffer;         /* internal buffer for compressed data */
+    z_stream stream;            /* zLib stream structure for inflate */
+
+    uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
+    uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+    uLong offset_local_extrafield;/* offset of the local extra field */
+    uInt  size_local_extrafield;/* size of the local extra field */
+    uLong pos_local_extrafield;   /* position in the local extra field in read*/
+
+    uLong crc32;                /* crc32 of all data uncompressed */
+    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+    uLong rest_read_compressed; /* number of byte to be decompressed */
+    uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+    zlib_filefunc_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    uLong compression_method;   /* compression method (0==store) */
+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    int   raw;
+} file_in_zip_read_info_s;
+
+
+/* unz_s contain internal information about the zipfile
+*/
+typedef struct
+{
+    zlib_filefunc_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    unz_global_info gi;       /* public global information */
+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    uLong num_file;             /* number of the current file in the zipfile*/
+    uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
+    uLong current_file_ok;      /* flag about the usability of the current file*/
+    uLong central_pos;          /* position of the beginning of the central dir*/
+
+    uLong size_central_dir;     /* size of the central directory  */
+    uLong offset_central_dir;   /* offset of start of central directory with
+                                   respect to the starting disk number */
+
+    unz_file_info cur_file_info; /* public info about the current file in zip*/
+    unz_file_info_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
+                                        file if we are decompressing it */
+    int encrypted;
+#    ifndef NOUNCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const unsigned long* pcrc_32_tab;
+#    endif
+} unz_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unzlocal_getByte OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    int *pi));
+
+local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    int *pi;
+{
+    unsigned char c;
+    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ZERROR(*pzlib_filefunc_def,filestream))
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unzlocal_getShort OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unzlocal_getLong OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (fileName1,fileName2)
+    const char* fileName1;
+    const char* fileName2;
+{
+    for (;;)
+    {
+        char c1=*(fileName1++);
+        char c2=*(fileName2++);
+        if ((c1>='a') && (c1<='z'))
+            c1 -= 0x20;
+        if ((c2>='a') && (c2<='z'))
+            c2 -= 0x20;
+        if (c1=='\0')
+            return ((c2=='\0') ? 0 : -1);
+        if (c2=='\0')
+            return 1;
+        if (c1<c2)
+            return -1;
+        if (c1>c2)
+            return 1;
+    }
+}
+
+
+#ifdef  CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+        (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
+    const char* fileName1;
+    const char* fileName2;
+    int iCaseSensitivity;
+{
+    if (iCaseSensitivity==0)
+        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+    if (iCaseSensitivity==1)
+        return strcmp(fileName1,fileName2);
+
+    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local uLong unzlocal_SearchCentralDir OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream));
+
+local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+{
+    unsigned char* buf;
+    uLong uSizeFile;
+    uLong uBackRead;
+    uLong uMaxBack=0xffff; /* maximum size of global comment */
+    uLong uPosFound=0;
+
+    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize,uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
+        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    return uPosFound;
+}
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+     "zlib/zlib114.zip".
+     If the zipfile cannot be opened (file doesn't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
+    const char *path;
+    zlib_filefunc_def* pzlib_filefunc_def;
+{
+    unz_s us;
+    unz_s *s;
+    uLong central_pos,uL;
+
+    uLong number_disk;          /* number of the current dist, used for
+                                   spaning ZIP, unsupported, always 0*/
+    uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                   for spaning ZIP, unsupported, always 0*/
+    uLong number_entry_CD;      /* total number of entries in
+                                   the central dir
+                                   (same than number_entry on nospan) */
+
+    int err=UNZ_OK;
+
+    if (unz_copyright[0]!=' ')
+        return NULL;
+
+    if (pzlib_filefunc_def==NULL)
+        fill_fopen_filefunc(&us.z_filefunc);
+    else
+        us.z_filefunc = *pzlib_filefunc_def;
+
+    us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
+                                                 path,
+                                                 ZLIB_FILEFUNC_MODE_READ |
+                                                 ZLIB_FILEFUNC_MODE_EXISTING);
+    if (us.filestream==NULL)
+        return NULL;
+
+    central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
+    if (central_pos==0)
+        err=UNZ_ERRNO;
+
+    if (ZSEEK(us.z_filefunc, us.filestream,
+                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+    /* the signature, already checked */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* number of this disk */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* total number of entries in the central dir on this disk */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* total number of entries in the central dir */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if ((number_entry_CD!=us.gi.number_entry) ||
+        (number_disk_with_CD!=0) ||
+        (number_disk!=0))
+        err=UNZ_BADZIPFILE;
+
+    /* size of the central directory */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* offset of start of central directory with respect to the
+          starting disk number */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* zipfile comment length */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+        (err==UNZ_OK))
+        err=UNZ_BADZIPFILE;
+
+    if (err!=UNZ_OK)
+    {
+        ZCLOSE(us.z_filefunc, us.filestream);
+        return NULL;
+    }
+
+    us.byte_before_the_zipfile = central_pos -
+                            (us.offset_central_dir+us.size_central_dir);
+    us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+    us.encrypted = 0;
+
+
+    s=(unz_s*)ALLOC(sizeof(unz_s));
+    *s=us;
+    unzGoToFirstFile((unzFile)s);
+    return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen (path)
+    const char *path;
+{
+    return unzOpen2(path, NULL);
+}
+
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (file)
+    unzFile file;
+{
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+    ZCLOSE(s->z_filefunc, s->filestream);
+    TRYFREE(s);
+    return UNZ_OK;
+}
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
+    unzFile file;
+    unz_global_info *pglobal_info;
+{
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    *pglobal_info=s->gi;
+    return UNZ_OK;
+}
+
+
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
+    uLong ulDosDate;
+    tm_unz* ptm;
+{
+    uLong uDate;
+    uDate = (uLong)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+  Get Info about the current file in the zipfile, with internal only info
+*/
+local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
+                                                  unz_file_info *pfile_info,
+                                                  unz_file_info_internal
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                  uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                  uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                  uLong commentBufferSize));
+
+local int unzlocal_GetCurrentFileInfoInternal (file,
+                                              pfile_info,
+                                              pfile_info_internal,
+                                              szFileName, fileNameBufferSize,
+                                              extraField, extraFieldBufferSize,
+                                              szComment,  commentBufferSize)
+    unzFile file;
+    unz_file_info *pfile_info;
+    unz_file_info_internal *pfile_info_internal;
+    char *szFileName;
+    uLong fileNameBufferSize;
+    void *extraField;
+    uLong extraFieldBufferSize;
+    char *szComment;
+    uLong commentBufferSize;
+{
+    unz_s* s;
+    unz_file_info file_info;
+    unz_file_info_internal file_info_internal;
+    int err=UNZ_OK;
+    uLong uMagic;
+    long lSeek=0;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (ZSEEK(s->z_filefunc, s->filestream,
+              s->pos_in_central_dir+s->byte_before_the_zipfile,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+
+    /* we check the magic */
+    if (err==UNZ_OK)
+    {
+       if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+       {
+          err=UNZ_ERRNO;
+       }
+       else if (uMagic!=0x02014b50)
+       {
+          err=UNZ_BADZIPFILE;
+       }
+    }
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    lSeek+=file_info.size_filename;
+    if ((err==UNZ_OK) && (szFileName!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_filename<fileNameBufferSize)
+        {
+            *(szFileName+file_info.size_filename)='\0';
+            uSizeRead = file_info.size_filename;
+        }
+        else
+            uSizeRead = fileNameBufferSize;
+
+        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+            if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek -= uSizeRead;
+    }
+
+
+    if ((err==UNZ_OK) && (extraField!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_extra<extraFieldBufferSize)
+            uSizeRead = file_info.size_file_extra;
+        else
+            uSizeRead = extraFieldBufferSize;
+
+        if (lSeek!=0)
+        {
+           if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+           {
+              lSeek=0;
+           }
+           else
+           {
+              err=UNZ_ERRNO;
+           }
+        }
+        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+        {
+            if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
+            {
+               err=UNZ_ERRNO;
+            }
+        }
+        lSeek += file_info.size_file_extra - uSizeRead;
+    }
+    else
+    {
+        lSeek+=file_info.size_file_extra;
+    }
+
+    if ((err==UNZ_OK) && (szComment!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_comment<commentBufferSize)
+        {
+            *(szComment+file_info.size_file_comment)='\0';
+            uSizeRead = file_info.size_file_comment;
+        }
+        else
+            uSizeRead = commentBufferSize;
+
+        if (lSeek!=0)
+        {
+           if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+           {
+              lSeek=0;
+           }
+           else
+           {
+                err=UNZ_ERRNO;
+           }
+        }
+        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+        {
+            if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+            {
+               err=UNZ_ERRNO;
+            }
+        }
+        lSeek+=file_info.size_file_comment - uSizeRead;
+    }
+    else
+        lSeek+=file_info.size_file_comment;
+
+    if ((err==UNZ_OK) && (pfile_info!=NULL))
+        *pfile_info=file_info;
+
+    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+        *pfile_info_internal=file_info_internal;
+
+    return err;
+}
+
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo (file,
+                                          pfile_info,
+                                          szFileName, fileNameBufferSize,
+                                          extraField, extraFieldBufferSize,
+                                          szComment,  commentBufferSize)
+    unzFile file;
+    unz_file_info *pfile_info;
+    char *szFileName;
+    uLong fileNameBufferSize;
+    void *extraField;
+    uLong extraFieldBufferSize;
+    char *szComment;
+    uLong commentBufferSize;
+{
+    return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+                                                szFileName,fileNameBufferSize,
+                                                extraField,extraFieldBufferSize,
+                                                szComment,commentBufferSize);
+}
+
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (file)
+    unzFile file;
+{
+    int err=UNZ_OK;
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    s->pos_in_central_dir=s->offset_central_dir;
+    s->num_file=0;
+    err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                             &s->cur_file_info_internal,
+                                             NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (file)
+    unzFile file;
+{
+    unz_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
+      if (s->num_file+1==s->gi.number_entry)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+    s->num_file++;
+    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzipStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
+    unzFile file;
+    const char *szFileName;
+    int iCaseSensitivity;
+{
+    unz_s* s;
+    int err;
+
+    /* We remember the 'current' position in the file so that we can jump
+     * back there if we fail.
+     */
+    unz_file_info cur_file_infoSaved;
+    unz_file_info_internal cur_file_info_internalSaved;
+    uLong num_fileSaved;
+    uLong pos_in_central_dirSaved;
+
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+
+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+        return UNZ_PARAMERROR;
+
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    /* Save the current state */
+    num_fileSaved = s->num_file;
+    pos_in_central_dirSaved = s->pos_in_central_dir;
+    cur_file_infoSaved = s->cur_file_info;
+    cur_file_info_internalSaved = s->cur_file_info_internal;
+
+    err = unzGoToFirstFile(file);
+
+    while (err == UNZ_OK)
+    {
+        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+        err = unzGetCurrentFileInfo(file,NULL,
+                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                    NULL,0,NULL,0);
+        if (err == UNZ_OK)
+        {
+            if (unzStringFileNameCompare(szCurrentFileName,
+                                            szFileName,iCaseSensitivity)==0)
+                return UNZ_OK;
+            err = unzGoToNextFile(file);
+        }
+    }
+
+    /* We failed, so restore the state of the 'current file' to where we
+     * were.
+     */
+    s->num_file = num_fileSaved ;
+    s->pos_in_central_dir = pos_in_central_dirSaved ;
+    s->cur_file_info = cur_file_infoSaved;
+    s->cur_file_info_internal = cur_file_info_internalSaved;
+    return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   // offset in file
+    uLong num_of_file;            // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos(file, file_pos)
+    unzFile file;
+    unz_file_pos* file_pos;
+{
+    unz_s* s;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
+    file_pos->num_of_file           = s->num_file;
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzGoToFilePos(file, file_pos)
+    unzFile file;
+    unz_file_pos* file_pos;
+{
+    unz_s* s;
+    int err;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+
+    /* jump to the right spot */
+    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+    s->num_file           = file_pos->num_of_file;
+
+    /* set the current file */
+    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    /* return results */
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
+                                                    poffset_local_extrafield,
+                                                    psize_local_extrafield)
+    unz_s* s;
+    uInt* piSizeVar;
+    uLong *poffset_local_extrafield;
+    uInt  *psize_local_extrafield;
+{
+    uLong uMagic,uData,uFlags;
+    uLong size_filename;
+    uLong size_extra_field;
+    int err=UNZ_OK;
+
+    *piSizeVar = 0;
+    *poffset_local_extrafield = 0;
+    *psize_local_extrafield = 0;
+
+    if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+
+    if (err==UNZ_OK)
+    {
+        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+        {
+            err=UNZ_ERRNO;
+        }
+        else if (uMagic!=0x04034b50)
+        {
+           err=UNZ_BADZIPFILE;
+        }
+    }
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+/*
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+        err=UNZ_BADZIPFILE;
+*/
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+        err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+        err=UNZ_BADZIPFILE;
+
+    *piSizeVar += (uInt)size_filename;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+        err=UNZ_ERRNO;
+    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                    SIZEZIPLOCALHEADER + size_filename;
+    *psize_local_extrafield = (uInt)size_extra_field;
+
+    *piSizeVar += (uInt)size_extra_field;
+
+    return err;
+}
+
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
+    unzFile file;
+    int* method;
+    int* level;
+    int raw;
+    const char* password;
+{
+    int err=UNZ_OK;
+    uInt iSizeVar;
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    uLong offset_local_extrafield;  /* offset of the local extra field */
+    uInt  size_local_extrafield;    /* size of the local extra field */
+#    ifndef NOUNCRYPT
+    char source[12];
+#    else
+    if (password != NULL)
+        return UNZ_PARAMERROR;
+#    endif
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
+                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+        return UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
+                                        ALLOC(sizeof(file_in_zip_read_info_s));
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_INTERNALERROR;
+
+    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+    pfile_in_zip_read_info->pos_local_extrafield=0;
+    pfile_in_zip_read_info->raw=raw;
+
+    if (pfile_in_zip_read_info->read_buffer==NULL)
+    {
+        TRYFREE(pfile_in_zip_read_info);
+        return UNZ_INTERNALERROR;
+    }
+
+    pfile_in_zip_read_info->stream_initialised=0;
+
+    if (method!=NULL)
+        *method = (int)s->cur_file_info.compression_method;
+
+    if (level!=NULL)
+    {
+        *level = 6;
+        switch (s->cur_file_info.flag & 0x06)
+        {
+          case 6 : *level = 1; break;
+          case 4 : *level = 2; break;
+          case 2 : *level = 9; break;
+        }
+    }
+
+    if ((s->cur_file_info.compression_method!=0) &&
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+    pfile_in_zip_read_info->crc32=0;
+    pfile_in_zip_read_info->compression_method =
+            s->cur_file_info.compression_method;
+    pfile_in_zip_read_info->filestream=s->filestream;
+    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
+        (!raw))
+    {
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=1;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END.
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+         * size of both compressed and uncompressed data
+         */
+    }
+    pfile_in_zip_read_info->rest_read_compressed =
+            s->cur_file_info.compressed_size ;
+    pfile_in_zip_read_info->rest_read_uncompressed =
+            s->cur_file_info.uncompressed_size ;
+
+
+    pfile_in_zip_read_info->pos_in_zipfile =
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+              iSizeVar;
+
+    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+    s->pfile_in_zip_read = pfile_in_zip_read_info;
+
+#    ifndef NOUNCRYPT
+    if (password != NULL)
+    {
+        int i;
+        s->pcrc_32_tab = get_crc_table();
+        init_keys(password,s->keys,s->pcrc_32_tab);
+        if (ZSEEK(s->z_filefunc, s->filestream,
+                  s->pfile_in_zip_read->pos_in_zipfile +
+                     s->pfile_in_zip_read->byte_before_the_zipfile,
+                  SEEK_SET)!=0)
+            return UNZ_INTERNALERROR;
+        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
+            return UNZ_INTERNALERROR;
+
+        for (i = 0; i<12; i++)
+            zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+        s->pfile_in_zip_read->pos_in_zipfile+=12;
+        s->encrypted=1;
+    }
+#    endif
+
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (file)
+    unzFile file;
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
+    unzFile file;
+    const char* password;
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
+    unzFile file;
+    int* method;
+    int* level;
+    int raw;
+{
+    return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
+    unzFile file;
+    voidp buf;
+    unsigned len;
+{
+    int err=UNZ_OK;
+    uInt iRead = 0;
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->read_buffer == NULL))
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (len==0)
+        return 0;
+
+    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+        (!(pfile_in_zip_read_info->raw)))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+    if ((len>pfile_in_zip_read_info->rest_read_compressed+
+           pfile_in_zip_read_info->stream.avail_in) &&
+         (pfile_in_zip_read_info->raw))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_compressed+
+            pfile_in_zip_read_info->stream.avail_in;
+
+    while (pfile_in_zip_read_info->stream.avail_out>0)
+    {
+        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+        {
+            uInt uReadThis = UNZ_BUFSIZE;
+            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+            if (uReadThis == 0)
+                return UNZ_EOF;
+            if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile,
+                         ZLIB_FILEFUNC_SEEK_SET)!=0)
+                return UNZ_ERRNO;
+            if (ZREAD(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->read_buffer,
+                      uReadThis)!=uReadThis)
+                return UNZ_ERRNO;
+
+
+#            ifndef NOUNCRYPT
+            if(s->encrypted)
+            {
+                uInt i;
+                for(i=0;i<uReadThis;i++)
+                  pfile_in_zip_read_info->read_buffer[i] =
+                      zdecode(s->keys,s->pcrc_32_tab,
+                              pfile_in_zip_read_info->read_buffer[i]);
+            }
+#            endif
+
+
+            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+            pfile_in_zip_read_info->stream.next_in =
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+        }
+
+        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+        {
+            uInt uDoCopy,i ;
+
+            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                return (iRead==0) ? UNZ_EOF : iRead;
+
+            if (pfile_in_zip_read_info->stream.avail_out <
+                            pfile_in_zip_read_info->stream.avail_in)
+                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+            else
+                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+            for (i=0;i<uDoCopy;i++)
+                *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                pfile_in_zip_read_info->stream.next_out,
+                                uDoCopy);
+            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+            pfile_in_zip_read_info->stream.next_out += uDoCopy;
+            pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+            iRead += uDoCopy;
+        }
+        else
+        {
+            uLong uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            uLong uOutThis;
+            int flush=Z_SYNC_FLUSH;
+
+            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+            bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+            /*
+            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                     pfile_in_zip_read_info->stream.avail_out) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                flush = Z_FINISH;
+            */
+            err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+              err = Z_DATA_ERROR;
+
+            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->crc32 =
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+            pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            if (err==Z_STREAM_END)
+                return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=Z_OK)
+                break;
+        }
+    }
+
+    if (err==Z_OK)
+        return iRead;
+    return err;
+}
+
+
+/*
+  Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (file)
+    unzFile file;
+{
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (file)
+    unzFile file;
+{
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+        return 1;
+    else
+        return 0;
+}
+
+
+
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field that can be read
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
+    unzFile file;
+    voidp buf;
+    unsigned len;
+{
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    uInt read_now;
+    uLong size_to_read;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+                pfile_in_zip_read_info->pos_local_extrafield);
+
+    if (buf==NULL)
+        return (int)size_to_read;
+
+    if (len>size_to_read)
+        read_now = (uInt)size_to_read;
+    else
+        read_now = (uInt)len ;
+
+    if (read_now==0)
+        return 0;
+
+    if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              pfile_in_zip_read_info->offset_local_extrafield +
+              pfile_in_zip_read_info->pos_local_extrafield,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (ZREAD(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              buf,read_now)!=read_now)
+        return UNZ_ERRNO;
+
+    return (int)read_now;
+}
+
+/*
+  Close the file in zip opened with unzipOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (file)
+    unzFile file;
+{
+    int err=UNZ_OK;
+
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+        (!pfile_in_zip_read_info->raw))
+    {
+        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+            err=UNZ_CRCERROR;
+    }
+
+
+    TRYFREE(pfile_in_zip_read_info->read_buffer);
+    pfile_in_zip_read_info->read_buffer = NULL;
+    if (pfile_in_zip_read_info->stream_initialised)
+        inflateEnd(&pfile_in_zip_read_info->stream);
+
+    pfile_in_zip_read_info->stream_initialised = 0;
+    TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+    return err;
+}
+
+
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
+    unzFile file;
+    char *szComment;
+    uLong uSizeBuf;
+{
+/*    int err=UNZ_OK;*/
+    unz_s* s;
+    uLong uReadThis ;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+
+    uReadThis = uSizeBuf;
+    if (uReadThis>s->gi.size_comment)
+        uReadThis = s->gi.size_comment;
+
+    if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (uReadThis>0)
+    {
+      *szComment='\0';
+      if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+        return UNZ_ERRNO;
+    }
+
+    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+        *(szComment+s->gi.size_comment)='\0';
+    return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern uLong ZEXPORT unzGetOffset (file)
+    unzFile file;
+{
+    unz_s* s;
+
+    if (file==NULL)
+          return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+      return 0;
+    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+      if (s->num_file==s->gi.number_entry)
+         return 0;
+    return s->pos_in_central_dir;
+}
+
+extern int ZEXPORT unzSetOffset (file, pos)
+        unzFile file;
+        uLong pos;
+{
+    unz_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+
+    s->pos_in_central_dir = pos;
+    s->num_file = s->gi.number_entry;      /* hack */
+    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                              &s->cur_file_info_internal,
+                                              NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
diff --git a/ossimPlanet/src/ossimPlanet/zip.c b/ossimPlanet/src/ossimPlanet/zip.c
new file mode 100644
index 0000000..7eee2e8
--- /dev/null
+++ b/ossimPlanet/src/ossimPlanet/zip.c
@@ -0,0 +1,1219 @@
+/* zip.c -- IO on .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   27 Dec 2004 Rolf Kalbermatter
+   Modification to zipOpen2 to support globalComment retrieval.
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   Read zip.h for more info
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include <ossimPlanet/zip.h>
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY   (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =
+   " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC    (0x04034b50)
+#define CENTRALHEADERMAGIC  (0x02014b50)
+#define ENDHEADERMAGIC      (0x06054b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET  (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+  struct linkedlist_datablock_internal_s* next_datablock;
+  uLong  avail_in_this_block;
+  uLong  filled_in_this_block;
+  uLong  unused; /* for future use and alignement */
+  unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+    linkedlist_datablock_internal* first_block;
+    linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+    z_stream stream;            /* zLib stream structure for inflate */
+    int  stream_initialised;    /* 1 is stream is initialised */
+    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
+
+    uLong pos_local_header;     /* offset of the local header of the file
+                                     currenty writing */
+    char* central_header;       /* central header data for the current file */
+    uLong size_centralheader;   /* size of the central header for cur file */
+    uLong flag;                 /* flag of the file currently writing */
+
+    int  method;                /* compression method of file currenty wr.*/
+    int  raw;                   /* 1 for directly writing raw data */
+    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+    uLong dosDate;
+    uLong crc32;
+    int  encrypt;
+#ifndef NOCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const unsigned long* pcrc_32_tab;
+    int crypt_header_size;
+#endif
+} curfile_info;
+
+typedef struct
+{
+    zlib_filefunc_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    linkedlist_data central_dir;/* datablock with central dir in construction*/
+    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
+    curfile_info ci;            /* info on the file curretly writing */
+
+    uLong begin_pos;            /* position of the beginning of the zipfile */
+    uLong add_position_when_writting_offset;
+    uLong number_entry;
+#ifndef NO_ADDFILEINEXISTINGZIP
+    char *globalcomment;
+#endif
+} zip_internal;
+
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+    linkedlist_datablock_internal* ldi;
+    ldi = (linkedlist_datablock_internal*)
+                 ALLOC(sizeof(linkedlist_datablock_internal));
+    if (ldi!=NULL)
+    {
+        ldi->next_datablock = NULL ;
+        ldi->filled_in_this_block = 0 ;
+        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+    }
+    return ldi;
+}
+
+local void free_datablock(ldi)
+    linkedlist_datablock_internal* ldi;
+{
+    while (ldi!=NULL)
+    {
+        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+        TRYFREE(ldi);
+        ldi = ldinext;
+    }
+}
+
+local void init_linkedlist(ll)
+    linkedlist_data* ll;
+{
+    ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(ll)
+    linkedlist_data* ll;
+{
+    free_datablock(ll->first_block);
+    ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(ll,buf,len)
+    linkedlist_data* ll;
+    const void* buf;
+    uLong len;
+{
+    linkedlist_datablock_internal* ldi;
+    const unsigned char* from_copy;
+
+    if (ll==NULL)
+        return ZIP_INTERNALERROR;
+
+    if (ll->last_block == NULL)
+    {
+        ll->first_block = ll->last_block = allocate_new_datablock();
+        if (ll->first_block == NULL)
+            return ZIP_INTERNALERROR;
+    }
+
+    ldi = ll->last_block;
+    from_copy = (unsigned char*)buf;
+
+    while (len>0)
+    {
+        uInt copy_this;
+        uInt i;
+        unsigned char* to_copy;
+
+        if (ldi->avail_in_this_block==0)
+        {
+            ldi->next_datablock = allocate_new_datablock();
+            if (ldi->next_datablock == NULL)
+                return ZIP_INTERNALERROR;
+            ldi = ldi->next_datablock ;
+            ll->last_block = ldi;
+        }
+
+        if (ldi->avail_in_this_block < len)
+            copy_this = (uInt)ldi->avail_in_this_block;
+        else
+            copy_this = (uInt)len;
+
+        to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+        for (i=0;i<copy_this;i++)
+            *(to_copy+i)=*(from_copy+i);
+
+        ldi->filled_in_this_block += copy_this;
+        ldi->avail_in_this_block -= copy_this;
+        from_copy += copy_this ;
+        len -= copy_this;
+    }
+    return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+   Inputs a long in LSB order to the given file
+   nbByte == 1, 2 or 4 (byte, short or long)
+*/
+
+local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
+                                voidpf filestream, uLong x, int nbByte));
+local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong x;
+    int nbByte;
+{
+    unsigned char buf[4];
+    int n;
+    for (n = 0; n < nbByte; n++)
+    {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+    if (x != 0)
+      {     /* data overflow - hack for ZIP64 (X Roche) */
+      for (n = 0; n < nbByte; n++)
+        {
+          buf[n] = 0xff;
+        }
+      }
+
+    if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+        return ZIP_ERRNO;
+    else
+        return ZIP_OK;
+}
+
+local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
+local void ziplocal_putValue_inmemory (dest, x, nbByte)
+    void* dest;
+    uLong x;
+    int nbByte;
+{
+    unsigned char* buf=(unsigned char*)dest;
+    int n;
+    for (n = 0; n < nbByte; n++) {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+
+    if (x != 0)
+    {     /* data overflow - hack for ZIP64 */
+       for (n = 0; n < nbByte; n++)
+       {
+          buf[n] = 0xff;
+       }
+    }
+}
+
+/****************************************************************************/
+
+
+local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
+    const tm_zip* ptm;
+    uLong dosDate;
+{
+    uLong year = (uLong)ptm->tm_year;
+    if (year>1980)
+        year-=1980;
+    else if (year>80)
+        year-=80;
+    return
+      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int ziplocal_getByte OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    int *pi));
+
+local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    int *pi;
+{
+    unsigned char c;
+    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return ZIP_OK;
+    }
+    else
+    {
+        if (ZERROR(*pzlib_filefunc_def,filestream))
+            return ZIP_ERRNO;
+        else
+            return ZIP_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int ziplocal_getShort OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int ziplocal_getLong OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==ZIP_OK)
+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local uLong ziplocal_SearchCentralDir OF((
+    const zlib_filefunc_def* pzlib_filefunc_def,
+    voidpf filestream));
+
+local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+{
+    unsigned char* buf;
+    uLong uSizeFile;
+    uLong uBackRead;
+    uLong uMaxBack=0xffff; /* maximum size of global comment */
+    uLong uPosFound=0;
+
+    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize,uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
+        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    return uPosFound;
+}
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
+    const char *pathname;
+    int append;
+    zipcharpc* globalcomment;
+    zlib_filefunc_def* pzlib_filefunc_def;
+{
+    zip_internal ziinit;
+    zip_internal* zi;
+    int err=ZIP_OK;
+
+
+    if (pzlib_filefunc_def==NULL)
+        fill_fopen_filefunc(&ziinit.z_filefunc);
+    else
+        ziinit.z_filefunc = *pzlib_filefunc_def;
+
+    ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
+                 (ziinit.z_filefunc.opaque,
+                  pathname,
+                  (append == APPEND_STATUS_CREATE) ?
+                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+    if (ziinit.filestream == NULL)
+        return NULL;
+    ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
+    ziinit.in_opened_file_inzip = 0;
+    ziinit.ci.stream_initialised = 0;
+    ziinit.number_entry = 0;
+    ziinit.add_position_when_writting_offset = 0;
+    init_linkedlist(&(ziinit.central_dir));
+
+
+    zi = (zip_internal*)ALLOC(sizeof(zip_internal));
+    if (zi==NULL)
+    {
+        ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
+        return NULL;
+    }
+
+    /* now we add file in a zipfile */
+#    ifndef NO_ADDFILEINEXISTINGZIP
+    ziinit.globalcomment = NULL;
+    if (append == APPEND_STATUS_ADDINZIP)
+    {
+        uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+        uLong size_central_dir;     /* size of the central directory  */
+        uLong offset_central_dir;   /* offset of start of central directory */
+        uLong central_pos,uL;
+
+        uLong number_disk;          /* number of the current dist, used for
+                                    spaning ZIP, unsupported, always 0*/
+        uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                    for spaning ZIP, unsupported, always 0*/
+        uLong number_entry;
+        uLong number_entry_CD;      /* total number of entries in
+                                    the central dir
+                                    (same than number_entry on nospan) */
+        uLong size_comment;
+
+        central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
+        if (central_pos==0)
+            err=ZIP_ERRNO;
+
+        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
+                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err=ZIP_ERRNO;
+
+        /* the signature, already checked */
+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* number of this disk */
+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* number of the disk with the start of the central directory */
+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* total number of entries in the central dir on this disk */
+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* total number of entries in the central dir */
+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        if ((number_entry_CD!=number_entry) ||
+            (number_disk_with_CD!=0) ||
+            (number_disk!=0))
+            err=ZIP_BADZIPFILE;
+
+        /* size of the central directory */
+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* offset of start of central directory with respect to the
+            starting disk number */
+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        /* zipfile global comment length */
+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
+            err=ZIP_ERRNO;
+
+        if ((central_pos<offset_central_dir+size_central_dir) &&
+            (err==ZIP_OK))
+            err=ZIP_BADZIPFILE;
+
+        if (err!=ZIP_OK)
+        {
+            ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
+            return NULL;
+        }
+
+        if (size_comment>0)
+        {
+            ziinit.globalcomment = ALLOC(size_comment+1);
+            if (ziinit.globalcomment)
+            {
+               size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
+               ziinit.globalcomment[size_comment]=0;
+            }
+        }
+
+        byte_before_the_zipfile = central_pos -
+                                (offset_central_dir+size_central_dir);
+        ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
+
+        {
+            uLong size_central_dir_to_read = size_central_dir;
+            size_t buf_size = SIZEDATA_INDATABLOCK;
+            void* buf_read = (void*)ALLOC(buf_size);
+            if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
+                  offset_central_dir + byte_before_the_zipfile,
+                  ZLIB_FILEFUNC_SEEK_SET) != 0)
+                  err=ZIP_ERRNO;
+
+            while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+            {
+                uLong read_this = SIZEDATA_INDATABLOCK;
+                if (read_this > size_central_dir_to_read)
+                    read_this = size_central_dir_to_read;
+                if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
+                    err=ZIP_ERRNO;
+
+                if (err==ZIP_OK)
+                    err = add_data_in_datablock(&ziinit.central_dir,buf_read,
+                                                (uLong)read_this);
+                size_central_dir_to_read-=read_this;
+            }
+            TRYFREE(buf_read);
+        }
+        ziinit.begin_pos = byte_before_the_zipfile;
+        ziinit.number_entry = number_entry_CD;
+
+        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
+                  offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err=ZIP_ERRNO;
+    }
+
+    if (globalcomment)
+    {
+      *globalcomment = ziinit.globalcomment;
+    }
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+    if (err != ZIP_OK)
+    {
+#    ifndef NO_ADDFILEINEXISTINGZIP
+        TRYFREE(ziinit.globalcomment);
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+        TRYFREE(zi);
+        return NULL;
+    }
+    else
+    {
+        *zi = ziinit;
+        return (zipFile)zi;
+    }
+}
+
+extern zipFile ZEXPORT zipOpen (pathname, append)
+    const char *pathname;
+    int append;
+{
+    return zipOpen2(pathname,append,NULL,NULL);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
+                                         extrafield_local, size_extrafield_local,
+                                         extrafield_global, size_extrafield_global,
+                                         comment, method, level, raw,
+                                         windowBits, memLevel, strategy,
+                                         password, crcForCrypting)
+    zipFile file;
+    const char* filename;
+    const zip_fileinfo* zipfi;
+    const void* extrafield_local;
+    uInt size_extrafield_local;
+    const void* extrafield_global;
+    uInt size_extrafield_global;
+    const char* comment;
+    int method;
+    int level;
+    int raw;
+    int windowBits;
+    int memLevel;
+    int strategy;
+    const char* password;
+    uLong crcForCrypting;
+{
+    zip_internal* zi;
+    uInt size_filename;
+    uInt size_comment;
+    uInt i;
+    int err = ZIP_OK;
+
+#    ifdef NOCRYPT
+    if (password != NULL)
+        return ZIP_PARAMERROR;
+#    endif
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    if ((method!=0) && (method!=Z_DEFLATED))
+        return ZIP_PARAMERROR;
+
+    zi = (zip_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+        if (err != ZIP_OK)
+            return err;
+    }
+
+
+    if (filename==NULL)
+        filename="-";
+
+    if (comment==NULL)
+        size_comment = 0;
+    else
+        size_comment = (uInt)strlen(comment);
+
+    size_filename = (uInt)strlen(filename);
+
+    if (zipfi == NULL)
+        zi->ci.dosDate = 0;
+    else
+    {
+        if (zipfi->dosDate != 0)
+            zi->ci.dosDate = zipfi->dosDate;
+        else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
+    }
+
+    zi->ci.flag = 0;
+    if ((level==8) || (level==9))
+      zi->ci.flag |= 2;
+    if ((level==2))
+      zi->ci.flag |= 4;
+    if ((level==1))
+      zi->ci.flag |= 6;
+    if (password != NULL)
+      zi->ci.flag |= 1;
+
+    zi->ci.crc32 = 0;
+    zi->ci.method = method;
+    zi->ci.encrypt = 0;
+    zi->ci.stream_initialised = 0;
+    zi->ci.pos_in_buffered_data = 0;
+    zi->ci.raw = raw;
+    zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
+    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
+                                      size_extrafield_global + size_comment;
+    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
+
+    ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+    /* version info */
+    ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+    ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+    ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+    ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+    if (zipfi==NULL)
+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+    else
+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+    if (zipfi==NULL)
+        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+    else
+        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+    ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
+
+    for (i=0;i<size_filename;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+    for (i=0;i<size_extrafield_global;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+              *(((const char*)extrafield_global)+i);
+
+    for (i=0;i<size_comment;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+              size_extrafield_global+i) = *(comment+i);
+    if (zi->ci.central_header == NULL)
+        return ZIP_INTERNALERROR;
+
+    /* write the local header */
+    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+    if (err==ZIP_OK)
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
+
+    if ((err==ZIP_OK) && (size_filename>0))
+        if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+                err = ZIP_ERRNO;
+
+    if ((err==ZIP_OK) && (size_extrafield_local>0))
+        if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
+                                                                           !=size_extrafield_local)
+                err = ZIP_ERRNO;
+
+    zi->ci.stream.avail_in = (uInt)0;
+    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+    zi->ci.stream.next_out = zi->ci.buffered_data;
+    zi->ci.stream.total_in = 0;
+    zi->ci.stream.total_out = 0;
+
+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+    {
+        zi->ci.stream.zalloc = (alloc_func)0;
+        zi->ci.stream.zfree = (free_func)0;
+        zi->ci.stream.opaque = (voidpf)0;
+
+        if (windowBits>0)
+            windowBits = -windowBits;
+
+        err = deflateInit2(&zi->ci.stream, level,
+               Z_DEFLATED, windowBits, memLevel, strategy);
+
+        if (err==Z_OK)
+            zi->ci.stream_initialised = 1;
+    }
+#    ifndef NOCRYPT
+    zi->ci.crypt_header_size = 0;
+    if ((err==Z_OK) && (password != NULL))
+    {
+        unsigned char bufHead[RAND_HEAD_LEN];
+        unsigned int sizeHead;
+        zi->ci.encrypt = 1;
+        zi->ci.pcrc_32_tab = get_crc_table();
+        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+        zi->ci.crypt_header_size = sizeHead;
+
+        if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+                err = ZIP_ERRNO;
+    }
+#    endif
+
+    if (err==Z_OK)
+        zi->in_opened_file_inzip = 1;
+    return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
+                                        extrafield_local, size_extrafield_local,
+                                        extrafield_global, size_extrafield_global,
+                                        comment, method, level, raw)
+    zipFile file;
+    const char* filename;
+    const zip_fileinfo* zipfi;
+    const void* extrafield_local;
+    uInt size_extrafield_local;
+    const void* extrafield_global;
+    uInt size_extrafield_global;
+    const char* comment;
+    int method;
+    int level;
+    int raw;
+{
+    return zipOpenNewFileInZip3 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
+                                        extrafield_local, size_extrafield_local,
+                                        extrafield_global, size_extrafield_global,
+                                        comment, method, level)
+    zipFile file;
+    const char* filename;
+    const zip_fileinfo* zipfi;
+    const void* extrafield_local;
+    uInt size_extrafield_local;
+    const void* extrafield_global;
+    uInt size_extrafield_global;
+    const char* comment;
+    int method;
+    int level;
+{
+    return zipOpenNewFileInZip2 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, 0);
+}
+
+local int zipFlushWriteBuffer(zi)
+  zip_internal* zi;
+{
+    int err=ZIP_OK;
+
+    if (zi->ci.encrypt != 0)
+    {
+#ifndef NOCRYPT
+        uInt i;
+        int t;
+        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
+                                       zi->ci.buffered_data[i],t);
+#endif
+    }
+    if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
+                                                                    !=zi->ci.pos_in_buffered_data)
+      err = ZIP_ERRNO;
+    zi->ci.pos_in_buffered_data = 0;
+    return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
+    zipFile file;
+    const void* buf;
+    unsigned len;
+{
+    zip_internal* zi;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+
+    zi->ci.stream.next_in = (void*)buf;
+    zi->ci.stream.avail_in = len;
+    zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
+
+    while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+    {
+        if (zi->ci.stream.avail_out == 0)
+        {
+            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
+                err = ZIP_ERRNO;
+            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+            zi->ci.stream.next_out = zi->ci.buffered_data;
+        }
+
+
+        if(err != ZIP_OK)
+            break;
+
+        if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+        {
+            uLong uTotalOutBefore = zi->ci.stream.total_out;
+            err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
+            zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+
+        }
+        else
+        {
+            uInt copy_this,i;
+            if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+                copy_this = zi->ci.stream.avail_in;
+            else
+                copy_this = zi->ci.stream.avail_out;
+            for (i=0;i<copy_this;i++)
+                *(((char*)zi->ci.stream.next_out)+i) =
+                    *(((const char*)zi->ci.stream.next_in)+i);
+            {
+                zi->ci.stream.avail_in -= copy_this;
+                zi->ci.stream.avail_out-= copy_this;
+                zi->ci.stream.next_in+= copy_this;
+                zi->ci.stream.next_out+= copy_this;
+                zi->ci.stream.total_in+= copy_this;
+                zi->ci.stream.total_out+= copy_this;
+                zi->ci.pos_in_buffered_data += copy_this;
+            }
+        }
+    }
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
+    zipFile file;
+    uLong uncompressed_size;
+    uLong crc32;
+{
+    zip_internal* zi;
+    uLong compressed_size;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+    zi->ci.stream.avail_in = 0;
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+        while (err==ZIP_OK)
+    {
+        uLong uTotalOutBefore;
+        if (zi->ci.stream.avail_out == 0)
+        {
+            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
+                err = ZIP_ERRNO;
+            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+            zi->ci.stream.next_out = zi->ci.buffered_data;
+        }
+        uTotalOutBefore = zi->ci.stream.total_out;
+        err=deflate(&zi->ci.stream,  Z_FINISH);
+        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+    }
+
+    if (err==Z_STREAM_END)
+        err=ZIP_OK; /* this is normal */
+
+    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+        if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
+            err = ZIP_ERRNO;
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+    {
+        err=deflateEnd(&zi->ci.stream);
+        zi->ci.stream_initialised = 0;
+    }
+
+    if (!zi->ci.raw)
+    {
+        crc32 = (uLong)zi->ci.crc32;
+        uncompressed_size = (uLong)zi->ci.stream.total_in;
+    }
+    compressed_size = (uLong)zi->ci.stream.total_out;
+#    ifndef NOCRYPT
+    compressed_size += zi->ci.crypt_header_size;
+#    endif
+
+    ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+    ziplocal_putValue_inmemory(zi->ci.central_header+20,
+                                compressed_size,4); /*compr size*/
+    if (zi->ci.stream.data_type == Z_ASCII)
+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+    ziplocal_putValue_inmemory(zi->ci.central_header+24,
+                                uncompressed_size,4); /*uncompr size*/
+
+    if (err==ZIP_OK)
+        err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
+                                       (uLong)zi->ci.size_centralheader);
+    free(zi->ci.central_header);
+
+    if (err==ZIP_OK)
+    {
+        long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
+        if (ZSEEK(zi->z_filefunc,zi->filestream,
+                  zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+
+        if (err==ZIP_OK)
+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+        if (err==ZIP_OK) /* compressed size, unknown */
+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+        if (err==ZIP_OK) /* uncompressed size, unknown */
+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+
+        if (ZSEEK(zi->z_filefunc,zi->filestream,
+                  cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+    }
+
+    zi->number_entry ++;
+    zi->in_opened_file_inzip = 0;
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (file)
+    zipFile file;
+{
+    return zipCloseFileInZipRaw (file,0,0);
+}
+
+extern int ZEXPORT zipClose (file, global_comment)
+    zipFile file;
+    const char* global_comment;
+{
+    zip_internal* zi;
+    int err = 0;
+    uLong size_centraldir = 0;
+    uLong centraldir_pos_inzip;
+    uInt size_global_comment;
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+    }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    if (global_comment==NULL)
+        global_comment = zi->globalcomment;
+#endif
+    if (global_comment==NULL)
+        size_global_comment = 0;
+    else
+        size_global_comment = (uInt)strlen(global_comment);
+
+    centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
+    if (err==ZIP_OK)
+    {
+        linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
+        while (ldi!=NULL)
+        {
+            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+                if (ZWRITE(zi->z_filefunc,zi->filestream,
+                           ldi->data,ldi->filled_in_this_block)
+                              !=ldi->filled_in_this_block )
+                    err = ZIP_ERRNO;
+
+            size_centraldir += ldi->filled_in_this_block;
+            ldi = ldi->next_datablock;
+        }
+    }
+    free_datablock(zi->central_dir.first_block);
+
+    if (err==ZIP_OK) /* Magic End */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+    if (err==ZIP_OK) /* number of this disk */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+    if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+
+    if (err==ZIP_OK) /* total number of entries in the central dir */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+
+    if (err==ZIP_OK) /* size of the central directory */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+    if (err==ZIP_OK) /* offset of start of central directory with respect to the
+                            starting disk number */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
+                                (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+
+    if (err==ZIP_OK) /* zipfile comment length */
+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+    if ((err==ZIP_OK) && (size_global_comment>0))
+        if (ZWRITE(zi->z_filefunc,zi->filestream,
+                   global_comment,size_global_comment) != size_global_comment)
+                err = ZIP_ERRNO;
+
+    if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
+        if (err == ZIP_OK)
+            err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    TRYFREE(zi->globalcomment);
+#endif
+    TRYFREE(zi);
+
+    return err;
+}
diff --git a/ossimPlanet/xcode/ossimPlanet/English.lproj/InfoPlist.strings b/ossimPlanet/xcode/ossimPlanet/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..ce87cdb
Binary files /dev/null and b/ossimPlanet/xcode/ossimPlanet/English.lproj/InfoPlist.strings differ
diff --git a/ossimPlanet/xcode/ossimPlanet/Info.plist b/ossimPlanet/xcode/ossimPlanet/Info.plist
new file mode 100644
index 0000000..bd3e928
--- /dev/null
+++ b/ossimPlanet/xcode/ossimPlanet/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>ossimPlanet</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.apple.carbonframeworktemplate</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+        <key>CFBundleShortVersionString</key>
+        <string>1.0</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+</dict>
+</plist>
diff --git a/ossimPlanet/xcode/ossimPlanet/ossimPlanet.xcodeproj/project.pbxproj b/ossimPlanet/xcode/ossimPlanet/ossimPlanet.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..7109bf4
--- /dev/null
+++ b/ossimPlanet/xcode/ossimPlanet/ossimPlanet.xcodeproj/project.pbxproj
@@ -0,0 +1,3219 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		EE9D26590DD888FB005A8951 /* All */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = EE9D26650DD88940005A8951 /* Build configuration list for PBXAggregateTarget "All" */;
+			buildPhases = (
+			);
+			dependencies = (
+				EE9D26610DD8891C005A8951 /* PBXTargetDependency */,
+				43DFCC080FF0F4E000FB2061 /* PBXTargetDependency */,
+				43DFCC0A0FF0F4E000FB2061 /* PBXTargetDependency */,
+			);
+			name = All;
+			productName = All;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		186EF5700B1CE22D00F7886A /* ossim.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186EF4F60B1CE11D00F7886A /* ossim.framework */; };
+		430485FE0F3CB80800B9C1E2 /* ossimPlanetDatabasePager.h in Headers */ = {isa = PBXBuildFile; fileRef = 430485FD0F3CB80800B9C1E2 /* ossimPlanetDatabasePager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4306ABAB10FE11A700C7202A /* osg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAA10FE11A700C7202A /* osg.framework */; };
+		4306ABAD10FE11AC00C7202A /* osgGA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAC10FE11AC00C7202A /* osgGA.framework */; };
+		4306ABB210FE11C000C7202A /* osgDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAE10FE11C000C7202A /* osgDB.framework */; };
+		4306ABB310FE11C000C7202A /* osgText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAF10FE11C000C7202A /* osgText.framework */; };
+		4306ABB410FE11C000C7202A /* osgUtil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABB010FE11C000C7202A /* osgUtil.framework */; };
+		4306ABB510FE11C000C7202A /* osgViewer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABB110FE11C000C7202A /* osgViewer.framework */; };
+		430C8F670CBBD0B9002BAF12 /* ossimPlanetCompass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 430C8F660CBBD0B8002BAF12 /* ossimPlanetCompass.cpp */; };
+		430C8F690CBBD0CA002BAF12 /* ossimPlanetCompass.h in Headers */ = {isa = PBXBuildFile; fileRef = 430C8F680CBBD0CA002BAF12 /* ossimPlanetCompass.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		430D8E911100DA3F00EB0F96 /* ossimPlanetDepthPartitionNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 430D8E901100DA3F00EB0F96 /* ossimPlanetDepthPartitionNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		430D8E941100DA5200EB0F96 /* ossimPlanetDistanceAccumulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 430D8E931100DA5200EB0F96 /* ossimPlanetDistanceAccumulator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		430D8E991100DB1F00EB0F96 /* ossimPlanetDepthPartitionNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 430D8E971100DB1F00EB0F96 /* ossimPlanetDepthPartitionNode.cpp */; };
+		430D8E9A1100DB1F00EB0F96 /* ossimPlanetDistanceAccumulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 430D8E981100DB1F00EB0F96 /* ossimPlanetDistanceAccumulator.cpp */; };
+		4314728F0CBE9F0F00EAADAB /* ossimPlanetVisitors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4314728E0CBE9F0F00EAADAB /* ossimPlanetVisitors.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		431476550CA838310090B3CE /* ossimPlanetKmlScreenOverlayNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431476540CA838310090B3CE /* ossimPlanetKmlScreenOverlayNode.cpp */; };
+		431476570CA838400090B3CE /* ossimPlanetKmlScreenOverlayNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 431476560CA838400090B3CE /* ossimPlanetKmlScreenOverlayNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BE0F0C9717B400D36F21 /* ossimPlanetDtedElevationDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDBF0C9717B400D36F21 /* ossimPlanetDtedElevationDatabase.cpp */; };
+		4315BE110C9717B400D36F21 /* ossimPlanetCubeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC10C9717B400D36F21 /* ossimPlanetCubeGrid.cpp */; };
+		4315BE120C9717B400D36F21 /* ossimPlanetWmsImageLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC20C9717B400D36F21 /* ossimPlanetWmsImageLayer.cpp */; };
+		4315BE130C9717B400D36F21 /* ossimPlanetUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC30C9717B400D36F21 /* ossimPlanetUtility.cpp */; };
+		4315BE140C9717B400D36F21 /* ossimPlanetThreadPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC40C9717B400D36F21 /* ossimPlanetThreadPool.cpp */; };
+		4315BE150C9717B400D36F21 /* ossimPlanetThreadImp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC50C9717B400D36F21 /* ossimPlanetThreadImp.cpp */; };
+		4315BE160C9717B400D36F21 /* ossimPlanetThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC60C9717B400D36F21 /* ossimPlanetThread.cpp */; };
+		4315BE170C9717B400D36F21 /* ossimPlanetTextureLayerRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC70C9717B400D36F21 /* ossimPlanetTextureLayerRegistry.cpp */; };
+		4315BE180C9717B400D36F21 /* ossimPlanetTextureLayerGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC80C9717B400D36F21 /* ossimPlanetTextureLayerGroup.cpp */; };
+		4315BE190C9717B400D36F21 /* ossimPlanetTextureLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDC90C9717B400D36F21 /* ossimPlanetTextureLayer.cpp */; };
+		4315BE1A0C9717B400D36F21 /* ossimPlanetStandardTextureLayerFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCA0C9717B400D36F21 /* ossimPlanetStandardTextureLayerFactory.cpp */; };
+		4315BE1B0C9717B400D36F21 /* ossimPlanetSocketNetworkConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCB0C9717B400D36F21 /* ossimPlanetSocketNetworkConnection.cpp */; };
+		4315BE1C0C9717B400D36F21 /* ossimPlanetShaderProgramSetup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCC0C9717B400D36F21 /* ossimPlanetShaderProgramSetup.cpp */; };
+		4315BE1D0C9717B400D36F21 /* ossimPlanetServerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCD0C9717B400D36F21 /* ossimPlanetServerThread.cpp */; };
+		4315BE1E0C9717B400D36F21 /* ossimPlanetSceneView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCE0C9717B400D36F21 /* ossimPlanetSceneView.cpp */; };
+		4315BE1F0C9717B400D36F21 /* ossimPlanetPlaneGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDCF0C9717B400D36F21 /* ossimPlanetPlaneGrid.cpp */; };
+		4315BE200C9717B400D36F21 /* ossimPlanetPagedLandLod.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD00C9717B400D36F21 /* ossimPlanetPagedLandLod.cpp */; };
+		4315BE210C9717B400D36F21 /* ossimPlanetOssimImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD10C9717B400D36F21 /* ossimPlanetOssimImage.cpp */; };
+		4315BE220C9717B400D36F21 /* ossimPlanetManipulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD20C9717B400D36F21 /* ossimPlanetManipulator.cpp */; };
+		4315BE230C9717B400D36F21 /* ossimPlanetNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD30C9717B400D36F21 /* ossimPlanetNavigator.cpp */; };
+		4315BE250C9717B400D36F21 /* ossimPlanetLookAt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD50C9717B400D36F21 /* ossimPlanetLookAt.cpp */; };
+		4315BE260C9717B400D36F21 /* ossimPlanetLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD60C9717B400D36F21 /* ossimPlanetLayer.cpp */; };
+		4315BE270C9717B400D36F21 /* ossimPlanetLatLonHud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD70C9717B400D36F21 /* ossimPlanetLatLonHud.cpp */; };
+		4315BE280C9717B400D36F21 /* ulError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD80C9717B400D36F21 /* ulError.cpp */; };
+		4315BE290C9717B400D36F21 /* ulClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDD90C9717B400D36F21 /* ulClock.cpp */; };
+		4315BE2A0C9717B400D36F21 /* sg_socket_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDA0C9717B400D36F21 /* sg_socket_udp.cpp */; };
+		4315BE2B0C9717B400D36F21 /* ossimPlanetYahooGeocoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDB0C9717B400D36F21 /* ossimPlanetYahooGeocoder.cpp */; };
+		4315BE2C0C9717B400D36F21 /* ossimPlanetWmsClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDC0C9717B400D36F21 /* ossimPlanetWmsClient.cpp */; };
+		4315BE2D0C9717B400D36F21 /* ossimPlanetIoThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDD0C9717B400D36F21 /* ossimPlanetIoThread.cpp */; };
+		4315BE2E0C9717B400D36F21 /* ossimPlanetIoSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDE0C9717B400D36F21 /* ossimPlanetIoSocketServerChannel.cpp */; };
+		4315BE2F0C9717B400D36F21 /* ossimPlanetIoSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDDF0C9717B400D36F21 /* ossimPlanetIoSocket.cpp */; };
+		4315BE300C9717B400D36F21 /* ossimPlanetIoRoutableMessageHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE00C9717B400D36F21 /* ossimPlanetIoRoutableMessageHandler.cpp */; };
+		4315BE310C9717B400D36F21 /* ossimPlanetInteractionController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE10C9717B400D36F21 /* ossimPlanetInteractionController.cpp */; };
+		4315BE320C9717B400D36F21 /* ossimPlanetImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE20C9717B400D36F21 /* ossimPlanetImage.cpp */; };
+		4315BE330C9717B400D36F21 /* ossimPlanetIdManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE30C9717B400D36F21 /* ossimPlanetIdManager.cpp */; };
+		4315BE340C9717B400D36F21 /* ossimPlanetClientThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE40C9717B400D36F21 /* ossimPlanetClientThread.cpp */; };
+		4315BE350C9717B400D36F21 /* ossimPlanetBoundingBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE50C9717B400D36F21 /* ossimPlanetBoundingBox.cpp */; };
+		4315BE360C9717B400D36F21 /* ossimPlanetBillboardIcon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE60C9717B400D36F21 /* ossimPlanetBillboardIcon.cpp */; };
+		4315BE370C9717B400D36F21 /* ossimPlanetKmlLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE70C9717B400D36F21 /* ossimPlanetKmlLayer.cpp */; };
+		4315BE390C9717B400D36F21 /* ossimPlanetKml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDE90C9717B400D36F21 /* ossimPlanetKml.cpp */; };
+		4315BE3A0C9717B400D36F21 /* ossimPlanetJpegImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDEA0C9717B400D36F21 /* ossimPlanetJpegImage.cpp */; };
+		4315BE3B0C9717B400D36F21 /* ossimPlanet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDEB0C9717B400D36F21 /* ossimPlanet.cpp */; };
+		4315BE3C0C9717B400D36F21 /* netSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDEC0C9717B400D36F21 /* netSocket.cpp */; };
+		4315BE3D0C9717B400D36F21 /* netMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDED0C9717B400D36F21 /* netMonitor.cpp */; };
+		4315BE3E0C9717B400D36F21 /* netMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDEE0C9717B400D36F21 /* netMessage.cpp */; };
+		4315BE3F0C9717B400D36F21 /* netChat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDEF0C9717B400D36F21 /* netChat.cpp */; };
+		4315BE400C9717B400D36F21 /* netChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF00C9717B400D36F21 /* netChannel.cpp */; };
+		4315BE410C9717B400D36F21 /* netBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF10C9717B400D36F21 /* netBuffer.cpp */; };
+		4315BE420C9717B400D36F21 /* mkUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF20C9717B400D36F21 /* mkUtils.cpp */; };
+		4315BE430C9717B400D36F21 /* iochannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF30C9717B400D36F21 /* iochannel.cpp */; };
+		4315BE440C9717B400D36F21 /* ossimPlanetGeocoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF40C9717B400D36F21 /* ossimPlanetGeocoder.cpp */; };
+		4315BE460C9717B400D36F21 /* ossimPlanetActionRouter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF60C9717B400D36F21 /* ossimPlanetActionRouter.cpp */; };
+		4315BE470C9717B400D36F21 /* ossimPlanetActionReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF70C9717B400D36F21 /* ossimPlanetActionReceiver.cpp */; };
+		4315BE480C9717B400D36F21 /* ossimPlanetAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF80C9717B400D36F21 /* ossimPlanetAction.cpp */; };
+		4315BE490C9717B400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDF90C9717B400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.cpp */; };
+		4315BE4A0C9717B400D36F21 /* ossimPlanetElevationGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFA0C9717B400D36F21 /* ossimPlanetElevationGrid.cpp */; };
+		4315BE4B0C9717B400D36F21 /* ulLinkedList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFB0C9717B400D36F21 /* ulLinkedList.cpp */; };
+		4315BE4C0C9717B400D36F21 /* ossimPlanetLandCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFC0C9717B400D36F21 /* ossimPlanetLandCache.cpp */; };
+		4315BE4D0C9717B400D36F21 /* ossimPlanetLand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFD0C9717B400D36F21 /* ossimPlanetLand.cpp */; };
+		4315BE4E0C9717B400D36F21 /* ossimPlanetKmlLayerNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFE0C9717B400D36F21 /* ossimPlanetKmlLayerNode.cpp */; };
+		4315BE4F0C9717B400D36F21 /* sg_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BDFF0C9717B400D36F21 /* sg_file.cpp */; };
+		4315BE500C9717B400D36F21 /* ossimPlanetTexture2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE000C9717B400D36F21 /* ossimPlanetTexture2D.cpp */; };
+		4315BE510C9717B400D36F21 /* ossimPlanetSrtmElevationDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE010C9717B400D36F21 /* ossimPlanetSrtmElevationDatabase.cpp */; };
+		4315BE520C9717B400D36F21 /* ossimPlanetId.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE020C9717B400D36F21 /* ossimPlanetId.cpp */; };
+		4315BE530C9717B400D36F21 /* ossimPlanetIconGeom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE030C9717B400D36F21 /* ossimPlanetIconGeom.cpp */; };
+		4315BE550C9717B400D36F21 /* ossimPlanetGridUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE050C9717B400D36F21 /* ossimPlanetGridUtility.cpp */; };
+		4315BE560C9717B400D36F21 /* ulRTTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE060C9717B400D36F21 /* ulRTTI.cpp */; };
+		4315BE570C9717B400D36F21 /* sg_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE070C9717B400D36F21 /* sg_socket.cpp */; };
+		4315BE580C9717B400D36F21 /* ossimPlanetOssimImageLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE080C9717B400D36F21 /* ossimPlanetOssimImageLayer.cpp */; };
+		4315BE590C9717B400D36F21 /* ul.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE090C9717B400D36F21 /* ul.cpp */; };
+		4315BE5A0C9717B400D36F21 /* ulList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE0A0C9717B400D36F21 /* ulList.cpp */; };
+		4315BE5B0C9717B400D36F21 /* ossimPlanetLandReaderWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE0B0C9717B400D36F21 /* ossimPlanetLandReaderWriter.cpp */; };
+		4315BE5C0C9717B400D36F21 /* ossimPlanetLandCullCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE0C0C9717B400D36F21 /* ossimPlanetLandCullCallback.cpp */; };
+		4315BE5D0C9717B400D36F21 /* ossimPlanetElevationDatabaseGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE0D0C9717B400D36F21 /* ossimPlanetElevationDatabaseGroup.cpp */; };
+		4315BE5E0C9717B400D36F21 /* ossimPlanetElevationDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4315BE0E0C9717B400D36F21 /* ossimPlanetElevationDatabase.cpp */; };
+		4315BEC80C9717E400D36F21 /* ossimPlanetLandTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE5F0C9717E400D36F21 /* ossimPlanetLandTreeNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEC90C9717E400D36F21 /* ossimPlanetLandNormalType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE600C9717E400D36F21 /* ossimPlanetLandNormalType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BECA0C9717E400D36F21 /* ossimPlanetKmlLayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE610C9717E400D36F21 /* ossimPlanetKmlLayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BECB0C9717E400D36F21 /* netBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE620C9717E400D36F21 /* netBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BECC0C9717E400D36F21 /* ossimPlanetLand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE630C9717E400D36F21 /* ossimPlanetLand.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BECD0C9717E400D36F21 /* ossimPlanetBillboardIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE640C9717E400D36F21 /* ossimPlanetBillboardIcon.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BECF0C9717E400D36F21 /* ossimPlanetElevationDatabaseGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE660C9717E400D36F21 /* ossimPlanetElevationDatabaseGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED00C9717E400D36F21 /* ossimPlanetIdolLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE670C9717E400D36F21 /* ossimPlanetIdolLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED20C9717E400D36F21 /* ossimPlanetIdManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE690C9717E400D36F21 /* ossimPlanetIdManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED30C9717E400D36F21 /* ossimPlanetLandReaderWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6A0C9717E400D36F21 /* ossimPlanetLandReaderWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED40C9717E400D36F21 /* ossimPlanetUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6B0C9717E400D36F21 /* ossimPlanetUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED50C9717E400D36F21 /* ossimPlanetThreadPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6C0C9717E400D36F21 /* ossimPlanetThreadPool.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED60C9717E400D36F21 /* ossimPlanetPlaneGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6D0C9717E400D36F21 /* ossimPlanetPlaneGrid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED70C9717E400D36F21 /* ossimPlanetPagedRequestNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6E0C9717E400D36F21 /* ossimPlanetPagedRequestNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED80C9717E400D36F21 /* ossimPlanetPagedLandLodRefreshType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE6F0C9717E400D36F21 /* ossimPlanetPagedLandLodRefreshType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BED90C9717E400D36F21 /* ossimPlanetLandNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE700C9717E400D36F21 /* ossimPlanetLandNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDA0C9717E400D36F21 /* ossimPlanetIoSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE710C9717E400D36F21 /* ossimPlanetIoSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDB0C9717E400D36F21 /* ossimPlanetInteractionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE720C9717E400D36F21 /* ossimPlanetInteractionController.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDC0C9717E400D36F21 /* ulLocal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE730C9717E400D36F21 /* ulLocal.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDD0C9717E400D36F21 /* ul.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE740C9717E400D36F21 /* ul.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDE0C9717E400D36F21 /* ossimPlanetInputDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE750C9717E400D36F21 /* ossimPlanetInputDevice.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEDF0C9717E400D36F21 /* ossimPlanetShaderProgramSetup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE760C9717E400D36F21 /* ossimPlanetShaderProgramSetup.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE00C9717E400D36F21 /* ossimPlanetSetup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE770C9717E400D36F21 /* ossimPlanetSetup.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE10C9717E400D36F21 /* ossimPlanetBoundingBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE780C9717E400D36F21 /* ossimPlanetBoundingBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE20C9717E400D36F21 /* ossimPlanetIoSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE790C9717E400D36F21 /* ossimPlanetIoSocketServerChannel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE30C9717E400D36F21 /* ossimPlanetPrimaryBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7A0C9717E400D36F21 /* ossimPlanetPrimaryBody.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE40C9717E400D36F21 /* ossimPlanetSocketNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7B0C9717E400D36F21 /* ossimPlanetSocketNetworkConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE50C9717E400D36F21 /* iochannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7C0C9717E400D36F21 /* iochannel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE60C9717E400D36F21 /* ossimPlanetIconGeom.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7D0C9717E400D36F21 /* ossimPlanetIconGeom.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE70C9717E400D36F21 /* ossimPlanetTextureLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7E0C9717E400D36F21 /* ossimPlanetTextureLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE80C9717E400D36F21 /* ossimPlanetTexture2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE7F0C9717E400D36F21 /* ossimPlanetTexture2D.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEE90C9717E400D36F21 /* ossimPlanetAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE800C9717E400D36F21 /* ossimPlanetAction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEEA0C9717E400D36F21 /* ossimPlanetServerMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE810C9717E400D36F21 /* ossimPlanetServerMessageHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEEB0C9717E400D36F21 /* ossimPlanetSceneView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE820C9717E400D36F21 /* ossimPlanetSceneView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEEC0C9717E400D36F21 /* ossimPlanetManipulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE830C9717E400D36F21 /* ossimPlanetManipulator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEED0C9717E400D36F21 /* ossimPlanetWmsImageLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE840C9717E400D36F21 /* ossimPlanetWmsImageLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEEE0C9717E400D36F21 /* ossimPlanetThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE850C9717E400D36F21 /* ossimPlanetThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEEF0C9717E400D36F21 /* ossimPlanetTextureLayerRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE860C9717E400D36F21 /* ossimPlanetTextureLayerRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF00C9717E400D36F21 /* netChat.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE870C9717E400D36F21 /* netChat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF10C9717E400D36F21 /* ossimPlanetTextureLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE880C9717E400D36F21 /* ossimPlanetTextureLayerGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF20C9717E400D36F21 /* ossimPlanetTextureLayerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE890C9717E400D36F21 /* ossimPlanetTextureLayerFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF30C9717E400D36F21 /* ossimPlanetOssimImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8A0C9717E400D36F21 /* ossimPlanetOssimImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF40C9717E400D36F21 /* ossimPlanetOrthoFlatLandNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8B0C9717E400D36F21 /* ossimPlanetOrthoFlatLandNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF50C9717E400D36F21 /* ossimPlanetServerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8C0C9717E400D36F21 /* ossimPlanetServerThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF60C9717E400D36F21 /* ossimPlanetIoThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8D0C9717E400D36F21 /* ossimPlanetIoThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF70C9717E400D36F21 /* ossimPlanet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8E0C9717E400D36F21 /* ossimPlanet.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF80C9717E400D36F21 /* ossimPlanetOssimImageLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE8F0C9717E400D36F21 /* ossimPlanetOssimImageLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEF90C9717E400D36F21 /* ossimPlanetThreadImp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE900C9717E400D36F21 /* ossimPlanetThreadImp.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEFB0C9717E400D36F21 /* ossimPlanetLandTextureRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE920C9717E400D36F21 /* ossimPlanetLandTextureRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEFC0C9717E400D36F21 /* ossimPlanetLandCullCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE930C9717E400D36F21 /* ossimPlanetLandCullCallback.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEFD0C9717E400D36F21 /* ossimPlanetConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE940C9717E400D36F21 /* ossimPlanetConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEFE0C9717E400D36F21 /* ossimPlanetNetworkConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE950C9717E400D36F21 /* ossimPlanetNetworkConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BEFF0C9717E400D36F21 /* ossimPlanetKml.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE960C9717E400D36F21 /* ossimPlanetKml.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF010C9717E400D36F21 /* ossimPlanetExport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE980C9717E400D36F21 /* ossimPlanetExport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF020C9717E400D36F21 /* netMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE990C9717E400D36F21 /* netMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF030C9717E400D36F21 /* ossimPlanetIo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE9A0C9717E400D36F21 /* ossimPlanetIo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF040C9717E400D36F21 /* ossimPlanetJpegImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE9B0C9717E400D36F21 /* ossimPlanetJpegImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF050C9717E400D36F21 /* ossimPlanetLookAt.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE9C0C9717E400D36F21 /* ossimPlanetLookAt.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF080C9717E400D36F21 /* net.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BE9F0C9717E400D36F21 /* net.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF090C9717E400D36F21 /* ulRTTI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA00C9717E400D36F21 /* ulRTTI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0A0C9717E400D36F21 /* netChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA10C9717E400D36F21 /* netChannel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0B0C9717E400D36F21 /* ossimPlanetElevationGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA20C9717E400D36F21 /* ossimPlanetElevationGrid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0C0C9717E400D36F21 /* ossimPlanetIntersectUserData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA30C9717E400D36F21 /* ossimPlanetIntersectUserData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0D0C9717E400D36F21 /* ossimPlanetLabelGeom.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA40C9717E400D36F21 /* ossimPlanetLabelGeom.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0E0C9717E400D36F21 /* ossimPlanetGeocoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA50C9717E400D36F21 /* ossimPlanetGeocoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF0F0C9717E400D36F21 /* ossimPlanetLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA60C9717E400D36F21 /* ossimPlanetLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF100C9717E400D36F21 /* netMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA70C9717E400D36F21 /* netMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF110C9717E400D36F21 /* ossimPlanetId.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEA80C9717E400D36F21 /* ossimPlanetId.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF130C9717E400D36F21 /* ossimPlanetActionRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAA0C9717E400D36F21 /* ossimPlanetActionRouter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF140C9717E400D36F21 /* ossimPlanetSrtmElevationDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAB0C9717E400D36F21 /* ossimPlanetSrtmElevationDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF150C9717E400D36F21 /* ossimPlanetStandardTextureLayerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAC0C9717E400D36F21 /* ossimPlanetStandardTextureLayerFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF160C9717E400D36F21 /* ossimPlanetActionReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAD0C9717E400D36F21 /* ossimPlanetActionReceiver.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF170C9717E400D36F21 /* sg_file.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAE0C9717E400D36F21 /* sg_file.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF180C9717E400D36F21 /* ossimPlanetYahooGeocoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEAF0C9717E400D36F21 /* ossimPlanetYahooGeocoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF190C9717E400D36F21 /* ossimPlanetIoMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB00C9717E400D36F21 /* ossimPlanetIoMessageHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1A0C9717E400D36F21 /* ossimPlanetElevationDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB10C9717E400D36F21 /* ossimPlanetElevationDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1B0C9717E400D36F21 /* compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB20C9717E400D36F21 /* compiler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1C0C9717E400D36F21 /* ossimPlanetLandCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB30C9717E400D36F21 /* ossimPlanetLandCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1D0C9717E400D36F21 /* ossimPlanetExtents.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB40C9717E400D36F21 /* ossimPlanetExtents.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1E0C9717E400D36F21 /* ossimPlanetKmlReaderWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB50C9717E400D36F21 /* ossimPlanetKmlReaderWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF1F0C9717E400D36F21 /* ossimPlanetDtedElevationDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB60C9717E400D36F21 /* ossimPlanetDtedElevationDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF200C9717E400D36F21 /* ossimPlanetNavigator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB70C9717E400D36F21 /* ossimPlanetNavigator.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF210C9717E400D36F21 /* ossimPlanetImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB80C9717E400D36F21 /* ossimPlanetImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF220C9717E400D36F21 /* sg_socket_udp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEB90C9717E400D36F21 /* sg_socket_udp.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF230C9717E400D36F21 /* sg_socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEBA0C9717E400D36F21 /* sg_socket.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF240C9717E400D36F21 /* ossimPlanetCubeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEBB0C9717E400D36F21 /* ossimPlanetCubeGrid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF250C9717E400D36F21 /* ossimPlanetIdolBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEBC0C9717E400D36F21 /* ossimPlanetIdolBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF270C9717E400D36F21 /* mkUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEBE0C9717E400D36F21 /* mkUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF280C9717E400D36F21 /* ossimPlanetLatLonHud.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEBF0C9717E400D36F21 /* ossimPlanetLatLonHud.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF290C9717E400D36F21 /* ossimPlanetClientThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC00C9717E400D36F21 /* ossimPlanetClientThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2A0C9717E400D36F21 /* ossimPlanetIoRoutableMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC10C9717E400D36F21 /* ossimPlanetIoRoutableMessageHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2B0C9717E400D36F21 /* ossimPlanetPagedLandLod.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC20C9717E400D36F21 /* ossimPlanetPagedLandLod.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2C0C9717E400D36F21 /* ossimPlanetWmsClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC30C9717E400D36F21 /* ossimPlanetWmsClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2D0C9717E400D36F21 /* netSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC40C9717E400D36F21 /* netSocket.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2E0C9717E400D36F21 /* ossimPlanetKmlLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC50C9717E400D36F21 /* ossimPlanetKmlLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF2F0C9717E400D36F21 /* ossimPlanetGridUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC60C9717E400D36F21 /* ossimPlanetGridUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4315BF300C9717E400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4315BEC70C9717E400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43244C830F742D70002F5FA3 /* ossimPlanetReentrantMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 43244C820F742D70002F5FA3 /* ossimPlanetReentrantMutex.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		432933BB10FE531E00C66EB8 /* OpenThreads.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 432933BA10FE531E00C66EB8 /* OpenThreads.framework */; };
+		432933E110FE577D00C66EB8 /* OpenThreads.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 432933BA10FE531E00C66EB8 /* OpenThreads.framework */; };
+		432933E410FE579100C66EB8 /* osg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAA10FE11A700C7202A /* osg.framework */; };
+		4329349110FE57A200C66EB8 /* osgViewer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABB110FE11C000C7202A /* osgViewer.framework */; };
+		432934AB10FE57AC00C66EB8 /* osgGA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAC10FE11AC00C7202A /* osgGA.framework */; };
+		432934C210FE57AF00C66EB8 /* osg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAA10FE11A700C7202A /* osg.framework */; };
+		432934C510FE57C800C66EB8 /* OpenThreads.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 432933BA10FE531E00C66EB8 /* OpenThreads.framework */; };
+		432934CA10FE57D600C66EB8 /* osgDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAE10FE11C000C7202A /* osgDB.framework */; };
+		4329351A10FE57FA00C66EB8 /* OpenThreads.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 432933BA10FE531E00C66EB8 /* OpenThreads.framework */; };
+		4329351B10FE57FA00C66EB8 /* osgDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAE10FE11C000C7202A /* osgDB.framework */; };
+		4329351C10FE57FA00C66EB8 /* osgUtil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABB010FE11C000C7202A /* osgUtil.framework */; };
+		4329351D10FE57FA00C66EB8 /* osgViewer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABB110FE11C000C7202A /* osgViewer.framework */; };
+		4329351E10FE57FA00C66EB8 /* osgGA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAC10FE11AC00C7202A /* osgGA.framework */; };
+		4329351F10FE57FA00C66EB8 /* osg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAA10FE11A700C7202A /* osg.framework */; };
+		4329352F10FE591500C66EB8 /* osgText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4306ABAF10FE11C000C7202A /* osgText.framework */; };
+		432D60B60CB548C800F15133 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 432D60B30CB548C800F15133 /* ioapi.c */; };
+		432D60B70CB548C800F15133 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 432D60B40CB548C800F15133 /* unzip.c */; };
+		432D60B80CB548C800F15133 /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 432D60B50CB548C800F15133 /* zip.c */; };
+		432D60BC0CB548DE00F15133 /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 432D60B90CB548DE00F15133 /* ioapi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		432D60BD0CB548DE00F15133 /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = 432D60BA0CB548DE00F15133 /* unzip.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		432D60BE0CB548DE00F15133 /* zip.h in Headers */ = {isa = PBXBuildFile; fileRef = 432D60BB0CB548DE00F15133 /* zip.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		432FACB90CC4F2D6004D5C1D /* ossimPlanetCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 432FACB80CC4F2D6004D5C1D /* ossimPlanetCallback.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		433A4CCA100CED8D000B969C /* ossim.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186EF4F60B1CE11D00F7886A /* ossim.framework */; };
+		433A4CCF100CED8D000B969C /* ossimPlanet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* ossimPlanet.framework */; };
+		433A4CF7100CEDD2000B969C /* ossimplanettest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433A4CF6100CEDD2000B969C /* ossimplanettest.cpp */; };
+		433E7EC20D32B9CF00BA05D0 /* ossimPlanetApi.h in Headers */ = {isa = PBXBuildFile; fileRef = 433E7EC10D32B9CF00BA05D0 /* ossimPlanetApi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		433E7EC80D32B9EC00BA05D0 /* ossimPlanetApi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 433E7EC70D32B9EC00BA05D0 /* ossimPlanetApi.cpp */; };
+		4345891C0FD3F95900046CB5 /* ossimPlanetAnimatedPointModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4345891B0FD3F95900046CB5 /* ossimPlanetAnimatedPointModel.cpp */; };
+		4345891E0FD3F96C00046CB5 /* ossimPlanetAnimatedPointModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4345891D0FD3F96C00046CB5 /* ossimPlanetAnimatedPointModel.h */; };
+		43463BC00FCF16DD0027D845 /* ossimPlanetAnimationPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 43463BBF0FCF16DD0027D845 /* ossimPlanetAnimationPath.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43463BD70FCF78850027D845 /* ossimPlanetAnimationPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43463BD60FCF78850027D845 /* ossimPlanetAnimationPath.cpp */; };
+		434E72B910DAACEE005EBB18 /* ossimPlanetOssimElevationDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 434E72B810DAACEE005EBB18 /* ossimPlanetOssimElevationDatabase.cpp */; };
+		434E72BC10DAAD15005EBB18 /* ossimPlanetOssimElevationDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 434E72BB10DAAD15005EBB18 /* ossimPlanetOssimElevationDatabase.h */; };
+		434EDC180D2BCA2600EDC08A /* ossimPlanetLayerRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 434EDC170D2BCA2600EDC08A /* ossimPlanetLayerRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		434EDC1A0D2BCC8000EDC08A /* ossimPlanetLayerFactoryBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 434EDC190D2BCC8000EDC08A /* ossimPlanetLayerFactoryBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		434EDC3C0D2BD04400EDC08A /* ossimPlanetLayerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 434EDC3B0D2BD04400EDC08A /* ossimPlanetLayerFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		434EDC400D2BD20500EDC08A /* ossimPlanetLayerRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 434EDC3E0D2BD20500EDC08A /* ossimPlanetLayerRegistry.cpp */; };
+		434EDC7C0D2BD8D200EDC08A /* ossimPlanetLayerFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 434EDC7A0D2BD8D200EDC08A /* ossimPlanetLayerFactory.cpp */; };
+		4351096E0FCC130A0065BA0E /* ossimPlanetViewMatrixBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4351096D0FCC130A0065BA0E /* ossimPlanetViewMatrixBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		435109740FCC134C0065BA0E /* ossimPlanetViewMatrixBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 435109730FCC134C0065BA0E /* ossimPlanetViewMatrixBuilder.cpp */; };
+		435BD1FC0F09848100CEAEAD /* ossimPlanetViewer.h in Headers */ = {isa = PBXBuildFile; fileRef = 435BD1FB0F09848100CEAEAD /* ossimPlanetViewer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43669A930CD177A400F1832B /* ossimPlanetSousaLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43669A920CD177A400F1832B /* ossimPlanetSousaLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43669A950CD177CD00F1832B /* ossimPlanetSousaLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43669A940CD177CD00F1832B /* ossimPlanetSousaLayer.cpp */; };
+		4377D4281029BB5800B6652D /* ossimPlanetCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4377D4271029BB5800B6652D /* ossimPlanetCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4377D42A1029BB7000B6652D /* ossimPlanetCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4377D4291029BB7000B6652D /* ossimPlanetCache.cpp */; };
+		4377D6F8102C509900B6652D /* ossimPlanetKmlNetworkLinkNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4377D6F7102C509900B6652D /* ossimPlanetKmlNetworkLinkNode.cpp */; };
+		4377D6FB102C50AD00B6652D /* ossimPlanetKmlNetworkLinkNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4377D6FA102C50AD00B6652D /* ossimPlanetKmlNetworkLinkNode.h */; };
+		437D9DE70FC3FFA60018F889 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 437D9DE60FC3FFA60018F889 /* OpenGL.framework */; };
+		43A113950D520D5D00DE3CF3 /* ossimPlanetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A113940D520D5D00DE3CF3 /* ossimPlanetNode.cpp */; };
+		43A113980D520D7100DE3CF3 /* ossimPlanetNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A113970D520D7100DE3CF3 /* ossimPlanetNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43A113DF0D520F3600DE3CF3 /* ossimPlanetNodeFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A113DC0D520F3600DE3CF3 /* ossimPlanetNodeFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43A113E00D520F3600DE3CF3 /* ossimPlanetNodeRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A113DD0D520F3600DE3CF3 /* ossimPlanetNodeRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43A113E10D520F3600DE3CF3 /* ossimPlanetNodeFactoryBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A113DE0D520F3600DE3CF3 /* ossimPlanetNodeFactoryBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43A113E70D520F8900DE3CF3 /* ossimPlanetNodeFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A113E50D520F8900DE3CF3 /* ossimPlanetNodeFactory.cpp */; };
+		43A113E80D520F8900DE3CF3 /* ossimPlanetNodeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A113E60D520F8900DE3CF3 /* ossimPlanetNodeRegistry.cpp */; };
+		43A52F150D4FA87100DB4777 /* ossimPlanetVisitors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A52F140D4FA87100DB4777 /* ossimPlanetVisitors.cpp */; };
+		43AA128F0D77ADF90020DF13 /* ossimPlanetXmlAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43AA128E0D77ADF90020DF13 /* ossimPlanetXmlAction.cpp */; };
+		43AB5F570FF9434D004874C2 /* ossim.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186EF4F60B1CE11D00F7886A /* ossim.framework */; };
+		43AB5FAF0FF99226004874C2 /* ossimPlanetEphemeris.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AB5FAE0FF99226004874C2 /* ossimPlanetEphemeris.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43AB5FB30FF99240004874C2 /* ossimPlanetEphemeris.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43AB5FB20FF99240004874C2 /* ossimPlanetEphemeris.cpp */; };
+		43BC2F8D0F8D13A600838B40 /* ossimPlanetTileRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BC2F8C0F8D13A600838B40 /* ossimPlanetTileRequest.cpp */; };
+		43BC2F8F0F8D13C600838B40 /* ossimPlanetTileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 43BC2F8E0F8D13C600838B40 /* ossimPlanetTileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43C443DE0D4A2179004BDD99 /* ossimPlanetOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C443DD0D4A2179004BDD99 /* ossimPlanetOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43C443E30D4A2C6D004BDD99 /* ossimPlanetOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C443E10D4A2C6D004BDD99 /* ossimPlanetOperation.cpp */; };
+		43C6E2B70FEFB50E004B52F7 /* ossimplanetklv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C6E2B60FEFB50E004B52F7 /* ossimplanetklv.cpp */; };
+		43C6E2C90FEFB531004B52F7 /* ossimplanetviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C6E2C30FEFB531004B52F7 /* ossimplanetviewer.cpp */; };
+		43C6E2CB0FEFB572004B52F7 /* ossimPredator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEB5ECF10D0F2284000CF6B2 /* ossimPredator.framework */; };
+		43C6E2CC0FEFB580004B52F7 /* ossimPlanet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* ossimPlanet.framework */; };
+		43C6E5660FF00474004B52F7 /* ossim.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 186EF4F60B1CE11D00F7886A /* ossim.framework */; };
+		43C8A82E0CAACB4E00EE840F /* ossimPlanetKmlPlacemarkNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C8A82D0CAACB4E00EE840F /* ossimPlanetKmlPlacemarkNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43C8A8320CAACB6500EE840F /* ossimPlanetKmlPlacemarkNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43C8A8310CAACB6500EE840F /* ossimPlanetKmlPlacemarkNode.cpp */; };
+		43CA034E0DD34451003EC1AB /* ossimPlanetArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CA034C0DD34451003EC1AB /* ossimPlanetArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43CA034F0DD34451003EC1AB /* ossimPlanetArchiveMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 43CA034D0DD34451003EC1AB /* ossimPlanetArchiveMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43CA03520DD34464003EC1AB /* ossimPlanetArchiveMapping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43CA03500DD34464003EC1AB /* ossimPlanetArchiveMapping.cpp */; };
+		43CA03530DD34464003EC1AB /* ossimPlanetArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43CA03510DD34464003EC1AB /* ossimPlanetArchive.cpp */; };
+		43D65A310F6839F1006C6786 /* ossimPlanetTerrainLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D65A300F6839F1006C6786 /* ossimPlanetTerrainLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43D65A530F683B15006C6786 /* ossimPlanetTerrainLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43D65A520F683B15006C6786 /* ossimPlanetTerrainLayer.cpp */; };
+		43D7ECB310FE1F8500762FA7 /* gpstk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D7ECB210FE1F8500762FA7 /* gpstk.framework */; };
+		43D8A1090D818E2200A60690 /* ossimPlanet.xsd in Resources */ = {isa = PBXBuildFile; fileRef = 43D8A1080D818E2200A60690 /* ossimPlanet.xsd */; };
+		43D9C7E010A4BBB900BA9119 /* ossimPlanetCacheTextureLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43D9C7DF10A4BBB900BA9119 /* ossimPlanetCacheTextureLayer.cpp */; };
+		43D9C7E510A4BC0F00BA9119 /* ossimPlanetCacheTextureLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D9C7E410A4BC0F00BA9119 /* ossimPlanetCacheTextureLayer.h */; };
+		43E957E00D2931C000D31E60 /* ossimPlanetRefBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 43E957DF0D2931C000D31E60 /* ossimPlanetRefBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43FDA2D70D770D0700945FA0 /* ossimPlanetDestinationCommandAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FDA2D60D770D0700945FA0 /* ossimPlanetDestinationCommandAction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43FDA2DA0D77274F00945FA0 /* ossimPlanetDestinationCommandAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43FDA2D90D77274F00945FA0 /* ossimPlanetDestinationCommandAction.cpp */; };
+		43FDA3D30D77495200945FA0 /* ossimPlanetXmlAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FDA3D20D77495200945FA0 /* ossimPlanetXmlAction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43FF0C201021065500CEA135 /* ossimPlanetCloudLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 43FF0C1F1021065500CEA135 /* ossimPlanetCloudLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		43FF0C261021068E00CEA135 /* ossimPlanetCloudLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43FF0C251021068E00CEA135 /* ossimPlanetCloudLayer.cpp */; };
+		8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
+		EE0517BC0EE81BB6009EC91D /* ossimPlanetViewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE0517BB0EE81BB6009EC91D /* ossimPlanetViewer.cpp */; };
+		EE26B23A0F39CB8400D4028C /* ossimPlanetElevationRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = EE26B2390F39CB8400D4028C /* ossimPlanetElevationRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE26B23D0F39CC0D00D4028C /* ossimPlanetElevationRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE26B23C0F39CC0D00D4028C /* ossimPlanetElevationRegistry.cpp */; };
+		EE26B2680F39DD1100D4028C /* ossimPlanetElevationFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE26B2670F39DD1100D4028C /* ossimPlanetElevationFactory.cpp */; };
+		EE26B26A0F39DD2000D4028C /* ossimPlanetElevationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = EE26B2690F39DD2000D4028C /* ossimPlanetElevationFactory.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE2F90FD0EB5E188003D424A /* ossimPlanetMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = EE2F90FC0EB5E188003D424A /* ossimPlanetMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE5403650F5D7030001139DD /* ossimPlanetTerrain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5403640F5D7030001139DD /* ossimPlanetTerrain.cpp */; };
+		EE5403670F5D7041001139DD /* ossimPlanetTerrain.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5403660F5D7041001139DD /* ossimPlanetTerrain.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE54036A0F5D74F5001139DD /* ossimPlanetTerrainTile.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5403690F5D74F5001139DD /* ossimPlanetTerrainTile.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE5403790F5D7522001139DD /* ossimPlanetTerrainTile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5403780F5D7522001139DD /* ossimPlanetTerrainTile.cpp */; };
+		EE5403EB0F5D8C42001139DD /* ossimPlanetGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5403EA0F5D8C42001139DD /* ossimPlanetGrid.cpp */; };
+		EE5403EE0F5D8C50001139DD /* ossimPlanetGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5403ED0F5D8C50001139DD /* ossimPlanetGrid.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE5403F10F5D8DDE001139DD /* ossimPlanetTerrainTileId.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5403F00F5D8DDE001139DD /* ossimPlanetTerrainTileId.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE5404550F5E21CF001139DD /* ossimPlanetTerrainTechnique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5404540F5E21CF001139DD /* ossimPlanetTerrainTechnique.cpp */; };
+		EE5404570F5E21DD001139DD /* ossimPlanetTerrainTechnique.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5404560F5E21DD001139DD /* ossimPlanetTerrainTechnique.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE54045A0F5E24D2001139DD /* ossimPlanetTerrainGeometryTechnique.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5404590F5E24D2001139DD /* ossimPlanetTerrainGeometryTechnique.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE5404660F5E24EC001139DD /* ossimPlanetTerrainGeometryTechnique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5404650F5E24EC001139DD /* ossimPlanetTerrainGeometryTechnique.cpp */; };
+		EE5409A10F615143001139DD /* ossimPlanetPointModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE5409A00F615143001139DD /* ossimPlanetPointModel.cpp */; };
+		EE5409A30F61516D001139DD /* ossimPlanetPointModel.h in Headers */ = {isa = PBXBuildFile; fileRef = EE5409A20F61516D001139DD /* ossimPlanetPointModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE540A8F0F61A503001139DD /* ossimPlanetGeoRefModel.h in Headers */ = {isa = PBXBuildFile; fileRef = EE540A8E0F61A503001139DD /* ossimPlanetGeoRefModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE69A3550B28842B00C91DD1 /* wms.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE69A3500B2883FA00C91DD1 /* wms.framework */; };
+		EE9B0A4D0F6463A500394285 /* ossimPlanetLsrSpaceTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9B0A4C0F6463A500394285 /* ossimPlanetLsrSpaceTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EE9B0A700F6463C400394285 /* ossimPlanetLsrSpaceTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE9B0A6F0F6463C400394285 /* ossimPlanetLsrSpaceTransform.cpp */; };
+		EEB5ECDA0D0F214E000CF6B2 /* ossimPlanetVideoLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = EEB5ECD80D0F214E000CF6B2 /* ossimPlanetVideoLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EEB5ECE50D0F220C000CF6B2 /* ossimPlanetVideoLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEB5ECE40D0F220C000CF6B2 /* ossimPlanetVideoLayer.cpp */; };
+		EEB5ECF20D0F2292000CF6B2 /* ossimPredator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEB5ECF10D0F2284000CF6B2 /* ossimPredator.framework */; };
+		EEB5EDDC0D101235000CF6B2 /* ossimPlanetPredatorVideoLayerNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEB5EDDB0D101235000CF6B2 /* ossimPlanetPredatorVideoLayerNode.cpp */; };
+		EEB5EDDE0D101268000CF6B2 /* ossimPlanetPredatorVideoLayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = EEB5EDDD0D101268000CF6B2 /* ossimPlanetPredatorVideoLayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EEBDD68E0D464823009DB3D5 /* ossimPlanetAnnotationLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBDD68D0D464823009DB3D5 /* ossimPlanetAnnotationLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EEBDD6920D465A0B009DB3D5 /* ossimPlanetAnnotationLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEBDD6900D465A0B009DB3D5 /* ossimPlanetAnnotationLayer.cpp */; };
+		EEBDD6CC0D46E214009DB3D5 /* ossimPlanetAnnotationLayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBDD6CB0D46E214009DB3D5 /* ossimPlanetAnnotationLayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EEBDD6CF0D46E3AC009DB3D5 /* ossimPlanetAnnotationLayerNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EEBDD6CE0D46E3AC009DB3D5 /* ossimPlanetAnnotationLayerNode.cpp */; };
+		EEBDDA7A0D491078009DB3D5 /* ossimPlanetVideoLayerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBDDA790D491078009DB3D5 /* ossimPlanetVideoLayerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EED173960CA0174100DF3588 /* ossimPlanetFadeText.h in Headers */ = {isa = PBXBuildFile; fileRef = EED173950CA0174100DF3588 /* ossimPlanetFadeText.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		EED173980CA0174E00DF3588 /* ossimPlanetFadeText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EED173970CA0174E00DF3588 /* ossimPlanetFadeText.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		186EF4F50B1CE11D00F7886A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 8D07F2C80486CC7A007CD1D0;
+			remoteInfo = ossim;
+		};
+		433A4CC6100CED8D000B969C /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = ossimPlanet;
+		};
+		435310B61044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628031042E368002A87C7;
+			remoteInfo = "template-app";
+		};
+		435310B81044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628151042E3B0002A87C7;
+			remoteInfo = "ossim-adrg-dump";
+		};
+		435310BA1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628371042E3F6002A87C7;
+			remoteInfo = "ossim-applanix2ogeom";
+		};
+		435310BC1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628551042E461002A87C7;
+			remoteInfo = "ossim-band-merge";
+		};
+		435310BE1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628741042E4AC002A87C7;
+			remoteInfo = "ossim-btoa";
+		};
+		435310C01044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628861042E4D1002A87C7;
+			remoteInfo = "ossim-chgkwval";
+		};
+		435310C21044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4336289F1042E52A002A87C7;
+			remoteInfo = "ossim-cmm";
+		};
+		435310C41044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628B91042E560002A87C7;
+			remoteInfo = "ossim-computeSrtmStats";
+		};
+		435310C61044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628D61042E59C002A87C7;
+			remoteInfo = "ossim-correl";
+		};
+		435310C81044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433628F11042E5D1002A87C7;
+			remoteInfo = "ossim-create-cg";
+		};
+		435310CA1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4336290B1042E607002A87C7;
+			remoteInfo = "ossim-create-histo";
+		};
+		435310D21044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433629811042E712002A87C7;
+			remoteInfo = "ossim-dms2deg";
+		};
+		435310D41044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4336299D1042E759002A87C7;
+			remoteInfo = "ossim-dump-ocg";
+		};
+		435310D61044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433629B51042E77C002A87C7;
+			remoteInfo = "ossim-ecg2ocg";
+		};
+		435310D81044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433629D01042E7B1002A87C7;
+			remoteInfo = "ossim-extract-vertices";
+		};
+		435310DA1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 433629E41042E807002A87C7;
+			remoteInfo = "ossim-foo";
+		};
+		435310DE1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362A2D1042E88F002A87C7;
+			remoteInfo = "ossim-height";
+		};
+		435310E01044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362A4B1042E8BD002A87C7;
+			remoteInfo = "ossim-icp";
+		};
+		435310E21044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362A631042E8EE002A87C7;
+			remoteInfo = "ossim-igen";
+		};
+		435310E41044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362A7D1042E914002A87C7;
+			remoteInfo = "ossim-img2md";
+		};
+		435310E61044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362A9A1042E955002A87C7;
+			remoteInfo = "ossim-img2rr";
+		};
+		435310E81044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362AB41042E981002A87C7;
+			remoteInfo = "ossim-info";
+		};
+		435310EA1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362AD21042EA43002A87C7;
+			remoteInfo = "ossim-modopt";
+		};
+		435310EC1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362AEF1042EA81002A87C7;
+			remoteInfo = "ossim-mosaic";
+		};
+		435310F21044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362B471042EB45002A87C7;
+			remoteInfo = "ossim-ogeom2ogeom";
+		};
+		435310F41044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362B641042EB70002A87C7;
+			remoteInfo = "ossim-orthoigen";
+		};
+		435310F61044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362B801042EB9B002A87C7;
+			remoteInfo = "ossim-pixelflip";
+		};
+		435310F81044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362B9B1042EBCE002A87C7;
+			remoteInfo = "ossim-prune";
+		};
+		435310FC1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362BD21042EC26002A87C7;
+			remoteInfo = "ossim-rejout";
+		};
+		435310FE1044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362BEE1042EC50002A87C7;
+			remoteInfo = "ossim-senint";
+		};
+		435311001044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362C081042EC80002A87C7;
+			remoteInfo = "ossim-space-imaging";
+		};
+		435311021044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362C221042ECAF002A87C7;
+			remoteInfo = "ossim-swapbytes";
+		};
+		435311041044384C004A4474 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 43362C3C1042ECD6002A87C7;
+			remoteInfo = "ossim-tfw2ogeom";
+		};
+		437A55AC0E789BB8000D89D5 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 1FD5B7C80E75D3DC00FBD730;
+			remoteInfo = wmsurl;
+		};
+		437A55AE0E789BB8000D89D5 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 1FD5B7EA0E75D46700FBD730;
+			remoteInfo = wmscapabilities.cpp;
+		};
+		437A55B00E789BB8000D89D5 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 1FD5B7FE0E75D4C500FBD730;
+			remoteInfo = wmsgetmap;
+		};
+		43AB5F2A0FF94015004874C2 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = ossimPlanet;
+		};
+		43DFCC070FF0F4E000FB2061 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 43C6E2900FEFB4D8004B52F7;
+			remoteInfo = ossimplanetklv;
+		};
+		43DFCC090FF0F4E000FB2061 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 43C6E29B0FEFB4E9004B52F7;
+			remoteInfo = ossimplanetviewer;
+		};
+		EE69A34F0B2883FA00C91DD1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 8DC2EF5B0486A6940098B216;
+			remoteInfo = wms;
+		};
+		EE9D26600DD8891C005A8951 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = ossimPlanet;
+		};
+		EEB5ECF00D0F2284000CF6B2 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EEB5ECEC0D0F2284000CF6B2 /* ossimPredator.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = EE3F868B0D0DBB2300DFD3DF;
+			remoteInfo = ossimPredator;
+		};
+		EEB5EE590D103A4A000CF6B2 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EEB5ECEC0D0F2284000CF6B2 /* ossimPredator.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = ossimPredator;
+		};
+		EEB5EE5B0D103A57000CF6B2 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = ossim;
+		};
+		EEB5EE5D0D103A68000CF6B2 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
+			remoteInfo = wms;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = common_settings.xcconfig; path = ../../../ossim/xcode/ossim/common_settings.xcconfig; sourceTree = SOURCE_ROOT; };
+		186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ossim.xcodeproj; path = ../../../ossim/xcode/ossim/ossim.xcodeproj; sourceTree = SOURCE_ROOT; };
+		430485FD0F3CB80800B9C1E2 /* ossimPlanetDatabasePager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetDatabasePager.h; sourceTree = "<group>"; };
+		4306ABAA10FE11A700C7202A /* osg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osg.framework; path = ../../../ossim_dependencies/Frameworks/osg.framework; sourceTree = SOURCE_ROOT; };
+		4306ABAC10FE11AC00C7202A /* osgGA.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osgGA.framework; path = ../../../ossim_dependencies/Frameworks/osgGA.framework; sourceTree = SOURCE_ROOT; };
+		4306ABAE10FE11C000C7202A /* osgDB.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osgDB.framework; path = ../../../ossim_dependencies/Frameworks/osgDB.framework; sourceTree = SOURCE_ROOT; };
+		4306ABAF10FE11C000C7202A /* osgText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osgText.framework; path = ../../../ossim_dependencies/Frameworks/osgText.framework; sourceTree = SOURCE_ROOT; };
+		4306ABB010FE11C000C7202A /* osgUtil.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osgUtil.framework; path = ../../../ossim_dependencies/Frameworks/osgUtil.framework; sourceTree = SOURCE_ROOT; };
+		4306ABB110FE11C000C7202A /* osgViewer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = osgViewer.framework; path = ../../../ossim_dependencies/Frameworks/osgViewer.framework; sourceTree = SOURCE_ROOT; };
+		430C8F660CBBD0B8002BAF12 /* ossimPlanetCompass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetCompass.cpp; sourceTree = "<group>"; };
+		430C8F680CBBD0CA002BAF12 /* ossimPlanetCompass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCompass.h; sourceTree = "<group>"; };
+		430D8E901100DA3F00EB0F96 /* ossimPlanetDepthPartitionNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetDepthPartitionNode.h; sourceTree = "<group>"; };
+		430D8E931100DA5200EB0F96 /* ossimPlanetDistanceAccumulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetDistanceAccumulator.h; sourceTree = "<group>"; };
+		430D8E971100DB1F00EB0F96 /* ossimPlanetDepthPartitionNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetDepthPartitionNode.cpp; sourceTree = "<group>"; };
+		430D8E981100DB1F00EB0F96 /* ossimPlanetDistanceAccumulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetDistanceAccumulator.cpp; sourceTree = "<group>"; };
+		4314728E0CBE9F0F00EAADAB /* ossimPlanetVisitors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetVisitors.h; sourceTree = "<group>"; };
+		431476540CA838310090B3CE /* ossimPlanetKmlScreenOverlayNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKmlScreenOverlayNode.cpp; sourceTree = "<group>"; };
+		431476560CA838400090B3CE /* ossimPlanetKmlScreenOverlayNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlScreenOverlayNode.h; sourceTree = "<group>"; };
+		4315BDBF0C9717B400D36F21 /* ossimPlanetDtedElevationDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetDtedElevationDatabase.cpp; sourceTree = "<group>"; };
+		4315BDC10C9717B400D36F21 /* ossimPlanetCubeGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetCubeGrid.cpp; sourceTree = "<group>"; };
+		4315BDC20C9717B400D36F21 /* ossimPlanetWmsImageLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetWmsImageLayer.cpp; sourceTree = "<group>"; };
+		4315BDC30C9717B400D36F21 /* ossimPlanetUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetUtility.cpp; sourceTree = "<group>"; };
+		4315BDC40C9717B400D36F21 /* ossimPlanetThreadPool.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetThreadPool.cpp; sourceTree = "<group>"; };
+		4315BDC50C9717B400D36F21 /* ossimPlanetThreadImp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetThreadImp.cpp; sourceTree = "<group>"; };
+		4315BDC60C9717B400D36F21 /* ossimPlanetThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetThread.cpp; sourceTree = "<group>"; };
+		4315BDC70C9717B400D36F21 /* ossimPlanetTextureLayerRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTextureLayerRegistry.cpp; sourceTree = "<group>"; };
+		4315BDC80C9717B400D36F21 /* ossimPlanetTextureLayerGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTextureLayerGroup.cpp; sourceTree = "<group>"; };
+		4315BDC90C9717B400D36F21 /* ossimPlanetTextureLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTextureLayer.cpp; sourceTree = "<group>"; };
+		4315BDCA0C9717B400D36F21 /* ossimPlanetStandardTextureLayerFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetStandardTextureLayerFactory.cpp; sourceTree = "<group>"; };
+		4315BDCB0C9717B400D36F21 /* ossimPlanetSocketNetworkConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetSocketNetworkConnection.cpp; sourceTree = "<group>"; };
+		4315BDCC0C9717B400D36F21 /* ossimPlanetShaderProgramSetup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetShaderProgramSetup.cpp; sourceTree = "<group>"; };
+		4315BDCD0C9717B400D36F21 /* ossimPlanetServerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetServerThread.cpp; sourceTree = "<group>"; };
+		4315BDCE0C9717B400D36F21 /* ossimPlanetSceneView.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetSceneView.cpp; sourceTree = "<group>"; };
+		4315BDCF0C9717B400D36F21 /* ossimPlanetPlaneGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetPlaneGrid.cpp; sourceTree = "<group>"; };
+		4315BDD00C9717B400D36F21 /* ossimPlanetPagedLandLod.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetPagedLandLod.cpp; sourceTree = "<group>"; };
+		4315BDD10C9717B400D36F21 /* ossimPlanetOssimImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetOssimImage.cpp; sourceTree = "<group>"; };
+		4315BDD20C9717B400D36F21 /* ossimPlanetManipulator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetManipulator.cpp; sourceTree = "<group>"; };
+		4315BDD30C9717B400D36F21 /* ossimPlanetNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetNavigator.cpp; sourceTree = "<group>"; };
+		4315BDD50C9717B400D36F21 /* ossimPlanetLookAt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLookAt.cpp; sourceTree = "<group>"; };
+		4315BDD60C9717B400D36F21 /* ossimPlanetLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLayer.cpp; sourceTree = "<group>"; };
+		4315BDD70C9717B400D36F21 /* ossimPlanetLatLonHud.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLatLonHud.cpp; sourceTree = "<group>"; };
+		4315BDD80C9717B400D36F21 /* ulError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ulError.cpp; sourceTree = "<group>"; };
+		4315BDD90C9717B400D36F21 /* ulClock.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ulClock.cpp; sourceTree = "<group>"; };
+		4315BDDA0C9717B400D36F21 /* sg_socket_udp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sg_socket_udp.cpp; sourceTree = "<group>"; };
+		4315BDDB0C9717B400D36F21 /* ossimPlanetYahooGeocoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetYahooGeocoder.cpp; sourceTree = "<group>"; };
+		4315BDDC0C9717B400D36F21 /* ossimPlanetWmsClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetWmsClient.cpp; sourceTree = "<group>"; };
+		4315BDDD0C9717B400D36F21 /* ossimPlanetIoThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIoThread.cpp; sourceTree = "<group>"; };
+		4315BDDE0C9717B400D36F21 /* ossimPlanetIoSocketServerChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIoSocketServerChannel.cpp; sourceTree = "<group>"; };
+		4315BDDF0C9717B400D36F21 /* ossimPlanetIoSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIoSocket.cpp; sourceTree = "<group>"; };
+		4315BDE00C9717B400D36F21 /* ossimPlanetIoRoutableMessageHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIoRoutableMessageHandler.cpp; sourceTree = "<group>"; };
+		4315BDE10C9717B400D36F21 /* ossimPlanetInteractionController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetInteractionController.cpp; sourceTree = "<group>"; };
+		4315BDE20C9717B400D36F21 /* ossimPlanetImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetImage.cpp; sourceTree = "<group>"; };
+		4315BDE30C9717B400D36F21 /* ossimPlanetIdManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIdManager.cpp; sourceTree = "<group>"; };
+		4315BDE40C9717B400D36F21 /* ossimPlanetClientThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetClientThread.cpp; sourceTree = "<group>"; };
+		4315BDE50C9717B400D36F21 /* ossimPlanetBoundingBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetBoundingBox.cpp; sourceTree = "<group>"; };
+		4315BDE60C9717B400D36F21 /* ossimPlanetBillboardIcon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetBillboardIcon.cpp; sourceTree = "<group>"; };
+		4315BDE70C9717B400D36F21 /* ossimPlanetKmlLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKmlLayer.cpp; sourceTree = "<group>"; };
+		4315BDE90C9717B400D36F21 /* ossimPlanetKml.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKml.cpp; sourceTree = "<group>"; };
+		4315BDEA0C9717B400D36F21 /* ossimPlanetJpegImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetJpegImage.cpp; sourceTree = "<group>"; };
+		4315BDEB0C9717B400D36F21 /* ossimPlanet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanet.cpp; sourceTree = "<group>"; };
+		4315BDEC0C9717B400D36F21 /* netSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netSocket.cpp; sourceTree = "<group>"; };
+		4315BDED0C9717B400D36F21 /* netMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netMonitor.cpp; sourceTree = "<group>"; };
+		4315BDEE0C9717B400D36F21 /* netMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netMessage.cpp; sourceTree = "<group>"; };
+		4315BDEF0C9717B400D36F21 /* netChat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netChat.cpp; sourceTree = "<group>"; };
+		4315BDF00C9717B400D36F21 /* netChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netChannel.cpp; sourceTree = "<group>"; };
+		4315BDF10C9717B400D36F21 /* netBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = netBuffer.cpp; sourceTree = "<group>"; };
+		4315BDF20C9717B400D36F21 /* mkUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = mkUtils.cpp; sourceTree = "<group>"; };
+		4315BDF30C9717B400D36F21 /* iochannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = iochannel.cpp; sourceTree = "<group>"; };
+		4315BDF40C9717B400D36F21 /* ossimPlanetGeocoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetGeocoder.cpp; sourceTree = "<group>"; };
+		4315BDF60C9717B400D36F21 /* ossimPlanetActionRouter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetActionRouter.cpp; sourceTree = "<group>"; };
+		4315BDF70C9717B400D36F21 /* ossimPlanetActionReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetActionReceiver.cpp; sourceTree = "<group>"; };
+		4315BDF80C9717B400D36F21 /* ossimPlanetAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetAction.cpp; sourceTree = "<group>"; };
+		4315BDF90C9717B400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetGeneralRasterElevationDatabase.cpp; sourceTree = "<group>"; };
+		4315BDFA0C9717B400D36F21 /* ossimPlanetElevationGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetElevationGrid.cpp; sourceTree = "<group>"; };
+		4315BDFB0C9717B400D36F21 /* ulLinkedList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ulLinkedList.cpp; sourceTree = "<group>"; };
+		4315BDFC0C9717B400D36F21 /* ossimPlanetLandCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLandCache.cpp; sourceTree = "<group>"; };
+		4315BDFD0C9717B400D36F21 /* ossimPlanetLand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLand.cpp; sourceTree = "<group>"; };
+		4315BDFE0C9717B400D36F21 /* ossimPlanetKmlLayerNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKmlLayerNode.cpp; sourceTree = "<group>"; };
+		4315BDFF0C9717B400D36F21 /* sg_file.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sg_file.cpp; sourceTree = "<group>"; };
+		4315BE000C9717B400D36F21 /* ossimPlanetTexture2D.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTexture2D.cpp; sourceTree = "<group>"; };
+		4315BE010C9717B400D36F21 /* ossimPlanetSrtmElevationDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetSrtmElevationDatabase.cpp; sourceTree = "<group>"; };
+		4315BE020C9717B400D36F21 /* ossimPlanetId.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetId.cpp; sourceTree = "<group>"; };
+		4315BE030C9717B400D36F21 /* ossimPlanetIconGeom.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetIconGeom.cpp; sourceTree = "<group>"; };
+		4315BE050C9717B400D36F21 /* ossimPlanetGridUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetGridUtility.cpp; sourceTree = "<group>"; };
+		4315BE060C9717B400D36F21 /* ulRTTI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ulRTTI.cpp; sourceTree = "<group>"; };
+		4315BE070C9717B400D36F21 /* sg_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = sg_socket.cpp; sourceTree = "<group>"; };
+		4315BE080C9717B400D36F21 /* ossimPlanetOssimImageLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetOssimImageLayer.cpp; sourceTree = "<group>"; };
+		4315BE090C9717B400D36F21 /* ul.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ul.cpp; sourceTree = "<group>"; };
+		4315BE0A0C9717B400D36F21 /* ulList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ulList.cpp; sourceTree = "<group>"; };
+		4315BE0B0C9717B400D36F21 /* ossimPlanetLandReaderWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLandReaderWriter.cpp; sourceTree = "<group>"; };
+		4315BE0C0C9717B400D36F21 /* ossimPlanetLandCullCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLandCullCallback.cpp; sourceTree = "<group>"; };
+		4315BE0D0C9717B400D36F21 /* ossimPlanetElevationDatabaseGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetElevationDatabaseGroup.cpp; sourceTree = "<group>"; };
+		4315BE0E0C9717B400D36F21 /* ossimPlanetElevationDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetElevationDatabase.cpp; sourceTree = "<group>"; };
+		4315BE5F0C9717E400D36F21 /* ossimPlanetLandTreeNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandTreeNode.h; sourceTree = "<group>"; };
+		4315BE600C9717E400D36F21 /* ossimPlanetLandNormalType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandNormalType.h; sourceTree = "<group>"; };
+		4315BE610C9717E400D36F21 /* ossimPlanetKmlLayerNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlLayerNode.h; sourceTree = "<group>"; };
+		4315BE620C9717E400D36F21 /* netBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netBuffer.h; sourceTree = "<group>"; };
+		4315BE630C9717E400D36F21 /* ossimPlanetLand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLand.h; sourceTree = "<group>"; };
+		4315BE640C9717E400D36F21 /* ossimPlanetBillboardIcon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetBillboardIcon.h; sourceTree = "<group>"; };
+		4315BE660C9717E400D36F21 /* ossimPlanetElevationDatabaseGroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetElevationDatabaseGroup.h; sourceTree = "<group>"; };
+		4315BE670C9717E400D36F21 /* ossimPlanetIdolLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIdolLayer.h; sourceTree = "<group>"; };
+		4315BE690C9717E400D36F21 /* ossimPlanetIdManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIdManager.h; sourceTree = "<group>"; };
+		4315BE6A0C9717E400D36F21 /* ossimPlanetLandReaderWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandReaderWriter.h; sourceTree = "<group>"; };
+		4315BE6B0C9717E400D36F21 /* ossimPlanetUtility.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetUtility.h; sourceTree = "<group>"; };
+		4315BE6C0C9717E400D36F21 /* ossimPlanetThreadPool.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetThreadPool.h; sourceTree = "<group>"; };
+		4315BE6D0C9717E400D36F21 /* ossimPlanetPlaneGrid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPlaneGrid.h; sourceTree = "<group>"; };
+		4315BE6E0C9717E400D36F21 /* ossimPlanetPagedRequestNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPagedRequestNode.h; sourceTree = "<group>"; };
+		4315BE6F0C9717E400D36F21 /* ossimPlanetPagedLandLodRefreshType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPagedLandLodRefreshType.h; sourceTree = "<group>"; };
+		4315BE700C9717E400D36F21 /* ossimPlanetLandNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandNode.h; sourceTree = "<group>"; };
+		4315BE710C9717E400D36F21 /* ossimPlanetIoSocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIoSocket.h; sourceTree = "<group>"; };
+		4315BE720C9717E400D36F21 /* ossimPlanetInteractionController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetInteractionController.h; sourceTree = "<group>"; };
+		4315BE730C9717E400D36F21 /* ulLocal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ulLocal.h; sourceTree = "<group>"; };
+		4315BE740C9717E400D36F21 /* ul.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ul.h; sourceTree = "<group>"; };
+		4315BE750C9717E400D36F21 /* ossimPlanetInputDevice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetInputDevice.h; sourceTree = "<group>"; };
+		4315BE760C9717E400D36F21 /* ossimPlanetShaderProgramSetup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetShaderProgramSetup.h; sourceTree = "<group>"; };
+		4315BE770C9717E400D36F21 /* ossimPlanetSetup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetSetup.h; sourceTree = "<group>"; };
+		4315BE780C9717E400D36F21 /* ossimPlanetBoundingBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetBoundingBox.h; sourceTree = "<group>"; };
+		4315BE790C9717E400D36F21 /* ossimPlanetIoSocketServerChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIoSocketServerChannel.h; sourceTree = "<group>"; };
+		4315BE7A0C9717E400D36F21 /* ossimPlanetPrimaryBody.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPrimaryBody.h; sourceTree = "<group>"; };
+		4315BE7B0C9717E400D36F21 /* ossimPlanetSocketNetworkConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetSocketNetworkConnection.h; sourceTree = "<group>"; };
+		4315BE7C0C9717E400D36F21 /* iochannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = iochannel.h; sourceTree = "<group>"; };
+		4315BE7D0C9717E400D36F21 /* ossimPlanetIconGeom.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIconGeom.h; sourceTree = "<group>"; };
+		4315BE7E0C9717E400D36F21 /* ossimPlanetTextureLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTextureLayer.h; sourceTree = "<group>"; };
+		4315BE7F0C9717E400D36F21 /* ossimPlanetTexture2D.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTexture2D.h; sourceTree = "<group>"; };
+		4315BE800C9717E400D36F21 /* ossimPlanetAction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetAction.h; sourceTree = "<group>"; };
+		4315BE810C9717E400D36F21 /* ossimPlanetServerMessageHandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetServerMessageHandler.h; sourceTree = "<group>"; };
+		4315BE820C9717E400D36F21 /* ossimPlanetSceneView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetSceneView.h; sourceTree = "<group>"; };
+		4315BE830C9717E400D36F21 /* ossimPlanetManipulator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetManipulator.h; sourceTree = "<group>"; };
+		4315BE840C9717E400D36F21 /* ossimPlanetWmsImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetWmsImageLayer.h; sourceTree = "<group>"; };
+		4315BE850C9717E400D36F21 /* ossimPlanetThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetThread.h; sourceTree = "<group>"; };
+		4315BE860C9717E400D36F21 /* ossimPlanetTextureLayerRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTextureLayerRegistry.h; sourceTree = "<group>"; };
+		4315BE870C9717E400D36F21 /* netChat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netChat.h; sourceTree = "<group>"; };
+		4315BE880C9717E400D36F21 /* ossimPlanetTextureLayerGroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTextureLayerGroup.h; sourceTree = "<group>"; };
+		4315BE890C9717E400D36F21 /* ossimPlanetTextureLayerFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTextureLayerFactory.h; sourceTree = "<group>"; };
+		4315BE8A0C9717E400D36F21 /* ossimPlanetOssimImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetOssimImage.h; sourceTree = "<group>"; };
+		4315BE8B0C9717E400D36F21 /* ossimPlanetOrthoFlatLandNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetOrthoFlatLandNode.h; sourceTree = "<group>"; };
+		4315BE8C0C9717E400D36F21 /* ossimPlanetServerThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetServerThread.h; sourceTree = "<group>"; };
+		4315BE8D0C9717E400D36F21 /* ossimPlanetIoThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIoThread.h; sourceTree = "<group>"; };
+		4315BE8E0C9717E400D36F21 /* ossimPlanet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanet.h; sourceTree = "<group>"; };
+		4315BE8F0C9717E400D36F21 /* ossimPlanetOssimImageLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetOssimImageLayer.h; sourceTree = "<group>"; };
+		4315BE900C9717E400D36F21 /* ossimPlanetThreadImp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetThreadImp.h; sourceTree = "<group>"; };
+		4315BE920C9717E400D36F21 /* ossimPlanetLandTextureRequest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandTextureRequest.h; sourceTree = "<group>"; };
+		4315BE930C9717E400D36F21 /* ossimPlanetLandCullCallback.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandCullCallback.h; sourceTree = "<group>"; };
+		4315BE940C9717E400D36F21 /* ossimPlanetConstants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetConstants.h; sourceTree = "<group>"; };
+		4315BE950C9717E400D36F21 /* ossimPlanetNetworkConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNetworkConnection.h; sourceTree = "<group>"; };
+		4315BE960C9717E400D36F21 /* ossimPlanetKml.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKml.h; sourceTree = "<group>"; };
+		4315BE980C9717E400D36F21 /* ossimPlanetExport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetExport.h; sourceTree = "<group>"; };
+		4315BE990C9717E400D36F21 /* netMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netMessage.h; sourceTree = "<group>"; };
+		4315BE9A0C9717E400D36F21 /* ossimPlanetIo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIo.h; sourceTree = "<group>"; };
+		4315BE9B0C9717E400D36F21 /* ossimPlanetJpegImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetJpegImage.h; sourceTree = "<group>"; };
+		4315BE9C0C9717E400D36F21 /* ossimPlanetLookAt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLookAt.h; sourceTree = "<group>"; };
+		4315BE9F0C9717E400D36F21 /* net.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = net.h; sourceTree = "<group>"; };
+		4315BEA00C9717E400D36F21 /* ulRTTI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ulRTTI.h; sourceTree = "<group>"; };
+		4315BEA10C9717E400D36F21 /* netChannel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netChannel.h; sourceTree = "<group>"; };
+		4315BEA20C9717E400D36F21 /* ossimPlanetElevationGrid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetElevationGrid.h; sourceTree = "<group>"; };
+		4315BEA30C9717E400D36F21 /* ossimPlanetIntersectUserData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIntersectUserData.h; sourceTree = "<group>"; };
+		4315BEA40C9717E400D36F21 /* ossimPlanetLabelGeom.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLabelGeom.h; sourceTree = "<group>"; };
+		4315BEA50C9717E400D36F21 /* ossimPlanetGeocoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetGeocoder.h; sourceTree = "<group>"; };
+		4315BEA60C9717E400D36F21 /* ossimPlanetLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLayer.h; sourceTree = "<group>"; };
+		4315BEA70C9717E400D36F21 /* netMonitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netMonitor.h; sourceTree = "<group>"; };
+		4315BEA80C9717E400D36F21 /* ossimPlanetId.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetId.h; sourceTree = "<group>"; };
+		4315BEAA0C9717E400D36F21 /* ossimPlanetActionRouter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetActionRouter.h; sourceTree = "<group>"; };
+		4315BEAB0C9717E400D36F21 /* ossimPlanetSrtmElevationDatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetSrtmElevationDatabase.h; sourceTree = "<group>"; };
+		4315BEAC0C9717E400D36F21 /* ossimPlanetStandardTextureLayerFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetStandardTextureLayerFactory.h; sourceTree = "<group>"; };
+		4315BEAD0C9717E400D36F21 /* ossimPlanetActionReceiver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetActionReceiver.h; sourceTree = "<group>"; };
+		4315BEAE0C9717E400D36F21 /* sg_file.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sg_file.h; sourceTree = "<group>"; };
+		4315BEAF0C9717E400D36F21 /* ossimPlanetYahooGeocoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetYahooGeocoder.h; sourceTree = "<group>"; };
+		4315BEB00C9717E400D36F21 /* ossimPlanetIoMessageHandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIoMessageHandler.h; sourceTree = "<group>"; };
+		4315BEB10C9717E400D36F21 /* ossimPlanetElevationDatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetElevationDatabase.h; sourceTree = "<group>"; };
+		4315BEB20C9717E400D36F21 /* compiler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = compiler.h; sourceTree = "<group>"; };
+		4315BEB30C9717E400D36F21 /* ossimPlanetLandCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLandCache.h; sourceTree = "<group>"; };
+		4315BEB40C9717E400D36F21 /* ossimPlanetExtents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetExtents.h; sourceTree = "<group>"; };
+		4315BEB50C9717E400D36F21 /* ossimPlanetKmlReaderWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlReaderWriter.h; sourceTree = "<group>"; };
+		4315BEB60C9717E400D36F21 /* ossimPlanetDtedElevationDatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetDtedElevationDatabase.h; sourceTree = "<group>"; };
+		4315BEB70C9717E400D36F21 /* ossimPlanetNavigator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNavigator.h; sourceTree = "<group>"; };
+		4315BEB80C9717E400D36F21 /* ossimPlanetImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetImage.h; sourceTree = "<group>"; };
+		4315BEB90C9717E400D36F21 /* sg_socket_udp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sg_socket_udp.h; sourceTree = "<group>"; };
+		4315BEBA0C9717E400D36F21 /* sg_socket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sg_socket.h; sourceTree = "<group>"; };
+		4315BEBB0C9717E400D36F21 /* ossimPlanetCubeGrid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCubeGrid.h; sourceTree = "<group>"; };
+		4315BEBC0C9717E400D36F21 /* ossimPlanetIdolBridge.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIdolBridge.h; sourceTree = "<group>"; };
+		4315BEBE0C9717E400D36F21 /* mkUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mkUtils.h; sourceTree = "<group>"; };
+		4315BEBF0C9717E400D36F21 /* ossimPlanetLatLonHud.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLatLonHud.h; sourceTree = "<group>"; };
+		4315BEC00C9717E400D36F21 /* ossimPlanetClientThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetClientThread.h; sourceTree = "<group>"; };
+		4315BEC10C9717E400D36F21 /* ossimPlanetIoRoutableMessageHandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetIoRoutableMessageHandler.h; sourceTree = "<group>"; };
+		4315BEC20C9717E400D36F21 /* ossimPlanetPagedLandLod.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPagedLandLod.h; sourceTree = "<group>"; };
+		4315BEC30C9717E400D36F21 /* ossimPlanetWmsClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetWmsClient.h; sourceTree = "<group>"; };
+		4315BEC40C9717E400D36F21 /* netSocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = netSocket.h; sourceTree = "<group>"; };
+		4315BEC50C9717E400D36F21 /* ossimPlanetKmlLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlLayer.h; sourceTree = "<group>"; };
+		4315BEC60C9717E400D36F21 /* ossimPlanetGridUtility.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetGridUtility.h; sourceTree = "<group>"; };
+		4315BEC70C9717E400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetGeneralRasterElevationDatabase.h; sourceTree = "<group>"; };
+		43244C820F742D70002F5FA3 /* ossimPlanetReentrantMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetReentrantMutex.h; sourceTree = "<group>"; };
+		432933BA10FE531E00C66EB8 /* OpenThreads.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenThreads.framework; path = ../../../ossim_dependencies/Frameworks/OpenThreads.framework; sourceTree = SOURCE_ROOT; };
+		432D60B30CB548C800F15133 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; };
+		432D60B40CB548C800F15133 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = "<group>"; };
+		432D60B50CB548C800F15133 /* zip.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = "<group>"; };
+		432D60B90CB548DE00F15133 /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = "<group>"; };
+		432D60BA0CB548DE00F15133 /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
+		432D60BB0CB548DE00F15133 /* zip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = "<group>"; };
+		432FACB80CC4F2D6004D5C1D /* ossimPlanetCallback.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCallback.h; sourceTree = "<group>"; };
+		433A4CD8100CED8D000B969C /* ossimplanettest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ossimplanettest; sourceTree = BUILT_PRODUCTS_DIR; };
+		433A4CF6100CEDD2000B969C /* ossimplanettest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimplanettest.cpp; sourceTree = "<group>"; };
+		433E7EC10D32B9CF00BA05D0 /* ossimPlanetApi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetApi.h; sourceTree = "<group>"; };
+		433E7EC70D32B9EC00BA05D0 /* ossimPlanetApi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetApi.cpp; sourceTree = "<group>"; };
+		4345891B0FD3F95900046CB5 /* ossimPlanetAnimatedPointModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetAnimatedPointModel.cpp; sourceTree = "<group>"; };
+		4345891D0FD3F96C00046CB5 /* ossimPlanetAnimatedPointModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetAnimatedPointModel.h; sourceTree = "<group>"; };
+		43463BBF0FCF16DD0027D845 /* ossimPlanetAnimationPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetAnimationPath.h; sourceTree = "<group>"; };
+		43463BD60FCF78850027D845 /* ossimPlanetAnimationPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetAnimationPath.cpp; sourceTree = "<group>"; };
+		434E72B810DAACEE005EBB18 /* ossimPlanetOssimElevationDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetOssimElevationDatabase.cpp; sourceTree = "<group>"; };
+		434E72BB10DAAD15005EBB18 /* ossimPlanetOssimElevationDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetOssimElevationDatabase.h; sourceTree = "<group>"; };
+		434EDC170D2BCA2600EDC08A /* ossimPlanetLayerRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLayerRegistry.h; sourceTree = "<group>"; };
+		434EDC190D2BCC8000EDC08A /* ossimPlanetLayerFactoryBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLayerFactoryBase.h; sourceTree = "<group>"; };
+		434EDC3B0D2BD04400EDC08A /* ossimPlanetLayerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLayerFactory.h; sourceTree = "<group>"; };
+		434EDC3E0D2BD20500EDC08A /* ossimPlanetLayerRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLayerRegistry.cpp; sourceTree = "<group>"; };
+		434EDC7A0D2BD8D200EDC08A /* ossimPlanetLayerFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLayerFactory.cpp; sourceTree = "<group>"; };
+		4351096D0FCC130A0065BA0E /* ossimPlanetViewMatrixBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetViewMatrixBuilder.h; sourceTree = "<group>"; };
+		435109730FCC134C0065BA0E /* ossimPlanetViewMatrixBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ossimPlanetViewMatrixBuilder.cpp; path = ../../src/ossimPlanet/ossimPlanetViewMatrixBuilder.cpp; sourceTree = SOURCE_ROOT; };
+		435BD1FB0F09848100CEAEAD /* ossimPlanetViewer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetViewer.h; sourceTree = "<group>"; };
+		43669A920CD177A400F1832B /* ossimPlanetSousaLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetSousaLayer.h; sourceTree = "<group>"; };
+		43669A940CD177CD00F1832B /* ossimPlanetSousaLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetSousaLayer.cpp; sourceTree = "<group>"; };
+		4377D4271029BB5800B6652D /* ossimPlanetCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCache.h; sourceTree = "<group>"; };
+		4377D4291029BB7000B6652D /* ossimPlanetCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetCache.cpp; sourceTree = "<group>"; };
+		4377D6F7102C509900B6652D /* ossimPlanetKmlNetworkLinkNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKmlNetworkLinkNode.cpp; sourceTree = "<group>"; };
+		4377D6FA102C50AD00B6652D /* ossimPlanetKmlNetworkLinkNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlNetworkLinkNode.h; sourceTree = "<group>"; };
+		437D9DE60FC3FFA60018F889 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
+		43A113940D520D5D00DE3CF3 /* ossimPlanetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetNode.cpp; sourceTree = "<group>"; };
+		43A113970D520D7100DE3CF3 /* ossimPlanetNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNode.h; sourceTree = "<group>"; };
+		43A113DC0D520F3600DE3CF3 /* ossimPlanetNodeFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNodeFactory.h; sourceTree = "<group>"; };
+		43A113DD0D520F3600DE3CF3 /* ossimPlanetNodeRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNodeRegistry.h; sourceTree = "<group>"; };
+		43A113DE0D520F3600DE3CF3 /* ossimPlanetNodeFactoryBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetNodeFactoryBase.h; sourceTree = "<group>"; };
+		43A113E50D520F8900DE3CF3 /* ossimPlanetNodeFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetNodeFactory.cpp; sourceTree = "<group>"; };
+		43A113E60D520F8900DE3CF3 /* ossimPlanetNodeRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetNodeRegistry.cpp; sourceTree = "<group>"; };
+		43A52F140D4FA87100DB4777 /* ossimPlanetVisitors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetVisitors.cpp; sourceTree = "<group>"; };
+		43AA128E0D77ADF90020DF13 /* ossimPlanetXmlAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetXmlAction.cpp; sourceTree = "<group>"; };
+		43AB5FAE0FF99226004874C2 /* ossimPlanetEphemeris.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetEphemeris.h; sourceTree = "<group>"; };
+		43AB5FB20FF99240004874C2 /* ossimPlanetEphemeris.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetEphemeris.cpp; sourceTree = "<group>"; };
+		43BC2F8C0F8D13A600838B40 /* ossimPlanetTileRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTileRequest.cpp; sourceTree = "<group>"; };
+		43BC2F8E0F8D13C600838B40 /* ossimPlanetTileRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTileRequest.h; sourceTree = "<group>"; };
+		43C443DD0D4A2179004BDD99 /* ossimPlanetOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetOperation.h; sourceTree = "<group>"; };
+		43C443E10D4A2C6D004BDD99 /* ossimPlanetOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetOperation.cpp; sourceTree = "<group>"; };
+		43C6E2910FEFB4D8004B52F7 /* ossimplanetklv */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ossimplanetklv; sourceTree = BUILT_PRODUCTS_DIR; };
+		43C6E29C0FEFB4E9004B52F7 /* ossimplanetviewer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ossimplanetviewer; sourceTree = BUILT_PRODUCTS_DIR; };
+		43C6E2B60FEFB50E004B52F7 /* ossimplanetklv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimplanetklv.cpp; sourceTree = "<group>"; };
+		43C6E2C30FEFB531004B52F7 /* ossimplanetviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimplanetviewer.cpp; sourceTree = "<group>"; };
+		43C6E2C50FEFB531004B52F7 /* readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = readme.txt; sourceTree = "<group>"; };
+		43C8A82D0CAACB4E00EE840F /* ossimPlanetKmlPlacemarkNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetKmlPlacemarkNode.h; sourceTree = "<group>"; };
+		43C8A8310CAACB6500EE840F /* ossimPlanetKmlPlacemarkNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetKmlPlacemarkNode.cpp; sourceTree = "<group>"; };
+		43CA034C0DD34451003EC1AB /* ossimPlanetArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetArchive.h; sourceTree = "<group>"; };
+		43CA034D0DD34451003EC1AB /* ossimPlanetArchiveMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetArchiveMapping.h; sourceTree = "<group>"; };
+		43CA03500DD34464003EC1AB /* ossimPlanetArchiveMapping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetArchiveMapping.cpp; sourceTree = "<group>"; };
+		43CA03510DD34464003EC1AB /* ossimPlanetArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetArchive.cpp; sourceTree = "<group>"; };
+		43D65A300F6839F1006C6786 /* ossimPlanetTerrainLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrainLayer.h; sourceTree = "<group>"; };
+		43D65A520F683B15006C6786 /* ossimPlanetTerrainLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTerrainLayer.cpp; sourceTree = "<group>"; };
+		43D7ECB210FE1F8500762FA7 /* gpstk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = gpstk.framework; path = ../../../ossim_dependencies/Frameworks/gpstk.framework; sourceTree = SOURCE_ROOT; };
+		43D8A1080D818E2200A60690 /* ossimPlanet.xsd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = ossimPlanet.xsd; path = ../../schema/ossimPlanet.xsd; sourceTree = SOURCE_ROOT; };
+		43D8A1120D818ED300A60690 /* binds.act */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = binds.act; path = ../../binds.act; sourceTree = SOURCE_ROOT; };
+		43D9C7DF10A4BBB900BA9119 /* ossimPlanetCacheTextureLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetCacheTextureLayer.cpp; sourceTree = "<group>"; };
+		43D9C7E410A4BC0F00BA9119 /* ossimPlanetCacheTextureLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCacheTextureLayer.h; sourceTree = "<group>"; };
+		43E957DF0D2931C000D31E60 /* ossimPlanetRefBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetRefBlock.h; sourceTree = "<group>"; };
+		43FDA2D60D770D0700945FA0 /* ossimPlanetDestinationCommandAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetDestinationCommandAction.h; sourceTree = "<group>"; };
+		43FDA2D90D77274F00945FA0 /* ossimPlanetDestinationCommandAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetDestinationCommandAction.cpp; sourceTree = "<group>"; };
+		43FDA3D20D77495200945FA0 /* ossimPlanetXmlAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetXmlAction.h; sourceTree = "<group>"; };
+		43FF0C1F1021065500CEA135 /* ossimPlanetCloudLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetCloudLayer.h; sourceTree = "<group>"; };
+		43FF0C251021068E00CEA135 /* ossimPlanetCloudLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetCloudLayer.cpp; sourceTree = "<group>"; };
+		8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D07F2C80486CC7A007CD1D0 /* ossimPlanet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ossimPlanet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		EE0517BB0EE81BB6009EC91D /* ossimPlanetViewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetViewer.cpp; sourceTree = "<group>"; };
+		EE26B2390F39CB8400D4028C /* ossimPlanetElevationRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetElevationRegistry.h; sourceTree = "<group>"; };
+		EE26B23C0F39CC0D00D4028C /* ossimPlanetElevationRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetElevationRegistry.cpp; sourceTree = "<group>"; };
+		EE26B2670F39DD1100D4028C /* ossimPlanetElevationFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetElevationFactory.cpp; sourceTree = "<group>"; };
+		EE26B2690F39DD2000D4028C /* ossimPlanetElevationFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetElevationFactory.h; sourceTree = "<group>"; };
+		EE2F90FC0EB5E188003D424A /* ossimPlanetMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetMessage.h; sourceTree = "<group>"; };
+		EE5403640F5D7030001139DD /* ossimPlanetTerrain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTerrain.cpp; sourceTree = "<group>"; };
+		EE5403660F5D7041001139DD /* ossimPlanetTerrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrain.h; sourceTree = "<group>"; };
+		EE5403690F5D74F5001139DD /* ossimPlanetTerrainTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrainTile.h; sourceTree = "<group>"; };
+		EE5403780F5D7522001139DD /* ossimPlanetTerrainTile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTerrainTile.cpp; sourceTree = "<group>"; };
+		EE5403EA0F5D8C42001139DD /* ossimPlanetGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetGrid.cpp; sourceTree = "<group>"; };
+		EE5403ED0F5D8C50001139DD /* ossimPlanetGrid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetGrid.h; sourceTree = "<group>"; };
+		EE5403F00F5D8DDE001139DD /* ossimPlanetTerrainTileId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrainTileId.h; sourceTree = "<group>"; };
+		EE5404540F5E21CF001139DD /* ossimPlanetTerrainTechnique.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTerrainTechnique.cpp; sourceTree = "<group>"; };
+		EE5404560F5E21DD001139DD /* ossimPlanetTerrainTechnique.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrainTechnique.h; sourceTree = "<group>"; };
+		EE5404590F5E24D2001139DD /* ossimPlanetTerrainGeometryTechnique.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetTerrainGeometryTechnique.h; sourceTree = "<group>"; };
+		EE5404650F5E24EC001139DD /* ossimPlanetTerrainGeometryTechnique.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetTerrainGeometryTechnique.cpp; sourceTree = "<group>"; };
+		EE5409A00F615143001139DD /* ossimPlanetPointModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetPointModel.cpp; sourceTree = "<group>"; };
+		EE5409A20F61516D001139DD /* ossimPlanetPointModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPointModel.h; sourceTree = "<group>"; };
+		EE540A8E0F61A503001139DD /* ossimPlanetGeoRefModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetGeoRefModel.h; sourceTree = "<group>"; };
+		EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libwms.xcodeproj; path = ../../../libwms/xcode/libwms/libwms.xcodeproj; sourceTree = SOURCE_ROOT; };
+		EE9B0A4C0F6463A500394285 /* ossimPlanetLsrSpaceTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetLsrSpaceTransform.h; sourceTree = "<group>"; };
+		EE9B0A6F0F6463C400394285 /* ossimPlanetLsrSpaceTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetLsrSpaceTransform.cpp; sourceTree = "<group>"; };
+		EEB5ECD80D0F214E000CF6B2 /* ossimPlanetVideoLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetVideoLayer.h; sourceTree = "<group>"; };
+		EEB5ECE40D0F220C000CF6B2 /* ossimPlanetVideoLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetVideoLayer.cpp; sourceTree = "<group>"; };
+		EEB5ECEC0D0F2284000CF6B2 /* ossimPredator.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ossimPredator.xcodeproj; path = ../../../ossimPredator/xcode/ossimPredator/ossimPredator.xcodeproj; sourceTree = SOURCE_ROOT; };
+		EEB5EDDB0D101235000CF6B2 /* ossimPlanetPredatorVideoLayerNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetPredatorVideoLayerNode.cpp; sourceTree = "<group>"; };
+		EEB5EDDD0D101268000CF6B2 /* ossimPlanetPredatorVideoLayerNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetPredatorVideoLayerNode.h; sourceTree = "<group>"; };
+		EEBDD68D0D464823009DB3D5 /* ossimPlanetAnnotationLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetAnnotationLayer.h; sourceTree = "<group>"; };
+		EEBDD6900D465A0B009DB3D5 /* ossimPlanetAnnotationLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetAnnotationLayer.cpp; sourceTree = "<group>"; };
+		EEBDD6CB0D46E214009DB3D5 /* ossimPlanetAnnotationLayerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetAnnotationLayerNode.h; sourceTree = "<group>"; };
+		EEBDD6CE0D46E3AC009DB3D5 /* ossimPlanetAnnotationLayerNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetAnnotationLayerNode.cpp; sourceTree = "<group>"; };
+		EEBDDA790D491078009DB3D5 /* ossimPlanetVideoLayerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ossimPlanetVideoLayerNode.h; sourceTree = "<group>"; };
+		EED173950CA0174100DF3588 /* ossimPlanetFadeText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ossimPlanetFadeText.h; sourceTree = "<group>"; };
+		EED173970CA0174E00DF3588 /* ossimPlanetFadeText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ossimPlanetFadeText.cpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		433A4CC9100CED8D000B969C /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4329352F10FE591500C66EB8 /* osgText.framework in Frameworks */,
+				4329351A10FE57FA00C66EB8 /* OpenThreads.framework in Frameworks */,
+				4329351B10FE57FA00C66EB8 /* osgDB.framework in Frameworks */,
+				4329351C10FE57FA00C66EB8 /* osgUtil.framework in Frameworks */,
+				4329351D10FE57FA00C66EB8 /* osgViewer.framework in Frameworks */,
+				4329351E10FE57FA00C66EB8 /* osgGA.framework in Frameworks */,
+				4329351F10FE57FA00C66EB8 /* osg.framework in Frameworks */,
+				433A4CCA100CED8D000B969C /* ossim.framework in Frameworks */,
+				433A4CCF100CED8D000B969C /* ossimPlanet.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		43C6E28F0FEFB4D8004B52F7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				432933E410FE579100C66EB8 /* osg.framework in Frameworks */,
+				432933E110FE577D00C66EB8 /* OpenThreads.framework in Frameworks */,
+				43AB5F570FF9434D004874C2 /* ossim.framework in Frameworks */,
+				43C6E2CB0FEFB572004B52F7 /* ossimPredator.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		43C6E29A0FEFB4E9004B52F7 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				432934CA10FE57D600C66EB8 /* osgDB.framework in Frameworks */,
+				432934C510FE57C800C66EB8 /* OpenThreads.framework in Frameworks */,
+				432934C210FE57AF00C66EB8 /* osg.framework in Frameworks */,
+				432934AB10FE57AC00C66EB8 /* osgGA.framework in Frameworks */,
+				4329349110FE57A200C66EB8 /* osgViewer.framework in Frameworks */,
+				43C6E5660FF00474004B52F7 /* ossim.framework in Frameworks */,
+				43C6E2CC0FEFB580004B52F7 /* ossimPlanet.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D07F2C30486CC7A007CD1D0 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				EEB5ECF20D0F2292000CF6B2 /* ossimPredator.framework in Frameworks */,
+				EE69A3550B28842B00C91DD1 /* wms.framework in Frameworks */,
+				186EF5700B1CE22D00F7886A /* ossim.framework in Frameworks */,
+				437D9DE70FC3FFA60018F889 /* OpenGL.framework in Frameworks */,
+				4306ABAB10FE11A700C7202A /* osg.framework in Frameworks */,
+				4306ABAD10FE11AC00C7202A /* osgGA.framework in Frameworks */,
+				4306ABB210FE11C000C7202A /* osgDB.framework in Frameworks */,
+				4306ABB310FE11C000C7202A /* osgText.framework in Frameworks */,
+				4306ABB410FE11C000C7202A /* osgUtil.framework in Frameworks */,
+				4306ABB510FE11C000C7202A /* osgViewer.framework in Frameworks */,
+				43D7ECB310FE1F8500762FA7 /* gpstk.framework in Frameworks */,
+				432933BB10FE531E00C66EB8 /* OpenThreads.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		034768DDFF38A45A11DB9C8B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D07F2C80486CC7A007CD1D0 /* ossimPlanet.framework */,
+				43C6E2910FEFB4D8004B52F7 /* ossimplanetklv */,
+				43C6E29C0FEFB4E9004B52F7 /* ossimplanetviewer */,
+				433A4CD8100CED8D000B969C /* ossimplanettest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		0867D691FE84028FC02AAC07 /* ossimPlanet */ = {
+			isa = PBXGroup;
+			children = (
+				EE9D25F30DD87952005A8951 /* apps */,
+				43D8A10D0D818EC100A60690 /* Sample files */,
+				43D8A1060D818DFD00A60690 /* schema */,
+				08FB77ACFE841707C02AAC07 /* Source */,
+				089C1665FE841158C02AAC07 /* Resources */,
+				1862497F0B2070A20021FDF7 /* External Projects */,
+				437D9ACC0FC3FE810018F889 /* External Frameworks and Libraries */,
+				034768DDFF38A45A11DB9C8B /* Products */,
+			);
+			name = ossimPlanet;
+			sourceTree = "<group>";
+		};
+		089C1665FE841158C02AAC07 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				8D07F2C70486CC7A007CD1D0 /* Info.plist */,
+				089C1666FE841158C02AAC07 /* InfoPlist.strings */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		08FB77ACFE841707C02AAC07 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */,
+				186EECB10B1CDF1400F7886A /* ossimPlanet */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		1862497F0B2070A20021FDF7 /* External Projects */ = {
+			isa = PBXGroup;
+			children = (
+				186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */,
+				EEB5ECEC0D0F2284000CF6B2 /* ossimPredator.xcodeproj */,
+				EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */,
+			);
+			name = "External Projects";
+			sourceTree = "<group>";
+		};
+		186EECB10B1CDF1400F7886A /* ossimPlanet */ = {
+			isa = PBXGroup;
+			children = (
+				186EECB20B1CDF1400F7886A /* include */,
+				186EECF10B1CDF1400F7886A /* src */,
+			);
+			name = ossimPlanet;
+			path = ../..;
+			sourceTree = SOURCE_ROOT;
+		};
+		186EECB20B1CDF1400F7886A /* include */ = {
+			isa = PBXGroup;
+			children = (
+				186EECB30B1CDF1400F7886A /* ossimPlanet */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		186EECB30B1CDF1400F7886A /* ossimPlanet */ = {
+			isa = PBXGroup;
+			children = (
+				430D8E931100DA5200EB0F96 /* ossimPlanetDistanceAccumulator.h */,
+				430D8E901100DA3F00EB0F96 /* ossimPlanetDepthPartitionNode.h */,
+				434E72BB10DAAD15005EBB18 /* ossimPlanetOssimElevationDatabase.h */,
+				43D9C7E410A4BC0F00BA9119 /* ossimPlanetCacheTextureLayer.h */,
+				4377D6FA102C50AD00B6652D /* ossimPlanetKmlNetworkLinkNode.h */,
+				4377D4271029BB5800B6652D /* ossimPlanetCache.h */,
+				43FF0C1F1021065500CEA135 /* ossimPlanetCloudLayer.h */,
+				43AB5FAE0FF99226004874C2 /* ossimPlanetEphemeris.h */,
+				4345891D0FD3F96C00046CB5 /* ossimPlanetAnimatedPointModel.h */,
+				43463BBF0FCF16DD0027D845 /* ossimPlanetAnimationPath.h */,
+				435109730FCC134C0065BA0E /* ossimPlanetViewMatrixBuilder.cpp */,
+				4351096D0FCC130A0065BA0E /* ossimPlanetViewMatrixBuilder.h */,
+				43BC2F8E0F8D13C600838B40 /* ossimPlanetTileRequest.h */,
+				43244C820F742D70002F5FA3 /* ossimPlanetReentrantMutex.h */,
+				43D65A300F6839F1006C6786 /* ossimPlanetTerrainLayer.h */,
+				EE9B0A4C0F6463A500394285 /* ossimPlanetLsrSpaceTransform.h */,
+				EE540A8E0F61A503001139DD /* ossimPlanetGeoRefModel.h */,
+				EE5409A20F61516D001139DD /* ossimPlanetPointModel.h */,
+				EE5404590F5E24D2001139DD /* ossimPlanetTerrainGeometryTechnique.h */,
+				EE5404560F5E21DD001139DD /* ossimPlanetTerrainTechnique.h */,
+				EE5403F00F5D8DDE001139DD /* ossimPlanetTerrainTileId.h */,
+				EE5403ED0F5D8C50001139DD /* ossimPlanetGrid.h */,
+				EE5403690F5D74F5001139DD /* ossimPlanetTerrainTile.h */,
+				EE5403660F5D7041001139DD /* ossimPlanetTerrain.h */,
+				430485FD0F3CB80800B9C1E2 /* ossimPlanetDatabasePager.h */,
+				EE26B2690F39DD2000D4028C /* ossimPlanetElevationFactory.h */,
+				EE26B2390F39CB8400D4028C /* ossimPlanetElevationRegistry.h */,
+				435BD1FB0F09848100CEAEAD /* ossimPlanetViewer.h */,
+				EE2F90FC0EB5E188003D424A /* ossimPlanetMessage.h */,
+				43CA034C0DD34451003EC1AB /* ossimPlanetArchive.h */,
+				43CA034D0DD34451003EC1AB /* ossimPlanetArchiveMapping.h */,
+				43A113DC0D520F3600DE3CF3 /* ossimPlanetNodeFactory.h */,
+				43A113DD0D520F3600DE3CF3 /* ossimPlanetNodeRegistry.h */,
+				43A113DE0D520F3600DE3CF3 /* ossimPlanetNodeFactoryBase.h */,
+				43A113970D520D7100DE3CF3 /* ossimPlanetNode.h */,
+				43C443DD0D4A2179004BDD99 /* ossimPlanetOperation.h */,
+				EEBDDA790D491078009DB3D5 /* ossimPlanetVideoLayerNode.h */,
+				EEBDD6CB0D46E214009DB3D5 /* ossimPlanetAnnotationLayerNode.h */,
+				EEBDD68D0D464823009DB3D5 /* ossimPlanetAnnotationLayer.h */,
+				433E7EC10D32B9CF00BA05D0 /* ossimPlanetApi.h */,
+				434EDC3B0D2BD04400EDC08A /* ossimPlanetLayerFactory.h */,
+				434EDC190D2BCC8000EDC08A /* ossimPlanetLayerFactoryBase.h */,
+				434EDC170D2BCA2600EDC08A /* ossimPlanetLayerRegistry.h */,
+				43E957DF0D2931C000D31E60 /* ossimPlanetRefBlock.h */,
+				EEB5EDDD0D101268000CF6B2 /* ossimPlanetPredatorVideoLayerNode.h */,
+				EEB5ECD80D0F214E000CF6B2 /* ossimPlanetVideoLayer.h */,
+				43669A920CD177A400F1832B /* ossimPlanetSousaLayer.h */,
+				432FACB80CC4F2D6004D5C1D /* ossimPlanetCallback.h */,
+				4314728E0CBE9F0F00EAADAB /* ossimPlanetVisitors.h */,
+				430C8F680CBBD0CA002BAF12 /* ossimPlanetCompass.h */,
+				432D60B90CB548DE00F15133 /* ioapi.h */,
+				432D60BA0CB548DE00F15133 /* unzip.h */,
+				432D60BB0CB548DE00F15133 /* zip.h */,
+				43C8A82D0CAACB4E00EE840F /* ossimPlanetKmlPlacemarkNode.h */,
+				431476560CA838400090B3CE /* ossimPlanetKmlScreenOverlayNode.h */,
+				EED173950CA0174100DF3588 /* ossimPlanetFadeText.h */,
+				4315BE5F0C9717E400D36F21 /* ossimPlanetLandTreeNode.h */,
+				4315BE600C9717E400D36F21 /* ossimPlanetLandNormalType.h */,
+				4315BE610C9717E400D36F21 /* ossimPlanetKmlLayerNode.h */,
+				4315BE620C9717E400D36F21 /* netBuffer.h */,
+				4315BE630C9717E400D36F21 /* ossimPlanetLand.h */,
+				4315BE640C9717E400D36F21 /* ossimPlanetBillboardIcon.h */,
+				4315BE660C9717E400D36F21 /* ossimPlanetElevationDatabaseGroup.h */,
+				4315BE670C9717E400D36F21 /* ossimPlanetIdolLayer.h */,
+				4315BE690C9717E400D36F21 /* ossimPlanetIdManager.h */,
+				4315BE6A0C9717E400D36F21 /* ossimPlanetLandReaderWriter.h */,
+				4315BE6B0C9717E400D36F21 /* ossimPlanetUtility.h */,
+				4315BE6C0C9717E400D36F21 /* ossimPlanetThreadPool.h */,
+				4315BE6D0C9717E400D36F21 /* ossimPlanetPlaneGrid.h */,
+				4315BE6E0C9717E400D36F21 /* ossimPlanetPagedRequestNode.h */,
+				4315BE6F0C9717E400D36F21 /* ossimPlanetPagedLandLodRefreshType.h */,
+				4315BE700C9717E400D36F21 /* ossimPlanetLandNode.h */,
+				4315BE710C9717E400D36F21 /* ossimPlanetIoSocket.h */,
+				4315BE720C9717E400D36F21 /* ossimPlanetInteractionController.h */,
+				4315BE730C9717E400D36F21 /* ulLocal.h */,
+				4315BE740C9717E400D36F21 /* ul.h */,
+				4315BE750C9717E400D36F21 /* ossimPlanetInputDevice.h */,
+				4315BE760C9717E400D36F21 /* ossimPlanetShaderProgramSetup.h */,
+				4315BE770C9717E400D36F21 /* ossimPlanetSetup.h */,
+				4315BE780C9717E400D36F21 /* ossimPlanetBoundingBox.h */,
+				4315BE8F0C9717E400D36F21 /* ossimPlanetOssimImageLayer.h */,
+				4315BE790C9717E400D36F21 /* ossimPlanetIoSocketServerChannel.h */,
+				4315BE7A0C9717E400D36F21 /* ossimPlanetPrimaryBody.h */,
+				4315BE7B0C9717E400D36F21 /* ossimPlanetSocketNetworkConnection.h */,
+				4315BE7C0C9717E400D36F21 /* iochannel.h */,
+				4315BE7D0C9717E400D36F21 /* ossimPlanetIconGeom.h */,
+				4315BE7E0C9717E400D36F21 /* ossimPlanetTextureLayer.h */,
+				4315BE7F0C9717E400D36F21 /* ossimPlanetTexture2D.h */,
+				4315BE800C9717E400D36F21 /* ossimPlanetAction.h */,
+				4315BE810C9717E400D36F21 /* ossimPlanetServerMessageHandler.h */,
+				4315BE820C9717E400D36F21 /* ossimPlanetSceneView.h */,
+				4315BE830C9717E400D36F21 /* ossimPlanetManipulator.h */,
+				4315BE840C9717E400D36F21 /* ossimPlanetWmsImageLayer.h */,
+				4315BE850C9717E400D36F21 /* ossimPlanetThread.h */,
+				4315BE860C9717E400D36F21 /* ossimPlanetTextureLayerRegistry.h */,
+				4315BE870C9717E400D36F21 /* netChat.h */,
+				4315BE880C9717E400D36F21 /* ossimPlanetTextureLayerGroup.h */,
+				4315BE890C9717E400D36F21 /* ossimPlanetTextureLayerFactory.h */,
+				4315BE8A0C9717E400D36F21 /* ossimPlanetOssimImage.h */,
+				4315BE8B0C9717E400D36F21 /* ossimPlanetOrthoFlatLandNode.h */,
+				4315BE8C0C9717E400D36F21 /* ossimPlanetServerThread.h */,
+				4315BE8D0C9717E400D36F21 /* ossimPlanetIoThread.h */,
+				4315BE8E0C9717E400D36F21 /* ossimPlanet.h */,
+				4315BE900C9717E400D36F21 /* ossimPlanetThreadImp.h */,
+				4315BE920C9717E400D36F21 /* ossimPlanetLandTextureRequest.h */,
+				4315BE930C9717E400D36F21 /* ossimPlanetLandCullCallback.h */,
+				4315BE940C9717E400D36F21 /* ossimPlanetConstants.h */,
+				4315BE950C9717E400D36F21 /* ossimPlanetNetworkConnection.h */,
+				4315BE960C9717E400D36F21 /* ossimPlanetKml.h */,
+				4315BE980C9717E400D36F21 /* ossimPlanetExport.h */,
+				4315BE990C9717E400D36F21 /* netMessage.h */,
+				4315BE9A0C9717E400D36F21 /* ossimPlanetIo.h */,
+				4315BE9B0C9717E400D36F21 /* ossimPlanetJpegImage.h */,
+				4315BE9C0C9717E400D36F21 /* ossimPlanetLookAt.h */,
+				4315BE9F0C9717E400D36F21 /* net.h */,
+				4315BEA00C9717E400D36F21 /* ulRTTI.h */,
+				4315BEA10C9717E400D36F21 /* netChannel.h */,
+				4315BEA20C9717E400D36F21 /* ossimPlanetElevationGrid.h */,
+				4315BEA30C9717E400D36F21 /* ossimPlanetIntersectUserData.h */,
+				4315BEA40C9717E400D36F21 /* ossimPlanetLabelGeom.h */,
+				4315BEA50C9717E400D36F21 /* ossimPlanetGeocoder.h */,
+				4315BEA60C9717E400D36F21 /* ossimPlanetLayer.h */,
+				4315BEA70C9717E400D36F21 /* netMonitor.h */,
+				4315BEA80C9717E400D36F21 /* ossimPlanetId.h */,
+				4315BEAA0C9717E400D36F21 /* ossimPlanetActionRouter.h */,
+				4315BEAB0C9717E400D36F21 /* ossimPlanetSrtmElevationDatabase.h */,
+				4315BEAC0C9717E400D36F21 /* ossimPlanetStandardTextureLayerFactory.h */,
+				4315BEAD0C9717E400D36F21 /* ossimPlanetActionReceiver.h */,
+				4315BEAE0C9717E400D36F21 /* sg_file.h */,
+				4315BEAF0C9717E400D36F21 /* ossimPlanetYahooGeocoder.h */,
+				4315BEB00C9717E400D36F21 /* ossimPlanetIoMessageHandler.h */,
+				4315BEB10C9717E400D36F21 /* ossimPlanetElevationDatabase.h */,
+				4315BEB20C9717E400D36F21 /* compiler.h */,
+				4315BEB30C9717E400D36F21 /* ossimPlanetLandCache.h */,
+				4315BEB40C9717E400D36F21 /* ossimPlanetExtents.h */,
+				4315BEB50C9717E400D36F21 /* ossimPlanetKmlReaderWriter.h */,
+				4315BEB60C9717E400D36F21 /* ossimPlanetDtedElevationDatabase.h */,
+				4315BEB70C9717E400D36F21 /* ossimPlanetNavigator.h */,
+				4315BEB80C9717E400D36F21 /* ossimPlanetImage.h */,
+				4315BEB90C9717E400D36F21 /* sg_socket_udp.h */,
+				4315BEBA0C9717E400D36F21 /* sg_socket.h */,
+				4315BEBB0C9717E400D36F21 /* ossimPlanetCubeGrid.h */,
+				4315BEBC0C9717E400D36F21 /* ossimPlanetIdolBridge.h */,
+				4315BEBE0C9717E400D36F21 /* mkUtils.h */,
+				4315BEBF0C9717E400D36F21 /* ossimPlanetLatLonHud.h */,
+				4315BEC00C9717E400D36F21 /* ossimPlanetClientThread.h */,
+				4315BEC10C9717E400D36F21 /* ossimPlanetIoRoutableMessageHandler.h */,
+				4315BEC20C9717E400D36F21 /* ossimPlanetPagedLandLod.h */,
+				4315BEC30C9717E400D36F21 /* ossimPlanetWmsClient.h */,
+				4315BEC40C9717E400D36F21 /* netSocket.h */,
+				4315BEC50C9717E400D36F21 /* ossimPlanetKmlLayer.h */,
+				4315BEC60C9717E400D36F21 /* ossimPlanetGridUtility.h */,
+				4315BEC70C9717E400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.h */,
+				43FDA2D60D770D0700945FA0 /* ossimPlanetDestinationCommandAction.h */,
+				43FDA3D20D77495200945FA0 /* ossimPlanetXmlAction.h */,
+			);
+			path = ossimPlanet;
+			sourceTree = "<group>";
+		};
+		186EECF10B1CDF1400F7886A /* src */ = {
+			isa = PBXGroup;
+			children = (
+				186EECF20B1CDF1400F7886A /* ossimPlanet */,
+			);
+			path = src;
+			sourceTree = "<group>";
+		};
+		186EECF20B1CDF1400F7886A /* ossimPlanet */ = {
+			isa = PBXGroup;
+			children = (
+				430D8E971100DB1F00EB0F96 /* ossimPlanetDepthPartitionNode.cpp */,
+				430D8E981100DB1F00EB0F96 /* ossimPlanetDistanceAccumulator.cpp */,
+				434E72B810DAACEE005EBB18 /* ossimPlanetOssimElevationDatabase.cpp */,
+				43D9C7DF10A4BBB900BA9119 /* ossimPlanetCacheTextureLayer.cpp */,
+				4377D6F7102C509900B6652D /* ossimPlanetKmlNetworkLinkNode.cpp */,
+				4377D4291029BB7000B6652D /* ossimPlanetCache.cpp */,
+				43FF0C251021068E00CEA135 /* ossimPlanetCloudLayer.cpp */,
+				43AB5FB20FF99240004874C2 /* ossimPlanetEphemeris.cpp */,
+				4345891B0FD3F95900046CB5 /* ossimPlanetAnimatedPointModel.cpp */,
+				43463BD60FCF78850027D845 /* ossimPlanetAnimationPath.cpp */,
+				43BC2F8C0F8D13A600838B40 /* ossimPlanetTileRequest.cpp */,
+				43D65A520F683B15006C6786 /* ossimPlanetTerrainLayer.cpp */,
+				EE9B0A6F0F6463C400394285 /* ossimPlanetLsrSpaceTransform.cpp */,
+				EE5409A00F615143001139DD /* ossimPlanetPointModel.cpp */,
+				EE5404650F5E24EC001139DD /* ossimPlanetTerrainGeometryTechnique.cpp */,
+				EE5404540F5E21CF001139DD /* ossimPlanetTerrainTechnique.cpp */,
+				EE5403EA0F5D8C42001139DD /* ossimPlanetGrid.cpp */,
+				EE5403780F5D7522001139DD /* ossimPlanetTerrainTile.cpp */,
+				EE5403640F5D7030001139DD /* ossimPlanetTerrain.cpp */,
+				EE26B2670F39DD1100D4028C /* ossimPlanetElevationFactory.cpp */,
+				EE26B23C0F39CC0D00D4028C /* ossimPlanetElevationRegistry.cpp */,
+				EE0517BB0EE81BB6009EC91D /* ossimPlanetViewer.cpp */,
+				43CA03500DD34464003EC1AB /* ossimPlanetArchiveMapping.cpp */,
+				43CA03510DD34464003EC1AB /* ossimPlanetArchive.cpp */,
+				43A113E50D520F8900DE3CF3 /* ossimPlanetNodeFactory.cpp */,
+				43A113E60D520F8900DE3CF3 /* ossimPlanetNodeRegistry.cpp */,
+				43A113940D520D5D00DE3CF3 /* ossimPlanetNode.cpp */,
+				43A52F140D4FA87100DB4777 /* ossimPlanetVisitors.cpp */,
+				43C443E10D4A2C6D004BDD99 /* ossimPlanetOperation.cpp */,
+				EEBDD6CE0D46E3AC009DB3D5 /* ossimPlanetAnnotationLayerNode.cpp */,
+				EEBDD6900D465A0B009DB3D5 /* ossimPlanetAnnotationLayer.cpp */,
+				433E7EC70D32B9EC00BA05D0 /* ossimPlanetApi.cpp */,
+				434EDC7A0D2BD8D200EDC08A /* ossimPlanetLayerFactory.cpp */,
+				434EDC3E0D2BD20500EDC08A /* ossimPlanetLayerRegistry.cpp */,
+				EEB5EDDB0D101235000CF6B2 /* ossimPlanetPredatorVideoLayerNode.cpp */,
+				EEB5ECE40D0F220C000CF6B2 /* ossimPlanetVideoLayer.cpp */,
+				43669A940CD177CD00F1832B /* ossimPlanetSousaLayer.cpp */,
+				430C8F660CBBD0B8002BAF12 /* ossimPlanetCompass.cpp */,
+				432D60B30CB548C800F15133 /* ioapi.c */,
+				432D60B40CB548C800F15133 /* unzip.c */,
+				432D60B50CB548C800F15133 /* zip.c */,
+				43C8A8310CAACB6500EE840F /* ossimPlanetKmlPlacemarkNode.cpp */,
+				431476540CA838310090B3CE /* ossimPlanetKmlScreenOverlayNode.cpp */,
+				EED173970CA0174E00DF3588 /* ossimPlanetFadeText.cpp */,
+				4315BDBF0C9717B400D36F21 /* ossimPlanetDtedElevationDatabase.cpp */,
+				4315BDC10C9717B400D36F21 /* ossimPlanetCubeGrid.cpp */,
+				4315BDC20C9717B400D36F21 /* ossimPlanetWmsImageLayer.cpp */,
+				4315BDC30C9717B400D36F21 /* ossimPlanetUtility.cpp */,
+				4315BDC40C9717B400D36F21 /* ossimPlanetThreadPool.cpp */,
+				4315BDC50C9717B400D36F21 /* ossimPlanetThreadImp.cpp */,
+				4315BDC60C9717B400D36F21 /* ossimPlanetThread.cpp */,
+				4315BDC70C9717B400D36F21 /* ossimPlanetTextureLayerRegistry.cpp */,
+				4315BDC80C9717B400D36F21 /* ossimPlanetTextureLayerGroup.cpp */,
+				4315BDC90C9717B400D36F21 /* ossimPlanetTextureLayer.cpp */,
+				4315BDCA0C9717B400D36F21 /* ossimPlanetStandardTextureLayerFactory.cpp */,
+				4315BDCB0C9717B400D36F21 /* ossimPlanetSocketNetworkConnection.cpp */,
+				4315BDCC0C9717B400D36F21 /* ossimPlanetShaderProgramSetup.cpp */,
+				4315BDCD0C9717B400D36F21 /* ossimPlanetServerThread.cpp */,
+				4315BDCE0C9717B400D36F21 /* ossimPlanetSceneView.cpp */,
+				4315BDCF0C9717B400D36F21 /* ossimPlanetPlaneGrid.cpp */,
+				4315BDD00C9717B400D36F21 /* ossimPlanetPagedLandLod.cpp */,
+				4315BDD10C9717B400D36F21 /* ossimPlanetOssimImage.cpp */,
+				4315BDD20C9717B400D36F21 /* ossimPlanetManipulator.cpp */,
+				4315BDD30C9717B400D36F21 /* ossimPlanetNavigator.cpp */,
+				4315BDD50C9717B400D36F21 /* ossimPlanetLookAt.cpp */,
+				4315BDD60C9717B400D36F21 /* ossimPlanetLayer.cpp */,
+				4315BDD70C9717B400D36F21 /* ossimPlanetLatLonHud.cpp */,
+				4315BDD80C9717B400D36F21 /* ulError.cpp */,
+				4315BDD90C9717B400D36F21 /* ulClock.cpp */,
+				4315BDDA0C9717B400D36F21 /* sg_socket_udp.cpp */,
+				4315BDDB0C9717B400D36F21 /* ossimPlanetYahooGeocoder.cpp */,
+				4315BDDC0C9717B400D36F21 /* ossimPlanetWmsClient.cpp */,
+				4315BDDD0C9717B400D36F21 /* ossimPlanetIoThread.cpp */,
+				4315BDDE0C9717B400D36F21 /* ossimPlanetIoSocketServerChannel.cpp */,
+				4315BDDF0C9717B400D36F21 /* ossimPlanetIoSocket.cpp */,
+				4315BDE00C9717B400D36F21 /* ossimPlanetIoRoutableMessageHandler.cpp */,
+				4315BDE10C9717B400D36F21 /* ossimPlanetInteractionController.cpp */,
+				4315BDE20C9717B400D36F21 /* ossimPlanetImage.cpp */,
+				4315BDE30C9717B400D36F21 /* ossimPlanetIdManager.cpp */,
+				4315BDE40C9717B400D36F21 /* ossimPlanetClientThread.cpp */,
+				4315BDE50C9717B400D36F21 /* ossimPlanetBoundingBox.cpp */,
+				4315BDE60C9717B400D36F21 /* ossimPlanetBillboardIcon.cpp */,
+				4315BDE70C9717B400D36F21 /* ossimPlanetKmlLayer.cpp */,
+				4315BDE90C9717B400D36F21 /* ossimPlanetKml.cpp */,
+				4315BDEA0C9717B400D36F21 /* ossimPlanetJpegImage.cpp */,
+				4315BDEB0C9717B400D36F21 /* ossimPlanet.cpp */,
+				4315BDEC0C9717B400D36F21 /* netSocket.cpp */,
+				4315BDED0C9717B400D36F21 /* netMonitor.cpp */,
+				4315BDEE0C9717B400D36F21 /* netMessage.cpp */,
+				4315BDEF0C9717B400D36F21 /* netChat.cpp */,
+				4315BDF00C9717B400D36F21 /* netChannel.cpp */,
+				4315BDF10C9717B400D36F21 /* netBuffer.cpp */,
+				4315BDF20C9717B400D36F21 /* mkUtils.cpp */,
+				4315BDF30C9717B400D36F21 /* iochannel.cpp */,
+				4315BDF40C9717B400D36F21 /* ossimPlanetGeocoder.cpp */,
+				4315BDF60C9717B400D36F21 /* ossimPlanetActionRouter.cpp */,
+				4315BDF70C9717B400D36F21 /* ossimPlanetActionReceiver.cpp */,
+				4315BDF80C9717B400D36F21 /* ossimPlanetAction.cpp */,
+				4315BDF90C9717B400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.cpp */,
+				4315BDFA0C9717B400D36F21 /* ossimPlanetElevationGrid.cpp */,
+				4315BDFB0C9717B400D36F21 /* ulLinkedList.cpp */,
+				4315BDFC0C9717B400D36F21 /* ossimPlanetLandCache.cpp */,
+				4315BDFD0C9717B400D36F21 /* ossimPlanetLand.cpp */,
+				4315BDFE0C9717B400D36F21 /* ossimPlanetKmlLayerNode.cpp */,
+				4315BDFF0C9717B400D36F21 /* sg_file.cpp */,
+				4315BE000C9717B400D36F21 /* ossimPlanetTexture2D.cpp */,
+				4315BE010C9717B400D36F21 /* ossimPlanetSrtmElevationDatabase.cpp */,
+				4315BE020C9717B400D36F21 /* ossimPlanetId.cpp */,
+				4315BE030C9717B400D36F21 /* ossimPlanetIconGeom.cpp */,
+				4315BE050C9717B400D36F21 /* ossimPlanetGridUtility.cpp */,
+				4315BE060C9717B400D36F21 /* ulRTTI.cpp */,
+				4315BE070C9717B400D36F21 /* sg_socket.cpp */,
+				4315BE080C9717B400D36F21 /* ossimPlanetOssimImageLayer.cpp */,
+				4315BE090C9717B400D36F21 /* ul.cpp */,
+				4315BE0A0C9717B400D36F21 /* ulList.cpp */,
+				4315BE0B0C9717B400D36F21 /* ossimPlanetLandReaderWriter.cpp */,
+				4315BE0C0C9717B400D36F21 /* ossimPlanetLandCullCallback.cpp */,
+				4315BE0D0C9717B400D36F21 /* ossimPlanetElevationDatabaseGroup.cpp */,
+				4315BE0E0C9717B400D36F21 /* ossimPlanetElevationDatabase.cpp */,
+				43FDA2D90D77274F00945FA0 /* ossimPlanetDestinationCommandAction.cpp */,
+				43AA128E0D77ADF90020DF13 /* ossimPlanetXmlAction.cpp */,
+			);
+			path = ossimPlanet;
+			sourceTree = "<group>";
+		};
+		186EF4B50B1CE11D00F7886A /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				186EF4F60B1CE11D00F7886A /* ossim.framework */,
+				435310B71044384C004A4474 /* template-app */,
+				435310B91044384C004A4474 /* ossim-adrg-dump */,
+				435310BB1044384C004A4474 /* ossim-applanix2ogeom */,
+				435310BD1044384C004A4474 /* ossim-band-merge */,
+				435310BF1044384C004A4474 /* ossim-btoa */,
+				435310C11044384C004A4474 /* template-app */,
+				435310C31044384C004A4474 /* ossim-cmm */,
+				435310C51044384C004A4474 /* ossim-computeSrtmStats */,
+				435310C71044384C004A4474 /* ossim-correl */,
+				435310C91044384C004A4474 /* ossim-create-cg */,
+				435310CB1044384C004A4474 /* ossim-create-histo */,
+				435310D31044384C004A4474 /* ossim-dms2deg */,
+				435310D51044384C004A4474 /* ossim-dump-ocg */,
+				435310D71044384C004A4474 /* ossim-ecg2ocg */,
+				435310D91044384C004A4474 /* ossim-extract-vertices */,
+				435310DB1044384C004A4474 /* ossim-foo */,
+				435310DF1044384C004A4474 /* ossim-height */,
+				435310E11044384C004A4474 /* ossim-icp */,
+				435310E31044384C004A4474 /* ossim-igen */,
+				435310E51044384C004A4474 /* ossim-img2md */,
+				435310E71044384C004A4474 /* ossim-img2rr */,
+				435310E91044384C004A4474 /* ossim-info */,
+				435310EB1044384C004A4474 /* ossim-modopt */,
+				435310ED1044384C004A4474 /* ossim-mosaic */,
+				435310F31044384C004A4474 /* ossim-ogeom2ogeom */,
+				435310F51044384C004A4474 /* ossim-orthoigen */,
+				435310F71044384C004A4474 /* ossim-pixelflip */,
+				435310F91044384C004A4474 /* ossim-prune */,
+				435310FD1044384C004A4474 /* ossim-rejout */,
+				435310FF1044384C004A4474 /* ossim-senint */,
+				435311011044384C004A4474 /* ossim-space-imaging */,
+				435311031044384C004A4474 /* ossim-swapbytes */,
+				435311051044384C004A4474 /* ossim-tfw2ogeom */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		433A4CF5100CEDD2000B969C /* ossimplanettest */ = {
+			isa = PBXGroup;
+			children = (
+				433A4CF6100CEDD2000B969C /* ossimplanettest.cpp */,
+			);
+			name = ossimplanettest;
+			path = ../../examples/ossimplanettest;
+			sourceTree = SOURCE_ROOT;
+		};
+		437D9ACC0FC3FE810018F889 /* External Frameworks and Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				432933BA10FE531E00C66EB8 /* OpenThreads.framework */,
+				43D7ECB210FE1F8500762FA7 /* gpstk.framework */,
+				4306ABAE10FE11C000C7202A /* osgDB.framework */,
+				4306ABAF10FE11C000C7202A /* osgText.framework */,
+				4306ABB010FE11C000C7202A /* osgUtil.framework */,
+				4306ABB110FE11C000C7202A /* osgViewer.framework */,
+				4306ABAC10FE11AC00C7202A /* osgGA.framework */,
+				4306ABAA10FE11A700C7202A /* osg.framework */,
+				437D9DE60FC3FFA60018F889 /* OpenGL.framework */,
+			);
+			name = "External Frameworks and Libraries";
+			sourceTree = "<group>";
+		};
+		43C6E2B40FEFB50E004B52F7 /* ossimplanetklv */ = {
+			isa = PBXGroup;
+			children = (
+				43C6E2B60FEFB50E004B52F7 /* ossimplanetklv.cpp */,
+			);
+			name = ossimplanetklv;
+			path = ../../examples/ossimplanetklv;
+			sourceTree = SOURCE_ROOT;
+		};
+		43C6E2B80FEFB531004B52F7 /* ossimplanetviewer */ = {
+			isa = PBXGroup;
+			children = (
+				43C6E2C30FEFB531004B52F7 /* ossimplanetviewer.cpp */,
+				43C6E2C50FEFB531004B52F7 /* readme.txt */,
+			);
+			name = ossimplanetviewer;
+			path = ../../examples/ossimplanetviewer;
+			sourceTree = SOURCE_ROOT;
+		};
+		43D8A1060D818DFD00A60690 /* schema */ = {
+			isa = PBXGroup;
+			children = (
+				43D8A1080D818E2200A60690 /* ossimPlanet.xsd */,
+			);
+			name = schema;
+			sourceTree = "<group>";
+		};
+		43D8A10D0D818EC100A60690 /* Sample files */ = {
+			isa = PBXGroup;
+			children = (
+				43D8A1120D818ED300A60690 /* binds.act */,
+			);
+			name = "Sample files";
+			sourceTree = "<group>";
+		};
+		EE69A34C0B2883FA00C91DD1 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				EE69A3500B2883FA00C91DD1 /* wms.framework */,
+				437A55AD0E789BB8000D89D5 /* wmsurl */,
+				437A55AF0E789BB8000D89D5 /* wmscapabilities.cpp */,
+				437A55B10E789BB8000D89D5 /* wmsgetmap */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		EE9D25F30DD87952005A8951 /* apps */ = {
+			isa = PBXGroup;
+			children = (
+				433A4CF5100CEDD2000B969C /* ossimplanettest */,
+				43C6E2B40FEFB50E004B52F7 /* ossimplanetklv */,
+				43C6E2B80FEFB531004B52F7 /* ossimplanetviewer */,
+			);
+			name = apps;
+			sourceTree = "<group>";
+		};
+		EEB5ECED0D0F2284000CF6B2 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				EEB5ECF10D0F2284000CF6B2 /* ossimPredator.framework */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8D07F2BD0486CC7A007CD1D0 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				430485FE0F3CB80800B9C1E2 /* ossimPlanetDatabasePager.h in Headers */,
+				EE26B26A0F39DD2000D4028C /* ossimPlanetElevationFactory.h in Headers */,
+				EE26B23A0F39CB8400D4028C /* ossimPlanetElevationRegistry.h in Headers */,
+				435BD1FC0F09848100CEAEAD /* ossimPlanetViewer.h in Headers */,
+				EE2F90FD0EB5E188003D424A /* ossimPlanetMessage.h in Headers */,
+				43CA034E0DD34451003EC1AB /* ossimPlanetArchive.h in Headers */,
+				43CA034F0DD34451003EC1AB /* ossimPlanetArchiveMapping.h in Headers */,
+				43A113DF0D520F3600DE3CF3 /* ossimPlanetNodeFactory.h in Headers */,
+				43A113E00D520F3600DE3CF3 /* ossimPlanetNodeRegistry.h in Headers */,
+				43A113E10D520F3600DE3CF3 /* ossimPlanetNodeFactoryBase.h in Headers */,
+				43A113980D520D7100DE3CF3 /* ossimPlanetNode.h in Headers */,
+				43C443DE0D4A2179004BDD99 /* ossimPlanetOperation.h in Headers */,
+				EEBDDA7A0D491078009DB3D5 /* ossimPlanetVideoLayerNode.h in Headers */,
+				EEBDD6CC0D46E214009DB3D5 /* ossimPlanetAnnotationLayerNode.h in Headers */,
+				EEBDD68E0D464823009DB3D5 /* ossimPlanetAnnotationLayer.h in Headers */,
+				433E7EC20D32B9CF00BA05D0 /* ossimPlanetApi.h in Headers */,
+				434EDC3C0D2BD04400EDC08A /* ossimPlanetLayerFactory.h in Headers */,
+				434EDC1A0D2BCC8000EDC08A /* ossimPlanetLayerFactoryBase.h in Headers */,
+				434EDC180D2BCA2600EDC08A /* ossimPlanetLayerRegistry.h in Headers */,
+				43E957E00D2931C000D31E60 /* ossimPlanetRefBlock.h in Headers */,
+				EEB5EDDE0D101268000CF6B2 /* ossimPlanetPredatorVideoLayerNode.h in Headers */,
+				EEB5ECDA0D0F214E000CF6B2 /* ossimPlanetVideoLayer.h in Headers */,
+				43669A930CD177A400F1832B /* ossimPlanetSousaLayer.h in Headers */,
+				432FACB90CC4F2D6004D5C1D /* ossimPlanetCallback.h in Headers */,
+				4314728F0CBE9F0F00EAADAB /* ossimPlanetVisitors.h in Headers */,
+				430C8F690CBBD0CA002BAF12 /* ossimPlanetCompass.h in Headers */,
+				432D60BC0CB548DE00F15133 /* ioapi.h in Headers */,
+				432D60BD0CB548DE00F15133 /* unzip.h in Headers */,
+				432D60BE0CB548DE00F15133 /* zip.h in Headers */,
+				43C8A82E0CAACB4E00EE840F /* ossimPlanetKmlPlacemarkNode.h in Headers */,
+				431476570CA838400090B3CE /* ossimPlanetKmlScreenOverlayNode.h in Headers */,
+				EED173960CA0174100DF3588 /* ossimPlanetFadeText.h in Headers */,
+				4315BEC80C9717E400D36F21 /* ossimPlanetLandTreeNode.h in Headers */,
+				4315BEC90C9717E400D36F21 /* ossimPlanetLandNormalType.h in Headers */,
+				4315BECA0C9717E400D36F21 /* ossimPlanetKmlLayerNode.h in Headers */,
+				4315BECB0C9717E400D36F21 /* netBuffer.h in Headers */,
+				4315BECC0C9717E400D36F21 /* ossimPlanetLand.h in Headers */,
+				4315BECD0C9717E400D36F21 /* ossimPlanetBillboardIcon.h in Headers */,
+				4315BECF0C9717E400D36F21 /* ossimPlanetElevationDatabaseGroup.h in Headers */,
+				4315BED00C9717E400D36F21 /* ossimPlanetIdolLayer.h in Headers */,
+				4315BED20C9717E400D36F21 /* ossimPlanetIdManager.h in Headers */,
+				4315BED30C9717E400D36F21 /* ossimPlanetLandReaderWriter.h in Headers */,
+				4315BED40C9717E400D36F21 /* ossimPlanetUtility.h in Headers */,
+				4315BED50C9717E400D36F21 /* ossimPlanetThreadPool.h in Headers */,
+				4315BED60C9717E400D36F21 /* ossimPlanetPlaneGrid.h in Headers */,
+				4315BED70C9717E400D36F21 /* ossimPlanetPagedRequestNode.h in Headers */,
+				4315BED80C9717E400D36F21 /* ossimPlanetPagedLandLodRefreshType.h in Headers */,
+				4315BED90C9717E400D36F21 /* ossimPlanetLandNode.h in Headers */,
+				4315BEDA0C9717E400D36F21 /* ossimPlanetIoSocket.h in Headers */,
+				4315BEDB0C9717E400D36F21 /* ossimPlanetInteractionController.h in Headers */,
+				4315BEDC0C9717E400D36F21 /* ulLocal.h in Headers */,
+				4315BEDD0C9717E400D36F21 /* ul.h in Headers */,
+				4315BEDE0C9717E400D36F21 /* ossimPlanetInputDevice.h in Headers */,
+				4315BEDF0C9717E400D36F21 /* ossimPlanetShaderProgramSetup.h in Headers */,
+				4315BEE00C9717E400D36F21 /* ossimPlanetSetup.h in Headers */,
+				4315BEE10C9717E400D36F21 /* ossimPlanetBoundingBox.h in Headers */,
+				4315BEF80C9717E400D36F21 /* ossimPlanetOssimImageLayer.h in Headers */,
+				4315BEE20C9717E400D36F21 /* ossimPlanetIoSocketServerChannel.h in Headers */,
+				4315BEE30C9717E400D36F21 /* ossimPlanetPrimaryBody.h in Headers */,
+				4315BEE40C9717E400D36F21 /* ossimPlanetSocketNetworkConnection.h in Headers */,
+				4315BEE50C9717E400D36F21 /* iochannel.h in Headers */,
+				4315BEE60C9717E400D36F21 /* ossimPlanetIconGeom.h in Headers */,
+				4315BEE70C9717E400D36F21 /* ossimPlanetTextureLayer.h in Headers */,
+				4315BEE80C9717E400D36F21 /* ossimPlanetTexture2D.h in Headers */,
+				4315BEE90C9717E400D36F21 /* ossimPlanetAction.h in Headers */,
+				4315BEEA0C9717E400D36F21 /* ossimPlanetServerMessageHandler.h in Headers */,
+				4315BEEB0C9717E400D36F21 /* ossimPlanetSceneView.h in Headers */,
+				4315BEEC0C9717E400D36F21 /* ossimPlanetManipulator.h in Headers */,
+				4315BEED0C9717E400D36F21 /* ossimPlanetWmsImageLayer.h in Headers */,
+				4315BEEE0C9717E400D36F21 /* ossimPlanetThread.h in Headers */,
+				4315BEEF0C9717E400D36F21 /* ossimPlanetTextureLayerRegistry.h in Headers */,
+				4315BEF00C9717E400D36F21 /* netChat.h in Headers */,
+				4315BEF10C9717E400D36F21 /* ossimPlanetTextureLayerGroup.h in Headers */,
+				4315BEF20C9717E400D36F21 /* ossimPlanetTextureLayerFactory.h in Headers */,
+				4315BEF30C9717E400D36F21 /* ossimPlanetOssimImage.h in Headers */,
+				4315BEF40C9717E400D36F21 /* ossimPlanetOrthoFlatLandNode.h in Headers */,
+				4315BEF50C9717E400D36F21 /* ossimPlanetServerThread.h in Headers */,
+				4315BEF60C9717E400D36F21 /* ossimPlanetIoThread.h in Headers */,
+				4315BEF70C9717E400D36F21 /* ossimPlanet.h in Headers */,
+				4315BEF90C9717E400D36F21 /* ossimPlanetThreadImp.h in Headers */,
+				4315BEFB0C9717E400D36F21 /* ossimPlanetLandTextureRequest.h in Headers */,
+				4315BEFC0C9717E400D36F21 /* ossimPlanetLandCullCallback.h in Headers */,
+				4315BEFD0C9717E400D36F21 /* ossimPlanetConstants.h in Headers */,
+				4315BEFE0C9717E400D36F21 /* ossimPlanetNetworkConnection.h in Headers */,
+				4315BEFF0C9717E400D36F21 /* ossimPlanetKml.h in Headers */,
+				4315BF010C9717E400D36F21 /* ossimPlanetExport.h in Headers */,
+				4315BF020C9717E400D36F21 /* netMessage.h in Headers */,
+				4315BF030C9717E400D36F21 /* ossimPlanetIo.h in Headers */,
+				4315BF040C9717E400D36F21 /* ossimPlanetJpegImage.h in Headers */,
+				4315BF050C9717E400D36F21 /* ossimPlanetLookAt.h in Headers */,
+				4315BF080C9717E400D36F21 /* net.h in Headers */,
+				4315BF090C9717E400D36F21 /* ulRTTI.h in Headers */,
+				4315BF0A0C9717E400D36F21 /* netChannel.h in Headers */,
+				4315BF0B0C9717E400D36F21 /* ossimPlanetElevationGrid.h in Headers */,
+				4315BF0C0C9717E400D36F21 /* ossimPlanetIntersectUserData.h in Headers */,
+				4315BF0D0C9717E400D36F21 /* ossimPlanetLabelGeom.h in Headers */,
+				4315BF0E0C9717E400D36F21 /* ossimPlanetGeocoder.h in Headers */,
+				4315BF0F0C9717E400D36F21 /* ossimPlanetLayer.h in Headers */,
+				4315BF100C9717E400D36F21 /* netMonitor.h in Headers */,
+				4315BF110C9717E400D36F21 /* ossimPlanetId.h in Headers */,
+				4315BF130C9717E400D36F21 /* ossimPlanetActionRouter.h in Headers */,
+				4315BF140C9717E400D36F21 /* ossimPlanetSrtmElevationDatabase.h in Headers */,
+				4315BF150C9717E400D36F21 /* ossimPlanetStandardTextureLayerFactory.h in Headers */,
+				4315BF160C9717E400D36F21 /* ossimPlanetActionReceiver.h in Headers */,
+				4315BF170C9717E400D36F21 /* sg_file.h in Headers */,
+				4315BF180C9717E400D36F21 /* ossimPlanetYahooGeocoder.h in Headers */,
+				4315BF190C9717E400D36F21 /* ossimPlanetIoMessageHandler.h in Headers */,
+				4315BF1A0C9717E400D36F21 /* ossimPlanetElevationDatabase.h in Headers */,
+				4315BF1B0C9717E400D36F21 /* compiler.h in Headers */,
+				4315BF1C0C9717E400D36F21 /* ossimPlanetLandCache.h in Headers */,
+				4315BF1D0C9717E400D36F21 /* ossimPlanetExtents.h in Headers */,
+				4315BF1E0C9717E400D36F21 /* ossimPlanetKmlReaderWriter.h in Headers */,
+				4315BF1F0C9717E400D36F21 /* ossimPlanetDtedElevationDatabase.h in Headers */,
+				4315BF200C9717E400D36F21 /* ossimPlanetNavigator.h in Headers */,
+				4315BF210C9717E400D36F21 /* ossimPlanetImage.h in Headers */,
+				4315BF220C9717E400D36F21 /* sg_socket_udp.h in Headers */,
+				4315BF230C9717E400D36F21 /* sg_socket.h in Headers */,
+				4315BF240C9717E400D36F21 /* ossimPlanetCubeGrid.h in Headers */,
+				4315BF250C9717E400D36F21 /* ossimPlanetIdolBridge.h in Headers */,
+				4315BF270C9717E400D36F21 /* mkUtils.h in Headers */,
+				4315BF280C9717E400D36F21 /* ossimPlanetLatLonHud.h in Headers */,
+				4315BF290C9717E400D36F21 /* ossimPlanetClientThread.h in Headers */,
+				4315BF2A0C9717E400D36F21 /* ossimPlanetIoRoutableMessageHandler.h in Headers */,
+				4315BF2B0C9717E400D36F21 /* ossimPlanetPagedLandLod.h in Headers */,
+				4315BF2C0C9717E400D36F21 /* ossimPlanetWmsClient.h in Headers */,
+				4315BF2D0C9717E400D36F21 /* netSocket.h in Headers */,
+				4315BF2E0C9717E400D36F21 /* ossimPlanetKmlLayer.h in Headers */,
+				4315BF2F0C9717E400D36F21 /* ossimPlanetGridUtility.h in Headers */,
+				4315BF300C9717E400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.h in Headers */,
+				43FDA2D70D770D0700945FA0 /* ossimPlanetDestinationCommandAction.h in Headers */,
+				43FDA3D30D77495200945FA0 /* ossimPlanetXmlAction.h in Headers */,
+				EE5403670F5D7041001139DD /* ossimPlanetTerrain.h in Headers */,
+				EE54036A0F5D74F5001139DD /* ossimPlanetTerrainTile.h in Headers */,
+				EE5403EE0F5D8C50001139DD /* ossimPlanetGrid.h in Headers */,
+				EE5403F10F5D8DDE001139DD /* ossimPlanetTerrainTileId.h in Headers */,
+				EE5404570F5E21DD001139DD /* ossimPlanetTerrainTechnique.h in Headers */,
+				EE54045A0F5E24D2001139DD /* ossimPlanetTerrainGeometryTechnique.h in Headers */,
+				EE5409A30F61516D001139DD /* ossimPlanetPointModel.h in Headers */,
+				EE540A8F0F61A503001139DD /* ossimPlanetGeoRefModel.h in Headers */,
+				EE9B0A4D0F6463A500394285 /* ossimPlanetLsrSpaceTransform.h in Headers */,
+				43D65A310F6839F1006C6786 /* ossimPlanetTerrainLayer.h in Headers */,
+				43244C830F742D70002F5FA3 /* ossimPlanetReentrantMutex.h in Headers */,
+				43BC2F8F0F8D13C600838B40 /* ossimPlanetTileRequest.h in Headers */,
+				4351096E0FCC130A0065BA0E /* ossimPlanetViewMatrixBuilder.h in Headers */,
+				43463BC00FCF16DD0027D845 /* ossimPlanetAnimationPath.h in Headers */,
+				4345891E0FD3F96C00046CB5 /* ossimPlanetAnimatedPointModel.h in Headers */,
+				43AB5FAF0FF99226004874C2 /* ossimPlanetEphemeris.h in Headers */,
+				43FF0C201021065500CEA135 /* ossimPlanetCloudLayer.h in Headers */,
+				4377D4281029BB5800B6652D /* ossimPlanetCache.h in Headers */,
+				4377D6FB102C50AD00B6652D /* ossimPlanetKmlNetworkLinkNode.h in Headers */,
+				43D9C7E510A4BC0F00BA9119 /* ossimPlanetCacheTextureLayer.h in Headers */,
+				434E72BC10DAAD15005EBB18 /* ossimPlanetOssimElevationDatabase.h in Headers */,
+				430D8E911100DA3F00EB0F96 /* ossimPlanetDepthPartitionNode.h in Headers */,
+				430D8E941100DA5200EB0F96 /* ossimPlanetDistanceAccumulator.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		433A4CC4100CED8D000B969C /* ossimplanettest */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 433A4CD2100CED8D000B969C /* Build configuration list for PBXNativeTarget "ossimplanettest" */;
+			buildPhases = (
+				433A4CC7100CED8D000B969C /* Sources */,
+				433A4CC9100CED8D000B969C /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				433A4CC5100CED8D000B969C /* PBXTargetDependency */,
+			);
+			name = ossimplanettest;
+			productName = ossimplanetviewer;
+			productReference = 433A4CD8100CED8D000B969C /* ossimplanettest */;
+			productType = "com.apple.product-type.tool";
+		};
+		43C6E2900FEFB4D8004B52F7 /* ossimplanetklv */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 43C6E2B00FEFB4F1004B52F7 /* Build configuration list for PBXNativeTarget "ossimplanetklv" */;
+			buildPhases = (
+				43C6E28E0FEFB4D8004B52F7 /* Sources */,
+				43C6E28F0FEFB4D8004B52F7 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = ossimplanetklv;
+			productName = ossimplanetklv;
+			productReference = 43C6E2910FEFB4D8004B52F7 /* ossimplanetklv */;
+			productType = "com.apple.product-type.tool";
+		};
+		43C6E29B0FEFB4E9004B52F7 /* ossimplanetviewer */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 43C6E2B10FEFB4F1004B52F7 /* Build configuration list for PBXNativeTarget "ossimplanetviewer" */;
+			buildPhases = (
+				43C6E2990FEFB4E9004B52F7 /* Sources */,
+				43C6E29A0FEFB4E9004B52F7 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				43AB5F2B0FF94015004874C2 /* PBXTargetDependency */,
+			);
+			name = ossimplanetviewer;
+			productName = ossimplanetviewer;
+			productReference = 43C6E29C0FEFB4E9004B52F7 /* ossimplanetviewer */;
+			productType = "com.apple.product-type.tool";
+		};
+		8D07F2BC0486CC7A007CD1D0 /* ossimPlanet */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "ossimPlanet" */;
+			buildPhases = (
+				8D07F2BD0486CC7A007CD1D0 /* Headers */,
+				8D07F2BF0486CC7A007CD1D0 /* Resources */,
+				8D07F2C10486CC7A007CD1D0 /* Sources */,
+				8D07F2C30486CC7A007CD1D0 /* Frameworks */,
+				8D07F2C50486CC7A007CD1D0 /* Rez */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				EEB5EE5E0D103A68000CF6B2 /* PBXTargetDependency */,
+				EEB5EE5C0D103A57000CF6B2 /* PBXTargetDependency */,
+				EEB5EE5A0D103A4A000CF6B2 /* PBXTargetDependency */,
+			);
+			name = ossimPlanet;
+			productInstallPath = "$(HOME)/Library/Frameworks";
+			productName = ossimPlanet;
+			productReference = 8D07F2C80486CC7A007CD1D0 /* ossimPlanet.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		0867D690FE84028FC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "ossimPlanet" */;
+			compatibilityVersion = "Xcode 2.4";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 0867D691FE84028FC02AAC07 /* ossimPlanet */;
+			productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
+			projectDirPath = "";
+			projectReferences = (
+				{
+					ProductGroup = EE69A34C0B2883FA00C91DD1 /* Products */;
+					ProjectRef = EE69A34B0B2883FA00C91DD1 /* libwms.xcodeproj */;
+				},
+				{
+					ProductGroup = 186EF4B50B1CE11D00F7886A /* Products */;
+					ProjectRef = 186EF4B40B1CE11D00F7886A /* ossim.xcodeproj */;
+				},
+				{
+					ProductGroup = EEB5ECED0D0F2284000CF6B2 /* Products */;
+					ProjectRef = EEB5ECEC0D0F2284000CF6B2 /* ossimPredator.xcodeproj */;
+				},
+			);
+			projectRoot = "";
+			targets = (
+				EE9D26590DD888FB005A8951 /* All */,
+				8D07F2BC0486CC7A007CD1D0 /* ossimPlanet */,
+				43C6E2900FEFB4D8004B52F7 /* ossimplanetklv */,
+				43C6E29B0FEFB4E9004B52F7 /* ossimplanetviewer */,
+				433A4CC4100CED8D000B969C /* ossimplanettest */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+		186EF4F60B1CE11D00F7886A /* ossim.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = ossim.framework;
+			remoteRef = 186EF4F50B1CE11D00F7886A /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310B71044384C004A4474 /* template-app */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "template-app";
+			remoteRef = 435310B61044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310B91044384C004A4474 /* ossim-adrg-dump */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-adrg-dump";
+			remoteRef = 435310B81044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310BB1044384C004A4474 /* ossim-applanix2ogeom */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-applanix2ogeom";
+			remoteRef = 435310BA1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310BD1044384C004A4474 /* ossim-band-merge */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-band-merge";
+			remoteRef = 435310BC1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310BF1044384C004A4474 /* ossim-btoa */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-btoa";
+			remoteRef = 435310BE1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310C11044384C004A4474 /* template-app */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "template-app";
+			remoteRef = 435310C01044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310C31044384C004A4474 /* ossim-cmm */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-cmm";
+			remoteRef = 435310C21044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310C51044384C004A4474 /* ossim-computeSrtmStats */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-computeSrtmStats";
+			remoteRef = 435310C41044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310C71044384C004A4474 /* ossim-correl */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-correl";
+			remoteRef = 435310C61044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310C91044384C004A4474 /* ossim-create-cg */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-create-cg";
+			remoteRef = 435310C81044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310CB1044384C004A4474 /* ossim-create-histo */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-create-histo";
+			remoteRef = 435310CA1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310D31044384C004A4474 /* ossim-dms2deg */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-dms2deg";
+			remoteRef = 435310D21044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310D51044384C004A4474 /* ossim-dump-ocg */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-dump-ocg";
+			remoteRef = 435310D41044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310D71044384C004A4474 /* ossim-ecg2ocg */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-ecg2ocg";
+			remoteRef = 435310D61044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310D91044384C004A4474 /* ossim-extract-vertices */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-extract-vertices";
+			remoteRef = 435310D81044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310DB1044384C004A4474 /* ossim-foo */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-foo";
+			remoteRef = 435310DA1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310DF1044384C004A4474 /* ossim-height */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-height";
+			remoteRef = 435310DE1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310E11044384C004A4474 /* ossim-icp */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-icp";
+			remoteRef = 435310E01044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310E31044384C004A4474 /* ossim-igen */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-igen";
+			remoteRef = 435310E21044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310E51044384C004A4474 /* ossim-img2md */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-img2md";
+			remoteRef = 435310E41044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310E71044384C004A4474 /* ossim-img2rr */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-img2rr";
+			remoteRef = 435310E61044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310E91044384C004A4474 /* ossim-info */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-info";
+			remoteRef = 435310E81044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310EB1044384C004A4474 /* ossim-modopt */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-modopt";
+			remoteRef = 435310EA1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310ED1044384C004A4474 /* ossim-mosaic */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-mosaic";
+			remoteRef = 435310EC1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310F31044384C004A4474 /* ossim-ogeom2ogeom */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-ogeom2ogeom";
+			remoteRef = 435310F21044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310F51044384C004A4474 /* ossim-orthoigen */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-orthoigen";
+			remoteRef = 435310F41044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310F71044384C004A4474 /* ossim-pixelflip */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-pixelflip";
+			remoteRef = 435310F61044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310F91044384C004A4474 /* ossim-prune */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-prune";
+			remoteRef = 435310F81044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310FD1044384C004A4474 /* ossim-rejout */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-rejout";
+			remoteRef = 435310FC1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435310FF1044384C004A4474 /* ossim-senint */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-senint";
+			remoteRef = 435310FE1044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435311011044384C004A4474 /* ossim-space-imaging */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-space-imaging";
+			remoteRef = 435311001044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435311031044384C004A4474 /* ossim-swapbytes */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-swapbytes";
+			remoteRef = 435311021044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		435311051044384C004A4474 /* ossim-tfw2ogeom */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = "ossim-tfw2ogeom";
+			remoteRef = 435311041044384C004A4474 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		437A55AD0E789BB8000D89D5 /* wmsurl */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = wmsurl;
+			remoteRef = 437A55AC0E789BB8000D89D5 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		437A55AF0E789BB8000D89D5 /* wmscapabilities.cpp */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = wmscapabilities.cpp;
+			remoteRef = 437A55AE0E789BB8000D89D5 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		437A55B10E789BB8000D89D5 /* wmsgetmap */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = wmsgetmap;
+			remoteRef = 437A55B00E789BB8000D89D5 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		EE69A3500B2883FA00C91DD1 /* wms.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = wms.framework;
+			remoteRef = EE69A34F0B2883FA00C91DD1 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		EEB5ECF10D0F2284000CF6B2 /* ossimPredator.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = ossimPredator.framework;
+			remoteRef = EEB5ECF00D0F2284000CF6B2 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D07F2BF0486CC7A007CD1D0 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */,
+				43D8A1090D818E2200A60690 /* ossimPlanet.xsd in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+		8D07F2C50486CC7A007CD1D0 /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		433A4CC7100CED8D000B969C /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				433A4CF7100CEDD2000B969C /* ossimplanettest.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		43C6E28E0FEFB4D8004B52F7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				43C6E2B70FEFB50E004B52F7 /* ossimplanetklv.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		43C6E2990FEFB4E9004B52F7 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				43C6E2C90FEFB531004B52F7 /* ossimplanetviewer.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D07F2C10486CC7A007CD1D0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4315BE0F0C9717B400D36F21 /* ossimPlanetDtedElevationDatabase.cpp in Sources */,
+				4315BE110C9717B400D36F21 /* ossimPlanetCubeGrid.cpp in Sources */,
+				4315BE120C9717B400D36F21 /* ossimPlanetWmsImageLayer.cpp in Sources */,
+				4315BE130C9717B400D36F21 /* ossimPlanetUtility.cpp in Sources */,
+				4315BE140C9717B400D36F21 /* ossimPlanetThreadPool.cpp in Sources */,
+				4315BE150C9717B400D36F21 /* ossimPlanetThreadImp.cpp in Sources */,
+				4315BE160C9717B400D36F21 /* ossimPlanetThread.cpp in Sources */,
+				4315BE170C9717B400D36F21 /* ossimPlanetTextureLayerRegistry.cpp in Sources */,
+				4315BE180C9717B400D36F21 /* ossimPlanetTextureLayerGroup.cpp in Sources */,
+				4315BE190C9717B400D36F21 /* ossimPlanetTextureLayer.cpp in Sources */,
+				4315BE1A0C9717B400D36F21 /* ossimPlanetStandardTextureLayerFactory.cpp in Sources */,
+				4315BE1B0C9717B400D36F21 /* ossimPlanetSocketNetworkConnection.cpp in Sources */,
+				4315BE1C0C9717B400D36F21 /* ossimPlanetShaderProgramSetup.cpp in Sources */,
+				4315BE1D0C9717B400D36F21 /* ossimPlanetServerThread.cpp in Sources */,
+				4315BE1E0C9717B400D36F21 /* ossimPlanetSceneView.cpp in Sources */,
+				4315BE1F0C9717B400D36F21 /* ossimPlanetPlaneGrid.cpp in Sources */,
+				4315BE200C9717B400D36F21 /* ossimPlanetPagedLandLod.cpp in Sources */,
+				4315BE210C9717B400D36F21 /* ossimPlanetOssimImage.cpp in Sources */,
+				4315BE220C9717B400D36F21 /* ossimPlanetManipulator.cpp in Sources */,
+				4315BE230C9717B400D36F21 /* ossimPlanetNavigator.cpp in Sources */,
+				4315BE250C9717B400D36F21 /* ossimPlanetLookAt.cpp in Sources */,
+				4315BE260C9717B400D36F21 /* ossimPlanetLayer.cpp in Sources */,
+				4315BE270C9717B400D36F21 /* ossimPlanetLatLonHud.cpp in Sources */,
+				4315BE280C9717B400D36F21 /* ulError.cpp in Sources */,
+				4315BE290C9717B400D36F21 /* ulClock.cpp in Sources */,
+				4315BE2A0C9717B400D36F21 /* sg_socket_udp.cpp in Sources */,
+				4315BE2B0C9717B400D36F21 /* ossimPlanetYahooGeocoder.cpp in Sources */,
+				4315BE2C0C9717B400D36F21 /* ossimPlanetWmsClient.cpp in Sources */,
+				4315BE2D0C9717B400D36F21 /* ossimPlanetIoThread.cpp in Sources */,
+				4315BE2E0C9717B400D36F21 /* ossimPlanetIoSocketServerChannel.cpp in Sources */,
+				4315BE2F0C9717B400D36F21 /* ossimPlanetIoSocket.cpp in Sources */,
+				4315BE300C9717B400D36F21 /* ossimPlanetIoRoutableMessageHandler.cpp in Sources */,
+				4315BE310C9717B400D36F21 /* ossimPlanetInteractionController.cpp in Sources */,
+				4315BE320C9717B400D36F21 /* ossimPlanetImage.cpp in Sources */,
+				4315BE330C9717B400D36F21 /* ossimPlanetIdManager.cpp in Sources */,
+				4315BE340C9717B400D36F21 /* ossimPlanetClientThread.cpp in Sources */,
+				4315BE350C9717B400D36F21 /* ossimPlanetBoundingBox.cpp in Sources */,
+				4315BE360C9717B400D36F21 /* ossimPlanetBillboardIcon.cpp in Sources */,
+				4315BE370C9717B400D36F21 /* ossimPlanetKmlLayer.cpp in Sources */,
+				4315BE390C9717B400D36F21 /* ossimPlanetKml.cpp in Sources */,
+				4315BE3A0C9717B400D36F21 /* ossimPlanetJpegImage.cpp in Sources */,
+				4315BE3B0C9717B400D36F21 /* ossimPlanet.cpp in Sources */,
+				4315BE3C0C9717B400D36F21 /* netSocket.cpp in Sources */,
+				4315BE3D0C9717B400D36F21 /* netMonitor.cpp in Sources */,
+				4315BE3E0C9717B400D36F21 /* netMessage.cpp in Sources */,
+				4315BE3F0C9717B400D36F21 /* netChat.cpp in Sources */,
+				4315BE400C9717B400D36F21 /* netChannel.cpp in Sources */,
+				4315BE410C9717B400D36F21 /* netBuffer.cpp in Sources */,
+				4315BE420C9717B400D36F21 /* mkUtils.cpp in Sources */,
+				4315BE430C9717B400D36F21 /* iochannel.cpp in Sources */,
+				4315BE440C9717B400D36F21 /* ossimPlanetGeocoder.cpp in Sources */,
+				4315BE460C9717B400D36F21 /* ossimPlanetActionRouter.cpp in Sources */,
+				4315BE470C9717B400D36F21 /* ossimPlanetActionReceiver.cpp in Sources */,
+				4315BE480C9717B400D36F21 /* ossimPlanetAction.cpp in Sources */,
+				4315BE490C9717B400D36F21 /* ossimPlanetGeneralRasterElevationDatabase.cpp in Sources */,
+				4315BE4A0C9717B400D36F21 /* ossimPlanetElevationGrid.cpp in Sources */,
+				4315BE4B0C9717B400D36F21 /* ulLinkedList.cpp in Sources */,
+				4315BE4C0C9717B400D36F21 /* ossimPlanetLandCache.cpp in Sources */,
+				4315BE4D0C9717B400D36F21 /* ossimPlanetLand.cpp in Sources */,
+				4315BE4E0C9717B400D36F21 /* ossimPlanetKmlLayerNode.cpp in Sources */,
+				4315BE4F0C9717B400D36F21 /* sg_file.cpp in Sources */,
+				4315BE500C9717B400D36F21 /* ossimPlanetTexture2D.cpp in Sources */,
+				4315BE510C9717B400D36F21 /* ossimPlanetSrtmElevationDatabase.cpp in Sources */,
+				4315BE520C9717B400D36F21 /* ossimPlanetId.cpp in Sources */,
+				4315BE530C9717B400D36F21 /* ossimPlanetIconGeom.cpp in Sources */,
+				4315BE550C9717B400D36F21 /* ossimPlanetGridUtility.cpp in Sources */,
+				4315BE560C9717B400D36F21 /* ulRTTI.cpp in Sources */,
+				4315BE570C9717B400D36F21 /* sg_socket.cpp in Sources */,
+				4315BE580C9717B400D36F21 /* ossimPlanetOssimImageLayer.cpp in Sources */,
+				4315BE590C9717B400D36F21 /* ul.cpp in Sources */,
+				4315BE5A0C9717B400D36F21 /* ulList.cpp in Sources */,
+				4315BE5B0C9717B400D36F21 /* ossimPlanetLandReaderWriter.cpp in Sources */,
+				4315BE5C0C9717B400D36F21 /* ossimPlanetLandCullCallback.cpp in Sources */,
+				4315BE5D0C9717B400D36F21 /* ossimPlanetElevationDatabaseGroup.cpp in Sources */,
+				4315BE5E0C9717B400D36F21 /* ossimPlanetElevationDatabase.cpp in Sources */,
+				EED173980CA0174E00DF3588 /* ossimPlanetFadeText.cpp in Sources */,
+				431476550CA838310090B3CE /* ossimPlanetKmlScreenOverlayNode.cpp in Sources */,
+				43C8A8320CAACB6500EE840F /* ossimPlanetKmlPlacemarkNode.cpp in Sources */,
+				432D60B60CB548C800F15133 /* ioapi.c in Sources */,
+				432D60B70CB548C800F15133 /* unzip.c in Sources */,
+				432D60B80CB548C800F15133 /* zip.c in Sources */,
+				430C8F670CBBD0B9002BAF12 /* ossimPlanetCompass.cpp in Sources */,
+				43669A950CD177CD00F1832B /* ossimPlanetSousaLayer.cpp in Sources */,
+				EEB5ECE50D0F220C000CF6B2 /* ossimPlanetVideoLayer.cpp in Sources */,
+				EEB5EDDC0D101235000CF6B2 /* ossimPlanetPredatorVideoLayerNode.cpp in Sources */,
+				434EDC400D2BD20500EDC08A /* ossimPlanetLayerRegistry.cpp in Sources */,
+				434EDC7C0D2BD8D200EDC08A /* ossimPlanetLayerFactory.cpp in Sources */,
+				433E7EC80D32B9EC00BA05D0 /* ossimPlanetApi.cpp in Sources */,
+				EEBDD6920D465A0B009DB3D5 /* ossimPlanetAnnotationLayer.cpp in Sources */,
+				EEBDD6CF0D46E3AC009DB3D5 /* ossimPlanetAnnotationLayerNode.cpp in Sources */,
+				43C443E30D4A2C6D004BDD99 /* ossimPlanetOperation.cpp in Sources */,
+				43A52F150D4FA87100DB4777 /* ossimPlanetVisitors.cpp in Sources */,
+				43A113950D520D5D00DE3CF3 /* ossimPlanetNode.cpp in Sources */,
+				43A113E70D520F8900DE3CF3 /* ossimPlanetNodeFactory.cpp in Sources */,
+				43A113E80D520F8900DE3CF3 /* ossimPlanetNodeRegistry.cpp in Sources */,
+				43FDA2DA0D77274F00945FA0 /* ossimPlanetDestinationCommandAction.cpp in Sources */,
+				43AA128F0D77ADF90020DF13 /* ossimPlanetXmlAction.cpp in Sources */,
+				43CA03520DD34464003EC1AB /* ossimPlanetArchiveMapping.cpp in Sources */,
+				43CA03530DD34464003EC1AB /* ossimPlanetArchive.cpp in Sources */,
+				EE0517BC0EE81BB6009EC91D /* ossimPlanetViewer.cpp in Sources */,
+				EE26B23D0F39CC0D00D4028C /* ossimPlanetElevationRegistry.cpp in Sources */,
+				EE26B2680F39DD1100D4028C /* ossimPlanetElevationFactory.cpp in Sources */,
+				EE5403650F5D7030001139DD /* ossimPlanetTerrain.cpp in Sources */,
+				EE5403790F5D7522001139DD /* ossimPlanetTerrainTile.cpp in Sources */,
+				EE5403EB0F5D8C42001139DD /* ossimPlanetGrid.cpp in Sources */,
+				EE5404550F5E21CF001139DD /* ossimPlanetTerrainTechnique.cpp in Sources */,
+				EE5404660F5E24EC001139DD /* ossimPlanetTerrainGeometryTechnique.cpp in Sources */,
+				EE5409A10F615143001139DD /* ossimPlanetPointModel.cpp in Sources */,
+				EE9B0A700F6463C400394285 /* ossimPlanetLsrSpaceTransform.cpp in Sources */,
+				43D65A530F683B15006C6786 /* ossimPlanetTerrainLayer.cpp in Sources */,
+				43BC2F8D0F8D13A600838B40 /* ossimPlanetTileRequest.cpp in Sources */,
+				435109740FCC134C0065BA0E /* ossimPlanetViewMatrixBuilder.cpp in Sources */,
+				43463BD70FCF78850027D845 /* ossimPlanetAnimationPath.cpp in Sources */,
+				4345891C0FD3F95900046CB5 /* ossimPlanetAnimatedPointModel.cpp in Sources */,
+				43AB5FB30FF99240004874C2 /* ossimPlanetEphemeris.cpp in Sources */,
+				43FF0C261021068E00CEA135 /* ossimPlanetCloudLayer.cpp in Sources */,
+				4377D42A1029BB7000B6652D /* ossimPlanetCache.cpp in Sources */,
+				4377D6F8102C509900B6652D /* ossimPlanetKmlNetworkLinkNode.cpp in Sources */,
+				43D9C7E010A4BBB900BA9119 /* ossimPlanetCacheTextureLayer.cpp in Sources */,
+				434E72B910DAACEE005EBB18 /* ossimPlanetOssimElevationDatabase.cpp in Sources */,
+				430D8E991100DB1F00EB0F96 /* ossimPlanetDepthPartitionNode.cpp in Sources */,
+				430D8E9A1100DB1F00EB0F96 /* ossimPlanetDistanceAccumulator.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		433A4CC5100CED8D000B969C /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* ossimPlanet */;
+			targetProxy = 433A4CC6100CED8D000B969C /* PBXContainerItemProxy */;
+		};
+		43AB5F2B0FF94015004874C2 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* ossimPlanet */;
+			targetProxy = 43AB5F2A0FF94015004874C2 /* PBXContainerItemProxy */;
+		};
+		43DFCC080FF0F4E000FB2061 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 43C6E2900FEFB4D8004B52F7 /* ossimplanetklv */;
+			targetProxy = 43DFCC070FF0F4E000FB2061 /* PBXContainerItemProxy */;
+		};
+		43DFCC0A0FF0F4E000FB2061 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 43C6E29B0FEFB4E9004B52F7 /* ossimplanetviewer */;
+			targetProxy = 43DFCC090FF0F4E000FB2061 /* PBXContainerItemProxy */;
+		};
+		EE9D26610DD8891C005A8951 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* ossimPlanet */;
+			targetProxy = EE9D26600DD8891C005A8951 /* PBXContainerItemProxy */;
+		};
+		EEB5EE5A0D103A4A000CF6B2 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = ossimPredator;
+			targetProxy = EEB5EE590D103A4A000CF6B2 /* PBXContainerItemProxy */;
+		};
+		EEB5EE5C0D103A57000CF6B2 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = ossim;
+			targetProxy = EEB5EE5B0D103A57000CF6B2 /* PBXContainerItemProxy */;
+		};
+		EEB5EE5E0D103A68000CF6B2 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = wms;
+			targetProxy = EEB5EE5D0D103A68000CF6B2 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		089C1666FE841158C02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C1667FE841158C02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		18A9BCBE0CDA158B00F4581A /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH)";
+				GCC_MODEL_TUNING = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(DEV_HOME_PATH)/ossim/include",
+					"$(DEV_HOME_PATH)/libwms/include",
+					"$(DEV_HOME_PATH)/ossimPlanet/include",
+					"$(UNIV_HEADER_DEP)",
+				);
+				OTHER_CFLAGS = "";
+				OTHER_CPLUSPLUSFLAGS = (
+					"-DOSSIMPLANET_ENABLE_PREDATOR",
+					"-DOSSIMPLANET_ENABLE_EPHEMERIS",
+					"-g",
+				);
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
+			};
+			name = DebugNativeLeopard;
+		};
+		18A9BCBF0CDA158B00F4581A /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				COPY_PHASE_STRIP = NO;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = "";
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+				GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1 = "EXTRA_INFO_STRING_FOR_MENU=\\\"Version\\";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				LIBRARY_SEARCH_PATHS = "$(UNIV_STATICLIB_DEP)";
+				LIBRARY_STYLE = DYNAMIC;
+				MACH_O_TYPE = mh_dylib;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				OTHER_LDFLAGS = /usr/lib/libz.dylib;
+				PRODUCT_NAME = ossimPlanet;
+				REZ_SEARCH_PATHS = (
+					"$(OSSIM_HOME_PATH)/xcode/ossim/Resources",
+					"$(REZ_SEARCH_PATHS)/**",
+				);
+				USER_HEADER_SEARCH_PATHS = "$(OSSIM_HOME_PATH)/include $(DEV_HOME_PATH)/libwms/include $(DEV_HOME_PATH)/ossimPlanet/include $(UNIV_HEADER_DEP) /usr/X11R6/include/freetype2 /usr/X11R6/include";
+				WARNING_CFLAGS = "-Wall";
+				WRAPPER_EXTENSION = framework;
+				ZERO_LINK = YES;
+			};
+			name = DebugNativeLeopard;
+		};
+		18B28C4F0CD57AB3008F45B2 /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					i386,
+					ppc,
+				);
+				GCC_MODEL_TUNING = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(DEV_HOME_PATH)/ossim/include",
+					"$(DEV_HOME_PATH)/libwms/include",
+					"$(DEV_HOME_PATH)/ossimPlanet/include",
+					"$(UNIV_HEADER_DEP)",
+				);
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				OTHER_CFLAGS = "";
+				OTHER_CPLUSPLUSFLAGS = (
+					"-DOSSIMPLANET_ENABLE_PREDATOR",
+					"-DOSSIMPLANET_ENABLE_EPHEMERIS",
+					"-g",
+				);
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
+			};
+			name = ReleaseLeopard;
+		};
+		18B28C500CD57AB3008F45B2 /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_MODEL_TUNING = "";
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				LIBRARY_SEARCH_PATHS = "$(UNIV_STATICLIB_DEP)";
+				LIBRARY_STYLE = DYNAMIC;
+				MACH_O_TYPE = mh_dylib;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				OTHER_LDFLAGS = /usr/lib/libz.dylib;
+				PRODUCT_NAME = ossimPlanet;
+				REZ_SEARCH_PATHS = (
+					"$(OSSIM_HOME_PATH)/xcode/ossim/Resources",
+					"$(REZ_SEARCH_PATHS)/**",
+				);
+				USER_HEADER_SEARCH_PATHS = "$(DEV_HOME_PATH)/ossim/include $(DEV_HOME_PATH)/libwms/include $(DEV_HOME_PATH)/ossimPlanet/include $(UNIV_HEADER_DEP)";
+				WARNING_CFLAGS = "-Wall";
+				WRAPPER_EXTENSION = framework;
+			};
+			name = ReleaseLeopard;
+		};
+		18E4E5560BE7802B00C8442B /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				COPY_PHASE_STRIP = NO;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = "";
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
+				GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1 = "EXTRA_INFO_STRING_FOR_MENU=\\\"Version\\";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				LIBRARY_SEARCH_PATHS = "$(UNIV_STATICLIB_DEP)";
+				LIBRARY_STYLE = DYNAMIC;
+				MACH_O_TYPE = mh_dylib;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				OTHER_LDFLAGS = /usr/lib/libz.dylib;
+				PRODUCT_NAME = ossimPlanet;
+				REZ_SEARCH_PATHS = (
+					"$(OSSIM_HOME_PATH)/xcode/ossim/Resources",
+					"$(REZ_SEARCH_PATHS)/**",
+				);
+				USER_HEADER_SEARCH_PATHS = "$(OSSIM_HOME_PATH)/include $(DEV_HOME_PATH)/libwms/include $(DEV_HOME_PATH)/ossimPlanet/include $(UNIV_HEADER_DEP) /usr/X11R6/include/freetype2 /usr/X11R6/include";
+				WARNING_CFLAGS = "-Wall";
+				WRAPPER_EXTENSION = framework;
+				ZERO_LINK = YES;
+			};
+			name = DebugNative;
+		};
+		18E4E5570BE7802B00C8442B /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH)";
+				GCC_MODEL_TUNING = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(DEV_HOME_PATH)/ossim/include",
+					"$(DEV_HOME_PATH)/libwms/include",
+					"$(DEV_HOME_PATH)/ossimPlanet/include",
+					"$(UNIV_HEADER_DEP)",
+				);
+				OTHER_CFLAGS = "";
+				OTHER_CPLUSPLUSFLAGS = (
+					"-DOSSIMPLANET_ENABLE_PREDATOR",
+					"-DOSSIMPLANET_ENABLE_EPHEMERIS",
+					"-g",
+				);
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = DebugNative;
+		};
+		433A4CD3100CED8D000B969C /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanettest;
+			};
+			name = Debug;
+		};
+		433A4CD4100CED8D000B969C /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanettest;
+			};
+			name = DebugNative;
+		};
+		433A4CD5100CED8D000B969C /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanettest;
+			};
+			name = DebugNativeLeopard;
+		};
+		433A4CD6100CED8D000B969C /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanettest;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		433A4CD7100CED8D000B969C /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanettest;
+			};
+			name = ReleaseLeopard;
+		};
+		43C6E2930FEFB4DA004B52F7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetklv;
+			};
+			name = Debug;
+		};
+		43C6E2940FEFB4DA004B52F7 /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetklv;
+			};
+			name = DebugNative;
+		};
+		43C6E2950FEFB4DA004B52F7 /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetklv;
+			};
+			name = DebugNativeLeopard;
+		};
+		43C6E2960FEFB4DA004B52F7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetklv;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		43C6E2970FEFB4DA004B52F7 /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetklv;
+			};
+			name = ReleaseLeopard;
+		};
+		43C6E29E0FEFB4EA004B52F7 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetviewer;
+			};
+			name = Debug;
+		};
+		43C6E29F0FEFB4EA004B52F7 /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetviewer;
+			};
+			name = DebugNative;
+		};
+		43C6E2A00FEFB4EA004B52F7 /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetviewer;
+			};
+			name = DebugNativeLeopard;
+		};
+		43C6E2A10FEFB4EA004B52F7 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetviewer;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		43C6E2A20FEFB4EA004B52F7 /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				INSTALL_PATH = /usr/local/bin;
+				PREBINDING = NO;
+				PRODUCT_NAME = ossimplanetviewer;
+			};
+			name = ReleaseLeopard;
+		};
+		4FADC24308B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				COPY_PHASE_STRIP = NO;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = "";
+				GCC_OPTIMIZATION_LEVEL = s;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1)",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS_QUOTED_1 = "EXTRA_INFO_STRING_FOR_MENU=\\\"Version\\";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				LIBRARY_SEARCH_PATHS = "$(UNIV_STATICLIB_DEP)";
+				LIBRARY_STYLE = DYNAMIC;
+				MACH_O_TYPE = mh_dylib;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				OTHER_LDFLAGS = /usr/lib/libz.dylib;
+				PRODUCT_NAME = ossimPlanet;
+				REZ_SEARCH_PATHS = (
+					"$(OSSIM_HOME_PATH)/xcode/ossim/Resources",
+					"$(REZ_SEARCH_PATHS)/**",
+				);
+				USER_HEADER_SEARCH_PATHS = "$(OSSIM_HOME_PATH)/include $(DEV_HOME_PATH)/libwms/include $(DEV_HOME_PATH)/ossimPlanet/include $(UNIV_HEADER_DEP) /usr/X11R6/include/freetype2 /usr/X11R6/include";
+				WARNING_CFLAGS = "-Wall";
+				WRAPPER_EXTENSION = framework;
+				ZERO_LINK = YES;
+			};
+			name = Debug;
+		};
+		4FADC24408B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_6)",
+					"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_7)",
+				);
+				FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_5 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_6 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_7 = "\"$(SRCROOT)/../../../ossim_dependencies/Frameworks\"";
+				FRAMEWORK_VERSION = A;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+				GCC_MODEL_TUNING = G4;
+				GCC_OPTIMIZATION_LEVEL = "$(inherited)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "";
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				LIBRARY_SEARCH_PATHS = "$(UNIV_STATICLIB_DEP)";
+				LIBRARY_STYLE = DYNAMIC;
+				MACH_O_TYPE = mh_dylib;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				OTHER_LDFLAGS = "$(inherited)";
+				PRODUCT_NAME = ossimPlanet;
+				REZ_SEARCH_PATHS = (
+					"$(OSSIM_HOME_PATH)/xcode/ossim/Resources",
+					"$(REZ_SEARCH_PATHS)/**",
+				);
+				SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
+				USER_HEADER_SEARCH_PATHS = "$(inherited)";
+				WARNING_CFLAGS = "-Wall";
+				WRAPPER_EXTENSION = framework;
+			};
+			name = Release;
+		};
+		4FADC24708B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					ppc,
+					i386,
+				);
+				GCC_MODEL_TUNING = "";
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(DEV_HOME_PATH)/ossim/include",
+					"$(DEV_HOME_PATH)/libwms/include",
+					"$(DEV_HOME_PATH)/ossimPlanet/include",
+					"$(UNIV_HEADER_DEP)",
+				);
+				OTHER_CFLAGS = "";
+				OTHER_CPLUSPLUSFLAGS = (
+					"-DOSSIMPLANET_ENABLE_PREDATOR",
+					"-DOSSIMPLANET_ENABLE_EPHEMERIS",
+					"-g",
+				);
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Debug;
+		};
+		4FADC24808B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 186EECAE0B1CDEF300F7886A /* common_settings.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(inherited)";
+				GCC_MODEL_TUNING = "";
+				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = NO;
+				GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = NO;
+				GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
+				GCC_WARN_ABOUT_MISSING_NEWLINE = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = NO;
+				GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO;
+				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
+				GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = NO;
+				GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				GCC_WARN_INHIBIT_ALL_WARNINGS = NO;
+				GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = NO;
+				GCC_WARN_MISSING_PARENTHESES = NO;
+				GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO;
+				GCC_WARN_PEDANTIC = NO;
+				GCC_WARN_PROTOTYPE_CONVERSION = NO;
+				GCC_WARN_SHADOW = NO;
+				GCC_WARN_SIGN_COMPARE = NO;
+				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+				GCC_WARN_UNINITIALIZED_AUTOS = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				GCC_WARN_UNUSED_FUNCTION = NO;
+				GCC_WARN_UNUSED_LABEL = NO;
+				GCC_WARN_UNUSED_PARAMETER = NO;
+				GCC_WARN_UNUSED_VALUE = NO;
+				GCC_WARN_UNUSED_VARIABLE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(DEV_HOME_PATH)/ossim/include",
+					"$(DEV_HOME_PATH)/libwms/include",
+					"$(DEV_HOME_PATH)/ossimPlanet/include",
+					"$(UNIV_HEADER_DEP)",
+				);
+				INSTALL_PATH = "@executable_path/../Frameworks";
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = (
+					"-DOSSIMPLANET_ENABLE_PREDATOR",
+					"-DOSSIMPLANET_ENABLE_EPHEMERIS",
+					"-g",
+				);
+				OTHER_LDFLAGS = "-lz";
+				PREBINDING = NO;
+				SDKROOT = /Developer/SDKs/MacOSX10.5.sdk;
+				WARNING_CFLAGS = "-Wall";
+			};
+			name = Release;
+		};
+		EE9D265B0DD888FB005A8951 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				PRODUCT_NAME = All;
+			};
+			name = Debug;
+		};
+		EE9D265C0DD888FB005A8951 /* DebugNative */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = All;
+			};
+			name = DebugNative;
+		};
+		EE9D265D0DD888FB005A8951 /* DebugNativeLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = All;
+			};
+			name = DebugNativeLeopard;
+		};
+		EE9D265E0DD888FB005A8951 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				PRODUCT_NAME = All;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		EE9D265F0DD888FB005A8951 /* ReleaseLeopard */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = All;
+			};
+			name = ReleaseLeopard;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		433A4CD2100CED8D000B969C /* Build configuration list for PBXNativeTarget "ossimplanettest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				433A4CD3100CED8D000B969C /* Debug */,
+				433A4CD4100CED8D000B969C /* DebugNative */,
+				433A4CD5100CED8D000B969C /* DebugNativeLeopard */,
+				433A4CD6100CED8D000B969C /* Release */,
+				433A4CD7100CED8D000B969C /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		43C6E2B00FEFB4F1004B52F7 /* Build configuration list for PBXNativeTarget "ossimplanetklv" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				43C6E2930FEFB4DA004B52F7 /* Debug */,
+				43C6E2940FEFB4DA004B52F7 /* DebugNative */,
+				43C6E2950FEFB4DA004B52F7 /* DebugNativeLeopard */,
+				43C6E2960FEFB4DA004B52F7 /* Release */,
+				43C6E2970FEFB4DA004B52F7 /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		43C6E2B10FEFB4F1004B52F7 /* Build configuration list for PBXNativeTarget "ossimplanetviewer" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				43C6E29E0FEFB4EA004B52F7 /* Debug */,
+				43C6E29F0FEFB4EA004B52F7 /* DebugNative */,
+				43C6E2A00FEFB4EA004B52F7 /* DebugNativeLeopard */,
+				43C6E2A10FEFB4EA004B52F7 /* Release */,
+				43C6E2A20FEFB4EA004B52F7 /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "ossimPlanet" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24308B4156D00ABE55E /* Debug */,
+				18E4E5560BE7802B00C8442B /* DebugNative */,
+				18A9BCBF0CDA158B00F4581A /* DebugNativeLeopard */,
+				4FADC24408B4156D00ABE55E /* Release */,
+				18B28C500CD57AB3008F45B2 /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "ossimPlanet" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24708B4156D00ABE55E /* Debug */,
+				18E4E5570BE7802B00C8442B /* DebugNative */,
+				18A9BCBE0CDA158B00F4581A /* DebugNativeLeopard */,
+				4FADC24808B4156D00ABE55E /* Release */,
+				18B28C4F0CD57AB3008F45B2 /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		EE9D26650DD88940005A8951 /* Build configuration list for PBXAggregateTarget "All" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				EE9D265B0DD888FB005A8951 /* Debug */,
+				EE9D265C0DD888FB005A8951 /* DebugNative */,
+				EE9D265D0DD888FB005A8951 /* DebugNativeLeopard */,
+				EE9D265E0DD888FB005A8951 /* Release */,
+				EE9D265F0DD888FB005A8951 /* ReleaseLeopard */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/ossim-planet.git



More information about the Pkg-grass-devel mailing list