diff --git a/src/BuildTiles/CMakeLists.txt b/src/BuildTiles/CMakeLists.txt
index 692337a1..0fa541e3 100644
--- a/src/BuildTiles/CMakeLists.txt
+++ b/src/BuildTiles/CMakeLists.txt
@@ -5,5 +5,4 @@ include_directories(${PROJECT_SOURCE_DIR}/src/BuildTiles)
 
 add_subdirectory(Osgb36)
 add_subdirectory(Parallel)
-add_subdirectory(Match)
 add_subdirectory(Main)
diff --git a/src/BuildTiles/Main/CMakeLists.txt b/src/BuildTiles/Main/CMakeLists.txt
index 2b93962c..8d767d1a 100644
--- a/src/BuildTiles/Main/CMakeLists.txt
+++ b/src/BuildTiles/Main/CMakeLists.txt
@@ -12,7 +12,6 @@ set_target_properties(tg-construct PROPERTIES
 
 target_link_libraries(tg-construct
     Osgb36  
-    Match
     Polygon Geometry
     Array landcover poly2tri
     ${GDAL_LIBRARY}
diff --git a/src/BuildTiles/Main/construct.cxx b/src/BuildTiles/Main/construct.cxx
index 41539ecb..16950fbe 100644
--- a/src/BuildTiles/Main/construct.cxx
+++ b/src/BuildTiles/Main/construct.cxx
@@ -40,11 +40,11 @@
 #include <simgear/io/sg_binobj.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/debug/logstream.hxx>
+#include <CGAL/Plane_3.h>
 
 #include <Geometry/poly_support.hxx>
 #include <Geometry/poly_extra.hxx>
 
-#include <Match/match.hxx>
 #include <Osgb36/osgb36.hxx>
 
 #include "construct.hxx"
@@ -72,8 +72,6 @@ static const double quarter_cover_size = cover_size * 0.25;
 // Constructor
 TGConstruct::TGConstruct():
         useUKGrid(false),
-        writeSharedEdges(true),
-        useOwnSharedEdges(false),
         ignoreLandmass(false),
         debug_all(false),
         ds_id((void*)-1)
@@ -92,6 +90,20 @@ TGConstruct::~TGConstruct() {
     nodes.clear();
 }
 
+// paths
+void TGConstruct::set_paths( const std::string work, const std::string share, const std::string output, const std::vector<std::string> load ) {
+    work_base   = work;
+    share_base  = share;
+    output_base = output;
+    load_dirs   = load;
+}
+
+void TGConstruct::set_options( bool uk_grid, bool ignore_lm, double n ) {
+    useUKGrid      = uk_grid;
+    ignoreLandmass = ignore_lm;
+    nudge          = n;
+}
+
 void TGConstruct::set_debug( std::string path, std::vector<string> area_defs, std::vector<string> shape_defs )
 {
     SG_LOG(SG_GENERAL, SG_ALERT, "Set debug Path " << path);
@@ -195,13 +207,20 @@ bool TGConstruct::IsDebugArea( unsigned int area )
 void TGConstruct::WriteDebugShape( const char* layer_name, const TGShape& shape )
 {
     char name[64];
+    char feature_name[128];
     shape.GetName( name );
 
     ds_id = tgShapefileOpenDatasource( ds_name );
     l_id  = tgShapefileOpenLayer( ds_id, layer_name );
 
-    tgShapefileCreateFeature( ds_id, l_id, shape.clip_mask, name );
+    sprintf( feature_name, "%s_clipmask", name );
+    tgShapefileCreateFeature( ds_id, l_id, shape.clip_mask, feature_name );
 
+    for (unsigned int i=0; i<shape.sps.size(); i++) {
+        sprintf( feature_name, "%s_%d", name, i );
+        tgShapefileCreateFeature( ds_id, l_id, shape.sps[i].get_poly(), feature_name );
+    }
+    
     // close after each write
     ds_id = tgShapefileCloseDatasource( ds_id );
 }
@@ -239,7 +258,7 @@ void TGConstruct::LoadElevationArray( void ) {
     int i;
 
     for ( i = 0; i < (int)load_dirs.size(); ++i ) {
-        string array_path = get_work_base() + "/" + load_dirs[i] + "/" + base + "/" + bucket.gen_index_str();
+        string array_path = work_base + "/" + load_dirs[i] + "/" + base + "/" + bucket.gen_index_str();
 
         if ( array.open(array_path) ) {
             break;
@@ -590,7 +609,7 @@ int TGConstruct::LoadLandclassPolys( void ) {
 
     // load 2D polygons from all directories provided
     for ( i = 0; i < (int)load_dirs.size(); ++i ) {
-        poly_path = get_work_base() + "/" + load_dirs[i] + '/' + base;
+        poly_path = work_base + "/" + load_dirs[i] + '/' + base;
 
         string tile_str = bucket.gen_index_str();
         simgear::Dir d(poly_path);
@@ -1158,7 +1177,7 @@ TGPolygon TGConstruct::linear_tex_coords( const TGPolygon& tri, const TGTexParam
 // collect custom objects and move to scenery area
 void TGConstruct::AddCustomObjects( void ) {
     // Create/open the output .stg file for writing
-    SGPath dest_d(get_output_base().c_str());
+    SGPath dest_d(output_base.c_str());
     dest_d.append(bucket.gen_base_path().c_str());
     string dest_dir = dest_d.str_native();
     SGPath dest_i(dest_d);
@@ -1180,7 +1199,7 @@ void TGConstruct::AddCustomObjects( void ) {
     char name[256];
 
     for ( int i = 0; i < (int)load_dirs.size(); ++i ) {
-        SGPath base(get_work_base().c_str());
+        SGPath base(work_base.c_str());
         base.append(load_dirs[i]);
         base.append( bucket.gen_base_path() );
         SGPath index(base);
@@ -1807,27 +1826,6 @@ void TGConstruct::CalcPointNormals( void )
     }
 }
 
-void TGConstruct::LoadSharedEdgeData( void )
-{
-    match.load_neighbor_shared( bucket, share_base );
-    if ( useOwnSharedEdges ) {
-        match.load_missing_shared( bucket, share_base );
-    }
-    match.add_shared_nodes( this );
-}
-
-void TGConstruct::SaveSharedEdgeData( void )
-{
-    match.split_tile( bucket, this );
-    SG_LOG(SG_GENERAL, SG_ALERT, "Tile Split");
-
-    if ( writeSharedEdges ) {
-        SG_LOG(SG_GENERAL, SG_ALERT, "write shared edges");
-
-        match.write_shared( bucket, share_base );
-    }
-}
-
 void TGConstruct::TesselatePolys( void )
 {
     // tesselate the polygons and prepair them for final output
@@ -1854,6 +1852,10 @@ void TGConstruct::TesselatePolys( void )
                         shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) << 
                         ": id = " << id );
 
+                if ( IsDebugShape( id ) ) {
+                    SG_LOG( SG_CLIPPER, SG_INFO, std::setprecision(12) << std::fixed << poly );
+                }
+
 //              TGPolygon tri = polygon_tesselate_alt_with_extra( poly, poly_extra, false );
                 TGPolygon tri = polygon_tesselate_alt_with_extra_cgal( poly, poly_extra, false );
 
@@ -1980,7 +1982,7 @@ void TGConstruct::WriteBtgFile( void )
     group_list fans_tc; fans_tc.clear();
     string_list fan_materials; fan_materials.clear();
 
-    string base = get_output_base();
+    string base = output_base;
     string binname = bucket.gen_index_str();
     binname += ".btg";
     string txtname = bucket.gen_index_str();
@@ -2117,6 +2119,66 @@ void TGConstruct::CalcTextureCoordinates( void )
     }
 }
 
+void TGConstruct::SaveSharedEdgeData( int stage )
+{
+    string dir;
+    string file;
+
+    switch( stage ) {
+        case 1:
+        {
+            point_list north, south, east, west;
+            int nCount;
+
+            nodes.get_geod_edge( bucket, north, south, east, west );
+
+            dir  = share_base + "/stage1/" + bucket.gen_base_path();
+
+            SGPath sgp( dir );
+            sgp.append( "dummy" );
+            sgp.create_dir( 0755 );
+
+            file = dir + "/" + bucket.gen_index_str() + "_edges";
+            std::ofstream ofs_e( file.c_str() );
+
+            // first, set the precision
+            ofs_e << std::setprecision(12);
+            ofs_e << std::fixed;
+
+            // north
+            nCount = north.size();
+            ofs_e << nCount << "\n";
+            for (int i=0; i<nCount; i++) {
+                ofs_e << north[i];
+            }
+
+            // south
+            nCount = south.size();
+            ofs_e << nCount << "\n";
+            for (int i=0; i<nCount; i++) {
+                ofs_e << south[i];
+            }
+
+            // east
+            nCount = east.size();
+            ofs_e << nCount << "\n";
+            for (int i=0; i<nCount; i++) {
+                ofs_e << east[i];
+            }
+
+            // west
+            nCount = west.size();
+            ofs_e << nCount << "\n";
+            for (int i=0; i<nCount; i++) {
+                ofs_e << west[i];
+            }
+
+            ofs_e.close();
+        }
+        break;
+    }
+}
+
 void TGConstruct::SaveToIntermediateFiles( int stage )
 {
     string dir;
@@ -2126,19 +2188,27 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
         case 1:     // Save the clipped polys and node list
         {
             dir  = share_base + "/stage1/" + bucket.gen_base_path();
-            file = dir        + "/"        + bucket.gen_index_str() + "_clipped_polys";
 
             SGPath sgp( dir );
             sgp.append( "dummy" );
             sgp.create_dir( 0755 );
 
+            file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
             std::ofstream ofs_cp( file.c_str() );
+
+            // first, set the precision
+            ofs_cp << std::setprecision(15);
+            ofs_cp << std::fixed;
             ofs_cp << polys_clipped;
             ofs_cp.close();
 
-            file = dir + "/" + bucket.gen_index_str() + "_nodes";
 
+            file = dir + "/" + bucket.gen_index_str() + "_nodes";
             std::ofstream ofs_n( file.c_str() );
+
+            // first, set the precision
+            ofs_n << std::setprecision(15);
+            ofs_n << std::fixed;
             ofs_n << nodes;
             ofs_n.close();
             break;
@@ -2147,19 +2217,26 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
         case 2:     // Save the clipped polys and node list
         {
             dir  = share_base + "/stage2/" + bucket.gen_base_path();
-            file = dir        + "/"        + bucket.gen_index_str() + "_clipped_polys";
 
             SGPath sgp( dir );
             sgp.append( "dummy" );
             sgp.create_dir( 0755 );
 
+            file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
             std::ofstream ofs_cp( file.c_str() );
+
+            // first, set the precision
+            ofs_cp << std::setprecision(15);
+            ofs_cp << std::fixed;
             ofs_cp << polys_clipped;
             ofs_cp.close();
 
             file = dir + "/" + bucket.gen_index_str() + "_nodes";
-
             std::ofstream ofs_n( file.c_str() );
+
+            // first, set the precision
+            ofs_n << std::setprecision(15);
+            ofs_n << std::fixed;
             ofs_n << nodes;
             ofs_n.close();
             break;
@@ -2167,6 +2244,103 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
     }
 }
 
+void TGConstruct::LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west )
+{
+    string dir;
+    string file;
+    Point3D pt;
+    int nCount;
+
+    dir  = share_base + "/stage1/" + b.gen_base_path();
+    file = dir + "/" + b.gen_index_str() + "_edges";
+    std::ifstream ifs_edges( file.c_str() );
+
+    north.clear();
+    south.clear();
+    east.clear();
+    west.clear();
+
+    if ( ifs_edges.is_open() ) {
+        // North
+        ifs_edges >> nCount;
+        SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary");
+        for (int i=0; i<nCount; i++) {
+            ifs_edges >> pt;
+            north.push_back(pt);
+        }
+
+        // South
+        ifs_edges >> nCount;
+        SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary");
+        for (int i=0; i<nCount; i++) {
+            ifs_edges >> pt;
+            south.push_back(pt);
+        }
+
+        // East
+        ifs_edges >> nCount;
+        SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary");
+        for (int i=0; i<nCount; i++) {
+            ifs_edges >> pt;
+            east.push_back(pt);
+        }
+
+        // West
+        ifs_edges >> nCount;
+        SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary");
+        for (int i=0; i<nCount; i++) {
+            ifs_edges >> pt;
+            west.push_back(pt);
+        }
+
+        ifs_edges.close();
+    }
+}
+
+void TGConstruct::LoadSharedEdgeData( int stage )
+{
+    switch( stage ) {
+        case 1:
+        {
+            // we need to read just 4 buckets for stage 1 - 1 for each edge
+            point_list north, south, east, west;
+            SGBucket   nb, sb, eb, wb;
+            double     clon = bucket.get_center_lon();
+            double     clat = bucket.get_center_lat();
+
+            // Read North tile and add its southern nodes
+            nb = sgBucketOffset(clon, clat, 0, 1);
+            LoadNeighboorEdgeDataStage1( nb, north, south, east, west );
+            // Add southern nodes from northern tile
+            for (unsigned int i=0; i<south.size(); i++) {
+                nodes.unique_add( south[i] );
+            }
+
+            // Read South Tile and add its northern nodes
+            sb = sgBucketOffset(clon, clat, 0, -1);
+            LoadNeighboorEdgeDataStage1( sb, north, south, east, west );
+            for (unsigned  int i=0; i<north.size(); i++) {
+                nodes.unique_add( north[i] );
+            }
+
+            // Read East Tile and add its western nodes
+            eb = sgBucketOffset(clon, clat, 1, 0);
+            LoadNeighboorEdgeDataStage1( eb, north, south, east, west );
+            for (unsigned  int i=0; i<west.size(); i++) {
+                nodes.unique_add( west[i] );
+            }
+
+            // Read West Tile and add its eastern nodes
+            wb = sgBucketOffset(clon, clat, -1, 0);
+            LoadNeighboorEdgeDataStage1( wb, north, south, east, west );
+            for (unsigned  int i=0; i<east.size(); i++) {
+                nodes.unique_add( east[i] );
+            }
+        }
+        break;
+    }
+}
+
 void TGConstruct::LoadFromIntermediateFiles( int stage )
 {
     string dir;
@@ -2253,6 +2427,10 @@ void TGConstruct::ConstructBucketStage1() {
     // Clean the polys - after this, we shouldn't change their shape (other than slightly for
     // fix T-Junctions - as This is the end of the first pass for multicore design
     CleanClippedPolys();
+
+    // STEP 6)
+    // Save the tile boundary info for stage 2 (just x,y coords of points on the boundary)
+    SaveSharedEdgeData( 1 );
 }
 
 void TGConstruct::ConstructBucketStage2() {
@@ -2267,16 +2445,13 @@ void TGConstruct::ConstructBucketStage2() {
         strcpy( ds_name, "" );
     }
 
-    // TEMP TEMP TEMP - save in intermediate file...)
-    // Load grid of elevation data (Array)
+    // STEP 7) 
+    // Need the array of elevation data for stage 2
     LoadElevationArray();
 
-    // restore construct from stage1 intermediate files
-    LoadFromIntermediateFiles( 1 );
-
     // STEP 6)
     // Merge in Shared data - should just be x,y nodes on the borders from stage1
-    LoadSharedEdgeData();
+    LoadSharedEdgeData( 1 );
 
     // STEP 7) 
     // Fix T-Junctions by finding nodes that lie close to polygon edges, and
@@ -2296,6 +2471,11 @@ void TGConstruct::ConstructBucketStage2() {
     // STEP 10)
     // Interpolate elevations, and flatten stuff
     CalcElevations();
+
+    // STEP 11)
+    // Save the tile boundary info for stage 3
+    // includes elevation info, and a list of connected triangles
+    SaveSharedEdgeData( 2 );
 }
 
 void TGConstruct::ConstructBucketStage3() {
@@ -2310,15 +2490,6 @@ void TGConstruct::ConstructBucketStage3() {
         strcpy( ds_name, "" );
     }
 
-    // TEMP TEMP TEMP )
-    // Load grid of elevation data (Array)
-    LoadElevationArray();
-
-    // STEP 11)
-    // Merge in Shared data - nodes on the shared edge should have x,y,z - we'll average the z
-    // shared edge data nodes also have 1 or 2 connected nodes so we can see their connected faces
-    //LoadSharedEdgeData();
-
     // STEP 12)
     // Generate face_connected list
     LookupFacesPerNode();
@@ -2344,10 +2515,6 @@ void TGConstruct::ConstructBucketStage3() {
     // Calculate Texture Coordinates
     CalcTextureCoordinates();
 
-    // STEP 15)         // only if not stages...
-    // Write out the shared edge data
-    SaveSharedEdgeData();
-
     // STEP 16)
     // Generate the btg file
     WriteBtgFile();
diff --git a/src/BuildTiles/Main/construct.hxx b/src/BuildTiles/Main/construct.hxx
index 5f03f5c0..39b80c91 100644
--- a/src/BuildTiles/Main/construct.hxx
+++ b/src/BuildTiles/Main/construct.hxx
@@ -117,27 +117,22 @@ public:
 inline std::istream& operator >> ( std::istream& in, TGShape& p)
 {
     int i, count;
-    TGSuperPoly sp;
-    TGTexParams tp;
 
     // First, load the clipmask
-    SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: clipmask" );
     in >> p.clip_mask;
 
     // Then load superpolys
     in >> count;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: superpoly count " << count );
     for (i=0; i<count; i++) {
-        SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: load superpoly " << i );
+        TGSuperPoly sp;
         in >> sp;
         p.sps.push_back( sp );
     }
 
     // Then load texparams
     in >> count;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: texparams count " << count );
     for (i=0; i<count; i++) {
-        SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: load texparam " << i );
+        TGTexParams tp;
         in >> tp;
         p.tps.push_back( tp );
     }
@@ -326,10 +321,8 @@ inline std::istream& operator >> ( std::istream& in, TGLandclass& lc)
     // Load all landclass shapes
     for (i=0; i<TG_MAX_AREA_TYPES; i++) {
         in >> count;
-        SG_LOG(SG_GENERAL, SG_ALERT, "Loading Landclass: area " << i << " size is " << count );
 
         for (j=0; j<count; j++) {
-            SG_LOG(SG_GENERAL, SG_ALERT, "Loading Landclass: load shape " << j << " of " << count );
             TGShape shape;
 
             in >> shape;
@@ -345,10 +338,6 @@ inline std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
     int i, j, count;
     TGShape shape;
 
-    // first, set the precision
-    out << std::setprecision(12);
-    out << std::fixed;
-
     // Save all landclass shapes
     for (i=0; i<TG_MAX_AREA_TYPES; i++) {
         count = lc.shapes[i].size();
@@ -388,18 +377,12 @@ private:
     // with the UK grid
     bool useUKGrid;
 
-    double nudge;
-
-    // flag indicating whether this is a rebuild and Shared edge
-    // data should only be used for fitting, but not rewritten
-    bool writeSharedEdges;
-    // flag indicating whether the shared edge data of the
-    // tile to be built should be used in addition to neighbour data
-    bool useOwnSharedEdges;
-
     // flag indicating whether to ignore the landmass
     bool ignoreLandmass;
 
+    // I think we should remove this
+    double nudge;
+
     // path to the debug shapes
     std::string debug_path;
 
@@ -431,7 +414,7 @@ private:
     TGNodes nodes;
 
     // SHared Edges match data
-    TGMatch match;
+    // TGMatch match;
 
 private:
     // Load Data
@@ -452,6 +435,11 @@ private:
     void LoadSharedEdgeData( void );
     void SaveSharedEdgeData( void );
 
+    void LoadSharedEdgeData( int stage );
+    void LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west );
+
+    void SaveSharedEdgeData( int stage );
+
     // Polygon Cleaning
     void CleanClippedPolys( void );
     void FixTJunctions( void );
@@ -523,6 +511,9 @@ public:
     inline void set_cover (const std::string &s) { cover = s; }
 
     // paths
+    void set_paths( const std::string work, const std::string share, const std::string output, const std::vector<std::string> load_dirs );
+
+#if 0
     inline std::string get_work_base() const { return work_base; }
     inline void set_work_base( const std::string s ) { work_base = s; }
     inline std::string get_output_base() const { return output_base; }
@@ -530,22 +521,21 @@ public:
     inline std::string get_share_base() const { return share_base; }
     inline void set_share_base( const std::string s ) { share_base = s; }
     inline void set_load_dirs( const std::vector<std::string> ld ) { load_dirs = ld; }
+#endif
 
+    void set_options( bool uk_grid, bool ignore_lm, double n );
+
+#if 0
     // UK grid flag
     inline bool get_useUKGrid() const { return useUKGrid; }
     inline void set_useUKGrid( const bool b ) { useUKGrid = b; }
-    
+
     // Nudge
     inline void set_nudge( double n ) { nudge = n; }
 
-    // shared edge write flag
-    inline void set_write_shared_edges( const bool b ) { writeSharedEdges = b; }
-    
-    // own shared edge use flag
-    inline void set_use_own_shared_edges( const bool b ) { useOwnSharedEdges = b; }
-    
     // ignore landmass flag
     inline void set_ignore_landmass( const bool b) { ignoreLandmass = b; }
+#endif
 
     // TODO : REMOVE
     inline TGNodes* get_nodes() { return &nodes; }
diff --git a/src/BuildTiles/Main/main.cxx b/src/BuildTiles/Main/main.cxx
index df2ada8b..79372261 100644
--- a/src/BuildTiles/Main/main.cxx
+++ b/src/BuildTiles/Main/main.cxx
@@ -52,9 +52,6 @@
 #include <Geometry/poly_support.hxx>
 #include <landcover/landcover.hxx>
 
-// TODO : Get rid of match...
-#include <Match/match.hxx>
-
 #include "construct.hxx"
 #include "usgs.hxx"
 
@@ -147,8 +144,6 @@ static void usage( const string name ) {
     SG_LOG(SG_GENERAL, SG_ALERT, "  --priorities=<filename>");
     SG_LOG(SG_GENERAL, SG_ALERT, "  --usgs-map=<filename>");
     SG_LOG(SG_GENERAL, SG_ALERT, "  --useUKgrid");
-    SG_LOG(SG_GENERAL, SG_ALERT, "  --no-write-shared-edges");
-    SG_LOG(SG_GENERAL, SG_ALERT, "  --use-own-shared-edges");
     SG_LOG(SG_GENERAL, SG_ALERT, "  --ignore-landmass");
     SG_LOG(SG_GENERAL, SG_ALERT, " ] <load directory...>");
     exit(-1);
@@ -174,17 +169,9 @@ int main(int argc, char **argv) {
     // flag indicating whether UK grid should be used for in-UK
     // texture coordinate generation
     bool useUKgrid = false;
-    
-    // flag indicating whether this is a rebuild and Shared edge
-    // data should only be used for fitting, but not rewritten
-    bool writeSharedEdges = true;
-    
-    // flag indicating whether the shared edge data of the
-    // tile to be built should be used in addition to neighbour data
-    bool useOwnSharedEdges = false;
-    
+
     bool ignoreLandmass = false;
-    
+
     sglog().setLogLevels( SG_ALL, SG_INFO );
 
     // Initialize shapefile support (for debugging)
@@ -223,10 +210,6 @@ int main(int argc, char **argv) {
             usgs_map_file = arg.substr(11);
         } else if (arg.find("--useUKgrid") == 0) {
             useUKgrid = true;
-        } else if (arg.find("--no-write-shared-edges") == 0) {
-            writeSharedEdges = false;
-        } else if (arg.find("--use-own-shared-edges") == 0) {
-            useOwnSharedEdges = true;
         } else if (arg.find("--ignore-landmass") == 0) {
             ignoreLandmass = true;
         } else if (arg.find("--debug-dir=") == 0) {
@@ -283,15 +266,8 @@ int main(int argc, char **argv) {
 
             all_stages = new TGConstruct();
             all_stages->set_cover( cover );
-            all_stages->set_work_base( work_dir );
-            all_stages->set_output_base( output_dir );
-            all_stages->set_share_base( share_dir );
-            all_stages->set_load_dirs( load_dirs );
-            all_stages->set_useUKGrid( useUKgrid );
-            all_stages->set_write_shared_edges( writeSharedEdges );
-            all_stages->set_use_own_shared_edges( useOwnSharedEdges );
-            all_stages->set_ignore_landmass( ignoreLandmass );
-            all_stages->set_nudge( nudge );
+            all_stages->set_paths( work_dir, share_dir, output_dir, load_dirs );
+            all_stages->set_options( useUKgrid, ignoreLandmass, nudge );
             all_stages->set_bucket( b );
             all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
 
@@ -316,15 +292,8 @@ int main(int argc, char **argv) {
 
                 all_stages = new TGConstruct();
                 all_stages->set_cover( cover );
-                all_stages->set_work_base( work_dir );
-                all_stages->set_output_base( output_dir );
-                all_stages->set_share_base( share_dir );
-                all_stages->set_load_dirs( load_dirs );
-                all_stages->set_useUKGrid( useUKgrid );
-                all_stages->set_write_shared_edges( writeSharedEdges );
-                all_stages->set_use_own_shared_edges( useOwnSharedEdges );
-                all_stages->set_ignore_landmass( ignoreLandmass );
-                all_stages->set_nudge( nudge );
+                all_stages->set_paths( work_dir, share_dir, output_dir, load_dirs );
+                all_stages->set_options( useUKgrid, ignoreLandmass, nudge );
                 all_stages->set_bucket( b_min );
                 all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
 
@@ -341,7 +310,6 @@ int main(int argc, char **argv) {
                 SG_LOG(SG_GENERAL, SG_ALERT, "  construction area spans tile boundaries");
                 SG_LOG(SG_GENERAL, SG_ALERT, "  dx = " << dx << "  dy = " << dy);
 
-
                 // construct stage 1
                 for ( j = 0; j <= dy; j++ ) {
                     for ( i = 0; i <= dx; i++ ) {
@@ -356,15 +324,8 @@ int main(int argc, char **argv) {
                             
                             stage1 = new TGConstruct();
                             stage1->set_cover( cover );
-                            stage1->set_work_base( work_dir );
-                            stage1->set_output_base( output_dir );
-                            stage1->set_share_base( share_dir );
-                            stage1->set_load_dirs( load_dirs );
-                            stage1->set_useUKGrid( useUKgrid );
-                            stage1->set_write_shared_edges( writeSharedEdges );
-                            stage1->set_use_own_shared_edges( useOwnSharedEdges );
-                            stage1->set_ignore_landmass( ignoreLandmass );
-                            stage1->set_nudge( nudge );
+                            stage1->set_paths( work_dir, share_dir, output_dir, load_dirs );
+                            stage1->set_options( useUKgrid, ignoreLandmass, nudge );
                             stage1->set_bucket( b_cur );
                             stage1->set_debug( debug_dir, debug_defs );
 
@@ -392,15 +353,8 @@ int main(int argc, char **argv) {
 
                             stage2 = new TGConstruct();
                             stage2->set_cover( cover );
-                            stage2->set_work_base( work_dir );
-                            stage2->set_output_base( output_dir );
-                            stage2->set_share_base( share_dir );
-                            stage2->set_load_dirs( load_dirs );
-                            stage2->set_useUKGrid( useUKgrid );
-                            stage2->set_write_shared_edges( writeSharedEdges );
-                            stage2->set_use_own_shared_edges( useOwnSharedEdges );
-                            stage2->set_ignore_landmass( ignoreLandmass );
-                            stage2->set_nudge( nudge );
+                            stage2->set_paths( work_dir, share_dir, output_dir, load_dirs );
+                            stage2->set_options( useUKgrid, ignoreLandmass, nudge );
                             stage2->set_bucket( b_cur );
                             stage2->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
 
@@ -429,15 +383,8 @@ int main(int argc, char **argv) {
 
                             stage3 = new TGConstruct();
                             stage3->set_cover( cover );
-                            stage3->set_work_base( work_dir );
-                            stage3->set_output_base( output_dir );
-                            stage3->set_share_base( share_dir );
-                            stage3->set_load_dirs( load_dirs );
-                            stage3->set_useUKGrid( useUKgrid );
-                            stage3->set_write_shared_edges( writeSharedEdges );
-                            stage3->set_use_own_shared_edges( useOwnSharedEdges );
-                            stage3->set_ignore_landmass( ignoreLandmass );
-                            stage3->set_nudge( nudge );
+                            stage3->set_paths( work_dir, share_dir, output_dir, load_dirs );
+                            stage3->set_options( useUKgrid, ignoreLandmass, nudge );
                             stage3->set_bucket( b_cur );
                             stage3->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
 
@@ -460,15 +407,8 @@ int main(int argc, char **argv) {
 
         all_stages = new TGConstruct();
         all_stages->set_cover( cover );
-        all_stages->set_work_base( work_dir );
-        all_stages->set_output_base( output_dir );
-        all_stages->set_share_base( share_dir );
-        all_stages->set_load_dirs( load_dirs );
-        all_stages->set_useUKGrid( useUKgrid );
-        all_stages->set_write_shared_edges( writeSharedEdges );
-        all_stages->set_use_own_shared_edges( useOwnSharedEdges );
-        all_stages->set_ignore_landmass( ignoreLandmass );
-        all_stages->set_nudge( nudge );
+        all_stages->set_paths( work_dir, share_dir, output_dir, load_dirs );
+        all_stages->set_options( useUKgrid, ignoreLandmass, nudge );
         all_stages->set_bucket( b );
         all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
 
diff --git a/src/BuildTiles/Match/CMakeLists.txt b/src/BuildTiles/Match/CMakeLists.txt
deleted file mode 100644
index 86efd725..00000000
--- a/src/BuildTiles/Match/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-add_library(Match STATIC 
-    match.cxx match.hxx
-)
diff --git a/src/BuildTiles/Match/match.cxx b/src/BuildTiles/Match/match.cxx
deleted file mode 100644
index 07db42f3..00000000
--- a/src/BuildTiles/Match/match.cxx
+++ /dev/null
@@ -1,874 +0,0 @@
-// match.cxx -- Handle details of matching up tile edges
-//
-// Written by Curtis Olson, started March 1998.
-//
-// Copyright (C) 1998 - 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// $Id: match.cxx,v 1.21 2004-11-19 22:25:49 curt Exp $
-
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-#include <Geometry/point3d.hxx>
-#include <Geometry/tg_nodes.hxx>
-#include <Polygon/point2d.hxx>
-#include "match.hxx"
-#include <Main/construct.hxx>
-#include <simgear/math/sg_geodesy.hxx>
-#include <simgear/misc/sgstream.hxx>
-#include <simgear/misc/sg_path.hxx>
-#include <simgear/debug/logstream.hxx>
-
-#include <stdlib.h>
-
-//using std::cout;
-//using std::endl;
-using std::string;
-
-TGMatch::TGMatch( void ) {
-}
-
-
-TGMatch::~TGMatch( void ) {
-}
-
-
-// scan the specified share file for the specified information
-void TGMatch::scan_share_file( const string& dir, const SGBucket& b, 
-			       neighbor_type search, neighbor_type dest )
-{
-    string file = dir + "/"  + b.gen_base_path() + "/" + b.gen_index_str();
-
-//    cout << "reading shared data from " << file << endl;
-
-    sg_gzifstream in( file );
-    if ( !in.is_open() ) {
-//        cout << "Cannot open file: " << file << endl;
-	return;
-    }
-
-//    cout << "open successful." << endl;
-
-    string target;
-    if ( search == SW_Corner ) {
-	target = "sw_node";
-    } else if ( search == SE_Corner ) {
-	target = "se_node";
-    } else if ( search == NE_Corner ) {
-	target = "ne_node";
-    } else if ( search == NW_Corner ) {
-	target = "nw_node";
-    } else if ( search == NORTH ) {
-	target = "n_node";
-    } else if ( search == SOUTH ) {
-	target = "s_node";
-    } else if ( search == EAST ) {
-	target = "e_node";
-    } else if ( search == WEST ) {
-	target = "w_node";
-    }
-
-    string key;
-    Point3D node, normal;
-    while ( in ) {
-	in >> key;
-	in >> node;
-	if ( key == target ) {
-	    // cout << key << " " << node << endl;
-	    in >> key;
-	    in >> normal;
-
-	    if ( dest == SW_Corner ) {
-		sw_node = node;
-		sw_normal = normal;
-		sw_flag = true;
-	    } else if ( dest == SE_Corner ) {
-		se_node = node;
-		se_normal = normal;
-		se_flag = true;
-	    } else if ( dest == NE_Corner ) {
-		ne_node = node;
-		ne_normal = normal;
-		ne_flag = true;
-	    } else if ( dest == NW_Corner ) {
-		nw_node = node;
-		nw_normal = normal;
-		nw_flag = true;
-	    } else if ( dest == NORTH ) {
-		north_nodes.push_back(node);
-		north_normals.push_back(normal);
-		north_flag = true;
-	    } else if ( dest == SOUTH ) {
-		south_nodes.push_back(node);
-		south_normals.push_back(normal);
-		south_flag = true;
-	    } else if ( dest == EAST ) {
-		east_nodes.push_back(node);
-		east_normals.push_back(normal);
-		east_flag = true;
-	    } else if ( dest == WEST ) {
-		west_nodes.push_back(node);
-		west_normals.push_back(normal);
-		west_flag = true;
-	    }
-	} else if ( (target == "n_node") && (key == "n_null") ) {
-	    south_flag = true;
-	} else if ( (target == "s_node") && (key == "s_null") ) {
-	    north_flag = true;
-	} else if ( (target == "e_node") && (key == "e_null") ) {
-	    west_flag = true;
-	} else if ( (target == "w_node") && (key == "w_null") ) {
-	    east_flag = true;
-	}
-    }
-}
-
-
-// try to find info for the specified shared component
-void TGMatch::load_shared( SGBucket b, string base, neighbor_type n ) {
-    double clon = b.get_center_lon();
-    double clat = b.get_center_lat();
-
-    SGBucket cb;
-
-    if ( n == SW_Corner ) {
-	// cout << "searching for SW corner data" << endl;
-	cb = sgBucketOffset(clon, clat, -1, 0);
-	scan_share_file( base, cb, SE_Corner, n );
-	cb = sgBucketOffset(clon, clat, -1, -1);
-	scan_share_file( base, cb, NE_Corner, n );
-	cb = sgBucketOffset(clon, clat, 0, -1);
-	scan_share_file( base, cb, NW_Corner, n );
-    } else if ( n == SE_Corner ) {
-	// cout << "searching for SE corner data" << endl;
-	cb = sgBucketOffset(clon, clat, 0, -1);
-	scan_share_file( base, cb, NE_Corner, n );
-	cb = sgBucketOffset(clon, clat, 1, -1);
-	scan_share_file( base, cb, NW_Corner, n );
-	cb = sgBucketOffset(clon, clat, 1, 0);
-	scan_share_file( base, cb, SW_Corner, n );
-    } else if ( n == NE_Corner ) {
-	// cout << "searching for NE corner data" << endl;
-	cb = sgBucketOffset(clon, clat, 1, 0);
-	scan_share_file( base, cb, NW_Corner, n );
-	cb = sgBucketOffset(clon, clat, 1, 1);
-	scan_share_file( base, cb, SW_Corner, n );
-	cb = sgBucketOffset(clon, clat, 0, 1);
-	scan_share_file( base, cb, SE_Corner, n );
-    } else if ( n == NW_Corner ) {
-	// cout << "searching for NW corner data" << endl;
-	cb = sgBucketOffset(clon, clat, 0, 1);
-	scan_share_file( base, cb, SW_Corner, n );
-	cb = sgBucketOffset(clon, clat, -1, 1);
-	scan_share_file( base, cb, SE_Corner, n );
-	cb = sgBucketOffset(clon, clat, -1, 0);
-	scan_share_file( base, cb, NE_Corner, n );
-    } else if ( n == NORTH ) {
-	// cout << "searching for NORTH edge data" << endl;
- 	cb = sgBucketOffset(clon, clat, 0, 1);
-	scan_share_file( base, cb, SOUTH, n );
-    } else if ( n == SOUTH ) {
-	// cout << "searching for SOUTH edge data" << endl;
- 	cb = sgBucketOffset(clon, clat, 0, -1);
-	scan_share_file( base, cb, NORTH, n );
-    } else if ( n == EAST ) {
-	// cout << "searching for EAST edge data" << endl;
- 	cb = sgBucketOffset(clon, clat, 1, 0);
-	scan_share_file( base, cb, WEST, n );
-    } else if ( n == WEST ) {
-	// cout << "searching for WEST edge data" << endl;
- 	cb = sgBucketOffset(clon, clat, -1, 0);
-	scan_share_file( base, cb, EAST, n );
-    }
-}
-
-
-// load any previously existing shared data from all neighbors (if
-// shared data for a component exists set that components flag to true
-void TGMatch::load_neighbor_shared( SGBucket b, string share_dir ) {
-//    cout << "Loading existing shared data from neighbor tiles" << endl;
-
-    string base = share_dir + "/";
-
-    // start with all flags false
-    sw_flag = se_flag = ne_flag = nw_flag = false;
-    north_flag = south_flag = east_flag = west_flag = false;
-
-    load_shared( b, base, SW_Corner );
-    load_shared( b, base, SE_Corner );
-    load_shared( b, base, NE_Corner );
-    load_shared( b, base, NW_Corner );
-
-    north_nodes.clear();
-    south_nodes.clear();
-    east_nodes.clear();
-    west_nodes.clear();
-
-    load_shared( b, base, NORTH );
-    load_shared( b, base, SOUTH );
-    load_shared( b, base, EAST );
-    load_shared( b, base, WEST );
-
-#if 0
-    cout << "Shared data read in:" << endl;
-    if ( sw_flag ) {
-	cout << "  sw corner = " << sw_node << endl;
-	cout << "     normal = " << sw_normal << endl;
-    }
-    if ( se_flag ) {
-	cout << "  se corner = " << se_node << endl;
-	cout << "     normal = " << se_normal << endl;
-    }
-    if ( ne_flag ) {
-	cout << "  ne corner = " << ne_node << endl;
-	cout << "     normal = " << ne_normal << endl;
-    }
-    if ( nw_flag ) {
-	cout << "  nw corner = " << nw_node << endl;
-	cout << "     normal = " << nw_normal << endl;
-    }
-    if ( north_flag ) {
-	cout << "  north nodes = " << north_nodes.size() << endl;
-	for ( int i = 0; i < (int)north_nodes.size(); ++i ) {
-	    cout << "    " << north_nodes[i] << endl;
-	}
-    }
-    if ( south_flag ) { 
-	cout << "  south nodes = " << south_nodes.size() << endl;
-	for ( int i = 0; i < (int)south_nodes.size(); ++i ) {
-	    cout << "    " << south_nodes[i] << endl;
-	}
-    }
-    if ( east_flag ) { 
-	cout << "  east nodes = " << east_nodes.size() << endl;
-	for ( int i = 0; i < (int)east_nodes.size(); ++i ) {
-	    cout << "    " << east_nodes[i] << endl;
-	}
-    }
-    if ( west_flag ) { 
-	cout << "  west nodes = " << west_nodes.size() << endl;
-	for ( int i = 0; i < (int)west_nodes.size(); ++i ) {
-	    cout << "    " << west_nodes[i] << endl;
-	}
-    }
-#endif
-}
-
-// try to load any missing shared data from our own shared data file
-void TGMatch::load_missing_shared( SGBucket b, string share ) {
-    string base = share + "/";
-    
-    if ( !nw_flag ) {
-	scan_share_file( base, b, NW_Corner, NW_Corner );
-    }
-    
-    if ( !ne_flag ) {
-	scan_share_file( base, b, NE_Corner, NE_Corner );
-    }
-    
-    if ( !se_flag ) {
-	scan_share_file( base, b, SE_Corner, SE_Corner );
-    }
-    
-    if ( !sw_flag ) {
-	scan_share_file( base, b, SW_Corner, SW_Corner );
-    }
-    
-    if ( !north_flag ) {
-	scan_share_file( base, b, NORTH, NORTH );
-    }
-    
-    if ( !east_flag ) {
-	scan_share_file( base, b, EAST, EAST );
-    }
-    
-    if ( !south_flag ) {
-	scan_share_file( base, b, SOUTH, SOUTH );
-    }
-    
-    if ( !west_flag ) {
-	scan_share_file( base, b, WEST, WEST );
-    }
-}
-
-
-// fake a normal for a point which is basically straight up
-Point3D tgFakeNormal( const Point3D& p ) {
-    Point3D radians = Point3D( p.x() * SGD_DEGREES_TO_RADIANS,
-			       p.y() * SGD_DEGREES_TO_RADIANS,
-			       p.z() );
-    Point3D cart = sgGeodToCart(radians);
-    double len = Point3D(0.0).distance3D(cart);
-    // cout << "len = " << len << endl;
-    cart /= len;
-    // cout << "new fake normal = " << cart << endl;
-
-    return cart;
-}
-
-
-// split up the tile between the shared edge points, normals, and
-// segments and the body.  This must be done after calling
-// load_neighbor_data() and will ignore any shared data from the
-// current tile that already exists from a neighbor.
-void TGMatch::split_tile( SGBucket b, TGConstruct* c ) {
-    int i;
-
-    //cout << "Spliting tile" << endl;
-    //cout << "  extracting (shared) edge nodes and normals" << endl;
-
-    // calculate tile boundaries
-    point2d min, max;
-
-    min.x = b.get_center_lon() - 0.5 * b.get_width();
-    min.y = b.get_center_lat() - 0.5 * b.get_height();
-    max.x = b.get_center_lon() + 0.5 * b.get_width();
-    max.y = b.get_center_lat() + 0.5 * b.get_height();
-
-    // defaults "just in case"
-    if ( ! sw_flag ) {
-	sw_node = Point3D( min.x, min.y, 0.0 );
-	sw_normal = tgFakeNormal( sw_node );
-    }
-    if ( ! se_flag ) {
-	se_node = Point3D( max.x, min.y, 0.0 );
-	se_normal = tgFakeNormal( se_node );
-    }
-    if ( ! nw_flag ) {
-	nw_node = Point3D( min.x, max.y, 0.0 );
- 	nw_normal = tgFakeNormal( nw_node );
-    }
-    if ( ! ne_flag ) {
-	ne_node = Point3D( max.x, max.y, 0.0 );
- 	ne_normal = tgFakeNormal( ne_node );
-   }
-
-    // separate nodes and normals into components
-
-    body_nodes.clear();
-
-    point_list nodes = c->get_geod_nodes();
-    point_list point_normals = c->get_point_normals();
-
-    SG_LOG(SG_GENERAL, SG_ALERT, "number of geod nodes = " << nodes.size() );
-    SG_LOG(SG_GENERAL, SG_ALERT, "number of normals = " << point_normals.size() );
-
-    for ( i = 0; i < (int)nodes.size(); ++i ) {
-	Point3D node = nodes[i];
-	Point3D normal = point_normals[i];
-
-	if ( (fabs(node.y() - min.y) < SG_EPSILON) && 
-	     (fabs(node.x() - min.x) < SG_EPSILON) ) {
-	    if ( ! sw_flag ) {
-		sw_node = node;
-		sw_normal = normal;
-	    }
-	} else if ( (fabs(node.y() - min.y) < SG_EPSILON) &&
-		    (fabs(node.x() - max.x) < SG_EPSILON) ) {
-	    if ( ! se_flag ) {
-		se_node = node;
-		se_normal = normal;
-	    }
-	} else if ( (fabs(node.y() - max.y) < SG_EPSILON) &&
-		    (fabs(node.x() - max.x) < SG_EPSILON)) {
-	    if ( ! ne_flag ) {
-		ne_node = node;
-		ne_normal = normal;
-	    }
-	} else if ( (fabs(node.y() - max.y) < SG_EPSILON) &&
-		    (fabs(node.x() - min.x) < SG_EPSILON) ) {
-	    if ( ! nw_flag ) {
-		nw_node = node;
-		nw_normal = normal;
-	    }
-	} else if ( fabs(node.x() - min.x) < SG_EPSILON ) {
-	    if ( ! west_flag ) {
-		west_nodes.push_back( node );
-		west_normals.push_back( normal );
-	    }
-	} else if ( fabs(node.x() - max.x) < SG_EPSILON ) {
-	    if ( ! east_flag ) {
-		east_nodes.push_back( node );
-		east_normals.push_back( normal );
-	    }
-	} else if ( fabs(node.y() - min.y) < SG_EPSILON ) {
-	    if ( ! south_flag ) {
-		south_nodes.push_back( node );
-		south_normals.push_back( normal );
-	    }
-	} else if ( fabs(node.y() - max.y) < SG_EPSILON ) {
-	    if ( ! north_flag ) {
-		north_nodes.push_back( node );
-		north_normals.push_back( normal );
-	    }
-	} else {
-	    body_nodes.push_back( node );
-	    body_normals.push_back( normal );
-	}
-    }
-
-#if 0 // UNUSED
-    // separate area edge segment into components
-    cout << "  extracting (shared) area edge segments" << endl;
-
-    TGTriSeg seg;
-    Point3D p1, p2;
-    triseg_list seg_list = c.get_tri_segs().get_seg_list();
-    triseg_list_iterator current = seg_list.begin();
-    triseg_list_iterator last = seg_list.end();
-
-    for ( ; current != last; ++current ) {
-	seg = *current;
-	p1 = nodes[ seg.get_n1() ];
-	p2 = nodes[ seg.get_n2() ];
-
-	if ( fabs(p1.y() - p2.y()) < SG_EPSILON ) {
-	    // check if horizontal
-	    if ( fabs(p1.y() - max.y) < SG_EPSILON ) {
-		north_segs.push_back( seg );
-	    } else if ( fabs(p1.y() - min.y) < SG_EPSILON ) {
-		south_segs.push_back( seg );
-	    } else {
-		body_segs.push_back( seg );
-	    }
-	} else if ( fabs(p1.x() - p2.x()) < SG_EPSILON ) {
-	    // check if vertical
-	    if ( fabs(p1.x() - max.x) < SG_EPSILON ) {
-		east_segs.push_back( seg );
-	    } else if ( fabs(p1.x() - min.x) < SG_EPSILON ) {
-		west_segs.push_back( seg );
-	    } else {
-		body_segs.push_back( seg );
-	    }
-	} else {
-	    body_segs.push_back( seg );
-	}
-    }
-
-    if ( !sw_flag ) { cout << "  sw corner = " << sw_node << endl; }
-    if ( !se_flag ) { cout << "  se corner = " << se_node << endl; }
-    if ( !ne_flag ) { cout << "  ne corner = " << ne_node << endl; }
-    if ( !nw_flag ) { cout << "  nw corner = " << nw_node << endl; }
-    /*
-    if ( !north_flag ) { 
-	cout << "  north nodes = " << north_nodes.size() << endl;
-	for ( i = 0; i < (int)north_nodes.size(); ++i ) {
-	    cout << "    " << north_nodes[i] << endl;
-	}
-    }
-    if ( !south_flag ) { 
-	cout << "  south nodes = " << south_nodes.size() << endl;
-	for ( i = 0; i < (int)south_nodes.size(); ++i ) {
-	    cout << "    " << south_nodes[i] << endl;
-	}
-    }
-    if ( !east_flag ) { 
-	cout << "  east nodes = " << east_nodes.size() << endl;
-	for ( i = 0; i < (int)east_nodes.size(); ++i ) {
-	    cout << "    " << east_nodes[i] << endl;
-	}
-    }
-    if ( !west_flag ) { 
-	cout << "  west nodes = " << west_nodes.size() << endl;
-	for ( i = 0; i < (int)west_nodes.size(); ++i ) {
-	    cout << "    " << west_nodes[i] << endl;
-	}
-    }
-    cout << "  body nodes = " << body_nodes.size() << endl;
-    for ( i = 0; i < (int)body_nodes.size(); ++i ) {
-	cout << "    " << body_nodes[i] << endl;
-    }
-    */
-#endif
-
-    SG_LOG(SG_GENERAL, SG_ALERT, "SPLIT TILE COMPLETE " );
-
-}
-
-
-// write the new shared edge points, normals, and segments for this
-// tile
-void TGMatch::write_shared( SGBucket b, string shared ) {
-
-    string dir  = shared + "/" + b.gen_base_path();
-    string file = dir    + "/" + b.gen_index_str();
-
-    SGPath sgp( dir );
-    sgp.append( "dummy" );
-    sgp.create_dir( 0755 );
-
-    //cout << "shared data will be written to " << file << endl;
-
-
-#if 0
-    cout << "FLAGS" << endl;
-    cout << "=====" << endl;
-    cout << "sw_flag = " << sw_flag << endl;
-    cout << "se_flag = " << se_flag << endl;
-    cout << "ne_flag = " << ne_flag << endl;
-    cout << "nw_flag = " << nw_flag << endl;
-    cout << "north_flag = " << north_flag << endl;
-    cout << "south_flag = " << south_flag << endl;
-    cout << "east_flag = " << east_flag << endl;
-    cout << "west_flag = " << west_flag << endl;
-#endif
-
-    FILE *fp;
-    if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
-//	cout << "ERROR: opening " << file << " for writing!" << endl;
-	exit(-1);
-    }
-
-    /*
-     * We only write data out for those sides for which the adjacent
-     * tiles still have to be built.
-     *
-     * If we have already read data for a given corner or side, this
-     * means that the adjacent tile already has been built.
-     */
-    if ( ! sw_flag ) {
-	fprintf( fp, "sw_node %.10f %.10f %.10f\n", 
-		 sw_node.x(), sw_node.y(), sw_node.z() );
-	fprintf( fp, "sw_normal %.10f %.10f %.10f\n", 
-		 sw_normal.x(), sw_normal.y(), sw_normal.z() );
-    }
-
-    if ( ! se_flag ) {
-	fprintf( fp, "se_node %.10f %.10f %.10f\n", 
-		 se_node.x(), se_node.y(), se_node.z() );
-	fprintf( fp, "se_normal %.10f %.10f %.10f\n", 
-		 se_normal.x(), se_normal.y(), se_normal.z() );
-    }
-
-    if ( ! nw_flag ) {
-	fprintf( fp, "nw_node %.10f %.10f %.10f\n", 
-		 nw_node.x(), nw_node.y(), nw_node.z() );
-	fprintf( fp, "nw_normal %.10f %.10f %.10f\n", 
-		 nw_normal.x(), nw_normal.y(), nw_normal.z() );
-    }
-
-    if ( ! ne_flag ) {
-	fprintf( fp, "ne_node %.10f %.10f %.10f\n", 
-		 ne_node.x(), ne_node.y(), ne_node.z() );
-	fprintf( fp, "ne_normal %.10f %.10f %.10f\n", 
-		 ne_normal.x(), ne_normal.y(), ne_normal.z() );
-    }
-
-    if ( ! north_flag ) {
-	if ( (int)north_nodes.size() == 0 ) {
-	    fprintf( fp, "n_null -999.0 -999.0 -999.0\n" );
-	} else {
-	    for ( int i = 0; i < (int)north_nodes.size(); ++i ) {
-		fprintf( fp, "n_node %.10f %.10f %.10f\n", 
-			 north_nodes[i].x(), north_nodes[i].y(),
-			 north_nodes[i].z() );
-		fprintf( fp, "n_normal %.10f %.10f %.10f\n", 
-			 north_normals[i].x(), north_normals[i].y(),
-			 north_normals[i].z() );
-	    }
-	}
-    }
-
-    if ( ! south_flag ) {
-	if ( (int)south_nodes.size() == 0 ) {
-	    fprintf( fp, "s_null -999.0 -999.0 -999.0\n" );
-	} else {
-	    for ( int i = 0; i < (int)south_nodes.size(); ++i ) {
-		fprintf( fp, "s_node %.10f %.10f %.10f\n", 
-			 south_nodes[i].x(), south_nodes[i].y(),
-			 south_nodes[i].z() );
-		fprintf( fp, "s_normal %.10f %.10f %.10f\n", 
-			 south_normals[i].x(), south_normals[i].y(),
-			 south_normals[i].z() );
-	    }
-	} 
-    }
-
-    if ( ! east_flag ) {
-	if ( (int)east_nodes.size() == 0 ) {
-	    fprintf( fp, "e_null -999.0 -999.0 -999.0\n" );
-	} else {
-	    for ( int i = 0; i < (int)east_nodes.size(); ++i ) {
-		fprintf( fp, "e_node %.10f %.10f %.10f\n", 
-			 east_nodes[i].x(), east_nodes[i].y(), 
-			 east_nodes[i].z() );
-		fprintf( fp, "e_normal %.10f %.10f %.10f\n", 
-			 east_normals[i].x(), east_normals[i].y(),
-			 east_normals[i].z() );
-	    }
-	}
-    }
-
-    if ( ! west_flag ) {
-	if ( (int)west_nodes.size() == 0 ) {
-	    fprintf( fp, "w_null -999.0 -999.0 -999.0\n" );
-	} else {
-	    for ( int i = 0; i < (int)west_nodes.size(); ++i ) {
-		fprintf( fp, "w_node %.10f %.10f %.10f\n", 
-			 west_nodes[i].x(), west_nodes[i].y(),
-			 west_nodes[i].z() );
-		fprintf( fp, "w_normal %.10f %.10f %.10f\n", 
-			 west_normals[i].x(), west_normals[i].y(),
-			 west_normals[i].z() );
-	    }
-	}
-    }
-
-#if 0 // not needed
-    point_list nodes = c.get_geod_nodes();
-    Point3D p1, p2;
-
-    for ( int i = 0; i < (int)north_segs.size(); ++i ) {
-	p1 = nodes[ north_segs[i].get_n1() ];
-	p2 = nodes[ north_segs[i].get_n2() ];
-	fprintf( fp, "n_seg %.10f %.10f %.10f %.10f\n", 
-		 p1.x(), p1.y(), p2.x(), p2.y() );
-    }
-
-    for ( int i = 0; i < (int)south_segs.size(); ++i ) {
-	p1 = nodes[ south_segs[i].get_n1() ];
-	p2 = nodes[ south_segs[i].get_n2() ];
-	fprintf( fp, "s_seg %.10f %.10f %.10f %.10f\n", 
-		 p1.x(), p1.y(), p2.x(), p2.y() );
-    }
-
-    for ( int i = 0; i < (int)east_segs.size(); ++i ) {
-	p1 = nodes[ east_segs[i].get_n1() ];
-	p2 = nodes[ east_segs[i].get_n2() ];
-	fprintf( fp, "e_seg %.10f %.10f %.10f %.10f\n", 
-		 p1.x(), p1.y(), p2.x(), p2.y() );
-    }
-
-    for ( int i = 0; i < (int)west_segs.size(); ++i ) {
-	p1 = nodes[ west_segs[i].get_n1() ];
-	p2 = nodes[ west_segs[i].get_n2() ];
-	fprintf( fp, "w_seg %.10f %.10f %.10f %.10f\n", 
-		 p1.x(), p1.y(), p2.x(), p2.y() );
-    }
-#endif
-
-    fclose( fp );
-
-    string command = "gzip --force --best " + file;
-    system(command.c_str());
-}
-
-
-// insert normal into vector, extending it first if needed
-void insert_normal( point_list& normals, Point3D n, int i ) {
-    Point3D empty( 0.0 );
-
-    // extend vector if needed
-    while ( i >= (int)normals.size() ) {
-	normals.push_back( empty );
-    }
-
-    normals[i] = n;
-}
-
-// Just add nodes and normals to the node list
-void TGMatch::add_shared_nodes( TGConstruct* c ) {
-    TGNodes* nodes;
-    nodes = c->get_nodes();
-
-//    cout << " BEFORE ADDING SHARED NODES: " << nodes->size() << endl;
-
-    if ( sw_flag ) {
-        nodes->unique_add_fixed_elevation( sw_node );
-    }
-
-    if ( se_flag ) {
-        nodes->unique_add_fixed_elevation( se_node );
-    }
-
-    if ( nw_flag ) {
-        nodes->unique_add_fixed_elevation( nw_node );
-    }
-
-    if ( ne_flag ) {
-        nodes->unique_add_fixed_elevation( ne_node );
-    }
-
-    if ( north_flag ) {
-        for (unsigned int i = 0; i < north_nodes.size(); i++) {
-            nodes->unique_add_fixed_elevation( north_nodes[i] );
-        }
-    }
-
-    if ( south_flag ) {
-        for (unsigned int i = 0; i < south_nodes.size(); i++) {
-            nodes->unique_add_fixed_elevation( south_nodes[i] );
-        }
-    }
-
-    if ( east_flag ) {
-        for (unsigned int i = 0; i < east_nodes.size(); i++) {
-            nodes->unique_add_fixed_elevation( east_nodes[i] );
-        }
-    }
-
-    if ( west_flag ) {
-        for (unsigned int i = 0; i < west_nodes.size(); i++) {
-            nodes->unique_add_fixed_elevation( west_nodes[i] );
-        }
-    }
-    
-//    cout << " AFTER ADDING SHARED NODES: " << nodes->size() << endl;
-}
-
-// reassemble the tile pieces (combining the shared data and our own
-// data)
-void TGMatch::assemble_tile( TGConstruct* c ) {
-    int i;
-    TGTriNodes new_nodes;
-    new_nodes.clear();
-
-    point_list new_normals;
-    new_normals.clear();
-
-    TGTriSegments new_segs;
-    new_segs.clear();
-
-    // add the corner points
-    int sw_index = new_nodes.unique_add( sw_node );
-    insert_normal( new_normals, sw_normal, sw_index );
-
-    int se_index = new_nodes.unique_add( se_node );
-    insert_normal( new_normals, se_normal, se_index );
-
-    int ne_index = new_nodes.unique_add( ne_node );
-    insert_normal( new_normals, ne_normal, ne_index );
-
-    int nw_index = new_nodes.unique_add( nw_node );
-    insert_normal( new_normals, nw_normal, nw_index );
-
-//    cout << "after adding corners:" << endl;
-//    cout << "  new_nodes = " << new_nodes.size() << endl;
-//    cout << "  new normals = " << new_normals.size() << endl;
-
-    // add the edge points
-
-    int index;
-
-    // cout << "Total north nodes = " << north_nodes.size() << endl;
-    for ( i = 0; i < (int)north_nodes.size(); ++i ) {
-	// cout << "adding north node " << north_nodes[i] << endl;
-	index = new_nodes.unique_add( north_nodes[i] );
-	insert_normal( new_normals, north_normals[i], index );
-    }
-
-    for ( i = 0; i < (int)south_nodes.size(); ++i ) {
-	index = new_nodes.unique_add( south_nodes[i] );
-	insert_normal( new_normals, south_normals[i], index );
-    }
-
-    for ( i = 0; i < (int)east_nodes.size(); ++i ) {
-	index = new_nodes.unique_add( east_nodes[i] );
-	insert_normal( new_normals, east_normals[i], index );
-    }
-
-    // cout << "Total west nodes = " << west_nodes.size() << endl;
-    for ( i = 0; i < (int)west_nodes.size(); ++i ) {
-	// cout << "adding west node " << west_nodes[i] << endl;
-	index = new_nodes.unique_add( west_nodes[i] );
-	insert_normal( new_normals, west_normals[i], index );
-    }
-
-//    cout << "after adding edges:" << endl;
-//    cout << "  new_nodes = " << new_nodes.size() << endl;
-//    cout << "  new normals = " << new_normals.size() << endl;
-
-    // add the body points
-    for ( i = 0; i < (int)body_nodes.size(); ++i ) {
-	index = new_nodes.unique_add( body_nodes[i] );
-	insert_normal( new_normals, body_normals[i], index );
-    }
-
-//    cout << "after adding body points:" << endl;
-//    cout << "  new_nodes = " << new_nodes.size() << endl;
-//    cout << "  new normals = " << new_normals.size() << endl;
-
-    // add the edge segments
-    new_segs.unique_divide_and_add( new_nodes.get_node_list(),
-				    TGTriSeg(sw_index, se_index, 1) );
-    new_segs.unique_divide_and_add( new_nodes.get_node_list(),
-				    TGTriSeg(se_index, ne_index, 1) );
-    new_segs.unique_divide_and_add( new_nodes.get_node_list(),
-				    TGTriSeg(ne_index, nw_index, 1) );
-    new_segs.unique_divide_and_add( new_nodes.get_node_list(),
-				    TGTriSeg(nw_index, sw_index, 1) );
-
-//    cout << "after adding edge segments:" << endl;
-//    cout << "  new_nodes = " << new_nodes.size() << endl;
-//    cout << "  new normals = " << new_normals.size() << endl;
-
-    // add the body segments
-
-    point_list geod_nodes = c->get_geod_nodes();
-
-    TGTriSeg seg;
-    Point3D p1, p2;
-    int n1, n2, marker;
-
-    triseg_list_iterator current = body_segs.begin();
-    triseg_list_iterator last = body_segs.end();
-
-    for ( ; current != last; ++current ) {
-	seg = *current;
-
-	// get the original points (x,y,z)
-	p1 = geod_nodes[ seg.get_n1() ];
-	p2 = geod_nodes[ seg.get_n2() ];
-	marker = seg.get_boundary_marker();
-
-	// make sure these points are in the new node list (and get
-	// their new index)
-	n1 = new_nodes.unique_add( p1 );
-	if ( n1 >= (int)new_normals.size() ) {
-//	    cout << "Adding a segment resulted in a new node, faking a normal" 
-//		 << endl;
-	    Point3D fake = tgFakeNormal( p1 );
-	    insert_normal( new_normals, fake, n1 );
-	}
-
-	n2 = new_nodes.unique_add( p2 );
-	if ( n2 >= (int)new_normals.size() ) {
-//	    cout << "Adding a segment resulted in a new node, faking a normal" 
-//		 << endl;
-	    Point3D fake = tgFakeNormal( p2 );
-	    insert_normal( new_normals, fake, n2 );
-	}
-
-	// add the segment using the new indices
-	new_segs.unique_divide_and_add( new_nodes.get_node_list(),
-					TGTriSeg(n1, n2, marker) );
-    }
-
-#if 0 // UNUSED
-    c.set_tri_nodes( new_nodes );
-    c.set_point_normals( new_normals );
-    c.set_tri_segs( new_segs );
-
-    cout << "after adding all segments (should be the same):" << endl;
-    cout << "  new_nodes = " << new_nodes.size() << endl;
-    cout << "  new normals = " << new_normals.size() << endl;
-#endif
-
-}
diff --git a/src/BuildTiles/Match/match.hxx b/src/BuildTiles/Match/match.hxx
deleted file mode 100644
index 55b6e726..00000000
--- a/src/BuildTiles/Match/match.hxx
+++ /dev/null
@@ -1,130 +0,0 @@
-// match.hxx -- Class to help match up tile edges
-//
-// Written by Curtis Olson, started April 1999.
-//
-// Copyright (C) 1998 - 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// $Id: match.hxx,v 1.7 2004-11-19 22:25:49 curt Exp $
-
-
-#ifndef _MATCH_HXX
-#define _MATCH_HXX
-
-
-#ifndef __cplusplus                                                          
-# error This library requires C++
-#endif                                   
-
-#include <string>
-#include <vector>
-
-#include <simgear/compiler.h>
-#include <simgear/math/sg_types.hxx>
-#include <simgear/bucket/newbucket.hxx>
-
-// TO REMOVE
-#include <Geometry/trieles.hxx>
-#include <Geometry/trinodes.hxx>
-#include <Geometry/trisegs.hxx>
-// TO REMOVE
-
-// Forward Declaration
-class TGConstruct;
-
-class TGMatch {
-
-private:
-
-    // nodes breakdown
-    Point3D sw_node, se_node, ne_node, nw_node;
-    point_list north_nodes, south_nodes, east_nodes, west_nodes;
-    point_list body_nodes;
-
-    // normals breakdown
-    Point3D sw_normal, se_normal, ne_normal, nw_normal;
-    point_list north_normals, south_normals, east_normals, west_normals;
-    point_list body_normals;
-
-    // flags
-    // a flag is set if and only if we have read data for the given
-    // corner or side
-    bool sw_flag, se_flag, ne_flag, nw_flag;
-    bool north_flag, south_flag, east_flag, west_flag;
-
-    // segment breakdown
-    triseg_list north_segs, south_segs, east_segs, west_segs;
-    triseg_list body_segs;
-
-public:
-
-    enum neighbor_type {
-	SW_Corner = 1,
-	SE_Corner = 2,
-	NE_Corner = 3,
-	NW_Corner = 4,
-	NORTH = 5,
-	SOUTH = 6,
-	EAST = 7,
-	WEST = 8
-    };
-
-    // Constructor
-    TGMatch( void );
-
-    // Destructor
-    ~TGMatch( void );
-
-    // load any previously existing shared data from all neighbors (if
-    // shared data for a component exists set that components flag to
-    // true
-    void load_neighbor_shared( SGBucket b, std::string base );
-    
-    // try to load any missing shared data from our own shared data file
-    void load_missing_shared( SGBucket b, std::string base );
-
-    // scan the specified share file for the specified information
-    void scan_share_file( const std::string& dir, const SGBucket& b,
-			  neighbor_type search, neighbor_type dest );
-
-    // try to find info for the specified shared component
-    void load_shared( SGBucket b, std::string base, neighbor_type n );
-
-    // NEW TILE MATCHING - PRE TRIANGULATION
-    // Just add nodes and normals to the node list
-    void add_shared_nodes( TGConstruct* c );
-
-    // split up the tile between the shared edge points, normals, and
-    // segments and the body.  This must be done after calling
-    // load_neighbor_data() and will ignore any shared data from the
-    // current tile that already exists from a neighbor.
-    void split_tile( SGBucket b, TGConstruct* c );
-
-    // write the new shared edge points, normals, and segments for
-    // this tile
-    void write_shared( SGBucket b, std::string base );
-
-    // reassemble the tile pieces (combining the shared data and our
-    // own data)
-    void assemble_tile( TGConstruct* c );
-};
-
-
-// fake a normal for a point which is basically straight up
-Point3D tgFakeNormal( const Point3D& p );
-
-
-#endif // _MATCH_HXX
diff --git a/src/Lib/Geometry/tg_nodes.cxx b/src/Lib/Geometry/tg_nodes.cxx
index 6553c781..b57c3fa1 100644
--- a/src/Lib/Geometry/tg_nodes.cxx
+++ b/src/Lib/Geometry/tg_nodes.cxx
@@ -1,4 +1,5 @@
 #include <simgear/debug/logstream.hxx>
+#include <CGAL/Plane_3.h>
 
 #include "tg_nodes.hxx"
 
@@ -119,6 +120,36 @@ point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
     return points;
 }
 
+void TGNodes::get_geod_edge( SGBucket b, point_list& north, point_list& south, point_list& east, point_list& west ) const {
+    const_node_list_iterator current, last;
+    double north_compare = b.get_center_lat() + 0.5 * b.get_height();
+    double south_compare = b.get_center_lat() - 0.5 * b.get_height();
+    double east_compare  = b.get_center_lon() + 0.5 * b.get_width();
+    double west_compare  = b.get_center_lon() - 0.5 * b.get_width();
+
+    // find all points on the edges
+    current = tg_node_list.begin();
+    last    = tg_node_list.end();
+
+    for ( ; current != last; ++current ) {
+        Point3D pt = (*current).GetPosition();
+
+        // may save the same point twice - so we get all the corners
+        if ( fabs(pt.y() - north_compare) < SG_EPSILON) {
+            north.push_back( pt );
+        }
+        if ( fabs(pt.y() - south_compare) < SG_EPSILON) {
+            south.push_back( pt );
+        }
+        if ( fabs(pt.x() - east_compare) < SG_EPSILON) {
+            east.push_back( pt );
+        }
+        if ( fabs(pt.x() - west_compare) < SG_EPSILON) {
+            west.push_back( pt );
+        }
+    }
+}
+
 std::vector< SGVec3d > TGNodes::get_wgs84_nodes_as_SGVec3d( void ) const {
     const_node_list_iterator current, last;
     std::vector< SGVec3d > points;
@@ -201,6 +232,90 @@ void TGNodes::Dump( void ) {
     }
 }
 
+// input from stream
+std::istream& operator >> ( std::istream& in, TGNode& n )
+{
+    int i, nCount;
+
+    // Load a tgnode
+    in >> n.position;
+    n.CalcWgs84();
+
+    in >> n.normal;
+    in >> n.fixed_position;
+    in >> n.fixed_normal;
+
+    in >> nCount;
+    for (i=0; i<nCount; i++) {
+        TGFaceLookup face;
+
+        in >> face.area;
+        in >> face.shape;
+        in >> face.seg;
+        in >> face.tri;
+
+        n.faces.push_back( face );
+    }
+
+    return in;
+}
+
+std::ostream& operator<< ( std::ostream& out, const TGNode& n )
+{
+    int i, nCount;
+
+    // Save a tgnode
+    out << n.position;
+    out << n.normal;
+    out << n.fixed_position << " ";
+    out << n.fixed_normal << "\n";
+
+    nCount = n.faces.size();
+    out << nCount << "\n";
+    for (i=0; i<nCount; i++) {
+        out << n.faces[i].area << " ";
+        out << n.faces[i].shape << " ";
+        out << n.faces[i].seg << " ";
+        out << n.faces[i].tri << "\n";
+    }
+
+    return out;
+}
+
+// input from stream
+std::istream& operator >> ( std::istream& in, TGNodes& ns )
+{
+    int i, nCount;
+
+    // Load all tgnodes
+    in >> nCount;
+    
+    for (i=0; i<nCount; i++) {
+        TGNode node;
+        in >> node;
+
+        ns.tg_node_list.push_back( node );
+    }
+
+    return in;
+}
+
+std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
+{
+    int i, nCount;
+
+    // Save all tgnodes
+    nCount = ns.tg_node_list.size();
+    out << nCount << "\n";
+
+    for (i=0; i<nCount; i++) {
+        out << ns.tg_node_list[i];
+    }
+
+    return out;
+}
+
+
 #if 0
 bool TGNodes::LookupFixedElevation( Point3D p, double* z )
 {
diff --git a/src/Lib/Geometry/tg_nodes.hxx b/src/Lib/Geometry/tg_nodes.hxx
index 54c3fdeb..3a7542cc 100644
--- a/src/Lib/Geometry/tg_nodes.hxx
+++ b/src/Lib/Geometry/tg_nodes.hxx
@@ -7,6 +7,7 @@
 #endif                                   
 
 #include <simgear/compiler.h>
+#include <simgear/bucket/newbucket.hxx>
 #include <Geometry/point3d.hxx>
 #include <simgear/math/sg_types.hxx>
 
@@ -26,6 +27,10 @@ typedef std::vector < TGFaceLookup > TGFaceList;
 
 class TGNode {
 public:
+    TGNode() {
+        // constructor for serialization only
+    }
+    
     TGNode( Point3D p ) {
         position    = p;
         normal      = Point3D();
@@ -88,6 +93,10 @@ public:
     inline void    SetNormal( const Point3D& n )    { normal = n; }
     inline Point3D GetNormal( void ) const          { return normal; }
 
+    // Friends for serialization
+    friend std::istream& operator>> ( std::istream&, TGNode& );
+    friend std::ostream& operator<< ( std::ostream&, const TGNode& );
+
 private:
     Point3D     position;
     Point3D     normal;
@@ -152,7 +161,10 @@ public:
 
     // Find all the nodes within a bounding box
     point_list get_geod_inside( Point3D min, Point3D max ) const;
-        
+
+    // Find a;; the nodes on the tile edges
+    void get_geod_edge( SGBucket b, point_list& north, point_list& south, point_list& east, point_list& west ) const;
+
     // return a point list of wgs84 nodes
     std::vector< SGVec3d > get_wgs84_nodes_as_SGVec3d() const;
     point_list get_wgs84_nodes_as_Point3d() const;
@@ -173,6 +185,10 @@ public:
 
     void Dump( void );
 
+    // Friends for serialization
+    friend std::istream& operator>> ( std::istream&, TGNodes& );
+    friend std::ostream& operator<< ( std::ostream&, const TGNodes& );
+
 private:
     node_list tg_node_list;
 
diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx
index d48b214c..4ce9fbcd 100644
--- a/src/Lib/Polygon/polygon.cxx
+++ b/src/Lib/Polygon/polygon.cxx
@@ -970,7 +970,6 @@ TGPolygon tgPolygonSimplify(const TGPolygon &poly)
 // Send a polygon to standard output.
 std::ostream& operator << (std::ostream &output, const TGPolygon &poly)
 {
-    char buff[128];
     int  nContours = poly.contours();
 
     // Save the number of contours
diff --git a/src/Lib/Polygon/superpoly.cxx b/src/Lib/Polygon/superpoly.cxx
index 83154ffd..5a7ab783 100644
--- a/src/Lib/Polygon/superpoly.cxx
+++ b/src/Lib/Polygon/superpoly.cxx
@@ -94,40 +94,25 @@ std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
 
     // Load the data
     input >> sp.material;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: material " << sp.material );
-
     input >> sp.poly;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: poly " << sp.poly );
-
     input >> sp.normals;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: normals " << sp.normals );
-
     input >> sp.texcoords;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: texcoords " << sp.texcoords );
-
     input >> sp.tris;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: tris " << sp.tris );
-
     input >> sp.tri_idxs;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: tri_idxs " << sp.tri_idxs );
 
     input >> nFaceNormals;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: nFaceNormals " << nFaceNormals );
-
     for ( int i = 0; i < nFaceNormals; i++ ) {
         input >> normal;
         sp.face_normals.push_back(normal);
     }
 
     input >> nFaceAreas;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: nFaceAreas " << nFaceAreas );
     for ( int i = 0; i < nFaceAreas; i++ ) {
         input >> area;
         sp.face_areas.push_back(area);
     }
 
     input >> sp.flag;
-    SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: flag " << sp.flag );
 
     return input;
 }