diff --git a/.gitignore b/.gitignore
index 85e2bb49..d4574fb8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ Makefile.in
 .deps
 *.o
 *.a
+*~
 COPYING
 INSTALL
 VERSION
diff --git a/src/Airports/GenAirports/build.cxx b/src/Airports/GenAirports/build.cxx
index 9e074dc5..52c56455 100644
--- a/src/Airports/GenAirports/build.cxx
+++ b/src/Airports/GenAirports/build.cxx
@@ -828,7 +828,7 @@ void build_airport( string airport_id, float alt_m,
 
 	TGPolygon poly = rwy_polys[i].get_poly();
 	SG_LOG(SG_GENERAL, SG_DEBUG, "total size before = " << poly.total_size());
-	TGPolygon tri = polygon_tesselate_alt( poly );
+	TGPolygon tri = polygon_tesselate_alt( poly, false );
 	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
 
         TGPolygon tc;
@@ -844,7 +844,7 @@ void build_airport( string airport_id, float alt_m,
     }
 
     SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating base");
-    TGPolygon base_tris = polygon_tesselate_alt( base_poly );
+    TGPolygon base_tris = polygon_tesselate_alt( base_poly, false );
 
 #if 0
     // dump more debugging output
diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx
index 1898035e..a476e38e 100644
--- a/src/Airports/GenAirports850/airport.cxx
+++ b/src/Airports/GenAirports850/airport.cxx
@@ -325,6 +325,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     int i, j, k;
     Point3D p;
 
+    bool verbose_triangulation = false;
+
     // parse main airport information
     double apt_lon = 0.0, apt_lat = 0.0;
 
@@ -334,16 +336,24 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     struct timeval  cleanup_end;
     struct timeval  triangulation_start;
     struct timeval  triangulation_end;
+    struct timeval  log_time;
 
-    // Find the average of all the runway long / lats
-    // TODO : Need runway object...    
+    // Find the average of all the runway and heliport long / lats
+    int num_samples = 0;
     for (i=0; i<runways.size(); i++)
     {
-        apt_lon += runways.at(i)->GetMidpoint().x();
-        apt_lat += runways.at(i)->GetMidpoint().y();
+        apt_lon += runways[i]->GetMidpoint().x();
+        apt_lat += runways[i]->GetMidpoint().y();
+        num_samples++;
     }
-    apt_lon = apt_lon / (double)runways.size();
-    apt_lat = apt_lat / (double)runways.size();
+    for (i=0; i<helipads.size(); i++)
+    {
+        apt_lon += helipads[i]->GetLoc().x();
+        apt_lat += helipads[i]->GetLoc().y();
+        num_samples++;
+    }
+    apt_lon = apt_lon / (double)num_samples;
+    apt_lat = apt_lat / (double)num_samples;
 
     SGBucket b( apt_lon, apt_lat );
     SG_LOG(SG_GENERAL, SG_DEBUG, b.gen_base_path() << "/" << b.gen_index_str());
@@ -368,7 +378,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     {
         for ( i=0; i<features.size(); i++ )
         {
-            SG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << i << ": " << features[i]->GetDescription() );
+            SG_LOG(SG_GENERAL, SG_INFO, "Build Feature Poly " << i << " of " << features.size() << " : " << features[i]->GetDescription() );
 
             // cut the linear feature in until we get the geometry right...
             // features[i]->BuildBtg( altitude, &line_polys, &line_tps, &line_accum );
@@ -380,9 +390,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
         SG_LOG(SG_GENERAL, SG_DEBUG, "no markings");
     }
 
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time.tv_sec) );
+
     // Build runways next
     for (i=0; i<runways.size(); i++ ) 
     {
+        SG_LOG(SG_GENERAL, SG_INFO, "Build Runway " << i << " of " << runways.size());
+
         if ( runways[i]->IsPrecision() ) 
         {
             if (boundary)
@@ -393,13 +408,18 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
             {
                 runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
             }
-	    }
+        }
     }
 
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << ctime(&log_time.tv_sec) );
+
     if (lightobjects.size())
     {
         for ( i=0; i<lightobjects.size(); i++ )
         {
+            SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
+
             lightobjects[i]->BuildBtg( altitude, &rwy_lights );
         }
     }
@@ -407,6 +427,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // Build helipads (use runway poly- and texture list for this)
     if (helipads.size())
     {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i << " of " << helipads.size());
+
         for (i=0; i<helipads.size(); i++ )
         {
             if (boundary)
@@ -419,12 +441,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
             }
         }
     }
+
     // Build the pavements
     if (pavements.size())
     {
         for ( i=0; i<pavements.size(); i++ )
         {
-            SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
+            SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
 
             if (boundary)
             {
@@ -441,9 +464,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
         SG_LOG(SG_GENERAL, SG_DEBUG, "no pavements");
     }
 
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished building pavements for " << icao << " at " << ctime(&log_time.tv_sec) );
+
     // Build runway shoulders here
     for (i=0; i<runways.size(); i++ )
     {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << i << " of " << runways.size());
+
         if ( runways[i]->GetsShoulder() )
         {
             runways[i]->BuildShoulder( altitude, &rwy_polys, &rwy_tps, &accum );
@@ -453,10 +481,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // build the base and clearing if there's a boundary
     if (boundary)
     {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Build user defined boundary " );
+
         boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
     }
 
-	if ( apt_base.total_size() == 0 )
+    if ( apt_base.total_size() == 0 )
     {
         SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
     	return;
@@ -464,7 +494,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
 
     TGPolygon filled_base  = tgPolygonStripHoles( apt_base );
     TGPolygon divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );
-    //TGPolygon base_poly    = tgPolygonDiff( filled_base, accum );
     TGPolygon base_poly    = tgPolygonDiff( divided_base, accum );
 
     gettimeofday(&build_end, NULL);
@@ -477,6 +506,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     TGTriNodes tmp_nodes;
 
     // build temporary node list from runways...
+    SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
+
     for ( k = 0; k < (int)rwy_polys.size(); ++k ) 
     {
     	TGPolygon poly = rwy_polys[k].get_poly();
@@ -484,7 +515,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
         {
     	    for ( j = 0; j < poly.contour_size( i ); ++j ) 
             {
-        		tmp_nodes.unique_add( poly.get_pt(i, j) );
+                tmp_nodes.unique_add( poly.get_pt(i, j) );
+                //tmp_nodes.course_add( poly.get_pt(i, j) );
     	    }
     	}
     }
@@ -498,6 +530,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	    for ( j = 0; j < poly.contour_size( i ); ++j ) 
             {
         		tmp_nodes.unique_add( poly.get_pt(i, j) );
+                //tmp_nodes.course_add( poly.get_pt(i, j) );
     	    }
     	}
     }
@@ -511,6 +544,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	    for ( j = 0; j < poly.contour_size( i ); ++j ) 
             {
         		tmp_nodes.unique_add( poly.get_pt(i, j) );
+                //tmp_nodes.course_add( poly.get_pt(i, j) );
     	    }
     	}
     }
@@ -521,6 +555,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	for ( j = 0; j < base_poly.contour_size( i ); ++j ) 
         {
     	    tmp_nodes.unique_add( base_poly.get_pt(i, j) );
+            //tmp_nodes.course_add( base_poly.get_pt(i, j) );
     	}
     }
 
@@ -531,9 +566,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
 	    for ( j = 0; j < divided_base.contour_size( i ); ++j ) 
         {
     	    tmp_nodes.unique_add( divided_base.get_pt(i, j) );
+            //tmp_nodes.course_add( divided_base.get_pt(i, j) );
     	}
     }
 
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
+
     // second pass : runways
     for ( k = 0; k < (int)rwy_polys.size(); ++k ) 
     {
@@ -564,6 +603,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	line_polys[k].set_poly( poly );
     }
 
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
 
     // One more pass to try to get rid of other yukky stuff
     for ( k = 0; k < (int)rwy_polys.size(); ++k ) 
@@ -572,12 +613,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
 
     	SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
 
+        poly = remove_cycles( poly );
         poly = remove_dups( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
         poly = remove_bad_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
         poly = remove_tiny_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
 
     	rwy_polys[k].set_poly( poly );
     }
@@ -588,12 +627,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
 
     	SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
 
+        poly = remove_cycles( poly );
         poly = remove_dups( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
         poly = remove_bad_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
         poly = remove_tiny_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
 
     	pvmt_polys[k].set_poly( poly );
     }
@@ -604,17 +641,16 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
 
     	SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
 
+        poly = remove_cycles( poly );
         poly = remove_dups( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
         poly = remove_bad_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
         poly = remove_tiny_contours( poly );
-    	SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
 
     	line_polys[k].set_poly( poly );
     }
 
-    
+    gettimeofday(&log_time, NULL);
+    SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning poly for " << icao << " at " << ctime(&log_time.tv_sec) );
 
     SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
     SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
@@ -623,15 +659,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
     SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
 
-    // write_polygon( base_poly, "base-add" );
-    SG_LOG(SG_GENERAL, SG_DEBUG, "remove dups base ");
+    base_poly = remove_cycles( base_poly );
     base_poly = remove_dups( base_poly );
-    SG_LOG(SG_GENERAL, SG_DEBUG, "remove bad contours base");
     base_poly = remove_bad_contours( base_poly );
-    SG_LOG(SG_GENERAL, SG_DEBUG, "remove small contours base");
     base_poly = remove_tiny_contours( base_poly );
-    // write_polygon( base_poly, "base-fin" );
-    SG_LOG(SG_GENERAL, SG_DEBUG, " after clean up: " << base_poly);
 
     gettimeofday(&cleanup_end, NULL);
     timersub(&cleanup_end, &cleanup_start, &cleanup_time);
@@ -641,11 +672,19 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // tesselate the polygons and prepair them for final output
     for ( i = 0; i < (int)rwy_polys.size(); ++i ) 
     {
-        SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << rwy_polys[i].get_flag());
+        SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i << " of " << rwy_polys.size() << " : flag = " << rwy_polys[i].get_flag());
 
     	TGPolygon poly = rwy_polys[i].get_poly();
+
+#if 0
+        if ( i == 62 ) {
+            tgChopNormalPolygon( "/home/pete", "Base", poly, false );
+            verbose_triangulation = true;
+        }
+#endif
+
 	    SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
-	    TGPolygon tri = polygon_tesselate_alt( poly );
+        TGPolygon tri = polygon_tesselate_alt( poly, verbose_triangulation );
 	    SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
 
         TGPolygon tc;
@@ -658,11 +697,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // tesselate the polygons and prepair them for final output
     for ( i = 0; i < (int)pvmt_polys.size(); ++i ) 
     {
-        SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << pvmt_polys[i].get_flag());
+        SG_LOG(SG_GENERAL, SG_INFO, "Tesselating pavement poly = " << i << " of " << pvmt_polys.size() << " : flag = " << pvmt_polys[i].get_flag());
 
     	TGPolygon poly = pvmt_polys[i].get_poly();
 	    SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
-	    TGPolygon tri = polygon_tesselate_alt( poly );
+	    TGPolygon tri = polygon_tesselate_alt( poly, false );
 	    SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
 
         TGPolygon tc;
@@ -682,27 +721,30 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // tesselate the polygons and prepair them for final output
     for ( i = 0; i < (int)line_polys.size(); ++i ) 
     {
-        SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << line_polys[i].get_flag());
+        SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i << " of " << line_polys.size() << " : flag = " << line_polys[i].get_flag());
 
     	TGPolygon poly = line_polys[i].get_poly();
-	    SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
-	    TGPolygon tri = polygon_tesselate_alt( poly );
-	    SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
+
+  	    SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
+        TGPolygon tri = polygon_tesselate_alt( poly, false );
+        SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
 
         TGPolygon tc;
         tc = linear_feature_tex_coords( tri, line_tps[i] );
 
-    	line_polys[i].set_tris( tri );
-	    line_polys[i].set_texcoords( tc );
+      	line_polys[i].set_tris( tri );
+        line_polys[i].set_texcoords( tc );
     }
 
-#if 0    
-	{
-    	string polypath = root + "/AirportArea";
-    	tgChopNormalPolygon( polypath, "Base", base_poly, false );
-	}
+#if 1
+    {
+        tgChopNormalPolygon( "/home/pete", "Base", base_poly, false );
+        verbose_triangulation = true;
+    }
 #endif
-	TGPolygon base_tris = polygon_tesselate_alt( base_poly );
+
+    SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly ");
+	TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
 
     gettimeofday(&triangulation_end, NULL);
     timersub(&triangulation_end, &triangulation_start, &triangulation_time);
@@ -776,6 +818,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	    for ( j = 0; j < tri_poly.contour_size(i); ++j ) 
             {
         		p = tri_poly.get_pt( i, j );
+                SG_LOG(SG_GENERAL, SG_DEBUG, "adding runway point = " << p);
+
         		index = nodes.unique_add( p );
         		tri_v.push_back( index );
 
@@ -878,6 +922,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     	for ( j = 0; j < base_tris.contour_size(i); ++j ) 
         {
     	    p = base_tris.get_pt( i, j );
+
+            SG_LOG(SG_GENERAL, SG_DEBUG, "adding base point " << p);
     	    index = nodes.unique_add( p );
     	    tri_v.push_back( index );
 
@@ -916,6 +962,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     {
     	for ( j = 0; j < divided_base.contour_size( i ); ++j ) 
         {
+            SG_LOG(SG_GENERAL, SG_DEBUG, "adding divided base point " << p);
+            
     	    nodes.unique_add( divided_base.get_pt(i, j) );
     	}
     }
@@ -927,7 +975,22 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
     // it avoids biases introduced from the surrounding area if the
     // airport is located in a bowl or on a hill.
 
+    SG_LOG(SG_GENERAL, SG_DEBUG, " calcaverage elevation");
+    
+    {
+        point_list dbg = nodes.get_node_list();
+
+        // dump the node list
+        SG_LOG(SG_GENERAL, SG_DEBUG, " node list size is " << dbg.size() );
+        for (unsigned int w = 0; w<dbg.size(); w++)
+        {
+            SG_LOG(SG_GENERAL, SG_DEBUG, " node " << w << " is " << dbg[w] );            
+        }
+    }
+
     double average = tgAverageElevation( root, elev_src, nodes.get_node_list() );
+    SG_LOG(SG_GENERAL, SG_DEBUG, " done");
+
     // cout << "average airport elevation = " << average << endl;
 
     // Now build the fitted airport surface ...
diff --git a/src/Airports/GenAirports850/airport.hxx b/src/Airports/GenAirports850/airport.hxx
index 50219de2..3bb24335 100644
--- a/src/Airports/GenAirports850/airport.hxx
+++ b/src/Airports/GenAirports850/airport.hxx
@@ -51,7 +51,7 @@ public:
 
     void AddFeatures( FeatureList* feature_list )
     {
-        for (int i=0; i<feature_list->size(); i++)
+        for (unsigned int i=0; i<feature_list->size(); i++)
         {
             features.push_back( feature_list->at(i) );
         }
diff --git a/src/Airports/GenAirports850/apt_math.cxx b/src/Airports/GenAirports850/apt_math.cxx
index ed647767..9d4afb8f 100644
--- a/src/Airports/GenAirports850/apt_math.cxx
+++ b/src/Airports/GenAirports850/apt_math.cxx
@@ -172,6 +172,39 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
     return result_list;
 }
 
+TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
+{
+    TGPolygon result_list;
+    double ptlat, ptlon, r;
+    Point3D p;
+
+    // starting point is in the middle of the rectangle width, at the beginning - stretch to heading
+    
+    // Point 1 is -90deg, 1/2 width away
+    double left_hdg = heading -90;
+    if ( left_hdg < 0 ) { left_hdg += 360.0; }
+
+    geo_direct_wgs_84 ( 0.0, lat, lon, left_hdg, width / 2.0, &ptlat, &ptlon, &r );
+    p = Point3D( ptlon, ptlat, 0.0 );
+    result_list.add_node( 0, p );
+
+    // Point 2 is heading, length away from point 1
+    geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, length, &ptlat, &ptlon, &r );
+    p = Point3D( ptlon, ptlat, 0.0 );
+    result_list.add_node( 0, p );
+
+    // Point 3 is -90deg, -width away from point 2
+    geo_direct_wgs_84 ( 0.0, ptlat, ptlon, left_hdg, -width, &ptlat, &ptlon, &r );
+    p = Point3D( ptlon, ptlat, 0.0 );
+    result_list.add_node( 0, p );
+
+    // last point is heading, -length from point 3
+    geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, -length, &ptlat, &ptlon, &r );
+    p = Point3D( ptlon, ptlat, 0.0 );
+    result_list.add_node( 0, p );
+
+    return result_list;
+}
 
 // generate a section of texture
 void gen_tex_section( const TGPolygon& runway,
diff --git a/src/Airports/GenAirports850/apt_math.hxx b/src/Airports/GenAirports850/apt_math.hxx
index 48a0b53a..59e3ead9 100644
--- a/src/Airports/GenAirports850/apt_math.hxx
+++ b/src/Airports/GenAirports850/apt_math.hxx
@@ -25,6 +25,9 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
                           double alt_m,
                           bool   add_mid );
 
+TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width );
+
+
 void gen_tex_section( const TGPolygon& runway,
                          double startl_pct, double endl_pct,
                          double startw_pct, double endw_pct,
diff --git a/src/Airports/GenAirports850/closedpoly.cxx b/src/Airports/GenAirports850/closedpoly.cxx
index 803f1035..f6308e99 100644
--- a/src/Airports/GenAirports850/closedpoly.cxx
+++ b/src/Airports/GenAirports850/closedpoly.cxx
@@ -10,6 +10,15 @@
 #include "convex_hull.hxx"
 #include "closedpoly.hxx"
 
+static void stringPurifier( string& s )
+{
+    for ( string::iterator it = s.begin(), itEnd = s.end(); it!=itEnd; ++it) {
+        if ( static_cast<unsigned int>(*it) < 32 || static_cast<unsigned int>(*it) > 127 ) {
+            (*it) = ' ';
+        }
+    }
+}
+
 ClosedPoly::ClosedPoly( char* desc )
 {
     is_pavement = false;
@@ -17,6 +26,7 @@ ClosedPoly::ClosedPoly( char* desc )
     if ( desc )
     {
         description = desc;
+        stringPurifier(description);
     }
     else
     {
@@ -38,6 +48,7 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
     if ( desc )
     {
         description = desc;
+        stringPurifier(description);
     }
     else
     {
@@ -65,7 +76,7 @@ void ClosedPoly::AddNode( BezNode* node )
     {
         if (!cur_feature)
         {
-            string feature_desc = description + ":";
+            string feature_desc = description + " - ";
             if (boundary)
             {
                 feature_desc += "hole";
@@ -84,10 +95,10 @@ void ClosedPoly::AddNode( BezNode* node )
 
 void ClosedPoly::CreateConvexHull( void )
 {
-    TGPolygon  convexHull;
-    point_list nodes;
-    Point3D    p;
-    int        i;
+    TGPolygon    convexHull;
+    point_list   nodes;
+    Point3D      p;
+    unsigned int i;
 
     if (boundary->size() > 2)
     {
@@ -105,7 +116,7 @@ void ClosedPoly::CreateConvexHull( void )
     }
 }
 
-int ClosedPoly::CloseCurContour()
+void ClosedPoly::CloseCurContour()
 {
     SG_LOG(SG_GENERAL, SG_DEBUG, "Close Contour");
 
@@ -151,7 +162,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
     Point3D cp2;    
 
     int curve_type = CURVE_LINEAR;
-    int i;
+    unsigned int i;
 
     SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
 
@@ -346,7 +357,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
     double h1;
     double o1;
     double az2;
-    int i;
+    unsigned int i;
         
     // iterate through each bezier node in the contour
     for (i=0; i<src.size(); i++)
@@ -427,7 +438,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
 }
 
 // finish the poly - convert to TGPolygon, and tesselate
-int ClosedPoly::Finish()
+void ClosedPoly::Finish()
 {
     point_list          dst_contour;
 
@@ -448,7 +459,7 @@ int ClosedPoly::Finish()
         pre_tess.add_contour( dst_contour, 0 );
 
         // The convert the hole contours
-        for (int i=0; i<holes.size(); i++)
+        for (unsigned int i=0; i<holes.size(); i++)
         {
             dst_contour.clear();
             ConvertContour( holes[i], &dst_contour );
@@ -574,4 +585,6 @@ int ClosedPoly::BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clear
         // and add the clearing to the base
         *apt_base = tgPolygonUnion( pre_tess, *apt_base );
     }
+
+    return 1;
 }
diff --git a/src/Airports/GenAirports850/closedpoly.hxx b/src/Airports/GenAirports850/closedpoly.hxx
index bb499c5d..c022d331 100644
--- a/src/Airports/GenAirports850/closedpoly.hxx
+++ b/src/Airports/GenAirports850/closedpoly.hxx
@@ -24,8 +24,8 @@ public:
     
     inline string GetDescription() { return description; }
     void AddNode( BezNode* node );
-    int  CloseCurContour();
-    int  Finish();
+    void CloseCurContour();
+    void Finish();
 
     // Build BTG for airport base for airports with boundary
     int  BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing );
diff --git a/src/Airports/GenAirports850/elevations.cxx b/src/Airports/GenAirports850/elevations.cxx
index 376689bb..21a93f66 100644
--- a/src/Airports/GenAirports850/elevations.cxx
+++ b/src/Airports/GenAirports850/elevations.cxx
@@ -68,21 +68,23 @@ double tgAverageElevation( const string &root, const string_list elev_src,
     }
 
     while ( !done ) {
-	// find first node with -9999 elevation
+        // find first node with -9999 elevation
         Point3D first(0.0);
         bool found_one = false;
         for ( i = 0; i < points.size(); ++i ) {
             if ( points[i].z() < -9000.0 && !found_one ) {
                 first = points[i];
+                SG_LOG( SG_GENERAL, SG_DEBUG, "founf first = " << first );
+
                 found_one = true;
             }
         }
 
-	if ( found_one ) {
-	    SGBucket b( first.x(), first.y() );
-	    string base = b.gen_base_path();
+        if ( found_one ) {
+            SGBucket b( first.x(), first.y() );
+            string base = b.gen_base_path();
 
-	    // try the various elevation sources
+            // try the various elevation sources
             i = 0;
             bool found_file = false;
             while ( !found_file && i < elev_src.size() ) {
@@ -98,7 +100,7 @@ double tgAverageElevation( const string &root, const string_list elev_src,
             
             // this will fill in a zero structure if no array data
             // found/opened
-	    array.parse( b );
+            array.parse( b );
 
             // this will do a hasty job of removing voids by inserting
             // data from the nearest neighbor (sort of)
diff --git a/src/Airports/GenAirports850/main.cxx b/src/Airports/GenAirports850/main.cxx
index 0f5afc7f..18f1c492 100644
--- a/src/Airports/GenAirports850/main.cxx
+++ b/src/Airports/GenAirports850/main.cxx
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
     setup_default_elevation_sources(elev_src);
 
     // Set verbose
-//    sglog().setLogLevels( SG_GENERAL, SG_BULK );
+    // sglog().setLogLevels( SG_GENERAL, SG_BULK );
     sglog().setLogLevels( SG_GENERAL, SG_INFO );
 
     SG_LOG(SG_GENERAL, SG_INFO, "Run genapt");
diff --git a/src/Airports/GenAirports850/parser.cxx b/src/Airports/GenAirports850/parser.cxx
index 4d30ed82..fac47383 100644
--- a/src/Airports/GenAirports850/parser.cxx
+++ b/src/Airports/GenAirports850/parser.cxx
@@ -345,6 +345,8 @@ void Parser::Parse()
         }
         gettimeofday(&parse_end, NULL);
         timersub(&parse_end, &parse_start, &parse_time);
+        
+        SG_LOG( SG_GENERAL, SG_ALERT, "Finished parsing airport " << airport_icaos[i] << " at " << ctime(&parse_end.tv_sec) );
 
         // write the airport BTG
         if (cur_airport)
@@ -536,9 +538,13 @@ ClosedPoly* Parser::ParsePavement( char* line )
     if (numParams == 4)
     {
         d = strstr(line,desc);
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
+    }
+    else
+    {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th );
     }
 
-    SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
     poly = new ClosedPoly(st, s, th, d);
 
     return poly;
@@ -599,178 +605,146 @@ int Parser::ParseLine(char* line)
 
     BezNode* cur_node = NULL;
 
-    // Get the number code
-    tok = strtok(line, " \t\r\n");
-
-    if (tok)
+    if (*line != '#')
     {
-        line += strlen(tok)+1;
-        code = atoi(tok);
+        // Get the number code
+        tok = strtok(line, " \t\r\n");
 
-        switch(code)
+        if (tok)
         {
-            case LAND_AIRPORT_CODE: 
-            case SEA_AIRPORT_CODE:
-                if (cur_state == STATE_NONE)
-                {
+            line += strlen(tok)+1;
+            code = atoi(tok);
+
+            switch(code)
+            {
+                case LAND_AIRPORT_CODE: 
+                case SEA_AIRPORT_CODE:
+                    if (cur_state == STATE_NONE)
+                    {
+                        SetState( STATE_PARSE_SIMPLE );
+                        SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
+                        cur_airport = new Airport( code, line );
+                    }
+                    else
+                    {
+                        SetState( STATE_DONE );
+                    }
+                    break;
+                case HELIPORT_CODE:
+                    if (cur_state == STATE_NONE)
+                    {
+                        SetState( STATE_PARSE_SIMPLE );
+                        SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
+                        cur_airport = new Airport( code, line );
+                    }
+                    else
+                    {
+                        SetState( STATE_DONE );
+                    }
+                    break;
+    
+                case LAND_RUNWAY_CODE:
                     SetState( STATE_PARSE_SIMPLE );
-                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
-                    cur_airport = new Airport( code, line );
-                }
-                else
-                {
-                    SetState( STATE_DONE );
-                }
-                break;
-            case HELIPORT_CODE:
-                if (cur_state == STATE_NONE)
-                {
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
+                    cur_runway = new Runway(line);
+                    if (cur_airport)
+                    {
+                        cur_airport->AddRunway( cur_runway );
+                    }
+                    break;
+    
+                case WATER_RUNWAY_CODE:
                     SetState( STATE_PARSE_SIMPLE );
-                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
-                    cur_airport = new Airport( code, line );
-                }
-                else
-                {
-                    SetState( STATE_DONE );
-                }
-                break;
-
-            case LAND_RUNWAY_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
-                cur_runway = new Runway(line);
-                if (cur_airport)
-                {
-                    cur_airport->AddRunway( cur_runway );
-                }
-                break;
-
-            case WATER_RUNWAY_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
-                cur_waterrunway = new WaterRunway(line);
-                if (cur_airport)
-                {
-                    cur_airport->AddWaterRunway( cur_waterrunway );
-                }
-                break;
-            case HELIPAD_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
-                cur_helipad = new Helipad(line);
-                if (cur_airport)
-                {
-                    cur_airport->AddHelipad( cur_helipad );
-                }
-                break;
-
-            case PAVEMENT_CODE:
-                SetState( STATE_PARSE_PAVEMENT );
-                cur_pavement  = ParsePavement( line );
-                break;
-
-            case LINEAR_FEATURE_CODE:
-                SetState( STATE_PARSE_FEATURE );
-                cur_feat = ParseFeature( line );
-                break;
-
-            case BOUNDRY_CODE:
-                SetState( STATE_PARSE_BOUNDARY );
-                cur_boundary = ParseBoundary( line ); 
-                break;
-
-            case NODE_CODE:
-            case BEZIER_NODE_CODE:
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
-                cur_node = ParseNode( code, line, prev_node );
-
-                if ( prev_node && (cur_node != prev_node) )
-                {
-                    // prev node is done - process it\n");
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
+                    cur_waterrunway = new WaterRunway(line);
+                    if (cur_airport)
+                    {
+                        cur_airport->AddWaterRunway( cur_waterrunway );
+                    }
+                    break;
+                case HELIPAD_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
+                    cur_helipad = new Helipad(line);
+                    if (cur_airport)
+                    {
+                        cur_airport->AddHelipad( cur_helipad );
+                    }
+                    break;
+    
+                case PAVEMENT_CODE:
+                    SetState( STATE_PARSE_PAVEMENT );
+                    cur_pavement  = ParsePavement( line );
+                    break;
+    
+                case LINEAR_FEATURE_CODE:
+                    SetState( STATE_PARSE_FEATURE );
+                    cur_feat = ParseFeature( line );
+                    break;
+    
+                case BOUNDRY_CODE:
+                    SetState( STATE_PARSE_BOUNDARY );
+                    cur_boundary = ParseBoundary( line ); 
+                    break;
+    
+                case NODE_CODE:
+                case BEZIER_NODE_CODE:
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
+                    cur_node = ParseNode( code, line, prev_node );
+    
+                    if ( prev_node && (cur_node != prev_node) )
+                    {
+                        // prev node is done - process it\n");
+                        if ( cur_state == STATE_PARSE_PAVEMENT )
+                        {
+                            cur_pavement->AddNode( prev_node );
+                        }
+                        else if ( cur_state == STATE_PARSE_FEATURE )
+                        {
+                            cur_feat->AddNode( prev_node );
+                        }
+                        else if ( cur_state == STATE_PARSE_BOUNDARY )
+                        {
+                            cur_boundary->AddNode( prev_node );
+                        }
+                    }
+    
+                    prev_node = cur_node;
+                    break;
+    
+                case CLOSE_NODE_CODE:
+                case CLOSE_BEZIER_NODE_CODE:
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
+                    cur_node = ParseNode( code, line, prev_node );
+    
                     if ( cur_state == STATE_PARSE_PAVEMENT )
                     {
-                        cur_pavement->AddNode( prev_node );
-                    }
-                    else if ( cur_state == STATE_PARSE_FEATURE )
-                    {
-                        cur_feat->AddNode( prev_node );
+                        if (cur_node != prev_node)
+                        {
+                            cur_pavement->AddNode( prev_node );
+                            cur_pavement->AddNode( cur_node );
+                        }
+                        else
+                        {
+                            cur_pavement->AddNode( cur_node );
+                        }
+                        cur_pavement->CloseCurContour();
                     }
                     else if ( cur_state == STATE_PARSE_BOUNDARY )
                     {
-                        cur_boundary->AddNode( prev_node );
+                        if (cur_node != prev_node)
+                        {
+                            cur_boundary->AddNode( prev_node );
+                            cur_boundary->AddNode( cur_node );
+                        }
+                        else
+                        {
+                            cur_boundary->AddNode( cur_node );
+                        }
+                        cur_boundary->CloseCurContour();
                     }
-                }
-
-                prev_node = cur_node;
-                break;
-
-            case CLOSE_NODE_CODE:
-            case CLOSE_BEZIER_NODE_CODE:
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
-                cur_node = ParseNode( code, line, prev_node );
-
-                if ( cur_state == STATE_PARSE_PAVEMENT )
-                {
-                    if (cur_node != prev_node)
+                    else if ( cur_state == STATE_PARSE_FEATURE )
                     {
-                        cur_pavement->AddNode( prev_node );
-                        cur_pavement->AddNode( cur_node );
-                    }
-                    else
-                    {
-                        cur_pavement->AddNode( cur_node );
-                    }
-                    cur_pavement->CloseCurContour();
-                }
-                else if ( cur_state == STATE_PARSE_BOUNDARY )
-                {
-                    if (cur_node != prev_node)
-                    {
-                        cur_boundary->AddNode( prev_node );
-                        cur_boundary->AddNode( cur_node );
-                    }
-                    else
-                    {
-                        cur_boundary->AddNode( cur_node );
-                    }
-                    cur_boundary->CloseCurContour();
-                }
-                else if ( cur_state == STATE_PARSE_FEATURE )
-                {
-                    if (cur_node != prev_node)
-                    {
-                        cur_feat->AddNode( prev_node );
-                        cur_feat->AddNode( cur_node );
-                    }
-                    else
-                    {
-                        cur_feat->AddNode( cur_node );
-                    }
-                    if (cur_airport)
-                    {
-                        cur_feat->Finish();
-                        cur_airport->AddFeature( cur_feat );
-                    }
-                    cur_feat = NULL;
-                    SetState( STATE_NONE );
-                }
-                prev_node = NULL;
-                cur_node  = NULL;
-                break;
-
-            case TERM_NODE_CODE:
-            case TERM_BEZIER_NODE_CODE:
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
-
-                if ( cur_state == STATE_PARSE_FEATURE )
-                {
-                    // we have some bad data - termination nodes right after the
-                    // linear feature declaration - can't do anything with a
-                    // single point - detect and delete.
-                    if ( prev_node )
-                    {
-                        cur_node = ParseNode( code, line, prev_node );
-
                         if (cur_node != prev_node)
                         {
                             cur_feat->AddNode( prev_node );
@@ -785,87 +759,122 @@ int Parser::ParseLine(char* line)
                             cur_feat->Finish();
                             cur_airport->AddFeature( cur_feat );
                         }
+                        cur_feat = NULL;
+                        SetState( STATE_NONE );
                     }
-                    else
+                    prev_node = NULL;
+                    cur_node  = NULL;
+                    break;
+    
+                case TERM_NODE_CODE:
+                case TERM_BEZIER_NODE_CODE:
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
+    
+                    if ( cur_state == STATE_PARSE_FEATURE )
                     {
-                        SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
-
-                        // this feature is bogus...
-                        delete cur_feat;
+                        // we have some bad data - termination nodes right after the
+                        // linear feature declaration - can't do anything with a
+                        // single point - detect and delete.
+                        if ( prev_node )
+                        {
+                            cur_node = ParseNode( code, line, prev_node );
+    
+                            if (cur_node != prev_node)
+                            {
+                                cur_feat->AddNode( prev_node );
+                                cur_feat->AddNode( cur_node );
+                            }
+                            else
+                            {
+                                cur_feat->AddNode( cur_node );
+                            }
+                            if (cur_airport)
+                            {
+                                cur_feat->Finish();
+                                cur_airport->AddFeature( cur_feat );
+                            }
+                        }
+                        else
+                        {
+                            SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
+    
+                            // this feature is bogus...
+                            delete cur_feat;
+                        }
+                        cur_feat = NULL;
+                        SetState( STATE_NONE );
                     }
-                    cur_feat = NULL;
-                    SetState( STATE_NONE );
-                }
-                prev_node = NULL;
-                cur_node  = NULL;
-                break;
-
-            case AIRPORT_VIEWPOINT_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
-                break;
-            case AIRPLANE_STARTUP_LOCATION_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
-                break;
-            case LIGHT_BEACON_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
-                cur_beacon = new Beacon(line);
-                cur_airport->AddBeacon( cur_beacon );                                
-                break;
-            case WINDSOCK_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
-                cur_windsock = new Windsock(line);
-                cur_airport->AddWindsock( cur_windsock );                                
-                break;
-            case TAXIWAY_SIGN:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
-                cur_sign = new Sign(line);
-                cur_airport->AddSign( cur_sign );                                
-                break;
-            case LIGHTING_OBJECT:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
-                cur_object = new LightingObj(line);
-                cur_airport->AddObj( cur_object );
-                break;
-            case COMM_FREQ1_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
-                break;
-            case COMM_FREQ2_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
-                break;
-            case COMM_FREQ3_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
-                break;
-            case COMM_FREQ4_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
-                break;
-            case COMM_FREQ5_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
-                break;
-            case COMM_FREQ6_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
-                break;
-            case COMM_FREQ7_CODE:
-                SetState( STATE_PARSE_SIMPLE );
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
-                break;
-            case END_OF_FILE :
-                SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
-                SetState( STATE_DONE );
-                break;
+                    prev_node = NULL;
+                    cur_node  = NULL;
+                    break;
+    
+                case AIRPORT_VIEWPOINT_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
+                    break;
+                case AIRPLANE_STARTUP_LOCATION_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
+                    break;
+                case LIGHT_BEACON_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
+                    cur_beacon = new Beacon(line);
+                    cur_airport->AddBeacon( cur_beacon );                                
+                    break;
+                case WINDSOCK_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
+                    cur_windsock = new Windsock(line);
+                    cur_airport->AddWindsock( cur_windsock );                                
+                    break;
+                case TAXIWAY_SIGN:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
+                    cur_sign = new Sign(line);
+                    cur_airport->AddSign( cur_sign );                                
+                    break;
+                case LIGHTING_OBJECT:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
+                    cur_object = new LightingObj(line);
+                    cur_airport->AddObj( cur_object );
+                    break;
+                case COMM_FREQ1_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
+                    break;
+                case COMM_FREQ2_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
+                    break;
+                case COMM_FREQ3_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
+                    break;
+                case COMM_FREQ4_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
+                    break;
+                case COMM_FREQ5_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
+                    break;
+                case COMM_FREQ6_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
+                    break;
+                case COMM_FREQ7_CODE:
+                    SetState( STATE_PARSE_SIMPLE );
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
+                    break;
+                case END_OF_FILE :
+                    SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
+                    SetState( STATE_DONE );
+                    break;
+            }
         }
     }
-
+    
     return cur_state;
 }
diff --git a/src/Airports/GenAirports850/runway.cxx b/src/Airports/GenAirports850/runway.cxx
index 27363327..6cb430fd 100644
--- a/src/Airports/GenAirports850/runway.cxx
+++ b/src/Airports/GenAirports850/runway.cxx
@@ -136,8 +136,8 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
         case 4: // Dirt
         case 5: // Gravel
             SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Turf, Dirt or Gravel" << rwy.surface );
-	        gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
-                gen_runway_lights( alt_m, rwy_lights );
+            gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
+            gen_runway_lights( alt_m, rwy_lights );
             break;
 
         case 12: // dry lakebed
@@ -164,10 +164,10 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
     if (apt_base)
     {
         // generate area around runways
-        base      = gen_runway_area_w_extend( 0.0, rwy.width * 0.25, -rwy.overrun[0], -rwy.overrun[1], rwy.width * 0.25);
+        base      = gen_runway_area_w_extend( 0.0, 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0);
 
         // also clear a safe area around the runway
-        safe_base = gen_runway_area_w_extend( 0.0, rwy.width, -rwy.overrun[0], -rwy.overrun[1], rwy.width );
+        safe_base = gen_runway_area_w_extend( 0.0, 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
 
         // add this to the airport clearing
         *apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
diff --git a/src/Airports/GenAirports850/rwy_gen.cxx b/src/Airports/GenAirports850/rwy_gen.cxx
index 75eae0a3..53b0c1d7 100644
--- a/src/Airports/GenAirports850/rwy_gen.cxx
+++ b/src/Airports/GenAirports850/rwy_gen.cxx
@@ -354,7 +354,7 @@ void Runway::BuildShoulder( float alt_m,
         } else SG_LOG(SG_GENERAL, SG_ALERT, "Unknown shoulder surface code = " << rwy.shoulder );
 
     } else if (rwy.shoulder == 0){ // We add a fake shoulder if the runway has an asphalt or concrete surface
-        shoulder_width = 1;
+        shoulder_width = 1.0;
         if (rwy.surface == 1){
             shoulder_surface = "pa_shoulder_f";
         } else if (rwy.surface == 2){
@@ -365,6 +365,13 @@ void Runway::BuildShoulder( float alt_m,
     SG_LOG(SG_GENERAL, SG_DEBUG, "Shoulder surface is: " << shoulder_surface );
 
     if (shoulder_width > 0.0f) {
+
+        // we need to break these shoulders up into managable pieces, as we're asked to triangulate
+        // 3-4 km long by 1m wide strips - jrs-can't handle it.
+        double max_dist = (double)shoulder_width * 50.0f;
+        int numSegs = (rwy.length / max_dist) + 1;
+        double dist = rwy.length / (double)numSegs;
+
         // Create both shoulder sides
         for (int i=0; i<2; ++i){
             double step;
@@ -374,44 +381,40 @@ void Runway::BuildShoulder( float alt_m,
             /* If the are 'equal' there's a good chance roundoff error can create a  */
             /* REALY thin long polygon, which causes a segfault  */
             if (i == 0){
-                step= (rwy.width + shoulder_width)*0.5 - 0.00001;
+                step= (rwy.width + shoulder_width)*0.5;
             } else if (i == 1) {
-                step= -(rwy.width + shoulder_width)*0.5 + 0.00001;
+                step= -(rwy.width + shoulder_width)*0.5;
             }
             double left_hdg = rwy.heading - 90.0;
 
             if ( left_hdg < 0 ) { left_hdg += 360.0; }
 
-            geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg,
-                                step, &lat, &lon, &r );
+            geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg, step, &lat, &lon, &r );
+            Point3D ref = Point3D( lon, lat, 0.0f );
 
-            Point3D shoulder1 = Point3D( lon, lat, 0.0f );
+            for (int j=0; j<numSegs; j++)
+            {
+                geo_direct_wgs_84 ( alt_m, ref.y(), ref.x(), rwy.heading, (j*dist), &lat, &lon, &r );
+                TGPolygon shoulderSegment = gen_wgs84_rect( lat, lon, rwy.heading, dist+0.2, shoulder_width+0.5 );
 
-            geo_direct_wgs_84 ( alt_m, rwy.lat[1], rwy.lon[1], left_hdg,
-                                step, &lat, &lon, &r );
+                TGSuperPoly sp;
+                TGTexParams tp;
+                TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
 
-            Point3D shoulder2 = Point3D( lon, lat, 0.0f );
+                sp.erase();
+                sp.set_poly( clipped );
+                sp.set_material( shoulder_surface );
+                rwy_polys->push_back( sp );
 
-            TGPolygon shoulder = gen_wgs84_area( shoulder1, shoulder2, 0.0, 0.0, 0.0, shoulder_width, rwy.heading, alt_m, false);
+                *accum = tgPolygonUnion( shoulderSegment, *accum );
 
-            TGSuperPoly sp;
-            TGTexParams tp;
-            TGPolygon clipped = tgPolygonDiff( shoulder, *accum );
-            TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
-
-            sp.erase();
-            sp.set_poly( split );
-            sp.set_material( shoulder_surface );
-            rwy_polys->push_back( sp );
-
-            *accum = tgPolygonUnion( shoulder, *accum );
-
-            tp = TGTexParams( shoulder.get_pt(0,0), shoulder_width , rwy.length + 2, rwy.heading );
-            if (i == 1){
-                tp.set_maxu(0);
-                tp.set_minu(1);
+                tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
+                if (i == 0){
+                    tp.set_maxu(0);
+                    tp.set_minu(1);
+                }
+                texparams->push_back( tp );
             }
-            texparams->push_back( tp );
         }
     }
 }
diff --git a/src/Lib/Array/array.cxx b/src/Lib/Array/array.cxx
index fb5ac989..d8883562 100644
--- a/src/Lib/Array/array.cxx
+++ b/src/Lib/Array/array.cxx
@@ -63,6 +63,8 @@ TGArray::TGArray( const string &file ):
     for (int i = 0; i < ARRAY_SIZE_1; i++)
         in_data[i] = new int[ARRAY_SIZE_1];
 
+    SG_LOG(SG_GENERAL, SG_ALERT, "ps TGArray CONstructor called." );
+
     TGArray::open(file);
 }
 
@@ -75,7 +77,7 @@ bool TGArray::open( const string& file_base ) {
     string array_name = file_base + ".arr.gz";
     array_in = new sg_gzifstream( array_name );
     if ( ! array_in->is_open() ) {
-        SG_LOG(SG_GENERAL, SG_DEBUG, "  Cannot open " << array_name );
+        SG_LOG(SG_GENERAL, SG_DEBUG, "  ps: Cannot open " << array_name );
         success = false;
     } else {
         SG_LOG(SG_GENERAL, SG_DEBUG, "  Opening array data file: " << array_name );
@@ -89,7 +91,7 @@ bool TGArray::open( const string& file_base ) {
         // can do a really stupid/crude fit on the fly, but it will
         // not be nearly as nice as what the offline terrafit utility
         // would have produced.
-        SG_LOG(SG_GENERAL, SG_DEBUG, "  Cannot open " << fitted_name );
+        SG_LOG(SG_GENERAL, SG_DEBUG, "  ps: Cannot open " << fitted_name );
     } else {
         SG_LOG(SG_GENERAL, SG_DEBUG, "  Opening fitted data file: " << fitted_name );
     }
diff --git a/src/Lib/Geometry/poly_support.cxx b/src/Lib/Geometry/poly_support.cxx
index 66c50ee8..caf231dc 100644
--- a/src/Lib/Geometry/poly_support.cxx
+++ b/src/Lib/Geometry/poly_support.cxx
@@ -50,8 +50,6 @@ extern "C" {
 #include "trisegs.hxx"
 
 using std::copy;
-using std::cout;
-using std::endl;
 using std::ostream_iterator;
 using std::sort;
 using std::vector;
@@ -117,7 +115,7 @@ static bool intersects( Point3D p0, Point3D p1, double x, Point3D *result ) {
 
 // basic triangulation of a polygon with out adding points or
 // splitting edges, this should triangulate around interior holes.
-void polygon_tesselate( const TGPolygon &p, 
+int polygon_tesselate( const TGPolygon &p, 
             const point_list &extra_nodes, 
 			triele_list &elelist,
 			point_list &out_pts,
@@ -125,8 +123,7 @@ void polygon_tesselate( const TGPolygon &p,
 {
     struct triangulateio in, out, vorout;
     int i;
-
-    tri_flags = "pzqenXYYQ";
+    int success = 0;
 
     // make sure all elements of these structs point to "NULL"
     zero_triangulateio( &in );
@@ -272,7 +269,7 @@ void polygon_tesselate( const TGPolygon &p,
     // no new points on boundary (Y), no internal segment
     // splitting (YY), no quality refinement (q)
     // Quite (Q)
-    triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
+    success = triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
 
     // TEMPORARY
     // write_tri_data(&out);
@@ -280,33 +277,36 @@ void polygon_tesselate( const TGPolygon &p,
     // now copy the results back into the corresponding TGTriangle
     // structures
 
-    // triangles
-    elelist.clear();
-    int n1, n2, n3;
-    double attribute;
-    for ( i = 0; i < out.numberoftriangles; ++i ) {
-        n1 = out.trianglelist[i * 3];
-        n2 = out.trianglelist[i * 3 + 1];
-        n3 = out.trianglelist[i * 3 + 2];
-        if ( out.numberoftriangleattributes > 0 ) {
-            attribute = out.triangleattributelist[i];
-        } else {
-            attribute = 0.0;
+    if (success >= 0) {
+    
+        // triangles
+        elelist.clear();
+        int n1, n2, n3;
+        double attribute;
+        for ( i = 0; i < out.numberoftriangles; ++i ) {
+            n1 = out.trianglelist[i * 3];
+            n2 = out.trianglelist[i * 3 + 1];
+            n3 = out.trianglelist[i * 3 + 2];
+            if ( out.numberoftriangleattributes > 0 ) {
+                attribute = out.triangleattributelist[i];
+            } else {
+                attribute = 0.0;
+            }
+            // cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
+            elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
+        }
+
+        // output points
+        out_pts.clear();
+        double x, y, z;
+        for ( i = 0; i < out.numberofpoints; ++i ) {
+            x = out.pointlist[i * 2    ];
+            y = out.pointlist[i * 2 + 1];
+            z = out.pointattributelist[i];
+            out_pts.push_back( Point3D(x, y, z) );
         }
-        // cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
-        elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
     }
 
-    // output points
-    out_pts.clear();
-    double x, y, z;
-    for ( i = 0; i < out.numberofpoints; ++i ) {
-        x = out.pointlist[i * 2    ];
-        y = out.pointlist[i * 2 + 1];
-        z = out.pointattributelist[i];
-        out_pts.push_back( Point3D(x, y, z) );
-    }
-   
     // free mem allocated to the "Triangle" structures
     free(in.pointlist);
     free(in.pointattributelist);
@@ -327,6 +327,8 @@ void polygon_tesselate( const TGPolygon &p,
     free(vorout.pointattributelist);
     free(vorout.edgelist);
     free(vorout.normlist);
+
+    return success;
 }
 
 
@@ -336,7 +338,7 @@ void polygon_tesselate( const TGPolygon &p,
 // wrapper for the polygon_tesselate() function.  Note, this routine
 // will modify the points_inside list for your polygon.
 
-TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
+TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
     TGPolygon result;
     point_list extra_nodes;
     result.erase();
@@ -358,25 +360,42 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
     // 2.  Do a final triangulation of the entire polygon
     triele_list trieles;
     point_list nodes;
-//    polygon_tesselate( p, extra_nodes, trieles, nodes, "pzYYenQ" );
-    polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
+    string flags;
+    if (verbose) {
+        flags = "pzqenXYY";
+    } else {
+        flags = "pzqenXYYQ";
+    }
 
-    // 3.  Convert the tesselated output to a list of tringles.
-    //     basically a polygon with a contour for every triangle
-    for ( i = 0; i < (int)trieles.size(); ++i ) {
-	TGTriEle t = trieles[i];
-	Point3D p1 = nodes[ t.get_n1() ];
-	Point3D p2 = nodes[ t.get_n2() ];
-	Point3D p3 = nodes[ t.get_n3() ];
-	result.add_node( i, p1 );
-	result.add_node( i, p2 );
-	result.add_node( i, p3 );
+    if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
+        // 3.  Convert the tesselated output to a list of tringles.
+        //     basically a polygon with a contour for every triangle
+        for ( i = 0; i < (int)trieles.size(); ++i ) {
+        	TGTriEle t = trieles[i];
+        	Point3D p1 = nodes[ t.get_n1() ];
+        	Point3D p2 = nodes[ t.get_n2() ];
+        	Point3D p3 = nodes[ t.get_n3() ];
+        	result.add_node( i, p1 );
+        	result.add_node( i, p2 );
+        	result.add_node( i, p3 );
+        }
+    } 
+
+    // check the result for nan point
+    for (int c = 0; c < result.contours(); c++) {    
+        point_list contour = result.get_contour( c );
+        for ( int d = 0; d < (int)contour.size(); ++d ) {
+            if ( isnan( contour[d].x() ) || isnan( contour[d].y() ) ) {
+                printf("Uh-oh - got nan from tesselation\n");
+                exit(0);
+            }
+        }
     }
 
     return result;
 }
 
-TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes ) {
+TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes, bool verbose ) {
     TGPolygon result;
     result.erase();
     int i;
@@ -394,18 +413,25 @@ TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extr
     // 2.  Do a final triangulation of the entire polygon
     triele_list trieles;
     point_list  nodes;
-    polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
+    string flags;
+    if (verbose) {
+        flags = "VVpzqenXYY";
+    } else {
+        flags = "pzqenXYYQ";
+    }
 
-    // 3.  Convert the tesselated output to a list of tringles.
-    //     basically a polygon with a contour for every triangle
-    for ( i = 0; i < (int)trieles.size(); ++i ) {
-        TGTriEle t = trieles[i];
-        Point3D p1 = nodes[ t.get_n1() ];
-        Point3D p2 = nodes[ t.get_n2() ];
-        Point3D p3 = nodes[ t.get_n3() ];
-        result.add_node( i, p1 );
-        result.add_node( i, p2 );
-        result.add_node( i, p3 );
+    if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
+        // 3.  Convert the tesselated output to a list of tringles.
+        //     basically a polygon with a contour for every triangle
+        for ( i = 0; i < (int)trieles.size(); ++i ) {
+            TGTriEle t = trieles[i];
+            Point3D p1 = nodes[ t.get_n1() ];
+            Point3D p2 = nodes[ t.get_n2() ];
+            Point3D p3 = nodes[ t.get_n3() ];
+            result.add_node( i, p1 );
+            result.add_node( i, p2 );
+            result.add_node( i, p3 );
+        }
     }
 
     return result;
@@ -598,7 +624,7 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
 }
 
 static void print_contour_tree( TGContourNode *node, string indent ) {
-    cout << indent << node->get_contour_num() << endl;
+    // cout << indent << node->get_contour_num() << endl;
 
     indent += "  ";
     for ( int i = 0; i < node->get_num_kids(); ++i ) {
@@ -997,7 +1023,7 @@ static point_list reduce_contour_degeneracy( const point_list& contour ) {
 	    // remove bad node from contour.  But only remove one node.  If
 	    // the 'badness' is caused by coincident adjacent nodes, we don't
 	    // want to remove both of them, just one (either will do.)
-  	    cout << "found a bad node = " << bad_node << endl;
+  	    // cout << "found a bad node = " << bad_node << endl;
 	    point_list tmp; tmp.clear();
 	    bool found_one = false;
 	    for ( int j = 0; j < (int)result.size(); ++j ) {
@@ -1045,11 +1071,11 @@ static point_list remove_small_cycles( const point_list& contour ) {
         result.push_back( contour[i] );
         for ( unsigned int j = i + 1; j < contour.size(); ++j ) {
             if ( contour[i] == contour[j] && i + 4 > j ) {
-                cout << "detected a small cycle: i = "
-                     << i << " j = " << j << endl;
-                for ( unsigned int k = i; k <= j; ++k ) {
-                    cout << "  " << contour[k] << endl;
-                }
+                // cout << "detected a small cycle: i = "
+                //     << i << " j = " << j << endl;
+                //for ( unsigned int k = i; k <= j; ++k ) {
+                //    cout << "  " << contour[k] << endl;
+                //}
                 i = j;
             }
         }
diff --git a/src/Lib/Geometry/poly_support.hxx b/src/Lib/Geometry/poly_support.hxx
index 328f6aac..eb57c53d 100644
--- a/src/Lib/Geometry/poly_support.hxx
+++ b/src/Lib/Geometry/poly_support.hxx
@@ -53,7 +53,7 @@ inline double triangle_area( const Point3D p1,
 
 // basic triangulation of a polygon with out adding points or
 // splitting edges
-void polygon_tesselate( const TGPolygon &p,
+int polygon_tesselate( const TGPolygon &p,
             const point_list &extra_nodes,
 			triele_list &elelist,
 			point_list &out_pts,
@@ -64,10 +64,10 @@ void polygon_tesselate( const TGPolygon &p,
 // with one contour per tesselated triangle.  This is mostly just a
 // wrapper for the polygon_tesselate() function.  Note, this routine
 // will modify the points_inside list for your polygon.
-TGPolygon polygon_tesselate_alt( TGPolygon &p );
+TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose );
 
 TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, 
-            const point_list &extra_nodes );
+            const point_list &extra_nodes, bool verbose );
 
 // calculate some "arbitrary" point inside each of the polygons contours
 void calc_points_inside( TGPolygon& p );
diff --git a/src/Lib/Geometry/trinodes.hxx b/src/Lib/Geometry/trinodes.hxx
index 6998a73c..7753d91c 100644
--- a/src/Lib/Geometry/trinodes.hxx
+++ b/src/Lib/Geometry/trinodes.hxx
@@ -36,8 +36,8 @@
 
 
 #define FG_PROXIMITY_EPSILON 0.000001
-#define FG_COURSE_EPSILON 0.0003
-
+//#define FG_COURSE_EPSILON 0.0003
+#define FG_COURSE_EPSILON 0.0001
 
 class TGTriNodes {