[OpenLayers-Commits] r12409 - in sandbox/august/trunk: . apidoc_config build doc_config examples img lib/OpenLayers lib/OpenLayers/BaseTypes lib/OpenLayers/Control lib/OpenLayers/Filter lib/OpenLayers/Format lib/OpenLayers/Format/OWSContext lib/OpenLayers/Format/WFSCapabilities lib/OpenLayers/Format/WFST lib/OpenLayers/Format/WMSCapabilities lib/OpenLayers/Format/WMTSCapabilities lib/OpenLayers/Geometry lib/OpenLayers/Handler lib/OpenLayers/Lang lib/OpenLayers/Layer lib/OpenLayers/Layer/Google lib/OpenLayers/Layer/Vector lib/OpenLayers/Marker lib/OpenLayers/Popup lib/OpenLayers/Protocol lib/OpenLayers/Protocol/WFS lib/OpenLayers/Renderer lib/OpenLayers/Strategy lib/OpenLayers/Test lib/OpenLayers/Tile lib/OpenLayers/Tile/Image tests tests/BaseTypes tests/Control tests/Format tests/Format/Filter tests/Format/WFST tests/Format/WMSCapabilities tests/Handler tests/Layer tests/Layer/WMS tests/Protocol tests/Renderer tests/Tile tests/Tile/Image tests/manual tools

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Thu Sep 22 13:32:02 EDT 2011


Author: augusttown
Date: 2011-09-22 10:32:00 -0700 (Thu, 22 Sep 2011)
New Revision: 12409

Added:
   sandbox/august/trunk/lib/OpenLayers/BaseTypes/Date.js
   sandbox/august/trunk/lib/OpenLayers/Tile/BackBufferable.js
   sandbox/august/trunk/tests/BaseTypes/Date.html
   sandbox/august/trunk/tests/Test.AnotherWay.baseadditions.js
   sandbox/august/trunk/tests/Test.AnotherWay.css
   sandbox/august/trunk/tests/Test.AnotherWay.geom_eq.js
   sandbox/august/trunk/tests/Test.AnotherWay.js
   sandbox/august/trunk/tests/Test.AnotherWay.xml_eq.js
   sandbox/august/trunk/tests/Tile/BackBufferable.html
   sandbox/august/trunk/tests/manual/dateline-sketch.html
   sandbox/august/trunk/tests/manual/google-fullscreen-overlay.html
   sandbox/august/trunk/tests/manual/google-tilt.html
   sandbox/august/trunk/tools/git_to_svn.sh
Removed:
   sandbox/august/trunk/examples/google-ng.html
   sandbox/august/trunk/examples/google-ng.js
   sandbox/august/trunk/lib/OpenLayers/Layer/GoogleNG.js
   sandbox/august/trunk/lib/OpenLayers/Tile/Google.js
   sandbox/august/trunk/tests/Layer/GoogleNG.html
   sandbox/august/trunk/tests/Tile/Google.html
   sandbox/august/trunk/tests/geom_eq.js
   sandbox/august/trunk/tests/xml_eq.js
Modified:
   sandbox/august/trunk/
   sandbox/august/trunk/apidoc_config/Menu.txt
   sandbox/august/trunk/build/build.py
   sandbox/august/trunk/doc_config/Menu.txt
   sandbox/august/trunk/examples/KMLParser.html
   sandbox/august/trunk/examples/WMSDescribeLayerParser.html
   sandbox/august/trunk/examples/arcgiscache_jsonp.html
   sandbox/august/trunk/examples/buffer.html
   sandbox/august/trunk/examples/measure.html
   sandbox/august/trunk/examples/mobile-drawing.js
   sandbox/august/trunk/examples/multitouch.html
   sandbox/august/trunk/examples/select-feature-multilayer.html
   sandbox/august/trunk/examples/sld.js
   sandbox/august/trunk/examples/sundials-spherical-mercator.html
   sandbox/august/trunk/examples/sundials.html
   sandbox/august/trunk/examples/vector-formats.html
   sandbox/august/trunk/examples/wms-long-url.js
   sandbox/august/trunk/examples/wrapDateLine.html
   sandbox/august/trunk/examples/xml.html
   sandbox/august/trunk/examples/xyz-esri.html
   sandbox/august/trunk/examples/xyz-offset.js
   sandbox/august/trunk/img/cloud-popup-relative.png
   sandbox/august/trunk/lib/OpenLayers/Ajax.js
   sandbox/august/trunk/lib/OpenLayers/BaseTypes.js
   sandbox/august/trunk/lib/OpenLayers/BaseTypes/Bounds.js
   sandbox/august/trunk/lib/OpenLayers/BaseTypes/Class.js
   sandbox/august/trunk/lib/OpenLayers/BaseTypes/LonLat.js
   sandbox/august/trunk/lib/OpenLayers/BaseTypes/Size.js
   sandbox/august/trunk/lib/OpenLayers/Control.js
   sandbox/august/trunk/lib/OpenLayers/Control/DragFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/DrawFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/EditingToolbar.js
   sandbox/august/trunk/lib/OpenLayers/Control/Geolocate.js
   sandbox/august/trunk/lib/OpenLayers/Control/GetFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/Measure.js
   sandbox/august/trunk/lib/OpenLayers/Control/ModifyFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/SLDSelect.js
   sandbox/august/trunk/lib/OpenLayers/Control/SelectFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/Snapping.js
   sandbox/august/trunk/lib/OpenLayers/Control/Split.js
   sandbox/august/trunk/lib/OpenLayers/Control/TransformFeature.js
   sandbox/august/trunk/lib/OpenLayers/Control/WMSGetFeatureInfo.js
   sandbox/august/trunk/lib/OpenLayers/Control/WMTSGetFeatureInfo.js
   sandbox/august/trunk/lib/OpenLayers/Events.js
   sandbox/august/trunk/lib/OpenLayers/Filter/FeatureId.js
   sandbox/august/trunk/lib/OpenLayers/Filter/Function.js
   sandbox/august/trunk/lib/OpenLayers/Filter/Spatial.js
   sandbox/august/trunk/lib/OpenLayers/Format/GPX.js
   sandbox/august/trunk/lib/OpenLayers/Format/KML.js
   sandbox/august/trunk/lib/OpenLayers/Format/OWSContext/v0_3_1.js
   sandbox/august/trunk/lib/OpenLayers/Format/QueryStringFilter.js
   sandbox/august/trunk/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js
   sandbox/august/trunk/lib/OpenLayers/Format/WFST/v1.js
   sandbox/august/trunk/lib/OpenLayers/Format/WMC.js
   sandbox/august/trunk/lib/OpenLayers/Format/WMSCapabilities/v1.js
   sandbox/august/trunk/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js
   sandbox/august/trunk/lib/OpenLayers/Format/WPSDescribeProcess.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/Curve.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/LineString.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/LinearRing.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/MultiLineString.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPoint.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPolygon.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/Polygon.js
   sandbox/august/trunk/lib/OpenLayers/Geometry/Surface.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Click.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Hover.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Path.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Pinch.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Point.js
   sandbox/august/trunk/lib/OpenLayers/Handler/Polygon.js
   sandbox/august/trunk/lib/OpenLayers/Handler/RegularPolygon.js
   sandbox/august/trunk/lib/OpenLayers/Lang/be-tarask.js
   sandbox/august/trunk/lib/OpenLayers/Lang/br.js
   sandbox/august/trunk/lib/OpenLayers/Lang/ca.js
   sandbox/august/trunk/lib/OpenLayers/Lang/cs-CZ.js
   sandbox/august/trunk/lib/OpenLayers/Lang/da-DK.js
   sandbox/august/trunk/lib/OpenLayers/Lang/de.js
   sandbox/august/trunk/lib/OpenLayers/Lang/en.js
   sandbox/august/trunk/lib/OpenLayers/Lang/es.js
   sandbox/august/trunk/lib/OpenLayers/Lang/fi.js
   sandbox/august/trunk/lib/OpenLayers/Lang/fr.js
   sandbox/august/trunk/lib/OpenLayers/Lang/gl.js
   sandbox/august/trunk/lib/OpenLayers/Lang/gsw.js
   sandbox/august/trunk/lib/OpenLayers/Lang/hr.js
   sandbox/august/trunk/lib/OpenLayers/Lang/hsb.js
   sandbox/august/trunk/lib/OpenLayers/Lang/hu.js
   sandbox/august/trunk/lib/OpenLayers/Lang/ia.js
   sandbox/august/trunk/lib/OpenLayers/Lang/id.js
   sandbox/august/trunk/lib/OpenLayers/Lang/is.js
   sandbox/august/trunk/lib/OpenLayers/Lang/it.js
   sandbox/august/trunk/lib/OpenLayers/Lang/ja.js
   sandbox/august/trunk/lib/OpenLayers/Lang/ksh.js
   sandbox/august/trunk/lib/OpenLayers/Lang/lt.js
   sandbox/august/trunk/lib/OpenLayers/Lang/nb.js
   sandbox/august/trunk/lib/OpenLayers/Lang/nds.js
   sandbox/august/trunk/lib/OpenLayers/Lang/nl.js
   sandbox/august/trunk/lib/OpenLayers/Lang/oc.js
   sandbox/august/trunk/lib/OpenLayers/Lang/pt-BR.js
   sandbox/august/trunk/lib/OpenLayers/Lang/pt.js
   sandbox/august/trunk/lib/OpenLayers/Lang/ru.js
   sandbox/august/trunk/lib/OpenLayers/Lang/sk.js
   sandbox/august/trunk/lib/OpenLayers/Lang/sv-SE.js
   sandbox/august/trunk/lib/OpenLayers/Lang/vi.js
   sandbox/august/trunk/lib/OpenLayers/Lang/zh-CN.js
   sandbox/august/trunk/lib/OpenLayers/Lang/zh-TW.js
   sandbox/august/trunk/lib/OpenLayers/Layer.js
   sandbox/august/trunk/lib/OpenLayers/Layer/ArcGIS93Rest.js
   sandbox/august/trunk/lib/OpenLayers/Layer/ArcGISCache.js
   sandbox/august/trunk/lib/OpenLayers/Layer/ArcIMS.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Bing.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Google/v3.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Grid.js
   sandbox/august/trunk/lib/OpenLayers/Layer/HTTPRequest.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Markers.js
   sandbox/august/trunk/lib/OpenLayers/Layer/TMS.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Vector.js
   sandbox/august/trunk/lib/OpenLayers/Layer/Vector/RootContainer.js
   sandbox/august/trunk/lib/OpenLayers/Layer/WMS.js
   sandbox/august/trunk/lib/OpenLayers/Layer/WorldWind.js
   sandbox/august/trunk/lib/OpenLayers/Layer/XYZ.js
   sandbox/august/trunk/lib/OpenLayers/Map.js
   sandbox/august/trunk/lib/OpenLayers/Marker.js
   sandbox/august/trunk/lib/OpenLayers/Marker/Box.js
   sandbox/august/trunk/lib/OpenLayers/Popup.js
   sandbox/august/trunk/lib/OpenLayers/Popup/FramedCloud.js
   sandbox/august/trunk/lib/OpenLayers/Protocol/HTTP.js
   sandbox/august/trunk/lib/OpenLayers/Protocol/Script.js
   sandbox/august/trunk/lib/OpenLayers/Protocol/WFS.js
   sandbox/august/trunk/lib/OpenLayers/Protocol/WFS/v1.js
   sandbox/august/trunk/lib/OpenLayers/Renderer/Canvas.js
   sandbox/august/trunk/lib/OpenLayers/Request.js
   sandbox/august/trunk/lib/OpenLayers/Strategy/Save.js
   sandbox/august/trunk/lib/OpenLayers/Test/AgsOgcRegression.js
   sandbox/august/trunk/lib/OpenLayers/Tile.js
   sandbox/august/trunk/lib/OpenLayers/Tile/Image.js
   sandbox/august/trunk/lib/OpenLayers/Tile/Image/IFrame.js
   sandbox/august/trunk/lib/OpenLayers/Util.js
   sandbox/august/trunk/tests/BaseTypes.html
   sandbox/august/trunk/tests/BaseTypes/Class.html
   sandbox/august/trunk/tests/BaseTypes/LonLat.html
   sandbox/august/trunk/tests/Control/DrawFeature.html
   sandbox/august/trunk/tests/Control/EditingToolbar.html
   sandbox/august/trunk/tests/Control/ModifyFeature.html
   sandbox/august/trunk/tests/Control/Snapping.html
   sandbox/august/trunk/tests/Events.html
   sandbox/august/trunk/tests/Format/Filter/v1.html
   sandbox/august/trunk/tests/Format/GPX.html
   sandbox/august/trunk/tests/Format/KML.html
   sandbox/august/trunk/tests/Format/WFST/v1.html
   sandbox/august/trunk/tests/Format/WMSCapabilities/v1_1_1.html
   sandbox/august/trunk/tests/Format/WMSCapabilities/v1_3_0.html
   sandbox/august/trunk/tests/Handler/Path.html
   sandbox/august/trunk/tests/Handler/Polygon.html
   sandbox/august/trunk/tests/Handler/RegularPolygon.html
   sandbox/august/trunk/tests/Layer/ArcGIS93Rest.html
   sandbox/august/trunk/tests/Layer/ArcGISCache.html
   sandbox/august/trunk/tests/Layer/Grid.html
   sandbox/august/trunk/tests/Layer/Image.html
   sandbox/august/trunk/tests/Layer/MapServer.html
   sandbox/august/trunk/tests/Layer/Text.html
   sandbox/august/trunk/tests/Layer/Vector.html
   sandbox/august/trunk/tests/Layer/WMS.html
   sandbox/august/trunk/tests/Layer/WMS/Post.html
   sandbox/august/trunk/tests/Map.html
   sandbox/august/trunk/tests/Popup.html
   sandbox/august/trunk/tests/Protocol/Script.html
   sandbox/august/trunk/tests/Protocol/WFS.html
   sandbox/august/trunk/tests/Renderer/Canvas.html
   sandbox/august/trunk/tests/Tile.html
   sandbox/august/trunk/tests/Tile/Image.html
   sandbox/august/trunk/tests/Tile/Image/IFrame.html
   sandbox/august/trunk/tests/Util.html
   sandbox/august/trunk/tests/list-tests.html
   sandbox/august/trunk/tests/run-tests.html
   sandbox/august/trunk/tools/closure.py
Log:



Property changes on: sandbox/august/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/openlayers:10329-10354,10357-10502,10504-12173
   + /trunk/openlayers:10329-10354,10357-10502,10504-12408

Modified: sandbox/august/trunk/apidoc_config/Menu.txt
===================================================================
--- sandbox/august/trunk/apidoc_config/Menu.txt	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/apidoc_config/Menu.txt	2011-09-22 17:32:00 UTC (rev 12409)
@@ -55,6 +55,7 @@
       File: Base Types  (no auto-title, OpenLayers/BaseTypes.js)
       File: Bounds  (no auto-title, OpenLayers/BaseTypes/Bounds.js)
       File: Class  (no auto-title, OpenLayers/BaseTypes/Class.js)
+      File: Date  (no auto-title, OpenLayers/BaseTypes/Date.js)
       File: Element  (no auto-title, OpenLayers/BaseTypes/Element.js)
       File: LonLat  (no auto-title, OpenLayers/BaseTypes/LonLat.js)
       File: Pixel  (no auto-title, OpenLayers/BaseTypes/Pixel.js)
@@ -351,7 +352,6 @@
       File: GML  (no auto-title, OpenLayers/Layer/GML.js)
       File: Google  (no auto-title, OpenLayers/Layer/Google.js)
       File: Google.v3  (no auto-title, OpenLayers/Layer/Google/v3.js)
-      File: GoogleNG  (no auto-title, OpenLayers/Layer/GoogleNG.js)
       File: Grid  (no auto-title, OpenLayers/Layer/Grid.js)
       File: HTTPRequest  (no auto-title, OpenLayers/Layer/HTTPRequest.js)
       File: Image  (no auto-title, OpenLayers/Layer/Image.js)
@@ -474,7 +474,6 @@
    Group: Tile  {
 
       File: Tile  (no auto-title, OpenLayers/Tile.js)
-      File: Google  (no auto-title, OpenLayers/Tile/Google.js)
       File: Image  (no auto-title, OpenLayers/Tile/Image.js)
       File: Image.IFrame  (no auto-title, OpenLayers/Tile/Image/IFrame.js)
       File: WFS  (no auto-title, OpenLayers/Tile/WFS.js)

Modified: sandbox/august/trunk/build/build.py
===================================================================
--- sandbox/august/trunk/build/build.py	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/build/build.py	2011-09-22 17:32:00 UTC (rev 12409)
@@ -16,7 +16,7 @@
         import closure
         have_compressor.append("closure")
     except Exception, E:
-        print "No closure (%s) % E"
+        print "No closure (%s)" % E
     try:
         import closure_ws
         have_compressor.append("closure_ws")
@@ -55,7 +55,20 @@
     elif use_compressor == "minimize":
         minimized = minimize.minimize(merged)
     elif use_compressor == "closure_ws":
-        minimized = closure_ws.minimize(merged)      
+        if len(merged) > 1000000: # The maximum file size for this web service is 1000 KB.
+            print "\nPre-compressing using jsmin"
+            merged = jsmin.jsmin(merged)
+        print "\nIs being compressed using Closure Compiler Service."
+        try:
+            minimized = closure_ws.minimize(merged)
+        except Exception, E:
+            print "\nAbnormal termination."
+            sys.exit("ERROR: Closure Compilation using Web service failed!\n%s" % E)
+        if len(minimized) <= 2:
+            print "\nAbnormal termination due to compilation errors."
+            sys.exit("ERROR: Closure Compilation using Web service failed!")
+        else:
+            print '\nClosure Compilation using Web service has completed successfully.'
     elif use_compressor == "closure":
         minimized = closure.minimize(merged)      
     else: # fallback

Modified: sandbox/august/trunk/doc_config/Menu.txt
===================================================================
--- sandbox/august/trunk/doc_config/Menu.txt	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/doc_config/Menu.txt	2011-09-22 17:32:00 UTC (rev 12409)
@@ -55,6 +55,7 @@
       File: Base Types  (no auto-title, OpenLayers/BaseTypes.js)
       File: Bounds  (no auto-title, OpenLayers/BaseTypes/Bounds.js)
       File: Class  (no auto-title, OpenLayers/BaseTypes/Class.js)
+      File: Date  (no auto-title, OpenLayers/BaseTypes/Date.js)
       File: Element  (no auto-title, OpenLayers/BaseTypes/Element.js)
       File: LonLat  (no auto-title, OpenLayers/BaseTypes/LonLat.js)
       File: Pixel  (no auto-title, OpenLayers/BaseTypes/Pixel.js)
@@ -351,7 +352,6 @@
       File: GML  (no auto-title, OpenLayers/Layer/GML.js)
       File: Google  (no auto-title, OpenLayers/Layer/Google.js)
       File: Google.v3  (no auto-title, OpenLayers/Layer/Google/v3.js)
-      File: GoogleNG  (no auto-title, OpenLayers/Layer/GoogleNG.js)
       File: Grid  (no auto-title, OpenLayers/Layer/Grid.js)
       File: HTTPRequest  (no auto-title, OpenLayers/Layer/HTTPRequest.js)
       File: Image  (no auto-title, OpenLayers/Layer/Image.js)
@@ -474,7 +474,6 @@
    Group: Tile  {
 
       File: Tile  (no auto-title, OpenLayers/Tile.js)
-      File: Google  (no auto-title, OpenLayers/Tile/Google.js)
       File: Image  (no auto-title, OpenLayers/Tile/Image.js)
       File: Image.IFrame  (no auto-title, OpenLayers/Tile/Image/IFrame.js)
       File: WFS  (no auto-title, OpenLayers/Tile/WFS.js)

Modified: sandbox/august/trunk/examples/KMLParser.html
===================================================================
--- sandbox/august/trunk/examples/KMLParser.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/KMLParser.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -28,7 +28,10 @@
           document.getElementById('output').innerHTML = html;
         }
         function load() {
-            OpenLayers.loadURL("kml/lines.kml", "", null, parseData);
+            OpenLayers.Request.GET({
+                url: "kml/lines.kml",
+                success: parseData
+            });
         }
     </script>
   </head>

Modified: sandbox/august/trunk/examples/WMSDescribeLayerParser.html
===================================================================
--- sandbox/august/trunk/examples/WMSDescribeLayerParser.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/WMSDescribeLayerParser.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -9,7 +9,7 @@
     <script src="../lib/OpenLayers.js"></script>
     <script type="text/javascript">
         function parseData(req) {
-          format =  new OpenLayers.Format.WMSDescribeLayer();
+          format = new OpenLayers.Format.WMSDescribeLayer();
           html = "<br>"
           resp = format.read(req.responseText);
           for(var i = 0; i < resp.length; i++) {
@@ -22,7 +22,10 @@
           document.getElementById('output').innerHTML = html;
         }
         function load() {
-            OpenLayers.loadURL("xml/wmsdescribelayer.xml", "", null, parseData);
+            OpenLayers.Request.GET({
+                url: "xml/wmsdescribelayer.xml",
+                success: parseData
+            });
         }
     </script>
   </head>

Modified: sandbox/august/trunk/examples/arcgiscache_jsonp.html
===================================================================
--- sandbox/august/trunk/examples/arcgiscache_jsonp.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/arcgiscache_jsonp.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -7,20 +7,17 @@
     <link rel="stylesheet" href="style.css" type="text/css">
 
     <script src="../lib/OpenLayers.js"></script>
-    <script src="../lib/OpenLayers/Layer/ArcGISCache.js" type="text/javascript"></script>
     
-    <!-- This is to simplify making the JSONP request for this example -->
-    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
-    
     <script type="text/javascript">
         var map,
             layerURL = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer";
         
         function init() {
-            var jsonp_url = layerURL + '?f=json&pretty=true&callback=?';
-            $.getJSON(jsonp_url, function(data) {                
-                initMap(data);
-            });
+            var jsonp = new OpenLayers.Protocol.Script();
+            jsonp.createRequest(layerURL, {
+                f: 'json', 
+                pretty: 'true'
+            }, initMap);
         }
 
         function initMap(layerInfo){
@@ -93,7 +90,7 @@
         <p>
         This method automatically configures the layer using the capabilities object 
         generated by the server itself.  This page shows how to construct the url for the server capabilities object,
-        retrieve it using JSONP (and jQuery), and pass it in during construction.  Note that in this case, 
+        retrieve it using JSONP, and pass it in during construction.  Note that in this case, 
         the layer is constructed before the map.  This approach greatly simplifies the
         configuration of your map, and works best when all your tiles / overlays are similarly laid out.
         If you are using a live AGS map server for your layer, it can be helpful to check your

Modified: sandbox/august/trunk/examples/buffer.html
===================================================================
--- sandbox/august/trunk/examples/buffer.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/buffer.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -48,7 +48,7 @@
 
         <div id="docs">
             Use the buffer property to control how many tiles are included
-            outside the visible map area. Default is 2.
+            outside the visible map area. Default is 0.
         </div>
     </body>
 </html>

Deleted: sandbox/august/trunk/examples/google-ng.html
===================================================================
--- sandbox/august/trunk/examples/google-ng.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/google-ng.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
-        <meta name="apple-mobile-web-app-capable" content="yes">
-        <title>OpenLayers Google NG Layer Example</title>
-        <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
-        <link rel="stylesheet" href="../theme/default/google.css" type="text/css">
-        <link rel="stylesheet" href="style.css" type="text/css">
-        <style type="text/css">
-        .olControlAttribution {
-            left: 2px;
-            right: inherit;
-            bottom: 3px; 
-            line-height: 11px;
-            font-family: Arial, sans-serif;
-        }
-        </style>
-        <script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false"></script>
-        <script src="../lib/OpenLayers.js"></script>
-        <script src="google-ng.js"></script>
-    </head>
-    <body onload="init()">
-        <h1 id="title">Google NG Layer Example</h1>
-        <div id="tags">
-            Google, api key, apikey
-        </div>
-        <p id="shortdesc">
-            Demonstrate use of tiles from the Google Maps v3 API.
-        </p>
-        <div id="map" class="smallmap"></div>
-        <div id="docs">
-            <p>
-                If you use OpenLayers.Layer.GoogleNG, the getTile method of the
-                GMaps v3 API's MapType is used to load tiles.  This allows for
-                better integration than interacting with a whole map generated
-                by a google.maps.Map instance, as done with
-                OpenLayers.Layer.Google.  See the
-                <a href="google-ng.js" target="_blank">google-ng.js source</a> 
-                to see how this is done.
-            </p>
-        </div>
-    </body>
-</html>

Deleted: sandbox/august/trunk/examples/google-ng.js
===================================================================
--- sandbox/august/trunk/examples/google-ng.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/google-ng.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,28 +0,0 @@
-var map;
-
-function init() {
-    map = new OpenLayers.Map('map');
-    map.addControl(new OpenLayers.Control.LayerSwitcher());
-    
-    var gphy = new OpenLayers.Layer.GoogleNG(
-        {type: google.maps.MapTypeId.TERRAIN}
-    );
-    var gmap = new OpenLayers.Layer.GoogleNG(
-        // ROADMAP, the default
-    );
-    var ghyb = new OpenLayers.Layer.GoogleNG(
-        {type: google.maps.MapTypeId.HYBRID}
-    );
-    var gsat = new OpenLayers.Layer.GoogleNG(
-        {type: google.maps.MapTypeId.SATELLITE}
-    );
-
-    map.addLayers([gphy, gmap, ghyb, gsat]);
-
-    // GoogleNG uses EPSG:900913 as projection, so we have to
-    // transform our coordinates
-    map.setCenter(new OpenLayers.LonLat(10.2, 48.9).transform(
-        new OpenLayers.Projection("EPSG:4326"),
-        map.getProjectionObject()
-    ), 5);
-}

Modified: sandbox/august/trunk/examples/measure.html
===================================================================
--- sandbox/august/trunk/examples/measure.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/measure.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -70,12 +70,19 @@
             ]);
             var styleMap = new OpenLayers.StyleMap({"default": style});
             
+            // allow testing of specific renderers via "?renderer=Canvas", etc
+            var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
+            renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
+
             measureControls = {
                 line: new OpenLayers.Control.Measure(
                     OpenLayers.Handler.Path, {
                         persist: true,
                         handlerOptions: {
-                            layerOptions: {styleMap: styleMap}
+                            layerOptions: {
+                                renderers: renderer,
+                                styleMap: styleMap
+                            }
                         }
                     }
                 ),
@@ -83,7 +90,10 @@
                     OpenLayers.Handler.Polygon, {
                         persist: true,
                         handlerOptions: {
-                            layerOptions: {styleMap: styleMap}
+                            layerOptions: {
+                                renderers: renderer,
+                                styleMap: styleMap
+                            }
                         }
                     }
                 )

Modified: sandbox/august/trunk/examples/mobile-drawing.js
===================================================================
--- sandbox/august/trunk/examples/mobile-drawing.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/mobile-drawing.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -48,7 +48,11 @@
             -20037508.34, -20037508.34, 20037508.34, 20037508.34
         ),
         controls: [
-            new OpenLayers.Control.TouchNavigation(),
+            new OpenLayers.Control.TouchNavigation({
+                dragPanOptions: {
+                    enableKinetic: true
+                }
+            }),
             new OpenLayers.Control.ZoomPanel(),
             toolbar
         ],

Modified: sandbox/august/trunk/examples/multitouch.html
===================================================================
--- sandbox/august/trunk/examples/multitouch.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/multitouch.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -5,7 +5,7 @@
    <title>Multitouch Test</title>
   </head>
   <body>
-   <div style="width:80%; height: 80%; border: 1px solid black; font-size: 5em;" id="box">
+   <div style="width:80%; height: 200px; border: 1px solid black; font-size: 5em;" id="box">
    </div>
    Touch inside the box. On a touch enabled browser, you will get the number
    of detected touch events. If the box is red, your browser does not support

Modified: sandbox/august/trunk/examples/select-feature-multilayer.html
===================================================================
--- sandbox/august/trunk/examples/select-feature-multilayer.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/select-feature-multilayer.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -24,7 +24,12 @@
                 {layers: 'basic'}
             ); 
 
+            // allow testing of specific renderers via "?renderer=Canvas", etc
+            var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
+            renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;
+
             var vectors1 = new OpenLayers.Layer.Vector("Vector Layer 1", {
+                renderers: renderer,
                 styleMap: new OpenLayers.StyleMap({
                     "default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
                         externalGraphic: "../img/marker-green.png",
@@ -38,6 +43,7 @@
                 })
             });
             var vectors2 = new OpenLayers.Layer.Vector("Vector Layer 2", {
+                renderers: renderer,
                 styleMap: new OpenLayers.StyleMap({
                     "default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
                         fillColor: "red",

Modified: sandbox/august/trunk/examples/sld.js
===================================================================
--- sandbox/august/trunk/examples/sld.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/sld.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -12,10 +12,13 @@
     ));
     map.addControl(new OpenLayers.Control.LayerSwitcher());
 
-    OpenLayers.loadURL("tasmania/sld-tasmania.xml", null, null, complete);
+    OpenLayers.Request.GET({
+        url: "tasmania/sld-tasmania.xml",
+        success: complete
+    });
 }
 
-// handler for the loadURL function in the init method
+// handler for the OpenLayers.Request.GET function in the init method
 function complete(req) {
     sld = format.read(req.responseXML || req.responseText);
     buildStyleChooser();

Modified: sandbox/august/trunk/examples/sundials-spherical-mercator.html
===================================================================
--- sandbox/august/trunk/examples/sundials-spherical-mercator.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/sundials-spherical-mercator.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -10,6 +10,9 @@
     <link rel="stylesheet" href="style.css" type="text/css">
 
     <style type="text/css">
+        html, body {
+            height: 100%;
+        }
         #map {
             width: 100%;
             height: 80%;

Modified: sandbox/august/trunk/examples/sundials.html
===================================================================
--- sandbox/august/trunk/examples/sundials.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/sundials.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -8,6 +8,9 @@
     <link rel="stylesheet" href="style.css" type="text/css">
 
     <style type="text/css">
+        html, body {
+            height: 100%;
+        }
         #map {
             width: 100%;
             height: 80%;

Modified: sandbox/august/trunk/examples/vector-formats.html
===================================================================
--- sandbox/august/trunk/examples/vector-formats.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/vector-formats.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -86,7 +86,8 @@
                 gml2: new OpenLayers.Format.GML.v2(gmlOptionsIn),
                 gml3: new OpenLayers.Format.GML.v3(gmlOptionsIn),
                 kml: new OpenLayers.Format.KML(kmlOptionsIn),
-                atom: new OpenLayers.Format.Atom(in_options)
+                atom: new OpenLayers.Format.Atom(in_options),
+                gpx: new OpenLayers.Format.GPX(in_options)
               }, 
               'out': {
                 wkt: new OpenLayers.Format.WKT(out_options),
@@ -95,7 +96,8 @@
                 gml2: new OpenLayers.Format.GML.v2(gmlOptionsOut),
                 gml3: new OpenLayers.Format.GML.v3(gmlOptionsOut),
                 kml: new OpenLayers.Format.KML(out_options),
-                atom: new OpenLayers.Format.Atom(out_options)
+                atom: new OpenLayers.Format.Atom(out_options),
+                gpx: new OpenLayers.Format.GPX(out_options)
               } 
             };
         }
@@ -199,6 +201,7 @@
                 <option value="gml2">GML (v2)</option>
                 <option value="gml3">GML (v3)</option>
                 <option value="wkt">Well-Known Text (WKT)</option>
+                <option value="gpx">GPX</option>
             </select>
             &nbsp;
             <label for="prettyPrint">Pretty print</label>

Modified: sandbox/august/trunk/examples/wms-long-url.js
===================================================================
--- sandbox/august/trunk/examples/wms-long-url.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/wms-long-url.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -5,12 +5,12 @@
 var base = new OpenLayers.Layer.WMS( "OpenLayers WMS",
     "http://vmap0.tiles.osgeo.org/wms/vmap0",
     {layers: 'basic', makeTheUrlLong: longText},
-    {tileOptions: {maxGetUrlLength: 2048}}
+    {tileOptions: {maxGetUrlLength: 2048}, transitionEffect: 'resize'}
 );
 var overlay = new OpenLayers.Layer.WMS("Overlay",
     "http://suite.opengeo.org/geoserver/wms",
     {layers: "usa:states", transparent: true, makeTheUrlLong: longText},
-    {ratio: 1, singleTile: true, tileOptions: {maxGetUrlLength: 2048}}
+    {ratio: 1, singleTile: true, tileOptions: {maxGetUrlLength: 2048}, transitionEffect: 'resize'}
 );
 map.addLayers([base, overlay]);
 map.zoomToMaxExtent();

Modified: sandbox/august/trunk/examples/wrapDateLine.html
===================================================================
--- sandbox/august/trunk/examples/wrapDateLine.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/wrapDateLine.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -27,7 +27,7 @@
                 {layers: "bathymetry,land_fn,park,drain_fn,drainage," +
                          "prov_bound,fedlimit,rail,road,popplace",
                  transparent: "true", format: "image/png"},
-                {wrapDateLine: true, reproject: false});
+                {wrapDateLine: true});
 
             /* WW doesn't quite work yet */
             ww = new OpenLayers.Layer.WorldWind( "LANDSAT",

Modified: sandbox/august/trunk/examples/xml.html
===================================================================
--- sandbox/august/trunk/examples/xml.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/xml.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -39,8 +39,11 @@
         var doc = null;
 
         function init() {
-            var url = "xml/features.xml";
-            OpenLayers.loadURL(url, null, null, loadSuccess, loadFailure);
+            OpenLayers.Request.GET({
+                url: "xml/features.xml",
+                success: loadSuccess,
+                failure: loadFailure
+            });
         }
 
         function loadSuccess(request) {

Modified: sandbox/august/trunk/examples/xyz-esri.html
===================================================================
--- sandbox/august/trunk/examples/xyz-esri.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/xyz-esri.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -7,11 +7,15 @@
     <title>OpenLayers Basic ESRI Map Cache Example</title>
     <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
     <link rel="stylesheet" href="style.css" type="text/css">
+    <style>
+      .olImageLoadError {
+          display: none;
+      }
+    </style>
     <script src="../lib/OpenLayers.js"></script>
     <script type="text/javascript">
         var map, layer;
         function init(){
-            OpenLayers.Util.onImageLoadError = function() { this.style.display="none";}
             var layerExtent = new OpenLayers.Bounds( -13758743.4295939,  5591455.28887228, -13531302.3472101 , 5757360.4178881)
             map = new OpenLayers.Map( 'map', {'restrictedExtent': layerExtent} );
             layer = new OpenLayers.Layer.XYZ( "ESRI",

Modified: sandbox/august/trunk/examples/xyz-offset.js
===================================================================
--- sandbox/august/trunk/examples/xyz-offset.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/examples/xyz-offset.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,10 +1,5 @@
 var map, layer;
 
-// if tiles are not available, hide images
-//OpenLayers.Util.onImageLoadError = function() {
-//    this.style.display = "none";
-//}
-
 // called on body load
 function init() {
 

Modified: sandbox/august/trunk/img/cloud-popup-relative.png
===================================================================
(Binary files differ)

Modified: sandbox/august/trunk/lib/OpenLayers/Ajax.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Ajax.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Ajax.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -46,8 +46,8 @@
 
 /** 
  * APIFunction: OpenLayers.loadURL
- * Background load a document.  For more flexibility in using XMLHttpRequest,
- *     see the <OpenLayers.Request> methods.
+ * Background load a document.
+ * *Deprecated*.  Use <OpenLayers.Request.GET> method instead.
  *
  * Parameters:
  * uri - {String} URI of source doc

Modified: sandbox/august/trunk/lib/OpenLayers/BaseTypes/Bounds.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes/Bounds.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes/Bounds.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -155,7 +155,7 @@
      * 
      * Returns:
      * {String} Simple String representation of bounds object.
-     *          (ex. <i>"5,42,10,45"</i>)
+     *          (e.g. <i>"5,42,10,45"</i>)
      */
     toBBOX:function(decimal, reverseAxisOrder) {
         if (decimal== null) {
@@ -615,7 +615,7 @@
  *     parameter string
  * 
  * Parameters: 
- * str - {String}Comma-separated bounds string. (ex. <i>"5,42,10,45"</i>)
+ * str - {String}Comma-separated bounds string. (e.g. <i>"5,42,10,45"</i>)
  * reverseAxisOrder - {Boolean} Does the string use reverse axis order?
  * 
  * Returns:
@@ -633,7 +633,7 @@
  *     from an array
  * 
  * Parameters:
- * bbox - {Array(Float)} Array of bounds values (ex. <i>[5,42,10,45]</i>)
+ * bbox - {Array(Float)} Array of bounds values (e.g. <i>[5,42,10,45]</i>)
  * reverseAxisOrder - {Boolean} Does the array use reverse axis order?
  *
  * Returns:

Modified: sandbox/august/trunk/lib/OpenLayers/BaseTypes/Class.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes/Class.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes/Class.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -37,7 +37,7 @@
 
     var C = typeof F.initialize == "function" ?
         F.initialize :
-        function(){ P.apply(this, arguments); };
+        function(){ P.prototype.initialize.apply(this, arguments); };
 
     if (len > 1) {
         var newArgs = [C, P].concat(

Copied: sandbox/august/trunk/lib/OpenLayers/BaseTypes/Date.js (from rev 12408, trunk/openlayers/lib/OpenLayers/BaseTypes/Date.js)
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes/Date.js	                        (rev 0)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes/Date.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,118 @@
+/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * Namespace: OpenLayers.Date
+ * Contains implementations of Date.parse and date.toISOString that match the
+ *     ECMAScript 5 specification for parsing RFC 3339 dates.
+ *     http://tools.ietf.org/html/rfc3339
+ */
+OpenLayers.Date = {
+
+    /**
+     * APIMethod: toISOString
+     * Generates a string representing a date.  The format of the string follows
+     *     the profile of ISO 8601 for date and time on the Internet (see
+     *     http://tools.ietf.org/html/rfc3339).  If the toISOString method is
+     *     available on the Date prototype, that is used.  The toISOString
+     *     method for Date instances is defined in ECMA-262.
+     *
+     * Parameters:
+     * date - {Date} A date object.
+     *
+     * Returns:
+     * {String} A string representing the date (e.g.
+     *     "2010-08-07T16:58:23.123Z").  If the date does not have a valid time
+     *     (i.e. isNaN(date.getTime())) this method returns the string "Invalid
+     *     Date".  The ECMA standard says the toISOString method should throw
+     *     RangeError in this case, but Firefox returns a string instead.  For
+     *     best results, use isNaN(date.getTime()) to determine date validity
+     *     before generating date strings.
+     */
+    toISOString: (function() {
+        if ("toISOString" in Date.prototype) {
+            return function(date) {
+                return date.toISOString();
+            };
+        } else {
+            function pad(num, len) {
+                var str = num + "";
+                while (str.length < len) {
+                    str = "0" + str;
+                }
+                return str;
+            }
+            return function(date) {
+                var str;
+                if (isNaN(date.getTime())) {
+                    // ECMA-262 says throw RangeError, Firefox returns
+                    // "Invalid Date"
+                    str = "Invalid Date";
+                } else {
+                    str =
+                        date.getUTCFullYear() + "-" +
+                        pad(date.getUTCMonth() + 1, 2) + "-" +
+                        pad(date.getUTCDate(), 2) + "T" +
+                        pad(date.getUTCHours(), 2) + ":" +
+                        pad(date.getUTCMinutes(), 2) + ":" +
+                        pad(date.getUTCSeconds(), 2) + "." +
+                        pad(date.getUTCMilliseconds(), 3) + "Z";
+                }
+                return str;
+            };
+        }
+
+    })(),
+
+    /**
+     * APIMethod: parse
+     * Generate a date object from a string.  The format for the string follows
+     *     the profile of ISO 8601 for date and time on the Internet (see
+     *     http://tools.ietf.org/html/rfc3339).  We don't call the native
+     *     Date.parse because of inconsistency between implmentations.  In
+     *     Chrome, calling Date.parse with a string that doesn't contain any
+     *     indication of the timezone (e.g. "2011"), the date is interpreted
+     *     in local time.  On Firefox, the assumption is UTC.
+     *
+     * Parameters:
+     * str - {String} A string representing the date (e.g.
+     *     "2010", "2010-08", "2010-08-07", "2010-08-07T16:58:23.123Z",
+     *     "2010-08-07T11:58:23.123-06").
+     *
+     * Returns:
+     * {Date} A date object.  If the string could not be parsed, an invalid
+     *     date is returned (i.e. isNaN(date.getTime())).
+     */
+    parse: function(str) {
+        var date;
+        var match = str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);
+        if (match && (match[1] || match[7])) { // must have at least year or time
+            var year = parseInt(match[1], 10) || 0;
+            var month = (parseInt(match[2], 10) - 1) || 0;
+            var day = parseInt(match[3], 10) || 1;
+            date = new Date(Date.UTC(year, month, day));
+            // optional time
+            var type = match[7];
+            if (type) {
+                var hours = parseInt(match[4], 10);
+                var minutes = parseInt(match[5], 10);
+                var secFrac = parseFloat(match[6]);
+                var seconds = secFrac | 0;
+                var milliseconds = Math.round(1000 * (secFrac - seconds));
+                date.setUTCHours(hours, minutes, seconds, milliseconds);
+                // check offset
+                if (type !== "Z") {
+                    var hoursOffset = parseInt(type, 10);
+                    var minutesOffset = parseInt(match[8], 10) || 0;
+                    var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);
+                    date = new Date(date.getTime() + offset);
+                }
+            }
+        } else {
+            date = new Date("invalid");
+        }
+        return date;
+    }
+};

Modified: sandbox/august/trunk/lib/OpenLayers/BaseTypes/LonLat.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes/LonLat.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes/LonLat.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -50,7 +50,7 @@
      *
      * Returns:
      * {String} String representation of OpenLayers.LonLat object. 
-     *           (ex. <i>"lon=5,lat=42"</i>)
+     *           (e.g. <i>"lon=5,lat=42"</i>)
      */
     toString:function() {
         return ("lon=" + this.lon + ",lat=" + this.lat);
@@ -61,7 +61,7 @@
      * 
      * Returns:
      * {String} Shortened String representation of OpenLayers.LonLat object. 
-     *         (ex. <i>"5, 42"</i>)
+     *         (e.g. <i>"5, 42"</i>)
      */
     toShortString:function() {
         return (this.lon + ", " + this.lat);
@@ -180,7 +180,7 @@
  * 
  * Parameters:
  * str - {String} Comma-separated Lon,Lat coordinate string. 
- *                 (ex. <i>"5,40"</i>)
+ *                 (e.g. <i>"5,40"</i>)
  * 
  * Returns:
  * {<OpenLayers.LonLat>} New <OpenLayers.LonLat> object built from the 
@@ -190,3 +190,22 @@
     var pair = str.split(",");
     return new OpenLayers.LonLat(pair[0], pair[1]);
 };
+
+/** 
+ * Function: fromArray
+ * Alternative constructor that builds a new <OpenLayers.LonLat> from an 
+ *     array of two numbers that represent lon- and lat-values.
+ * 
+ * Parameters:
+ * arr - {Array(Float)} Array of lon/lat values (e.g. [5,-42])
+ * 
+ * Returns:
+ * {<OpenLayers.LonLat>} New <OpenLayers.LonLat> object built from the 
+ *                       passed-in array.
+ */
+OpenLayers.LonLat.fromArray = function(arr) {
+    var gotArr = OpenLayers.Util.isArray(arr),
+        lon = gotArr && arr[0],
+        lat = gotArr && arr[1];
+    return new OpenLayers.LonLat(lon, lat);
+};

Modified: sandbox/august/trunk/lib/OpenLayers/BaseTypes/Size.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes/Size.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes/Size.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -45,7 +45,7 @@
      *
      * Returns:
      * {String} The string representation of OpenLayers.Size object. 
-     * (ex. <i>"w=55,h=66"</i>)
+     * (e.g. <i>"w=55,h=66"</i>)
      */
     toString:function() {
         return ("w=" + this.w + ",h=" + this.h);

Modified: sandbox/august/trunk/lib/OpenLayers/BaseTypes.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/BaseTypes.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/BaseTypes.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -564,118 +564,3 @@
     }
     
 };
-
-/**
- * Namespace: OpenLayers.Date
- * Contains implementations of Date.parse and date.toISOString that match the 
- *     ECMAScript 5 specification for parsing RFC 3339 dates.
- *     http://tools.ietf.org/html/rfc3339
- */
-OpenLayers.Date = {
-    
-    /**
-     * APIMethod: toISOString
-     * Generates a string representing a date.  The format of the string follows 
-     *     the profile of ISO 8601 for date and time on the Internet (see 
-     *     http://tools.ietf.org/html/rfc3339).  If the toISOString method is 
-     *     available on the Date prototype, that is used.  The toISOString
-     *     method for Date instances is defined in ECMA-262.
-     *
-     * Parameters:
-     * date - {Date} A date object.
-     *
-     * Returns:
-     * {String} A string representing the date (e.g. 
-     *     "2010-08-07T16:58:23.123Z").  If the date does not have a valid time
-     *     (i.e. isNaN(date.getTime())) this method returns the string "Invalid
-     *     Date".  The ECMA standard says the toISOString method should throw
-     *     RangeError in this case, but Firefox returns a string instead.  For
-     *     best results, use isNaN(date.getTime()) to determine date validity
-     *     before generating date strings.  
-     */
-    toISOString: (function() {
-        if ("toISOString" in Date.prototype) {
-            return function(date) {
-                return date.toISOString();
-            };
-        } else {
-            function pad(num, len) {
-                var str = num + "";
-                while (str.length < len) {
-                    str = "0" + str;
-                }
-                return str;
-            }
-            return function(date) {
-                var str;
-                if (isNaN(date.getTime())) {
-                    // ECMA-262 says throw RangeError, Firefox returns 
-                    // "Invalid Date"
-                    str = "Invalid Date";
-                } else {
-                    str = 
-                        date.getUTCFullYear() + "-" +
-                        pad(date.getUTCMonth() + 1, 2) + "-" +
-                        pad(date.getUTCDate(), 2) + "T" +
-                        pad(date.getUTCHours(), 2) + ":" +
-                        pad(date.getUTCMinutes(), 2) + ":" +
-                        pad(date.getUTCSeconds(), 2) + "." +
-                        pad(date.getUTCMilliseconds(), 3) + "Z";
-                }
-                return str;
-            };
-        }
-
-    })(),
-    
-    /**
-     * APIMethod: parse
-     * Generate a date object from a string.  The format for the string follows
-     *     the profile of ISO 8601 for date and time on the Internet (see 
-     *     http://tools.ietf.org/html/rfc3339).  We don't call the native
-     *     Date.parse because of inconsistency between implmentations.  In 
-     *     Chrome, calling Date.parse with a string that doesn't contain any
-     *     indication of the timezone (e.g. "2011"), the date is interpreted
-     *     in local time.  On Firefox, the assumption is UTC.
-     *
-     * Parameters:
-     * str - {String} A string representing the date (e.g. 
-     *     "2010", "2010-08", "2010-08-07", "2010-08-07T16:58:23.123Z",
-     *     "2010-08-07T11:58:23.123-06").
-     * 
-     * Returns:
-     * {Date} A date object.  If the string could not be parsed, an invalid
-     *     date is returned (i.e. isNaN(date.getTime())).
-     */
-    parse: function(str) {
-        var date;
-        var match = str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);
-        if (match && (match[1] || match[7])) { // must have at least year or time
-            var year = parseInt(match[1], 10) || 0;
-            var month = (parseInt(match[2], 10) - 1) || 0;
-            var day = parseInt(match[3], 10) || 1;
-            date = new Date(Date.UTC(year, month, day));
-            // optional time
-            var type = match[7];
-            if (type) {
-                var hours = parseInt(match[4], 10);
-                var minutes = parseInt(match[5], 10);
-                var secFrac = parseFloat(match[6]);
-                var seconds = secFrac | 0;
-                var milliseconds = Math.round(1000 * (secFrac - seconds));
-                date.setUTCHours(hours, minutes, seconds, milliseconds);
-                // check offset
-                if (type !== "Z") {
-                    var hoursOffset = parseInt(type, 10);
-                    var minutesOffset = parseInt(match[8], 10) || 0;
-                    var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);
-                    date = new Date(date.getTime() + offset);
-                }
-            }
-        } else {
-            date = new Date("invalid");
-        }
-        return date;
-    }
-
-};

Modified: sandbox/august/trunk/lib/OpenLayers/Control/DragFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/DragFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/DragFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -171,7 +171,7 @@
      * feature - {<OpenLayers.Feature.Vector>}
      */
     clickFeature: function(feature) {
-        if (!this.over && this.overFeature(feature)) {
+        if (this.handlers.feature.touch && !this.over && this.overFeature(feature)) {
             this.handlers.drag.dragstart(this.handlers.feature.evt);
             // to let the events propagate to the feature handler (click callback)
             this.handlers.drag.stopDown = false;
@@ -186,7 +186,7 @@
      * feature - {<OpenLayers.Feature.Vector>}
      */
     clickoutFeature: function(feature) {
-        if (this.over) {
+        if (this.handlers.feature.touch && this.over) {
             this.outFeature(feature);
             this.handlers.drag.stopDown = true;
         }

Modified: sandbox/august/trunk/lib/OpenLayers/Control/DrawFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/DrawFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/DrawFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -32,12 +32,9 @@
     callbacks: null,
     
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types:
      * featureadded - Triggered when a feature is added
      */
-    EVENT_TYPES: ["featureadded"],
     
     /**
      * APIProperty: multi
@@ -67,13 +64,6 @@
      * options - {Object} 
      */
     initialize: function(layer, handler, options) {
-        
-        // concatenate events specific to vector with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.DrawFeature.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
-        
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
         this.callbacks = OpenLayers.Util.extend(
             {

Modified: sandbox/august/trunk/lib/OpenLayers/Control/EditingToolbar.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/EditingToolbar.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/EditingToolbar.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -25,6 +25,13 @@
   OpenLayers.Control.Panel, {
 
     /**
+     * APIProperty: citeCompliant
+     * {Boolean} If set to true, coordinates of features drawn in a map extent
+     * crossing the date line won't exceed the world bounds. Default is false.
+     */
+    citeCompliant: false,
+
+    /**
      * Constructor: OpenLayers.Control.EditingToolbar
      * Create an editing toolbar for a given layer. 
      *
@@ -39,9 +46,18 @@
           [ new OpenLayers.Control.Navigation() ]
         );  
         var controls = [
-          new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}),
-          new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}),
-          new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'})
+            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {
+                displayClass: 'olControlDrawFeaturePoint',
+                handlerOptions: {citeCompliant: this.citeCompliant}
+            }),
+            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {
+                displayClass: 'olControlDrawFeaturePath',
+                handlerOptions: {citeCompliant: this.citeCompliant}
+            }),
+            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {
+                displayClass: 'olControlDrawFeaturePolygon',
+                handlerOptions: {citeCompliant: this.citeCompliant}
+            })
         ];
         this.addControls(controls);
     },

Modified: sandbox/august/trunk/lib/OpenLayers/Control/Geolocate.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/Geolocate.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/Geolocate.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,14 +23,12 @@
 OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
      * Supported event types:
      *  - *locationupdated* Triggered when browser return a new position
      *  - *locationfailed* Triggered when geolocation has failed
      *  - *locationuncapable* Triggered when control is activated on a browser
      *  which doesn't support geolocation
      */
-    EVENT_TYPES: ["locationupdated", "locationfailed", "locationuncapable"],
 
     /**
      * Property: geolocation
@@ -63,15 +61,6 @@
      * Create a new control to deal with browser geolocation API
      *
      */
-    initialize: function(options) {
-        // concatenate events specific to this control with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.Geolocate.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
-        this.geolocationOptions = {};
-        OpenLayers.Control.prototype.initialize.apply(this, [options]);
-    },
 
     /**
      * Method: destroy

Modified: sandbox/august/trunk/lib/OpenLayers/Control/GetFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/GetFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/GetFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -170,8 +170,6 @@
     filterType: OpenLayers.Filter.Spatial.BBOX,
 
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types:
      * beforefeatureselected - Triggered when <click> is true before a
      *      feature is selected. The event object has a feature property with
@@ -197,9 +195,6 @@
      * outfeature - Triggered when <hover> is true and the mouse moves
      *      moved away from a hover-selected feature
      */
-    EVENT_TYPES: ["featureselected", "featuresselected", "featureunselected", 
-        "clickout", "beforefeatureselected", "beforefeaturesselected", 
-        "hoverfeature", "outfeature"],
 
     /**
      * Constructor: OpenLayers.Control.GetFeature
@@ -211,12 +206,6 @@
      *     made)
      */
     initialize: function(options) {
-        // concatenate events specific to vector with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.GetFeature.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
-
         options.handlerOptions = options.handlerOptions || {};
 
         OpenLayers.Control.prototype.initialize.apply(this, [options]);

Modified: sandbox/august/trunk/lib/OpenLayers/Control/Measure.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/Measure.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/Measure.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,7 @@
 OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * control.events.register(type, obj, listener);
      * (end)
@@ -37,7 +35,6 @@
      *      measurement sketch is modified.  Listeners receive an event with measure,
      *      units, order, and geometry.
      */
-    EVENT_TYPES: ['measure', 'measurepartial'],
 
     /**
      * APIProperty: handlerOptions
@@ -120,11 +117,6 @@
      * options - {Object} 
      */
     initialize: function(handler, options) {
-        // concatenate events specific to measure with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
         var callbacks = {done: this.measureComplete,
             point: this.measurePartial};

Modified: sandbox/august/trunk/lib/OpenLayers/Control/ModifyFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/ModifyFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/ModifyFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -633,6 +633,7 @@
                 this.layer.drawFeature(this.feature, this.standalone ?
                                        undefined :
                                        this.selectControl.renderIntent);
+                this.modified = true;
                 this.resetVertices();
                 this.setFeatureState();
                 this.onModification(this.feature);

Modified: sandbox/august/trunk/lib/OpenLayers/Control/SLDSelect.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/SLDSelect.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/SLDSelect.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -24,9 +24,7 @@
 OpenLayers.Control.SLDSelect = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * control.events.register(type, obj, listener);
      * (end)
@@ -41,7 +39,6 @@
      *     array of OpenLayers.Filter objects created in order to perform 
      *     the particular selection.
      */
-    EVENT_TYPES: ["selected"],
 
     /**
      * APIProperty: clearOnDeactivate
@@ -148,11 +145,6 @@
      *     selection on.
      */
     initialize: function(handler, options) {
-        // concatenate events specific to this control with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.SLDSelect.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
 
         this.callbacks = OpenLayers.Util.extend({done: this.select, 

Modified: sandbox/august/trunk/lib/OpenLayers/Control/SelectFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/SelectFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/SelectFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,14 +22,11 @@
 OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types:
      *  - *beforefeaturehighlighted* Triggered before a feature is highlighted
      *  - *featurehighlighted* Triggered when a feature is highlighted
      *  - *featureunhighlighted* Triggered when a feature is unhighlighted
      */
-    EVENT_TYPES: ["beforefeaturehighlighted", "featurehighlighted", "featureunhighlighted"],
     
     /**
      * Property: multipleKey
@@ -74,9 +71,9 @@
 
     /**
      * APIProperty: highlightOnly
-     * {Boolean} If true do not actually select features (i.e. place them in the
-     * layer's selected features array), just highlight them. This property has
-     * no effect if hover is false. Defaults to false.
+     * {Boolean} If true do not actually select features (that is place them in 
+     * the layer's selected features array), just highlight them. This property
+     * has no effect if hover is false. Defaults to false.
      */
     highlightOnly: false,
     
@@ -173,11 +170,6 @@
      * options - {Object} 
      */
     initialize: function(layers, options) {
-        // concatenate events specific to this control with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.SelectFeature.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
         
         if(this.scope === null) {

Modified: sandbox/august/trunk/lib/OpenLayers/Control/Snapping.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/Snapping.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/Snapping.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,7 @@
 OpenLayers.Control.Snapping = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * control.events.register(type, obj, listener);
      * (end)
@@ -45,7 +43,6 @@
      * unsnap - Triggered when a vertex is unsnapped.  Listeners receive an
      *     event with a *point* property.
      */
-    EVENT_TYPES: ["beforesnap", "snap", "unsnap"],
     
     /**
      * CONSTANT: DEFAULTS
@@ -175,10 +172,6 @@
      *     no maximum resolution limit.
      */
     initialize: function(options) {
-        // concatenate events specific to measure with those from the base
-        Array.prototype.push.apply(
-            this.EVENT_TYPES, OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
         this.options = options || {}; // TODO: this could be done by the super
         
@@ -476,7 +469,7 @@
             feature = features[i];
             if(feature !== this.feature && !feature._sketch &&
                feature.state !== OpenLayers.State.DELETE &&
-               (!target.filter || target.filter.evaluate(feature.attributes))) {
+               (!target.filter || target.filter.evaluate(feature))) {
                 if(feature.atPoint(ll, maxTolerance, maxTolerance)) {
                     for(var j=0, stop=Math.min(result.rank+1, numTypes); j<stop; ++j) {
                         type = this.precedence[j];

Modified: sandbox/august/trunk/lib/OpenLayers/Control/Split.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/Split.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/Split.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -19,9 +19,7 @@
 OpenLayers.Control.Split = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * control.events.register(type, obj, listener);
      * (end)
@@ -47,7 +45,6 @@
      *     sketch or modified feature used as a splitter.  The features
      *     property is a list of all resulting features.
      */
-    EVENT_TYPES: ["beforesplit", "split", "aftersplit"],
     
     /**
      * APIProperty: layer
@@ -169,10 +166,6 @@
      *     splitting.
      */
     initialize: function(options) {
-        // concatenate events specific to measure with those from the base
-        Array.prototype.push.apply(
-            this.EVENT_TYPES, OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
         this.options = options || {}; // TODO: this could be done by the super
         

Modified: sandbox/august/trunk/lib/OpenLayers/Control/TransformFeature.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/TransformFeature.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/TransformFeature.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
 
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types:
      *  - *beforesetfeature* Triggered before a feature is set for
      *      tranformation. The feature will not be set if a listener returns
@@ -51,8 +49,6 @@
      *  - *transformcomplete* Triggered after dragging. Listeners receive
      *      an event object with the transformed *feature*.
      */
-    EVENT_TYPES: ["beforesetfeature", "setfeature", "beforetransform",
-        "transform", "transformcomplete"],
 
     /**
      * APIProperty: geometryTypes
@@ -181,11 +177,6 @@
      *     control.
      */
     initialize: function(layer, options) {
-        // concatenate events specific to this control with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.TransformFeature.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
         OpenLayers.Control.prototype.initialize.apply(this, [options]);
 
         this.layer = layer;

Modified: sandbox/august/trunk/lib/OpenLayers/Control/WMSGetFeatureInfo.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/WMSGetFeatureInfo.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/WMSGetFeatureInfo.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -155,8 +155,6 @@
     hoverRequest: null,
     
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types (in addition to those from <OpenLayers.Control>):
      * beforegetfeatureinfo - Triggered before the request is sent.
      *      The event object has an *xy* property with the position of the 
@@ -172,7 +170,6 @@
      *      layers, *text* and *request* will only contain the response body
      *      and request object of the last request.
      */
-    EVENT_TYPES: ["beforegetfeatureinfo", "nogetfeatureinfo", "getfeatureinfo"],
 
     /**
      * Constructor: <OpenLayers.Control.WMSGetFeatureInfo>
@@ -181,12 +178,6 @@
      * options - {Object} 
      */
     initialize: function(options) {
-        // concatenate events specific to vector with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
-
         options = options || {};
         options.handlerOptions = options.handlerOptions || {};
 

Modified: sandbox/august/trunk/lib/OpenLayers/Control/WMTSGetFeatureInfo.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control/WMTSGetFeatureInfo.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control/WMTSGetFeatureInfo.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -136,8 +136,6 @@
     hoverRequest: null,
     
     /**
-     * Constant: EVENT_TYPES
-     *
      * Supported event types (in addition to those from <OpenLayers.Control>):
      * beforegetfeatureinfo - Triggered before each request is sent.
      *      The event object has an *xy* property with the position of the 
@@ -157,7 +155,6 @@
      *      an event with *request*, *xy*, and *layer*  properties.  In the case 
      *      of a parsing error, the event will also contain an *error* property.
      */
-    EVENT_TYPES: ["beforegetfeatureinfo", "getfeatureinfo", "exception"],
     
     /** 
      * Property: pending
@@ -172,12 +169,6 @@
      * options - {Object} 
      */
     initialize: function(options) {
-        // concatenate events specific to vector with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Control.WMTSGetFeatureInfo.prototype.EVENT_TYPES.concat(
-            OpenLayers.Control.prototype.EVENT_TYPES
-        );
-
         options = options || {};
         options.handlerOptions = options.handlerOptions || {};
 

Modified: sandbox/august/trunk/lib/OpenLayers/Control.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Control.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Control.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -145,9 +145,7 @@
     events: null,
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * control.events.register(type, obj, listener);
      * (end)
@@ -165,7 +163,6 @@
      * activate - Triggered when activated.
      * deactivate - Triggered when deactivated.
      */
-    EVENT_TYPES: ["activate", "deactivate"],
 
     /**
      * Constructor: OpenLayers.Control
@@ -187,7 +184,7 @@
         
         OpenLayers.Util.extend(this, options);
         
-        this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
+        this.events = new OpenLayers.Events(this);
         if(this.eventListeners instanceof Object) {
             this.events.on(this.eventListeners);
         }

Modified: sandbox/august/trunk/lib/OpenLayers/Events.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Events.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Events.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -420,12 +420,6 @@
     element: null,
 
     /** 
-     * Property: eventTypes 
-     * {Array(String)}  list of support application events 
-     */
-    eventTypes: null,
-
-    /** 
      * Property: eventHandler 
      * {Function}  bound event handler attached to elements 
      */
@@ -480,7 +474,9 @@
      * Parameters:
      * object - {Object} The js object to which this Events object  is being added
      * element - {DOMElement} A dom element to respond to browser events
-     * eventTypes - {Array(String)} Array of custom application events 
+     * eventTypes - {Array(String)} Deprecated.  Array of custom application
+     *     events.  A listener may be registered for any named event, regardless
+     *     of the values provided here.
      * fallThrough - {Boolean} Allow events to fall through after these have
      *                         been handled?
      * options - {Object} Options for the events object.
@@ -490,30 +486,20 @@
         this.object     = object;
         this.fallThrough = fallThrough;
         this.listeners  = {};
-
-        // keep a bound copy of handleBrowserEvent() so that we can
-        // pass the same function to both Event.observe() and .stopObserving()
-        this.eventHandler = OpenLayers.Function.bindAsEventListener(
-            this.handleBrowserEvent, this
-        );
         
-        // to be used with observe and stopObserving
-        this.clearMouseListener = OpenLayers.Function.bind(
-            this.clearMouseCache, this
-        );
-
-        // if eventTypes is specified, create a listeners list for each 
-        // custom application event.
-        this.eventTypes = [];
-        if (eventTypes != null) {
-            for (var i=0, len=eventTypes.length; i<len; i++) {
-                this.addEventType(eventTypes[i]);
-            }
-        }
-        
         // if a dom element is specified, add a listeners list 
         // for browser events on the element and register them
         if (element != null) {
+            // keep a bound copy of handleBrowserEvent() so that we can
+            // pass the same function to both Event.observe() and .stopObserving()
+            this.eventHandler = OpenLayers.Function.bindAsEventListener(
+                this.handleBrowserEvent, this
+            );
+            
+            // to be used with observe and stopObserving
+            this.clearMouseListener = OpenLayers.Function.bind(
+                this.clearMouseCache, this
+            );
             this.attachToElement(element);
         }
     },
@@ -534,24 +520,18 @@
 
         this.listeners = null;
         this.object = null;
-        this.eventTypes = null;
         this.fallThrough = null;
         this.eventHandler = null;
     },
 
     /**
      * APIMethod: addEventType
-     * Add a new event type to this events object.
-     * If the event type has already been added, do nothing.
+     * Deprecated.  Any event can be triggered without adding it first.
      * 
      * Parameters:
      * eventName - {String}
      */
     addEventType: function(eventName) {
-        if (!this.listeners[eventName]) {
-            this.eventTypes.push(eventName);
-            this.listeners[eventName] = [];
-        }
     },
 
     /**
@@ -565,15 +545,11 @@
             OpenLayers.Event.stopObservingElement(this.element);
         }
         this.element = element;
-        for (var i=0, len=this.BROWSER_EVENTS.length; i<len; i++) {
-            var eventType = this.BROWSER_EVENTS[i];
-
-            // every browser event has a corresponding application event 
-            // (whether it's listened for or not).
-            this.addEventType(eventType);
-            
-            // use Prototype to register the event cross-browser
-            OpenLayers.Event.observe(element, eventType, this.eventHandler);
+        for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {
+            // register the event cross-browser
+            OpenLayers.Event.observe(
+                element, this.BROWSER_EVENTS[i], this.eventHandler
+            );
         }
         // disable dragstart in IE so that mousedown/move/up works normally
         OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
@@ -610,7 +586,7 @@
      */
     on: function(object) {
         for(var type in object) {
-            if(type != "scope") {
+            if(type != "scope" && object.hasOwnProperty(type)) {
                 this.register(type, object.scope, object[type]);
             }
         }
@@ -640,19 +616,24 @@
      *                     'object' property.
      * func - {Function} The callback function. If no callback is 
      *                        specified, this function does nothing.
-     * 
-     * 
+     * priority - {Boolean} If true, adds the new listener to the *front* of 
+     *                      the events queue instead of to the end.
      */
-    register: function (type, obj, func) {
-
-        if ( (func != null) && 
-             (OpenLayers.Util.indexOf(this.eventTypes, type) != -1) ) {
-
+    register: function (type, obj, func, priority) {
+        if (func != null) {
             if (obj == null)  {
                 obj = this.object;
             }
             var listeners = this.listeners[type];
-            listeners.push( {obj: obj, func: func} );
+            if (!listeners) {
+                listeners = [];
+                this.listeners[type] = listeners;
+            }
+            if (priority) {
+                listeners.unshift({obj: obj, func: func});
+            } else {
+                listeners.push({obj: obj, func: func});
+            }
         }
     },
 
@@ -674,16 +655,7 @@
      *                   specified, this function does nothing.
      */
     registerPriority: function (type, obj, func) {
-
-        if (func != null) {
-            if (obj == null)  {
-                obj = this.object;
-            }
-            var listeners = this.listeners[type];
-            if (listeners != null) {
-                listeners.unshift( {obj: obj, func: func} );
-            }
-        }
+        this.register(type, obj, func, true);
     },
     
     /**
@@ -714,7 +686,7 @@
      */
     un: function(object) {
         for(var type in object) {
-            if(type != "scope") {
+            if(type != "scope" && object.hasOwnProperty(type)) {
                 this.unregister(type, object.scope, object[type]);
             }
         }

Modified: sandbox/august/trunk/lib/OpenLayers/Filter/FeatureId.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Filter/FeatureId.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Filter/FeatureId.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -20,8 +20,8 @@
 
     /** 
      * APIProperty: fids
-     * {Array(String)} Feature Ids to evaluate this rule against. To be passed
-     * To be passed inside the params object.
+     * {Array(String)} Feature Ids to evaluate this rule against. 
+     *     To be passed inside the params object.
      */
     fids: null,
     

Modified: sandbox/august/trunk/lib/OpenLayers/Filter/Function.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Filter/Function.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Filter/Function.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -43,9 +43,6 @@
      * Returns:
      * {<OpenLayers.Filter.Function>}
      */
-    initialize: function(options) {
-        OpenLayers.Filter.prototype.initialize.apply(this, [options]);
-    },
 
     CLASS_NAME: "OpenLayers.Filter.Function"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Filter/Spatial.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Filter/Spatial.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Filter/Spatial.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -69,9 +69,6 @@
      * Returns:
      * {<OpenLayers.Filter.Spatial>}
      */
-    initialize: function(options) {
-        OpenLayers.Filter.prototype.initialize.apply(this, [options]);
-    },
 
    /**
     * Method: evaluate

Modified: sandbox/august/trunk/lib/OpenLayers/Format/GPX.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/GPX.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/GPX.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -20,6 +20,16 @@
  *  - <OpenLayers.Format.XML>
  */
 OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
+    
+
+    /** 
+     * APIProperty: defaultDesc
+     * {String} Default description for the waypoints/tracks in the case
+     *     where the feature has no "description" attribute.
+     *     Default is "No description available".
+     */
+    defaultDesc: "No description available",
+
    /**
     * APIProperty: extractWaypoints
     * {Boolean} Extract waypoints from GPX. (default: true)
@@ -45,6 +55,13 @@
      *     be extracted.
      */
     extractAttributes: true,
+
+    /**
+     * APIProperty: gpxns
+     * {String} GPX namespace to use. Defaults to
+     *   "http://www.topografix.com/GPX/1/1"
+     */
+    gpxns: "http://www.topografix.com/GPX/1/1",
     
     /**
      * Constructor: OpenLayers.Format.GPX
@@ -179,6 +196,170 @@
         }
         return attributes;
     },
+
+    /**
+     * APIMethod: write
+     * Accepts Feature Collection, and returns a string. 
+     * 
+     * Parameters: 
+     * features - {Array(<OpenLayers.Feature.Vector>)} List of features to serialize into a string.
+     * metadata - {Object} A key/value pairs object to build a metadata node to
+     *      add to the gpx. Supported keys are 'name', 'desc', 'author'.
+     */
+    write: function(features, metadata) {
+        var gpx;
+        features = OpenLayers.Util.isArray(features) ?
+            features : [features];
+        gpx = this.createElementNS(this.gpxns, "gpx");
+
+        for(var i=0, len=features.length; i<len; i++) {
+            gpx.appendChild(this.buildFeatureNode(features[i]));
+        }
+        if (metadata && typeof metadata == 'object') {
+            gpx.appendChild(this.buildMetadataNode(metadata));
+        }
+        return OpenLayers.Format.XML.prototype.write.apply(this, [gpx]);
+    },
+
+    /**
+     * Method: buildMetadataNode
+     * Creates a "metadata" node.
+     *
+     * Returns:
+     * {DOMElement}
+     */
+    buildMetadataNode: function(metadata) {
+        var types = ['name', 'desc', 'author'],
+            node = this.createElementNS(this.gpxns, 'metadata');
+        for (var i=0; i < types.length; i++) {
+            var type = types[i];
+            if (metadata[type]) {
+                var n = this.createElementNS(this.gpxns, type);
+                n.appendChild(this.createTextNode(metadata[type]));
+                node.appendChild(n);
+            }
+        }
+        return node;
+    },
+
+    /**
+     * Method: buildFeatureNode
+     * Accepts an <OpenLayers.Feature.Vector>, and builds a node for it.
+     * 
+     * Parameters:
+     * feature - {<OpenLayers.Feature.Vector>}
+     *
+     * Returns:
+     * {DOMElement} - The created node, either a 'wpt' or a 'trk'.
+     */
+    buildFeatureNode: function(feature) {
+        var geometry = feature.geometry;
+            geometry = geometry.clone();
+        if (this.internalProjection && this.externalProjection) {
+            geometry.transform(this.internalProjection, 
+                               this.externalProjection);
+        }
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
+            var wpt = this.buildWptNode(feature);
+            return wpt;
+        } else {
+            var trkNode = this.createElementNS(this.gpxns, "trk");
+            this.appendAttributesNode(trkNode, feature);
+            var trkSegNodes = this.buildTrkSegNode(geometry);
+            trkSegNodes = OpenLayers.Util.isArray(trkSegNodes) ?
+                trkSegNodes : [trkSegNodes];
+            for (var i = 0, len = trkSegNodes.length; i < len; i++) {
+                trkNode.appendChild(trkSegNodes[i]);
+            }
+            return trkNode;
+        }
+    },
+
+    /**
+     * Method: buildTrkSegNode
+     * Builds trkseg node(s) given a geometry
+     *
+     * Parameters:
+     * trknode
+     * geometry - {OpenLayers.Geometry}
+     */
+    buildTrkSegNode: function(geometry) {
+        var node,
+            i,
+            len,
+            point,
+            nodes;
+        if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString" ||
+            geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
+            node = this.createElementNS(this.gpxns, "trkseg");
+            for (i = 0, len=geometry.components.length; i < len; i++) {
+                point = geometry.components[i];
+                node.appendChild(this.buildTrkPtNode(point));
+            }
+            return node;
+        } else {
+            nodes = [];
+            for (i = 0, len = geometry.components.length; i < len; i++) {
+                nodes.push(this.buildTrkSegNode(geometry.components[i]));
+            }
+            return nodes;
+        }
+    },
     
+    /**
+     * Method: buildTrkPtNode
+     * Builds a trkpt node given a point 
+     *
+     * Parameters:
+     * line - {OpenLayers.Geometry.Point}
+     *
+     * Returns:
+     * {DOMElement} A trkpt node
+     */
+    buildTrkPtNode: function(point) {
+        var node = this.createElementNS(this.gpxns, "trkpt");
+        node.setAttribute("lon", point.x);
+        node.setAttribute("lat", point.y);
+        return node;
+    },
+
+    /**
+     * Method: buildWptNode
+     * Builds a wpt node given a point
+     *
+     * Parameters:
+     * feature - {OpenLayers.Feature.Vector}
+     *
+     * Returns:
+     * {DOMElement} A wpt node
+     */
+    buildWptNode: function(feature) {
+        var node = this.createElementNS(this.gpxns, "wpt");
+        node.setAttribute("lon", feature.geometry.x);
+        node.setAttribute("lat", feature.geometry.y);
+        this.appendAttributesNode(node, feature);
+        return node;
+    },
+
+    /**
+     * Method: appendAttributesNode
+     * Adds some attributes node.
+     *
+     * Parameters:
+     * node - {DOMElement} the node to append the attribute nodes to.
+     * feature - {OpenLayers.Feature.Vector}
+     */
+    appendAttributesNode: function(node, feature) {
+        var name = this.createElementNS(this.gpxns, 'name');
+        name.appendChild(this.createTextNode(
+            feature.attributes.name || feature.id));
+        node.appendChild(name);
+        var desc = this.createElementNS(this.gpxns, 'desc');
+        desc.appendChild(this.createTextNode(
+            feature.attributes.description || this.defaultDesc));
+        node.appendChild(desc);
+        // TBD - deal with remaining (non name/description) attributes.
+    },
+
     CLASS_NAME: "OpenLayers.Format.GPX"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Format/KML.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/KML.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/KML.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -4,6 +4,7 @@
  * full text of the license. */
 
 /**
+ * @requires OpenLayers/BaseTypes/Date.js
  * @requires OpenLayers/Format/XML.js
  * @requires OpenLayers/Feature/Vector.js
  * @requires OpenLayers/Geometry/Point.js
@@ -1222,12 +1223,6 @@
      * {DOMElement}
      */
     buildGeometryNode: function(geometry) {
-        if (this.internalProjection && this.externalProjection && 
-            !(geometry instanceof OpenLayers.Geometry.Collection)) {
-            geometry = geometry.clone();
-            geometry.transform(this.internalProjection, 
-                               this.externalProjection);
-        }                       
         var className = geometry.CLASS_NAME;
         var type = className.substring(className.lastIndexOf(".") + 1);
         var builder = this.buildGeometry[type.toLowerCase()];
@@ -1412,12 +1407,12 @@
             var parts = new Array(numPoints);
             for(var i=0; i<numPoints; ++i) {
                 point = points[i];
-                parts[i] = point.x + "," + point.y;
+                parts[i] = this.buildCoordinates(point);
             }
             path = parts.join(" ");
         } else {
             // Point
-            path = geometry.x + "," + geometry.y;
+            path = this.buildCoordinates(geometry);
         }
         
         var txtNode = this.createTextNode(path);
@@ -1425,6 +1420,24 @@
         
         return coordinatesNode;
     },    
+    
+    /**
+     * Method: buildCoordinates
+     *
+     * Parameters:
+     * point - {<OpenLayers.Geometry.Point>}
+     *
+     * Returns
+     * {String} a coordinate pair
+     */
+    buildCoordinates: function(point) {
+        if (this.internalProjection && this.externalProjection) {
+            point = point.clone();
+            point.transform(this.internalProjection, 
+                               this.externalProjection);
+        }
+        return point.x + "," + point.y;                     
+    },
 
     CLASS_NAME: "OpenLayers.Format.KML" 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Format/OWSContext/v0_3_1.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/OWSContext/v0_3_1.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/OWSContext/v0_3_1.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -466,7 +466,7 @@
                     name: layer.params.LAYERS,
                     queryable: layer.queryable ? "1" : "0",
                     hidden: layer.visibility ? "0" : "1",
-                    opacity: layer.opacity ? layer.opacity: null}
+                    opacity: layer.hasOwnProperty("opacity") ? layer.opacity : null}
                 });
                 this.writeNode("ows:Title", layer.name, node);
                 this.writeNode("ows:OutputFormat", layer.params.FORMAT, node);

Modified: sandbox/august/trunk/lib/OpenLayers/Format/QueryStringFilter.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/QueryStringFilter.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/QueryStringFilter.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -4,8 +4,11 @@
  * full text of the license. */
 
 /**
+ * @requires OpenLayers/Console.js
  * @requires OpenLayers/Format.js
+ * @requires OpenLayers/Filter/Spatial.js
  * @requires OpenLayers/Filter/Comparison.js
+ * @requires OpenLayers/Filter/Logical.js
  */
 
 /**
@@ -177,4 +180,4 @@
     });
 
 
-})();
\ No newline at end of file
+})();

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -12,7 +12,7 @@
  * Read WFS Capabilities version 1.0.0.
  * 
  * Inherits from:
- *  - <OpenLayers.Format.WFSCapabilities>
+ *  - <OpenLayers.Format.WFSCapabilities.v1>
  */
 OpenLayers.Format.WFSCapabilities.v1_0_0 = OpenLayers.Class(
     OpenLayers.Format.WFSCapabilities.v1, {

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WFST/v1.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WFST/v1.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WFST/v1.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -183,12 +183,12 @@
      * transaction:
      * - *modified* is not set at all: The geometry and all attributes will be
      *     included.
-     * - *modified.geometry* is truthy: The geometry will be
+     * - *modified.geometry* is set (null or a geometry): The geometry will be
      *     included. If *modified.attributes* is not set, all attributes will
      *     be included.
-     * - *modified.attributes* is set: Only the attributes with a truthy value
-     *     in *modified.attributes* will be included. If *modified.geometry*
-     *     is not set, the geometry will not be included.
+     * - *modified.attributes* is set: Only the attributes set (i.e. to null or
+     *     a value) in *modified.attributes* will be included. 
+     *     If *modified.geometry* is not set, the geometry will not be included.
      *
      * Valid options include:
      * - *multi* {Boolean} If set to true, geometries will be casted to
@@ -323,7 +323,7 @@
                 
                 // add in geometry
                 var modified = feature.modified;
-                if (this.geometryName !== null && (!modified || modified.geometry)) {
+                if (this.geometryName !== null && (!modified || modified.geometry !== undefined)) {
                     this.srsName = this.getSrsName(feature);
                     this.writeNode(
                         "Property", {name: this.geometryName, value: feature.geometry}, node
@@ -334,7 +334,7 @@
                 for(var key in feature.attributes) {
                     if(feature.attributes[key] !== undefined &&
                                 (!modified || !modified.attributes ||
-                                (modified.attributes && modified.attributes[key]))) {
+                                (modified.attributes && modified.attributes[key] !== undefined))) {
                         this.writeNode(
                             "Property", {name: key, value: feature.attributes[key]}, node
                         );

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WMC.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WMC.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WMC.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -61,7 +61,7 @@
             numZoomLevels: layer.numZoomLevels,
             units: layer.units,
             isBaseLayer: layer.isBaseLayer,
-            opacity: layer.opacity,
+            opacity: layer.opacity == 1 ? undefined : layer.opacity,
             displayInLayerSwitcher: layer.displayInLayerSwitcher,
             singleTile: layer.singleTile,
             tileSize: (layer.singleTile || !layer.tileSize) ? 

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WMSCapabilities/v1.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WMSCapabilities/v1.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WMSCapabilities/v1.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -113,6 +113,8 @@
             layer.formats = capability.request.getmap.formats;
         }
 
+        var i, len;
+
         // deal with property inheritance
         if(parentLayer) {
             // add style
@@ -134,8 +136,9 @@
                                "authorityURLs"];
             
             var key;
-            for (var j=0; j<attributes.length; j++) {
-                key = attributes[j];
+
+            for (i=0, len=attributes.length; i<len; i++) {
+                key = attributes[i];
                 if (key in parentLayer) {
                     // only take parent value if not present (null or undefined)
                     if (layer[key] == null) {
@@ -157,15 +160,15 @@
                 }
             }
 
-            for (var j=0; j<complexAttr.length; j++) {
-                key = complexAttr[j];
-                layer[key] = OpenLayers.Util.extend(
+            for (i=0, len=complexAttr.length; i<len; i++) {
+                key = complexAttr[i];
+                layer[key] = OpenLayers.Util.applyDefaults(
                     layer[key], parentLayer[key]);
             }
         }
 
         // process sublayers
-        for (var i=0, len=layer.nestedLayers.length; i<len; i++) {
+        for (i=0, len=layer.nestedLayers.length; i<len; i++) {
             var childLayer = layer.nestedLayers[i];
             this.processLayer(capability, childLayer, layer);
         }

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -115,6 +115,9 @@
                     tileMatrixSetLinks: []
                 };
                 layer.layers = [];
+                // add this so OWSCommon.v1 format will add both <ows:BoundingBox> and <ows:WGS84BoudningBox>
+                //     as child of <Layer>
+                layer.boundingBox = [];
                 this.readChildNodes(node, layer);
                 obj.layers.push(layer);
             },

Modified: sandbox/august/trunk/lib/OpenLayers/Format/WPSDescribeProcess.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Format/WPSDescribeProcess.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Format/WPSDescribeProcess.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -5,6 +5,7 @@
  
 /**
  * @requires OpenLayers/Format/XML.js
+ * @requires OpenLayers/Format/OWSCommon/v1_1_0.js
  */
 
 /**

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/Curve.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/Curve.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/Curve.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -32,10 +32,6 @@
      * Parameters:
      * point - {Array(<OpenLayers.Geometry.Point>)}
      */
-    initialize: function(points) {
-        OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this, 
-                                                                  arguments);
-    },
     
     /**
      * APIMethod: getLength

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/LineString.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/LineString.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/LineString.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -26,9 +26,6 @@
      *          generate the linestring
      *
      */
-    initialize: function(points) {
-        OpenLayers.Geometry.Curve.prototype.initialize.apply(this, arguments);        
-    },
 
     /**
      * APIMethod: removeComponent

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/LinearRing.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/LinearRing.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/LinearRing.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -42,10 +42,6 @@
      * Parameters:
      * points - {Array(<OpenLayers.Geometry.Point>)} points
      */
-    initialize: function(points) {
-        OpenLayers.Geometry.LineString.prototype.initialize.apply(this, 
-                                                                  arguments);
-    },
 
     /**
      * APIMethod: addComponent

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/MultiLineString.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/MultiLineString.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/MultiLineString.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -36,10 +36,6 @@
      * components - {Array(<OpenLayers.Geometry.LineString>)} 
      *
      */
-    initialize: function(components) {
-        OpenLayers.Geometry.Collection.prototype.initialize.apply(this, 
-                                                                  arguments);        
-    },
     
     /**
      * Method: split

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPoint.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPoint.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPoint.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -38,10 +38,6 @@
      * Returns:
      * {<OpenLayers.Geometry.MultiPoint>}
      */
-    initialize: function(components) {
-        OpenLayers.Geometry.Collection.prototype.initialize.apply(this, 
-                                                                  arguments);
-    },
 
     /**
      * APIMethod: addPoint

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPolygon.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPolygon.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/MultiPolygon.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -37,10 +37,6 @@
      *              used to generate the MultiPolygon
      *
      */
-    initialize: function(components) {
-        OpenLayers.Geometry.Collection.prototype.initialize.apply(this, 
-                                                                  arguments);
-    },
 
     CLASS_NAME: "OpenLayers.Geometry.MultiPolygon"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/Polygon.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/Polygon.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/Polygon.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -37,11 +37,7 @@
      * Parameters:
      * components - {Array(<OpenLayers.Geometry.LinearRing>)} 
      */
-    initialize: function(components) {
-        OpenLayers.Geometry.Collection.prototype.initialize.apply(this, 
-                                                                  arguments);
-    },
-    
+
     /** 
      * APIMethod: getArea
      * Calculated by subtracting the areas of the internal holes from the 

Modified: sandbox/august/trunk/lib/OpenLayers/Geometry/Surface.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Geometry/Surface.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Geometry/Surface.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -9,9 +9,5 @@
 
 OpenLayers.Geometry.Surface = OpenLayers.Class(OpenLayers.Geometry, {
 
-    initialize: function() {
-        OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
-    },
-
     CLASS_NAME: "OpenLayers.Geometry.Surface"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Click.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Click.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Click.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -146,9 +146,6 @@
      * options - {Object} Optional object whose properties will be set on the
      *     handler.
      */
-    initialize: function(control, callbacks, options) {
-        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
-    },
     
     /**
      * Method: touchstart
@@ -184,6 +181,9 @@
      * Method: touchend
      *   Correctly set event xy property, and add lastTouches to have
      *   touches property from last touchstart or touchmove
+     *
+     * Returns:
+     * {Boolean} Continue propagating this event.
      */
     touchend: function(evt) {
         // touchstart may not have been allowed to propagate

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Hover.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Hover.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Hover.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -69,9 +69,6 @@
      * options - {Object} An optional object whose properties will be set on
      *     the handler.
      */
-    initialize: function(control, callbacks, options) {
-        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
-    },
 
     /**
      * Method: mousemove

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Path.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Path.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Path.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -95,10 +95,7 @@
      * cancel - Called when the handler is deactivated while drawing.  The
      *     cancel callback will receive a geometry.
      */
-    initialize: function(control, callbacks, options) {
-        OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
-    },
-        
+
     /**
      * Method: createFeature
      * Add temporary geometries
@@ -108,7 +105,7 @@
      *     feature.
      */
     createFeature: function(pixel) {
-        var lonlat = this.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
         var geometry = new OpenLayers.Geometry.Point(
             lonlat.lon, lonlat.lat
         );
@@ -165,7 +162,7 @@
      */
     addPoint: function(pixel) {
         this.layer.removeFeatures([this.point]);
-        var lonlat = this.control.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
         this.point = new OpenLayers.Feature.Vector(
             new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
         );
@@ -326,7 +323,7 @@
         if(!this.line) {
             this.createFeature(pixel);
         }
-        var lonlat = this.control.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
         this.point.geometry.x = lonlat.lon;
         this.point.geometry.y = lonlat.lat;
         this.callback("modify", [this.point.geometry, this.getSketch(), drawing]);
@@ -417,6 +414,10 @@
         var stopDown = this.stopDown;
         if(this.freehandMode(evt)) {
             stopDown = true;
+            if (this.touch) {
+                this.modifyFeature(evt.xy, !!this.lastUp);
+                OpenLayers.Event.stop(evt);
+            }
         }
         if (!this.touch && (!this.lastDown ||
                             !this.passesTolerance(this.lastDown, evt.xy,

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Pinch.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Pinch.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Pinch.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -74,9 +74,6 @@
      *     information about scale, distance, and position of touch points.
      * options - {Object}
      */
-    initialize: function(control, callbacks, options) {
-        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
-    },
 
     /**
      * Method: touchstart
@@ -194,6 +191,9 @@
      *
      * Parameters:
      * touches - {Array(Object)}
+     *
+     * Returns:
+     * {Number} The distance in pixels.
      */
     getDistance: function(touches) {
         var t0 = touches[0];

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Point.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Point.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Point.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -43,6 +43,13 @@
     multi: false,
     
     /**
+     * APIProperty: citeCompliant
+     * {Boolean} If set to true, coordinates of features drawn in a map extent
+     * crossing the date line won't exceed the world bounds. Default is false.
+     */
+    citeCompliant: false,
+    
+    /**
      * Property: mouseDown
      * {Boolean} The mouse is down
      */
@@ -164,7 +171,8 @@
             // without this, resolution properties must be specified at the
             // map-level for this temporary layer to init its resolutions
             // correctly
-            calculateInRange: OpenLayers.Function.True
+            calculateInRange: OpenLayers.Function.True,
+            wrapDateLine: this.citeCompliant
         }, this.layerOptions);
         this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
         this.map.addLayer(this.layer);
@@ -179,7 +187,7 @@
      * pixel - {<OpenLayers.Pixel>} A pixel location on the map.
      */
     createFeature: function(pixel) {
-        var lonlat = this.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
         var geometry = new OpenLayers.Geometry.Point(
             lonlat.lon, lonlat.lat
         );
@@ -306,7 +314,7 @@
         if(!this.point) {
             this.createFeature(pixel);
         }
-        var lonlat = this.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); 
         this.point.geometry.x = lonlat.lon;
         this.point.geometry.y = lonlat.lat;
         this.callback("modify", [this.point.geometry, this.point, false]);

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/Polygon.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/Polygon.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/Polygon.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -62,9 +62,6 @@
      * cancel - Called when the handler is deactivated while drawing.  The
      *     cancel callback will receive a geometry.
      */
-    initialize: function(control, callbacks, options) {
-        OpenLayers.Handler.Path.prototype.initialize.apply(this, arguments);
-    },
     
     /**
      * Method: createFeature
@@ -75,7 +72,7 @@
      *     feature.
      */
     createFeature: function(pixel) {
-        var lonlat = this.map.getLonLatFromPixel(pixel);
+        var lonlat = this.layer.getLonLatFromViewPortPx(pixel);
         var geometry = new OpenLayers.Geometry.Point(
             lonlat.lon, lonlat.lat
         );

Modified: sandbox/august/trunk/lib/OpenLayers/Handler/RegularPolygon.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Handler/RegularPolygon.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Handler/RegularPolygon.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -84,6 +84,13 @@
     irregular: false,
 
     /**
+     * APIProperty: citeCompliant
+     * {Boolean} If set to true, coordinates of features drawn in a map extent
+     * crossing the date line won't exceed the world bounds. Default is false.
+     */
+    citeCompliant: false,
+
+    /**
      * Property: angle
      * {Float} The angle from the origin (mouse down) to the current mouse
      *     position, in radians.  This is measured counterclockwise from the
@@ -174,7 +181,8 @@
                 // without this, resolution properties must be specified at the
                 // map-level for this temporary layer to init its resolutions
                 // correctly
-                calculateInRange: OpenLayers.Function.True
+                calculateInRange: OpenLayers.Function.True,
+                wrapDateLine: this.citeCompliant
             }, this.layerOptions);
             this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
             this.map.addLayer(this.layer);
@@ -224,7 +232,7 @@
      */
     down: function(evt) {
         this.fixedRadius = !!(this.radius);
-        var maploc = this.map.getLonLatFromPixel(evt.xy);
+        var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); 
         this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
         // create the new polygon
         if(!this.fixedRadius || this.irregular) {
@@ -250,7 +258,7 @@
      * evt - {Evt} The move event
      */
     move: function(evt) {
-        var maploc = this.map.getLonLatFromPixel(evt.xy);
+        var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); 
         var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
         if(this.irregular) {
             var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2;

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/be-tarask.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/be-tarask.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/be-tarask.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "Базавы слой",
 
-    'sameProjection': "Аглядная мапа працуе толькі калі яна мае тую ж праекцыю, што і асноўная мапа",
-
     'readNotImplemented': "Функцыянальнасьць чытаньня ня створаная.",
 
     'writeNotImplemented': "Функцыянальнасьць запісу ня створаная.",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "Тып геамэтрыі не падтрымліваецца: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition failed: верагодна элемэнт з ідэнтыфікатарам ${elemId} займае няслушнае месца.",
-
     'filterEvaluateNotImplemented': "evaluate не рэалізаваны для гэтага тыпу фільтру."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/br.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/br.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/br.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Gwiskad diazez",
 
-    'sameProjection': "Ne\'z ar gartenn lec\'hiañ en-dro nemet pa vez heñvel ar banndres anezhi ha hini ar gartenn bennañ",
-
     'readNotImplemented': "N\'eo ket emplementet al lenn.",
 
     'writeNotImplemented': "N\'eo ket emplementet ar skrivañ.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Seurt mentoniezh anskoret : ${geomType}",
 
-    'pagePositionFailed': "C\'hwitet eo OpenLayers.Util.pagePosition : marteze emañ lec\'hiet fall an elfenn id ${elemId}.",
-
     'filterEvaluateNotImplemented': "N\'eo ket bet emplementet ar priziañ evit seurt siloù c\'hoazh."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/ca.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/ca.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/ca.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Capa Base",
 
-    'sameProjection':
-        "El mapa de referència només funciona si té la mateixa projecció que el mapa principal",
-
     'readNotImplemented': "Lectura no implementada.",
 
     'writeNotImplemented': "Escriptura no implementada.",
@@ -116,10 +113,6 @@
     'unsupportedGeometryType': "Tipus de geometria no suportada: ${geomType}",
 
     // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition ha fallat: l'element amb id ${elemId} pot estar fora de lloc.",
-                    
-    // console message
     'filterEvaluateNotImplemented': "evaluate no està implementat per aquest tipus de filtre.",
 
     // **** end ****

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/cs-CZ.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/cs-CZ.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/cs-CZ.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Podkladové vrstvy",
 
-    'sameProjection': "Přehledka pracuje správně pouze tehdy, pokud je ve stejné projekci jako hlavní mapa",
-
     'readNotImplemented': "Read není implementováno.",
 
     'writeNotImplemented': "Write není implementováno.",
@@ -62,8 +60,6 @@
 
     'pixelAddError': "Pro přídavnou funkci musíte zadat obě souřadnice x a y.",
 
-    'unsupportedGeometryType': "Nepodporovaný typ geometrie: ${geomType}",
+    'unsupportedGeometryType': "Nepodporovaný typ geometrie: ${geomType}"
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition selhalo: element s  id ${elemId} je asi umístěn chybně."
-
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/da-DK.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/da-DK.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/da-DK.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Baggrundslag",
 
-    'sameProjection':
-        "Oversigtskortet fungerer kun når det har samme projektion som hovedkortet",
-
     'readNotImplemented': "Læsning er ikke implementeret.",
 
     'writeNotImplemented': "Skrivning er ikke implementeret.",
@@ -111,9 +108,5 @@
     'unsupportedGeometryType': "Geometri typen: ${geomType} er ikke understøttet.",
 
     // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition fejlede: elementet med id ${elemId} er måske placeret forkert.",
-
-    // console message
     'filterEvaluateNotImplemented': "evaluering er ikke implementeret for denne filter type."
 };

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/de.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/de.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/de.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -24,8 +24,6 @@
 
     'Base Layer': "Grundkarte",
 
-    'sameProjection': "Die Übersichtskarte funktioniert nur, wenn sie dieselbe Projektion wie die Hauptkarte verwendet",
-
     'readNotImplemented': "Lesen nicht implementiert.",
 
     'writeNotImplemented': "Schreiben nicht implementiert.",
@@ -74,8 +72,6 @@
 
     'unsupportedGeometryType': "Nicht unterstützter Geometrie-Typ: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition fehlgeschlagen: Element mit Id ${elemId} möglicherweise falsch platziert.",
-
     'filterEvaluateNotImplemented': "„evaluate“ ist für diesen Filter-Typ nicht implementiert."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/en.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/en.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/en.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Base Layer",
 
-    'sameProjection':
-        "The overview map only works when it is in the same projection as the main map",
-
     'readNotImplemented': "Read not implemented.",
 
     'writeNotImplemented': "Write not implemented.",
@@ -116,10 +113,6 @@
     'unsupportedGeometryType': "Unsupported geometry type: ${geomType}",
 
     // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",
-
-    // console message
     'filterEvaluateNotImplemented': "evaluate is not implemented for this filter type.",
 
     'proxyNeeded': "You probably need to set OpenLayers.ProxyHost to access ${url}."+

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/es.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/es.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/es.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Capa Base",
 
-    'sameProjection':
-        "El mapa de vista general sólo funciona si está en la misma proyección que el mapa principal",
-
     'readNotImplemented': "Lectura no implementada.",
 
     'writeNotImplemented': "Escritura no implementada.",
@@ -117,10 +114,6 @@
     'unsupportedGeometryType': "Tipo de geometría no soportada: ${geomType}",
 
     // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition falló: el elemento con id ${elemId} puede haberse colocado de manera errónea.",
-                    
-    // console message
     'filterEvaluateNotImplemented': "evaluate no está implementado para este tipo de filtro.",
 
     // **** end ****

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/fi.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/fi.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/fi.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -21,8 +21,6 @@
 
     'Base Layer': "Peruskerros",
 
-    'sameProjection': "Yleiskuvakarttaa voi käyttää vain, kun sillä on sama projektio kuin pääkartalla.",
-
     'W': "L",
 
     'E': "I",

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/fr.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/fr.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/fr.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "Calque de base",
 
-    'sameProjection': "La carte de situation ne fonctionne que lorsque sa projection est la même que celle de la carte principale",
-
     'readNotImplemented': "Lecture non implémentée.",
 
     'writeNotImplemented': "Ecriture non implémentée.",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "Type de géométrie non supporté : ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition a échoué: l\'élément d\'id ${elemId} pourrait être mal positionné.",
-
     'filterEvaluateNotImplemented': "évaluer n\'a pas encore été implémenté pour ce type de filtre.",
 
     'proxyNeeded': "Vous avez très probablement besoin de renseigner OpenLayers.ProxyHost pour accéder à ${url}. Voir http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#ProxyHost"

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/gl.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/gl.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/gl.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Capa base",
 
-    'sameProjection': "A vista xeral do mapa só funciona cando está na mesma proxección có mapa principal",
-
     'readNotImplemented': "Lectura non implementada.",
 
     'writeNotImplemented': "Escritura non implementada.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Tipo xeométrico non soportado: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition fallou: o elemento con id ${elemId} pode non estar na súa posición.",
-
     'filterEvaluateNotImplemented': "avaliar non está implementado para este tipo de filtro."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/gsw.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/gsw.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/gsw.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Grundcharte",
 
-    'sameProjection': "D Ibersichts-Charte funktioniert nume, wänn si di glych Projäktion brucht wie d Hauptcharte",
-
     'readNotImplemented': "Läse nit implementiert.",
 
     'writeNotImplemented': "Schrybe nit implementiert.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Nit unterstitze Geometrii-Typ: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition fählgschlaa: Elemänt mit ID ${elemId} isch villicht falsch gsetzt.",
-
     'filterEvaluateNotImplemented': "evaluiere isch nit implemäntiert in däm Filtertyp."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/hr.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/hr.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/hr.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Osnovna karta",
 
-    'sameProjection': "Pregledna karta radi jedino kao je u istoj projekciji kao i glava karta",
-
     'readNotImplemented': "Čitanje nije implementirano.",
 
     'writeNotImplemented': "Pisanje nije implementirano.",
@@ -54,8 +52,6 @@
 
     'pixelAddError': "Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",
 
-    'unsupportedGeometryType': "Nepodržani tip geometrije: ${geomType}",
+    'unsupportedGeometryType': "Nepodržani tip geometrije: ${geomType}"
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition nije uspjelo: element sa id ${elemId} može biti krivo smješten."
-
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/hsb.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/hsb.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/hsb.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Zakładna runina",
 
-    'sameProjection': "Přehladowa karta jenož funguje, hdyž je w samsnej projekciji kaž hłowna karta",
-
     'readNotImplemented': "Čitanje njeimplementowane.",
 
     'writeNotImplemented': "Pisanje njeimplementowane.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Njepodpěrowany geometrijowy typ: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition je so njeporadźił: element z id ${elemId} bu snano wopak zaměstnjeny.",
-
     'filterEvaluateNotImplemented': "wuhódnoćenje njeje za tutón filtrowy typ implementowany."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/hu.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/hu.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/hu.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "Alapréteg",
 
-    'sameProjection': "Az áttekintő térkép csak abban az esetben működik, ha ugyanazon a vetületen van, mint a fő térkép.",
-
     'readNotImplemented': "Olvasás nincs végrehajtva.",
 
     'writeNotImplemented': "Írás nincs végrehajtva.",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "Nem támogatott geometriatípus: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition sikertelen: lehetséges, hogy a(z) ${elemId} azonosítójú elem téves helyre került.",
-
     'filterEvaluateNotImplemented': "ennél a szűrőtípusnál kiértékelés nem hajtódik végre."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/ia.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/ia.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/ia.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Strato de base",
 
-    'sameProjection': "Le mini-carta functiona solmente si illo es in le mesme projection que le carta principal",
-
     'readNotImplemented': "Lectura non implementate.",
 
     'writeNotImplemented': "Scriptura non implementate.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Typo de geometria non supportate: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition falleva: le elemento con id ${elemId} pote esser mal placiate.",
-
     'filterEvaluateNotImplemented': "\"evaluate\" non es implementate pro iste typo de filtro."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/id.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/id.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/id.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "Lapisan Dasar",
 
-    'sameProjection': "Peta tinjauan hanya bekerja bila dalam proyeksi yang sama dengan peta utama",
-
     'readNotImplemented': "Membaca tidak diterapkan.",
 
     'writeNotImplemented': "Menyimpan tidak diterapkan.",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "Tipe geometri tak didukung: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition gagal: elemen dengan id ${elemId} mungkin salah tempat.",
-
     'filterEvaluateNotImplemented': "evaluasi tidak tersedia untuk tipe filter ini."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/is.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/is.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/is.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -20,8 +20,6 @@
 
     'Base Layer': "Grunnlag",
 
-    'sameProjection': "Yfirlitskortið virkar aðeins ef það er í sömu vörpun og aðalkortið",
-
     'readNotImplemented': "Skrifun er óútfærð.",
 
     'writeNotImplemented': "Lestur er óútfærður.",

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/it.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/it.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/it.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Livello base",
 
-    'sameProjection':
-        "La mini mappa funziona solamente se ha la stessa proiezione della mappa principale",
-
     'readNotImplemented': "Lettura non implementata.",
 
     'writeNotImplemented': "Scrittura non implementata.",
@@ -108,9 +105,5 @@
     // console message
     'unsupportedGeometryType': "Tipo di geometria non supportata: ${geomType}",
 
-    // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition fallita: l'elemento con id ${elemId} è posizionato in modo errato.",
-                    
     'end': ''
 };

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/ja.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/ja.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/ja.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "基底レイヤー",
 
-    'sameProjection': "概観地図はメインの地図と同じ投影法をとる場合のみ機能します",
-
     'readNotImplemented': "読み込みは実装されていません。",
 
     'writeNotImplemented': "書き込みは実装されていません。",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "未対応の形状型: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition が失敗しました: id ${elemId} をもつ要素が誤った位置にある可能性があります。",
-
     'filterEvaluateNotImplemented': "このフィルター型について evaluate は実装されていません。"
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/ksh.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/ksh.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/ksh.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Jrund-Nivoh",
 
-    'sameProjection': "De Övverseeschs_Kaat deiht et bloß, wann se de sälve Projäxjuhn bruche deiht, wi de Houp_Kaat",
-
     'readNotImplemented': "„\x3ccode lang=\"en\"\x3eread\x3c/code\x3e“ is em Projramm nit fürjesinn.",
 
     'writeNotImplemented': "„\x3ccode lang=\"en\"\x3ewrite\x3c/code\x3e“ is em Projramm nit fürjesinn.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "De Zoot Jommetrii dom_mer nit ongershtöze: \x3ccode\x3e${geomType}\x3c/code\x3e",
 
-    'pagePositionFailed': "\x3ccode lang=\"en\"\x3eOpenLayers.Util.pagePosition\x3c/code\x3e es donevve jejange: dat Denge met dä Kännong \x3ccode\x3e${elemId}\x3c/code\x3e künnt am verkeehte Plaz sin.",
-
     'filterEvaluateNotImplemented': "„\x3ccode lang=\"en\"\x3eevaluate\x3c/code\x3e“ es för di Zoot Fellter nit enjereschdt."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/lt.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/lt.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/lt.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Pagrindinis sluoksnis",
 
-    'sameProjection':
-	"Apžvalginis žemėlapis veikia tik tada, kai jis yra tos pačios projekcijos kaip ir pagrindinis",
-
     'readNotImplemented': "Skaitymas nėra įgyvendintas.",
 
     'writeNotImplemented': "Rašymas nėra įgyvendintas.",
@@ -72,10 +69,6 @@
     // console message
     'unsupportedGeometryType': "Nepalaikomas geometrijos tipas: ${geomType}",
 
-    // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition žlugo: elementas su id ${elemId} gali būti neteisingoje vietoje.",
-
     // **** end ****
     'end': ''
     

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/nb.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/nb.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/nb.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "Bakgrunnskart",
 
-    'sameProjection':
-        "Oversiktskartet fungerer bare når det har samme projeksjon som hovedkartet",
-
     'readNotImplemented': "Lesing er ikke implementert.",
 
     'writeNotImplemented': "Skriving er ikke implementert.",
@@ -108,10 +105,6 @@
     // console message
     'unsupportedGeometryType': "Geometritypen ${geomType} er ikke støttet",
 
-    // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition feilet: elementet med id ${elemId} kan være feilplassert.",
-                    
     'end': ''
 };
 

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/nds.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/nds.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/nds.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Achtergrundkoort",
 
-    'sameProjection': "De Översichtskoort geiht blot, wenn de sülve Projekschoon as bi de Hööftkoort bruukt warrt",
-
     'readNotImplemented': "Lesen is nich inricht.",
 
     'writeNotImplemented': "Schrieven is nich inricht.",
@@ -54,8 +52,6 @@
 
     'pixelAddError': "De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",
 
-    'unsupportedGeometryType': "Nich ünnerstütt Geometrie-Typ: ${geomType}",
+    'unsupportedGeometryType': "Nich ünnerstütt Geometrie-Typ: ${geomType}"
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition güng nich: Element mit de Id ${elemId} is villicht an’n verkehrten Platz."
-
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/nl.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/nl.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/nl.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Achtergrondkaart",
 
-    'sameProjection': "De overzichtskaart werkt alleen als de projectie gelijk is aan de projectie van de hoofdkaart",
-
     'readNotImplemented': "Lezen is niet geïmplementeerd.",
 
     'writeNotImplemented': "Schrijven is niet geïmplementeerd.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Dit geometrietype wordt niet ondersteund: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition is mislukt: het element met id ${elemId} is wellicht onjuist geplaatst.",
-
     'filterEvaluateNotImplemented': "evalueren is niet geïmplementeerd voor dit filtertype."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/oc.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/oc.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/oc.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Calc de basa",
 
-    'sameProjection': "La carta de situacion fonciona pas que quora sa projeccion es la meteissa que la de la carta principala",
-
     'readNotImplemented': "Lectura pas implementada.",
 
     'writeNotImplemented': "Escritura pas implementada.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Tipe de geometria pas suportat : ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition a fracassat : l\'element d\'id ${elemId} poiriá èsser mal posicionat.",
-
     'filterEvaluateNotImplemented': "evaluar es pas encara estat implementat per aqueste tipe de filtre."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/pt-BR.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/pt-BR.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/pt-BR.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -23,8 +23,6 @@
 
     'Base Layer': "Camada Base",
 
-    'sameProjection': "O mapa de referência só funciona quando ele está na mesma projeção do mapa principal",
-
     'readNotImplemented': "Leitura não implementada.",
 
     'writeNotImplemented': "Escrita não implementada.",
@@ -73,8 +71,6 @@
 
     'unsupportedGeometryType': "Tipo geométrico não suportado: ${geomType}.",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition falhou: o elemento de id ${elemId} deve estar fora do lugar.",
-
     'filterEvaluateNotImplemented': "evaluete não está implementado para este tipo de filtro."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/pt.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/pt.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/pt.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -24,8 +24,6 @@
 
     'Base Layer': "Camada Base",
 
-    'sameProjection': "O mapa panorâmico só funciona quando está na mesma projeção que o mapa principal",
-
     'readNotImplemented': "Leitura não implementada.",
 
     'writeNotImplemented': "Escrita não implementada.",
@@ -74,8 +72,6 @@
 
     'unsupportedGeometryType': "Tipo de geometria não suportado: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition falhou: o elemento com o id ${elemId} poderá estar mal-posicionado.",
-
     'filterEvaluateNotImplemented': "avaliar não está implementado para este tipo de filtro."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/ru.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/ru.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/ru.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -25,8 +25,6 @@
 
     'Base Layer': "Основной слой",
 
-    'sameProjection': "Обзорная карта работает только тогда, когда имеет ту же проекцию, что и основная",
-
     'readNotImplemented': "Чтение не реализовано.",
 
     'writeNotImplemented': "Запись не реализована.",
@@ -75,8 +73,6 @@
 
     'unsupportedGeometryType': "Неподдерживаемый тип геометрии: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition failed: элемент с id ${elemId} может находиться не в нужном месте.",
-
     'filterEvaluateNotImplemented': "evaluate не реализовано для фильтра данного типа."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/sk.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/sk.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/sk.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Základná vrstva",
 
-    'sameProjection': "Prehľadová mapka funguje iba vtedy, keď je v rovnakej projekcii ako hlavná mapa",
-
     'readNotImplemented': "Čítanie nie je implementované.",
 
     'writeNotImplemented': "Zápis nie je implementovaný.",
@@ -64,8 +62,6 @@
 
     'unsupportedGeometryType': "Nepodporovaný typ geometrie: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition zlyhalo: prvok s id ${elemId} môže byť zle umiestnený.",
-
     'filterEvaluateNotImplemented': "evaluate nie je implementovaný pre tento typ filtra"
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/sv-SE.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/sv-SE.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/sv-SE.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Bakgrundskarta",
 
-    'sameProjection': "Översiktskartan fungerar endast när den har samma projektion som huvudkartan",
-
     'readNotImplemented': "Läsning ej implementerad.",
 
     'writeNotImplemented': "Skrivning ej implementerad.",
@@ -64,8 +62,6 @@
 
     'unsupportedGeometryType': "Stöd saknas för geometritypen: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition misslyckades: elementet med id ${elemId} kan placeras fel.",
-
     'filterEvaluateNotImplemented': "evaluering har ej implementerats för denna typ av filter."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/vi.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/vi.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/vi.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -22,8 +22,6 @@
 
     'Base Layer': "Lớp nền",
 
-    'sameProjection': "Bản đồ toàn cảnh chỉ hoạt động khi cùng phép chiếu với bản đồ chính",
-
     'readNotImplemented': "Chưa hỗ trợ chức năng đọc.",
 
     'writeNotImplemented': "Chưa hỗ trợ chức năng viết.",
@@ -72,8 +70,6 @@
 
     'unsupportedGeometryType': "Không hỗ trợ kiểu địa lý: ${geomType}",
 
-    'pagePositionFailed': "OpenLayers.Util.pagePosition bị thất bại: nguyên tố với ID ${elemId} có thể ở chỗ sai.",
-
     'filterEvaluateNotImplemented': "chưa hỗ trợ evaluate cho loại bộ lọc này."
 
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/zh-CN.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/zh-CN.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/zh-CN.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -18,9 +18,6 @@
 
     'Base Layer': "基础图层",
 
-    'sameProjection':
-        "鹰眼地图只有在和主地图使用相同的投影的时候才能正常共工作",
-
     'readNotImplemented': "读取功能没有实现。",
 
     'writeNotImplemented': "写入功能没有实现。",
@@ -108,9 +105,5 @@
     // console message
     'unsupportedGeometryType': "不支持的几何体类型: ${geomType}",
 
-    // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition 失败:id 为 ${elemId} 的元素可能被错置。",
-                    
     'end': ''
 };

Modified: sandbox/august/trunk/lib/OpenLayers/Lang/zh-TW.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Lang/zh-TW.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Lang/zh-TW.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -19,9 +19,6 @@
 
     'Base Layer': "基礎圖層",
 
-    'sameProjection':
-        "地圖縮覽(OverviewMap)只能在跟主地圖相同投影時起作用。",
-
     'readNotImplemented': "沒有實作讀取的功能。",
 
     'writeNotImplemented': "沒有實作寫入的功能。",
@@ -109,9 +106,5 @@
     // console message
     'unsupportedGeometryType': "未支援的幾何型別: ${geomType}。",
 
-    // console message
-    'pagePositionFailed':
-        "OpenLayers.Util.pagePosition 失敗: id ${elemId} 的 element 可能被錯置。",
-                    
     'end': ''
 };

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/ArcGIS93Rest.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/ArcGIS93Rest.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/ArcGIS93Rest.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -91,17 +91,7 @@
         }
     },    
 
-    
     /**
-     * Method: destroy
-     * Destroy this layer
-     */
-    destroy: function() {
-        // for now, nothing special to do here. 
-        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);  
-    },   
-    
-    /**
          * Method: clone
          * Create a clone of this layer
          *

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/ArcGISCache.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/ArcGISCache.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/ArcGISCache.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,5 +1,5 @@
 /** 
- * @requires OpenLayers/Layer/XYZ.js 
+ * @requires OpenLayers/Layer/XYZ.js
  */ 
 
 /** 
@@ -172,21 +172,23 @@
                 
                 this.lods = [];
                 for(var key in info.tileInfo.lods) {
-                    var lod = info.tileInfo.lods[key];
-                    if (this.useScales) {
-                        this.scales.push(lod.scale);
-                    } else {
-                        this.resolutions.push(lod.resolution);
-                    }
+                    if (info.tileInfo.lods.hasOwnProperty(key)) {
+                        var lod = info.tileInfo.lods[key];
+                        if (this.useScales) {
+                            this.scales.push(lod.scale);
+                        } else {
+                            this.resolutions.push(lod.resolution);
+                        }
                     
-                    var start = this.getContainingTileCoords(upperLeft, lod.resolution);
-                    lod.startTileCol = start.x;
-                    lod.startTileRow = start.y;
+                        var start = this.getContainingTileCoords(upperLeft, lod.resolution);
+                        lod.startTileCol = start.x;
+                        lod.startTileRow = start.y;
                     
-                    var end = this.getContainingTileCoords(bottomRight, lod.resolution);
-                    lod.endTileCol = end.x;
-                    lod.endTileRow = end.y;    
-                    this.lods.push(lod);
+                        var end = this.getContainingTileCoords(bottomRight, lod.resolution);
+                        lod.endTileCol = end.x;
+                        lod.endTileRow = end.y;    
+                        this.lods.push(lod);
+                    }
                 }
 
                 this.maxExtent = this.calculateMaxExtentWithLOD(this.lods[0]);

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/ArcIMS.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/ArcIMS.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/ArcIMS.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -149,18 +149,7 @@
         }
     },    
 
-    
     /**
-     * Method: destroy
-     * Destroy this layer
-     */
-    destroy: function() {
-        // for now, nothing special to do here. 
-        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);  
-    },   
-    
-    
-    /**
      * Method: getURL
      * Return an image url this layer.
      *

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Bing.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Bing.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Bing.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -159,7 +159,7 @@
      */
     getURL: function(bounds) {
         if (!this.url) {
-            return OpenLayers.Util.getImagesLocation() + "blank.gif";
+            return;
         }
         var xyz = this.getXYZ(bounds), x = xyz.x, y = xyz.y, z = xyz.z;
         var quadDigits = [];

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Google/v3.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Google/v3.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Google/v3.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -203,7 +203,7 @@
      */
     setGMapVisibility: function(visible) {
         var cache = OpenLayers.Layer.Google.cache[this.map.id];
-        if (cache && !cache.resized) {
+        if (cache) {
             var type = this.type;
             var layers = this.map.layers;
             var layer;

Deleted: sandbox/august/trunk/lib/OpenLayers/Layer/GoogleNG.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/GoogleNG.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/GoogleNG.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,336 +0,0 @@
-/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for 
- * full list of contributors). Published under the Clear BSD license.  
- * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
-/**
- * @requires OpenLayers/Layer/XYZ.js
- * @requires OpenLayers/Tile/Google.js
- * @requires OpenLayers/Layer/SphericalMercator.js
- */
-
-/** 
- * Class: OpenLayers.Layer.GoogleNG
- * Google layer using <OpenLayers.Tile.Google> tiles.
- * 
- * Inherits from:
- *  - <OpenLayers.Layer.XYZ>
- */
-OpenLayers.Layer.GoogleNG = OpenLayers.Class(OpenLayers.Layer.XYZ, {
-
-    /**
-     * Property: SUPPORTED_TRANSITIONS
-     * {Array} An immutable (that means don't change it!) list of supported 
-     *     transitionEffect values. This layer type supports none.
-     */
-    SUPPORTED_TRANSITIONS: [],
-    
-    /**
-     * Property: serverResolutions
-     * {Array} the resolutions provided by the Google API.
-     */
-    serverResolutions: [
-        156543.03390625, 78271.516953125, 39135.7584765625,
-        19567.87923828125, 9783.939619140625, 4891.9698095703125,
-        2445.9849047851562, 1222.9924523925781, 611.4962261962891,
-        305.74811309814453, 152.87405654907226, 76.43702827453613,
-        38.218514137268066, 19.109257068634033, 9.554628534317017,
-        4.777314267158508, 2.388657133579254, 1.194328566789627,
-        0.5971642833948135, 0.29858214169740677, 0.14929107084870338,
-        0.07464553542435169, 0.037322767712175846
-    ],
-    
-    /**
-     * Property: attributionTemplate
-     * {String}
-     */
-    attributionTemplate: '<span class="olGoogleAttribution ${mapType}">' +
-         '<div><a title="Click to see this area on Google Maps" ' + 
-         'target="_blank" href="http://maps.google.com/maps?' +
-         'll=${center}&z=${zoom}&t=${t}"><img width="62" height="24" ' +
-         'src="http://maps.gstatic.com/mapfiles/google_white.png"/></a>' +
-         '</div>${mapData}<a style="white-space: nowrap" target="_blank" ' +
-         'href="http://www.google.com/help/terms_maps.html">' +
-         'Terms of Use</a></span>',
-    
-    /**
-     * Property: mapTypes
-     * {Object} mapping of {google.maps.MapTypeId} to the t param of
-     * http://maps.google.com/maps? permalinks
-     */
-    mapTypes: {
-        "roadmap": "m",
-        "satellite": "k",
-        "hybrid": "h",
-        "terrain": "p"
-    },
-    
-    /**
-     * APIProperty: type
-     * {google.maps.MapTypeId} See
-     * http://code.google.com/apis/maps/documentation/javascript/reference.html#MapTypeId
-     */
-    type: null,
-    
-    /**
-     * Constructor: OpenLayers.Layer.GoogleNG
-     * Create a new GoogleNG layer. Requires the GMaps v3 JavaScript API script
-     * (http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false) loaded in
-     * the html document. Note: Terms of Service compliant use requires the map
-     * to be configured with an <OpenLayers.Control.Attribution> control and
-     * the attribution placed on the map.
-     *
-     * Example:
-     * (code)
-     * var terrain = new OpenLayers.Layer.GoogleNG({
-     *     name: "Google Terrain",
-     *     type: google.maps.MapTypeId.TERRAIN
-     * });
-     * (end)
-     *
-     * Parameters:
-     * options - {Object} Configuration properties for the layer.
-     *
-     * Required configuration properties:
-     * type - {google.maps.MapTypeId} The layer identifier.  See
-     *     http://code.google.com/apis/maps/documentation/javascript/reference.html#MapTypeId
-     *     for valid types.
-     *
-     * Any other documented layer properties can be provided in the config object.
-     */
-    initialize: function(options) {
-        options = OpenLayers.Util.applyDefaults({
-            sphericalMercator: true
-        }, options);
-
-        if (!options.type) {
-            options.type = google.maps.MapTypeId.ROADMAP;
-        }
-        var newArgs = [options.name, null, options];
-        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);
-        
-        if (!OpenLayers.Layer.GoogleNG.mapObject) {
-            OpenLayers.Layer.GoogleNG.mapObject =
-                new google.maps.Map(document.createElement("div"));
-        }
-        if (OpenLayers.Layer.GoogleNG.mapObject.mapTypes[this.type]) {
-            this.initLayer();
-        } else {
-            google.maps.event.addListenerOnce(
-                OpenLayers.Layer.GoogleNG.mapObject, 
-                "idle", 
-                OpenLayers.Function.bind(this.initLayer, this)
-            );
-        }
-    },
-
-    /**
-     * Method: initLayer
-     *
-     * Sets layer properties according to the metadata provided by the API
-     */
-    initLayer: function() {
-        var mapType = OpenLayers.Layer.GoogleNG.mapObject.mapTypes[this.type];
-        if (!this.name) {
-            this.setName("Google " + mapType.name);
-        }
-        
-        var minZoom = mapType.minZoom || 0;
-        this.addOptions({
-            maxResolution: Math.min(
-                this.serverResolutions[minZoom], this.maxResolution
-            ),
-            zoomOffset: minZoom,
-            numZoomLevels: Math.min(
-                mapType.maxZoom + 1 - minZoom, this.numZoomLevels
-            )
-        }, true);
-    },
-
-    /**
-     * Method: addTile
-     * Create a tile, initialize it, and add it to the layer div. 
-     *
-     * Parameters
-     * bounds - {<OpenLayers.Bounds>}
-     * position - {<OpenLayers.Pixel>}
-     *
-     * Returns:
-     * {<OpenLayers.Tile.Google>} The added OpenLayers.Tile.Google
-     */
-    addTile:function(bounds, position) {
-        return new OpenLayers.Tile.Google(
-            this, position, bounds, this.tileOptions
-        );
-    },
-    
-    /**
-     * Method: updateAttribution
-     * Updates the attribution using the <attributionTemplate>
-     *
-     * Parameters:
-     * copyrights - {Object} Object with "m", "k", "h" and "p" properties (see
-     *     <mapTypes>), each holding an array of copyrights.
-     */
-    updateAttribution: function(copyrights) {
-        var myCopyrights;
-        if (this.type == google.maps.MapTypeId.HYBRID) {
-            // the Copyright Service returns "k" and "m" copyrights for the
-            // HYBRID layer type.
-            var candidates = [].concat(
-                copyrights["h"], copyrights["k"], copyrights["m"]
-            );
-            myCopyrights = [];
-            for (var i=candidates.length-1; i>=0; --i) {
-                if (OpenLayers.Util.indexOf(candidates, myCopyrights) == -1) {
-                    myCopyrights.push(candidates[i]);
-                }
-            }
-        } else {
-            myCopyrights = copyrights[this.mapTypes[this.type]];
-        }
-        var mapData = myCopyrights.length == 0 ? "" :
-            "Map Data &copy;" + new Date().getFullYear() + " " +
-            myCopyrights.join(", ") + " - ";
-        var center = this.map.getCenter();
-        center && center.transform(
-            this.map.getProjectionObject(),
-            new OpenLayers.Projection("EPSG:4326")
-        );
-        var size = this.map.getSize();
-        this.attribution = OpenLayers.String.format(this.attributionTemplate, {
-            t: this.mapTypes[this.type],
-            zoom: this.map.getZoom(),
-            center: center.lat + "," + center.lon,
-            mapType: this.type,
-            mapData: mapData
-        });
-        this.map && this.map.events.triggerEvent("changelayer", {
-            layer: this,
-            property: "attribution"
-        });
-    },
-    
-    /**
-     * Method: setMap
-     */
-    setMap: function() {
-        OpenLayers.Layer.XYZ.prototype.setMap.apply(this, arguments);
-        this.events.register("moveend", this,
-            OpenLayers.Layer.GoogleNG.loadCopyrights
-        );
-    },
-    
-    /**
-     * Method: removeMap
-     */
-    removeMap: function() {
-        OpenLayers.Layer.XYZ.prototype.removeMap.apply(this, arguments);
-        this.events.unregister("moveend", this,
-            OpenLayers.Layer.GoogleNG.loadCopyrights
-        );
-    },
-        
-    /**
-     * APIMethod: clone
-     * 
-     * Parameters:
-     * obj - {Object}
-     * 
-     * Returns:
-     * {<OpenLayers.Layer.GoogleNG>} An exact clone of this
-     * <OpenLayers.Layer.GoogleNG>
-     */
-    clone: function(obj) {
-        if (obj == null) {
-            obj = new OpenLayers.Layer.GoogleNG(this.options);
-        }
-        //get all additions from superclasses
-        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
-        // copy/set any non-init, non-simple values here
-        return obj;
-    },
-    
-    CLASS_NAME: "OpenLayers.Layer.GoogleNG"
-});
-
-/**
- * Property: mapObject
- * {google.maps.Map} Shared GMaps instance - will be set upon instantiation of
- * the 1st GoogleNG layer
- */
-OpenLayers.Layer.GoogleNG.mapObject = null;
-
-/**
- * Function: loadCopyrights
- * Using the Google Maps Copyright Service mode (see
- * http://mapki.com/wiki/Google_Map_Parameters#Misc) to get the attribution for
- * the current map extent. Will be called by each GoogleNG layer instance on
- * moveend. 
- */
-OpenLayers.Layer.GoogleNG.loadCopyrights = function() {
-    var me = OpenLayers.Layer.GoogleNG.loadCopyrights;
-    if (me.numLoadingScripts == undefined) {
-        me.loadingScripts = [];
-        me.numLoadingScripts = 0;
-        me.copyrights = {"m": [], "k": [], "h": [], "p": []};
-        
-        // store window scope functions before overwriting them
-        me.origGAddCopyright = window.GAddCopyright;
-        me.origGVerify = window.GVerify;
-        me.origGAppFeatures = window.GAppFeatures;
-        
-        // defining window scope functions called by the script that the
-        // Copyright Service returns
-        window.GAddCopyright = function() {
-            var copyright = arguments[7];
-            var category = me.copyrights[arguments[0]];
-            if (OpenLayers.Util.indexOf(category, copyright) == -1) {
-                copyright && category.push(copyright);
-            }
-        };
-        window.GVerify = OpenLayers.Function.True;
-        window.GAppFeatures = OpenLayers.Function.bind(function() {
-            me.numLoadingScripts--;
-            if (me.numLoadingScripts == 0) {
-                var script;
-                for (var i=me.loadingScripts.length-1; i>=0; --i) {
-                    script = me.loadingScripts[i][0];
-                    me.loadingScripts[i][1].updateAttribution(me.copyrights);
-                    script.parentNode.removeChild(script);
-                }
-                
-                // restore original functions
-                window.GAddCopyright = me.origGAddCopyright;
-                delete me.origGAddCopyright;
-                window.GVerify = me.origGVerify;
-                delete me.origGVerify;
-                window.GAppFeatures = me.origGAppFeatures;
-                delete me.origGAppFeatures;
-                
-                delete me.loadingScripts;
-                delete me.numLoadingScripts;
-                delete me.copyrights;
-            }
-        }, this);
-    }
-    var mapProj = this.map.getProjectionObject();
-    var llProj = new OpenLayers.Projection("EPSG:4326");
-    var center = this.map.getCenter().transform(mapProj, llProj);
-    var extent = this.map.getExtent().transform(mapProj, llProj);
-    var params = {
-        spn: extent.getHeight() + "," + extent.getWidth(),
-        z: this.map.getZoom(),
-        t: this.mapTypes[this.type],
-        vp: center.lat + "," + center.lon
-    };
-    var url = "http://maps.google.com/maps?" +
-        OpenLayers.Util.getParameterString(params);
-    var script = document.createElement("script");
-    script.type = "text/javascript";
-    script.src = url;
-    me.numLoadingScripts++;
-    me.loadingScripts.push([script, this]);
-    document.getElementsByTagName("head")[0].appendChild(script);
-};
-

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Grid.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Grid.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Grid.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -7,6 +7,7 @@
 /**
  * @requires OpenLayers/Layer/HTTPRequest.js
  * @requires OpenLayers/Console.js
+ * @requires OpenLayers/Tile/Image.js
  */
 
 /**

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/HTTPRequest.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/HTTPRequest.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/HTTPRequest.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -58,9 +58,7 @@
      * options - {Object} Hashtable of extra options to tag onto the layer
      */
     initialize: function(name, url, params, options) {
-        var newArguments = arguments;
-        newArguments = [name, options];
-        OpenLayers.Layer.prototype.initialize.apply(this, newArguments);
+        OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);
         this.url = url;
         this.params = OpenLayers.Util.extend( {}, params);
     },

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Markers.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Markers.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Markers.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -104,7 +104,7 @@
     addMarker: function(marker) {
         this.markers.push(marker);
 
-        if (this.opacity != null) {
+        if (this.opacity < 1) {
             marker.setOpacity(this.opacity);
         }
 

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/TMS.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/TMS.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/TMS.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -123,15 +123,6 @@
     },    
 
     /**
-     * APIMethod:destroy
-     */
-    destroy: function() {
-        // for now, nothing special to do here. 
-        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);  
-    },
-
-    
-    /**
      * APIMethod: clone
      * Create a complete copy of this layer.
      *

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Vector/RootContainer.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Vector/RootContainer.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Vector/RootContainer.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -50,9 +50,6 @@
      * {<OpenLayers.Layer.Vector.RootContainer>} A new vector layer root
      *     container
      */
-    initialize: function(name, options) {
-        OpenLayers.Layer.Vector.prototype.initialize.apply(this, arguments);
-    },
     
     /**
      * Method: display

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/Vector.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/Vector.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/Vector.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -24,9 +24,7 @@
 OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * layer.events.register(type, obj, listener);
      * (end)
@@ -111,13 +109,6 @@
      * refresh - Triggered when something wants a strategy to ask the protocol
      *      for a new set of features.
      */
-    EVENT_TYPES: ["beforefeatureadded", "beforefeaturesadded",
-                  "featureadded", "featuresadded", "beforefeatureremoved",
-                  "beforefeaturesremoved", "featureremoved", "featuresremoved",
-                  "beforefeatureselected", "featureselected", "featureunselected", 
-                  "beforefeaturemodified", "featuremodified", "afterfeaturemodified",
-                  "vertexmodified", "vertexremoved", "sketchstarted",
-                  "sketchmodified", "sketchcomplete", "refresh"],
 
     /**
      * APIProperty: isBaseLayer
@@ -240,13 +231,6 @@
      * {<OpenLayers.Layer.Vector>} A new vector layer
      */
     initialize: function(name, options) {
-        
-        // concatenate events specific to vector with those from the base
-        this.EVENT_TYPES =
-            OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(
-            OpenLayers.Layer.prototype.EVENT_TYPES
-        );
-
         OpenLayers.Layer.prototype.initialize.apply(this, arguments);
 
         // allow user-set renderer, otherwise assign one
@@ -597,7 +581,7 @@
                 if(this.events.triggerEvent("beforefeatureadded",
                                             {feature: feature}) === false) {
                     continue;
-                };
+                }
                 this.preFeatureInsert(feature);
             }
 
@@ -816,7 +800,7 @@
             this.unrenderedFeatures[feature.id] = feature;
         } else {
             delete this.unrenderedFeatures[feature.id];
-        };
+        }
     },
     
     /**
@@ -988,17 +972,20 @@
      * Calculates the max extent which includes all of the features.
      * 
      * Returns:
-     * {<OpenLayers.Bounds>}
+     * {<OpenLayers.Bounds>} or null if the layer has no features with
+     * geometries.
      */
     getDataExtent: function () {
         var maxExtent = null;
         var features = this.features;
         if(features && (features.length > 0)) {
-            maxExtent = new OpenLayers.Bounds();
             var geometry = null;
             for(var i=0, len=features.length; i<len; i++) {
                 geometry = features[i].geometry;
                 if (geometry) {
+                    if (maxExtent === null) {
+                        maxExtent = new OpenLayers.Bounds();
+                    }
                     maxExtent.extend(geometry.getBounds());
                 }
             }

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/WMS.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/WMS.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/WMS.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -153,16 +153,6 @@
     },    
 
     /**
-     * Method: destroy
-     * Destroy this layer
-     */
-    destroy: function() {
-        // for now, nothing special to do here. 
-        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);  
-    },
-
-    
-    /**
      * Method: clone
      * Create a clone of this layer
      *

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/WorldWind.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/WorldWind.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/WorldWind.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -21,20 +21,19 @@
 
     /**
      * APIProperty: isBaseLayer
-     * WorldWind layer is a base layer by default.
+     * {Boolean} WorldWind layer is a base layer by default.
      */
-    isBaseLayer: true,    
+    isBaseLayer: true,
 
-    
     /** 
      * APIProperty: lzd
-     * LevelZeroTileSizeDegrees
+     * {Float} LevelZeroTileSizeDegrees
      */
     lzd: null,
 
     /**
      * APIProperty: zoomLevels
-     * Number of zoom levels.
+     * {Integer} Number of zoom levels.
      */
     zoomLevels: null,
     
@@ -45,7 +44,7 @@
      * name - {String} Name of Layer
      * url - {String} Base URL  
      * lzd - {Float} Level zero tile size degrees 
-     * zoomLevels - {Int} number of zoom levels
+     * zoomLevels - {Integer} number of zoom levels
      * params - {Object} additional parameters
      * options - {Object} additional options
      */

Modified: sandbox/august/trunk/lib/OpenLayers/Layer/XYZ.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer/XYZ.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer/XYZ.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -144,8 +144,9 @@
             (res * this.tileSize.w));
         var y = Math.round((this.maxExtent.top - bounds.top) /
             (res * this.tileSize.h));
-        var z = this.serverResolutions != null ?
-            OpenLayers.Util.indexOf(this.serverResolutions, res) :
+        var resolutions = this.serverResolutions || this.resolutions;
+        var z = this.zoomOffset == 0 ?
+            OpenLayers.Util.indexOf(resolutions, res) :
             this.map.getZoom() + this.zoomOffset;
 
         var limit = Math.pow(2, z);

Modified: sandbox/august/trunk/lib/OpenLayers/Layer.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Layer.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Layer.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -35,9 +35,10 @@
 
     /**
      * Property: opacity
-     * {Float} The layer's opacity. Float number between 0.0 and 1.0.
+     * {Float} The layer's opacity. Float number between 0.0 and 1.0. Default
+     * is 1.
      */
-    opacity: null,
+    opacity: 1,
 
     /**
      * APIProperty: alwaysInRange
@@ -57,9 +58,7 @@
     alwaysInRange: null,   
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * layer.events.register(type, obj, listener);
      * (end)
@@ -88,8 +87,6 @@
      *     will receive an object with a *map* property referencing the map and
      *     a *layer* property referencing the layer.
      */
-    EVENT_TYPES: ["loadstart", "loadend", "loadcancel", "visibilitychanged",
-                  "move", "moveend", "added", "removed"],
 
     /**
      * Constant: RESOLUTION_PROPERTIES
@@ -350,8 +347,7 @@
             this.div.style.height = "100%";
             this.div.dir = "ltr";
 
-            this.events = new OpenLayers.Events(this, this.div, 
-                                                this.EVENT_TYPES);
+            this.events = new OpenLayers.Events(this, this.div);
             if(this.eventListeners instanceof Object) {
                 this.events.on(this.eventListeners);
             }

Modified: sandbox/august/trunk/lib/OpenLayers/Map.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Map.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Map.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -36,9 +36,7 @@
     },
 
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * map.events.register(type, obj, listener);
      * (end)
@@ -85,13 +83,6 @@
      *  - *mousemove* triggered after mousemove the map
      *  - *changebaselayer* triggered after the base layer changes
      */
-    EVENT_TYPES: [ 
-        "preaddlayer", "addlayer","preremovelayer", "removelayer", 
-        "changelayer", "movestart",
-        "move", "moveend", "zoomend", "popupopen", "popupclose",
-        "addmarker", "removemarker", "clearmarkers", "mouseover",
-        "mouseout", "mousemove", "dragstart", "drag", "dragend",
-        "changebaselayer"],
 
     /**
      * Property: id
@@ -538,7 +529,7 @@
         this.viewPortDiv.appendChild(eventsDiv);
         this.eventsDiv = eventsDiv;
         this.events = new OpenLayers.Events(
-            this, this.eventsDiv, this.EVENT_TYPES, this.fallThrough, 
+            this, this.eventsDiv, null, this.fallThrough, 
             {includeXY: true}
         );
 
@@ -1722,7 +1713,8 @@
             var layer, i, len;
             for (i=0, len=this.layers.length; i<len; ++i) {
                 layer = this.layers[i];
-                if (layer.visibility) {
+                if (layer.visibility &&
+                    (layer === this.baseLayer || layer.inRange)) {
                     layer.moveByPx(dx, dy);
                     layer.events.triggerEvent("move");
                 }

Modified: sandbox/august/trunk/lib/OpenLayers/Marker/Box.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Marker/Box.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Marker/Box.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -40,7 +40,7 @@
         this.bounds = bounds;
         this.div    = OpenLayers.Util.createDiv();
         this.div.style.overflow = 'hidden';
-        this.events = new OpenLayers.Events(this, this.div, null);
+        this.events = new OpenLayers.Events(this, this.div);
         this.setBorder(borderColor, borderWidth);
     },
 

Modified: sandbox/august/trunk/lib/OpenLayers/Marker.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Marker.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Marker.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -80,7 +80,7 @@
             this.icon.offset = newIcon.offset;
             this.icon.calculateOffset = newIcon.calculateOffset;
         }
-        this.events = new OpenLayers.Events(this, this.icon.imageDiv, null);
+        this.events = new OpenLayers.Events(this, this.icon.imageDiv);
     },
     
     /**

Modified: sandbox/august/trunk/lib/OpenLayers/Popup/FramedCloud.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Popup/FramedCloud.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Popup/FramedCloud.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -223,12 +223,5 @@
         this.contentDiv.className = this.contentDisplayClass;
     },
 
-    /** 
-     * APIMethod: destroy
-     */
-    destroy: function() {
-        OpenLayers.Popup.Framed.prototype.destroy.apply(this, arguments);
-    },
-
     CLASS_NAME: "OpenLayers.Popup.FramedCloud"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Popup.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Popup.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Popup.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -888,6 +888,8 @@
             this.hide();
             OpenLayers.Event.stop(e);
         };
+        OpenLayers.Event.observe(this.closeDiv, "touchend", 
+                OpenLayers.Function.bindAsEventListener(closePopup, this));
         OpenLayers.Event.observe(this.closeDiv, "click", 
                 OpenLayers.Function.bindAsEventListener(closePopup, this));
     },
@@ -944,7 +946,8 @@
      *   Because the user might select the zoom-rectangle option and
      *    then drag it over a popup, we need a safe way to allow the
      *    mousemove and mouseup events to pass through the popup when
-     *    they are initiated from outside.
+     *    they are initiated from outside. The same procedure is needed for
+     *    touchmove and touchend events.
      * 
      *   Otherwise, we want to essentially kill the event propagation
      *    for all other events, though we have to do so carefully, 
@@ -954,6 +957,9 @@
      registerEvents:function() {
         this.events = new OpenLayers.Events(this, this.div, null, true);
 
+        function onTouchstart(evt) {
+            OpenLayers.Event.stop(evt, true);
+        }
         this.events.on({
             "mousedown": this.onmousedown,
             "mousemove": this.onmousemove,
@@ -961,6 +967,7 @@
             "click": this.onclick,
             "mouseout": this.onmouseout,
             "dblclick": this.ondblclick,
+            "touchstart": onTouchstart,
             scope: this
         });
         

Modified: sandbox/august/trunk/lib/OpenLayers/Protocol/HTTP.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/HTTP.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/HTTP.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -4,12 +4,7 @@
  * full text of the license. */
 
 /**
- * @requires OpenLayers/Console.js
  * @requires OpenLayers/Protocol.js
- * @requires OpenLayers/Feature/Vector.js
- * @requires OpenLayers/Filter/Spatial.js
- * @requires OpenLayers/Filter/Comparison.js
- * @requires OpenLayers/Filter/Logical.js
  * @requires OpenLayers/Request/XMLHttpRequest.js
  */
 
@@ -141,7 +136,7 @@
      * Optional method to translate an <OpenLayers.Filter> object into an object
      *     that can be serialized as request query string provided.  If a custom
      *     method is not provided, the filter will be serialized using the 
-     *     <OpenLayers.Protocol.simpleFilterSerializer> method.
+     *     <OpenLayers.Format.QueryStringFilter> class.
      *
      * Parameters:
      * filter - {<OpenLayers.Filter>} filter to convert.

Modified: sandbox/august/trunk/lib/OpenLayers/Protocol/Script.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/Script.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/Script.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -207,7 +207,7 @@
      */
     createRequest: function(url, params, callback) {
         var id = OpenLayers.Protocol.Script.register(callback);
-        var name = "OpenLayers.Protocol.Script.getCallback(" + id + ")";
+        var name = "OpenLayers.Protocol.Script.registry[" + id + "]";
         params = OpenLayers.Util.extend({}, params);
         params[this.callbackKey] = this.callbackPrefix + name;
         url = OpenLayers.Util.urlAppend(
@@ -328,7 +328,7 @@
 (function() {
     var o = OpenLayers.Protocol.Script;
     var counter = 0;
-    var registry = {};
+    o.registry = [];
     
     /**
      * Function: OpenLayers.Protocol.Script.register
@@ -344,7 +344,10 @@
      */
     o.register = function(callback) {
         var id = ++counter;
-        registry[id] = callback;
+        o.registry[id] = function() {
+            o.unregister(id);
+            callback.apply(this, arguments);
+        };
         return id;
     };
     
@@ -356,22 +359,6 @@
      * id: {Number} The identifer returned by the register function.
      */
     o.unregister = function(id) {
-        delete registry[id];
+        delete o.registry[id];
     };
-    
-    /**
-     * Function: OpenLayers.Protocol.Script.getCallback
-     * Retreive and unregister a callback.  A call to this function is the "P" 
-     * in JSONP.  For example, a script may be added with a src attribute 
-     * http://example.com/features.json?callback=OpenLayers.Protocol.Script.getCallback(1)
-     *
-     * Parameters:
-     * id: {Number} The identifer returned by the register function.
-     */
-    o.getCallback = function(id) {
-        var callback = registry[id];
-        o.unregister(id);
-        return callback;
-    };
 })();
-

Modified: sandbox/august/trunk/lib/OpenLayers/Protocol/WFS/v1.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/WFS/v1.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/WFS/v1.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -43,7 +43,7 @@
     /**
      * Property: geometryName
      * {String} Name of the geometry attribute for features.  Default is
-     *     "the_geom".
+     *     "the_geom" for WFS <version> 1.0, and null for higher versions.
      */
     geometryName: "the_geom",
     
@@ -102,19 +102,16 @@
      *     for this featureType).
      * featurePrefix - {String} Feature namespace alias (optional - only used
      *     for writing if featureNS is provided).  Default is 'feature'.
-     * geometryName - {String} Name of geometry attribute.  If featureNS is not
-     *     configured, the default is null to avoid failing on BBOX filters,
-     *     and it will be set on <read>. Otherwise, the default is 'the_geom'.
+     * geometryName - {String} Name of geometry attribute.  The default is
+     *     'the_geom' for WFS <version> 1.0, and null for higher versions. If
+     *     null, it will be set to the name of the first geometry found in the
+     *     first read operation.
      * multi - {Boolean} If set to true, geometries will be casted to Multi
      *     geometries before they are written in a transaction. No casting will
      *     be done when reading features.
      */
     initialize: function(options) {
         OpenLayers.Protocol.prototype.initialize.apply(this, [options]);
-        if (!options.geometryName && !options.featureNS) {
-            // poorly configured protocol - try to not fail on BBOX filters
-            this.geometryName = null;
-        }
         if(!options.format) {
             this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({
                 version: this.version,
@@ -126,6 +123,9 @@
                 schema: this.schema
             }, this.formatOptions));
         }
+        if (!options.geometryName && parseFloat(this.format.version) > 1.0) {
+            this.setGeometryName(null);
+        }
     },
     
     /**

Modified: sandbox/august/trunk/lib/OpenLayers/Protocol/WFS.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Protocol/WFS.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Protocol/WFS.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -47,7 +47,7 @@
  *     
  * This function is designed to auto-configure <url>, <featureType>,
  *     <featurePrefix> and <srsName> for WFS <version> 1.1.0. Note that
- *     srsName matching with the WMS layer will not work with WFS 1.0.0..
+ *     srsName matching with the WMS layer will not work with WFS 1.0.0.
  * 
  * Parameters:
  * layer - {<OpenLayers.Layer.WMS>} WMS layer that has a matching WFS

Modified: sandbox/august/trunk/lib/OpenLayers/Renderer/Canvas.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Renderer/Canvas.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Renderer/Canvas.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -140,8 +140,9 @@
         if (feature.geometry) {
             style = this.applyDefaultSymbolizer(style || feature.style);
             // don't render if display none or feature outside extent
-            rendered = (style.display !== "none") &&
-                feature.geometry.getBounds().intersectsBounds(this.extent);
+            var bounds = feature.geometry.getBounds();
+            rendered = (style.display !== "none") && !!bounds && 
+                bounds.intersectsBounds(this.extent);
             if (rendered) {
                 // keep track of what we have rendered for redraw
                 this.features[feature.id] = [feature, style];

Modified: sandbox/august/trunk/lib/OpenLayers/Request.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Request.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Request.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -57,7 +57,7 @@
      * success - Triggered when the HTTP response has a success code (200-299).
      * failure - Triggered when the HTTP response does not have a success code.
      */
-    events: new OpenLayers.Events(this, null, ["complete", "success", "failure"]),
+    events: new OpenLayers.Events(this),
     
     /**
      * APIMethod: issue

Modified: sandbox/august/trunk/lib/OpenLayers/Strategy/Save.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Strategy/Save.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Strategy/Save.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -20,19 +20,17 @@
 OpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, {
     
     /**
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types.  Register a listener
-     *     for a particular event with the following syntax:
+     * Register a listener for a particular event with the following syntax:
      * (code)
      * strategy.events.register(type, obj, listener);
      * (end)
      *
+     * Supported event types:
      *  - *start* Triggered before saving
      *  - *success* Triggered after a successful transaction
      *  - *fail* Triggered after a failed transaction
      *      
      */
-    EVENT_TYPES: ["start", "success", "fail"],
  
     /** 
      * Property: events
@@ -66,7 +64,7 @@
      */
     initialize: function(options) {
         OpenLayers.Strategy.prototype.initialize.apply(this, [options]);
-        this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
+        this.events = new OpenLayers.Events(this);
     },
    
     /**

Modified: sandbox/august/trunk/lib/OpenLayers/Test/AgsOgcRegression.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Test/AgsOgcRegression.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Test/AgsOgcRegression.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -272,10 +272,35 @@
 	        params: {},
 	        headers: {},
 	        data: postLockReqXmlStr
-	    });
-		
+	    });		
 	},
 
+	_run_wfst_post_without_locks: function(transactionReqId, transactionResUrl, t) {		
+		// send the transaction request
+		var postTransReqXmlStr = document.getElementById(transactionReqId).firstChild.nodeValue;		
+		var caller = this;										
+		OpenLayers.Request.POST({
+			url: this.url,
+			success: function(transResponse) {
+				OpenLayers.loadURL(
+					transactionResUrl,
+					null,
+					caller,
+					function(transReference) {					
+						t.html_eq(this._stripXmlDeclaration(transResponse.responseText), transReference.responseText, "...");								
+					}
+				);
+			},
+			failure: function(transResponse) {
+				t.ok(false, "......");
+			},
+			params: {},
+		    headers: {},
+		    data: postTransReqXmlStr			        
+		});
+			
+	},
+	
 	_stripXmlDeclaration: function(xmlStr) {
 		var idx_l = xmlStr.indexOf("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
 		var idx_u = xmlStr.indexOf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

Copied: sandbox/august/trunk/lib/OpenLayers/Tile/BackBufferable.js (from rev 12408, trunk/openlayers/lib/OpenLayers/Tile/BackBufferable.js)
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Tile/BackBufferable.js	                        (rev 0)
+++ sandbox/august/trunk/lib/OpenLayers/Tile/BackBufferable.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,201 @@
+/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+
+/**
+ * @requires OpenLayers/Tile.js
+ * @requires OpenLayers/Util.js
+ */
+
+/**
+ * Class: OpenLayers.Tile.BackBufferable
+ * Base class for tiles that can have backbuffers during transitions. Do not
+ * create instances of this class.
+ */
+OpenLayers.Tile.BackBufferable = OpenLayers.Class(OpenLayers.Tile, {
+    
+    /**
+     * Property: backBufferMode
+     * {Integer} Bitmap: 0 for no backbuffering at all, 1 for singleTile
+     * layers, 2 for transition effect set, 3 for both.
+     */
+    backBufferMode: null,
+    
+    /**
+     * Property: backBufferData
+     * {Object} Object including the necessary data for the back
+     * buffer.
+     *
+     * The object includes three properties:
+     * tile - {DOMElement} The DOM element for the back buffer.
+     * bounds - {<OpenLayers.Bounds>} The bounds of the tile to back.
+     * resolution - {Number} The resolution of the tile to back.
+     */
+    backBufferData: null,
+
+    /** 
+     * Method: initialize
+     * Determines the backBuffer mode and registers events
+     */   
+    initialize: function() {
+        OpenLayers.Tile.prototype.initialize.apply(this, arguments);
+        
+        var transitionSupported = OpenLayers.Util.indexOf(
+                                    this.layer.SUPPORTED_TRANSITIONS,
+                                    this.layer.transitionEffect) != -1;
+        this.backBufferMode = (this.layer.singleTile && 1) |
+                              (transitionSupported && 2);
+
+        this.backBufferData = {};
+        if (!this.size) {
+            this.size = new OpenLayers.Size(256, 256);
+        }
+    },
+    
+    /**
+     * Method: draw
+     * Check that a tile should be drawn, and draw it.
+     * 
+     * Returns:
+     * {Boolean} Was a tile drawn?
+     */
+    draw: function() {
+        var draw = OpenLayers.Tile.prototype.shouldDraw.apply(this, arguments),
+            backBufferMode = this.backBufferMode;
+        if (draw) {
+            this.updateBackBuffer();
+        }
+        this.clear();
+        if (!draw) {
+            this.resetBackBuffer();
+        };
+        return draw;
+    },
+    
+    /**
+     * Method: getTile
+     * Get the tile's markup. To be implemented by subclasses.
+     *
+     * Returns:
+     * {DOMElement} The tile's markup
+     */
+
+    /**
+     * Method: createBackBuffer
+     * Create a copy of this tile's markup for the back buffer. To be
+     * implemented by subclasses.
+     *
+     * Returns:
+     * {DOMElement} A copy of the tile's markup.
+     */
+    
+    /**
+     * Method: setBackBufferData
+     * Stores the current bounds and resolution, for offset and ratio
+     * calculations
+     */
+    setBackBufferData: function() {
+        this.backBufferData = OpenLayers.Util.extend(this.backBufferData, {
+            bounds: this.bounds,
+            resolution: this.layer.map.getResolution()
+        });
+    },
+    
+    /**
+     * Method: updateBackBuffer
+     * Update the <backBufferData>, and return a new or reposition the
+     * backBuffer. When a backbuffer is returned, the tile's markup is not
+     * available any more.
+     *
+     * Returns:
+     * {HTMLDivElement} the tile's markup in a cloned element, or undefined if
+     *     no backbuffer is currently available or needed
+     */
+    updateBackBuffer: function() {
+        var layer = this.layer, map = layer.map,
+            backBufferMode = this.backBufferMode,
+            data = this.backBufferData,
+            tile = this.getTile(),
+            backBuffer = data.tile,
+            resolution = data.resolution,
+            ratio = resolution ? resolution / map.getResolution() : 1,
+            
+        // Cases where we don't position and return a back buffer, but only
+        // update backBufferData and return undefined:
+            // (1) current ratio and backBufferMode dont't require a backbuffer
+            notNeeded = !(ratio == 1 ? backBufferMode & 1 : backBufferMode & 2),
+            // (2) the tile is not appended to the layer's div
+            noParent = tile && tile.parentNode !== layer.div,
+            // (3) we don't have a tile available that we could use as buffer
+            noTile = !(tile && tile.childNodes.length > 0),
+            // (4) no backbuffer is displayed for a tile that's still loading
+            noBackBuffer = !backBuffer && this.isLoading;            
+        if (notNeeded || noParent || noTile || noBackBuffer) {
+            this.setBackBufferData();
+            return;
+        }
+
+        // Create a back buffer tile and add it to the DOM
+        if (!backBuffer) {
+            backBuffer = this.createBackBuffer();
+            // some browsers fire the onload event before the image is
+            // displayed, so we keep the buffer until the whole layer finished
+            // loading to avoid visual glitches
+            layer.events.register("loadend", this, this.resetBackBuffer);
+            data.tile = backBuffer;
+            layer.div.insertBefore(backBuffer, tile);
+        }
+
+        // Position the back buffer now that we have one
+        var lonLat = {lon: data.bounds.left, lat: data.bounds.top},
+            position = map.getPixelFromLonLat(lonLat),
+            containerStyle = map.layerContainerDiv.style,
+            leftOffset = parseInt(containerStyle.left, 10),
+            topOffset = parseInt(containerStyle.top, 10),
+            style = backBuffer.style;
+        style.left = (position.x - leftOffset) + "px";
+        style.top = (position.y - topOffset) + "px";
+        style.width = (this.size.w * ratio) + "px";
+        style.height = (this.size.h * ratio) + "px";        
+
+        return backBuffer;
+    },
+    
+    /**
+     * Method: resetBackBuffer
+     * Handler for the layer's loadend event.
+     */
+    resetBackBuffer: function() {
+        this.layer.events.unregister("loadend", this, this.resetBackBuffer);
+        this.removeBackBuffer();
+        this.setBackBufferData();
+    },
+    
+    /**
+     * Method: removeBackBuffer
+     * Removes the backBuffer for this tile.
+     */
+    removeBackBuffer: function() {
+        var backBufferData = this.backBufferData;
+        var backBuffer = backBufferData.tile;
+        delete backBufferData.tile;
+        var parent = backBuffer && backBuffer.parentNode;
+        if (backBuffer) {
+            parent.removeChild(backBuffer);
+        }
+    },
+    
+    /** 
+     * APIMethod: destroy
+     * nullify references to prevent circular references and memory leaks
+     */
+    destroy: function() {
+        this.removeBackBuffer();
+        this.layer.events.unregister("loadend", this, this.resetBackBuffer);
+        this.backBufferData = null;
+        OpenLayers.Tile.prototype.destroy.apply(this, arguments);
+    }
+        
+});

Deleted: sandbox/august/trunk/lib/OpenLayers/Tile/Google.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Tile/Google.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Tile/Google.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,154 +0,0 @@
-/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for 
- * full list of contributors). Published under the Clear BSD license.  
- * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
-
-/*
- * @requires OpenLayers/BaseTypes/Class.js
- * @requires OpenLayers/Util.js
- * @requires OpenLayers/Tile.js
- */
-
-/*
- * Class: OpenLayers.Tile.Google
- * Instances of OpenLayers.Tile.Google are used to manage the tiles created
- * by google.maps.MapType (see
- * http://code.google.com/apis/maps/documentation/javascript/reference.html#MapType).
- *
- * Inherits from:
- *  - <OpenLayers.Tile>
- */
-OpenLayers.Tile.Google = OpenLayers.Class(OpenLayers.Tile, {
-    
-    /**
-     * Property: node
-     * {DOMElement} The tile node from the MapType's getTile method
-     */
-    node: null,
-        
-    /** 
-     * Constructor: OpenLayers.Tile.Google
-     * Constructor for a new <OpenLayers.Tile.Google> instance.
-     * 
-     * Parameters:
-     * layer - {<OpenLayers.Layer>} layer that the tile will go in.
-     * position - {<OpenLayers.Pixel>}
-     * bounds - {<OpenLayers.Bounds>}
-     * options - {Object}
-     */   
-    initialize: function(layer, position, bounds, options) {
-        OpenLayers.Tile.prototype.initialize.apply(this, [
-            layer, position, bounds, null, null, options
-        ]);
-    },
-
-    /** 
-     * APIMethod: destroy
-     * Nullify references to prevent circular references and memory leaks.
-     */
-    destroy:function() {
-        this.node && this.clear();
-        this.node = null;
-        OpenLayers.Tile.prototype.destroy.apply(this, arguments);
-    },
-    
-    /**
-     * Method: clone
-     *
-     * Parameters:
-     * obj - {<OpenLayers.Tile>} The tile to be cloned
-     *
-     * Returns:
-     * {<OpenLayers.Tile>} An exact clone of this <OpenLayers.Tile.Google>
-     */
-    clone: function (obj) {
-        if (obj == null) {
-            obj = new OpenLayers.Tile.Google(this.layer, 
-                                      this.position, 
-                                      this.bounds);
-        } 
-        
-        // catch any randomly tagged-on properties
-        OpenLayers.Util.applyDefaults(obj, this);
-        
-        obj.node = null;
-        
-        return obj;
-    },
-
-    /**
-     * Method: draw
-     * Check that a tile should be drawn, and draw it.
-     * 
-     * Returns:
-     * {Boolean} Always returns true.
-     */
-    draw: function() {
-        var layerType = OpenLayers.Layer.GoogleNG.mapObject.mapTypes[
-            this.layer.type
-        ];
-        if (layerType && OpenLayers.Tile.prototype.draw.apply(this, arguments)) {
-            var xyz = this.layer.getXYZ(this.bounds);
-            var point = new google.maps.Point(xyz.x, xyz.y);
-
-            // The hybrid tile consists of two images. For some reason, we have
-            // to make sure that the satellite image loads first, otherwise we
-            // occasionally get blank tiles for one of the two images. This is
-            // done by requesting the tile for just the satellite mapType
-            // first, before requesting the hybrid one.
-            //TODO revisit this - it may be a temporary issue with GMaps
-            var tempTile;
-            if (this.layer.type === google.maps.MapTypeId.HYBRID) {
-                tempTile = layerType.getTile(point, xyz.z, document);
-            }
-            
-            this.node = layerType.getTile(point, xyz.z, document);
-                        
-            this.isLoading = true;
-            this.events.triggerEvent("loadstart");
-
-            this.layer.div.appendChild(this.node);
-            
-            // We only modify what we need to - we expect the size to be set
-            // by getTile, and we have a test that will fail if this changes.
-            OpenLayers.Util.modifyDOMElement(
-                this.node, null, this.position, null, "absolute"
-            );  
-            
-            // The images inside the node returned from getTile seem to be
-            // preloaded already, so registering onload events on these images
-            // won't work. Instead, we trigger the loadend event immediately
-            // in the next cycle.
-            window.setTimeout(OpenLayers.Function.bind(function() {
-                this.isLoading = false;
-                // check for this.events - we may be destroyed already
-                this.events && this.events.triggerEvent("loadend"); 
-
-                // see hybrid tile issue above
-                //TODO revisit this - it may be a temporary issue with GMaps
-                if (tempTile) {
-                    layerType.releaseTile(tempTile);
-                }
-            }, this), 0);
-        }
-        return true;
-    },
-    
-    /** 
-     * Method: clear
-     * Clear the tile of any bounds/position-related data so that it can 
-     *     be reused in a new location. To be implemented by subclasses.
-     */
-    clear: function() {
-        if (this.node) {
-            this.node.parentNode &&
-                this.node.parentNode.removeChild(this.node);
-            OpenLayers.Layer.GoogleNG.mapObject.mapTypes[
-                this.layer.type
-            ].releaseTile(this.node);
-        }
-    },
-    
-    CLASS_NAME: "OpenLayers.Tile.Google"
-});

Modified: sandbox/august/trunk/lib/OpenLayers/Tile/Image/IFrame.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Tile/Image/IFrame.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Tile/Image/IFrame.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -14,14 +14,13 @@
  * remote services. Images will be loaded using HTTP-POST into an IFrame.
  *
  * This mixin will be applied to <OpenLayers.Tile.Image> instances
- * configured with <OpenLayers.Tile.Image.allowPost> or
- * <OpenLayers.Tile.Image.enforcePost> set to true.
+ * configured with <OpenLayers.Tile.Image.maxGetUrlLength> set.
  *
  * Inherits from:
  *  - <OpenLayers.Tile.Image>
  */
 OpenLayers.Tile.Image.IFrame = {
-    
+
     /**
      * Property: useIFrame
      * {Boolean} true if we are currently using an IFrame to render POST
@@ -30,159 +29,103 @@
     useIFrame: null,
 
     /**
-     * Method: clear
-     * Removes the iframe from DOM (avoids back-button problems).
+    * Method: updateBackBuffer
+    * Update the <backBufferData>, and return a new or reposition the
+    * backBuffer. When a backbuffer is returned, the tile's markup is not
+    * available any more.
+    *
+    * Returns:
+    * {HTMLDivElement} the tile's markup in a cloned element, or undefined if
+    *     no backbuffer is currently available or needed
      */
-    clear: function() {
-        if (this.useIFrame) {
-            if (this.imgDiv) {
-                var iFrame = this.imgDiv.firstChild;
-                OpenLayers.Event.stopObservingElement(iFrame);
-                this.imgDiv.removeChild(iFrame);
-                delete iFrame;
+    updateBackBuffer: function() {
+        this.url = this.layer.getURL(this.bounds);
+        var usedIFrame = this.useIFrame;
+        this.useIFrame = this.maxGetUrlLength !== null && !this.layer.async &&
+            this.url.length > this.maxGetUrlLength;
+        var fromIFrame = usedIFrame && !this.useIFrame;
+        var toIFrame = !usedIFrame && this.useIFrame;
+        if (fromIFrame || toIFrame) {
+            // switch between get (image) and post (iframe)
+            this.clear();
+            if (this.imgDiv && this.imgDiv.parentNode === this.frame) {
+                this.frame.removeChild(this.imgDiv);
             }
-        } else {
-            OpenLayers.Tile.Image.prototype.clear.apply(this, arguments);
+            this.imgDiv = null;
+            if (fromIFrame) {
+                // remove eventPane
+                this.frame.removeChild(this.frame.firstChild);
+                this.resetBackBuffer();
+            }
         }
-    },
-
-    /**
-     * Method: renderTile
-     */
-     renderTile: function() {
-        if (OpenLayers.Tile.Image.prototype.renderTile.apply(this, arguments) &&
-                                                            this.useIFrame) {
-            // create a html form and add it temporary to the layer div
-            var form = this.createRequestForm();
-            this.imgDiv.appendChild(form);
-
-            // submit the form (means fetching the image)
-            form.submit();
-            this.imgDiv.removeChild(form);
-            delete form;
+        if (!this.useIFrame) {
+            OpenLayers.Tile.Image.prototype.updateBackBuffer.apply(this, arguments);
         }
-        return true;
     },
-
+    
     /**
-     * Method: initImgDiv
-     * Creates the imgDiv property on the tile.
+     * Method: createImage
+     * Creates the content for the frame on the tile.
      */
-    initImgDiv: function() {
-        this.useIFrame = this.maxGetUrlLength !== null && !this.layer.async &&
-            this.url.length > this.maxGetUrlLength;
-        if (this.imgDiv != null) {
-            var nodeName = this.imgDiv.nodeName.toLowerCase();
-            if ((this.useIFrame && nodeName == "img") ||
-                                        (!this.useIFrame && nodeName == "div")) {
-                // switch between get and post
-                this.removeImgDiv();
-                this.imgDiv = null;
+    createImage: function() {
+        if (this.useIFrame === true) {
+            if (!this.frame.childNodes.length) {
+                var eventPane = document.createElement("div"),
+                    style = eventPane.style;
+                style.position = "absolute";
+                style.width = "100%";
+                style.height = "100%";
+                style.zIndex = 1;
+                style.backgroundImage = "url(" + this.blankImageUrl + ")";
+                this.frame.appendChild(eventPane);
             }
-        }
-        if (this.useIFrame) {
-            if (this.imgDiv == null) {
-                var eventPane = document.createElement("div");
 
-                if(OpenLayers.BROWSER_NAME == "msie") {
-                    // IE cannot handle events on elements without backgroundcolor.
-                    // So we use this little hack to make elements transparent
-                    eventPane.style.backgroundColor = '#FFFFFF';
-                    eventPane.style.filter          = 'chroma(color=#FFFFFF)';
-                }
+            var id = this.id + '_iFrame', iframe;
+            if (parseFloat(navigator.appVersion.split("MSIE")[1]) < 9) {
+                // Older IE versions do not set the name attribute of an iFrame 
+                // properly via DOM manipulation, so we need to do it on our own with
+                // this hack.
+                iframe = document.createElement('<iframe name="'+id+'">');
 
-                OpenLayers.Util.modifyDOMElement(eventPane, null,
-                    new OpenLayers.Pixel(0,0), this.layer.getImageSize(), "absolute");
+                // IFrames in older IE versions are not transparent, if you set
+                // the backgroundColor transparent. This is a workaround to get 
+                // transparent iframes.
+                iframe.style.backgroundColor = '#FFFFFF';
+                iframe.style.filter          = 'chroma(color=#FFFFFF)';
+            }
+            else {
+                iframe = document.createElement('iframe');
+                iframe.style.backgroundColor = 'transparent';
 
-                this.imgDiv = document.createElement("div");
-                this.imgDiv.appendChild(eventPane);
+                // iframe.name needs to be an unique id, otherwise it 
+                // could happen that other iframes are overwritten.
+                iframe.name = id;
+            }
 
-                OpenLayers.Util.modifyDOMElement(this.imgDiv, this.id, null,
-                    this.layer.getImageSize(), "relative");
-                this.imgDiv.className = 'olTileImage';
+            // some special properties to avoid scaling the images and scrollbars 
+            // in the iframe
+            iframe.scrolling      = 'no';
+            iframe.marginWidth    = '0px';
+            iframe.marginHeight   = '0px';
+            iframe.frameBorder    = '0';
 
-                this.frame.appendChild(this.imgDiv); 
-                this.layer.div.appendChild(this.frame); 
+            iframe.style.position = "absolute";
+            iframe.style.width    = "100%";
+            iframe.style.height   = "100%";
 
-                if(this.layer.opacity != null) {
-
-                    OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null,
-                                                     null, null, null, null, 
-                                                     this.layer.opacity);
-                }
-
-                // we need this reference to check back the viewRequestID
-                this.imgDiv.map = this.layer.map;
+            if (this.layer.opacity < 1) {
+                OpenLayers.Util.modifyDOMElement(iframe, null, null, null,
+                    null, null, null, this.layer.opacity);
             }
-            this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
-
+            this.frame.appendChild(iframe);
+            this.imgDiv = iframe;
+            return iframe;
         } else {
-            OpenLayers.Tile.Image.prototype.initImgDiv.apply(this, arguments);
+            return OpenLayers.Tile.Image.prototype.createImage.apply(this, arguments);
         }
     },
 
     /**
-     * Method: createIFrame
-     * Create the IFrame which shows the image.
-     *
-     * Returns:
-     * {DOMElement} Iframe
-     */
-    createIFrame: function() {
-        var id = this.id+'_iFrame';
-        var iframe;
-        if(OpenLayers.BROWSER_NAME == "msie") {
-            // InternetExplorer does not set the name attribute of an iFrame 
-            // properly via DOM manipulation, so we need to do it on our own with
-            // this hack.
-            iframe = document.createElement('<iframe name="'+id+'">');
-
-            // IFrames in InternetExplorer are not transparent, if you set the
-            // backgroundColor transparent. This is a workarround to get 
-            // transparent iframes.
-            iframe.style.backgroundColor = '#FFFFFF';
-            iframe.style.filter          = 'chroma(color=#FFFFFF)';
-        }
-        else {
-            iframe = document.createElement('iframe');
-            iframe.style.backgroundColor = 'transparent';
-        
-            // iframe.name needs to be an unique id, otherwise it 
-            // could happen that other iframes are overwritten.
-            iframe.name = id;
-        }
-        iframe.id = id;
-
-        // some special properties to avoid scaling the images and scrollbars 
-        // in the iframe
-        iframe.scrolling             = 'no';
-        iframe.marginWidth           = '0px';
-        iframe.marginHeight          = '0px';
-        iframe.frameBorder           = '0';
-
-        OpenLayers.Util.modifyDOMElement(iframe, id, 
-            new OpenLayers.Pixel(0,0), this.layer.getImageSize(), "absolute");
-
-        //bind a listener to the onload of the iframe so that we
-        // can register when a tile has finished loading.
-        var onload = function() {
-            //normally isLoading should always be true here but there are some
-            // right funky conditions where loading and then reloading a tile
-            // with the same url *really*fast*. this check prevents sending
-            // a 'loadend' if the msg has already been sent
-            //
-            if (this.isLoading) {
-                this.isLoading = false;
-                this.events.triggerEvent("loadend");
-            }
-        };
-        OpenLayers.Event.observe(iframe, 'load',
-            OpenLayers.Function.bind(onload, this));
-
-        return iframe;
-    },
-    
-    /**
      * Method: createRequestForm
      * Create the html <form> element with width, height, bbox and all 
      * parameters specified in the layer params.
@@ -198,20 +141,16 @@
         var cacheId = this.layer.params["_OLSALT"];
         cacheId = (cacheId ? cacheId + "_" : "") + this.bounds.toBBOX();
         form.action = OpenLayers.Util.urlAppend(this.layer.url, cacheId);
+        form.target = this.id + '_iFrame';
 
-        // insert the iframe, which has been removed to avoid back-button
-        // problems
-        this.imgDiv.insertBefore(this.createIFrame(), this.imgDiv.firstChild);
-
-        form.target = this.id+'_iFrame';
-
         // adding all parameters in layer params as hidden fields to the html
         // form element
-        var imageSize = this.layer.getImageSize();
-        var params = OpenLayers.Util.getParameters(this.url);
+        var imageSize = this.layer.getImageSize(),
+            params = OpenLayers.Util.getParameters(this.url),
+            field;
             
         for(var par in params) {
-            var field = document.createElement('input');
+            field = document.createElement('input');
             field.type  = 'hidden';
             field.name  = par;
             field.value = params[par];
@@ -219,6 +158,31 @@
         }   
 
         return form;
+    },
+
+    /**
+     * Method: setImgSrc
+     * Sets the source for the tile image
+     *
+     * Parameters:
+     * url - {String}
+     */
+    setImgSrc: function(url) {
+        if (this.useIFrame === true) {
+            if (url) {
+                var form = this.createRequestForm();
+                this.frame.appendChild(this.imgDiv);
+                this.frame.appendChild(form);
+                form.submit();
+                this.frame.removeChild(form);
+            } else if (this.imgDiv.parentNode === this.frame) {
+                // we don't reuse iframes to avoid caching issues
+                this.frame.removeChild(this.imgDiv);
+                this.imgDiv = null;
+            }
+        } else {
+            OpenLayers.Tile.Image.prototype.setImgSrc.apply(this, arguments);
+        }
     }
-};
 
+};

Modified: sandbox/august/trunk/lib/OpenLayers/Tile/Image.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Tile/Image.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Tile/Image.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -5,7 +5,7 @@
 
 
 /**
- * @requires OpenLayers/Tile.js
+ * @requires OpenLayers/Tile/BackBufferable.js
  */
 
 /**
@@ -15,9 +15,9 @@
  * <OpenLayers.Tile.Image> constructor.
  *
  * Inherits from:
- *  - <OpenLayers.Tile>
+ *  - <OpenLayers.Tile.BackBufferable>
  */
-OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
+OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile.BackBufferable, {
 
     /** 
      * Property: url
@@ -28,16 +28,22 @@
     
     /** 
      * Property: imgDiv
-     * {DOMElement} The div element which wraps the image.
+     * {HTMLImageElement} The image for this tile.
      */
     imgDiv: null,
-
+    
     /**
      * Property: frame
      * {DOMElement} The image element is appended to the frame.  Any gutter on
      * the image will be hidden behind the frame. 
      */ 
     frame: null, 
+
+    /** 
+     * Property: imageReloadAttempts
+     * {Integer} Attempts to load the image.
+     */
+    imageReloadAttempts: null,
     
     /**
      * Property: layerAlphaHack
@@ -46,30 +52,21 @@
     layerAlphaHack: null,
     
     /**
-     * Property: isBackBuffer
-     * {Boolean} Is this tile a back buffer tile?
+     * Property: asyncRequestId
+     * {Integer} ID of an request to see if request is still valid. This is a
+     * number which increments by 1 for each asynchronous request.
      */
-    isBackBuffer: false,
+    asyncRequestId: null,
     
     /**
-     * Property: isFirstDraw
-     * {Boolean} Is this the first time the tile is being drawn?
-     *     This is used to force resetBackBuffer to synchronize
-     *     the backBufferTile with the foreground tile the first time
-     *     the foreground tile loads so that if the user zooms
-     *     before the layer has fully loaded, the backBufferTile for
-     *     tiles that have been loaded can be used.
+     * Property: blankImageUrl
+     * {String} Using a data scheme url is not supported by all browsers, but
+     * we don't care because we either set it as css backgroundImage, or the
+     * image's display style is set to "none" when we use it.
      */
-    isFirstDraw: true,
-        
+    blankImageUrl: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAQAIBRAA7",
+
     /**
-     * Property: backBufferTile
-     * {<OpenLayers.Tile>} A clone of the tile used to create transition
-     *     effects when the tile is moved or changes resolution.
-     */
-    backBufferTile: null,
-    
-    /**
      * APIProperty: maxGetUrlLength
      * {Number} If set, requests that would result in GET urls with more
      * characters than the number provided will be made using form-encoded
@@ -77,12 +74,9 @@
      * characters.
      *
      * Caution:
-     * Older versions of Gecko based browsers (e.g. Firefox < 3.5) and
-     * Opera < 10.0 do not fully support this option.
-     *
-     * Note:
-     * Do not use this option for layers that have a transitionEffect
-     * configured - IFrame tiles from POST requests can not be resized.
+     * Older versions of Gecko based browsers (e.g. Firefox < 3.5) and most
+     * Opera versions do not fully support this option. On all browsers,
+     * transition effects are not supported if POST requests are used.
      */
     maxGetUrlLength: null,
     
@@ -102,502 +96,278 @@
      * options - {Object}
      */   
     initialize: function(layer, position, bounds, url, size, options) {
-        OpenLayers.Tile.prototype.initialize.apply(this, arguments);
+        OpenLayers.Tile.BackBufferable.prototype.initialize.apply(this, arguments);
 
-        if (this.maxGetUrlLength != null) {
-            OpenLayers.Util.extend(this, OpenLayers.Tile.Image.IFrame);
-        }
-
         this.url = url; //deprecated remove me
+
+        this.frame = document.createElement("div");
+        this.frame.style.position = "absolute";
+        this.frame.style.overflow = "hidden";
         
-        this.frame = document.createElement('div'); 
-        this.frame.style.overflow = 'hidden'; 
-        this.frame.style.position = 'absolute'; 
+        this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();
 
-        this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();        
+        if (this.maxGetUrlLength != null) {
+            OpenLayers.Util.extend(this, OpenLayers.Tile.Image.IFrame);
+        }
     },
-
+    
     /** 
      * APIMethod: destroy
      * nullify references to prevent circular references and memory leaks
      */
     destroy: function() {
-        if (this.imgDiv != null)  {
-            this.removeImgDiv();
+        if (this.frame != null)  {
+            this.clear();
+            this.imgDiv = null;
+            this.frame = null;
         }
-        this.imgDiv = null;
-        if ((this.frame != null) && (this.frame.parentNode == this.layer.div)) { 
-            this.layer.div.removeChild(this.frame); 
-        }
-        this.frame = null; 
-        
-        /* clean up the backBufferTile if it exists */
-        if (this.backBufferTile) {
-            this.backBufferTile.destroy();
-            this.backBufferTile = null;
-        }
-        
-        this.layer.events.unregister("loadend", this, this.resetBackBuffer);
-        
-        OpenLayers.Tile.prototype.destroy.apply(this, arguments);
+        // don't handle async requests any more
+        this.asyncRequestId = null;
+        OpenLayers.Tile.BackBufferable.prototype.destroy.apply(this, arguments);
     },
     
     /**
-     * Method: clone
-     *
-     * Parameters:
-     * obj - {<OpenLayers.Tile.Image>} The tile to be cloned
-     *
-     * Returns:
-     * {<OpenLayers.Tile.Image>} An exact clone of this <OpenLayers.Tile.Image>
-     */
-    clone: function (obj) {
-        if (obj == null) {
-            obj = new OpenLayers.Tile.Image(this.layer, 
-                                            this.position, 
-                                            this.bounds, 
-                                            this.url, 
-                                            this.size);        
-        } 
-        
-        //pick up properties from superclass
-        obj = OpenLayers.Tile.prototype.clone.apply(this, [obj]);
-        
-        //dont want to directly copy the image div
-        obj.imgDiv = null;
-            
-        
-        return obj;
-    },
-    
-    /**
      * Method: draw
      * Check that a tile should be drawn, and draw it.
      * 
      * Returns:
-     * {Boolean} Always returns true.
+     * {Boolean} Was a tile drawn?
      */
     draw: function() {
-        if (this.layer != this.layer.map.baseLayer && this.layer.reproject) {
-            this.bounds = this.getBoundsFromBaseLayer(this.position);
-        }
-        var drawTile = OpenLayers.Tile.prototype.draw.apply(this, arguments);
-        
-        if ((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) || 
-            this.layer.singleTile) {
-            if (drawTile) {
-                //we use a clone of this tile to create a double buffer for visual
-                //continuity.  The backBufferTile is used to create transition
-                //effects while the tile in the grid is repositioned and redrawn
-                if (!this.backBufferTile) {
-                    this.backBufferTile = this.clone();
-                    this.backBufferTile.hide();
-                    // this is important.  It allows the backBuffer to place itself
-                    // appropriately in the DOM.  The Image subclass needs to put
-                    // the backBufferTile behind the main tile so the tiles can
-                    // load over top and display as soon as they are loaded.
-                    this.backBufferTile.isBackBuffer = true;
-                    
-                    // potentially end any transition effects when the tile loads
-                    this.events.register('loadend', this, this.resetBackBuffer);
-                    
-                    // clear transition back buffer tile only after all tiles in
-                    // this layer have loaded to avoid visual glitches
-                    this.layer.events.register("loadend", this, this.resetBackBuffer);
-                }
-                // run any transition effects
-                this.startTransition();
+        var drawn = OpenLayers.Tile.BackBufferable.prototype.draw.apply(this, arguments);
+        if (drawn) {
+            if (this.layer != this.layer.map.baseLayer && this.layer.reproject) {
+                this.bounds = this.getBoundsFromBaseLayer(this.position);
+            }
+            if (this.isLoading) {
+                //if we're already loading, send 'reload' instead of 'loadstart'.
+                this.events.triggerEvent("reload"); 
             } else {
-                // if we aren't going to draw the tile, then the backBuffer should
-                // be hidden too!
-                if (this.backBufferTile) {
-                    this.backBufferTile.clear();
-                }
+                this.isLoading = true;
+                this.events.triggerEvent("loadstart");
             }
+            this.positionTile();
+            this.renderTile();
         } else {
-            if (drawTile && this.isFirstDraw) {
-                this.events.register('loadend', this, this.showTile);
-                this.isFirstDraw = false;
-            }   
-        }    
-        
-        if (!drawTile) {
-            return false;
+            this.unload();
         }
-        
-        if (this.isLoading) {
-            //if we're already loading, send 'reload' instead of 'loadstart'.
-            this.events.triggerEvent("reload"); 
-        } else {
-            this.isLoading = true;
-            this.events.triggerEvent("loadstart");
-        }
-        
-        return this.renderTile();
+        return drawn;
     },
     
-    /** 
-     * Method: resetBackBuffer
-     * Triggered by two different events, layer loadend, and tile loadend.
-     *     In any of these cases, we check to see if we can hide the 
-     *     backBufferTile yet and update its parameters to match the 
-     *     foreground tile.
-     *
-     * Basic logic:
-     *  - If the backBufferTile hasn't been drawn yet, reset it
-     *  - If layer is still loading, show foreground tile but don't hide
-     *    the backBufferTile yet
-     *  - If layer is done loading, reset backBuffer tile and show 
-     *    foreground tile
-     */
-    resetBackBuffer: function() {
-        this.showTile();
-        if (this.backBufferTile && 
-            (this.isFirstDraw || !this.layer.numLoadingTiles)) {
-            this.isFirstDraw = false;
-            // check to see if the backBufferTile is within the max extents
-            // before rendering it 
-            var maxExtent = this.layer.maxExtent;
-            var withinMaxExtent = (maxExtent &&
-                                   this.bounds.intersectsBounds(maxExtent, false));
-            if (withinMaxExtent) {
-                this.backBufferTile.position = this.position;
-                this.backBufferTile.bounds = this.bounds;
-                this.backBufferTile.size = this.size;
-                this.backBufferTile.imageSize = this.layer.getImageSize(this.bounds) || this.size;
-                this.backBufferTile.imageOffset = this.layer.imageOffset;
-                this.backBufferTile.resolution = this.layer.getResolution();
-                this.backBufferTile.renderTile();
-            }
-
-            this.backBufferTile.hide();
-        }
-    },
-    
     /**
      * Method: renderTile
      * Internal function to actually initialize the image tile,
      *     position it correctly, and set its url.
      */
     renderTile: function() {
+        this.layer.div.appendChild(this.frame);
         if (this.layer.async) {
-            this.initImgDiv();
-            // Asyncronous image requests call the asynchronous getURL method
+            // Asynchronous image requests call the asynchronous getURL method
             // on the layer to fetch an image that covers 'this.bounds', in the scope of
             // 'this', setting the 'url' property of the layer itself, and running
-            // the callback 'positionFrame' when the image request returns.
-            this.layer.getURLasync(this.bounds, this, "url", this.positionImage);
+            // the callback 'initImage' when the image request returns.
+            var myId = this.asyncRequestId = (this.asyncRequestId || 0) + 1;
+            this.layer.getURLasync(this.bounds, this, "url", function() {
+                if (myId == this.asyncRequestId) {
+                    this.initImage();
+                }
+            });
         } else {
-            // syncronous image requests get the url and position the frame immediately,
-            // and don't wait for an image request to come back.
-          
+            // synchronous image requests get the url immediately.
             this.url = this.layer.getURL(this.bounds);
-
-            this.initImgDiv();
-          
-            // position the frame immediately
-            this.positionImage(); 
+            this.initImage();
         }
-        return true;
     },
 
     /**
-     * Method: positionImage
+     * Method: positionTile
      * Using the properties currenty set on the layer, position the tile correctly.
      * This method is used both by the async and non-async versions of the Tile.Image
      * code.
      */
-     positionImage: function() {
-        // if the this layer doesn't exist at the point the image is
-        // returned, do not attempt to use it for size computation
-        if (this.layer === null) {
-            return;
-        }
-        // position the frame 
-        OpenLayers.Util.modifyDOMElement(this.frame, 
-                                          null, this.position, this.size);   
-
-        var imageSize = this.layer.getImageSize(this.bounds); 
-        if (this.layerAlphaHack) {
-            OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,
-                    null, null, imageSize, this.url);
-        } else {
-            OpenLayers.Util.modifyDOMElement(this.imgDiv,
-                    null, null, imageSize) ;
-            this.imgDiv.src = this.url;
-        }
+    positionTile: function() {
+        var style = this.frame.style;
+        style.left = this.position.x + "px";
+        style.top = this.position.y + "px";
+        style.width = this.size.w + "px";
+        style.height = this.size.h + "px";
     },
 
     /** 
      * Method: clear
-     *  Clear the tile of any bounds/position-related data so that it can 
-     *   be reused in a new location.
+     * Remove the tile from the DOM, clear it of any image related data so that
+     * it can be reused in a new location.
      */
     clear: function() {
-        if(this.imgDiv) {
-            this.hide();
-            if (OpenLayers.Tile.Image.useBlankTile) { 
-                this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
-            }    
+        var img = this.imgDiv;
+        if (img) {
+            OpenLayers.Event.stopObservingElement(img);
+            if (this.frame.parentNode === this.layer.div) {
+                this.layer.div.removeChild(this.frame);
+            }
+            this.setImgSrc();
+            if (this.layerAlphaHack === true) {
+                img.style.filter = "";
+            }
+            OpenLayers.Element.removeClass(img, "olImageLoadError");
         }
     },
-
+    
     /**
-     * Method: initImgDiv
-     * Creates the imgDiv property on the tile.
+     * Method: createImage
+     * Creates the content for the frame on the tile.
      */
-    initImgDiv: function() {
-        if (this.imgDiv == null) {
-            var offset = this.layer.imageOffset; 
-            var size = this.layer.getImageSize(this.bounds); 
+    createImage: function() {
+        var img = document.createElement("img");
+        this.imgDiv = img;
 
-            if (this.layerAlphaHack) {
-                this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null,
-                                                               offset,
-                                                               size,
-                                                               null,
-                                                               "relative",
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               true);
-            } else {
-                this.imgDiv = OpenLayers.Util.createImage(null,
-                                                          offset,
-                                                          size,
-                                                          null,
-                                                          "relative",
-                                                          null,
-                                                          null,
-                                                          true);
-            }
+        img.className = "olTileImage";
+        // avoid image gallery menu in IE6
+        img.galleryImg = "no";
 
-            // needed for changing to a different server for onload error
-            if (OpenLayers.Util.isArray(this.layer.url)) {
-                this.imgDiv.urls = this.layer.url.slice();
-            }
-      
-            this.imgDiv.className = 'olTileImage';
-
-            /* checkImgURL used to be used to called as a work around, but it
-               ended up hiding problems instead of solving them and broke things
-               like relative URLs. See discussion on the dev list:
-               http://openlayers.org/pipermail/dev/2007-January/000205.html
-
-            OpenLayers.Event.observe( this.imgDiv, "load",
-                OpenLayers.Function.bind(this.checkImgURL, this) );
-            */
-            this.frame.style.zIndex = this.isBackBuffer ? 0 : 1;
-            this.frame.appendChild(this.imgDiv); 
-            this.layer.div.appendChild(this.frame); 
-
-            if(this.layer.opacity != null) {
-
-                OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null, null,
-                                                 null, null, null, 
-                                                 this.layer.opacity);
-            }
-
-            // we need this reference to check back the viewRequestID
-            this.imgDiv.map = this.layer.map;
-
-            //bind a listener to the onload of the image div so that we 
-            // can register when a tile has finished loading.
-            var onload = function() {
-
-                //normally isLoading should always be true here but there are some 
-                // right funky conditions where loading and then reloading a tile
-                // with the same url *really*fast*. this check prevents sending 
-                // a 'loadend' if the msg has already been sent
-                //
-                if (this.isLoading) { 
-                    this.isLoading = false; 
-                    this.events.triggerEvent("loadend"); 
-                }
-            };
-
-            if (this.layerAlphaHack) { 
-                OpenLayers.Event.observe(this.imgDiv.childNodes[0], 'load', 
-                                         OpenLayers.Function.bind(onload, this));    
-            } else { 
-                OpenLayers.Event.observe(this.imgDiv, 'load', 
-                                     OpenLayers.Function.bind(onload, this)); 
-            } 
-
-
-            // Bind a listener to the onerror of the image div so that we
-            // can registere when a tile has finished loading with errors.
-            var onerror = function() {
-
-                // If we have gone through all image reload attempts, it is time
-                // to realize that we are done with this image. Since
-                // OpenLayers.Util.onImageLoadError already has taken care about
-                // the error, we can continue as if the image was loaded
-                // successfully.
-                if (this.imgDiv._attempts > OpenLayers.IMAGE_RELOAD_ATTEMPTS) {
-                    onload.call(this);
-                }
-            };
-            OpenLayers.Event.observe(this.imgDiv, "error",
-                                     OpenLayers.Function.bind(onerror, this));
+        var style = img.style,
+            gutter = this.layer.gutter;
+        if (gutter) {
+            var tileSize = this.layer.tileSize,
+                left = (gutter / tileSize.w * 100),
+                top = (gutter / tileSize.h * 100);
+            style.left = -left + "%";
+            style.top = -top + "%";
+            style.width = (2 * left + 100) + "%";
+            style.height = (2 * top + 100) + "%";
+            style.position = "absolute";
+        } else {
+            style.width = "100%";
+            style.height = "100%";
         }
-        
-        this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
+        style.display = "none";
+        if (this.layer.opacity < 1) {
+            OpenLayers.Util.modifyDOMElement(img, null, null, null, null, null,
+                null, this.layer.opacity);
+        }
+        if (this.layerAlphaHack) {
+            // move the image out of sight
+            style.paddingTop = style.height;
+            style.height = "0";
+        }
+
+        this.frame.appendChild(img);
+        return img;
     },
 
     /**
-     * Method: removeImgDiv
-     * Removes the imgDiv from the DOM and stops listening to events on it.
+     * Method: initImage
+     * Creates the content for the frame on the tile.
      */
-    removeImgDiv: function() {
-        // unregister the "load" and "error" handlers. Only the "error" handler if
-        // this.layerAlphaHack is true.
-        OpenLayers.Event.stopObservingElement(this.imgDiv);
-        
-        if (this.imgDiv.parentNode == this.frame) {
-            this.frame.removeChild(this.imgDiv);
-            this.imgDiv.map = null;
-        }
-        this.imgDiv.urls = null;
-
-        var child = this.imgDiv.firstChild;
-        //check for children (alphaHack img or IFrame)
-        if (child) {
-            OpenLayers.Event.stopObservingElement(child);
-            this.imgDiv.removeChild(child);
-            delete child;
+    initImage: function() {
+        var img = this.imgDiv || this.createImage();
+        if (this.url && img.getAttribute("src") == this.url) {
+            this.onImageLoad();
         } else {
-            // abort any currently loading image
-            this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
+            // We need to start with a blank image, to make sure that no
+            // loading image placeholder and no old image is displayed when we
+            // set the display style to "" in onImageLoad, which is called
+            // after the image is loaded, but before it is rendered. So we set
+            // a blank image with a data scheme URI, and register for the load
+            // event (for browsers that support data scheme) and the error
+            // event (for browsers that don't). In the event handler, we set
+            // the final src.
+            var load = OpenLayers.Function.bind(function() {
+                OpenLayers.Event.stopObservingElement(img);
+                OpenLayers.Event.observe(img, "load",
+                    OpenLayers.Function.bind(this.onImageLoad, this)
+                );
+                OpenLayers.Event.observe(img, "error",
+                    OpenLayers.Function.bind(this.onImageError, this)
+                );
+                this.imageReloadAttempts = 0;
+                this.setImgSrc(this.url);
+            }, this);
+            if (img.getAttribute("src") == this.blankImageUrl) {
+                load();
+            } else {
+                OpenLayers.Event.observe(img, "load", load);
+                OpenLayers.Event.observe(img, "error", load);
+                img.src = this.blankImageUrl;
+            }
         }
     },
-
+    
     /**
-     * Method: checkImgURL
-     * Make sure that the image that just loaded is the one this tile is meant
-     * to display, since panning/zooming might have changed the tile's URL in
-     * the meantime. If the tile URL did change before the image loaded, set
-     * the imgDiv display to 'none', as either (a) it will be reset to visible
-     * when the new URL loads in the image, or (b) we don't want to display
-     * this tile after all because its new bounds are outside our maxExtent.
-     * 
-     * This function should no longer  be neccesary with the improvements to
-     * Grid.js in OpenLayers 2.3. The lack of a good isEquivilantURL function
-     * caused problems in 2.2, but it's possible that with the improved 
-     * isEquivilant URL function, this might be neccesary at some point.
-     * 
-     * See discussion in the thread at 
-     * http://openlayers.org/pipermail/dev/2007-January/000205.html
+     * Method: setImgSrc
+     * Sets the source for the tile image
+     *
+     * Parameters:
+     * url - {String} or undefined to hide the image
      */
-    checkImgURL: function () {
-        // Sometimes our image will load after it has already been removed
-        // from the map, in which case this check is not needed.  
-        if (this.layer) {
-            var loaded = this.layerAlphaHack ? this.imgDiv.firstChild.src : this.imgDiv.src;
-            if (!OpenLayers.Util.isEquivalentUrl(loaded, this.url)) {
-                this.hide();
-            }
+    setImgSrc: function(url) {
+        var img = this.imgDiv;
+        img.style.display = "none";
+        if (url) {
+            img.src = url;
         }
     },
     
     /**
-     * Method: startTransition
-     * This method is invoked on tiles that are backBuffers for tiles in the
-     *     grid.  The grid tile is about to be cleared and a new tile source
-     *     loaded.  This is where the transition effect needs to be started
-     *     to provide visual continuity.
+     * Method: getTile
+     * Get the tile's markup.
+     *
+     * Returns:
+     * {DOMElement} The tile's markup
      */
-    startTransition: function() {
-        // backBufferTile has to be valid and ready to use
-        if (!this.backBufferTile || !this.backBufferTile.imgDiv) {
-            return;
-        }
+    getTile: function() {
+        return this.frame;
+    },
 
-        // calculate the ratio of change between the current resolution of the
-        // backBufferTile and the layer.  If several animations happen in a
-        // row, then the backBufferTile will scale itself appropriately for
-        // each request.
-        var ratio = 1;
-        if (this.backBufferTile.resolution) {
-            ratio = this.backBufferTile.resolution / this.layer.getResolution();
-        }
-        
-        // if the ratio is not the same as it was last time (i.e. we are
-        // zooming), then we need to adjust the backBuffer tile
-        if (ratio != 1) {
-            if (this.layer.transitionEffect == 'resize') {
-                // In this case, we can just immediately resize the 
-                // backBufferTile.
-                var upperLeft = new OpenLayers.LonLat(
-                    this.backBufferTile.bounds.left, 
-                    this.backBufferTile.bounds.top
-                );
-                var size = new OpenLayers.Size(
-                    this.backBufferTile.size.w * ratio,
-                    this.backBufferTile.size.h * ratio
-                );
+    /**
+     * Method: createBackBuffer
+     * Create a copy of this tile's markup for the <layer>'s backBufferDiv
+     *
+     * Returns:
+     * {DOMElement} a clone of the tile content
+     */
+    createBackBuffer: function() {
+        var frame = this.frame.cloneNode(false);
+        frame.appendChild(this.imgDiv);
+        this.imgDiv = null;
+        return frame;
+    },
 
-                var px = this.layer.map.getLayerPxFromLonLat(upperLeft);
-                OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame, 
-                                                 null, px, size);
-                var imageSize = this.backBufferTile.imageSize;
-                imageSize = new OpenLayers.Size(imageSize.w * ratio, 
-                                                imageSize.h * ratio);
-                var imageOffset = this.backBufferTile.imageOffset;
-                if(imageOffset) {
-                    imageOffset = new OpenLayers.Pixel(
-                        imageOffset.x * ratio, imageOffset.y * ratio
-                    );
-                }
+    /**
+     * Method: onImageLoad
+     * Handler for the image onload event
+     */
+    onImageLoad: function() {
+        var img = this.imgDiv;
+        OpenLayers.Event.stopObservingElement(img);
+        img.style.display = "";
+        this.isLoading = false;
+        this.events.triggerEvent("loadend");
 
-                OpenLayers.Util.modifyDOMElement(
-                    this.backBufferTile.imgDiv, null, imageOffset, imageSize
-                ) ;
-
-                this.backBufferTile.show();
-            }
-        } else {
-            // default effect is just to leave the existing tile
-            // until the new one loads if this is a singleTile and
-            // there was no change in resolution.  Otherwise we
-            // don't bother to show the backBufferTile at all
-            if (this.layer.singleTile) {
-                this.backBufferTile.show();
-            } else {
-                this.backBufferTile.hide();
-            }
+        if (this.layerAlphaHack === true) {
+            img.style.filter =
+                "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
+                img.src + "', sizingMethod='scale')";
         }
-
     },
     
-    /** 
-     * Method: show
-     * Show the tile by showing its frame.
+    /**
+     * Method: onImageError
+     * Handler for the image onerror event
      */
-    show: function() {
-        this.frame.style.display = '';
-        // Force a reflow on gecko based browsers to actually show the element
-        // before continuing execution.
-        if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, 
-                this.layer.transitionEffect) != -1) {
-            if (OpenLayers.IS_GECKO === true) { 
-                this.frame.scrollLeft = this.frame.scrollLeft; 
-            } 
+    onImageError: function() {
+        var img = this.imgDiv;
+        if (img.src != null) {
+            this.imageReloadAttempts++;
+            if (this.imageReloadAttempts <= OpenLayers.IMAGE_RELOAD_ATTEMPTS) {
+                this.setImgSrc(this.layer.getURL(this.bounds));
+            } else {
+                OpenLayers.Element.addClass(img, "olImageLoadError");
+                this.onImageLoad();
+            }
         }
     },
-    
-    /** 
-     * Method: hide
-     * Hide the tile by hiding its frame.
-     */
-    hide: function() {
-        this.frame.style.display = 'none';
-    },
-    
+
     CLASS_NAME: "OpenLayers.Tile.Image"
-  }
-);
 
-OpenLayers.Tile.Image.useBlankTile = ( 
-    OpenLayers.BROWSER_NAME == "safari" || 
-    OpenLayers.BROWSER_NAME == "opera"); 
+});

Modified: sandbox/august/trunk/lib/OpenLayers/Tile.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Tile.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Tile.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -4,7 +4,7 @@
  * full text of the license. */
 
 
-/*
+/**
  * @requires OpenLayers/BaseTypes/Class.js
  * @requires OpenLayers/Util.js
  * @requires OpenLayers/Console.js
@@ -26,10 +26,12 @@
 OpenLayers.Tile = OpenLayers.Class({
     
     /** 
-     * Constant: EVENT_TYPES
-     * {Array(String)} Supported application event types
+     * Supported event types:
+     *  - *loadstart* Triggered when tile loading starts.
+     *  - *loadend* Triggered when tile loading ends.
+     *  - *reload* Triggered when an already loading tile is reloaded.
+     *  - *unload* Triggered before a tile is unloaded.
      */
-    EVENT_TYPES: [ "loadstart", "loadend", "reload", "unload"],
     
     /**
      * APIProperty: events
@@ -77,7 +79,7 @@
      * {<OpenLayers.Pixel>} Top Left pixel of the tile
      */    
     position: null,
-
+    
     /**
      * Property: isLoading
      * {Boolean} Is the tile loading?
@@ -110,7 +112,7 @@
         //give the tile a unique id based on its BBOX.
         this.id = OpenLayers.Util.createUniqueID("Tile_");
         
-        this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
+        this.events = new OpenLayers.Events(this);
 
         OpenLayers.Util.extend(this, options);
     },
@@ -144,53 +146,37 @@
     },
     
     /**
-     * Method: clone
-     *
-     * Parameters:
-     * obj - {<OpenLayers.Tile>} The tile to be cloned
-     *
+     * Method: draw
+     * Clear whatever is currently in the tile, then return whether or not 
+     *     it should actually be re-drawn. This is an example implementation
+     *     that can be overridden by subclasses. The minimum thing to do here
+     *     is to call <clear> and return the result from <shouldDraw>.
+     * 
      * Returns:
-     * {<OpenLayers.Tile>} An exact clone of this <OpenLayers.Tile>
+     * {Boolean} Whether or not the tile should actually be drawn.
      */
-    clone: function (obj) {
-        if (obj == null) {
-            obj = new OpenLayers.Tile(this.layer, 
-                                      this.position, 
-                                      this.bounds, 
-                                      this.url, 
-                                      this.size);
-        } 
+    draw: function() {
+        //clear tile's contents and mark as not drawn
+        this.clear();
         
-        // catch any randomly tagged-on properties
-        OpenLayers.Util.applyDefaults(obj, this);
-        
-        return obj;
+        return this.shouldDraw();
     },
-
+    
     /**
-     * Method: draw
-     * Clear whatever is currently in the tile, then return whether or not 
-     *     it should actually be re-drawn.
+     * Method: shouldDraw
+     * Return whether or not the tile should actually be (re-)drawn. The only
+     * case where we *wouldn't* want to draw the tile is if the tile is outside
+     * its layer's maxExtent
      * 
      * Returns:
-     * {Boolean} Whether or not the tile should actually be drawn. Note that 
-     *     this is not really the best way of doing things, but such is 
-     *     the way the code has been developed. Subclasses call this and
-     *     depend on the return to know if they should draw or not.
+     * {Boolean} Whether or not the tile should actually be drawn.
      */
-    draw: function() {
+    shouldDraw: function() {
         var maxExtent = this.layer.maxExtent;
         var withinMaxExtent = (maxExtent &&
                                this.bounds.intersectsBounds(maxExtent, false));
- 
-        // The only case where we *wouldn't* want to draw the tile is if the 
-        // tile is outside its layer's maxExtent.
-        this.shouldDraw = (withinMaxExtent || this.layer.displayOutsideMaxExtent);
-                
-        //clear tile's contents and mark as not drawn
-        this.clear();
         
-        return this.shouldDraw;
+        return withinMaxExtent || this.layer.displayOutsideMaxExtent;
     },
     
     /** 
@@ -220,7 +206,7 @@
      * Clear the tile of any bounds/position-related data so that it can 
      *     be reused in a new location. To be implemented by subclasses.
      */
-    clear: function() {
+    clear: function(draw) {
         // to be implemented by subclasses
     },
     
@@ -260,29 +246,7 @@
                                        bottomRight.lon, 
                                        topLeft.lat);  
         return bounds;
-    },        
-        
-    /** 
-     * Method: showTile
-     * Show the tile only if it should be drawn.
-     */
-    showTile: function() { 
-        if (this.shouldDraw) {
-            this.show();
-        }
     },
     
-    /** 
-     * Method: show
-     * Show the tile.  To be implemented by subclasses.
-     */
-    show: function() { },
-    
-    /** 
-     * Method: hide
-     * Hide the tile.  To be implemented by subclasses.
-     */
-    hide: function() { },
-    
     CLASS_NAME: "OpenLayers.Tile"
 });

Modified: sandbox/august/trunk/lib/OpenLayers/Util.js
===================================================================
--- sandbox/august/trunk/lib/OpenLayers/Util.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/lib/OpenLayers/Util.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -694,85 +694,7 @@
     return returnValue;
 };
 
-
-/** 
- * Function: getNodes
- * 
- * These could/should be made namespace aware?
- * 
- * Parameters:
- * p - {}
- * tagName - {String}
- * 
- * Returns:
- * {Array}
- */
-OpenLayers.Util.getNodes=function(p, tagName) {
-    var nodes = OpenLayers.Util.Try(
-        function () {
-            return OpenLayers.Util._getNodes(p.documentElement.childNodes,
-                                            tagName);
-        },
-        function () {
-            return OpenLayers.Util._getNodes(p.childNodes, tagName);
-        }
-    );
-    return nodes;
-};
-
 /**
- * Function: _getNodes
- * 
- * Parameters:
- * nodes - {Array}
- * tagName - {String}
- * 
- * Returns:
- * {Array}
- */
-OpenLayers.Util._getNodes=function(nodes, tagName) {
-    var retArray = [];
-    for (var i=0, len=nodes.length; i<len; i++) {
-        if (nodes[i].nodeName==tagName) {
-            retArray.push(nodes[i]);
-        }
-    }
-
-    return retArray;
-};
-
-
-
-/**
- * Function: getTagText
- * 
- * Parameters:
- * parent - {}
- * item - {String}
- * index - {Integer}
- * 
- * Returns:
- * {String}
- */
-OpenLayers.Util.getTagText = function (parent, item, index) {
-    var result = OpenLayers.Util.getNodes(parent, item);
-    if (result && (result.length > 0))
-    {
-        if (!index) {
-            index=0;
-        }
-        if (result[index].childNodes.length > 1) {
-            return result.childNodes[1].nodeValue; 
-        }
-        else if (result[index].childNodes.length == 1) {
-            return result[index].firstChild.nodeValue; 
-        }
-    } else { 
-        return ""; 
-    }
-};
-
-/**
  * Function: getXmlNodeValue
  * 
  * Parameters:
@@ -1021,14 +943,15 @@
  * 
  * Parameters:
  * url - {String} Optional url used to extract the query string.
- *                If null, query string is taken from page location.
+ *                If url is null or is not supplied, query string is taken 
+ *                from the page location.
  * 
  * Returns:
  * {Object} An object of key/value pairs from the query string.
  */
 OpenLayers.Util.getParameters = function(url) {
     // if no url specified, take it from the location bar
-    url = url || window.location.href;
+    url = (url === null || url === undefined) ? window.location.href : url;
 
     //parse out parameters portion of url string
     var paramsString = "";
@@ -1582,7 +1505,11 @@
     }
     urlObject.args = OpenLayers.Util.getParameters(queryString);
 
-    //pathname (uniform browser behavior with leading "/")
+    // pathname
+    //
+    // This is a workaround for Internet Explorer where
+    // window.location.pathname has a leading "/", but
+    // a.pathname has no leading "/".
     urlObject.pathname = (a.pathname.charAt(0) == "/") ? a.pathname : "/" + a.pathname;
     
     return urlObject; 

Modified: sandbox/august/trunk/tests/BaseTypes/Class.html
===================================================================
--- sandbox/august/trunk/tests/BaseTypes/Class.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/BaseTypes/Class.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -162,6 +162,24 @@
              "inheritance doesn't mess with parents");
 
     }
+
+    function test_inheritance_chain(t) {
+        t.plan(1);
+        var A = new OpenLayers.Class({
+            initialize: function() {
+                this.a = 'foo';
+            }
+        });
+        var B = new OpenLayers.Class(A, {});
+        var C = new OpenLayers.Class(B, {
+            initialize: function() {
+                B.prototype.initialize.apply(this, arguments);
+                this.a = this.a + 'bar';
+            }
+        });
+        var c = new C;
+        t.eq(c.a, 'foobar', 'constructor at the root is called');
+    }
     
     // Remove this at 3.0
     function test_Class_backwards(t) {
@@ -308,6 +326,153 @@
         t.ok(!(bad instanceof OpenLayers.Control), "bad is a control, but it is also a layer and we cannot have two superclasses");
         t.ok(bad instanceof OpenLayers.Layer, "bad is a layer, it inherits from the layer first");
     }
+
+    //
+    // IGN's GeoPortal API overwrite prototypes of OpenLayers constructors.
+    // The tests below aim to cover their usage pattens.
+    //
+
+    // the overwrite function under test
+    function overwrite(C, o) {
+        if(typeof o.initialize === "function" &&
+            C === C.prototype.initialize) {
+            // OL 2.11
+
+            var proto = C.prototype;
+            var staticProps = OpenLayers.Util.extend({}, C);
+
+            C = o.initialize;
+
+            C.prototype = proto;
+            OpenLayers.Util.extend(C, staticProps);
+        }
+        OpenLayers.Util.extend(C.prototype, o);
+        return C;
+    }
+
+    function test_overwrite_1(t) {
+        // overwrite constructor
+        t.plan(1);
+        var A = OpenLayers.Class({
+            initialize: function() {
+                this.a = "foo";
+            }
+        });
+        A = overwrite(A, {
+            initialize: function() {
+                this.a = "bar";
+            }
+        });
+        var a = new A;
+        t.eq(a.a, "bar", "ctor overwritten");
+    }
+
+    function test_overwrite_2(t) {
+        // overwrite regular method
+        t.plan(1);
+        var A = OpenLayers.Class({
+            initialize: function() {
+            },
+            method: function() {
+                this.a = "foo";
+            }
+        });
+        A = overwrite(A, {
+            method: function() {
+                this.a = "bar";
+            }
+        });
+        var a = new A;
+        a.method();
+        t.eq(a.a, "bar", "method overwritten");
+    }
+
+    function test_overwrite_3(t) {
+        // overwrite constructor of subclass
+        t.plan(1);
+        var A = OpenLayers.Class({
+            initialize: function() {
+                this.a = "foo";
+            }
+        });
+        var B = OpenLayers.Class(A, {
+            initialize: function() {
+                A.prototype.initialize.call(this);
+            }
+        });
+        B = overwrite(B, {
+            initialize: function() {
+                A.prototype.initialize.call(this);
+                this.a = "bar";
+            }
+        });
+        var b = new B;
+        t.eq(b.a, "bar", "ctor overwritten");
+    }
+
+    function test_overwrite_4(t) {
+        // overwrite constructor of parent class
+        t.plan(1);
+        var A = OpenLayers.Class({
+            initialize: function() {
+                this.a = "foo";
+            }
+        });
+        var B = OpenLayers.Class(A, {
+            initialize: function() {
+                A.prototype.initialize.call(this);
+            }
+        });
+        A = overwrite(A, {
+            initialize: function() {
+                this.a = "bar";
+            }
+        });
+        var b = new B;
+        t.eq(b.a, "bar", "ctor overwritten");
+    }
+
+    function test_overwrite_5(t) {
+        // overwrite constructor of parent class, which itself
+        // doesn't defined "initialize"
+        t.plan(2);
+        var A = OpenLayers.Class({
+            initialize: function() {
+                this.a = "foo";
+            }
+        });
+        var B = OpenLayers.Class(A, {});
+        var _A = A;
+        A = overwrite(A, {
+            initialize: function() {
+                this.a = "bar";
+            }
+        });
+        var b = new B;
+        t.ok(A.prototype === _A.prototype, "A and _A share the prototype");
+        t.eq(b.a, "bar", "ctor overwritten");
+    }
+
+    function test_overwrite_6(t) {
+        // with static methods
+        t.plan(1);
+        var A = OpenLayers.Class({
+            initialize: function() {
+            }
+        });
+        A.staticMethod = function() {};
+        A = overwrite(A, {
+            initialize: function() {
+            }
+        });
+        var exc = false;
+        try {
+            A.staticMethod();
+        } catch(e) {
+            exc = true;
+        }
+        t.ok(!exc, "static method still there");
+    }
   </script>
 </head>
 <body>

Copied: sandbox/august/trunk/tests/BaseTypes/Date.html (from rev 12408, trunk/openlayers/tests/BaseTypes/Date.html)
===================================================================
--- sandbox/august/trunk/tests/BaseTypes/Date.html	                        (rev 0)
+++ sandbox/august/trunk/tests/BaseTypes/Date.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,170 @@
+<html>
+<head>
+  <script src="../OLLoader.js"></script>
+  <script type="text/javascript">
+
+    function test_Date_toISOString(t) {
+        t.plan(3);
+    
+        var date, str;
+
+        // check valid date
+        date = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));
+        str = OpenLayers.Date.toISOString(date);
+        t.eq(str, "2010-11-27T18:19:15.123Z", "valid date");
+        
+        // check zero padding
+        date = new Date(Date.UTC(2010, 7, 7, 18, 9, 5, 12));
+        str = OpenLayers.Date.toISOString(date);
+        t.eq(str, "2010-08-07T18:09:05.012Z", "zero padding");
+        
+        // check invalid date
+        date = new Date("foo");
+        try {
+            str = OpenLayers.Date.toISOString(date);
+        } catch (err) {
+            // some implementations throw RangeError
+            // see https://bugzilla.mozilla.org/show_bug.cgi?id=649575
+            if (err instanceof RangeError) {
+                str = "Invalid Date";
+            }
+        }
+        t.eq(str, "Invalid Date", "invalid date");
+
+    }
+    
+    function test_Date_parse(t) {
+        
+        t.plan(93);
+        
+        var cases = {
+            "2000": {
+                year: 2000,
+                month: 0,
+                date: 1
+            },
+            "2005-10": {
+                year: 2005,
+                month: 9,
+                date: 1
+            },
+            "1971-07-23": {
+                year: 1971,
+                month: 6,
+                date: 23
+            },
+            "1801-11-20T04:30:15Z": {
+                year: 1801,
+                month: 10,
+                date: 20,
+                hour: 4,
+                minutes: 30,
+                seconds: 15
+            },
+            "1989-06-15T18:30:15.91Z": {
+                year: 1989,
+                month: 5,
+                date: 15,
+                hour: 18,
+                minutes: 30,
+                seconds: 15,
+                milliseconds: 910
+            },
+            "1989-06-15T18:30:15.091Z": {
+                year: 1989,
+                month: 5,
+                date: 15,
+                hour: 18,
+                minutes: 30,
+                seconds: 15,
+                milliseconds: 91
+            },
+            "1989-06-15T13:30:15.091-05": {
+                year: 1989,
+                month: 5,
+                date: 15,
+                hour: 18,
+                minutes: 30,
+                seconds: 15,
+                milliseconds: 91
+            },
+            "2010-08-06T15:21:25-06": { // MDT
+                year: 2010,
+                month: 7,
+                date: 6,
+                hour: 21,
+                minutes: 21,
+                seconds: 25
+            },
+            "2010-08-07T06:21:25+9": { // JSP
+                year: 2010,
+                month: 7,
+                date: 6,
+                hour: 21,
+                minutes: 21,
+                seconds: 25
+            },
+            "2010-08-07T02:51:25+05:30": { // IST
+                year: 2010,
+                month: 7,
+                date: 6,
+                hour: 21,
+                minutes: 21,
+                seconds: 25
+            },
+            "T21:51:25Z": {
+                hour: 21,
+                minutes: 51,
+                seconds: 25
+            },
+            "T02:51:25+05:30": { // IST
+                hour: 21,
+                minutes: 21,
+                seconds: 25
+            },
+            "T2:51:25.1234-7": { // lenient
+                hour: 9,
+                minutes: 51,
+                seconds: 25,
+                milliseconds: 123
+            }
+        };
+
+        var o, got, exp;
+        for (var str in cases) {
+            o = cases[str];
+            got = OpenLayers.Date.parse(str);
+            exp = new Date(Date.UTC(o.year || 0, o.month || 0, o.date || 1, o.hour || 0, o.minutes || 0, o.seconds || 0, o.milliseconds || 0));
+            if ("year" in o) {
+                t.eq(got.getUTCFullYear(), exp.getUTCFullYear(), str + ": correct UTCFullYear");
+                t.eq(got.getUTCMonth(), exp.getUTCMonth(), str + ": correct UTCMonth");
+                t.eq(got.getUTCDate(), exp.getUTCDate(), str + ": correct UTCDate");
+            } else {
+                t.ok(true, str + ": ECMA doesn't specify how years are handled in time only strings");
+                t.ok(true, str + ": ECMA doesn't specify how months are handled in time only strings");
+                t.ok(true, str + ": ECMA doesn't specify how days are handled in time only strings");
+            }
+            if ("hour" in o) {
+                t.eq(got.getUTCHours(), exp.getUTCHours(), str + ": correct UTCHours");
+                t.eq(got.getUTCMinutes(), exp.getUTCMinutes(), str + ": correct UTCMinutes");
+                t.eq(got.getUTCSeconds(), exp.getUTCSeconds(), str + ": correct UTCSeconds");
+                t.eq(got.getUTCMilliseconds(), exp.getUTCMilliseconds(), str + ": correct UTCMilliseconds");
+            } else {
+                t.ok(true, str + ": ECMA doesn't specify how hours are handled in date only strings");
+                t.ok(true, str + ": ECMA doesn't specify how minutes are handled in date only strings");
+                t.ok(true, str + ": ECMA doesn't specify how seconds are handled in date only strings");
+                t.ok(true, str + ": ECMA doesn't specify how milliseconds are handled in date only strings");
+            }
+        }
+        
+        // check invalid date parsing
+        var invalid = OpenLayers.Date.parse("foo");
+        t.ok(invalid instanceof Date, "invalid is a date");
+        t.ok(isNaN(invalid.getTime()), "invalid has no time");
+    }
+
+  </script>
+</head>
+<body>
+</body>
+</html>

Modified: sandbox/august/trunk/tests/BaseTypes/LonLat.html
===================================================================
--- sandbox/august/trunk/tests/BaseTypes/LonLat.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/BaseTypes/LonLat.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -107,12 +107,58 @@
     function test_LonLat_fromString(t) {
         t.plan( 2 );
         lonlat = OpenLayers.LonLat.fromString("6,5");
-        t.ok( lonlat instanceof OpenLayers.LonLat, "new OpenLayers.LonLat returns LonLat object" );
+        t.ok( lonlat instanceof OpenLayers.LonLat, "OpenLayers.LonLat.fromString() returns LonLat object" );
 
         var ll = new OpenLayers.LonLat(6, 5);
         t.ok( lonlat.equals(ll), "lonlat is set correctly");
     }
+    
+    function test_LonLat_fromArray(t) {
+        t.plan( 3 );
+        
+        // (1 test) must return a OpenLayers.LonLat-instance 
+        lonlat = OpenLayers.LonLat.fromArray([6,5]);
+        t.ok( lonlat instanceof OpenLayers.LonLat, "OpenLayers.LonLat.fromArray returns LonLat object" );
 
+        var ll = new OpenLayers.LonLat(6, 5);
+        // (1 test) must return correct LonLat-object
+        t.ok( lonlat.equals(ll), "lonlat is set correctly");
+        
+        
+        // (1 test) check how function deals with illegal arguments, it should 
+        // never throw an exception and always return an instance of 
+        // OpenLayers.LonLat.
+        var unexpectedResult = false,
+            undef,
+            checkArgs = [
+                {},
+                '',
+                6,
+                false,
+                true,
+                [undef, 5],
+                [6, undef]
+            ],
+            returnedVal;
+            
+        try {
+            for(var i = 0, len = checkArgs.length; i < len; i++ ){
+                returnedVal = OpenLayers.LonLat.fromArray( checkArgs[i] );
+                if (!(returnedVal instanceof OpenLayers.LonLat) ) {
+                    unexpectedResult = true;
+                    break;
+                }
+            }
+            // no arguments at all
+            returnedVal = OpenLayers.LonLat.fromArray();
+            unexpectedResult = !(returnedVal instanceof OpenLayers.LonLat);
+        } catch(e) {
+            unexpectedResult = true;
+        } finally {
+            t.ok(!unexpectedResult, "OpenLayers.LonLat.fromArray always returns an instance of OpenLayers.LonLat and doesn't throw an exception when called with unexpected argument.");
+        }
+    }
+
     function test_LonLat_transform(t) {
         t.plan( 6 );
         lonlat = new OpenLayers.LonLat(10, -10);

Modified: sandbox/august/trunk/tests/BaseTypes.html
===================================================================
--- sandbox/august/trunk/tests/BaseTypes.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/BaseTypes.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -364,160 +364,6 @@
         
     }
 
-    function test_Date_toISOString(t) {
-        t.plan(3);
-    
-        var date, str;
-
-        // check valid date
-        date = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));
-        str = OpenLayers.Date.toISOString(date);
-        t.eq(str, "2010-11-27T18:19:15.123Z", "valid date");
-        
-        // check zero padding
-        date = new Date(Date.UTC(2010, 7, 7, 18, 9, 5, 12));
-        str = OpenLayers.Date.toISOString(date);
-        t.eq(str, "2010-08-07T18:09:05.012Z", "zero padding");
-        
-        // check invalid date
-        date = new Date("foo");
-        str = OpenLayers.Date.toISOString(date);
-        t.eq(str, "Invalid Date", "invalid date");
-
-    }
-    
-    function test_Date_parse(t) {
-        
-        t.plan(93);
-        
-        var cases = {
-            "2000": {
-                year: 2000,
-                month: 0,
-                date: 1
-            },
-            "2005-10": {
-                year: 2005,
-                month: 9,
-                date: 1
-            },
-            "1971-07-23": {
-                year: 1971,
-                month: 6,
-                date: 23
-            },
-            "1801-11-20T04:30:15Z": {
-                year: 1801,
-                month: 10,
-                date: 20,
-                hour: 4,
-                minutes: 30,
-                seconds: 15
-            },
-            "1989-06-15T18:30:15.91Z": {
-                year: 1989,
-                month: 5,
-                date: 15,
-                hour: 18,
-                minutes: 30,
-                seconds: 15,
-                milliseconds: 910
-            },
-            "1989-06-15T18:30:15.091Z": {
-                year: 1989,
-                month: 5,
-                date: 15,
-                hour: 18,
-                minutes: 30,
-                seconds: 15,
-                milliseconds: 91
-            },
-            "1989-06-15T13:30:15.091-05": {
-                year: 1989,
-                month: 5,
-                date: 15,
-                hour: 18,
-                minutes: 30,
-                seconds: 15,
-                milliseconds: 91
-            },
-            "2010-08-06T15:21:25-06": { // MDT
-                year: 2010,
-                month: 7,
-                date: 6,
-                hour: 21,
-                minutes: 21,
-                seconds: 25
-            },
-            "2010-08-07T06:21:25+9": { // JSP
-                year: 2010,
-                month: 7,
-                date: 6,
-                hour: 21,
-                minutes: 21,
-                seconds: 25
-            },
-            "2010-08-07T02:51:25+05:30": { // IST
-                year: 2010,
-                month: 7,
-                date: 6,
-                hour: 21,
-                minutes: 21,
-                seconds: 25
-            },
-            "T21:51:25Z": {
-                hour: 21,
-                minutes: 51,
-                seconds: 25
-            },
-            "T02:51:25+05:30": { // IST
-                hour: 21,
-                minutes: 21,
-                seconds: 25
-            },
-            "T2:51:25.1234-7": { // lenient
-                hour: 9,
-                minutes: 51,
-                seconds: 25,
-                milliseconds: 123
-            }
-        };
-
-        var o, got, exp;
-        for (var str in cases) {
-            o = cases[str];
-            got = OpenLayers.Date.parse(str);
-            exp = new Date(Date.UTC(o.year || 0, o.month || 0, o.date || 1, o.hour || 0, o.minutes || 0, o.seconds || 0, o.milliseconds || 0));
-            if ("year" in o) {
-                t.eq(got.getUTCFullYear(), exp.getUTCFullYear(), str + ": correct UTCFullYear");
-                t.eq(got.getUTCMonth(), exp.getUTCMonth(), str + ": correct UTCMonth");
-                t.eq(got.getUTCDate(), exp.getUTCDate(), str + ": correct UTCDate");
-            } else {
-                t.ok(true, str + ": ECMA doesn't specify how years are handled in time only strings");
-                t.ok(true, str + ": ECMA doesn't specify how months are handled in time only strings");
-                t.ok(true, str + ": ECMA doesn't specify how days are handled in time only strings");
-            }
-            if ("hour" in o) {
-                t.eq(got.getUTCHours(), exp.getUTCHours(), str + ": correct UTCHours");
-                t.eq(got.getUTCMinutes(), exp.getUTCMinutes(), str + ": correct UTCMinutes");
-                t.eq(got.getUTCSeconds(), exp.getUTCSeconds(), str + ": correct UTCSeconds");
-                t.eq(got.getUTCMilliseconds(), exp.getUTCMilliseconds(), str + ": correct UTCMilliseconds");
-            } else {
-                t.ok(true, str + ": ECMA doesn't specify how hours are handled in date only strings");
-                t.ok(true, str + ": ECMA doesn't specify how minutes are handled in date only strings");
-                t.ok(true, str + ": ECMA doesn't specify how seconds are handled in date only strings");
-                t.ok(true, str + ": ECMA doesn't specify how milliseconds are handled in date only strings");
-            }
-        }
-        
-        // check invalid date parsing
-        var invalid = OpenLayers.Date.parse("foo");
-        t.ok(invalid instanceof Date, "invalid is a date");
-        t.ok(isNaN(invalid.getTime()), "invalid has no time");
-            
-
-    }
-
   </script>
 </head>
 <body>

Modified: sandbox/august/trunk/tests/Control/DrawFeature.html
===================================================================
--- sandbox/august/trunk/tests/Control/DrawFeature.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Control/DrawFeature.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -4,12 +4,10 @@
     <script type="text/javascript">
 
     function test_initialize(t) {
-        t.plan(2);
+        t.plan(1);
         var control = new OpenLayers.Control.DrawFeature("foo", function() {});
         t.ok(control instanceof OpenLayers.Control.DrawFeature,
              "constructor returns an instance");
-        t.ok(OpenLayers.Util.indexOf(control.EVENT_TYPES, "featureadded") > -1,
-             "featureadded event in EVENT_TYPES");
     }
     
     function test_multi(t) {

Modified: sandbox/august/trunk/tests/Control/EditingToolbar.html
===================================================================
--- sandbox/august/trunk/tests/Control/EditingToolbar.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Control/EditingToolbar.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -3,12 +3,14 @@
   <script src="../OLLoader.js"></script>
   <script type="text/javascript">
     function test_ctor_draw(t) {
-        t.plan(4);
+        t.plan(5);
         var map = new OpenLayers.Map('map');
         var vLayer = new OpenLayers.Layer.Vector();
         map.addLayer(vLayer);
         
-        var editingToolbar = new OpenLayers.Control.EditingToolbar(vLayer);
+        var editingToolbar = new OpenLayers.Control.EditingToolbar(vLayer, {
+            citeCompliant: "foo"
+        });
         map.addControl(editingToolbar);
         
         t.ok(editingToolbar instanceof OpenLayers.Control.EditingToolbar,
@@ -19,6 +21,7 @@
                 "First control is active" );
         t.eq(editingToolbar.controls.length, 4,
                 "EditingToolbar contains 4 Controls" );
+        t.eq(editingToolbar.controls[1].handler.citeCompliant, "foo", "citeCompliant option passed to handler correctly")
         
         map.destroy();
     }

Modified: sandbox/august/trunk/tests/Control/ModifyFeature.html
===================================================================
--- sandbox/august/trunk/tests/Control/ModifyFeature.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Control/ModifyFeature.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -74,7 +74,7 @@
     }
     
     function test_handleKeypress(t) {
-        t.plan(14);
+        t.plan(16);
 
         /**
          * There are two things that we want to test here
@@ -101,6 +101,8 @@
         // mock up vertex deletion
         control.dragControl.feature = point;
         control.feature = poly;
+        // we cannot use selectFeature since the control is not part of a map
+        control._originalGeometry = poly.geometry.clone();
         control.vertices = [point];
         point.geometry.parent = {
             removeComponent: function(geometry) {
@@ -110,6 +112,7 @@
         };
         layer.events.on({
             "featuremodified": function(event) {
+                t.ok(event.feature.modified !== null, "modified property of feature should have been set");
                 t.eq(event.feature.id, poly.id, "vertex deletion: featuremodifed triggered");
             },
             "vertexremoved": function(evt) {

Modified: sandbox/august/trunk/tests/Control/Snapping.html
===================================================================
--- sandbox/august/trunk/tests/Control/Snapping.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Control/Snapping.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -236,6 +236,56 @@
         map.destroy();
     
     }
+
+    function test_filter(t) {
+        t.plan(3);
+        var map = new OpenLayers.Map("map", {
+            resolutions: [1],
+            maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)
+        });
+
+        var layer1 = new OpenLayers.Layer.Vector(null, {
+            isBaseLayer: true
+        });
+        var f1 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+            "LINESTRING(0 0, 10 10, 20 20, 30 30)"
+        ), {foo: 'bar'});
+        f1.fid = "FID1";
+        var f2 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+            "LINESTRING(11 10, 20 10, 30 10)"
+        ), {foo: 'bar'});
+        f2.fid = "FID2";
+        layer1.addFeatures([f1, f2]);
+        map.addLayers([layer1]);
+        map.zoomToMaxExtent();
+
+        var control = new OpenLayers.Control.Snapping({
+            layer: layer1,
+            targets: [layer1],
+            defaults: {tolerance: 4}
+        });
+        control.activate();
+
+        var result;
+        var loc = new OpenLayers.Geometry.Point(1, 1);
+
+        control.setTargets([{layer: layer1}]);
+        result = control.testTarget(control.targets[0], loc);
+        t.ok(result !== null, "target is eligible without a filter set");
+        var filter = new OpenLayers.Filter.Logical({
+            type: OpenLayers.Filter.Logical.NOT, 
+            filters: [
+                new OpenLayers.Filter.FeatureId({fids: ["FID1", "FID2"]})
+            ]
+        });
+        control.setTargets([{layer: layer1, filter: filter}]);
+        result = control.testTarget(control.targets[0], loc);
+        t.ok(result === null, "target is not eligible with a filter set which excludes the target's features");
+        filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, value: 'bar', property: 'foo'});
+        control.setTargets([{layer: layer1, filter: filter}]);
+        result = control.testTarget(control.targets[0], loc);
+        t.ok(result === null, "target is not eligible with a filter set which excludes the target's features using a comparison filter");
+    }
     
     function test_snapping(t) {
         

Modified: sandbox/august/trunk/tests/Events.html
===================================================================
--- sandbox/august/trunk/tests/Events.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Events.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -7,38 +7,22 @@
     var a;
     
     function test_Events_constructor (t) {
+        t.plan(4);
+
         var mapDiv = OpenLayers.Util.getElement('map');
         var obj = {result: 0};
-        var eventTypes = ["doThingA", "doThingB", "doThingC"];
-        var browserTypes = OpenLayers.Events.prototype.BROWSER_EVENTS;
 
-        var totalTests = 4 + 2*eventTypes.length + 2*browserTypes.length;
-
-        t.plan( totalTests );
-
-        events = new OpenLayers.Events(obj, mapDiv, eventTypes);
-
+        events = new OpenLayers.Events(obj, mapDiv);
         t.ok( events instanceof OpenLayers.Events, "new OpenLayers.Control returns object" );
-
         t.ok(events.object ==obj, " 'object' property correctly set");
         t.ok(events.element == mapDiv, " 'element' property correctly set");
+        events.destroy();
 
-
-        for (var i = 0; i < browserTypes.length; i++) {
-            var type = browserTypes[i];
-            t.ok( events.listeners[type] instanceof Array, "browser event: " + type + " correctly registered" );
-            t.ok( OpenLayers.Util.indexOf(events.eventTypes, type) != -1, "browser type " + type + "' correctly added to eventTypes array");
-        }
-        for (var i = 0; i < eventTypes.length; i++) {
-            var type = eventTypes[i];
-            t.ok( events.listeners[type] instanceof Array, "custom event: " + type + " correctly registered");
-            t.ok( OpenLayers.Util.indexOf(events.eventTypes, type) != -1, "eventType " + type + "' correctly added to eventTypes array");
-        }
-
         // default/nulls
         events = new OpenLayers.Events(null, null, null);
         t.ok( events.listeners != null,
               "init of Events with null object/element/eventTypes still creates listeners array" );
+        events.destroy();
     }
 
     function test_Events_register(t){
@@ -59,8 +43,7 @@
                                 gFuncB = options.func;
                             }
                 }
-            },
-            'eventTypes': ['listenerA', 'listenerB']
+            }
         };
 
         var type = null;
@@ -99,13 +82,12 @@
 
     function test_Events_register_unregister(t) {
  
-        t.plan( 18 );
+        t.plan(19);
  
         var mapDiv = OpenLayers.Util.getElement('map');
         var obj = {result: 0};
-        var eventTypes = ["doThingA", "doThingB", "doThingC"];
         
-        events = new OpenLayers.Events(obj, mapDiv, eventTypes);
+        events = new OpenLayers.Events(obj, mapDiv);
         
         var func = function () { this.result++ }
         events.register( "doThingA", obj, func );
@@ -136,9 +118,12 @@
         var listenerList = events.listeners["doThingA"];
         t.eq( listenerList.length, 3, "register correctly does not append null callback to event.listeners[doThingA] even when obj passed in is null" );
 
-        events.register( "chicken", obj, func);
-        t.ok( events.listeners["chicken"] == null, "register() does nothing on attempt to register un-enabled event");
+        events.register("chicken", obj, func);
+        t.eq(events.listeners["chicken"].length, 1, "register() allows listeners for any named event");
 
+        events.unregister("chicken", obj, func);
+        t.eq(events.listeners["chicken"].length, 0, "unregistering an event that is not in eventTypes list works")
+
         events.unregister("doThingA", obj, null);
         var listenerList = events.listeners["doThingA"];
         t.eq( listenerList.length, 3, "trying to unregister a null callback does nothing -- but doesnt crash :-)" );
@@ -174,10 +159,13 @@
         events.unregister("doThingA", obj, null);
         t.ok( (listenerList.length == 1), "unregister does not bomb if you try to remove a null callback" );
 
-        events.unregister("chicken", null, func3);
-        t.ok( events.listeners["chicken"] == null, "unregistering an event that is not enabled does not wierdly enable it -- or cause a script error")
+        try {
+            events.unregister("asdf", obj, func);
+            t.ok("unregistering for an event with no registered listeners works");
+        } catch (err) {
+            t.fail("unregistering for an event with no registered listeners causes trouble: " + err);
+        }
 
-
     }
 
     function test_Events_remove(t) {
@@ -186,9 +174,8 @@
  
         var mapDiv = OpenLayers.Util.getElement('map');
         var obj = {result: 0};
-        var eventTypes = ["doThingA", "doThingB", "doThingC"];
         
-        events = new OpenLayers.Events(obj, mapDiv, eventTypes);
+        events = new OpenLayers.Events(obj, mapDiv);
         
         var func = function () { this.result++ }
         var func2 = function () { this.result-- }
@@ -213,9 +200,8 @@
  
         var mapDiv = OpenLayers.Util.getElement('map');
         var obj = {result: 0};
-        var eventTypes = ["doThingA", "doThingB", "doThingC"];
         
-        events = new OpenLayers.Events(obj, mapDiv, eventTypes);
+        events = new OpenLayers.Events(obj, mapDiv);
         
         
         var func = function () { this.result++ }
@@ -248,7 +234,7 @@
         //no specific t.ok for this one, but if it breaks, you will know it.
         events.triggerEvent("chicken");
 
-        events = new OpenLayers.Events(null, mapDiv, eventTypes);
+        events = new OpenLayers.Events(null, mapDiv);
         
         // a is global variable (context-irrelevant)
         a = 0;
@@ -259,8 +245,7 @@
         t.eq(a, 5, "if Events has no object set and an event is registered also with no object, triggerEvent() calls it without trying to set the context to null");
         
         // trigger events with additional arguments
-        eventTypes = ["something"];
-        events = new OpenLayers.Events(null, null, eventTypes);
+        events = new OpenLayers.Events();
         var instance = {id: Math.random()};
         var listener = function(obj) {
             t.eq(this.id, instance.id,
@@ -309,7 +294,7 @@
 
     function test_Events_handleBrowserEvent(t) {
         t.plan(2);
-        var events = new OpenLayers.Events({}, null, ['sometouchevent']);
+        var events = new OpenLayers.Events({}, null);
         events.on({'sometouchevent': function() {}});
 
         // this test verifies that when handling a touch event we correctly
@@ -424,36 +409,6 @@
         
     }
 
-    function test_Events_addEventType(t) {
-
-        t.plan( 8 );
- 
-        var mapDiv = OpenLayers.Util.getElement('map');
-        var obj = {result: 0};
-        var eventTypes = ["doThingA", "doThingB"];
-
-        events = new OpenLayers.Events(obj, mapDiv, eventTypes);
-
-
-        t.eq( events.listeners["doThingA"].length, 0, "event type passed as passed as param to OpenLayers.Events constructor correctly set up" );
-        t.eq( events.listeners["doThingB"].length, 0, "event type passed as passed as param to OpenLayers.Events constructor correctly set up" );
-
-        var newEventType = "onFoo";
-        t.ok( events.listeners[newEventType] == null, "event type not yet registered has null entry in listeners array");
-        t.ok( OpenLayers.Util.indexOf(events.eventTypes, newEventType) == -1, "event type not yet registered not in eventTypes array");
-
-        events.addEventType(newEventType);
-        t.eq( events.listeners[newEventType].length, 0, "event type passed to addEventType correctly set up" );
-        t.ok( OpenLayers.Util.indexOf(events.eventTypes, newEventType) != -1, "event type passed to addEventType in eventTypes array");
-        
-        var func = function () {};
-        events.register( "doThingA", obj, func );
-        t.eq( events.listeners["doThingA"].length, 1, "listener correctly registered" );
-
-        events.addEventType("doThingsA");
-        t.eq( events.listeners["doThingA"].length, 1, "event type passed to addEventType correctly does nothing if clashes with already defined event type" );
-    }
-
     /** HACK HACK HACK Deprecated This test should be removed in 3.0 **/
     function test_Events_globalEventObject(t) {
         t.plan(1);

Modified: sandbox/august/trunk/tests/Format/Filter/v1.html
===================================================================
--- sandbox/august/trunk/tests/Format/Filter/v1.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/Filter/v1.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -7,7 +7,7 @@
 
         t.plan(6);
 
-        var test_wml, parser, xml;
+        var test_xml, parser, xml;
 
         parser = new OpenLayers.Format.Filter.v1();
         xml = new OpenLayers.Format.XML();

Modified: sandbox/august/trunk/tests/Format/GPX.html
===================================================================
--- sandbox/august/trunk/tests/Format/GPX.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/GPX.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -34,6 +34,85 @@
         t.eq(features[2].attributes['name'], "Mark", "Text attribute node read correctly.");
         t.eq(features[2].attributes['sym'], "Flag", "CDATA attribute node read correctly.");
     }
+    function test_Format_GPX_serialize_points(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var features = [
+            new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),
+            new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
+        ];
+        var data = parser.write(features);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><wpt lon="-111.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');
+    }
+    function test_Format_GPX_serialize_line(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+        var data = parser.write(f);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes line correctly');
+    }
+    function test_Format_GPX_serialize_lines(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var point3 = new OpenLayers.Geometry.Point(1, 2);  
+        var point4 = new OpenLayers.Geometry.Point(3, 4); 
+        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+        var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});
+        var data = parser.write([f, f2]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');
+    }
+    function test_Format_GPX_serialize_multiline(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var line = new OpenLayers.Geometry.LineString([point, point2]);
+        var point3 = new OpenLayers.Geometry.Point(1, 2);  
+        var point4 = new OpenLayers.Geometry.Point(3, 4); 
+        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+        var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);
+        var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});
+        var data = parser.write([f]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');
+    }
+    function test_Format_GPX_serialize_polygon(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  
+        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); 
+        var linearRing = new OpenLayers.Geometry.LinearRing([point, point2, point.clone()]);
+        var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
+        var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});
+        var data = parser.write([f]);
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/><trkpt lon="-111.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');
+    }
+    function test_Format_GPX_serialize_metadata(t) { 
+        t.plan(1);
+
+        var parser = new OpenLayers.Format.GPX();
+
+        var data = parser.write([], {name: 'foo', desc: 'bar'});
+        t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');
+    }
     </script> 
 </head> 
 <body> 

Modified: sandbox/august/trunk/tests/Format/KML.html
===================================================================
--- sandbox/august/trunk/tests/Format/KML.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/KML.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -230,6 +230,18 @@
         };
         t.eq(f.read(f.write(feature))[0].attributes.name, feature.style.label, "placemark name from style.label");
     }
+    function test_Format_KML_linestring_projected(t) {
+        t.plan(1);
+        var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([
+            new OpenLayers.Geometry.Point(15555162, 4247484), new OpenLayers.Geometry.Point(15555163, 4247485)]));
+        var format = new OpenLayers.Format.KML({
+            internalProjection: new OpenLayers.Projection("EPSG:900913"),
+            externalProjection: new OpenLayers.Projection("EPSG:4326")
+        });
+        var data = format.write(f);
+        var found = (data.search('139.734') != -1);
+        t.ok(found, "Found 139.734 (correct reprojection) in data output.");
+    }        
     
     function test_extractTracks(t) {
         

Modified: sandbox/august/trunk/tests/Format/WFST/v1.html
===================================================================
--- sandbox/august/trunk/tests/Format/WFST/v1.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/WFST/v1.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -45,7 +45,7 @@
         deleteFeature.state = OpenLayers.State.DELETE;
         deleteFeature.fid = "fid.37";
 
-        t.plan(7);
+        t.plan(8);
         var snippets = {
             "GetFeature": {handle: "handle_g", maxFeatures: 1, outputFormat: 'json'},
             "Transaction": {handle: "handle_t"},
@@ -74,6 +74,14 @@
         var expected = readXML("UpdateModifiedNoGeometry");
         var got = format.writers["wfs"]["Update"].apply(format, [{feature: updateFeature}]);
         t.xml_eq(got, expected, "Update request for feature with no modified geometry but modified attributes created correctly");
+
+        // test for a feature that originally had a null geometry and a null value for the attribute
+        updateFeature.modified = {attributes: {foo: null, nul: "nul"}, geometry: null};
+        updateFeature.attributes.foo = "bar";
+        updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);
+        var expected = readXML("UpdateModified");
+        var got = format.writers["wfs"]["Update"].apply(format, [{feature: updateFeature}]);
+        t.xml_eq(got, expected, "Update request for feature with modified geometry created correctly even if original geometry was null");
     }
 
     function test_writeNative(t) {

Modified: sandbox/august/trunk/tests/Format/WMSCapabilities/v1_1_1.html
===================================================================
--- sandbox/august/trunk/tests/Format/WMSCapabilities/v1_1_1.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/WMSCapabilities/v1_1_1.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -111,7 +111,7 @@
 
     function test_layers(t) {
 
-        t.plan(22);
+        t.plan(24);
 
         var xml = document.getElementById("ogcsample").firstChild.nodeValue;
         var doc = new OpenLayers.Format.XML().read(xml);
@@ -143,7 +143,11 @@
              [189000, 834000, 285000, 962000],
              "Correct bbox from BoundingBox");
         t.eq(bbox.res, {x: 1, y: 1}, "Correct resolution");
-
+        bbox = layers["ROADS_RIVERS"].bbox["EPSG:4326"];
+        t.eq(bbox.bbox,
+             [-71.63, 41.75, -70.78, 42.90],
+             "Correct bbox from BoundingBox (override)");
+        t.eq(bbox.res, {x: 0.01, y: 0.01}, "Correct resolution (override)");
         bbox = layers["ROADS_1M"].bbox["EPSG:26986"];
         t.eq(bbox.bbox,
              [189000, 834000, 285000, 962000],
@@ -531,12 +535,12 @@
   <Layer>
     <Title>Acme Corp. Map Server</Title>
     <SRS>EPSG:4326</SRS>
+    <BoundingBox SRS="EPSG:4326"
+     minx="-1" miny="-1" maxx="1" maxy="1" resx="0.0" resy="0.0"/>
     <AuthorityURL name="DIF_ID">
       <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
        xlink:href="http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html" />
     </AuthorityURL>
-
-
     <Layer>
       <Name>ROADS_RIVERS</Name> 
       <Title>Roads and Rivers</Title>

Modified: sandbox/august/trunk/tests/Format/WMSCapabilities/v1_3_0.html
===================================================================
--- sandbox/august/trunk/tests/Format/WMSCapabilities/v1_3_0.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Format/WMSCapabilities/v1_3_0.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -14,7 +14,7 @@
 
     function test_layers(t) {
 
-        t.plan(22);
+        t.plan(24);
 
         var xml = document.getElementById("ogcsample").firstChild.nodeValue;
         var doc = new OpenLayers.Format.XML().read(xml);
@@ -46,6 +46,11 @@
              [189000, 834000, 285000, 962000],
              "Correct bbox from BoundingBox");
         t.eq(bbox.res, {x: 1, y: 1}, "Correct resolution");
+        bbox = layers["ROADS_RIVERS"].bbox["CRS:84"];
+        t.eq(bbox.bbox,
+             [-71.63, 41.75, -70.78, 42.90],
+             "Correct bbox from BoundingBox (override)");
+        t.eq(bbox.res, {x: 0.01, y: 0.01}, "Correct resolution (override)");
 
         bbox = layers["ROADS_1M"].bbox["EPSG:26986"];
         t.eq(bbox.bbox,
@@ -432,6 +437,8 @@
       <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
        xlink:href="http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html" />
     </AuthorityURL>
+    <BoundingBox CRS="CRS:84"
+     minx="-1" miny="-1" maxx="1" maxy="1" resx="0.0" resy="0.0"/>
     <Layer>
 
       <Name>ROADS_RIVERS</Name>

Modified: sandbox/august/trunk/tests/Handler/Path.html
===================================================================
--- sandbox/august/trunk/tests/Handler/Path.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Handler/Path.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1301,6 +1301,107 @@
         
         map.destroy();
     }
+
+    function test_set_freehand(t) {
+        t.plan(5);
+        var map = new OpenLayers.Map("map", {
+            resolutions: [1]
+        });
+        var layer = new OpenLayers.Layer.Vector("foo", {
+            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+            isBaseLayer: true
+        });
+        map.addLayer(layer);
+        var control = new OpenLayers.Control({});
+
+        var geo, pointsCount;        
+        var handler = new OpenLayers.Handler.Path(control, {
+                done: function(g) {
+                    geo = g;
+                },
+                point: function() {
+                    pointsCount++;
+                }
+            },
+            {freehand: true}
+        );
+        control.handler = handler;
+        map.addControl(control);
+        map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+
+        handler.activate();
+
+        geo = null;
+        pointsCount = 0;
+        // Using mouse events
+        handler.mousemove(
+                {type: "mousemove", xy: new OpenLayers.Pixel(0, 0)});
+        handler.mousedown(
+                {type: "mousedown", xy: new OpenLayers.Pixel(0, 0)});
+        handler.mousemove(
+                {type: "mousemove", xy: new OpenLayers.Pixel(1, 1)});
+        handler.mousemove(
+                {type: "mousemove", xy: new OpenLayers.Pixel(2, 2)});
+        handler.mouseup(
+                {type: "mouseup", xy: new OpenLayers.Pixel(2, 2)});
+        t.ok(geo != null, "feature drawn when mouseup");
+        t.eq(pointsCount, 2, "two points have been added");
+
+        handler.deactivate();
+        var geoMouse = geo;
+        
+        handler.activate();
+        
+        geo = null;
+        pointsCount = 0;
+        // Using touch events
+        handler.touchstart(
+                {type: "touchstart", xy: new OpenLayers.Pixel(0, 0)});
+        try {
+            handler.touchmove(
+                    {type: "touchmove", xy: new OpenLayers.Pixel(1, 1)});
+            handler.touchmove(
+                    {type: "touchmove", xy: new OpenLayers.Pixel(2, 2)});
+            handler.touchend(
+                    {type: "touchend"});
+        } catch(err) {
+            t.fail("occurred errors using touch events");
+        }
+        t.ok(geo != null, "feature drawn when touchend");
+        t.eq(pointsCount, 2, "two points have been added");
+        
+        t.geom_eq(geo, geoMouse, 
+            "geometry obtained using the mouse and touch events are the same");
+
+        map.destroy();
+    }
+
+    function test_citeComplaint(t) {
+        t.plan(2);
+        var map = new OpenLayers.Map('map');
+        map.addLayer(new OpenLayers.Layer.OSM());
+        var layer = new OpenLayers.Layer.Vector();
+        map.addLayer(layer);
+        var control = new OpenLayers.Control({});
+        var handler = new OpenLayers.Handler.Path(control, {});
+        control.handler = handler;
+        map.addControl(control);
+        map.zoomToExtent(new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418));
+        handler.activate();
+        handler.createFeature(new OpenLayers.Pixel(100, 50));
+        t.ok(handler.point.geometry.x < 0, "Geometry started correctly when wrapping the dateline using citeCompliant false");
+        control.deactivate();
+
+        handler = new OpenLayers.Handler.Path(control, {}, {citeCompliant: true});
+        control.handler = handler;
+        control.activate();
+        handler.createFeature(new OpenLayers.Pixel(100, 50));
+        t.ok(handler.point.geometry.x > 0, "Geometry started correctly when wrapping the dateline using citeCompliant true");
+        
+        map.destroy();
+    }
+
+
   </script>
 </head>
 <body>

Modified: sandbox/august/trunk/tests/Handler/Polygon.html
===================================================================
--- sandbox/august/trunk/tests/Handler/Polygon.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Handler/Polygon.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1128,6 +1128,31 @@
         map.destroy();
     }
 
+    function test_citeComplaint(t) {
+        t.plan(2);
+        var map = new OpenLayers.Map('map');
+        map.addLayer(new OpenLayers.Layer.OSM());
+        var layer = new OpenLayers.Layer.Vector();
+        map.addLayer(layer);
+        var control = new OpenLayers.Control({});
+        var handler = new OpenLayers.Handler.Polygon(control, {});
+        control.handler = handler;
+        map.addControl(control);
+        map.zoomToExtent(new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418));        
+        control.activate();
+        handler.createFeature(new OpenLayers.Pixel(100, 50));
+        t.ok(handler.point.geometry.x < 0, "Geometry started correctly when wrapping the dateline using citeCompliant false");
+        control.deactivate();
+
+        var handler = new OpenLayers.Handler.Polygon(control, {}, {citeCompliant: true});
+        control.handler = handler;
+        control.activate();
+        handler.createFeature(new OpenLayers.Pixel(100, 50));
+        t.ok(handler.point.geometry.x > 0, "Geometry started correctly when wrapping the dateline using citeCompliant true");
+
+        map.destroy();
+    }
+
   </script>
 </head>
 <body>

Modified: sandbox/august/trunk/tests/Handler/RegularPolygon.html
===================================================================
--- sandbox/august/trunk/tests/Handler/RegularPolygon.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Handler/RegularPolygon.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -149,9 +149,6 @@
     function test_Handler_RegularPolygon_irregular(t) {
         t.plan(4);
         var map = {
-            getLonLatFromPixel: function(px) {
-                return {lon: px.x, lat: px.y};
-            },
             getResolution: function() {
                 return 1;
             }
@@ -164,6 +161,9 @@
                 t.eq(ring.components[0].y, 10, "correct bottom");
                 t.eq(ring.components[2].x, 10, "correct left");
                 t.eq(ring.components[2].y, 15, "correct top");
+            },
+            getLonLatFromViewPortPx: function(px) {
+                return {lon: px.x, lat: px.y};
             }
         };
         var control = {};
@@ -190,11 +190,7 @@
         t.plan(1);
 
         // setup
-        var map = new OpenLayers.Map("map", {
-            getLonLatFromPixel: function(px) {
-                return {lon: px.x, lat: px.y};
-            }
-        });
+        var map = new OpenLayers.Map("map");
 
         var control = {"map": map};
 
@@ -211,6 +207,17 @@
 
         var isLeftClick = OpenLayers.Event.isLeftClick;
         OpenLayers.Event.isLeftClick = function() { return true; };
+        handler.layer = {
+            renderer: {
+                clear: OpenLayers.Function.Void
+            },
+            addFeatures: OpenLayers.Function.Void,
+            drawFeature: OpenLayers.Function.Void,
+            destroyFeatures: OpenLayers.Function.Void,
+            getLonLatFromViewPortPx: function() {
+                return xy;
+            }
+        };
 
         // test
         map.events.triggerEvent("mousedown", {"xy": xy});

Modified: sandbox/august/trunk/tests/Layer/ArcGIS93Rest.html
===================================================================
--- sandbox/august/trunk/tests/Layer/ArcGIS93Rest.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/ArcGIS93Rest.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -72,20 +72,15 @@
         tParams = OpenLayers.Util.extend(tParams, {
             FORMAT: "png", BBOX: "1,2,3,4", SIZE: "256,256", F: "image", BBOXSR: "4326", IMAGESR: "4326"
         });
-        t.eq( img.src,
+        t.eq( tile.url,
              url + "?" + OpenLayers.Util.getParameterString(tParams),
              "image src is created correctly via addtile" );
         t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" );
         t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" );
 
         var firstChild = layer.div.firstChild.firstChild;
-        if (!isMozilla)
-            t.ok( true, "skipping element test outside of Mozilla");
-        else
-            t.ok( firstChild instanceof HTMLElement, "div first child is an image object" );
-        t.eq( firstChild.src,
-             url + "?" + OpenLayers.Util.getParameterString(tParams),
-             "div first child is correct image object" );
+        t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
+        t.ok( firstChild == img, "div first child is correct image object" );
         t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
         map.destroy();
     }
@@ -302,55 +297,46 @@
         var encodingHack = document.createElement("img");
         
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src no filter" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src no filter" );
         
         layer.setLayerFilter('1', "MR_TOAD = 'FLYING'");
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'FLYING';";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src one filter" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src one filter" );
 
         layer.setLayerFilter('1', "MR_TOAD = 'NOT FLYING'");
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src change one filter" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src change one filter" );
 
         layer.setLayerFilter('2', "true = false");
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';2:true = false;";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src two filters" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src two filters" );
 
         layer.setLayerFilter('99', "some_col > 5");
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';2:true = false;99:some_col > 5;";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src three filters" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src three filters" );
         
         layer.clearLayerFilter('2');
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';99:some_col > 5;";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src removed middle filter" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed middle filter" );
         
         layer.clearLayerFilter('2');
         tParams["LAYERDEFS"] = "1:MR_TOAD = 'NOT FLYING';99:some_col > 5;";
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src removed missing filter (no change)" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed missing filter (no change)" );
         
         layer.clearLayerFilter();
         delete tParams["LAYERDEFS"];
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src removed all filters" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed all filters" );
         
         layer.clearLayerFilter();
         tile.draw();
-        encodingHack.src = (url + "?" + OpenLayers.Util.getParameterString(tParams));
-        t.eq( tile.imgDiv.src, encodingHack.src, "image src removed all (no) filters" );
+        t.eq( tile.url, url + "?" + OpenLayers.Util.getParameterString(tParams), "image src removed all (no) filters" );
     }
     
     

Modified: sandbox/august/trunk/tests/Layer/ArcGISCache.html
===================================================================
--- sandbox/august/trunk/tests/Layer/ArcGISCache.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/ArcGISCache.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -219,6 +219,32 @@
         t.ok((tile.x >= 0 && tile.y >= 0), 'layer should not generate negative tile ranges for level of detail');
     }
 
+   /*  
+    * Test that messing up the Array.prototype does not mess up the lods of the layer. 
+    * This messes up zooming when resolutions are very small/scales are very large/zoomed way in. 
+    */ 
+    function test_Layer_ARCGISCACHE_lods (t) { 
+        t.plan( 2 ); 
+        var layerInfo = capabilitiesObject; 
+
+        lods = layerInfo.tileInfo.lods.length; 
+
+        // mess up the Array prototype
+        Array.prototype.foo = function() { };
+
+        t.ok( lods == layerInfo.tileInfo.lods.length, 'proper number of "Levels of Detail" before initialization' ); 
+
+        // initialize the layer using the JSON object from an arcgis server 
+        // see: ArcGISCache.json 
+        var layer = new OpenLayers.Layer.ArcGISCache(name, url, { 
+            layerInfo: layerInfo 
+        }); 
+
+        t.ok( lods == layer.lods.length, 'proper number of "Levels of Detail" after initialization.' );         
+        // restore the Array prototype
+        delete Array.prototype.foo;
+    } 
+
   </script>
 </head>
 <body>

Deleted: sandbox/august/trunk/tests/Layer/GoogleNG.html
===================================================================
--- sandbox/august/trunk/tests/Layer/GoogleNG.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/GoogleNG.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,104 +0,0 @@
-<html>
-<head>
-  <script src="http://maps.google.com/maps/api/js?sensor=false&v=3.5"></script>
-  <script src="../OLLoader.js"></script>
-  <script type="text/javascript">
-    var map, layer; 
-
-    function test_constructor(t) {
-        t.plan(2);
-                       
-        layer = new OpenLayers.Layer.GoogleNG({type: google.maps.MapTypeId.HYBRID});
-        t.ok(layer instanceof OpenLayers.Layer.GoogleNG, "returns OpenLayers.Layer.GoogleNG object" );
-        t.eq(layer.type, google.maps.MapTypeId.HYBRID, "Layer type set");
-    }
-    
-    function test_initLayer(t) {
-        t.plan(6);
-
-        map = new OpenLayers.Map("map");
-        var log = {};
-        layer = new OpenLayers.Layer.GoogleNG({
-            numZoomLevels: 10,
-            maxResolution: 39135.7584765625,
-            initLayer: function() {
-                log[layer.id] = true;
-                OpenLayers.Layer.GoogleNG.prototype.initLayer.apply(this, arguments);
-            }
-        });
-        map.addLayer(layer);
-        map.zoomToMaxExtent();
-        
-        var map2 = new OpenLayers.Map("map2");
-        var minZoom = 1;
-        var layer2 = new OpenLayers.Layer.GoogleNG({
-            numZoomLevels: 24,
-            initLayer: function() {
-                log[layer2.id] = true;
-                var origMinZoom = OpenLayers.Layer.GoogleNG.mapObject.mapTypes[layer2.type].minZoom;
-                // pretend the API reports a different minZoom
-                OpenLayers.Layer.GoogleNG.mapObject.mapTypes[layer2.type].minZoom = minZoom;
-                OpenLayers.Layer.GoogleNG.prototype.initLayer.apply(this, arguments);
-                OpenLayers.Layer.GoogleNG.mapObject.mapTypes[layer2.type].minZoom = origMinZoom;
-            }
-        });
-        map2.addLayer(layer2);
-        map2.zoomToMaxExtent();
-        
-        t.delay_call(1, function() {
-            t.eq(log[layer.id], true, "initLayer called for 1st layer");
-            t.eq(log[layer2.id], true, "initLayer called for 2nd layer");
-            
-            t.eq(layer.numZoomLevels, 10, "numZoomLevels from configuration takes precedence if lower");
-            t.eq(layer2.numZoomLevels, OpenLayers.Layer.GoogleNG.mapObject.mapTypes[layer2.type].maxZoom + 1 - minZoom, "numZoomLevels from API takes precedence if lower");
-
-            t.eq(layer.maxResolution, 39135.7584765625, "maxResolution from configuration takes precedence if higher");
-            t.eq(layer2.maxResolution, 78271.516953125, "maxResolution from API takes precedence if higher");
-
-            map.destroy();
-            map2.destroy();            
-        });
-    }
-    
-    function test_attribution(t) {
-        t.plan(4);
-        
-        var log = [];
-        map = new OpenLayers.Map("map");
-        layer = new OpenLayers.Layer.GoogleNG({
-            type: google.maps.MapTypeId.HYBRID,
-            updateAttribution: function(copyrights) {
-                log.push(copyrights);
-                OpenLayers.Layer.GoogleNG.prototype.updateAttribution.apply(this, arguments);
-            }
-        });
-        map.addLayer(layer);
-        map.setCenter(new OpenLayers.LonLat(16, 48).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()), 5);
-        
-        t.delay_call(3, function() {
-            t.eq(log.length, 1, "updateAttribution was called once");
-            t.ok(log[0]["m"].length && log[0]["k"].length, "'m' and 'k' copyrights populated for hybrid layer");
-            t.ok(layer.attribution.indexOf('olGoogleAttribution hybrid') != -1, "Attribution has the correct css class");
-            t.ok(layer.attribution.indexOf('?ll=48,16&z=5&t=h"') != -1, "maps.google.com link has correct parameters");
-            map.destroy();
-        });
-    }
-
-    function test_clone(t) {
-        t.plan(2);
-        
-        var clone;
-        
-        layer = new OpenLayers.Layer.GoogleNG({type: google.maps.MapTypeId.HYBRID});
-        clone = layer.clone();
-        t.ok(clone instanceof OpenLayers.Layer.GoogleNG, "clone is a Layer.GoogleNG instance");
-        t.eq(clone.type, google.maps.MapTypeId.HYBRID, "with the correct map type");
-    }
-
-  </script>
-</head>
-<body>
-<div id="map" style="width:500px;height:550px"></div>
-<div id="map2" style="width:500px;height:550px"></div>
-</body>
-</html>

Modified: sandbox/august/trunk/tests/Layer/Grid.html
===================================================================
--- sandbox/august/trunk/tests/Layer/Grid.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/Grid.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -6,10 +6,8 @@
     var layer; 
 
     var name = 'Test Layer';
-    var url = "http://octo.metacarta.com/cgi-bin/mapserv";
-    var params = { map: '/mapdata/vmap_wms.map', 
-                   layers: 'basic', 
-                   format: 'image/png'};
+    var url = "http://vmap0.tiles.osgeo.org/wms/vmap0";
+    var params = {layers: 'basic', format: 'image/png'};
 
     /**
      *  NOTE TO READER:
@@ -23,19 +21,14 @@
 
 
     function test_Layer_Grid_constructor (t) {
-        t.plan( 8 );
+        t.plan( 5 );
                        
         layer = new OpenLayers.Layer.Grid(name, url, params, null);
         t.ok( layer instanceof OpenLayers.Layer.Grid, "returns OpenLayers.Layer.Grid object" );
         t.eq( layer.buffer, 0, "buffer default is 0");
         t.eq( layer.ratio, 1.5, "ratio default is 1.5");
         t.eq( layer.numLoadingTiles, 0, "numLoadingTiles starts at 0");
-        t.ok( layer.events.listeners["tileloaded"] != null, "'tileloaded' event added to layer's event types");
-        t.ok( OpenLayers.Util.indexOf(layer.events.eventTypes, 'tileloaded') != -1 ,"'tileloaded' event added to layer's event types");
 
-        //regression testing for #1502
-        t.ok( layer.events.listeners['tileloaded'].length == 0, "no listeners for tileloaded preregister");        
-
         var obj = {};
         var func = function() {};
         layer.events.register('tileloaded', obj, func);        

Modified: sandbox/august/trunk/tests/Layer/Image.html
===================================================================
--- sandbox/august/trunk/tests/Layer/Image.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/Image.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -77,11 +77,11 @@
 
         t.eq(layer.tile.position.x,-42, "Tile x positioned correctly at maxextent");
         t.eq(layer.tile.position.y,106, "Tile y positioned correctly at maxextent");
-        t.eq(layer.tile.imgDiv.src, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct");
+        t.eq(layer.tile.url, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct");
         map.zoomIn();
-        t.eq(layer.tile.imgDiv.src, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct");
+        t.eq(layer.tile.url, "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", "URL is correct");
         layer.setUrl('http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256');
-        t.eq(layer.tile.imgDiv.src, "http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256", "URL is correct after setURL");
+        t.eq(layer.tile.url, "http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256", "URL is correct after setURL");
     }
 /******
  * 

Modified: sandbox/august/trunk/tests/Layer/MapServer.html
===================================================================
--- sandbox/august/trunk/tests/Layer/MapServer.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/MapServer.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -53,20 +53,15 @@
                  imgy:128,
                  imgxy:[256,256]
         });
-        t.eq( img.src,
+        t.eq( tile.url,
              url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"),
              "image src is created correctly via addtile" );
         t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" );
         t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" );
 
         var firstChild = layer.div.firstChild.firstChild;
-        if (!isMozilla)
-            t.ok( true, "skipping element test outside of Mozilla");
-        else
-            t.ok( firstChild instanceof HTMLElement, "div first child is an image object" );
-        t.eq( firstChild.src,
-             url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"),
-             "div first child is correct image object" );
+        t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
+        t.ok( firstChild == img, "div first child is correct image object" );
         t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
         map.destroy();
     }

Modified: sandbox/august/trunk/tests/Layer/Text.html
===================================================================
--- sandbox/august/trunk/tests/Layer/Text.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/Text.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -173,7 +173,7 @@
         var event = {};
         t.delay_call( 1, function() {  
           t.ok(layer.markers[0].events, "First marker has an events object");
-          t.eq(layer.markers[0].events.listeners['click'].length, 0, "Marker events has one object");
+          t.eq(layer.markers[0].events.listeners['click'], undefined, "Marker events has no object");
           layer.markers[0].events.triggerEvent('click', event);
           t.eq(map.popups.length, 0, "no popup on first marker");
           layer.markers[1].events.triggerEvent('click', event);

Modified: sandbox/august/trunk/tests/Layer/Vector.html
===================================================================
--- sandbox/august/trunk/tests/Layer/Vector.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/Vector.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -286,6 +286,14 @@
         t.ok(extent.toBBOX() != layer.features[0].geometry.getBounds().toBBOX(), "extent from getDataExtent doesn't clobber first feature");
     }
 
+    function test_Layer_Vector_getDataExtentEmpty(t) {
+        t.plan(1);
+        var layer = new OpenLayers.Layer.Vector(name);
+        layer.addFeatures([new OpenLayers.Feature.Vector(null), new OpenLayers.Feature.Vector(null)]);
+        var extent = layer.getDataExtent();
+        t.eq(extent, null, "We expect null to be returned if there are no features with a geometry");
+    }
+
     function test_Layer_Vector_removeFeatures(t) {
         t.plan(17);
     

Modified: sandbox/august/trunk/tests/Layer/WMS/Post.html
===================================================================
--- sandbox/august/trunk/tests/Layer/WMS/Post.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/WMS/Post.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -73,8 +73,9 @@
         });
         map.addLayer(layer);
         var tile2 = layer.addTile(bounds, pixel);
-        t.ok(
-            tile2.createIFrame,
+        tile2.draw();
+        t.eq(
+            tile2.useIFrame, true,
             "supported browser: tile is created with the Tile.Image.IFrame mixin");
         map.destroy();
     }

Modified: sandbox/august/trunk/tests/Layer/WMS.html
===================================================================
--- sandbox/august/trunk/tests/Layer/WMS.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Layer/WMS.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -83,20 +83,15 @@
             BBOX: [1,2,3,4],
             WIDTH: "256", HEIGHT: "256"
         });
-        t.eq( img.src,
+        t.eq( tile.url,
              layer.getFullRequestString(tParams),
              "image src is created correctly via addtile" );
         t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" );
         t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" );
 
         var firstChild = layer.div.firstChild.firstChild;
-        if (!isMozilla)
-            t.ok( true, "skipping element test outside of Mozilla");
-        else
-            t.ok( firstChild instanceof HTMLElement, "div first child is an image object" );
-        t.eq( firstChild.src,
-             layer.getFullRequestString(tParams),
-             "div first child is correct image object" );
+        t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
+        t.ok( firstChild == img, "div first child is correct image object" );
         t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
         map.destroy();
     }
@@ -119,20 +114,15 @@
             BBOX: "1,2,3,4",
             WIDTH: "256", HEIGHT: "256"
         });
-        t.eq( img.src,
+        t.eq( tile.url,
              layer.getFullRequestString(tParams),
              "image src is created correctly via addtile" );
         t.eq( tile.frame.style.top, "6px", "image top is set correctly via addtile" );
         t.eq( tile.frame.style.left, "5px", "image top is set correctly via addtile" );
 
         var firstChild = layer.div.firstChild.firstChild;
-        if (!isMozilla)
-            t.ok( true, "skipping element test outside of Mozilla");
-        else
-            t.ok( firstChild instanceof HTMLElement, "div first child is an image object" );
-        t.eq( firstChild.src,
-             layer.getFullRequestString(tParams),
-             "div first child is correct image object" );
+        t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
+        t.ok( firstChild, img, "div first child is correct image object" );
         t.eq( tile.position.toString(), "x=5,y=6", "Position of tile is set correctly." );
         map.destroy();
     }

Modified: sandbox/august/trunk/tests/Map.html
===================================================================
--- sandbox/august/trunk/tests/Map.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Map.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1790,37 +1790,77 @@
     }    
 
     function test_moveByPx(t) {
-        t.plan(8);
+        t.plan(16);
 
+        var moved;
+        var Layer = OpenLayers.Class(OpenLayers.Layer, {
+            moveByPx: function(dx, dy) {
+                moved[this.name] = true;
+            }
+        });
+
         var map = new OpenLayers.Map({
             div: 'map',
             maxExtent: new OpenLayers.Bounds(-50, -50, 50, 50),
             restrictedExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
             layers: [
-                new OpenLayers.Layer('name', {isBaseLayer: true})
+                new Layer('base',
+                    {isBaseLayer: true}),
+                new Layer('outofrange',
+                    {isBaseLayer: false, minResolution:2})
             ]
         });
+
+        moved = {};
         map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));
 
         // check initial state
-        t.eq(map.layerContainerDiv.style.left, '0px', 'layer container left correct');
-        t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct');
+        t.eq(map.layerContainerDiv.style.left, '0px',
+             '[initial state] layer container left correct');
+        t.eq(map.layerContainerDiv.style.top, '0px',
+             '[initial state] layer container top correct');
+        t.eq(moved['base'], undefined,
+             '[initial state] base layer not moved');
+        t.eq(moved['outofrange'], undefined,
+             '[initial state] out-of-range layer not moved');
 
         // move to a valid position
+        moved = {};
         map.moveByPx(-455, 455);
-        t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
-        t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+        t.eq(map.layerContainerDiv.style.left, '455px',
+             '[valid position] layer container left correct');
+        t.eq(map.layerContainerDiv.style.top, '-455px',
+             '[valid position] layer container top correct');
+        t.eq(moved['base'], true,
+             '[valid position] base layer moved');
+        t.eq(moved['outofrange'], undefined,
+             '[valid position] out-of-range layer not moved');
 
         // move outside the max extent
+        moved = {};
         map.moveByPx(-4500, 4500);
-        t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
-        t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+        t.eq(map.layerContainerDiv.style.left, '455px',
+             '[outside max extent] layer container left correct');
+        t.eq(map.layerContainerDiv.style.top, '-455px',
+             '[outside max extent] layer container top correct');
+        t.eq(moved['base'], undefined,
+             '[outside max extent] base layer not moved');
+        t.eq(moved['outofrange'], undefined,
+             '[outside max extent] out-of-range layer not moved');
 
         // move outside the restricted extent
+        moved = {};
         map.moveByPx(-500, 500);
-        t.eq(map.layerContainerDiv.style.left, '455px', 'layer container left correct');
-        t.eq(map.layerContainerDiv.style.top, '-455px', 'layer container top correct');
+        t.eq(map.layerContainerDiv.style.left, '455px',
+             '[outside restricted extent] layer container left correct');
+        t.eq(map.layerContainerDiv.style.top, '-455px',
+             '[outside restricted extent] layer container top correct');
+        t.eq(moved['base'], undefined,
+             '[outside restricted extent] base layer not moved');
+        t.eq(moved['outofrange'], undefined,
+             '[outside restricted extent] out-of-range layer not moved');
 
+
         map.destroy();
     }
 

Modified: sandbox/august/trunk/tests/Popup.html
===================================================================
--- sandbox/august/trunk/tests/Popup.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Popup.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -29,7 +29,7 @@
     }
     
     function test_Popup_constructor (t) {
-        t.plan( 8 );
+        t.plan(9);
 
         var id = "chicken";
         var w = 500;
@@ -63,11 +63,17 @@
         for (var i = 0; i < OpenLayers.Event.observers[cacheID].length; i++) {
             var observer = OpenLayers.Event.observers[cacheID][i];
             if (observer.element == closeImgDiv) {
-                t.ok(true, "An event was registered for the close box element");
-                t.eq(observer.name, "click", "A click event was registered for the close box element");
-                //call the registered observer to make sure it's the right one
-                observer.observer();
-                break;
+                if (observer.name == "click") {
+                    t.ok(true, "A click event was registered for the close box element");
+                    //call the registered observer to make sure it's the right one
+                    observer.observer();
+                } else if (observer.name == "touchend") {
+                    t.ok(true, "A touchend event was registered for the close box element");
+                    //call the registered observer to make sure it's the right one
+                    observer.observer();
+                } else {
+                    t.fail("A " + observer.name + " event was registered for the close box element");
+                }
             }
         }
     }

Modified: sandbox/august/trunk/tests/Protocol/Script.html
===================================================================
--- sandbox/august/trunk/tests/Protocol/Script.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Protocol/Script.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -150,7 +150,7 @@
 
         t.eq(script.type, 'text/javascript',
             'created script has a correct type');
-        t.eq(script.src, 'http://bar_url/?k=bar_param&cb_key=cb_prefix%3AOpenLayers.Protocol.Script.getCallback(bar)',
+        t.eq(script.src, 'http://bar_url/?k=bar_param&cb_key=cb_prefix%3AOpenLayers.Protocol.Script.registry%5Bbar%5D',
             'created script has a correct url');
         t.eq(script.id, 'OpenLayers_Protocol_Script_bar',
             'created script has a correct id');

Modified: sandbox/august/trunk/tests/Protocol/WFS.html
===================================================================
--- sandbox/august/trunk/tests/Protocol/WFS.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Protocol/WFS.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -111,7 +111,8 @@
         var protocol = new OpenLayers.Protocol.WFS({
             url: "http://some.url.org",
             featurePrefix: "topp",
-            featureType: "tasmania_roads"
+            featureType: "tasmania_roads",
+            geometryName: null
         });
 
         protocol.parseResponse({responseText: document.getElementById("query_response").firstChild.nodeValue});
@@ -299,7 +300,7 @@
     }
 
     function test_fromWMSLayer(t) {
-        t.plan(8);
+        t.plan(9);
         var map = new OpenLayers.Map("map", {
             projection: "EPSG:1234"
         });
@@ -313,6 +314,7 @@
         t.eq(protocol.featureType, "states", "typeName correctly extracted");
         t.eq(protocol.srsName, "EPSG:1234", "srsName set correctly");
         t.eq(protocol.version, "1.1.0", "version set correctly");
+        t.eq(protocol.format.geometryName, null, "format's geometryName set to null");
 
         layer.params["LAYERS"] = ["topp:street_centerline", "topp:states"];
         layer.projection = new OpenLayers.Projection("EPSG:900913");

Modified: sandbox/august/trunk/tests/Renderer/Canvas.html
===================================================================
--- sandbox/august/trunk/tests/Renderer/Canvas.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Renderer/Canvas.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -123,7 +123,7 @@
             return; 
         }
         
-        t.plan(8);
+        t.plan(10);
         var layer = new OpenLayers.Layer.Vector(null, {
             isBaseLayer: true,
             renderers: ["Canvas"]
@@ -183,6 +183,15 @@
         t.eq(count, 1, "d) redraw is called when drawing a feature outside renderer extent");
         renderer.clear();
         
+        // e) draw a polygon feature without bounds
+        count = 0;
+        exp = renderer.drawFeature(
+            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon()), {}
+        );
+        t.eq(exp, false, "d) drawFeature returns false");
+        t.eq(count, 1, "d) redraw is called when drawing a feature without bounds");
+        renderer.clear();
+
         map.destroy();
     }
 

Copied: sandbox/august/trunk/tests/Test.AnotherWay.baseadditions.js (from rev 12408, trunk/openlayers/tests/Test.AnotherWay.baseadditions.js)
===================================================================
--- sandbox/august/trunk/tests/Test.AnotherWay.baseadditions.js	                        (rev 0)
+++ sandbox/august/trunk/tests/Test.AnotherWay.baseadditions.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,177 @@
+// total counters
+Test.AnotherWay._openlayers_sum_total_detail_ok=0;
+Test.AnotherWay._openlayers_sum_total_detail_fail=0;
+Test.AnotherWay._startTime = null;
+
+// method overwrites
+//
+// behaviour (timing)
+Test.AnotherWay._old_run_all_onclick = Test.AnotherWay._run_all_onclick;
+Test.AnotherWay._run_all_onclick = function(){
+    Test.AnotherWay._startTime = (new Date()).getTime();
+    Test.AnotherWay.reset_running_time();
+    Test.AnotherWay._old_run_all_onclick.apply(this, arguments);
+};
+
+Test.AnotherWay._old_run_selected_onclick = Test.AnotherWay._run_selected_onclick;
+Test.AnotherWay._run_selected_onclick = function(){
+    Test.AnotherWay._startTime = (new Date()).getTime();
+    Test.AnotherWay.reset_running_time();
+    Test.AnotherWay._old_run_selected_onclick.apply(this, arguments);
+};
+
+Test.AnotherWay._old_run_one_onclick = Test.AnotherWay._run_one_onclick;
+Test.AnotherWay._run_one_onclick = function(){
+    Test.AnotherWay._startTime = (new Date()).getTime();
+    Test.AnotherWay.reset_running_time();
+    Test.AnotherWay._old_run_one_onclick.apply(this, arguments);
+};
+
+// test page loading
+Test.AnotherWay.old_load_next_page = Test.AnotherWay._load_next_page;
+Test.AnotherWay._load_next_page = function(){
+    Test.AnotherWay.update_running_time();    
+    Test.AnotherWay.old_load_next_page.apply(this, arguments);
+};
+
+
+Test.AnotherWay._add_test_page_url = function(test_url, convention){
+    var table = document.getElementById("testtable");
+    var record_select = document.getElementById("record_select");
+    var index = Test.AnotherWay._g_test_page_urls.length;
+    
+    // trim spaces.
+    if (test_url.match("^(\\s*)(.*\\S)(\\s*)$")) {
+        test_url = RegExp.$2;
+    }
+    
+    Test.AnotherWay._g_test_page_urls[index] = {
+        url: test_url,
+        convention: convention
+    };
+    var row = table.insertRow(-1);
+    
+    var cell;
+    var cell_child;
+    var link;
+    
+    cell = row.insertCell(-1);
+    cell_child = document.createElement("input");
+    cell_child.type = "checkbox";
+    cell_child.id = "checkbox" + index;
+    cell_child.checked = 'checked';
+    cell_child.defaultChecked = 'checked';
+    cell.appendChild(cell_child);
+    
+    cell = row.insertCell(-1);
+    cell.setAttribute("width", "75%");
+     
+    // make the URL a clickable link that opens in a new window
+    // start changes 
+    link = document.createElement("a");
+    link.href=test_url;
+    link.target='_blank';
+    link.title='Opens testfile in a new window.';
+    link.appendChild(document.createTextNode(test_url));    
+    cell.appendChild(link);
+    // end changes
+    
+    cell = row.insertCell(-1);
+    cell_child = document.createElement("input");
+    cell_child.type = "button";
+    cell_child.id = "test" + index;
+    cell_child.value = " run ";
+    cell_child.onclick = Test.AnotherWay._run_one_onclick;
+    cell.appendChild(cell_child);
+    
+    cell = row.insertCell(-1);
+    cell.setAttribute("width", "8em");
+    cell_child = document.createElement("span");
+    cell.appendChild(cell_child);
+    
+    var option = document.createElement("option");
+    option.appendChild(document.createTextNode(test_url));
+    record_select.appendChild(option);
+};
+
+
+// new methods
+Test.AnotherWay.update_running_time = function() {
+    var now = (new Date()).getTime();
+    var floor = Math.floor;
+    var elapsed = now - Test.AnotherWay._startTime;
+    var zeroPad = function(num, length){
+        var len = -1 * (length || 2);
+        return ('00000' + num).slice(len);  
+    };
+    var ms = zeroPad(elapsed%1000, 3);
+    var seconds=zeroPad(floor((elapsed/1000)%60));
+    var minutes=zeroPad(floor((elapsed/60000)%60));
+    
+    document.getElementById('running-time').innerHTML = 'Elapsed time ' + minutes + ':' + seconds + ':' + ms +' (m:s:ms).';
+};
+
+Test.AnotherWay.reset_running_time = function(){
+    document.getElementById('running-time').innerHTML = '';
+};
+
+// quickfilter
+Test.AnotherWay.bindQuicksearchListener = function(){
+    var input = document.getElementById('quickfilter');
+    if (input.addEventListener) {
+        input.addEventListener('keyup', Test.AnotherWay.quicksearch);
+    } else if (input.attachEvent) {
+        input.attachEvent('onkeyup', Test.AnotherWay.quicksearch);
+    } else {
+        // remove the input field
+        input.parentNode.removeChild(input);
+    }
+};
+Test.AnotherWay.quicksearchThrottleTimeOut = null;
+Test.AnotherWay.quicksearch = function(){
+    if (Test.AnotherWay.quicksearchThrottleTimeOut) {
+        window.clearTimeout(Test.AnotherWay.quicksearchThrottleTimeOut);
+    }
+    Test.AnotherWay.quicksearchThrottleTimeOut = window.setTimeout(function(){
+        var input = document.getElementById('quickfilter');
+        Test.AnotherWay.filterTestList(input.value);
+    }, 300);
+};
+
+Test.AnotherWay.filterTestList = function(str){
+    Test.AnotherWay.unfilterTestList();
+    var re = new RegExp(str, 'i');
+    var candidates  = document.querySelectorAll('#testtable tr td:nth-child(2) a');
+    for (var idx = 0, len = candidates.length; idx<len; idx++) {
+        var tr = candidates[idx].parentNode.parentNode;
+        var html = candidates[idx].innerHTML;
+        if (re.test(html)) {
+            tr.className = 'isShown';
+        } else {
+            tr.className = 'isHidden';
+        }
+    }
+    
+};
+
+Test.AnotherWay.unfilterTestList = function() {
+    if ( document.querySelectorAll ) {
+        var hidden = document.querySelectorAll('.isHidden');
+        for (var idx = 0, len = hidden.length; idx < len; idx++) {
+            hidden[idx].className = 'isShown';
+        }
+    }
+};
+
+// bind our quicksearch init method to body onload.
+(function(win){
+    if (win.addEventListener) {
+        win.addEventListener('load', Test.AnotherWay.bindQuicksearchListener);
+    } else if (input.attachEvent) {
+        win.attachEvent('onload', Test.AnotherWay.bindQuicksearchListener);
+    } else {
+        win.onload = function(){
+            Test.AnotherWay.bindQuicksearchListener();
+        };
+    }
+})(window);

Copied: sandbox/august/trunk/tests/Test.AnotherWay.css (from rev 12408, trunk/openlayers/tests/Test.AnotherWay.css)
===================================================================
--- sandbox/august/trunk/tests/Test.AnotherWay.css	                        (rev 0)
+++ sandbox/august/trunk/tests/Test.AnotherWay.css	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,243 @@
+/**
+ *  Test.AnotherWay version 0.5
+ *  
+ *  Copyright (c) 2005 Artem Khodush, http://straytree.org
+ *  
+ *  Permission is hereby granted, free of charge, to any person obtaining
+ *  a copy of this software and associated documentation files (the
+ *  "Software"), to deal in the Software without restriction, including
+ *  without limitation the rights to use, copy, modify, merge, publish,
+ *  distribute, sublicense, and/or sell copies of the Software, and to
+ *  permit persons to whom the Software is furnished to do so, subject to
+ *  the following conditions:
+ *  
+ *  The above copyright notice and this permission notice shall be
+ *  included in all copies or substantial portions of the Software.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *  
+ */
+
+* {
+    padding: 0;
+    margin: 0;
+}
+
+html {
+    height: 99%;
+}
+
+body {
+    height: 98%;
+    font: normal normal 10pt sans-serif
+}
+
+#col1 {
+    float: left;
+    width: 27em;
+    margin: 0 0 0 1em;
+    overflow: visible;
+}
+
+#col2 {
+    position: relative;
+    height: 98%;
+    margin: 0 0.5em 0 28em;
+}
+
+#col1_header {
+    margin-top: 0.5em;
+}
+
+#scroller {
+    height: 400px;
+    overflow: auto;
+}
+
+#testtable {
+    margin: 0 0 2em 0;
+    width: 97%;
+    font-size: 1em;
+    border-collapse: collapse;
+}
+#testtable input {
+    cursor: pointer;
+}
+#testtable td {
+    line-height: 2em;
+    padding: 0;
+    margin: 0;
+    border-top: 1px solid #ccc;
+    border-bottom: 1px solid #ccc;
+}
+#testtable tr:hover td {
+    background-color: #ededed;
+}
+#testtable tr.isHidden {
+    display: none;
+}
+#testtable tr.isShown {
+    display: table-row;
+}
+
+#run_buttons, #running-time {
+    margin-bottom: 1em;
+}
+
+#right_header {
+    padding-top: 0.8em;
+}
+
+#results_count {
+    float: left;
+}
+
+#results > p:hover {
+    background-color: #ededed;
+}
+
+.active_tab {
+    float: right;
+    padding: 0 1em 0.2em 1em;
+    background: #0af;
+    border: 1px solid #048;
+    border-bottom: none;
+    cursor: pointer;
+    cursor: hand;
+    position: relative;
+    top: -0.2em;
+}
+
+.inactive_tab {
+    float: right;
+    padding: 0 1em 0 1em;
+    background: #9bb;
+    color: #444;
+    border: 1px solid #9bb;
+    border-bottom: none;
+    cursor: pointer;
+    cursor: hand;
+}
+
+.inactive_mouseover_tab {
+    float: right;
+    padding: 0 1em 0 1em;
+    background: #9bb;
+    color: #062;
+    border: 1px solid #062;
+    border-bottom: none;
+    cursor: pointer;
+    cursor: hand;
+}
+
+#right_frame {
+    overflow: auto;
+    position: relative;
+    top: -0.2em;
+    clear: right;
+    height: 95%;
+    border: 1px solid #048;
+}
+
+#debug {
+    display: none;
+}
+
+#debug p {
+    margin: 2px 0 0 5em;
+    text-indent: -4.8em;
+}
+
+#error {
+    display: none;
+    color: #c22;
+}
+
+#results p {
+    margin: 0 0 2px 0;
+}
+
+/* cursor indicating that detailed results may be expanded/contracted */
+#results p.badtest {
+    cursor: text;
+}
+
+#results p.ok, #results p.fail {
+    cursor: pointer;
+    cursor: hand;
+}
+
+/* colored squares in the results window at the left of test page names */
+#results p.ok .bullet {
+    background: #6d6;
+}
+
+#results p.fail .bullet {
+    background: #d46;
+}
+
+#results p.badtest .bullet {
+    background: #ea3;
+}
+
+#results p.loading .bullet {
+    background: #48f;
+}
+
+#results p.running .bullet {
+    background: #26e;
+}
+
+#results p.waiting .bullet {
+    background: #04d;
+}
+
+/* highlight in the results line */
+#results p .warning {
+    background: #ffc;
+}
+
+/* layout of the detailed results */
+.result_detail {
+    padding-left: 3em;
+}
+
+.result_exception_detail {
+    padding-left: 4em;
+}
+
+.result_exception_stack_detail {
+    padding-left: 5em;
+}
+
+.result_micro_detail {
+    padding-left: 6em;
+}
+
+/* colouring in the detailed results */
+.result_detail .fail, .result_exception_detail .fail, .result_micro_detail .fail {
+    background: #ffd8d8;
+}
+
+/* "start recording" controls*/
+#record_div {
+    margin-top: 3em;
+}
+
+#record_div p {
+    margin-bottom: 0.5em;
+}
+
+#record_select {
+    width: 88%;
+}
+
+#record_input {
+    width: 53%;
+}
\ No newline at end of file

Copied: sandbox/august/trunk/tests/Test.AnotherWay.geom_eq.js (from rev 12408, trunk/openlayers/tests/Test.AnotherWay.geom_eq.js)
===================================================================
--- sandbox/august/trunk/tests/Test.AnotherWay.geom_eq.js	                        (rev 0)
+++ sandbox/august/trunk/tests/Test.AnotherWay.geom_eq.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,110 @@
+/**
+ * File: Test.AnotherWay.geom_eq.js
+ * Adds a geom_eq method to AnotherWay test objects.
+ *
+ */
+
+(function() {
+    
+    /**
+     * Function assertEqual
+     * Test two objects for equivalence (based on ==).  Throw an exception
+     *     if not equivalent.
+     * 
+     * Parameters:
+     * got - {Object}
+     * expected - {Object}
+     * msg - {String} The message to be thrown.  This message will be appended
+     *     with ": got {got} but expected {expected}" where got and expected are
+     *     replaced with string representations of the above arguments.
+     */
+    function assertEqual(got, expected, msg) {
+        if(got === undefined) {
+            got = "undefined";
+        } else if (got === null) {
+            got = "null";
+        }
+        if(expected === undefined) {
+            expected = "undefined";
+        } else if (expected === null) {
+            expected = "null";
+        }
+        if(got != expected) {
+            throw msg + ": got '" + got + "' but expected '" + expected + "'";
+        }
+    }
+    
+    /**
+     * Function assertGeometryEqual
+     * Test two geometries for equivalence.  Geometries are considered
+     *     equivalent if they are of the same class, and given component
+     *     geometries, if all components are equivalent. Throws a message as
+     *     exception if not equivalent.
+     * 
+     * Parameters:
+     * got - {OpenLayers.Geometry}
+     * expected - {OpenLayers.Geometry}
+     * options - {Object} Optional object for configuring test options.
+     */
+    function assertGeometryEqual(got, expected, options) {
+        
+        var OpenLayers = Test.AnotherWay._g_test_iframe.OpenLayers;
+
+        // compare types
+        assertEqual(typeof got, typeof expected, "Object types mismatch");
+        
+        // compare classes
+        assertEqual(got.CLASS_NAME, expected.CLASS_NAME, "Object class mismatch");
+        
+        if(got instanceof OpenLayers.Geometry.Point) {
+            // compare points
+            assertEqual(got.x, expected.x, "x mismatch");
+            assertEqual(got.y, expected.y, "y mismatch");
+            assertEqual(got.z, expected.z, "z mismatch");
+        } else {
+            // compare components
+            assertEqual(
+                got.components.length, expected.components.length,
+                "Component length mismatch for " + got.CLASS_NAME
+            );
+            for(var i=0; i<got.components.length; ++i) {
+                try {
+                    assertGeometryEqual(
+                        got.components[i], expected.components[i], options
+                    );
+                } catch(err) {
+                    throw "Bad component " + i + " for " + got.CLASS_NAME + ": " + err;
+                }
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Function: Test.AnotherWay._test_object_t.geom_eq
+     * Test if two geometry objects are equivalent.  Tests for same geometry
+     *     class, same number of components (if any), equivalent component
+     *     geometries, and same coordinates.
+     *
+     * (code)
+     * t.geom_eq(got, expected, message);
+     * (end)
+     * 
+     * Parameters:
+     * got - {OpenLayers.Geometry} Any geometry instance.
+     * expected - {OpenLayers.Geometry} The expected geometry.
+     * msg - {String} A message to print with test output.
+     * options - {Object} Optional object for configuring test options.
+     */
+    var proto = Test.AnotherWay._test_object_t.prototype;
+    proto.geom_eq = function(got, expected, msg, options) {        
+        // test geometries for equivalence
+        try {
+            assertGeometryEqual(got, expected, options);
+            this.ok(true, msg);
+        } catch(err) {
+            this.fail(msg + ": " + err);
+        }
+    }
+    
+})();
\ No newline at end of file

Copied: sandbox/august/trunk/tests/Test.AnotherWay.js (from rev 12408, trunk/openlayers/tests/Test.AnotherWay.js)
===================================================================
--- sandbox/august/trunk/tests/Test.AnotherWay.js	                        (rev 0)
+++ sandbox/august/trunk/tests/Test.AnotherWay.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,2498 @@
+/**
+ *  Test.AnotherWay version 0.5
+ *  
+ *  Copyright (c) 2005 Artem Khodush, http://straytree.org
+ *  
+ *  Permission is hereby granted, free of charge, to any person obtaining
+ *  a copy of this software and associated documentation files (the
+ *  "Software"), to deal in the Software without restriction, including
+ *  without limitation the rights to use, copy, modify, merge, publish,
+ *  distribute, sublicense, and/or sell copies of the Software, and to
+ *  permit persons to whom the Software is furnished to do so, subject to
+ *  the following conditions:
+ *  
+ *  The above copyright notice and this permission notice shall be
+ *  included in all copies or substantial portions of the Software.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *  
+ */
+
+if (typeof(Test) == "undefined") {
+    Test = {};
+}
+Test.AnotherWay = {};
+
+Test.AnotherWay._g_test_iframe = null; // frame where to load test pages
+Test.AnotherWay._g_test_frame_no_clear = false; // true - leave last page displayed after tests end
+Test.AnotherWay._g_test_page_urls = []; // array of: { url: url, convention: "anotherway" or "jsan" }
+Test.AnotherWay._g_test_object_for_jsan = null; // test object for filling by tests that adhere to jsan Test.Simple calling convention
+Test.AnotherWay._g_pages_to_run = null; // list of pages to run automatically after loading
+Test.AnotherWay._g_run_on_main_load = false; // special handling for run_pages_to_run when it might be called before onload or before list of test pages is known.
+Test.AnotherWay._g_run_on_list_load = false;
+Test.AnotherWay._g_main_loaded = false;
+
+Test.AnotherWay._run_pages_to_run = function(called_from_outside){
+    if (!Test.AnotherWay._g_main_loaded) {
+        Test.AnotherWay._g_run_on_main_load = true;
+    }
+    else {
+        var a_pages = Test.AnotherWay._g_pages_to_run;
+        if (a_pages == "all") {
+            for (var i = 0; i < Test.AnotherWay._g_test_page_urls.length; ++i) {
+                Test.AnotherWay._run_test_page("test" + i);
+            }
+        }
+        else 
+            if (a_pages != null) {
+                for (var run_i = 0; run_i < a_pages.length; ++run_i) {
+                    var run_page = a_pages[run_i];
+                    var found = false;
+                    for (var all_i = 0; all_i < Test.AnotherWay._g_test_page_urls.length; ++all_i) {
+                        if (run_page == Test.AnotherWay._g_test_page_urls[all_i].url) {
+                            Test.AnotherWay._run_test_page("test" + all_i, called_from_outside);
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found) {
+                        Test.AnotherWay._show_error("page specified to run is not found in the page list: " + run_page);
+                        break;
+                    }
+                }
+            }
+    }
+};
+
+Test.AnotherWay._add_test_page_url = function(test_url, convention){
+    var table = document.getElementById("testtable");
+    var record_select = document.getElementById("record_select");
+    var index = Test.AnotherWay._g_test_page_urls.length;
+    
+    // trim spaces.
+    if (test_url.match("^(\\s*)(.*\\S)(\\s*)$")) {
+        test_url = RegExp.$2;
+    }
+    
+    Test.AnotherWay._g_test_page_urls[index] = {
+        url: test_url,
+        convention: convention
+    };
+    var row = table.insertRow(-1);
+    
+    var cell;
+    var cell_child;
+    var link;
+    
+    cell = row.insertCell(-1);
+    cell_child = document.createElement("input");
+    cell_child.type = "checkbox";
+    cell_child.id = "checkbox" + index;
+    cell_child.checked = 'checked';
+    cell_child.defaultChecked = 'checked';
+    cell.appendChild(cell_child);
+    
+    cell = row.insertCell(-1);
+    cell.setAttribute("width", "75%");
+    
+    cell.appendChild(document.createTextNode(test_url));    
+    
+    cell = row.insertCell(-1);
+    cell_child = document.createElement("input");
+    cell_child.type = "button";
+    cell_child.id = "test" + index;
+    cell_child.value = " run ";
+    cell_child.onclick = Test.AnotherWay._run_one_onclick;
+    cell.appendChild(cell_child);
+    
+    cell = row.insertCell(-1);
+    cell.setAttribute("width", "8em");
+    cell_child = document.createElement("span");
+    cell.appendChild(cell_child);
+    
+    var option = document.createElement("option");
+    option.appendChild(document.createTextNode(test_url));
+    record_select.appendChild(option);
+};
+Test.AnotherWay._show_error = function(msg){
+    var error_div = document.getElementById("error");
+    error_div.innerHTML = "";
+    error_div.appendChild(document.createTextNode(msg));
+    error_div.style.display = "block";
+};
+
+// read urls from the list in the html file inside the list_iframe
+// fill on-screen list with urls and "run" buttons, and fill the g_test_page_urls object.
+Test.AnotherWay._list_iframe_onload = function(){
+    if (window.frames.list_iframe != null && window.frames.list_iframe.location != "" && window.frames.list_iframe.location != "about:blank") {
+        var list_doc = window.frames.list_iframe.document;
+        var list = list_doc.getElementById("testlist");
+        if (list != null) {
+            for (var i = 0; i < list.childNodes.length; ++i) {
+                var item = list.childNodes[i];
+                if (item.nodeName == "LI" || item.nodeName == "li") {
+                    var convention = "anotherway";
+                    if (Test.AnotherWay._get_css_class(item) == "jsan") {
+                        convention = "jsan";
+                    }
+                    Test.AnotherWay._add_test_page_url(item.innerHTML, convention);
+                }
+            }
+            if (Test.AnotherWay._g_run_on_list_load) {
+                Test.AnotherWay._g_run_on_list_load = false;
+                Test.AnotherWay._run_pages_to_run();
+            }
+        }
+        else {
+            Test.AnotherWay._show_error("no list with id 'testlist' in a list file " + window.frames.list_iframe.location);
+        }
+    }
+};
+
+Test.AnotherWay._map_checkboxes = function(f){
+    var table = document.getElementById("testtable");
+    var checks = table.getElementsByTagName("INPUT");
+    for (var i = 0; i < checks.length; ++i) {
+        if (checks[i].type == "checkbox" && checks[i].id.match(/^checkbox(\d+)$/)) {
+            f(checks[i], RegExp.$1);
+        }
+    }
+};
+
+Test.AnotherWay._run_all_onclick = function(){
+    Test.AnotherWay._map_checkboxes(function(c, id){
+        Test.AnotherWay._run_test_page("test" + id);
+    });
+};
+Test.AnotherWay._run_selected_onclick = function(){
+    Test.AnotherWay._map_checkboxes(function(c, id){
+        if (c.checked) {
+            Test.AnotherWay._run_test_page("test" + id);
+        }
+    });
+};
+
+Test.AnotherWay._unselect_all_onclick = function(){
+    Test.AnotherWay._map_checkboxes(function(c, id){
+        c.checked = false;
+    });
+};
+
+Test.AnotherWay._run_one_onclick = function(){
+    Test.AnotherWay._run_test_page(this.id);
+};
+
+// construct an object that will gather results of running one test function
+Test.AnotherWay._test_object_t = function(fun_name){
+    this.name = fun_name; // name of the test function
+    this.n_plan = null; // planned number of assertions
+    this.n_ok = 0; // # of ok assertions
+    this.n_fail = 0; // # of failed assertions
+    this.exception = ""; // if the function throwed an exception, it's its message
+    this.exception_stack = []; // strings: function call stack from the exception
+    this.assertions = []; // assertion results: array of { ok: 1 or 0, name: string }
+    this.wait_result_milliseconds = 0; // how long to wait before collecting results from the test
+    this.second_wait_msg = null; // <p> status message (in addition to the page wait_msg)
+    this.delay_actions = []; // array of actions to be perfomed after the test function returns
+    //  action : { acton_kind: "call" | "window" | "replay"
+    //              when "call":        { call_fn call_delay_milliseconds } call_fn takes nothing
+    //              when "window" :     { wnd_url wnd_wnd wnd_fn wnd_timeout_milliseconds wnd_dont_close } wnd_fn takes wnd
+    //              wnen "replay" :     { replay_wnd replay_events replay_event_i replay_checkpoints } checkpoint_fn takes this, wnd
+    //  }
+    this.delay_action_i = null; // index of delay action currently being performed
+    this.delay_prev_timer_time = 0; // for counting time while performing delay_actions
+    this.delay_current_milliseconds_left = 0; // time left before the next action, runs down
+    this.delay_total_milliseconds_left = 0; // for indication: total estimated time for all actions, runs up and down
+};
+
+Test.AnotherWay._test_object_t.prototype.ok = function(cond, name){
+    if (cond) {
+        ++this.n_ok;
+        cond = 1;
+    }
+    else {
+        ++this.n_fail;
+        cond = 0;
+    }
+    this.assertions.push({
+        ok: cond,
+        name: name
+    });
+};
+Test.AnotherWay._test_object_t.prototype.fail = function(name){
+    this.ok(false, name);
+};
+Test.AnotherWay._test_object_t.prototype.plan = function(n){
+    this.n_plan = n;
+};
+Test.AnotherWay._test_object_t.prototype.wait_result = function(seconds){
+    this.wait_result_milliseconds = 1000 * seconds;
+};
+Test.AnotherWay._eq_fail_msg = function(path, what, expected, got){
+    return "eq: " + path + " " + what + " differ: got " + got + ", but expected " + expected;
+};
+Test.AnotherWay._array_eq = function(expected, got, path, msg){
+    if (expected.length != got.length) {
+        msg.msg = Test.AnotherWay._eq_fail_msg(path, "array length", expected.length, got.length);
+        return false;
+    }
+    for (var i = 0; i < expected.length; ++i) {
+        if (!Test.AnotherWay._thing_eq(expected[i], got[i], path + "[" + i + "]", msg)) {
+            return false;
+        }
+    }
+    return true;
+};
+Test.AnotherWay._object_eq = function(expected, got, path, msg){
+    var v;
+    for (v in expected) {
+        if (!(v in got)) {
+            msg.msg = Test.AnotherWay._eq_fail_msg(path + "." + v, "properties", expected[v], "undefined");
+            return false;
+        }
+        if (!Test.AnotherWay._thing_eq(expected[v], got[v], path + "." + v, msg)) {
+            return false;
+        }
+    }
+    for (v in got) {
+        if (!(v in expected)) {
+            msg.msg = Test.AnotherWay._eq_fail_msg(path + "." + v, "properties", "undefined", got[v]);
+            return false;
+        }
+    }
+    return true;
+};
+
+Test.AnotherWay._constructor_name = function(x){
+    if (x == null) {
+        return "";
+    }
+    var s = "unknown";
+    try {
+        s = typeof(x.constructor);
+        if (s != "unknown") {
+            s = x.constructor.toString();
+        }
+    } 
+    catch (e) {
+        s = "unknown";
+    }
+    if (s == "unknown") {
+        // hackish attempt to guess a type
+        var is_array = true;
+        var index = 0;
+        for (i in x) {
+            if (i != index) {
+                is_array = false;
+            }
+            ++index;
+        }
+        return is_array ? "Array" : "Object"; // for empty arrays/objects, this will be wrong half the time
+    }
+    else 
+        if (s.match(/^\s*function\s+(\w+)\s*\(/)) {
+            return RegExp.$1;
+        }
+        else {
+            var c = '';
+            switch (typeof x) {
+                case 'string':
+                    c = 'String';
+                    break;
+                case 'object':
+                    c = 'Object';
+                    break;
+                default:
+                    c = '';
+            }
+            return c;
+        }
+};
+Test.AnotherWay._is_array = function(x){
+    return Test.AnotherWay._constructor_name(x) == "Array";
+};
+
+Test.AnotherWay._is_value_type = function(x){
+    cn = Test.AnotherWay._constructor_name(x);
+    return cn == "Number" || cn == "String" || cn == "Boolean" || cn == "Date";
+};
+
+Test.AnotherWay._thing_eq = function(expected, got, path, msg){
+    if (expected == null && got == null) {
+        return true;
+    }
+    else 
+        if ((expected == null && got != null) || (expected != null && got == null)) {
+            msg.msg = Test.AnotherWay._eq_fail_msg(path, "values", expected, got);
+            return false;
+        }
+        else {
+            var expected_cn = Test.AnotherWay._constructor_name(expected);
+            var got_cn = Test.AnotherWay._constructor_name(got);
+            if (expected_cn != got_cn) {
+                msg.msg = Test.AnotherWay._eq_fail_msg(path, "types", expected_cn, got_cn);
+                return false;
+            }
+            else {
+                if (Test.AnotherWay._is_array(expected)) {
+                    return Test.AnotherWay._array_eq(expected, got, path, msg);
+                }
+                else 
+                    if (Test.AnotherWay._is_value_type(expected)) {
+                        if (expected != got) {
+                            msg.msg = Test.AnotherWay._eq_fail_msg(path, "values", expected, got);
+                            return false;
+                        }
+                        else {
+                            return true;
+                        }
+                    }
+                    else { // just a plain object
+                        return Test.AnotherWay._object_eq(expected, got, path, msg);
+                    }
+            }
+        }
+};
+
+Test.AnotherWay._test_object_t.prototype.eq = function(got, expected, name){
+    var msg = {};
+    if (Test.AnotherWay._thing_eq(expected, got, "", msg)) {
+        this.ok(1, name);
+    }
+    else {
+        this.fail(name + ". " + msg.msg);
+    }
+};
+
+Test.AnotherWay._test_object_t.prototype.like = function(got, expected, name){
+    if (got.match(expected) != null) {
+        this.ok(1, name);
+    }
+    else {
+        this.fail(name + ": got " + got + ", but expected it to match: " + expected);
+    }
+};
+
+Test.AnotherWay._g_html_eq_span = null;
+Test.AnotherWay._html_eq_string_to_node = function(string_or_node, what, msg){
+    if (string_or_node.nodeType != null) {
+        string_or_node = Test.AnotherWay._html_eq_node_to_string(string_or_node); // double trip - to make properties assigned in scripts available as html node attributes
+    }
+    if (Test.AnotherWay._g_html_eq_span == null) {
+        Test.AnotherWay._g_html_eq_span = document.createElement("span");
+    }
+    Test.AnotherWay._g_html_eq_span.innerHTML = string_or_node;
+    if (Test.AnotherWay._g_html_eq_span.childNodes.length != 1) {
+        msg.msg = "bad " + what + " html string given (should contain exactly one outermost element): " + string_or_node;
+    }
+    return Test.AnotherWay._g_html_eq_span.childNodes[0].cloneNode(true);
+};
+
+Test.AnotherWay._html_eq_node_to_string = function(node){
+    if (Test.AnotherWay._g_html_eq_span == null) {
+        Test.AnotherWay._g_html_eq_span = document.createElement("span");
+    }
+    Test.AnotherWay._g_html_eq_span.innerHTML = "";
+    if (node.outerHTML != null) {
+        Test.AnotherWay._g_html_eq_span.innerHTML = node.outerHTML;
+    }
+    else {
+        var clone = node.cloneNode(true);
+        var node = Test.AnotherWay._g_html_eq_span;
+        if (node.ownerDocument && node.ownerDocument.importNode) {
+            if (node.ownerDocument != clone.ownerDocument) {
+                clone = node.ownerDocument.importNode(clone, true);
+            }
+        }
+        node.appendChild(clone);
+    }
+    return Test.AnotherWay._g_html_eq_span.innerHTML;
+};
+
+Test.AnotherWay._html_eq_path_msg = function(path){
+    var msg = "";
+    for (var i = 0; i < path.length; ++i) {
+        msg += " [node " + path[i].node;
+        if (path[i].id != null && path[i].id != "") {
+            msg += " id " + path[i].id;
+        }
+        else 
+            if (path[i].index != null) {
+                msg += " at index " + path[i].index;
+            }
+        msg += "] ";
+    }
+    return msg;
+};
+
+Test.AnotherWay._html_eq_fail_msg = function(path, what, expected, got){
+    return Test.AnotherWay._html_eq_path_msg(path) + ": " + what + " differ: got " + got + ", but expected " + expected;
+};
+
+Test.AnotherWay._html_eq_remove_blank = function(text){
+    if (text == null) {
+        return "";
+    }
+    else 
+        if (text.match("^(\\s*)(.*\\S)(\\s*)$")) {
+            return RegExp.$2;
+        }
+        else 
+            if (text.match("\s*")) {
+                return "";
+            }
+    return text;
+};
+
+Test.AnotherWay._html_eq_remove_blank_nodes = function(node){
+    var to_remove = [];
+    for (var child = node.firstChild; child != null; child = child.nextSibling) {
+        if (child.nodeType == 3) {
+            var value = Test.AnotherWay._html_eq_remove_blank(child.nodeValue);
+            if (value == "") {
+                to_remove.push(child);
+            }
+            else {
+                child.nodeValue = value;
+            }
+        }
+    }
+    for (var i = 0; i < to_remove.length; ++i) {
+        node.removeChild(to_remove[i]);
+    }
+};
+
+Test.AnotherWay._html_node_type_text = function(node_type){
+    if (node_type == 1) {
+        return "1 (html element)";
+    }
+    else 
+        if (node_type == 3) {
+            return "3 (text)";
+        }
+        else {
+            return node_type;
+        }
+};
+
+Test.AnotherWay._html_eq_node = function(expected, got, path, msg, expected_loc_base, got_loc_base){
+    if (expected.nodeType != got.nodeType) {
+        msg.msg = Test.AnotherWay._html_eq_fail_msg(path, "node types", Test.AnotherWay._html_node_type_text(expected.nodeType), Test.AnotherWay._html_node_type_text(got.nodeType));
+        return false;
+    }
+    else 
+        if (expected.nodeType == 3) {
+            if (expected.nodeValue != got.nodeValue) {
+                msg.msg = Test.AnotherWay._html_eq_fail_msg(path, "text", expected.nodeValue, got.nodeValue);
+                return false;
+            }
+        }
+        else 
+            if (expected.nodeType == 1) {
+                if (expected.nodeName != got.nodeName) {
+                    msg.msg = Test.AnotherWay._html_eq_fail_msg(path, "node names", expected.nodeName, got.nodeName);
+                    return false;
+                }
+                // compare attributes
+                var expected_attrs = {};
+                var got_attrs = {};
+                var i;
+                var a;
+                for (i = 0; i < expected.attributes.length; ++i) {
+                    a = expected.attributes[i];
+                    if (a.specified) {
+                        expected_attrs[a.name] = 1;
+                    }
+                }
+                for (i = 0; i < got.attributes.length; ++i) {
+                    a = got.attributes[i];
+                    if (a.specified) {
+                        got_attrs[a.name] = 1;
+                    }
+                }
+                for (a in expected_attrs) {
+                    if (!(a in got_attrs)) {
+                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + ": attribute sets differ: expected attribute " + a + " is missing";
+                        return false;
+                    }
+                }
+                for (a in got_attrs) {
+                    if (!(a in expected_attrs)) {
+                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + ": attribute sets differ: got extra attribute " + a;
+                        return false;
+                    }
+                }
+                for (a in expected_attrs) {
+                    var expected_value = expected.getAttribute(a);
+                    var got_value = got.getAttribute(a);
+                    if (typeof(expected_value) == "string" && typeof(got_value) == "string") {
+                        expected_value = Test.AnotherWay._html_eq_remove_blank(expected_value);
+                        got_value = Test.AnotherWay._html_eq_remove_blank(got_value);
+                        var ok = expected_value == got_value;
+                        if (!ok && (a == "href" || a == "HREF")) { // try relative hrefs
+                            var expected_relative_value = expected_value;
+                            if (expected_loc_base != null && expected_value.substring(0, expected_loc_base.length) == expected_loc_base) {
+                                expected_relative_value = expected_value.substring(expected_loc_base.length);
+                            }
+                            var got_relative_value = got_value;
+                            if (got_loc_base != null && got_value.substring(0, got_loc_base.length) == got_loc_base) {
+                                got_relative_value = got_value.substring(got_loc_base.length);
+                            }
+                            ok = expected_relative_value == got_relative_value;
+                        }
+                        if (!ok) {
+                            msg.msg = Test.AnotherWay._html_eq_fail_msg(path, "attribute " + a + " values", expected_value, got_value);
+                            return false;
+                        }
+                    }
+                    else 
+                        if (typeof(expected_value) == "function" && typeof(got_value) == "function") {
+                            expected_value = expected_value.toString();
+                            got_value = got_value.toString();
+                            if (expected_value != got_value) {
+                                msg.msg = Test.AnotherWay._html_eq_fail_msg(path, "attribute " + a + " values", expected_value, got_value);
+                                return false;
+                            }
+                        }
+                        else {
+                            var value_msg = {};
+                            if (!Test.AnotherWay._thing_eq(expected_value, got_value, "", value_msg)) {
+                                msg.msg = Test.AnotherWay._html_eq_path_msg(path) + ": attribute " + a + " values differ: " + value_msg.msg;
+                                return false;
+                            }
+                        }
+                }
+                // compare child nodes
+                Test.AnotherWay._html_eq_remove_blank_nodes(expected);
+                Test.AnotherWay._html_eq_remove_blank_nodes(got);
+                var expected_length = expected.childNodes.length;
+                var got_length = got.childNodes.length;
+                if (expected_length < got_length) {
+                    msg.msg = Test.AnotherWay._html_eq_path_msg(path) + ": got " + (got_length - expected_length) + " extra child nodes";
+                    return false;
+                }
+                else 
+                    if (expected_length > got_length) {
+                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + ": expected " + (expected_length - got_length) + " more child nodes";
+                        return false;
+                    }
+                    else {
+                        for (i = 0; i < expected_length; ++i) {
+                            var expected_node = expected.childNodes[i];
+                            path.push({
+                                node: expected_node.nodeName,
+                                id: expected_node.id,
+                                index: i
+                            });
+                            var eq = Test.AnotherWay._html_eq_node(expected_node, got.childNodes[i], path, msg, expected_loc_base, got_loc_base);
+                            path.pop();
+                            if (!eq) {
+                                return false;
+                            }
+                        }
+                    }
+            }
+    return true;
+};
+
+Test.AnotherWay._html_eq_get_loc_base = function(node){
+    var loc_base = document.location;
+    if (node.ownerDocument != null) {
+        loc_base = node.ownerDocument.location;
+    }
+    if (loc_base != null) {
+        loc_base = loc_base.href;
+        var slash_pos = loc_base.lastIndexOf("/");
+        if (slash_pos != -1) {
+            loc_base = loc_base.substring(0, slash_pos + 1);
+        }
+    }
+    return loc_base;
+};
+
+Test.AnotherWay._test_object_t.prototype.html_eq = function(got, expected, name){
+    var msg = {};
+    var expected_node = Test.AnotherWay._html_eq_string_to_node(expected, "expected", msg);
+    if (msg.msg != null) {
+        this.fail(name + " html_eq: " + msg.msg);
+    }
+    else {
+        var got_node = Test.AnotherWay._html_eq_string_to_node(got, "got", msg);
+        if (msg.msg != null) {
+            this.fail(name + " html_eq: " + msg.msg);
+        }
+        else {
+            var expected_loc_base = Test.AnotherWay._html_eq_get_loc_base(expected);
+            var got_loc_base = Test.AnotherWay._html_eq_get_loc_base(got);
+            if (Test.AnotherWay._html_eq_node(expected_node, got_node, [], msg, expected_loc_base, got_loc_base)) {
+                this.ok(1, name);
+            }
+            else {
+                var msg = name + " html_eq " + msg.msg;
+                var expected_str = Test.AnotherWay._html_eq_node_to_string(expected_node);
+                var got_str = Test.AnotherWay._html_eq_node_to_string(got_node);
+                msg += ".\n got html: " + got_str;
+                msg += ".\n expected html: " + expected_str;
+                this.fail(msg);
+            }
+        }
+    }
+};
+
+Test.AnotherWay._debug_pane_print = function(msg){
+    var d = new Date();
+    var p = document.createElement("p");
+    p.appendChild(document.createTextNode(d.toLocaleTimeString() + " " + msg));
+    var debug_pane = document.getElementById("debug");
+    debug_pane.appendChild(p);
+    var debug_tab = document.getElementById("debug_tab");
+    var results_tab = document.getElementById("results_tab");
+    debug_tab.style.visibility = "visible";
+    results_tab.style.visibility = "visible";
+};
+
+Test.AnotherWay._test_object_t.prototype.debug_print = function(msg){
+    Test.AnotherWay._debug_pane_print(this.name + ": " + msg);
+};
+
+Test.AnotherWay._test_object_t.prototype.delay_call = function(){
+    var timeout_ms = 200;
+    for (var i = 0; i < arguments.length; ++i) {
+        if (typeof(arguments[i]) != "function") {
+            timeout_ms = 1000 * arguments[i];
+        }
+        else {
+            var action = {
+                action_kind: "call",
+                call_delay_milliseconds: timeout_ms,
+                call_fn: arguments[i]
+            };
+            this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);
+            this.delay_actions.push(action);
+        }
+    }
+};
+
+Test.AnotherWay._test_object_t.prototype.open_window = function(url, fn, timeout_seconds){
+    if (timeout_seconds == null) {
+        timeout_seconds = 4;
+    }
+    var no_close = document.getElementById("dont_close_test_windows");
+    var action = {
+        action_kind: "window",
+        wnd_url: url.toString() + (window.location.search || ""),
+        wnd_wnd: null,
+        wnd_fn: fn,
+        wnd_timeout_milliseconds: timeout_seconds * 1000,
+        wnd_no_close: no_close.checked
+    };
+    this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);
+    this.delay_actions.push(action);
+};
+
+Test.AnotherWay._test_object_t.prototype.replay_events = function(wnd, events){
+    if (Test.AnotherWay._g_no_record_msg != null) {
+        this.fail("replay_events: " + Test.AnotherWay._g_no_record_msg);
+    }
+    else {
+        var action = {
+            action_kind: "replay",
+            replay_wnd: wnd,
+            replay_events: events.events,
+            replay_event_i: null,
+            replay_checkpoints: events.checkpoints
+        };
+        this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);
+        this.delay_actions.push(action);
+    }
+};
+
+Test.AnotherWay._action_estimate_milliseconds = function(action){
+    var ms = 0;
+    if (action.action_kind == "call") {
+        ms = action.call_delay_milliseconds;
+    }
+    else 
+        if (action.action_kind == "window") {
+            ms = 0;
+        }
+        else 
+            if (action.action_kind == "replay") {
+                ms = 0;
+                for (var i = 0; i < action.replay_events.length; ++i) {
+                    ms += action.replay_events[i]["time"] - 0;
+                }
+            }
+    return ms;
+};
+
+Test.AnotherWay._g_timeout_granularity = 200;
+Test.AnotherWay._g_tests_queue = []; // vector of { url: string, test_objects : array of test_object_t, test_object_i: int, wait_msg: <p> object, loading_timeout_milliseconds: int, timeout_id: id }
+// load one html page, schedule further processing
+Test.AnotherWay._run_test_page = function(id, called_from_outside){
+    if (id.match(/^test(\d+)/)) {
+        id = RegExp.$1;
+        Test.AnotherWay._g_tests_queue.push({
+            url: Test.AnotherWay._g_test_page_urls[id].url,
+            convention: Test.AnotherWay._g_test_page_urls[id].convention,
+            test_objects: []
+        });
+        if (Test.AnotherWay._g_tests_queue.length == 1) {
+            if (!called_from_outside) {
+                // Crap. Be careful stepping around.
+                // For Mozilla and Opera, when this file is included into the frameset page that is in another directory (and _g_outside_path_correction!=null)
+                // but the test pages are started from within it (by "run" buttons), then:
+                // depending on whether the page is the first one loaded into the test frame or not,
+                // the base url for relative test pages differs.
+                // Crap, like I said.
+                Test.AnotherWay._g_tests_queue[0].suppress_outside_path_correction = true;
+            }
+            Test.AnotherWay._start_loading_page();
+        }
+    }
+};
+
+Test.AnotherWay._load_next_page = function(){
+    Test.AnotherWay._g_tests_queue.splice(0, 1);
+    if (Test.AnotherWay._g_tests_queue.length > 0) {
+        Test.AnotherWay._start_loading_page();
+    }
+    else {
+        if (!Test.AnotherWay._g_test_frame_no_clear) {
+            Test.AnotherWay._g_test_iframe.location.replace("about:blank");
+        }
+    }
+};
+
+Test.AnotherWay._g_opera_path_correction = null; // ugly wart to support opera
+Test.AnotherWay._g_outside_path_correction = null; // ugly wart to accomodate Opera and Mozilla, where relative url relates to the directory where the page that calls this function is located
+Test.AnotherWay._set_iframe_location = function(iframe, loc, outside_path_correction){
+    // allow to load only locations with the same origin
+    var proto_end = loc.indexOf("://");
+    if (proto_end != -1) { // otherwise, it's safe to assume (for Opera, Mozilla and IE ) that loc will be treated as relative
+        var main_loc = window.location.href;
+        var host_end = loc.substring(proto_end + 3).indexOf("/");
+        var ok = false;
+        if (host_end != -1) {
+            var loc_origin = loc.substring(0, proto_end + 3 + host_end + 1);
+            if (main_loc.length >= loc_origin.length && main_loc.substring(0, loc_origin.length) == loc_origin) {
+                ok = true;
+            }
+        }
+        if (!ok) {
+            return {
+                msg: "test pages may have only urls with the same origin as " + main_loc
+            };
+        }
+    }
+    // opera cannot handle urls relative to file:// without assistance
+    if (window.opera != null && window.location.protocol == "file:" && loc.indexOf(":") == -1) {
+        var base = window.location.href;
+        var q_pos = base.indexOf("?");
+        if (q_pos != -1) {
+            base = base.substring(0, q_pos);
+        }
+        var slash_pos = base.lastIndexOf("/");
+        if (slash_pos != -1) {
+            base = base.substring(0, slash_pos + 1);
+            Test.AnotherWay._g_opera_path_correction = base;
+            loc = base + loc;
+        }
+    }
+    // if this function is called from another page, and if that page is in another directory, correction is needed
+    if (outside_path_correction != null) {
+        var pos = loc.indexOf(outside_path_correction);
+        if (pos == 0) {
+            loc = loc.substring(outside_path_correction.length + 1);
+        }
+    }
+    if (iframe.location != null) {
+        iframe.location.replace(loc);
+    }
+    else {
+        iframe.src = loc;
+    }
+    return {};
+};
+
+Test.AnotherWay._start_loading_page = function(){
+    var test_page = Test.AnotherWay._g_tests_queue[0];
+    test_page.loading_timeout_milliseconds = 12000;
+    test_page.timeout_id = setTimeout(Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity);
+    test_page.wait_msg = Test.AnotherWay._print_counter_result(test_page.url, "loading...", test_page.loading_timeout_milliseconds, "loading");
+    if (test_page.convention == "jsan") {
+        // the tests in that page will run when it's loading, so the test object must be ready
+        Test.AnotherWay._g_test_object_for_jsan = new Test.AnotherWay._test_object_t(test_page.url);
+    }
+    var outside_path_correction = null;
+    if (Test.AnotherWay._g_outside_path_correction != null && !test_page.suppress_outside_path_correction) {
+        outside_path_correction = Test.AnotherWay._g_outside_path_correction;
+    }
+    var result = Test.AnotherWay._set_iframe_location(Test.AnotherWay._g_test_iframe, test_page.url, outside_path_correction);
+    if (result.msg != null) {
+        Test.AnotherWay._unprint_result(test_page.wait_msg);
+        Test.AnotherWay._print_result(test_page.url, result.msg, "badtest", null);
+        Test.AnotherWay._load_next_page();
+    }
+};
+
+Test.AnotherWay._loading_timeout = function(){
+    var test_page = Test.AnotherWay._g_tests_queue[0];
+    test_page.loading_timeout_milliseconds -= Test.AnotherWay._g_timeout_granularity;
+    if (test_page.loading_timeout_milliseconds > 0) {
+        Test.AnotherWay._update_msg_counter(test_page.wait_msg, (test_page.loading_timeout_milliseconds / 1000).toFixed());
+        test_page.timeout_id = setTimeout(Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity);
+    }
+    else {
+        Test.AnotherWay._unprint_result(test_page.wait_msg);
+        Test.AnotherWay._print_result(test_page.url, "Unable to load test page. Timeout expired", "badtest", null);
+        Test.AnotherWay._load_next_page();
+    }
+};
+
+Test.AnotherWay._strip_query_and_hash = function(s){
+    var i = s.lastIndexOf("#");
+    if (i != -1) {
+        s = s.substring(0, i);
+    }
+    i = s.lastIndexOf("?");
+    if (i != -1) {
+        s = s.substring(0, i);
+    }
+    return s;
+};
+
+Test.AnotherWay._is_url_loaded = function(url, wnd){
+    var loaded = false;
+    if (wnd != null && wnd.location != null) {
+        // after some popup blocker interference, location may behave strange..
+        var location_s = "";
+        location_s += wnd.location;
+        if (location_s != "") {
+            var pathname = wnd.location.pathname;
+            var expected_url = url;
+            var i = expected_url.lastIndexOf("#");
+            if (i != -1) {
+                expected_url = expected_url.substring(0, i);
+            }
+            i = expected_url.lastIndexOf("?");
+            if (i != -1) {
+                expected_url = expected_url.substring(0, i);
+            }
+            i = expected_url.lastIndexOf("/");
+            if (i != -1 && i != expected_url.length - 1) {
+                expected_url = expected_url.substring(i + 1);
+            }
+            i = pathname.indexOf(expected_url);
+            if (wnd.location.href == url || (i != -1 && i == pathname.length - expected_url.length)) {
+                if ( /*window.opera==null*/wnd.document.readyState == null || wnd.document.readyState == "complete") { // for opera (and IE?), getElementById does not work until..
+                    loaded = true;
+                }
+            }
+        }
+    }
+    return loaded;
+};
+// find and run all test functions in the g_cur_page html page.
+Test.AnotherWay._test_page_onload = function(){
+    if (Test.AnotherWay._g_tests_queue.length == 0) {
+        return;
+    }
+    var test_page = Test.AnotherWay._g_tests_queue[0];
+    if (!Test.AnotherWay._is_url_loaded(test_page.url, Test.AnotherWay._g_test_iframe)) {
+        return;
+    }
+    clearTimeout(test_page.timeout_id);
+    Test.AnotherWay._unprint_result(test_page.wait_msg);
+    
+    if (test_page.convention == "anotherway") {
+        // get test function names (those beginning with "test")
+        if (typeof(Test.AnotherWay._g_test_iframe.document.scripts) != 'undefined') { // IE
+            for (var i = 0; i < Test.AnotherWay._g_test_iframe.document.scripts.length; ++i) {
+                var script_text = Test.AnotherWay._g_test_iframe.document.scripts[i].text;
+                var fun_sig = "function test";
+                var fun_start = script_text.indexOf(fun_sig);
+                
+                while (fun_start != -1) {
+                    script_text = script_text.substring(fun_start, script_text.length);
+                    var fun_end = script_text.indexOf('(');
+                    var fun_name = script_text.substring("function ".length, fun_end);
+                    var whitespace = fun_name.indexOf(' ');
+                    if (whitespace >= 0) {
+                        fun_name = fun_name.substring(0, whitespace);
+                    }
+                    test_page.test_objects.push(new Test.AnotherWay._test_object_t(fun_name));
+                    script_text = script_text.substring(fun_end, script_text.length);
+                    fun_start = script_text.indexOf(fun_sig);
+                }
+            }
+        }
+        else { // otherwise (not IE) it ought to work like this
+            for (var i in Test.AnotherWay._g_test_iframe) {
+                // Hack to prevent failure in FF3.0b1 (innerWidth/innerHeight) and FF>=3.5 (sessionStorage)
+                if (i == "innerWidth" || i == "innerHeight" || i == "sessionStorage") {
+                    continue;
+                }
+                if (typeof(Test.AnotherWay._g_test_iframe[i]) == 'function') {
+                    if (i.substring(0, 4) == "test") {
+                        test_page.test_objects.push(new Test.AnotherWay._test_object_t(i));
+                    }
+                }
+            }
+        }
+    }
+    else 
+        if (test_page.convention == "jsan") {
+            // the test object is already filled with results
+            test_page.test_objects.push(Test.AnotherWay._g_test_object_for_jsan);
+        }
+    
+    if (test_page.test_objects.length == 0) {
+        Test.AnotherWay._print_result(test_page.url, "No test functions defined in the page", "badtest", null);
+        Test.AnotherWay._load_next_page();
+        return;
+    }
+    
+    test_page.wait_msg = Test.AnotherWay._print_result(test_page.url, "running tests..<span class=\"counter\">" + test_page.test_objects.length + "</span>", "running", null);
+    
+    test_page.test_object_i = 0;
+    Test.AnotherWay._run_more_tests();
+};
+
+Test.AnotherWay._handle_exception = function(o, e, title){
+    var s = title + ": " + typeof(e) + ": ";
+    if (e.message != null) {
+        s += e.message;
+    }
+    else 
+        if (e.description != null) {
+            s += e.description;
+        }
+        else {
+            s += e.toString();
+        }
+    //  if( e.location!=null ) {  // XXX figure out how to display exception location if it's present (like in mozilla)
+    //      s+=" location: "+e.location.toString();
+    //  }
+    o.exception = s;
+    s = [];
+    if (e.stack) {
+        var lines = e.stack.split("\n");
+        for (var i = 0; i < lines.length; ++i) {
+            // format of the line: func_name(args)@file_name:line_no
+            if (lines[i].match(/(\w*)\(([^\)]*)\)@(.*):([^:]*)$/)) {
+                var func_name = RegExp.$1;
+                if (func_name.length == 0) {
+                    func_name = "<anonymous>";
+                }
+                s.push("in " + func_name + "( " + RegExp.$2 + ") at " + RegExp.$3 + " line " + RegExp.$4 + "\n");
+            }
+        }
+    }
+    o.exception_stack = s;
+};
+
+Test.AnotherWay._run_more_tests = function(){
+    var test_page = Test.AnotherWay._g_tests_queue[0];
+    while (test_page.test_object_i < test_page.test_objects.length) {
+        Test.AnotherWay._update_msg_counter(test_page.wait_msg, (1 + test_page.test_object_i) + "/" + test_page.test_objects.length);
+        var o = test_page.test_objects[test_page.test_object_i];
+        if (test_page.convention == "anotherway") {
+            try {
+                Test.AnotherWay._g_test_iframe[o.name](o);
+            } 
+            catch (e) {
+                Test.AnotherWay._handle_exception(o, e, "");
+            }
+        } // for "jsan" convention, test has run already
+        if (o.delay_actions.length > 0 || o.wait_result_milliseconds > 0) {
+            o.delay_total_milliseconds_left += o.wait_result_milliseconds;
+            Test.AnotherWay._delay_actions_timeout();
+            return;
+        }
+        ++test_page.test_object_i;
+    }
+    Test.AnotherWay._unprint_result(test_page.wait_msg);
+    Test.AnotherWay._print_result(test_page.url, null, null, test_page.test_objects);
+    Test.AnotherWay._load_next_page();
+};
+
+Test.AnotherWay._delay_actions_timeout = function(){
+    var test_page = Test.AnotherWay._g_tests_queue[0];
+    var test_object = test_page.test_objects[test_page.test_object_i];
+    var finished = true;
+    if (test_object.delay_action_i == null) {
+        // set up to start first action
+        test_object.delay_action_i = -1;
+    }
+    else {
+        // perform current action
+        var milliseconds_passed = (new Date()).getTime() - test_object.delay_prev_timer_time;
+        test_object.delay_current_milliseconds_left -= milliseconds_passed;
+        test_object.delay_total_milliseconds_left -= milliseconds_passed;
+        finished = Test.AnotherWay._delay_continue_action(test_object, milliseconds_passed);
+    }
+    while (finished && test_object.delay_action_i < test_object.delay_actions.length) {
+        ++test_object.delay_action_i; // start next action
+        finished = Test.AnotherWay._delay_start_action(test_object);
+    }
+    if (test_object.delay_action_i <= test_object.delay_actions.length) { // any more actions left ?
+        test_object.delay_prev_timer_time = (new Date()).getTime();
+        var next_timeout = Test.AnotherWay._g_timeout_granularity;
+        if (test_object.delay_current_milliseconds_left < next_timeout) {
+            next_timeout = test_object.delay_current_milliseconds_left;
+        }
+        if (test_object.second_wait_msg != null) {
+            Test.AnotherWay._update_msg_counter(test_object.second_wait_msg, (test_object.delay_total_milliseconds_left / 1000).toFixed());
+        }
+        setTimeout(Test.AnotherWay._delay_actions_timeout, next_timeout);
+    }
+    else { // no more actions left. run the next test.
+        if (test_object.second_wait_msg != null) {
+            Test.AnotherWay._unprint_result(test_object.second_wait_msg);
+            test_object.second_wait_msg = null;
+        }
+        ++test_page.test_object_i;
+        Test.AnotherWay._run_more_tests();
+    }
+};
+
+Test.AnotherWay._delay_start_action = function(test_object){
+    var finished = false;
+    var wait_msg = "";
+    if (test_object.delay_action_i == test_object.delay_actions.length) {
+        if (test_object.wait_result_milliseconds > 0) {
+            test_object.delay_current_milliseconds_left = test_object.wait_result_milliseconds; // wait for result
+            wait_msg = "waiting for results..";
+        }
+        else {
+            ++test_object.delay_action_i; // dont wait for result
+        }
+    }
+    else {
+        var action = test_object.delay_actions[test_object.delay_action_i];
+        if (action.action_kind == "call") {
+            test_object.delay_current_milliseconds_left = action.call_delay_milliseconds;
+            wait_msg = "performing delayed calls..";
+        }
+        else 
+            if (action.action_kind == "window") {
+                if (Test.AnotherWay._g_opera_path_correction != null && action.wnd_url.indexOf(":") == -1) {
+                    action.wnd_url = Test.AnotherWay._g_opera_path_correction + action.wnd_url;
+                }
+                action.wnd_wnd = window.open(action.wnd_url, "_blank");
+                if (action.wnd_wnd == null) {
+                    finished = true;
+                    test_object.fail("unable to open window for " + action.wnd_url);
+                }
+                else {
+                    test_object.delay_current_milliseconds_left = action.wnd_timeout_milliseconds;
+                    wait_msg = "opening window..";
+                }
+            }
+            else 
+                if (action.action_kind == "replay") {
+                    if (action.replay_events.length == 0) {
+                        finished = true;
+                    }
+                    else {
+                        action.replay_event_i = 0;
+                        test_object.delay_current_milliseconds_left = action.replay_events[0]["time"];
+                        wait_msg = "replaying events..";
+                    }
+                }
+    }
+    if (test_object.second_wait_msg != null) {
+        Test.AnotherWay._unprint_result(test_object.second_wait_msg);
+    }
+    if (wait_msg != "") {
+        var test_page = Test.AnotherWay._g_tests_queue[0];
+        test_object.second_wait_msg = Test.AnotherWay._print_counter_result(test_page.url, wait_msg, test_object.delay_total_milliseconds_left, "waiting");
+    }
+    else {
+        test_object.second_wait_msg = null;
+    }
+    return finished;
+};
+Test.AnotherWay._delay_continue_action = function(test_object, milliseconds_passed){
+    var finished = test_object.delay_current_milliseconds_left <= 0;
+    if (test_object.delay_action_i == test_object.delay_actions.length) { // action is "waiting for results"
+        if (test_object.n_plan != null && test_object.n_plan == test_object.n_ok + test_object.n_fail) {
+            finished = true; // if all assertions results are recorded, don't wait any more
+        }
+        if (finished) {
+            ++test_object.delay_action_i; // move on to the next test
+        }
+    }
+    else {
+        var action = test_object.delay_actions[test_object.delay_action_i];
+        if (action.action_kind == "call") {
+            if (finished) {
+                try {
+                    action.call_fn();
+                } 
+                catch (e) {
+                    Test.AnotherWay._handle_exception(test_object, e, "in delay_call");
+                }
+            }
+        }
+        else 
+            if (action.action_kind == "window") {
+                test_object.delay_total_milliseconds_left += milliseconds_passed; // for "window", the countdown is suspended since it's unknown how long it will take
+                if (Test.AnotherWay._is_url_loaded(action.wnd_url, action.wnd_wnd)) {
+                    try {
+                        action.wnd_fn(action.wnd_wnd);
+                    } 
+                    catch (e) {
+                        Test.AnotherWay._handle_exception(test_object, e, "in open_window function call");
+                    }
+                    finished = true;
+                }
+                else 
+                    if (finished) {
+                        test_object.fail("unable to open window for url '" + action.wnd_url + "'. timeout expired");
+                    }
+            }
+            else 
+                if (action.action_kind == "replay") {
+                    if (finished) {
+                        //              try {
+                        Test.AnotherWay._delay_replay_event(test_object, action.replay_wnd, action.replay_events[action.replay_event_i], action.replay_checkpoints);
+                        //              }catch( e ) { // disabled, until I know how to gel location info from an exception
+                        //                  Test.AnotherWay._handle_exception( test_object, e, "while replaying event" );
+                        //              }
+                        ++action.replay_event_i;
+                        finished = action.replay_event_i == action.replay_events.length;
+                        if (!finished) {
+                            test_object.delay_current_milliseconds_left = action.replay_events[action.replay_event_i]["time"];
+                        }
+                    }
+                }
+    }
+    return finished;
+};
+
+Test.AnotherWay._delay_replay_event = function(test_object, wnd, event, checkpoints){
+    if (event.type == "_checkpoint") {
+        var checkpoint_n = event.which;
+        var prev_n_fail = test_object.n_fail;
+        checkpoints[checkpoint_n](test_object, wnd);
+        var flash_color = prev_n_fail == test_object.n_fail ? "#2f2" : "#f22";
+        Test.AnotherWay._record_flash_border(flash_color);
+    }
+    else 
+        if (event.type == "click" || event.type == "mouseover" || event.type == "mouseout" || event.type == "mousemove" || event.type == "mousedown" || event.type == "mouseup") {
+            var target = Test.AnotherWay._record_node_path_to_node(event["target"], wnd.document);
+            if (target != null) {
+                Test.AnotherWay._record_control_update_highlight(target, "ball", event);
+                var e = wnd.document.createEvent("MouseEvents");
+                var related_target = Test.AnotherWay._record_node_path_to_node(event["relatedTarget"], wnd.document);
+                e.initMouseEvent(event["type"], event["cancelable"], event["bubbles"], wnd.document.defaultView, event["detail"], event["screenX"], event["screenY"], event["clientX"], event["clientY"], event["ctrlKey"], event["altKey"], event["shiftKey"], event["metaKey"], event["button"], Test.AnotherWay._record_node_path_to_node(event["relatedTarget"], wnd.document));
+                // Firefox 1.0.6 somehow loses relatedTarget somewhere on the way. Pass through our own, for those who choose to care.
+                e.passThroughRelatedTarget = related_target;
+                target.dispatchEvent(e);
+            }
+        }
+        else 
+            if (event.type == "keyup" || event.type == "keydown" || event.type == "keypress") {
+                var e = wnd.document.createEvent("KeyboardEvents"); // forget it. Apparently it's not supported neither by mozilla nor by opera.
+                e.initKeyboardEvent(event["type"], event["cancelable"], event["bubbles"], wnd.document.defaultView, event["which"], event["which"], event["ctrlKey"], event["altKey"], event["shiftKey"], event["metaKey"], false);
+                wnd.document.dispatchEvent(e);
+            }
+};
+
+Test.AnotherWay._print_counter_result = function(url, msg, milliseconds, style){
+    return Test.AnotherWay._print_result(url, msg + "<span class=\"counter\">" + (milliseconds / 1000).toFixed() + "</span>", style, null);
+};
+
+Test.AnotherWay._g_result_count = 0; // for assigning unique ids to result paragraphs
+// number of pages tested
+Test.AnotherWay._g_ok_pages = 0;
+Test.AnotherWay._g_fail_pages = 0;
+
+Test.AnotherWay._print_result = function(url, msg, style, test_objects){
+    var results = document.getElementById("results");
+    var r = results.appendChild(document.createElement("p"));
+    r.id = "result" + Test.AnotherWay._g_result_count;
+    ++Test.AnotherWay._g_result_count;
+    r.onclick = Test.AnotherWay._toggle_detail;
+    var text = "<span class=\"bullet\">&nbsp;&nbsp;&nbsp;</span>&nbsp;";
+    if (url != "") {
+        text += url + ":  ";
+    }
+    if (msg != null) {
+        text += msg;
+    }
+    if (test_objects != null) {
+        // compose summary and detail texts
+        var total_ok = 0;
+        var total_detail_ok = 0;
+        var total_fail = 0;
+        var total_detail_fail = 0;
+        var no_plan = 0;
+        
+        var detail = results.appendChild(document.createElement("div"));
+        
+        if (r.id.match(/^result(\d+)$/)) {
+            detail.id = "result_detail" + RegExp.$1;
+        }
+        
+        for (var i = 0; i < test_objects.length; ++i) {
+            var o = test_objects[i];
+            var p;
+            var p_text;
+            p = document.createElement("P");
+            Test.AnotherWay._set_css_class(p, "result_detail");
+            p_text = o.name;
+            if (o.n_fail > 0 || o.exception || (o.n_plan != null && o.n_plan != o.n_ok + o.n_fail) || (o.n_plan == null && o.n_ok == 0 && o.n_fail == 0)) {
+                ++total_fail;
+                p_text += " <span class=\"fail\">";
+                if (o.n_plan != null && o.n_plan != o.n_ok + o.n_fail) {
+                    p_text += "planned " + o.n_plan + " assertions but got " + (o.n_ok + o.n_fail) + "; ";
+                }
+                if (o.n_plan == null && o.n_ok == 0 && o.n_fail == 0) {
+                    p_text += "test did not output anything";
+                }
+                else {
+                    p_text += " fail " + o.n_fail;
+                }
+                p_text += "</span>";
+            }
+            else {
+                ++total_ok;
+            }
+            p_text += " ok " + o.n_ok;
+            if (o.n_plan == null) {
+                no_plan = 1;
+                p_text += " <span class=\"warning\">no plan</span>";
+            }
+            p.innerHTML = p_text;
+            detail.appendChild(p);
+            if (o.exception) {
+                p = document.createElement("P");
+                Test.AnotherWay._set_css_class(p, "result_exception_detail");
+                p.innerHTML = "<span class=\"fail\">exception:</span> " + o.exception;
+                detail.appendChild(p);
+                p = document.createElement("P");
+                Test.AnotherWay._set_css_class(p, "result_exception_stack_detail");
+                p.innerHTML = o.exception_stack.join("<br/>");
+                detail.appendChild(p);
+            }
+            for (var ii = 0; ii < o.assertions.length; ++ii) {
+                var oo = o.assertions[ii];
+                var status = oo.ok ? "ok" : "<span class=\"fail\">fail</span>";
+                p = document.createElement("P");
+                Test.AnotherWay._set_css_class(p, "result_micro_detail");
+                p.innerHTML = status;
+                p.appendChild(document.createTextNode(" " + oo.name));
+                detail.appendChild(p);
+            }
+            total_detail_ok += o.n_ok;
+            total_detail_fail += o.n_fail;
+        }
+        if (total_fail || total_detail_fail) {
+            text += " fail " + total_fail;
+        }
+        text += " ok " + total_ok + " (detailed:";
+        if (total_fail || total_detail_fail) {
+            text += " fail " + total_detail_fail;
+        }
+        text += " ok " + total_detail_ok + ")";
+        if (no_plan) {
+            text += " <span class=\"warning\">no plan</span>";
+        }
+        style = total_fail == 0 ? "ok" : "fail";
+        detail.style.display = style == "fail" ? "block" : "none";
+        detail.style.cursor = "text";
+    }
+    if (style != null) {
+        Test.AnotherWay._set_css_class(r, style);
+        if (style == "ok") {
+            ++Test.AnotherWay._g_ok_pages;
+        }
+        else 
+            if (style == "fail" || style == "badtest") {
+                ++Test.AnotherWay._g_fail_pages;
+            }
+        var pages_total = "";
+        if (Test.AnotherWay._g_fail_pages > 0) {
+            pages_total += " fail " + Test.AnotherWay._g_fail_pages;
+        }
+        pages_total += " ok " + Test.AnotherWay._g_ok_pages;
+        
+        // also count out the total number of tests in fail and ok
+        Test.AnotherWay._openlayers_sum_total_detail_ok  = Test.AnotherWay._openlayers_sum_total_detail_ok || 0;
+        Test.AnotherWay._openlayers_sum_total_detail_ok += (total_detail_ok||0);
+        
+        Test.AnotherWay._openlayers_sum_total_detail_fail  = Test.AnotherWay._openlayers_sum_total_detail_fail || 0;
+        Test.AnotherWay._openlayers_sum_total_detail_fail += (total_detail_fail||0);
+        
+        pages_total+=" (detailed: fail " + Test.AnotherWay._openlayers_sum_total_detail_fail + " | ok " + Test.AnotherWay._openlayers_sum_total_detail_ok + ")";
+        
+        Test.AnotherWay._update_results_total(pages_total);
+    }
+    r.innerHTML = text;
+    if (results.scrollHeight != null && results.scrollTop != null && results.offsetHeight != null) {
+        results.scrollTop = results.scrollHeight - results.offsetHeight;
+    }
+    // when test_objects is not null, the results are final - good time to clean up
+    if (test_objects != null) {
+        for (var i = 0; i < test_objects.length; ++i) {
+            var actions = test_objects[i].delay_actions;
+            for (var action_i = 0; action_i < actions.length; ++action_i) {
+                var action = actions[action_i];
+                if (action.action_kind == "window" && action.wnd_wnd != null && !action.wnd_no_close) {
+                    action.wnd_wnd.close();
+                    action.wnd_wnd = null;
+                }
+            }
+        }
+    }
+    return r;
+};
+
+Test.AnotherWay._unprint_result = function(child){
+    var results = document.getElementById("results");
+    results.removeChild(child);
+};
+
+Test.AnotherWay._toggle_detail = function(){
+    if (this.id.match(/^result(\d+)$/)) {
+        var detail = document.getElementById("result_detail" + RegExp.$1);
+        if (detail != null) {
+            if (detail.style.display == "none") {
+                detail.style.display = "block";
+            }
+            else 
+                if (detail.style.display == "block") {
+                    detail.style.display = "none";
+                }
+        }
+    }
+};
+
+Test.AnotherWay._update_msg_counter = function(msg, text){
+    for (var i = 0; i < msg.childNodes.length; ++i) {
+        var item = msg.childNodes[i];
+        if (item.nodeName == "SPAN" && Test.AnotherWay._get_css_class(item) == "counter") {
+            item.innerHTML = text;
+        }
+    }
+};
+
+Test.AnotherWay._update_results_total = function(msg){
+    var total = document.getElementById("total");
+    if (total) {
+        total.innerHTML = msg;
+    }
+};
+
+Test.AnotherWay._results_clear_onclick = function(){
+    var results = document.getElementById("results");
+    results.innerHTML = "";
+    Test.AnotherWay._update_results_total("");
+    Test.AnotherWay._g_ok_pages = 0;
+    Test.AnotherWay._g_fail_pages = 0;
+    Test.AnotherWay._openlayers_sum_total_detail_ok=0;
+    Test.AnotherWay._openlayers_sum_total_detail_fail=0;
+    var debug = document.getElementById("debug");
+    debug.innerHTML = "";
+    Test.AnotherWay.reset_running_time();
+};
+
+Test.AnotherWay._get_css_class = function(o){
+    var c = o.getAttribute("className");
+    if (c == null || c == "") {
+        c = o.getAttribute("class");
+    }
+    return c;
+};
+
+Test.AnotherWay._set_css_class = function(o, css_class){
+    o.setAttribute("className", css_class);
+    o.setAttribute("class", css_class);
+};
+
+Test.AnotherWay._tab_onclick = function(){
+    var tab = this;
+    var tabs = [document.getElementById("debug_tab"), document.getElementById("results_tab")];
+    var panes = [document.getElementById("debug"), document.getElementById("results")];
+    for (var i = 0; i < tabs.length; ++i) {
+        if (tab == tabs[i]) {
+            Test.AnotherWay._set_css_class(tabs[i], "active_tab");
+            panes[i].style.display = "block";
+        }
+        else {
+            Test.AnotherWay._set_css_class(tabs[i], "inactive_tab");
+            panes[i].style.display = "none";
+        }
+    }
+};
+Test.AnotherWay._tab_mouseover = function(){
+    if (Test.AnotherWay._get_css_class(this) == "inactive_tab") {
+        Test.AnotherWay._set_css_class(this, "inactive_mouseover_tab");
+    }
+};
+Test.AnotherWay._tab_mouseout = function(){
+    if (Test.AnotherWay._get_css_class(this) == "inactive_mouseover_tab") {
+        Test.AnotherWay._set_css_class(this, "inactive_tab");
+    }
+};
+
+// recording mouse input
+Test.AnotherWay._record_check_onfocus = function(){
+    var o = this;
+    var check_select = o.type != "text";
+    var div = document.getElementById("record_div");
+    var inputs = div.getElementsByTagName("input");
+    for (var i = 0; i < inputs.length; ++i) {
+        var input = inputs[i];
+        if (input.type == "radio") {
+            if (input.value == "select") {
+                input.checked = check_select;
+            }
+            else 
+                if (input.value == "input") {
+                    input.checked = !check_select;
+                }
+        }
+    }
+};
+
+Test.AnotherWay._g_no_record_msg = null; // not null - recording is unavailable
+Test.AnotherWay._g_record_timeout_cnt = 0; // opening window for a page for recording
+Test.AnotherWay._g_record_url = null;
+Test.AnotherWay._g_record_wnd = null;
+Test.AnotherWay._g_record_random_id = null; // added to element ids of record_control div so that they do not clash with ids already in the page for which input is recorded
+Test.AnotherWay._g_record_keydown = null; // recording control - which key is down
+Test.AnotherWay._g_record_ctrl_keydown = false;
+Test.AnotherWay._g_record_shift_keydown = false;
+Test.AnotherWay._g_record_control_visible = true; // recording control ui state
+Test.AnotherWay._g_record_started;
+Test.AnotherWay._g_record_paused;
+Test.AnotherWay._g_record_include_mousemove = false;
+Test.AnotherWay._g_record_start_time; // for time references
+Test.AnotherWay._g_record_pause_start_time;
+Test.AnotherWay._g_record_update_time_interval; // showing time in the control ui
+Test.AnotherWay._g_record_waiting_for_results = false; // waiting for results window to open
+Test.AnotherWay._g_record_events; // recorded events
+Test.AnotherWay._g_record_under_cursor; // track element under cursor
+Test.AnotherWay._g_record_checkpoint_count; // for checkpoint numbering
+Test.AnotherWay._g_record_mouse_over_record_control; // for avoiding record control highlight on mouseover
+Test.AnotherWay._g_record_highlighted_element = {
+    element: null,
+    x: null,
+    y: null
+};
+
+Test.AnotherWay._record_control_get_element = function(id){
+    if (Test.AnotherWay._g_record_wnd != null && Test.AnotherWay._g_record_wnd.document != null) {
+        return Test.AnotherWay._g_record_wnd.document.getElementById(id + Test.AnotherWay._g_record_random_id);
+    }
+    else {
+        return null;
+    }
+};
+Test.AnotherWay._record_start_onclick = function() // "record" button on the run_tests.html: open a window for a page for which input is recorded
+{
+    if (Test.AnotherWay._g_no_record_msg != null) {
+        alert(Test.AnotherWay._g_no_record_msg);
+        return;
+    }
+    if (Test.AnotherWay._g_record_timeout_cnt > 0 ||
+    (Test.AnotherWay._g_record_wnd != null && (Test.AnotherWay._g_record_wnd.closed != null && !Test.AnotherWay._g_record_wnd.closed))) { // in opera, closed is null.
+        alert("there is already window opened for recording input for a page " + Test.AnotherWay._g_record_url);
+        return;
+    }
+    var div = document.getElementById("record_div");
+    var inputs = div.getElementsByTagName("input");
+    var url = null;
+    for (var i = 0; i < inputs.length; ++i) {
+        var input = inputs[i];
+        if (input.type == "radio") {
+            if (input.value == "select" && input.checked) {
+                var index = document.getElementById("record_select").selectedIndex;
+                if (index > 0) {
+                    url = Test.AnotherWay._g_test_page_urls[index - 1].url;
+                }
+            }
+            else 
+                if (input.value == "input" && input.checked) {
+                    url = document.getElementById("record_input").value;
+                }
+        }
+    }
+    if (url != null) {
+        Test.AnotherWay._g_record_url = url;
+        Test.AnotherWay._g_record_wnd = window.open(url, "_blank");
+        if (Test.AnotherWay._g_record_wnd == null) {
+            alert("unable to open new window for a page: " + url);
+        }
+        else {
+            Test.AnotherWay._g_record_timeout_cnt = 50;
+            setTimeout(Test.AnotherWay._record_window_timeout, 100);
+        }
+    }
+};
+Test.AnotherWay._record_window_timeout = function(){
+    if (Test.AnotherWay._is_url_loaded(Test.AnotherWay._g_record_url, Test.AnotherWay._g_record_wnd)) {
+        Test.AnotherWay._record_window_setup(Test.AnotherWay._g_record_wnd);
+    }
+    else {
+        if (--Test.AnotherWay._g_record_timeout_cnt > 0) {
+            setTimeout(Test.AnotherWay._record_window_timeout, 100);
+        }
+        else {
+            alert("timeout expired while opening new window for a page: " + Test.AnotherWay._g_record_url);
+            Test.AnotherWay._g_record_wnd = null;
+            Test.AnotherWay._g_record_url = null;
+            Test.AnotherWay._g_record_timeout_cnt = 0;
+        }
+    }
+};
+Test.AnotherWay._record_control_randomize_id = function(e, r){
+    if (e.id != "") {
+        e.id = e.id + r;
+    }
+    for (var c = e.firstChild; c != null; c = c.nextSibling) {
+        Test.AnotherWay._record_control_randomize_id(c, r);
+    }
+};
+Test.AnotherWay._record_window_setup = function(wnd) // insert recording control into the page for which input is recorded
+{
+    Test.AnotherWay._g_record_timeout_cnt = 0;
+    var this_div = document.getElementById("record_control");
+    var record_control = wnd.document.importNode(this_div, true);
+    Test.AnotherWay._g_record_random_id = (1000 * Math.random()).toFixed();
+    Test.AnotherWay._record_control_randomize_id(record_control, Test.AnotherWay._g_record_random_id);
+    Test.AnotherWay._g_record_control_visible = true;
+    Test.AnotherWay._g_record_started = false;
+    Test.AnotherWay._g_record_paused = false;
+    Test.AnotherWay._g_record_checkpoint_count = 0;
+    Test.AnotherWay._g_record_mouse_over_record_control = false;
+    var doc = wnd.document;
+    doc.body.appendChild(record_control);
+    // opera sans-serif font is different
+    if (window.opera) {
+        cursor_over_indicator = Test.AnotherWay._record_control_get_element("record_cursor_over");
+        cursor_over_indicator.style.width = "18em";
+        cursor_over_indicator.style.height = "2em";
+        cursor_over_indicator.style.fontSize = "7pt";
+    }
+    doc.addEventListener("keydown", Test.AnotherWay._record_control_keydown, true);
+    doc.addEventListener("keyup", Test.AnotherWay._record_control_keyup, true);
+    //  doc.addEventListener( "keypress", Test.AnotherWay._record_event, true ); // replaying is not supported by any known browser
+    
+    doc.body.addEventListener("mousemove", Test.AnotherWay._record_on_mousemove, true);
+    doc.body.addEventListener("click", Test.AnotherWay._record_event, true);
+    doc.body.addEventListener("mouseover", Test.AnotherWay._record_event, true);
+    doc.body.addEventListener("mouseout", Test.AnotherWay._record_event, true);
+    doc.body.addEventListener("mousedown", Test.AnotherWay._record_event, true);
+    doc.body.addEventListener("mouseup", Test.AnotherWay._record_event, true);
+};
+Test.AnotherWay._record_control_key_disabled = function(k){
+    if (k == "c") {
+        return !Test.AnotherWay._g_record_started;
+    }
+    else 
+        if (k == "p") {
+            return !Test.AnotherWay._g_record_started;
+        }
+        else 
+            if (k == "s") {
+                return Test.AnotherWay._g_record_waiting_for_results;
+            }
+            else {
+                return false;
+            }
+};
+
+Test.AnotherWay._record_control_update_ui = function(){
+    var keydown_color = "#fff";
+    var disabled_color = "#aaa";
+    var button_color = "#adf";
+    var active_color = "#fdf";
+    
+    var display = {};
+    display[false] = "none";
+    display[true] = "inline";
+    
+    var s_button = Test.AnotherWay._record_control_get_element("record_s");
+    var record_on = Test.AnotherWay._record_control_get_element("record_on");
+    var record_off = Test.AnotherWay._record_control_get_element("record_off");
+    
+    s_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled("s") ? disabled_color : Test.AnotherWay._g_record_keydown == "s" ? keydown_color : Test.AnotherWay._g_record_started ? active_color : button_color;
+    record_on.style.display = display[!Test.AnotherWay._g_record_started];
+    record_off.style.display = display[Test.AnotherWay._g_record_started];
+    
+    var h_button = Test.AnotherWay._record_control_get_element("record_h");
+    h_button.style.backgroundColor = Test.AnotherWay._g_record_keydown == "h" ? keydown_color : button_color;
+    
+    var p_button = Test.AnotherWay._record_control_get_element("record_p");
+    var record_pause_on = Test.AnotherWay._record_control_get_element("record_pause_on");
+    var record_pause_off = Test.AnotherWay._record_control_get_element("record_pause_off");
+    p_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled("p") ? disabled_color : Test.AnotherWay._g_record_keydown == "p" ? keydown_color : Test.AnotherWay._g_record_paused ? active_color : button_color;
+    record_pause_on.style.display = display[!Test.AnotherWay._g_record_paused];
+    record_pause_off.style.display = display[Test.AnotherWay._g_record_paused];
+    
+    var m_button = Test.AnotherWay._record_control_get_element("record_m");
+    var record_include_mousemove = Test.AnotherWay._record_control_get_element("record_include_mousemove");
+    var record_omit_mousemove = Test.AnotherWay._record_control_get_element("record_omit_mousemove");
+    m_button.style.backgroundColor = Test.AnotherWay._g_record_keydown == "m" ? keydown_color : Test.AnotherWay._g_record_include_mousemove ? active_color : button_color;
+    record_include_mousemove.style.display = display[!Test.AnotherWay._g_record_include_mousemove];
+    record_omit_mousemove.style.display = display[Test.AnotherWay._g_record_include_mousemove];
+    
+    var c_button = Test.AnotherWay._record_control_get_element("record_c");
+    c_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled("c") ? disabled_color : Test.AnotherWay._g_record_keydown == "c" ? keydown_color : button_color;
+    
+    var record_indicator = Test.AnotherWay._record_control_get_element("record_indicator");
+    record_indicator.style.display = display[Test.AnotherWay._g_record_started];
+    
+    var pause_indicator = Test.AnotherWay._record_control_get_element("record_pause_indicator");
+    pause_indicator.style.display = display[Test.AnotherWay._g_record_paused];
+    
+    var record_control = Test.AnotherWay._record_control_get_element("record_control");
+    record_control.style.display = Test.AnotherWay._g_record_control_visible ? "block" : "none";
+    
+    var shift_button = Test.AnotherWay._record_control_get_element("record_shift_key");
+    shift_button.style.backgroundColor = Test.AnotherWay._g_record_shift_keydown ? keydown_color : button_color;
+    
+    var ctrl_button = Test.AnotherWay._record_control_get_element("record_ctrl_key");
+    ctrl_button.style.backgroundColor = Test.AnotherWay._g_record_ctrl_keydown ? keydown_color : button_color;
+};
+Test.AnotherWay._record_format_time = function(t){
+    t = new Date(t);
+    var m = t.getMinutes();
+    var s = t.getSeconds();
+    var str = m == 0 ? "" : m + "m ";
+    str += s + "s.";
+    return str;
+};
+Test.AnotherWay._record_control_update_time = function(){
+    var time_display = Test.AnotherWay._record_control_get_element("record_time");
+    if (time_display != null) {
+        time_display.innerHTML = Test.AnotherWay._record_format_time((new Date()).getTime() - Test.AnotherWay._g_record_start_time);
+    }
+};
+Test.AnotherWay._record_control_update_highlight = function(elem, style, event){
+    if (elem == null) {
+        Test.AnotherWay._record_highlight_border(null);
+    }
+    else {
+        var pos = Test.AnotherWay._get_page_coords(elem);
+        if (style == "ball" || elem != Test.AnotherWay._g_record_highlighted_element.element || pos.x != Test.AnotherWay._g_record_highlighted_element.x || pos.y != Test.AnotherWay._g_record_highlighted_element.y) {
+            Test.AnotherWay._g_record_highlighted_element = {
+                element: elem,
+                x: pos.x,
+                y: pos.y
+            };
+            Test.AnotherWay._record_highlight_border(elem, style, event);
+        }
+    }
+};
+Test.AnotherWay._record_decode_key = function(event){
+    var k = null;
+    if (event == null) {
+        k = Test.AnotherWay._g_record_wnd.event.keyCode;
+    }
+    else {
+        k = event.which;
+    }
+    if (k == 83) {
+        return "s";
+    }
+    else 
+        if (k == 72) {
+            return "h";
+        }
+        else 
+            if (k == 73) {
+                return "i";
+            }
+            else 
+                if (k == 80) {
+                    return "p";
+                }
+                else 
+                    if (k == 67) {
+                        return "c";
+                    }
+                    else 
+                        if (k == 77) {
+                            return "m";
+                        }
+                        else 
+                            if (k == 16) {
+                                return "shift";
+                            }
+                            else 
+                                if (k == 17) {
+                                    return "ctrl";
+                                }
+                                else 
+                                    if (k == 18) {
+                                        return "alt";
+                                    }
+                                    else 
+                                        if (k == 19) {
+                                            return "pause";
+                                        }
+                                        else 
+                                            if (k == 123) {
+                                                return "f12";
+                                            }
+    return "";
+};
+Test.AnotherWay._record_control_keydown = function(event){
+    var handled = false;
+    var k = Test.AnotherWay._record_decode_key(event);
+    if (k == "shift") {
+        Test.AnotherWay._g_record_shift_keydown = true;
+    }
+    else 
+        if (k == "ctrl") {
+            Test.AnotherWay._g_record_ctrl_keydown = true;
+        }
+        else 
+            if (k != "" && (Test.AnotherWay._g_record_keydown == null || Test.AnotherWay._g_record_keydown == k)) {
+                if (Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown && !Test.AnotherWay._record_control_key_disabled(k)) {
+                    Test.AnotherWay._g_record_keydown = k;
+                    handled = true;
+                }
+            }
+            else {
+                Test.AnotherWay._g_record_keydown = "";
+            }
+    Test.AnotherWay._record_control_update_ui();
+    if (!handled) {
+        //      Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
+    }
+    return;
+};
+Test.AnotherWay._record_control_keyup = function(event){
+    var handled = false;
+    var k = Test.AnotherWay._record_decode_key(event);
+    if (k == "shift") {
+        Test.AnotherWay._g_record_shift_keydown = false;
+    }
+    else 
+        if (k == "ctrl") {
+            Test.AnotherWay._g_record_ctrl_keydown = false;
+        }
+        else 
+            if (k != "" && k == Test.AnotherWay._g_record_keydown && Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown) {
+                if (k == "s") {
+                    Test.AnotherWay._g_record_started = !Test.AnotherWay._g_record_started;
+                    if (Test.AnotherWay._g_record_started) {
+                        Test.AnotherWay._g_record_events = [];
+                        Test.AnotherWay._g_record_start_time = (new Date()).getTime();
+                        Test.AnotherWay._record_control_update_time();
+                        Test.AnotherWay._g_record_update_time_interval = window.setInterval(Test.AnotherWay._record_control_update_time, 200);
+                    }
+                    else {
+                        Test.AnotherWay._record_control_update_highlight(null);
+                        if (!Test.AnotherWay._g_record_paused) {
+                            window.clearInterval(Test.AnotherWay._g_record_update_time_interval);
+                        }
+                        Test.AnotherWay._g_record_waiting_for_results = true;
+                        // open a new window for self, pass a parameter to dump recorded events as javascript code there
+                        // (the easiest way to obtain a document from the same origin, so it's writable, is to open this same page again)
+                        Test.AnotherWay._g_record_paused = false;
+                        var loc = window.location;
+                        loc = loc.protocol + "//" + loc.host + loc.pathname + "?recording_results=" + Test.AnotherWay._g_record_random_id;
+                        if (window.open(loc, "_blank") == null) {
+                            alert("unable to open new window for results");
+                        }
+                    }
+                    handled = true;
+                }
+                else 
+                    if (k == "h") {
+                        Test.AnotherWay._g_record_control_visible = !Test.AnotherWay._g_record_control_visible;
+                        handled = true;
+                    }
+                    else 
+                        if (k == "p") {
+                            Test.AnotherWay._g_record_paused = !Test.AnotherWay._g_record_paused;
+                            if (Test.AnotherWay._g_record_paused) {
+                                Test.AnotherWay._g_record_pause_start_time = (new Date()).getTime();
+                                if (Test.AnotherWay._g_record_started) {
+                                    window.clearInterval(Test.AnotherWay._g_record_update_time_interval);
+                                }
+                                Test.AnotherWay._record_control_update_highlight(null);
+                            }
+                            else {
+                                var pause_duration = (new Date()).getTime() - Test.AnotherWay._g_record_pause_start_time;
+                                Test.AnotherWay._g_record_start_time += pause_duration;
+                                Test.AnotherWay._g_record_update_time_interval = window.setInterval(Test.AnotherWay._record_control_update_time, 200);
+                            }
+                            handled = true;
+                        }
+                        else 
+                            if (k == "m") {
+                                Test.AnotherWay._g_record_include_mousemove = !Test.AnotherWay._g_record_include_mousemove;
+                                handled = true;
+                            }
+                            else 
+                                if (k == "c") {
+                                    var o = Test.AnotherWay._record_checkpoint();
+                                    Test.AnotherWay._record_display_checkpoint(o);
+                                    Test.AnotherWay._record_flash_border("#24d");
+                                    handled = true;
+                                }
+            }
+    Test.AnotherWay._g_record_keydown = null;
+    Test.AnotherWay._record_control_update_ui();
+    if (!handled) {
+        //      Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
+    }
+    return;
+};
+Test.AnotherWay._record_html_node_path = function(node){
+    if (node == null) {
+        return null;
+    }
+    var path = [];
+    while (true) {
+        if (node.id != null && node.id != "") {
+            path.unshift("#" + node.id + " " + node.nodeName);
+            break;
+        }
+        else {
+            var parent_node = node.parentNode;
+            if (parent_node == null) {
+                return []; // no BODY up the path - this node is screwed (browsers differ in what's above the body), discard
+            }
+            else {
+                var i = 0;
+                var found = false;
+                for (var child = parent_node.firstChild; child != null; child = child.nextSibling) {
+                    if (child == node) {
+                        found = true;
+                        break;
+                    }
+                    if (child.nodeType == 1) { // count only HTML element nodes
+                        ++i;
+                    }
+                }
+                if (!found) {
+                    i = -1;
+                }
+                path.unshift(i + " " + node.nodeName);
+                if (parent_node.nodeName == "BODY" || parent_node.nodeName == "body") {
+                    break;
+                }
+                node = parent_node;
+            }
+        }
+    }
+    return path;
+};
+Test.AnotherWay._record_node_path_to_string = function(path){
+    var s = "";
+    if (path != null) {
+        for (var i = 0; i < path.length; ++i) {
+            s += i == 0 ? "" : ", ";
+            var elem = path[i].split(" ");
+            if (elem[0].charAt(0) == "#") {
+                s += elem[1] + " " + elem[0];
+            }
+            else {
+                s += elem[1] + " [" + elem[0] + "]";
+            }
+        }
+    }
+    return s;
+};
+Test.AnotherWay._record_node_path_to_node = function(path_str, doc){
+    if (path_str == null) {
+        return null;
+    }
+    var path = path_str.split(",");
+    var node = doc.body;
+    for (var i = 0; i < path.length; ++i) {
+        var node_i = path[i].split(" ")[0];
+        if (node_i.charAt(0) == "#") {
+            node = doc.getElementById(node_i.substring(1));
+        }
+        else {
+            if (node_i < 0 || node_i >= node.childNodes.length) {
+                node = null;
+            }
+            else {
+                node = node.firstChild;
+                while (node != null) {
+                    if (node.nodeType == 1) { // count only HTML element nodes
+                        if (node_i == 0) {
+                            break;
+                        }
+                        --node_i;
+                    }
+                    node = node.nextSibling;
+                }
+            }
+        }
+        if (node == null) {
+            return null;
+        }
+    }
+    return node;
+};
+Test.AnotherWay._record_control_contains_id = function(s){
+    return s.match(/^#record_[\w_]+/) && s.match(Test.AnotherWay._g_record_random_id);
+};
+Test.AnotherWay._record_checkpoint = function(){
+    var o = {
+        type: "_checkpoint",
+        time: (new Date()).getTime() - Test.AnotherWay._g_record_start_time,
+        which: Test.AnotherWay._g_record_checkpoint_count++,
+        target: Test.AnotherWay._record_html_node_path(Test.AnotherWay._g_record_under_cursor)
+    };
+    Test.AnotherWay._g_record_events.push(o);
+    return o;
+};
+Test.AnotherWay._record_event = function(event){
+    var unneeded = ["rangeOffset", "eventPhase", "timeStamp", "isTrusted", "popupWindowFeatures", "rangeOffset"];
+    if (Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused) {
+        var o = {};
+        for (var n in event) {
+            var needed = !n.match(/^[A-Z0-9_]+$/);
+            if (needed) {
+                for (var ui = 0; ui < unneeded.length; ++ui) {
+                    if (unneeded[ui] == n) {
+                        needed = false;
+                        break;
+                    }
+                }
+                if (needed) {
+                    var value = event[n];
+                    if (typeof(value) != "object" && typeof(value) != "function") {
+                        o[n] = value;
+                    }
+                    else 
+                        if (n == "target" || n == "relatedTarget") {
+                            o[n] = Test.AnotherWay._record_html_node_path(value);
+                        }
+                }
+            }
+        }
+        o["time"] = (new Date()).getTime() - Test.AnotherWay._g_record_start_time;
+        var over_record_control = o["target"] != null && o["target"][0] != null && Test.AnotherWay._record_control_contains_id(o["target"][0]);
+        if (!over_record_control) {
+            Test.AnotherWay._g_record_events.push(o);
+        }
+    }
+    return true;
+};
+Test.AnotherWay._record_on_mousemove = function(event){
+    var path = Test.AnotherWay._record_html_node_path(event.target);
+    var new_mouse_over_record_control = path != null && path[0] != null && Test.AnotherWay._record_control_contains_id(path[0]);
+    if (new_mouse_over_record_control != Test.AnotherWay._g_record_mouse_over_record_control) {
+        Test.AnotherWay._g_record_mouse_over_record_control = new_mouse_over_record_control;
+        Test.AnotherWay._record_control_update_ui();
+    }
+    if (event.target != null && event.target != Test.AnotherWay._g_record_under_cursor) {
+        Test.AnotherWay._g_record_under_cursor = event.target;
+        var s = "";
+        if (path == null || path[0] == null || !Test.AnotherWay._record_control_contains_id(path[0])) {
+            s = Test.AnotherWay._record_node_path_to_string(path);
+        }
+        if (s == "") {
+            s = "&nbsp;";
+        }
+        var cursor_over_indicator = Test.AnotherWay._record_control_get_element("record_cursor_over");
+        cursor_over_indicator.innerHTML = s;
+    }
+    
+    var highlight_element = null;
+    if (!Test.AnotherWay._g_record_mouse_over_record_control && Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused) {
+        highlight_element = event.target;
+    }
+    // highlight border disabled on recording - it causes page to scroll, issuing spurious mouseover/mouseout event
+    //Test.AnotherWay._record_control_update_highlight( highlight_element, "border" );
+    
+    if (Test.AnotherWay._g_record_include_mousemove) {
+        Test.AnotherWay._record_event(event);
+    }
+    return true;
+};
+Test.AnotherWay._record_display_checkpoint = function(o){
+    var checkpoints_div = Test.AnotherWay._record_control_get_element("record_checkpoints");
+    var p = checkpoints_div.appendChild(checkpoints_div.ownerDocument.createElement("div"));
+    p.style.marginTop = "3px";
+    p.style.font = "normal normal 8pt sans-serif";
+    p.style.color = "#000";
+    p.style.textAligh = "left";
+    p.style.position = "relative";
+    p.style.width = "100%";
+    var checkpoint_text = "";
+    checkpoint_text += "#" + (o.which + 1);
+    checkpoint_text += "  " + Test.AnotherWay._record_format_time(o.time);
+    if (o.target != null) {
+        checkpoint_text += Test.AnotherWay._record_node_path_to_string(o.target);
+    }
+    p.appendChild(p.ownerDocument.createTextNode(checkpoint_text));
+};
+Test.AnotherWay._record_save_results = function(doc){
+    // strange, but DOM-style append does not work here in opera 8.
+    var append = function(s){
+        doc.write("<div>" + s + "</div>");
+    };
+    append("/* paste this data into your javascript and pass it as an argument to replay_events method */");
+    append("{ checkpoints: [");
+    var first_checkpoint = true;
+    for (var i = 0; i < Test.AnotherWay._g_record_events.length; ++i) {
+        var o = Test.AnotherWay._g_record_events[i];
+        if (o.type == "_checkpoint") {
+            var str = first_checkpoint ? "" : "}, ";
+            str += "function( tst, wnd ) { // #" + o.which + " time " + Test.AnotherWay._record_format_time(o.time) + " cursor was over " + Test.AnotherWay._record_node_path_to_string(o.target);
+            append(str);
+            first_checkpoint = false;
+        }
+    }
+    if (!first_checkpoint) {
+        append("}");
+    }
+    append("], events: [ ");
+    var prev_time = 0;
+    for (var i = 0; i < Test.AnotherWay._g_record_events.length; ++i) {
+        var o = Test.AnotherWay._g_record_events[i];
+        var s = "";
+        s += "{";
+        var n_first = true;
+        for (var n in o) {
+            if (n == "time") { // convert to relative time
+                var cur_time = o[n] - 0;
+                o[n] = cur_time - prev_time;
+                prev_time = cur_time;
+            }
+            s += n_first ? n : ", " + n;
+            s += ":";
+            if (o[n] == null) {
+                s += "null";
+            }
+            else {
+                s += "\"" + o[n] + "\"";
+            }
+            n_first = false;
+        }
+        s += i == Test.AnotherWay._g_record_events.length - 1 ? "}" : "},";
+        append(s);
+    }
+    append("] }");
+    append(";");
+};
+
+Test.AnotherWay._g_record_border; // border highlighting element under cursor
+Test.AnotherWay._g_record_border_flashes = []; // array of { color: color, timeout: milliseconds }
+Test.AnotherWay._g_record_border_flashing = false;
+Test.AnotherWay._g_record_border_normal_color = "#d4b";
+Test.AnotherWay._record_flash_border_timeout = function(){
+    var color = Test.AnotherWay._g_record_border_normal_color;
+    var timeout = null;
+    if (Test.AnotherWay._g_record_border_flashes.length != 0) {
+        color = Test.AnotherWay._g_record_border_flashes[0].color;
+        timeout = Test.AnotherWay._g_record_border_flashes[0].timeout;
+        Test.AnotherWay._g_record_border_flashes.splice(0, 1);
+    }
+    if (Test.AnotherWay._g_record_border != null) {
+        for (var i = 0; i < Test.AnotherWay._g_record_border.length; ++i) {
+            Test.AnotherWay._g_record_border[i].style.backgroundColor = color;
+        }
+    }
+    if (timeout != null) {
+        setTimeout(Test.AnotherWay._record_flash_border_timeout, timeout);
+    }
+    else {
+        Test.AnotherWay._g_record_border_flashing = false;
+    }
+};
+Test.AnotherWay._get_page_coords = function(elm){
+    var point = {
+        x: 0,
+        y: 0
+    };
+    while (elm) {
+        point.x += elm.offsetLeft;
+        point.y += elm.offsetTop;
+        elm = elm.offsetParent;
+    }
+    return point;
+};
+Test.AnotherWay._set_page_coords = function(elm, x, y){
+    var parent_coords = {
+        x: 0,
+        y: 0
+    };
+    if (elm.offsetParent) {
+        parent_coords = Test.AnotherWay._get_page_coords(elm.offsetParent);
+    }
+    var new_x = x - parent_coords.x;
+    if (new_x < 0) {
+        new_x = 0;
+    }
+    elm.style.left = new_x + 'px';
+    var new_y = y - parent_coords.y;
+    if (new_y < 0) {
+        new_y = 0;
+    }
+    elm.style.top = new_y + 'px';
+};
+Test.AnotherWay._record_setup_highlight_positions = function(element, style, coords, positions){
+    if (style == "border") {
+        var width = element.clientWidth;
+        var height = element.clientHeight;
+        var step = 0;
+        var thickness = 2;
+        var fudge_expand = 4;
+        positions.push({
+            x: coords.x - step - thickness,
+            y: coords.y - step - thickness,
+            width: width + 2 * step + 2 * thickness + fudge_expand,
+            height: thickness
+        });
+        positions.push({
+            x: coords.x + width + step + fudge_expand,
+            y: coords.y - step - thickness,
+            width: thickness,
+            height: height + 2 * step + 2 * thickness + fudge_expand
+        });
+        positions.push({
+            x: positions[0].x,
+            y: positions[0].y,
+            width: positions[0].width,
+            height: positions[0].height
+        });
+        positions.push({
+            x: positions[1].x,
+            y: positions[1].y,
+            width: positions[1].width,
+            height: positions[1].height
+        });
+        positions[2].y += height + thickness + 2 * step + fudge_expand;
+        positions[3].x -= width + thickness + 2 * step + fudge_expand;
+    }
+    else 
+        if (style == "ball") {
+            positions.push({
+                x: coords.x + 2,
+                y: coords.y,
+                width: 2,
+                height: 6
+            });
+            positions.push({
+                x: coords.x,
+                y: coords.y + 2,
+                width: 6,
+                height: 2
+            });
+            positions.push({
+                x: coords.x + 1,
+                y: coords.y + 1,
+                width: 4,
+                height: 4
+            });
+        }
+};
+Test.AnotherWay._record_highlight_border = function(element, style, event) // null - hide border
+{
+    if (element != null) {
+        if (Test.AnotherWay._g_record_border == null || Test.AnotherWay._g_record_border[0].ownerDocument != element.ownerDocument) {
+            Test.AnotherWay._g_record_border = [];
+            var n = style == "border" ? 4 : style == "ball" ? 3 : 0;
+            for (var i = 0; i < 4; ++i) {
+                var b = element.ownerDocument.createElement("div");
+                b.style.position = "absolute";
+                b.style.zIndex = "1";
+                b.style.backgroundColor = Test.AnotherWay._g_record_border_normal_color;
+                element.ownerDocument.body.appendChild(b);
+                Test.AnotherWay._g_record_border.push(b);
+            }
+        }
+        var coords = null;
+        if (style == "border") {
+            coords = Test.AnotherWay._get_page_coords(element);
+        }
+        else 
+            if (style == "ball") {
+                if (event != null) {
+                    if (event.pageX != null && event.pageY != null) {
+                        coords = {
+                            x: event.pageX - 0,
+                            y: event.pageY - 0
+                        };
+                    }
+                    else 
+                        if (event.clientX != null && event.clientY != null) {
+                            var doc = element.ownerDocument;
+                            if (doc != null) {
+                                coords = {
+                                    x: (event.clientX - 0) + doc.body.scrollLeft,
+                                    y: (event.clientY - 0) + doc.body.scrollTop
+                                };
+                            }
+                        }
+                }
+            }
+        if (coords != null && element.clientWidth != null && element.clientHeight != null) {
+            var positions = [];
+            Test.AnotherWay._record_setup_highlight_positions(element, style, coords, positions);
+            for (var i = 0; i < positions.length; ++i) {
+                var b = Test.AnotherWay._g_record_border[i];
+                var p = positions[i];
+                Test.AnotherWay._set_page_coords(b, p.x, p.y);
+                b.style.width = p.width + "px";
+                b.style.height = p.height + "px";
+                b.style.display = "block";
+            }
+        }
+    }
+    else {
+        if (Test.AnotherWay._g_record_border != null) {
+            for (var i = 0; i < Test.AnotherWay._g_record_border.length; ++i) {
+                Test.AnotherWay._g_record_border[i].style.display = "none";
+            }
+        }
+    }
+};
+Test.AnotherWay._record_flash_border = function(color){
+    if (Test.AnotherWay._g_record_border_flashing) { //already
+        Test.AnotherWay._g_record_border_flashes.push({
+            color: Test.AnotherWay._g_record_border_normal_color,
+            timeout: 300
+        });
+        Test.AnotherWay._g_record_border_flashes.push({
+            color: color,
+            timeout: 600
+        });
+    }
+    else {
+        Test.AnotherWay._g_record_border_flashing = true;
+        Test.AnotherWay._g_record_border_flashes.push({
+            color: color,
+            timeout: 600
+        });
+        Test.AnotherWay._record_flash_border_timeout();
+    }
+};
+Test.AnotherWay._record_prepare_doc_for_results = function(){
+    document.open();
+    document.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
+    document.write("<html><head><title> Input recording results</title>");
+    document.write("<style type=\"text/css\">");
+    document.write("body { font: normal normal smaller sans-serif; }");
+    document.write("div { margin-top: 3px; }");
+    document.write("</style></head><body>");
+    // opera and mozilla disagree over who the opener is.
+    if (typeof(window.opener.Test) != "undefined" && typeof(window.opener.Test.AnotherWay) != "undefined") {
+        window.opener.Test.AnotherWay._record_save_results(document);
+        window.opener.Test.AnotherWay._g_record_waiting_for_results = false;
+        window.opener.Test.AnotherWay._record_control_update_ui();
+    }
+    else 
+        if (typeof(window.opener.opener.Test) != "undefined" && typeof(window.opener.opener.Test.AnotherWay) != "undefined") {
+            window.opener.opener.Test.AnotherWay._record_save_results(document);
+            window.opener.opener.Test.AnotherWay._g_record_waiting_for_results = false;
+            window.opener.opener.Test.AnotherWay._record_control_update_ui();
+        }
+    document.write("</body>");
+    document.close();
+};
+
+// global initialization
+onload = function(){
+    if (window.opera) {
+        var good_opera = typeof(window.opera.version) == "function";
+        good_opera = good_opera && window.opera.version().match(/^\s*(\d+)/);
+        good_opera = good_opera && RegExp.$1 >= 8;
+    }
+    var span = document.createElement("SPAN");
+    span.innerHTML = "<!--[if IE]><br /><![endif]-" + "->";
+    var is_ie = span.getElementsByTagName("BR").length > 0;
+    
+    Test.AnotherWay._g_test_iframe = window.frames.test_iframe;
+    
+    var query_str = window.location.search;
+    if (query_str.charAt(0) == "?") {
+        query_str = query_str.substring(1);
+    }
+    var testlist_page = "list-tests.html";
+    var auto_run = false;
+    if (query_str != "") {
+        var params = [query_str];
+        if (query_str.indexOf(";") != -1) {
+            params = query_str.split(";");
+        }
+        else 
+            if (query_str.indexOf("&") != -1) {
+                params = query_str.split("&");
+            }
+        for (var param_i = 0; param_i < params.length; ++param_i) {
+            var param = params[param_i].split("=");
+            if (param[0] == "recording_results") {
+                if (window.opener != null) {
+                    // we were told to show recording results - replace everything in the document with the results
+                    Test.AnotherWay._record_prepare_doc_for_results();
+                    return;
+                }
+            }
+            else 
+                if (param[0] == "testpage") {
+                    Test.AnotherWay._add_test_page_url(decodeURIComponent(param[1]), "anotherway");
+                }
+                else 
+                    if (param[0] == "jsantestpage") {
+                        Test.AnotherWay._add_test_page_url(decodeURIComponent(param[1]), "jsan");
+                    }
+                    else 
+                        if (param[0] == "testlist") {
+                            testlist_page = decodeURIComponent(param[1]);
+                        }
+                        else 
+                            if (param[0] == "testframe") {
+                                if (window.opera && !good_opera) {
+                                    Test.AnotherWay._show_error("testframe parameter does not work in versions of Opera prior to 8.0. Sorry (pathches are welcome).");
+                                // Opera 7 barfs on attempt to access frame.frameElement.
+                                // if someone knows a way to assign onload handler to that iframe in Opera 7
+                                // without disrupting code that works in other browsers, patches are welcome.
+                                }
+                                else {
+                                    var frame_path = param[1].split(".");
+                                    var frame = top;
+                                    for (var frame_path_i = 0; frame_path_i < frame_path.length; ++frame_path_i) {
+                                        frame = frame[frame_path[frame_path_i]];
+                                    }
+                                    if (frame == null) {
+                                        Test.AnotherWay._show_error("unable to find frame specified for loading test pages: " + param[1]);
+                                    }
+                                    else {
+                                        if (frame.frameElement != null) { // for the following assignement to onload to work, frameElement is required
+                                            frame = frame.frameElement;
+                                        }
+                                        Test.AnotherWay._g_test_iframe = frame;
+                                    }
+                                }
+                            }
+                            else 
+                                if (param[0] == "testframe_no_clear") {
+                                    Test.AnotherWay._g_test_frame_no_clear = true;
+                                }
+                                else 
+                                    if (param[0] == "windows") {
+                                        if (param[1] == "none") {
+                                            Test.AnotherWay._test_object_t.prototype.open_window = null;
+                                        }
+                                    }
+                                    else 
+                                        if (param[0] == "run") {
+                                            auto_run = true;
+                                            if (param[1] == "all") {
+                                                Test.AnotherWay._g_pages_to_run = "all";
+                                            }
+                                            else {
+                                                if (Test.AnotherWay._g_pages_to_run == null || Test.AnotherWay._g_pages_to_run == "all") {
+                                                    Test.AnotherWay._g_pages_to_run = [];
+                                                }
+                                                var pages = param[1].split(",");
+                                                for (var i = 0; i < pages.length; ++i) {
+                                                    Test.AnotherWay._g_pages_to_run.push(pages[i]);
+                                                }
+                                            }
+                                        }
+        }
+    }
+    if (Test.AnotherWay._g_test_page_urls.length == 0) { // if no individual pages were given on the command line, load the list
+        var result = Test.AnotherWay._set_iframe_location(window.frames["list_iframe"], testlist_page);
+        if (result.msg != null) {
+            Test.AnotherWay._show_error(result.msg);
+        }
+        Test.AnotherWay._g_run_on_list_load = auto_run;
+    }
+    else {
+        Test.AnotherWay._g_run_on_main_load = auto_run;
+    }
+    
+    var f = Test.AnotherWay._g_test_iframe;
+    try {
+        if (f.attachEvent != null) {
+            f.attachEvent("onload", Test.AnotherWay._test_page_onload);
+        }
+        else {
+            f.onload = Test.AnotherWay._test_page_onload;
+        }
+        if (Test.AnotherWay._g_test_iframe.nodeType != null && Test.AnotherWay._g_test_iframe.contentWindow != null) { // it's iframe element, not the iframe. we need iframe.
+            Test.AnotherWay._g_test_iframe = Test.AnotherWay._g_test_iframe.contentWindow;
+        }
+    } 
+    catch (e) {
+        // ignore stupid opera error if the frame has onload handler assigned in the inline html
+    }
+    var handlers = {
+        "run_all": {
+            "onclick": Test.AnotherWay._run_all_onclick
+        },
+        "run_selected": {
+            "onclick": Test.AnotherWay._run_selected_onclick
+        },
+        "unselect_all": {
+            "onclick": Test.AnotherWay._unselect_all_onclick
+        },
+        "record_select": {
+            "onfocus": Test.AnotherWay._record_check_onfocus
+        },
+        "record_input": {
+            "onfocus": Test.AnotherWay._record_check_onfocus
+        },
+        "record_start": {
+            "onclick": Test.AnotherWay._record_start_onclick
+        },
+        "clear_btn": {
+            "onclick": Test.AnotherWay._results_clear_onclick
+        },
+        "results_tab": {
+            "onclick": Test.AnotherWay._tab_onclick,
+            "onmouseover": Test.AnotherWay._tab_mouseover,
+            "onmouseout": Test.AnotherWay._tab_mouseout
+        },
+        "debug_tab": {
+            "onclick": Test.AnotherWay._tab_onclick,
+            "onmouseover": Test.AnotherWay._tab_mouseover,
+            "onmouseout": Test.AnotherWay._tab_mouseout
+        }
+    };
+    for (var hs in handlers) {
+        var o = document.getElementById(hs);
+        if (o != null) {
+            for (var h in handlers[hs]) {
+                o[h] = handlers[hs][h];
+            }
+        }
+        else {
+            Test.AnotherWay._show_error("unable to set " + h + " handler: id " + hs + " not found");
+        }
+    }
+    
+    if (window.opera && !good_opera) {
+        Test.AnotherWay._g_no_record_msg = "Input events recording and replaying is not available in opera versions prior to 8.0.";
+    }
+    if (is_ie) {
+        Test.AnotherWay._g_no_record_msg = "Input events recording and replaying is not available in internet explorer.";
+    }
+    if (Test.AnotherWay._g_no_record_msg != null) {
+        var no_record_p = document.getElementById("record_not_supported");
+        no_record_p.style.display = "block";
+        no_record_p.appendChild(document.createTextNode(Test.AnotherWay._g_no_record_msg));
+    }
+    
+    Test.AnotherWay._g_main_loaded = true;
+    if (Test.AnotherWay._g_run_on_main_load) {
+        Test.AnotherWay._g_run_on_main_load = false;
+        Test.AnotherWay._run_pages_to_run();
+    }
+};

Copied: sandbox/august/trunk/tests/Test.AnotherWay.xml_eq.js (from rev 12408, trunk/openlayers/tests/Test.AnotherWay.xml_eq.js)
===================================================================
--- sandbox/august/trunk/tests/Test.AnotherWay.xml_eq.js	                        (rev 0)
+++ sandbox/august/trunk/tests/Test.AnotherWay.xml_eq.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,311 @@
+/**
+ * File: Test.AnotherWay.xml_eq.js 
+ * Adds a xml_eq method to AnotherWay test objects.
+ *
+ */
+
+(function() {
+
+    /**
+     * Function: createNode
+     * Given a string, try to create an XML DOM node.  Throws string messages
+     *     on failure.
+     * 
+     * Parameters:
+     * text - {String} An XML string.
+     *
+     * Returns:
+     * {DOMElement} An element node.
+     */
+    function createNode(text) {
+        
+        var index = text.indexOf('<');
+        if(index > 0) {
+            text = text.substring(index);
+        }
+        
+        var doc;
+        if(window.ActiveXObject && !this.xmldom) {
+            doc = new ActiveXObject("Microsoft.XMLDOM");
+            try {
+                doc.loadXML(text);
+            } catch(err) {
+                throw "ActiveXObject loadXML failed: " + err;
+            }
+        } else if(window.DOMParser) {
+            try {
+                doc = new DOMParser().parseFromString(text, 'text/xml');
+            } catch(err) {
+                throw "DOMParser.parseFromString failed";
+            }
+            if(doc.documentElement && doc.documentElement.nodeName == "parsererror") {
+                throw "DOMParser.parseFromString returned parsererror";
+            }
+        } else {
+            var req = new XMLHttpRequest();
+            req.open("GET", "data:text/xml;charset=utf-8," +
+                     encodeURIComponent(text), false);
+            if(req.overrideMimeType) {
+                req.overrideMimeType("text/xml");
+            }
+            req.send(null);
+            doc = req.responseXML;
+        }
+        
+        var root = doc.documentElement;
+        if(!root) {
+            throw "no documentElement";
+        }
+        return root;
+    }
+    
+    /**
+     * Function assertEqual
+     * Test two objects for equivalence (based on ==).  Throw an exception
+     *     if not equivalent.
+     * 
+     * Parameters:
+     * got - {Object}
+     * expected - {Object}
+     * msg - {String} The message to be thrown.  This message will be appended
+     *     with ": got {got} but expected {expected}" where got and expected are
+     *     replaced with string representations of the above arguments.
+     */
+    function assertEqual(got, expected, msg) {
+        if(got === undefined) {
+            got = "undefined";
+        } else if (got === null) {
+            got = "null";
+        }
+        if(expected === undefined) {
+            expected = "undefined";
+        } else if (expected === null) {
+            expected = "null";
+        }
+        if(got != expected) {
+            throw msg + ": got '" + got + "' but expected '" + expected + "'";
+        }
+    }
+    
+    /**
+     * Function assertElementNodesEqual
+     * Test two element nodes for equivalence.  Nodes are considered equivalent
+     *     if they are of the same type, have the same name, have the same
+     *     namespace prefix and uri, and if all child nodes are equivalent.
+     *     Throws a message as exception if not equivalent.
+     * 
+     * Parameters:
+     * got - {DOMElement}
+     * expected - {DOMElement}
+     * options - {Object} Optional object for configuring test options.
+     *
+     * Valid options:
+     * prefix - {Boolean} Compare element and attribute
+     *     prefixes (namespace uri always tested).  Default is false.
+     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
+     *     comparing child nodes.  Default is false.
+     */
+    function assertElementNodesEqual(got, expected, options) {
+        var testPrefix = (options && options.prefix === true);
+        
+        // compare types
+        assertEqual(got.nodeType, expected.nodeType, "Node type mismatch");
+        
+        // compare names
+        var gotName = testPrefix ?
+            got.nodeName : got.nodeName.split(":").pop();
+        var expName = testPrefix ?
+            expected.nodeName : expected.nodeName.split(":").pop();
+        assertEqual(gotName, expName, "Node name mismatch");
+        
+        // for text nodes compare value
+        if(got.nodeType == 3) {
+            assertEqual(
+                got.nodeValue, expected.nodeValue, "Node value mismatch"
+            );
+        }
+        // for element type nodes compare namespace, attributes, and children
+        else if(got.nodeType == 1) {
+            
+            // test namespace alias and uri
+            if(got.prefix || expected.prefix) {
+                if(testPrefix) {
+                    assertEqual(
+                        got.prefix, expected.prefix,
+                        "Bad prefix for " + got.nodeName
+                    );
+                }
+            }
+            if(got.namespaceURI || expected.namespaceURI) {
+                assertEqual(
+                    got.namespaceURI, expected.namespaceURI,
+                    "Bad namespaceURI for " + got.nodeName
+                );
+            }
+            
+            // compare attributes - disregard xmlns given namespace handling above
+            var gotAttrLen = 0;
+            var gotAttr = {};
+            var expAttrLen = 0;
+            var expAttr = {};
+            var ga, ea, gn, en;
+            for(var i=0; i<got.attributes.length; ++i) {
+                ga = got.attributes[i];
+                if(ga.specified === undefined || ga.specified === true) {
+                    if(ga.name.split(":").shift() != "xmlns") {
+                        gn = testPrefix ? ga.name : ga.name.split(":").pop();
+                        gotAttr[gn] = ga;
+                        ++gotAttrLen;
+                    }
+                }
+            }
+            for(var i=0; i<expected.attributes.length; ++i) {
+                ea = expected.attributes[i];
+                if(ea.specified === undefined || ea.specified === true) {
+                    if(ea.name.split(":").shift() != "xmlns") {
+                        en = testPrefix ? ea.name : ea.name.split(":").pop();
+                        expAttr[en] = ea;
+                        ++expAttrLen;
+                    }
+                }
+            }
+            assertEqual(
+                gotAttrLen, expAttrLen,
+                "Attributes length mismatch for " + got.nodeName
+            );
+            var gv, ev;
+            for(var name in gotAttr) {
+                if(expAttr[name] == undefined) {
+                    throw "Attribute name " + gotAttr[name].name + " expected for element " + got.nodeName;
+                }
+                // test attribute namespace
+                assertEqual(
+                    gotAttr[name].namespaceURI, expAttr[name].namespaceURI,
+                    "Attribute namespace mismatch for element " +
+                    got.nodeName + " attribute name " + gotAttr[name].name
+                );
+                // test attribute value
+                assertEqual(
+                    gotAttr[name].value, expAttr[name].value,
+                    "Attribute value mismatch for element " + got.nodeName +
+                    " attribute name " + gotAttr[name].name
+                );
+            }
+            
+            // compare children
+            var gotChildNodes = getChildNodes(got, options);
+            var expChildNodes = getChildNodes(expected, options);
+
+            assertEqual(
+                gotChildNodes.length, expChildNodes.length,
+                "Children length mismatch for " + got.nodeName
+            );
+            for(var j=0; j<gotChildNodes.length; ++j) {
+                try {
+                    assertElementNodesEqual(
+                        gotChildNodes[j], expChildNodes[j], options
+                    );
+                } catch(err) {
+                    throw "Bad child " + j + " for element " + got.nodeName + ": " + err;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Function getChildNodes
+     * Returns the child nodes of the specified nodes. By default this method
+     *     will ignore child text nodes which are made up of whitespace content.
+     *     The 'includeWhiteSpace' option is used to control this behaviour.
+     * 
+     * Parameters:
+     * node - {DOMElement}
+     * options - {Object} Optional object for test configuration.
+     * 
+     * Valid options:
+     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
+     *     comparing child nodes.  Default is false.
+     * 
+     * Returns:
+     * {Array} of {DOMElement}
+     */
+    function getChildNodes(node, options) {
+        //check whitespace
+        if (options && options.includeWhiteSpace) {
+            return node.childNodes;
+        }
+        else {
+           nodes = [];
+           for (var i = 0; i < node.childNodes.length; i++ ) {
+              var child = node.childNodes[i];
+              if (child.nodeType == 1) {
+                 //element node, add it 
+                 nodes.push(child);
+              }
+              else if (child.nodeType == 3) {
+                 //text node, add if non empty
+                 if (child.nodeValue && 
+                       child.nodeValue.replace(/^\s*(.*?)\s*$/, "$1") != "" ) { 
+
+                    nodes.push(child);
+                 }
+              }
+           }
+  
+           return nodes;
+        }
+    } 
+    
+    /**
+     * Function: Test.AnotherWay._test_object_t.xml_eq
+     * Test if two XML nodes are equivalent.  Tests for same node types, same
+     *     node names, same namespace URI, same attributes, and recursively
+     *     tests child nodes for same criteria.
+     *
+     * (code)
+     * t.xml_eq(got, expected, message);
+     * (end)
+     * 
+     * Parameters:
+     * got - {DOMElement | String} A DOM node or XML string to test.
+     * expected - {DOMElement | String} The expected DOM node or XML string.
+     * msg - {String} A message to print with test output.
+     * options - {Object} Optional object for configuring test.
+     *
+     * Valid options:
+     * prefix - {Boolean} Compare element and attribute
+     *     prefixes (namespace uri always tested).  Default is false.
+     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
+     *     comparing child nodes.  Default is false.
+     */
+    var proto = Test.AnotherWay._test_object_t.prototype;
+    proto.xml_eq = function(got, expected, msg, options) {
+        // convert arguments to nodes if string
+        if(typeof got == "string") {
+            try {
+                got = createNode(got);
+            } catch(err) {
+                this.fail(msg + ": got argument could not be converted to an XML node: " + err);
+                return;
+            }
+        }
+        if(typeof expected == "string") {
+            try {
+                expected = createNode(expected);
+            } catch(err) {
+                this.fail(msg + ": expected argument could not be converted to an XML node: " + err);
+                return;
+            }
+        }
+        
+        // test nodes for equivalence
+        try {
+            assertElementNodesEqual(got, expected, options);
+            this.ok(true, msg);
+        } catch(err) {
+            this.fail(msg + ": " + err);
+        }
+    }
+    
+})();

Copied: sandbox/august/trunk/tests/Tile/BackBufferable.html (from rev 12408, trunk/openlayers/tests/Tile/BackBufferable.html)
===================================================================
--- sandbox/august/trunk/tests/Tile/BackBufferable.html	                        (rev 0)
+++ sandbox/august/trunk/tests/Tile/BackBufferable.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,114 @@
+<html>
+<head>
+  <script src="../OLLoader.js"></script>
+  <script type="text/javascript">
+    var tile;
+    var layer = new OpenLayers.Layer.WMS(
+            "WMS",
+            window.location.href + "#",
+            null,
+            {transitionEffect: "resize"}); 
+    var position = new OpenLayers.Pixel(20,30);
+    var bounds = new OpenLayers.Bounds(1,2,3,4);
+
+    
+    function test_initialize (t) {
+        t.plan(2);
+        
+        tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
+        t.eq(tile.backBufferData, {}, "back buffer data initialized");
+        t.eq(tile.size.w, 256, "size object with default width created");
+    }
+    
+    function test_backBufferMode(t) {
+        t.plan(4);
+
+        var l;
+
+        l = new OpenLayers.Layer.WMS('', window.location.href + '#');
+        tile = new OpenLayers.Tile.Image(l, position, bounds, null);
+        t.eq(tile.backBufferMode, 0,
+             'backBufferMode correctly set [tiled]');
+
+        l = new OpenLayers.Layer.WMS('', window.location.href + '#',
+                                     null, {singleTile: true});
+        tile = new OpenLayers.Tile.Image(l, position, bounds, null);
+        t.eq(tile.backBufferMode, 1,
+             'backBufferMode correctly set [singleTile]');
+
+        l = new OpenLayers.Layer.WMS('', window.location.href + '#',
+                                     null, {transitionEffect: 'resize'});
+        tile = new OpenLayers.Tile.Image(l, position, bounds, null);
+        t.eq(tile.backBufferMode, 2,
+             'backBufferMode correctly set [tiled, transition]');
+
+        l = new OpenLayers.Layer.WMS('', window.location.href + '#',
+                                     null, {singleTile: true,
+                                            transitionEffect: 'resize'});
+        tile = new OpenLayers.Tile.Image(l, position, bounds, null);
+        t.eq(tile.backBufferMode, 3,
+             'backBufferMode correctly set [singleTile, transition]');
+    }
+
+    function test_setBackBufferData(t) {
+        t.plan(2);
+
+        var map = new OpenLayers.Map("map");
+        map.addLayer(layer);
+        map.zoomToMaxExtent();
+        tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
+        tile.draw();
+        // moveTo calls setBackBufferData
+        tile.moveTo(new OpenLayers.Bounds(1,2,3,4),
+                    new OpenLayers.Pixel(30,40), true);
+        t.eq(tile.backBufferData.bounds.toString(), bounds.toString(),
+             "bounds stored correctly");
+        t.eq(tile.backBufferData.resolution, map.getResolution(),
+             "resolution stored correctly");
+        map.removeLayer(layer);
+        map.destroy();
+    }
+    
+    function test_updateBackBuffer(t) {
+        t.plan(1);
+        
+        var map = new OpenLayers.Map("map");
+        map.addLayer(layer);
+        map.zoomToMaxExtent();
+        tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
+        tile.draw();
+        tile.isLoading = false;
+        map.zoomIn();
+        tile.updateBackBuffer();
+        t.eq(tile.backBufferData.tile.style.width, (layer.tileSize.w*2)+"px",
+             "backBuffer frame correctly resized");
+        map.removeLayer(layer);
+        map.destroy();
+    }
+    
+    function test_removeBackBuffer(t) {
+        t.plan(2);
+        var map = new OpenLayers.Map("map");
+        map.addLayer(layer);
+        map.zoomToMaxExtent();
+        tile = new OpenLayers.Tile.Image(layer, position, bounds, null);
+        tile.draw();
+        tile.isLoading = false;
+        map.zoomIn();
+        tile.updateBackBuffer();
+        var backBuffer = tile.backBufferData.tile;
+        tile.removeBackBuffer();
+        t.eq(tile.backBufferData.tile, null,
+             "backBuffer reference removed");
+        t.ok(backBuffer.parentNode !== layer.div,
+             "backBuffer removed from layer");
+        map.removeLayer(layer);
+        map.destroy();
+    }
+        
+  </script>
+</head>
+<body>
+<div id="map" style="height:550px;width:500px"></div>
+</body>
+</html>
\ No newline at end of file

Deleted: sandbox/august/trunk/tests/Tile/Google.html
===================================================================
--- sandbox/august/trunk/tests/Tile/Google.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Tile/Google.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,74 +0,0 @@
-<html>
-<head>
-  <script src="http://maps.google.com/maps/api/js?sensor=false&v=3.5"></script>
-  <script src="../OLLoader.js"></script>
-  <script type="text/javascript">
-    var tile; 
-    var layer = new OpenLayers.Layer.GoogleNG(); 
-    var position = new OpenLayers.Pixel(20,30);
-    var bounds = new OpenLayers.Bounds(1,2,3,4);
-
-    
-    function test_constructor (t) {
-        t.plan( 4 );
-        
-        tile = new OpenLayers.Tile.Google(layer, position, bounds);
-    
-        t.ok( tile instanceof OpenLayers.Tile.Google, "new OpenLayers.Tile.Google returns Tile object" );
-        t.ok( tile.layer == layer, "tile.layer is set correctly");
-        t.ok( tile.position.equals(position), "tile.position is set correctly");
-        t.ok( tile.bounds.equals(bounds), "tile.bounds is set correctly");
-    }
-
-    function test_clone (t) {
-        t.plan( 5 );
-        
-        tile = new OpenLayers.Tile.Google(layer, position, bounds);
-        tile.node = document.createElement("div");
-        var clone = tile.clone();
-    
-        t.ok( clone instanceof OpenLayers.Tile.Google, "OpenLayers.Tile.Google.clone returns Tile.Google object" );
-        t.ok( clone.layer == layer, "clone.layer is set correctly");
-        t.ok( clone.position.equals(position), "clone.position is set correctly");
-        t.ok( clone.bounds.equals(bounds), "clone.bounds is set correctly");
-        t.ok( !clone.node, "node not cloned");
-    }
-    
-    function test_draw (t) {
-        t.plan( 5 );
-
-        var map = new OpenLayers.Map('map');
-        map.addLayer(layer);  
-
-        tile = new OpenLayers.Tile.Google(layer, position, bounds);
-
-        tile.events.register("loadstart", this, function() { 
-            t.ok(true, "loadstart triggered");
-        });
-        tile.events.register("loadend", this, function() { 
-            t.ok(true, "loadend triggered");
-        });
-
-        t.delay_call(1, function() {
-            //this should trigger a "loadstart" event
-            tile.draw();
-
-            t.ok( tile.node, "tile.draw creates a node");
-            // The two tests below will fail when getTile doesn't set the tile size
-            t.eq( tile.node.style.width, layer.tileSize.w+"px", "Image width is correct" );
-            t.eq( tile.node.style.height, layer.tileSize.h+"px", "Image height is correct" );
-        });       
-        t.delay_call(2, function() {
-            map.removeLayer(layer);
-            map.destroy();
-            /* wait until "loadend" fires */
-        });        
-        
-    }
-        
-  </script>
-</head>
-<body>
-<div id="map" style="height:550px;width:500px"></div>
-</body>
-</html>
\ No newline at end of file

Modified: sandbox/august/trunk/tests/Tile/Image/IFrame.html
===================================================================
--- sandbox/august/trunk/tests/Tile/Image/IFrame.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Tile/Image/IFrame.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -15,26 +15,29 @@
     var wmsUrl   = "http://labs.metacarta.com/wms/vmap0?";
     
     function test_Tile_Image_IFrame_create (t) {
-        t.plan( 3 );
+        t.plan( 5 );
         map   = new OpenLayers.Map('map');
         var bar = new Array(205).join("1234567890");
-        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic', foo: bar}, {tileOptions: {maxGetUrlLength: 2048}}); 
+        layer = new OpenLayers.Layer.WMS(name, wmsUrl,
+                                         {layers: 'basic', foo: bar},
+                                         {tileOptions: {maxGetUrlLength: 2048},
+                                          transitionEffect: 'resize'});
         map.addLayer(layer);
 
         var tile = layer.addTile(bounds, position);
-        tile.renderTile();
-        tile.positionImage();
-        t.eq(tile.imgDiv.firstChild.nodeName.toLowerCase(), "iframe", "IFrame used for long URL");
+        t.eq(tile.backBufferMode, 2, "backBufferMode is 2 after tile creation");
+
+        tile.draw();
+        t.eq(tile.imgDiv.nodeName.toLowerCase(), "iframe", "IFrame used for long URL");
         
         layer.mergeNewParams({foo: null});
-        tile.renderTile();
-        tile.positionImage();
+        tile.draw();
         t.eq(tile.imgDiv.nodeName.toLowerCase(), "img", "IMG used for short URL");
+        t.eq(tile.backBufferMode, 2, "backBufferMode reset to 2");
         
         tile.maxGetUrlLength = 0;
-        tile.renderTile();
-        tile.positionImage();
-        t.eq(tile.imgDiv.firstChild.nodeName.toLowerCase(), "iframe", "IFrame used when maxGetUrlLength is 0");
+        tile.draw();
+        t.eq(tile.imgDiv.nodeName.toLowerCase(), "iframe", "IFrame used when maxGetUrlLength is 0");
         
         tile.destroy();
         layer.destroy();
@@ -52,22 +55,22 @@
         tile.clear();
 
         t.eq(
-            tile.imgDiv.firstChild.nodeName.toLowerCase(), "div",
-            "IFrame successfully removed from DOM");
+            tile.frame.getElementsByTagName("iframe").length, 0,
+            "IFrame removed on clear()");
         tile.destroy();
         layer.destroy();
         map.destroy();
     }
 
-    function test_Tile_Image_IFrame_initImgDiv (t) {
-        t.plan( 4 );
+    function test_Tile_Image_IFrame_initImage (t) {
+        t.plan( 2 );
 
         map   = new OpenLayers.Map('map');
         layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
         tile = layer.addTile(bounds, position);
         tile.url = layer.getURL(bounds);
-        tile.initImgDiv();
+        tile.initImage();
 
         if(isMozilla) {
             t.ok( tile.imgDiv instanceof HTMLElement, "tile.iFrame successfully created.");
@@ -75,63 +78,41 @@
         else {
             t.ok( tile.imgDiv != null, "tile.iFrame successfully created.");
         }
-        t.eq( tile.imgDiv.id, tile.id, "imgDiv id correctly set.");
         t.eq( tile.imgDiv.className, "olTileImage", "iFrame's className correctly set.");
-        t.ok( tile.imgDiv.map == map, "map correctly added to iFrame.");
 
         map.destroy();
     }
 
-    function test_Tile_Image_IFrame_createImgDiv (t) {
-        t.plan( 3 );
+    function test_Tile_Image_IFrame_createImage (t) {
+        t.plan( 9 );
 
         map   = new OpenLayers.Map('map');
         layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
         map.addLayer(layer);  
         var tile = layer.addTile(bounds, position);
-        tile.renderTile();
-        var imgDiv = tile.imgDiv;
-        var iFrame    = imgDiv.firstChild;
-        var eventPane = imgDiv.childNodes[1];
+        tile.draw();
+        var iFrame    = tile.imgDiv;
+        var eventPane = tile.frame.childNodes[0];
 
+        t.ok(OpenLayers.String.contains(eventPane.style.backgroundImage,
+                    tile.blankImageUrl),
+             "backgroundImage of eventPane is set.");
+        t.eq(parseInt(eventPane.style.zIndex, 10), 1, "zIndex of eventPane is set.");
         if(isIE) {
             t.ok(iFrame != null, "IFrame successfully created.");
-            t.eq(eventPane.style.backgroundColor, '#ffffff', "backgroundColor of overlay pane is set in InternetExplorer.");
-            t.eq(eventPane.style.filter, 'chroma(color=#FFFFFF)', "filter of overlay pane is set in InternetExplorer.");
-        }
-        else {
-            t.ok(iFrame instanceof HTMLElement, "IFrame successfully created.");
-            t.ok(true, 'Skip eventPane backgroundColor test outside IE');
-            t.ok(true, 'Skip eventPane filter test outside IE');
-        }
-        map.destroy();
-    }
-
-    function test_Tile_Image_IFrame_createIFrame (t) {
-        t.plan( 8 );
-        
-        map   = new OpenLayers.Map('map');
-        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); 
-        map.addLayer(layer);  
-        var tile = layer.addTile(bounds, position);
-        var iFrame = tile.createIFrame();
-
-        var id = tile.id+'_iFrame';
-        t.eq(iFrame.id, id, "iframe id correctly set.");
-        t.eq(iFrame.name, id, "iframe name correctly set.");
-        
-        if(isIE) {
             t.eq(iFrame.style.backgroundColor, '#ffffff', "backgroundColor correctly set.");
             t.eq(iFrame.style.filter, 'chroma(color=#FFFFFF)', "filter correctly set.");
+        } else {
+            t.ok(iFrame instanceof HTMLElement, "IFrame successfully created.");
+            t.ok(true, 'Skip IFrame backgroundColor test outside IE');
+            t.ok(true, 'Skip IFrame filter test outside IE');
         }
-        else {
-            t.eq(iFrame.style.backgroundColor, 'transparent', "backgroundColor correctly set.");
-            t.ok(true, "Skip filter test outside InternetExplorer.");
-        }
         t.eq( iFrame.scrolling, 'no', "no scrolling");
         t.eq( parseFloat(iFrame.marginWidth), 0, "no margin width");
         t.eq( parseFloat(iFrame.marginHeight), 0, "no margin height");
         t.eq( parseFloat(iFrame.frameBorder), 0, "no iframe border");
+
+        map.destroy();
     }
 
     function test_Tile_Image_IFrame_createRequestForm (t) {
@@ -152,7 +133,7 @@
         map.addLayer(newLayer);  
         tile = newLayer.addTile(bounds, position);
         tile.url = newLayer.getURL(bounds);
-        tile.initImgDiv();
+        tile.initImage();
 
         tile.url = newLayer.getURL(bounds);
         var form = tile.createRequestForm();
@@ -182,9 +163,10 @@
 
         tile.draw();
         tile.clear();
+        tile.initImage();
         tile.createRequestForm();
         t.ok(
-            tile.imgDiv.firstChild.nodeName == "IFRAME",
+            tile.imgDiv.nodeName == "IFRAME",
             "Iframe has been reinserted properly"
         );
         

Modified: sandbox/august/trunk/tests/Tile/Image.html
===================================================================
--- sandbox/august/trunk/tests/Tile/Image.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Tile/Image.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -62,38 +62,16 @@
         map.destroy();
     }
 
-    function test_Tile_Image_clone (t) {
-        t.plan( 9 );
-        
-        var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
-            "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'}); 
-
-        var position = new OpenLayers.Pixel(20,30);
-        var bounds = new OpenLayers.Bounds(1,2,3,4);
-        var url = "http://www.openlayers.org/dev/tests/tileimage";
-        var size = new OpenLayers.Size(5,6);
-        tile = new OpenLayers.Tile.Image(layer, position, bounds, url, size);
-        tile.imgDiv = {};
-        var clone = tile.clone();
-        
-        t.ok( clone instanceof OpenLayers.Tile.Image, "OpenLayers.Tile.clone returns Tile.Image object" );
-        t.ok( clone.layer == layer, "clone.layer is set correctly");
-        t.ok( clone.position.equals(position), "clone.position is set correctly");
-        t.ok( clone.bounds.equals(bounds), "clone.bounds is set correctly");
-        t.eq( clone.url, url, "clone.url is set correctly");
-        t.ok( clone.size.equals(size), "clone.size is set correctly");
-        t.ok( clone.frame, "clone has a frame");
-        t.ok( clone.frame != tile.frame, "clone's frame is a new one");
-        t.ok( clone.imgDiv == null, "clone's imgDiv was not copied");
-    }
-    
-    function test_Tile_Image_IFrame_viewRequestID (t) {
-        t.plan( 2 );
+    function test_Tile_Image_async (t) {
+        t.plan( 3 );
         var map   = new OpenLayers.Map('map');
         var layer = new OpenLayers.Layer.WMS(
             "Name",
             "http://labs.metacarta.com/TESTURL?",
-            {layers: 'basic'}
+            {layers: 'basic'}, {async: true, getURLasync: function(bounds, scope, url, callback) {
+                scope.url = this.getURL(bounds);
+                callback.call(scope);
+            }}
         ); 
         map.addLayer(layer);
 
@@ -101,13 +79,17 @@
         var bounds = new OpenLayers.Bounds(1,2,3,4);
         tile = layer.addTile(bounds, position);
         tile.renderTile();
-        t.eq(tile.imgDiv.viewRequestID, map.viewRequestID, "viewRequestID correct after renderTile");
-        map.viewRequestID++;
-        tile.renderTile();
-        t.eq(tile.imgDiv.viewRequestID, map.viewRequestID, "viewRequestID correct after subsequent renderTile");
-        tile.destroy();
-        layer.destroy();
-        map.destroy();
+        t.delay_call(0.1, function() {
+            t.eq(tile.imgDiv.src, layer.getURL(bounds), "image src correct for async request");
+            t.eq(tile.asyncRequestId, 1, "asyncRequestId correct after renderTile");
+            tile.renderTile();
+        });
+        t.delay_call(0.2, function() {
+            t.eq(tile.asyncRequestId, 2, "asyncRequestId correct after subsequent renderTile");
+            tile.destroy();
+            layer.destroy();
+            map.destroy();
+        });
     }
 
     function test_Tile_Image_draw (t) {
@@ -153,11 +135,13 @@
             SRS: "EPSG:4326", BBOX: [1,2,3,4],
             WIDTH: String(size.w), HEIGHT: String(size.h)
         };
-        t.eq( img.src,
-             "http://labs.metacarta.com/TESTURL?" + OpenLayers.Util.getParameterString(tParams),
-             "tile.draw creates an image");
-        t.eq( tile.imgDiv.style.width, "5px", "Image width is correct" );
-        t.eq( tile.imgDiv.style.height, "6px", "Image height is correct" );
+        t.delay_call(0.1, function() {
+            t.eq( img.src,
+                 "http://labs.metacarta.com/TESTURL?" + OpenLayers.Util.getParameterString(tParams),
+                 "tile.draw creates an image");
+        });
+        t.eq( tile.imgDiv.style.width, "100%", "Image width is correct" );
+        t.eq( tile.imgDiv.style.height, "100%", "Image height is correct" );
 
         // this should trigger a "reload" event (since the image never actually
         // loads in tests)
@@ -186,31 +170,31 @@
             SRS: "EPSG:4326", BBOX: "-181,-91,180,90",
             WIDTH: "256", HEIGHT: "256"
         };
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Images over edges of maxextent do load");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-181,-90,180,90), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-181,-90,180,90"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Images over edges of maxextent do load");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-180,-90,180,90), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-180,-90,180,90"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering all of extent loads");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-80,-45,80,45), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-80,-45,80,45"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering small part of extent loads");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-95,185,95), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-185,-95,185,95"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering more than all of extent loads");
 
@@ -218,31 +202,31 @@
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-90,-180,90), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-185,-90,-180,90"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Images against side of maxextent do load with displayOutsideMaxExtent");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-181,-90,180,90), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-181,-90,180,90"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Images over edges of maxextent do load with displayOutsideMaxExtent set");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-180,-90,180,90), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-180,-90,180,90"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering all of extent loads with display outside max extent");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-80,-45,80,45), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-80,-45,80,45"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering small part of extent loads with display outside max extent");
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-95,185,95), url, size);
         tile.draw()
         tParams = OpenLayers.Util.extend(tParams, {BBOX: "-185,-95,185,95"});
-        t.eq(tile.imgDiv.src,
+        t.eq(tile.url,
              "http://labs.metacarta.com/wms/vmap0?" + OpenLayers.Util.getParameterString(tParams),
              "Image covering more than all of extent loads");
     } 
@@ -260,14 +244,14 @@
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-90,-85,-90,85), url, size);
         tile.draw();
         tile.moveTo(new OpenLayers.Bounds(-185,-90,-180,-80), new OpenLayers.Pixel(-180,-85), true);
-        t.delay_call( 1, function() { t.eq(tile.imgDiv, null, "Tile imgDiv is null.") } );
+        t.delay_call( 1, function() { t.eq(tile.imgDiv.style.display, "none", "Tile image is invisible.") } );
         var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
             "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'}, {'reproject': true, 'alpha':true});
         map.addLayer(layer);
         tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-90,-85,-90,85), url, size);
         tile.draw();
         tile.moveTo(new OpenLayers.Bounds(-185,-90,-180,-80), new OpenLayers.Pixel(-180,-85), true)
-        t.delay_call( 1, function() { t.eq(tile.imgDiv, null, "Alpha tile imgDiv is null.") } );
+        t.delay_call( 1, function() { t.eq(tile.imgDiv.style.display, "none", "Alpha tile image is invisible.") } );
         
     }
 
@@ -316,6 +300,23 @@
         map.destroy();
     }
     
+    function test_createBackBuffer(t) {
+        t.plan(3);
+
+        var map = new OpenLayers.Map('map');
+        var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
+            "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});
+        map.addLayer(layer);
+        map.setCenter(new OpenLayers.LonLat(0,0), 5);
+        var tile = layer.grid[0][0];
+        var img = tile.imgDiv;
+        var backBuffer = tile.createBackBuffer();
+        t.eq(backBuffer.style.left, tile.frame.style.left, "backBuffer tile has same left style as frame");
+        t.ok(backBuffer.firstChild === img, "image appended to backBuffer");
+        t.ok(tile.imgDiv == null, "image reference removed from tile");
+        map.destroy();
+    }
+    
   </script>
 </head>
 <body>

Modified: sandbox/august/trunk/tests/Tile.html
===================================================================
--- sandbox/august/trunk/tests/Tile.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Tile.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -31,32 +31,6 @@
         t.ok( tile.events != null, "tile's events intitialized");
     }
 
-    function test_Tile_clone (t) {
-        t.plan( 10 );
-     
-        var layer = {}; // bogus layer
-        var position = new OpenLayers.Pixel(10,20);
-        var bounds = new OpenLayers.Bounds(1,2,3,4);
-        var url = "bobob";
-        var size = new OpenLayers.Size(5,6);
-        
-        tile = new OpenLayers.Tile(layer, position, bounds, url, size);
-        var clone = tile.clone();
-        
-        t.ok( clone instanceof OpenLayers.Tile, "OpenLayers.Tile.clone returns Tile object" );
-        t.eq( clone.layer, layer, "clone.layer set correctly");
-        t.ok( clone.position.equals(position), "clone.position set correctly");
-        t.ok( clone.bounds.equals(bounds), "clone.bounds set correctly");
-        t.eq( clone.url, url, "clone.url set correctly");        
-        t.ok( clone.size.equals(size), "clone.size is set correctly" );
-
-        t.ok( clone.id != null, "clone is given an id");
-        t.ok( clone.id != tile.id, "clone is given a new id");
-        t.ok(OpenLayers.String.startsWith(clone.id, "Tile_"),
-             "clone's id starts correctly");
-        t.ok( clone.events != null, "clone's events intitialized");
-    }
-
     function test_Tile_destroy(t) {
         t.plan( 6 );
 

Modified: sandbox/august/trunk/tests/Util.html
===================================================================
--- sandbox/august/trunk/tests/Util.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/Util.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -952,8 +952,17 @@
     }
 
     function test_Util_getParameters(t) {
-        t.plan(17);
+        t.plan(20);
 
+        t.eq(OpenLayers.Util.getParameters(''), {},
+                "getParameters works when the given argument is empty string");
+
+        t.eq(OpenLayers.Util.getParameters(), {},
+                "getParameters works with optional argument");
+
+        t.eq(OpenLayers.Util.getParameters(null), {},
+                "getParameters works with optional argument");
+
         t.eq(OpenLayers.Util.getParameters('http://www.example.com'), {},
              "getParameters works when args = ''");
         t.eq(OpenLayers.Util.getParameters('http://www.example.com?'), {},

Deleted: sandbox/august/trunk/tests/geom_eq.js
===================================================================
--- sandbox/august/trunk/tests/geom_eq.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/geom_eq.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,110 +0,0 @@
-/**
- * File: xml_eq.js
- * Adds a xml_eq method to AnotherWay test objects.
- *
- */
-
-(function() {
-    
-    /**
-     * Function assertEqual
-     * Test two objects for equivalence (based on ==).  Throw an exception
-     *     if not equivalent.
-     * 
-     * Parameters:
-     * got - {Object}
-     * expected - {Object}
-     * msg - {String} The message to be thrown.  This message will be appended
-     *     with ": got {got} but expected {expected}" where got and expected are
-     *     replaced with string representations of the above arguments.
-     */
-    function assertEqual(got, expected, msg) {
-        if(got === undefined) {
-            got = "undefined";
-        } else if (got === null) {
-            got = "null";
-        }
-        if(expected === undefined) {
-            expected = "undefined";
-        } else if (expected === null) {
-            expected = "null";
-        }
-        if(got != expected) {
-            throw msg + ": got '" + got + "' but expected '" + expected + "'";
-        }
-    }
-    
-    /**
-     * Function assertGeometryEqual
-     * Test two geometries for equivalence.  Geometries are considered
-     *     equivalent if they are of the same class, and given component
-     *     geometries, if all components are equivalent. Throws a message as
-     *     exception if not equivalent.
-     * 
-     * Parameters:
-     * got - {OpenLayers.Geometry}
-     * expected - {OpenLayers.Geometry}
-     * options - {Object} Optional object for configuring test options.
-     */
-    function assertGeometryEqual(got, expected, options) {
-        
-        var OpenLayers = Test.AnotherWay._g_test_iframe.OpenLayers;
-
-        // compare types
-        assertEqual(typeof got, typeof expected, "Object types mismatch");
-        
-        // compare classes
-        assertEqual(got.CLASS_NAME, expected.CLASS_NAME, "Object class mismatch");
-        
-        if(got instanceof OpenLayers.Geometry.Point) {
-            // compare points
-            assertEqual(got.x, expected.x, "x mismatch");
-            assertEqual(got.y, expected.y, "y mismatch");
-            assertEqual(got.z, expected.z, "z mismatch");
-        } else {
-            // compare components
-            assertEqual(
-                got.components.length, expected.components.length,
-                "Component length mismatch for " + got.CLASS_NAME
-            );
-            for(var i=0; i<got.components.length; ++i) {
-                try {
-                    assertGeometryEqual(
-                        got.components[i], expected.components[i], options
-                    );
-                } catch(err) {
-                    throw "Bad component " + i + " for " + got.CLASS_NAME + ": " + err;
-                }
-            }
-        }
-        return true;
-    }
-    
-    /**
-     * Function: Test.AnotherWay._test_object_t.geom_eq
-     * Test if two geometry objects are equivalent.  Tests for same geometry
-     *     class, same number of components (if any), equivalent component
-     *     geometries, and same coordinates.
-     *
-     * (code)
-     * t.geom_eq(got, expected, message);
-     * (end)
-     * 
-     * Parameters:
-     * got - {OpenLayers.Geometry} Any geometry instance.
-     * expected - {OpenLayers.Geometry} The expected geometry.
-     * msg - {String} A message to print with test output.
-     * options - {Object} Optional object for configuring test options.
-     */
-    var proto = Test.AnotherWay._test_object_t.prototype;
-    proto.geom_eq = function(got, expected, msg, options) {        
-        // test geometries for equivalence
-        try {
-            assertGeometryEqual(got, expected, options);
-            this.ok(true, msg);
-        } catch(err) {
-            this.fail(msg + ": " + err);
-        }
-    }
-    
-})();
\ No newline at end of file

Modified: sandbox/august/trunk/tests/list-tests.html
===================================================================
--- sandbox/august/trunk/tests/list-tests.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/list-tests.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -3,6 +3,7 @@
     <li>BaseTypes.html</li>
     <li>BaseTypes/Bounds.html</li>
     <li>BaseTypes/Class.html</li>
+    <li>BaseTypes/Date.html</li>
     <li>BaseTypes/Element.html</li>
     <li>BaseTypes/LonLat.html</li>
     <li>BaseTypes/Pixel.html</li>
@@ -152,7 +153,6 @@
     <li>Layer/GML.html</li>
     <li>Layer/Google.html</li>
     <li>Layer/Google/v3.html</li>
-    <li>Layer/GoogleNG.html</li>
     <li>Layer/Grid.html</li>
     <li>Layer/HTTPRequest.html</li>
     <li>Layer/Image.html</li>
@@ -223,8 +223,8 @@
     <li>Symbolizer/Raster.html</li>
     <li>Symbolizer/Text.html</li>
     <li>Tile.html</li>
-    <li>Tile/Google.html</li>
     <li>Tile/Image.html</li>
+    <li>Tile/BackBufferable.html</li>
     <li>Tile/Image/IFrame.html</li>
     <li>Tile/WFS.html</li>
     <li>Tween.html</li>

Copied: sandbox/august/trunk/tests/manual/dateline-sketch.html (from rev 12408, trunk/openlayers/tests/manual/dateline-sketch.html)
===================================================================
--- sandbox/august/trunk/tests/manual/dateline-sketch.html	                        (rev 0)
+++ sandbox/august/trunk/tests/manual/dateline-sketch.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <meta name="apple-mobile-web-app-capable" content="yes">
+    <title>OpenLayers: Sketch handlers crossing the dateline</title>
+    <link rel="stylesheet" href="../../theme/default/style.css" type="text/css">
+    <link rel="stylesheet" href="../../examples/style.css" type="text/css">
+    <style type="text/css">
+        #map {
+            height: 512px;
+        }
+    </style>
+
+    <script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false"></script>
+
+    <script src="../../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+
+// make map available for easy debugging
+var map;
+
+function init(){
+    map = new OpenLayers.Map('map');
+
+    var gmap = new OpenLayers.Layer.Google(
+        "Google Streets",
+        {sphericalMercator: true}
+    );
+    var vector = new OpenLayers.Layer.Vector("Editable Vectors");
+
+    map.addLayers([gmap, vector]);
+    map.addControl(new OpenLayers.Control.EditingToolbar(vector));
+
+    var extent = new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418);
+    map.zoomToExtent(extent);
+}
+
+    </script>
+  </head>
+  <body onload="init()">
+    <h1 id="title">OpenLayers sketch handlers crossing the dateline example</h1>
+
+    <div id="tags">
+        international date line, dateline, sketch
+    </div>
+    <p id="shortdesc">
+        Start digitizing a polygon or line
+        on one side of the international dateline, and then cross the dateline
+        whilst digitizing. The feature should behave like digitizing on any
+        other location.
+    </p>
+    <div id="map" class="smallmap"></div>
+
+    <div id="docs">
+    </div>
+  </body>
+</html>

Copied: sandbox/august/trunk/tests/manual/google-fullscreen-overlay.html (from rev 12408, trunk/openlayers/tests/manual/google-fullscreen-overlay.html)
===================================================================
--- sandbox/august/trunk/tests/manual/google-fullscreen-overlay.html	                        (rev 0)
+++ sandbox/august/trunk/tests/manual/google-fullscreen-overlay.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Google v3 with Overlay Test</title>
+    <link rel="stylesheet" href="../../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="../../examples/style.css" type="text/css">
+    <style type="text/css">
+        html, body, #map {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+        #text {
+            position: absolute;
+            top: 1em;
+            right: 1em;
+            width: 512px;
+            z-index: 20000;
+            background-color: white;
+            padding: 0 0.5em 0.5em 0.5em;
+        }
+    </style>
+    <script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false"></script>
+    <script src="../../lib/OpenLayers.js"></script>
+  </head>
+  <body>
+    <div id="map"></div>
+      <div id="text">
+          <h1 id="title">Google v3 with Overlay Test</h1>
+
+        <div id="docs">
+            <p>This test shows that the Google layer and overlays are not in sync while dragging or zooming.</p>
+        </div>
+    </div>
+    <script type="text/javascript">
+        var options = {
+            projection: new OpenLayers.Projection("EPSG:900913"),
+            units: "m",
+            maxResolution: 156543.0339,
+            maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)
+        };
+        var map = new OpenLayers.Map('map', options);
+        var gmap = new OpenLayers.Layer.Google(
+            "Google Streets", {sphericalMercator: true}
+        );
+        var states = new OpenLayers.Layer.WMS(
+            "USA States", "http://demo.opengeo.org/geoserver/wms",
+            {layers: "topp:states", transparent: true}
+        );
+        map.addLayers([gmap, states]);
+        map.setCenter(new OpenLayers.LonLat(-10028537.429619, 4598451.0222853), 5);
+    </script>
+  </body>
+</html>

Copied: sandbox/august/trunk/tests/manual/google-tilt.html (from rev 12408, trunk/openlayers/tests/manual/google-tilt.html)
===================================================================
--- sandbox/august/trunk/tests/manual/google-tilt.html	                        (rev 0)
+++ sandbox/august/trunk/tests/manual/google-tilt.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+    <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+    <meta name="apple-mobile-web-app-capable" content="yes">
+        <title>OpenLayers Google (v3) Layer Example</title>
+        <link rel="stylesheet" href="../../theme/default/style.css" type="text/css">
+        <link rel="stylesheet" href="../../theme/default/google.css" type="text/css">
+        <link rel="stylesheet" href="../../examples/style.css" type="text/css">
+        <script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false"></script>
+        <script src="../../lib/OpenLayers.js"></script>
+    </head>
+    <body onload="init()">
+        <h1 id="title">Google (v3) Unexpected Tilt Test</h1>
+        <div id="map" class="smallmap"></div>
+        <div id="docs">
+            <p>
+                OpenLayers uses the disableDefaultUI option of the GMaps API.
+                Despite that, the tilt feature is active. To see it, zoom in
+                once and see the buildings from a 45° angle instead of from the
+                top as you would expect from aerial imagery.
+            </p>
+        </div>
+        <script>
+            var map = new OpenLayers.Map('map');
+
+            var ghyb = new OpenLayers.Layer.Google(
+                "Google Hybrid",
+                {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
+            );
+
+            map.addLayers([ghyb]);
+
+            map.setCenter(new OpenLayers.LonLat(-13635213, 4544641), 17);
+        </script>
+    </body>
+</html>

Modified: sandbox/august/trunk/tests/run-tests.html
===================================================================
--- sandbox/august/trunk/tests/run-tests.html	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/run-tests.html	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,2419 +1,153 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html><head><title> Run the testsuite</title>
-<noscript>Javascript is disabled in your browser. This page cannot be displayed correctly without Javascript. Sorry. <br/> If you want to view this page, please change your browser settings so that Javascript is enabled.</noscript>
-<!--
-Test.AnotherWay version 0.5
-
-Copyright (c) 2005 Artem Khodush, http://straytree.org
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--->
-<style type="text/css">
-* { padding: 0; margin: 0; }
-html { height: 99%; }
-body { height: 98%; font: normal normal 10pt sans-serif }
-#col1 {  float: left; width: 27em; margin: 0 0 0 1em; overflow: visible; }
-#col2 {  position: relative; height: 98%; margin: 0 0.5em 0 28em; }
-#col1_header { margin-top: 0.5em; }
-#scroller { height: 400px; overflow: auto;}
-#testtable { margin: 0 0 2em 0; width: 97%; }
-#run_buttons { margin-bottom: 4em; }
-
-#right_header { padding-top: 0.8em; }
-#results_count { float: left; }
-.active_tab 			{ float: right; padding: 0 1em 0.2em 1em; background: #0af; border: 1px solid #048; border-bottom: none; cursor: pointer; cursor: hand;
-					 position: relative; top: -0.2em; }
-.inactive_tab 			{ float: right; padding: 0 1em 0 1em; background: #9bb; color: #444; border: 1px solid #9bb; border-bottom: none; cursor: pointer; cursor: hand; }
-.inactive_mouseover_tab 	{ float: right; padding: 0 1em 0 1em; background: #9bb; color: #062; border: 1px solid #062; border-bottom: none; cursor: pointer; cursor: hand; }
-
-#right_frame { overflow: auto; position: relative; top: -0.2em; clear: right; height: 95%; border: 1px solid #048; }
-
-#debug { display: none; }
-#debug p { margin: 2px 0 0 5em; text-indent: -4.8em; }
-
-#error { display: none; color: #c22; }
-
-#results p { margin: 0 0 2px 0; }
-/* cursor indicating that detailed results may be expanded/contracted */
-#results p.badtest { cursor: text; }
-#results p.ok, #results p.fail { cursor: pointer; cursor: hand; }
-
-/* colored squares in the results window at the left of test page names */
-#results p.ok .bullet { background: #6d6; }
-#results p.fail .bullet { background:  #d46; }
-#results p.badtest .bullet { background: #ea3; }
-#results p.loading .bullet { background: #48f; }
-#results p.running .bullet { background: #26e; }
-#results p.waiting .bullet { background: #04d; }
-/* highlight in the results line */
-#results p .warning { background: #ffc; }
-
-/* layout of the detailed results */
-.result_detail { padding-left: 3em; }
-.result_exception_detail { padding-left: 4em; }
-.result_exception_stack_detail { padding-left: 5em;  }
-.result_micro_detail { padding-left: 6em; }
-/* colouring in the detailed results */
-.result_detail .fail, .result_exception_detail .fail,  .result_micro_detail .fail { background: #ffd8d8; }
-
-/* "start recording" controls*/
-#record_div { margin-top: 3em; }
-#record_div p { margin-bottom: 0.5em; }
-#record_select { width: 88%; }
-#record_input { width: 53%; }
-</style>
-<script type="text/javascript">
-<!--
-if( typeof( Test )=="undefined" ) {
-	Test={};
-}
-Test.AnotherWay={};
-
-Test.AnotherWay._g_test_iframe=null; // frame where to load test pages
-Test.AnotherWay._g_test_frame_no_clear=false; // true - leave last page displayed after tests end
-Test.AnotherWay._g_test_page_urls=[]; // array of: { url: url, convention: "anotherway" or "jsan" }
-Test.AnotherWay._g_test_object_for_jsan=null; // test object for filling by tests that adhere to jsan Test.Simple calling convention
-Test.AnotherWay._g_pages_to_run=null; // list of pages to run automatically after loading
-Test.AnotherWay._g_run_on_main_load=false; // special handling for run_pages_to_run when it might be called before onload or before list of test pages is known.
-Test.AnotherWay._g_run_on_list_load=false;
-Test.AnotherWay._g_main_loaded=false;
-
-Test.AnotherWay._run_pages_to_run=function( called_from_outside )
-{
-	if( !Test.AnotherWay._g_main_loaded ) {
-		Test.AnotherWay._g_run_on_main_load=true;
-	}else {
-		var a_pages=Test.AnotherWay._g_pages_to_run;
-		if( a_pages=="all" ) {
-			for( var i=0; i<Test.AnotherWay._g_test_page_urls.length; ++i ) {
-				Test.AnotherWay._run_test_page( "test"+i );
-			}
-		}else if( a_pages!=null ) {
-			for( var run_i=0; run_i<a_pages.length; ++run_i ) {
-				var run_page=a_pages[run_i];
-				var found=false;
-				for( var all_i=0; all_i<Test.AnotherWay._g_test_page_urls.length; ++all_i ) {
-					if( run_page==Test.AnotherWay._g_test_page_urls[all_i].url ) {
-						Test.AnotherWay._run_test_page( "test"+all_i, called_from_outside );
-						found=true;
-						break;
-					}
-				}
-				if( !found ) {
-					Test.AnotherWay._show_error( "page specified to run is not found in the page list: "+run_page );
-					break;
-				}
-			}
-		}
-	}
-}
-
-Test.AnotherWay._add_test_page_url=function( test_url, convention )
-{
-	var table=document.getElementById( "testtable" );
-	var record_select=document.getElementById( "record_select" );
-	var index=Test.AnotherWay._g_test_page_urls.length;
-
-	// trim spaces.
-	if( test_url.match( "^(\\s*)(.*\\S)(\\s*)$" ) ) {
-		test_url=RegExp.$2;
-	}
-
-	Test.AnotherWay._g_test_page_urls[index]={ url: test_url, convention: convention };
-	var row=table.insertRow( -1 );
-
-	var cell;
-	var cell_child;
-	cell=row.insertCell( -1 );
-	cell_child=document.createElement( "input" );
-	cell_child.type="checkbox";
-	cell_child.id="checkbox"+index;
-    cell_child.checked='checked';
-    cell_child.defaultChecked='checked';
-	cell.appendChild( cell_child );
-
-	cell=row.insertCell( -1 );
-	cell.setAttribute( "width", "75%" );
-	cell.appendChild( document.createTextNode( test_url ) );
-
-	cell=row.insertCell( -1 );
-	cell_child=document.createElement( "input" );
-	cell_child.type="button";
-	cell_child.id="test"+index;
-	cell_child.value=" run ";
-	cell_child.onclick=Test.AnotherWay._run_one_onclick;
-	cell.appendChild( cell_child );
-
-	cell=row.insertCell( -1 );
-	cell.setAttribute( "width", "8em" );
-	cell_child=document.createElement( "span" );
-	cell.appendChild( cell_child );
-
-	var option=document.createElement( "option" );
-	option.appendChild( document.createTextNode( test_url ) );
-	record_select.appendChild( option );
-}
-Test.AnotherWay._show_error=function( msg )
-{
-	var error_div=document.getElementById( "error" );
-	error_div.innerHTML="";
-	error_div.appendChild( document.createTextNode( msg ) );
-	error_div.style.display="block";
-}
-
-// read urls from the list in the html file inside the list_iframe
-// fill on-screen list with urls and "run" buttons, and fill the g_test_page_urls object.
-Test.AnotherWay._list_iframe_onload=function()
-{
-	if( window.frames.list_iframe!=null && window.frames.list_iframe.location!="" && window.frames.list_iframe.location!="about:blank" ) {
-		var list_doc=window.frames.list_iframe.document;
-		var list=list_doc.getElementById( "testlist" );
-		if( list!=null ) {
-			for( var i=0; i<list.childNodes.length; ++i ) {
-				var item=list.childNodes[i];
-				if( item.nodeName=="LI" || item.nodeName=="li" ) {
-					var convention="anotherway";
-					if( Test.AnotherWay._get_css_class( item )=="jsan" ) {
-						convention="jsan";
-					}
-					Test.AnotherWay._add_test_page_url( item.innerHTML, convention );
-				}
-			}
-			if( Test.AnotherWay._g_run_on_list_load ) {
-				Test.AnotherWay._g_run_on_list_load=false;
-				Test.AnotherWay._run_pages_to_run();
-			}
-		}else {
-			Test.AnotherWay._show_error( "no list with id 'testlist' in a list file "+window.frames.list_iframe.location );
-		}
-	}
-}
-
-Test.AnotherWay._map_checkboxes=function( f )
-{
-	var table=document.getElementById( "testtable" );
-	var checks=table.getElementsByTagName( "INPUT" );
-	for( var i=0; i<checks.length; ++i ) {
-		if( checks[i].type=="checkbox" && checks[i].id.match( /^checkbox(\d+)$/ ) ) {
-			f( checks[i], RegExp.$1 );
-		}
-	}
-}
-Test.AnotherWay._run_all_onclick=function()
-{
-	Test.AnotherWay._map_checkboxes( function( c, id ) { Test.AnotherWay._run_test_page( "test"+id ); } );
-}
-Test.AnotherWay._run_selected_onclick=function()
-{
-	Test.AnotherWay._map_checkboxes( function( c, id ) { if( c.checked ) Test.AnotherWay._run_test_page( "test"+id ); } );
-}
-Test.AnotherWay._unselect_all_onclick=function()
-{
-	Test.AnotherWay._map_checkboxes( function( c, id ) { c.checked=false; } );
-}
-Test.AnotherWay._run_one_onclick=function()
-{
-	Test.AnotherWay._run_test_page( this.id );
-}
-
-// construct an object that will gather results of running one test function
-Test.AnotherWay._test_object_t=function( fun_name )
-{
-	this.name=fun_name; // name of the test function
-	this.n_plan=null; // planned number of assertions
-	this.n_ok=0; // # of ok assertions
-	this.n_fail=0; // # of failed assertions
-	this.exception=""; // if the function throwed an exception, it's its message
-	this.exception_stack=[]; // strings: function call stack from the exception
-	this.assertions=[]; // assertion results: array of { ok: 1 or 0, name: string }
-	this.wait_result_milliseconds=0; // how long to wait before collecting results from the test
-	this.second_wait_msg=null; // <p> status message (in addition to the page wait_msg)
-	this.delay_actions=[]; // array of actions to be perfomed after the test function returns
-				//	action : { acton_kind: "call" | "window" | "replay"
-				//				when "call": 		{ call_fn call_delay_milliseconds } call_fn takes nothing
-				//				when "window" : 	{ wnd_url wnd_wnd wnd_fn wnd_timeout_milliseconds wnd_dont_close } wnd_fn takes wnd
-				//				wnen "replay" : 	{ replay_wnd replay_events replay_event_i replay_checkpoints } checkpoint_fn takes this, wnd
-				//	}
-	this.delay_action_i=null; // index of delay action currently being performed
-	this.delay_prev_timer_time=0;	// for counting time while performing delay_actions
-	this.delay_current_milliseconds_left=0; // time left before the next action, runs down
-	this.delay_total_milliseconds_left=0; 	// for indication: total estimated time for all actions, runs up and down
-}
-
-Test.AnotherWay._test_object_t.prototype.ok=function( cond, name )
-{
-	if( cond ) {
-		++this.n_ok;
-		cond=1;
-	}else {
-		++this.n_fail;
-		cond=0;
-	}
-	this.assertions.push( { ok: cond, name: name } );
-}
-Test.AnotherWay._test_object_t.prototype.fail=function( name )
-{
-	this.ok( false, name );
-}
-Test.AnotherWay._test_object_t.prototype.plan=function( n )
-{
-	this.n_plan=n;
-}
-Test.AnotherWay._test_object_t.prototype.wait_result=function( seconds )
-{
-	this.wait_result_milliseconds=1000*seconds;
-}
-Test.AnotherWay._eq_fail_msg=function( path, what, expected, got )
-{
-	return "eq: "+path+" "+what+" differ: got "+got+", but expected "+expected;
-}
-Test.AnotherWay._array_eq=function( expected, got, path, msg )
-{
-	if( expected.length!=got.length ) {
-		msg.msg=Test.AnotherWay._eq_fail_msg( path, "array length", expected.length, got.length );
-		return false;
-	}
-	for( var i=0; i<expected.length; ++i ) {
-		if( !Test.AnotherWay._thing_eq( expected[i], got[i], path+"["+i+"]", msg ) ) {
-			return false;
-		}
-	}
-	return true;
-}
-Test.AnotherWay._object_eq=function( expected, got, path, msg )
-{
-	var v;
-	for( v in expected ) {
-		if( ! (v in got) ) {
-			msg.msg=Test.AnotherWay._eq_fail_msg( path+"."+v, "properties", expected[v], "undefined" );
-			return false;
-		}
-		if( !Test.AnotherWay._thing_eq( expected[v], got[v], path+"."+v, msg ) ) {
-			return false;
-		}
-	}
-	for( v in got ) {
-		if( ! (v in expected) ) {
-			msg.msg=Test.AnotherWay._eq_fail_msg( path+"."+v, "properties", "undefined", got[v] );
-			return false;
-		}
-	}
-	return true;
-}
-Test.AnotherWay._constructor_name=function( x )
-{
-	if( x==null ) {
-		return "";
-	}
-	var s="unknown";
-	try {
-		s=typeof( x.constructor );
-		if( s!="unknown" ) {
-			s=x.constructor.toString();
-		}
-	}catch( e ) {
-		s="unknown";
-	}
-	if( s=="unknown" ) {
-		// hackish attempt to guess a type
-		var is_array=true;
-		var index=0;
-		for( i in x ) {
-			if( i!=index ) {
-				is_array=false;
-			}
-			++index;
-		}
-		return is_array ? "Array" : "Object"; // for empty arrays/objects, this will be wrong half the time
-	}else if( s.match( /^\s*function\s+(\w+)\s*\(/ ) ) {
-		return RegExp.$1;
-	}else {
-	  var c = '';
-	  switch(typeof x) {
-	    case 'string':
-	      c = 'String';
-	      break;
-	    case 'object':
-	      c = 'Object';
-	      break;
-	    default:
-	      c = '';
-	  }
-		return c;
-	}
-}
-Test.AnotherWay._is_array=function( x )
-{
-	return Test.AnotherWay._constructor_name( x )=="Array";
-}
-Test.AnotherWay._is_value_type=function( x )
-{
-	cn=Test.AnotherWay._constructor_name( x );
-	return cn=="Number" || cn=="String" || cn=="Boolean" || cn=="Date";
-}
-Test.AnotherWay._thing_eq=function( expected, got, path, msg )
-{
-	if( expected==null && got==null ) {
-		return true;
-	}else if( (expected==null && got!=null) || (expected!=null && got==null) ) {
-		msg.msg=Test.AnotherWay._eq_fail_msg( path, "values", expected, got );
-		return false;
-	}else {
-		var expected_cn=Test.AnotherWay._constructor_name( expected );
-		var got_cn=Test.AnotherWay._constructor_name( got );
-		if( expected_cn!=got_cn ) {
-			msg.msg=Test.AnotherWay._eq_fail_msg( path, "types", expected_cn, got_cn );
-			return false;
-		}else {
-			if( Test.AnotherWay._is_array( expected ) ) {
-				return Test.AnotherWay._array_eq( expected, got, path, msg );
-			}else if( Test.AnotherWay._is_value_type( expected ) ) {
-				if( expected!=got ) {
-					msg.msg=Test.AnotherWay._eq_fail_msg( path, "values", expected, got );
-					return false;
-				}else {
-					return true;
-				}
-			}else { // just a plain object
-				return Test.AnotherWay._object_eq( expected, got, path, msg );
-			}
-		}
-	}
-}
-Test.AnotherWay._test_object_t.prototype.eq=function( got, expected, name )
-{
-	var msg={};
-	if( Test.AnotherWay._thing_eq( expected, got, "", msg ) ) {
-		this.ok( 1, name );
-	}else {
-		this.fail( name+". "+msg.msg );
-	}
-}
-Test.AnotherWay._test_object_t.prototype.like=function( got, expected, name )
-{
-	if( got.match( expected )!=null ) {
-		this.ok( 1, name );
-	}else {
-		this.fail( name+": got "+got+", but expected it to match: "+expected );
-	}
-}
-Test.AnotherWay._g_html_eq_span=null;
-Test.AnotherWay._html_eq_string_to_node=function( string_or_node, what, msg )
-{
-	if( string_or_node.nodeType!=null ) {
-		string_or_node=Test.AnotherWay._html_eq_node_to_string( string_or_node ); // double trip - to make properties assigned in scripts available as html node attributes
-	}
-	if( Test.AnotherWay._g_html_eq_span==null ) {
-		Test.AnotherWay._g_html_eq_span=document.createElement( "span" );
-	}
-	Test.AnotherWay._g_html_eq_span.innerHTML=string_or_node;
-	if( Test.AnotherWay._g_html_eq_span.childNodes.length!=1 ) {
-		msg.msg="bad "+what+" html string given (should contain exactly one outermost element): "+string_or_node;
-	}
-	return Test.AnotherWay._g_html_eq_span.childNodes[0].cloneNode( true );
-}
-Test.AnotherWay._html_eq_node_to_string=function( node ) {
-	if( Test.AnotherWay._g_html_eq_span==null ) {
-		Test.AnotherWay._g_html_eq_span=document.createElement( "span" );
-	}
-	Test.AnotherWay._g_html_eq_span.innerHTML="";
-	if( node.outerHTML!=null ) {
-		Test.AnotherWay._g_html_eq_span.innerHTML=node.outerHTML;
-	}else {
-            var clone = node.cloneNode(true);
-            var node = Test.AnotherWay._g_html_eq_span;
-            if(node.ownerDocument && node.ownerDocument.importNode) {
-                if(node.ownerDocument != clone.ownerDocument) {
-                    clone = node.ownerDocument.importNode(clone, true);
-                }
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Run the testsuite</title>
+        <noscript>
+            Javascript is disabled in your browser. This page cannot be 
+            displayed correctly without Javascript. Sorry. 
+            <br/>
+            If you want to view this page, please change your browser settings
+            so that Javascript is enabled.
+        </noscript>
+        <!--
+        
+        Test.AnotherWay version 0.5
+        
+        Copyright (c) 2005 Artem Khodush, http://straytree.org
+        
+        Permission is hereby granted, free of charge, to any person obtaining
+        a copy of this software and associated documentation files (the
+        "Software"), to deal in the Software without restriction, including
+        without limitation the rights to use, copy, modify, merge, publish,
+        distribute, sublicense, and/or sell copies of the Software, and to
+        permit persons to whom the Software is furnished to do so, subject to
+        the following conditions:
+        
+        The above copyright notice and this permission notice shall be
+        included in all copies or substantial portions of the Software.
+        
+        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+        EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+        MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+        NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+        LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+        OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+        WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+        
+        -->
+        <link rel="stylesheet" href="Test.AnotherWay.css" />
+        <script type="text/javascript" src="Test.AnotherWay.js"></script>
+        <script type="text/javascript" src="Test.AnotherWay.baseadditions.js"></script>
+        <script type="text/javascript" src="Test.AnotherWay.xml_eq.js"></script>
+        <script type="text/javascript" src="Test.AnotherWay.geom_eq.js"></script>
+    </head>
+    <body>
+        <div id="col1">
+            <div id="col1_header">
+                Test pages:
+                <input id="quickfilter" placeholder="quick filter">
+            </div>
+            <div id="scroller">
+                <table id="testtable">
+                </table>
+            </div>
+            <div id="run_buttons">
+                <input type="button" value=" clear " id="clear_btn" /><input type="button" value=" run all " id="run_all" /><input type="button" value=" run selected " id="run_selected" /><input type="button" value=" unselect all " id="unselect_all" />
+            </div>
+            <div id="running-time">
+            </div>
+            <input type="checkbox" id="dont_close_test_windows" /> do not close windows opened by tests
+            <div id="error">
+            </div>
+            <div id="record_div">
+                <p id="record_not_supported" style="display:none">
+                </p>
+                <p>
+                    Record mouse input for the page:
+                </p>
+                <p>
+                    <input type="radio" name="record_choose" value="select" checked="checked" />
+                    <select id="record_select">
+                        <option selected="selected">-- select a page: --</option>
+                    </select>
+                </p>
+                <p>
+                    <input type="radio" name="record_choose" value="input" /> or enter page url: <input type="text" id="record_input" />
+                </p>
+                <p>
+                    <input type="button" value=" record " id="record_start" />
+                </p>
+            </div>
+        </div>
+        <div id="col2">
+            <div id="right_header">
+                <span id="results_count">Results: <span id="total"></span></span>
+                <span id="results_tab" class="active_tab" style="visibility:hidden">Results</span>
+                <span id="debug_tab" class="inactive_tab" style="visibility:hidden">Debug</span>
+            </div>
+            <div id="right_frame">
+                <div id="results">
+                </div>
+                <div id="debug">
+                </div>
+            </div>
+        </div>
+        <span style="display:none">
+            <iframe name="list_iframe" onload="Test.AnotherWay._list_iframe_onload();">
+            </iframe>
+            <iframe name="test_iframe" onload="Test.AnotherWay._test_page_onload();">
+            </iframe>
+            <!-- record_control div is to be imported into other documents, so all its styles are inline -->-
+            <div id="record_control" style="position:absolute;bottom:0;left:0;margin:0;padding:0.5em;width:22em;height:22em;border:1px solid;background:#ffd;font: normal normal 8pt sans-serif; color:#000; text-align: left">
+                <p style="margin:0 0 0 0; padding:0">
+                    &nbsp;<span style="display:none;font-weight:bold;color:#408" id="record_indicator">recording. <span style="font-weight:normal">time: <span id="record_time"></span></span><span id="record_pause_indicator">paused</span></span>
+                </p>
+                <div id="record_cursor_over" style="margin:0;padding:2px;width:14em;height:1.1em;overflow:hidden;float:right;border:1px solid #777;background:#fff;font: normal normal 8pt sans-serif;position:relative;top:3px;color:#000;text-align:left;">
+                    &nbsp;
+                </div>
+                <p style="margin:2px 0 0 0; padding:0">
+                    cursor is over
+                </p>
+                <p style="margin:8px 0 0 0; padding:0;">
+                    keyboard control: press<span id="record_ctrl_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">ctrl</span>
+                    -<span id="record_shift_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">shift</span>
+                    -
+                </p>
+                <p style="margin:4px 0 0 0; padding:0">
+                    <span id="record_s" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">s</span>
+                    <span id="record_on">to <b>start</b> recording</span>
+                    <span id="record_off" style="display:none">to <b>stop</b> recording</span>
+                </p>
+                <p style="margin:4px 0 0 0; padding:0">
+                    <span id="record_h" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">h</span>
+                    <span>to <b>hide/show</b> this window</span>
+                </p>
+                <p style="margin:4px 0 0 0; padding:0">
+                    <span id="record_m" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">m</span>
+                    <span id="record_include_mousemove">to <b>record</b> mousemove</span>
+                    <span id="record_omit_mousemove" style="display:none">to <b>omit</b> mousemove</span>
+                </p>
+                <p style="margin:4px 0 0 0; padding:0">
+                    <span id="record_p" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">p</span>
+                    <span id="record_pause_on">to <b>pause</b> recording</span>
+                    <span id="record_pause_off" style="display:none">to <b>continue</b> recording</span>
+                </p>
+                <p style="margin:4px 0 0 0; padding:0">
+                    <span id="record_c" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">c</span>
+                    <span>to add checkpoint</span>
+                </p>
+                <p style="margin:6px 0 0 0; padding:0">
+                    checkpoints:
+                </p>
+                <div id="record_checkpoints" style="position:relative;width:100%;height:6em;overflow:auto;font: normal normal 8pt sans-serif; color:#000; text-align: left">
+                </div>
+            </div>
+        </span>
+        <script>
+            if (/noscroll/.test(location.href)) {
+                document.getElementById('scroller').style.height = 'auto';
+                document.getElementById('right_frame').style.height = 'auto';
             }
-            node.appendChild(clone);
-	}
-	return Test.AnotherWay._g_html_eq_span.innerHTML;
-}
-Test.AnotherWay._html_eq_path_msg=function( path )
-{
-	var msg="";
-	for( var i=0; i<path.length; ++i ) {
-		msg+=" [node "+path[i].node;
-		if( path[i].id!=null && path[i].id!="" ) {
-			msg+=" id "+path[i].id;
-		}else if( path[i].index!=null ) {
-			msg+=" at index "+path[i].index;
-		}
-		msg+="] "
-	}
-	return msg;
-}
-Test.AnotherWay._html_eq_fail_msg=function( path, what, expected, got )
-{
-	return Test.AnotherWay._html_eq_path_msg( path )+": "+what+" differ: got "+got+", but expected "+expected;
-}
-Test.AnotherWay._html_eq_remove_blank=function( text )
-{
-	if( text==null ) {
-		return "";
-	}else if( text.match( "^(\\s*)(.*\\S)(\\s*)$" ) ) {
-		return RegExp.$2;
-	}else if( text.match( "\s*" ) ) {
-		return "";
-	}
-	return text;
-}
-Test.AnotherWay._html_eq_remove_blank_nodes=function( node )
-{
-	var to_remove=[];
-	for( var child=node.firstChild; child!=null; child=child.nextSibling ) {
-		if( child.nodeType==3 ) {
-			var value=Test.AnotherWay._html_eq_remove_blank( child.nodeValue );
-			if( value=="" ) {
-				to_remove.push( child );
-			}else {
-				child.nodeValue=value;
-			}
-		}
-	}
-	for( var i=0; i<to_remove.length; ++i ) {
-		node.removeChild( to_remove[i] );
-	}
-}
-Test.AnotherWay._html_node_type_text=function( node_type )
-{
-	if( node_type==1 ) {
-		return "1 (html element)";
-	}else if( node_type==3 ) {
-		return "3 (text)";
-	}else {
-		return node_type;
-	}
-}
-Test.AnotherWay._html_eq_node=function( expected, got, path, msg, expected_loc_base, got_loc_base )
-{
-	if( expected.nodeType!=got.nodeType ) {
-		msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "node types", Test.AnotherWay._html_node_type_text( expected.nodeType ), Test.AnotherWay._html_node_type_text( got.nodeType ) );
-		return false;
-	}else if( expected.nodeType==3 ) {
-		if( expected.nodeValue!=got.nodeValue ) {
-			msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "text", expected.nodeValue, got.nodeValue );
-			return false;
-		}
-	}else if( expected.nodeType==1 ) {
-		if( expected.nodeName!=got.nodeName ) {
-			msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "node names", expected.nodeName, got.nodeName );
-			return false;
-		}
-		// compare attributes
-		var expected_attrs={};
-		var got_attrs={};
-		var i;
-		var a;
-		for( i=0; i<expected.attributes.length; ++i ) {
-			a=expected.attributes[i];
-			if( a.specified ) {
-				expected_attrs[a.name]=1;
-			}
-		}
-		for( i=0; i<got.attributes.length; ++i ) {
-			a=got.attributes[i];
-			if( a.specified ) {
-				got_attrs[a.name]=1;
-			}
-		}
-		for( a in expected_attrs ) {
-			if( ! (a in got_attrs) ) {
-				msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute sets differ: expected attribute "+a+" is missing";
-				return false;
-			}
-		}
-		for( a in got_attrs ) {
-			if( ! (a in expected_attrs) ) {
-				msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute sets differ: got extra attribute "+a;
-				return false;
-			}
-		}
-		for( a in expected_attrs ) {
-			var expected_value=expected.getAttribute( a );
-			var got_value=got.getAttribute( a );
-			if( typeof( expected_value )=="string" && typeof( got_value )=="string" ) {
-				expected_value=Test.AnotherWay._html_eq_remove_blank( expected_value );
-				got_value=Test.AnotherWay._html_eq_remove_blank( got_value );
-				var ok=expected_value==got_value;
-				if( !ok && (a=="href" || a=="HREF" )  ) { // try relative hrefs
-					var expected_relative_value=expected_value;
-					if( expected_loc_base!=null && expected_value.substring( 0, expected_loc_base.length )==expected_loc_base ) {
-						expected_relative_value=expected_value.substring( expected_loc_base.length );
-					}
-					var got_relative_value=got_value;
-					if( got_loc_base!=null && got_value.substring( 0, got_loc_base.length )==got_loc_base ) {
-						got_relative_value=got_value.substring( got_loc_base.length );
-					}
-					ok=expected_relative_value==got_relative_value;
-				}
-				if( !ok ) {
-					msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "attribute "+a+" values", expected_value, got_value );
-					return false;
-				}
-			}else if( typeof( expected_value )=="function" && typeof( got_value )=="function" ) {
-				expected_value=expected_value.toString();
-				got_value=got_value.toString();
-				if( expected_value!=got_value ) {
-					msg.msg=Test.AnotherWay._html_eq_fail_msg( path, "attribute "+a+" values", expected_value, got_value );
-					return false;
-				}
-			}else {
-				var value_msg={};
-				if( !Test.AnotherWay._thing_eq( expected_value, got_value, "", value_msg ) ) {
-					msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": attribute "+a+" values differ: "+value_msg.msg;
-					return false;
-				}
-			}
-		}
-		// compare child nodes
-		Test.AnotherWay._html_eq_remove_blank_nodes( expected );
-		Test.AnotherWay._html_eq_remove_blank_nodes( got );
-		var expected_length=expected.childNodes.length;
-		var got_length=got.childNodes.length;
-		if( expected_length<got_length ) {
-			msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": got "+(got_length-expected_length)+" extra child nodes";
-			return false;
-		}else if( expected_length>got_length ) {
-			msg.msg=Test.AnotherWay._html_eq_path_msg( path )+": expected "+(expected_length-got_length)+" more child nodes";
-			return false;
-		}else {
-			for( i=0; i<expected_length; ++i ) {
-				var expected_node=expected.childNodes[i];
-				path.push( { node: expected_node.nodeName, id: expected_node.id, index: i } );
-				var eq=Test.AnotherWay._html_eq_node( expected_node, got.childNodes[i], path, msg, expected_loc_base, got_loc_base );
-				path.pop();
-				if( !eq ) {
-					return false;
-				}
-			}
-		}
-	}
-	return true;
-}
-Test.AnotherWay._html_eq_get_loc_base=function( node )
-{
-	var loc_base=document.location;
-	if( node.ownerDocument!=null ) {
-		loc_base=node.ownerDocument.location;
-	}
-	if( loc_base!=null ) {
-		loc_base=loc_base.href;
-		var slash_pos=loc_base.lastIndexOf( "/" );
-		if( slash_pos!=-1 ) {
-			loc_base=loc_base.substring( 0, slash_pos+1 );
-		}
-	}
-	return loc_base;
-}
-Test.AnotherWay._test_object_t.prototype.html_eq=function( got, expected, name )
-{
-	var msg={};
-	var expected_node=Test.AnotherWay._html_eq_string_to_node( expected, "expected", msg );
-	if( msg.msg!=null ) {
-		this.fail( name+" html_eq: "+msg.msg );
-	}else {
-		var got_node=Test.AnotherWay._html_eq_string_to_node( got, "got", msg );
-		if( msg.msg!=null ) {
-			this.fail( name+" html_eq: "+msg.msg );
-		}else {
-			var expected_loc_base=Test.AnotherWay._html_eq_get_loc_base( expected );
-			var got_loc_base=Test.AnotherWay._html_eq_get_loc_base( got );
-			if( Test.AnotherWay._html_eq_node( expected_node, got_node, [], msg, expected_loc_base, got_loc_base ) ) {
-				this.ok( 1, name );
-			}else {
-				var msg=name+" html_eq "+msg.msg;
-				var expected_str=Test.AnotherWay._html_eq_node_to_string( expected_node );
-				var got_str=Test.AnotherWay._html_eq_node_to_string( got_node );
-				msg+=".\n got html: "+got_str;
-				msg+=".\n expected html: "+expected_str;
-				this.fail( msg );
-			}
-		}
-	}
-}
-Test.AnotherWay._debug_pane_print=function( msg )
-{
-	var d=new Date();
-	var p=document.createElement( "p" );
-	p.appendChild( document.createTextNode( d.toLocaleTimeString()+" "+msg ) );
-	var debug_pane=document.getElementById( "debug" );
-	debug_pane.appendChild( p );
-	var debug_tab=document.getElementById( "debug_tab" );
-	var results_tab=document.getElementById( "results_tab" );
-	debug_tab.style.visibility="visible";
-	results_tab.style.visibility="visible";
-}
-Test.AnotherWay._test_object_t.prototype.debug_print=function( msg )
-{
-	Test.AnotherWay._debug_pane_print( this.name+": "+msg );
-}
-Test.AnotherWay._test_object_t.prototype.delay_call=function()
-{
-	var timeout_ms=200;
-	for( var i=0; i<arguments.length; ++i ) {
-		if( typeof( arguments[i] )!="function" ) {
-			timeout_ms=1000*arguments[i];
-		}else {
-			var action={ action_kind: "call", call_delay_milliseconds: timeout_ms, call_fn: arguments[i] };
-			this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
-			this.delay_actions.push( action );
-		}
-	}
-}
-Test.AnotherWay._test_object_t.prototype.open_window=function( url, fn, timeout_seconds )
-{
-	if( timeout_seconds==null ) {
-		timeout_seconds=4;
-	}
-	var no_close=document.getElementById( "dont_close_test_windows" );
-	var action={ action_kind: "window", wnd_url: url.toString() + (window.location.search || ""), wnd_wnd: null, wnd_fn: fn, wnd_timeout_milliseconds: timeout_seconds*1000, wnd_no_close: no_close.checked };
-	this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
-	this.delay_actions.push( action );
-}
-Test.AnotherWay._test_object_t.prototype.replay_events=function( wnd, events )
-{
-	if( Test.AnotherWay._g_no_record_msg!=null ) {
-		this.fail( "replay_events: "+Test.AnotherWay._g_no_record_msg );
-	}else {
-		var action={ action_kind: "replay", replay_wnd: wnd, replay_events: events.events, replay_event_i: null, replay_checkpoints: events.checkpoints };
-		this.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );
-		this.delay_actions.push( action );
-	}
-}
-Test.AnotherWay._action_estimate_milliseconds=function( action )
-{
-	var ms=0;
-	if( action.action_kind=="call" ) {
-		ms=action.call_delay_milliseconds;
-	}else if( action.action_kind=="window" ) {
-		ms=0;
-	}else if( action.action_kind=="replay" ) {
-		ms=0;
-		for( var i=0; i<action.replay_events.length; ++i ) {
-			ms+=action.replay_events[i]["time"]-0;
-		}
-	}
-	return ms;
-}
-
-Test.AnotherWay._g_timeout_granularity=200;
-Test.AnotherWay._g_tests_queue=[]; // vector of { url: string, test_objects : array of test_object_t, test_object_i: int, wait_msg: <p> object, loading_timeout_milliseconds: int, timeout_id: id }
-
-// load one html page, schedule further processing
-Test.AnotherWay._run_test_page=function( id, called_from_outside )
-{
-	if( id.match( /^test(\d+)/ ) ) {
-		id=RegExp.$1;
-		Test.AnotherWay._g_tests_queue.push( {
-			url: Test.AnotherWay._g_test_page_urls[id].url,
-			convention: Test.AnotherWay._g_test_page_urls[id].convention,
-			test_objects: []
-			} );
-		if( Test.AnotherWay._g_tests_queue.length==1 ) {
-			if( !called_from_outside ) {
-				// Crap. Be careful stepping around.
-				// For Mozilla and Opera, when this file is included into the frameset page that is in another directory (and _g_outside_path_correction!=null)
-				// but the test pages are started from within it (by "run" buttons), then:
-				// depending on whether the page is the first one loaded into the test frame or not,
-				// the base url for relative test pages differs.
-				// Crap, like I said.
-				Test.AnotherWay._g_tests_queue[0].suppress_outside_path_correction=true;
-			}
-			Test.AnotherWay._start_loading_page();
-		}
-	}
-}
-Test.AnotherWay._load_next_page=function()
-{
-	Test.AnotherWay._g_tests_queue.splice( 0, 1 );
-	if( Test.AnotherWay._g_tests_queue.length>0 ) {
-		Test.AnotherWay._start_loading_page();
-	}else {
-		if( !Test.AnotherWay._g_test_frame_no_clear ) {
-			Test.AnotherWay._g_test_iframe.location.replace( "about:blank" );
-		}
-	}
-}
-Test.AnotherWay._g_opera_path_correction=null; // ugly wart to support opera
-Test.AnotherWay._g_outside_path_correction=null; // ugly wart to accomodate Opera and Mozilla, where relative url relates to the directory where the page that calls this function is located
-Test.AnotherWay._set_iframe_location=function( iframe, loc, outside_path_correction )
-{
-	// allow to load only locations with the same origin
-	var proto_end=loc.indexOf( "://" );
-	if( proto_end!=-1 ) { // otherwise, it's safe to assume (for Opera, Mozilla and IE ) that loc will be treated as relative
-		var main_loc=window.location.href;
-		var host_end=loc.substring( proto_end+3 ).indexOf( "/" );
-		var ok=false;
-		if( host_end!=-1 ) {
-			var loc_origin=loc.substring( 0, proto_end+3+host_end+1 );
-			if( main_loc.length>=loc_origin.length && main_loc.substring( 0, loc_origin.length )==loc_origin ) {
-				ok=true;
-			}
-		}
-		if( !ok ) {
-			return { msg: "test pages may have only urls with the same origin as "+main_loc };
-		}
-	}
-	// opera cannot handle urls relative to file:// without assistance
-	if( window.opera!=null && window.location.protocol=="file:" && loc.indexOf( ":" )==-1 ) {
-		var base=window.location.href;
-		var q_pos=base.indexOf( "?" );
-		if( q_pos!=-1 ) {
-			base=base.substring( 0, q_pos );
-		}
-		var slash_pos=base.lastIndexOf( "/" );
-		if( slash_pos!=-1 ) {
-			base=base.substring( 0, slash_pos+1 );
-			Test.AnotherWay._g_opera_path_correction=base;
-			loc=base+loc;
-		}
-	}
-	// if this function is called from another page, and if that page is in another directory, correction is needed
-	if( outside_path_correction!=null ) {
-		var pos=loc.indexOf( outside_path_correction );
-		if( pos==0 ) {
-			loc=loc.substring( outside_path_correction.length+1 );
-		}
-	}
-	if( iframe.location!=null ) {
-		iframe.location.replace( loc );
-	}else {
-		iframe.src=loc;
-	}
-	return {};
-}
-Test.AnotherWay._start_loading_page=function()
-{
-	var test_page=Test.AnotherWay._g_tests_queue[0];
-	test_page.loading_timeout_milliseconds=12000;
-	test_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );
-	test_page.wait_msg=Test.AnotherWay._print_counter_result( test_page.url, "loading...", test_page.loading_timeout_milliseconds, "loading" );
-	if( test_page.convention=="jsan" ) {
-		// the tests in that page will run when it's loading, so the test object must be ready
-		Test.AnotherWay._g_test_object_for_jsan=new Test.AnotherWay._test_object_t( test_page.url );
-	}
-	var outside_path_correction=null;
-	if( Test.AnotherWay._g_outside_path_correction!=null && !test_page.suppress_outside_path_correction ) {
-		outside_path_correction=Test.AnotherWay._g_outside_path_correction;
-	}
-	var result=Test.AnotherWay._set_iframe_location( Test.AnotherWay._g_test_iframe, test_page.url, outside_path_correction );
-	if( result.msg!=null ) {
-		Test.AnotherWay._unprint_result( test_page.wait_msg );
-		Test.AnotherWay._print_result( test_page.url, result.msg, "badtest", null );
-		Test.AnotherWay._load_next_page();
-	}
-}
-
-Test.AnotherWay._loading_timeout=function()
-{
-	var test_page=Test.AnotherWay._g_tests_queue[0];
-	test_page.loading_timeout_milliseconds-=Test.AnotherWay._g_timeout_granularity;
-	if( test_page.loading_timeout_milliseconds>0 ) {
-		Test.AnotherWay._update_msg_counter( test_page.wait_msg, (test_page.loading_timeout_milliseconds/1000).toFixed() );
-		test_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );
-	}else {
-		Test.AnotherWay._unprint_result( test_page.wait_msg );
-		Test.AnotherWay._print_result( test_page.url, "Unable to load test page. Timeout expired", "badtest", null );
-		Test.AnotherWay._load_next_page();
-	}
-}
-
-Test.AnotherWay._strip_query_and_hash=function( s )
-{
-	var i=s.lastIndexOf( "#" );
-	if( i!=-1 ) {
-		s=s.substring( 0, i );
-	}
-	i=s.lastIndexOf( "?" );
-	if( i!=-1 ) {
-		s=s.substring( 0, i );
-	}
-	return s;
-}
-Test.AnotherWay._is_url_loaded=function( url, wnd )
-{
-	var loaded=false;
-	if( wnd!=null && wnd.location!=null ) {
-		// after some popup blocker interference, location may behave strange..
-		var location_s="";
-		location_s+=wnd.location;
-		if( location_s!="" ) {
-			var pathname=wnd.location.pathname;
-			var expected_url=url;
-			var i=expected_url.lastIndexOf( "#" );
-			if( i!=-1 ) {
-				expected_url=expected_url.substring( 0, i );
-			}
-			i=expected_url.lastIndexOf( "?" );
-			if( i!=-1 ) {
-				expected_url=expected_url.substring( 0, i );
-			}
-			i=expected_url.lastIndexOf( "/" );
-			if( i!=-1 && i!=expected_url.length-1 ) {
-				expected_url=expected_url.substring( i+1 );
-			}
-			i=pathname.indexOf( expected_url )
-			if( wnd.location.href==url || (i!=-1 && i==pathname.length-expected_url.length) ) {
-				if( /*window.opera==null*/wnd.document.readyState==null || wnd.document.readyState=="complete" ) { // for opera (and IE?), getElementById does not work until..
-					loaded=true;
-				}
-			}
-		}
-	}
-	return loaded;
-}
-// find and run all test functions in the g_cur_page html page.
-Test.AnotherWay._test_page_onload=function()
-{
-	if( Test.AnotherWay._g_tests_queue.length==0 ) {
-		return;
-	}
-	var test_page=Test.AnotherWay._g_tests_queue[0];
-	if( !Test.AnotherWay._is_url_loaded( test_page.url, Test.AnotherWay._g_test_iframe ) ) {
-		return;
-	}
-	clearTimeout( test_page.timeout_id );
-	Test.AnotherWay._unprint_result( test_page.wait_msg );
-
-	if( test_page.convention=="anotherway" ) {
-		// get test function names (those beginning with "test")
-		if( typeof( Test.AnotherWay._g_test_iframe.document.scripts )!='undefined' ) { // IE
-			for( var i=0; i<Test.AnotherWay._g_test_iframe.document.scripts.length; ++i ) {
-				var script_text=Test.AnotherWay._g_test_iframe.document.scripts[i].text;
-				var fun_sig="function test";
-				var fun_start=script_text.indexOf( fun_sig );
-
-				while( fun_start!=-1 ) {
-					script_text=script_text.substring( fun_start, script_text.length );
-					var fun_end=script_text.indexOf( '(' );
-					var fun_name=script_text.substring( "function ".length,  fun_end );
-                                        var whitespace = fun_name.indexOf( ' ' );
-                                        if (whitespace >= 0)
-                                            fun_name = fun_name.substring( 0, whitespace );
-					test_page.test_objects.push( new Test.AnotherWay._test_object_t( fun_name ) );
-					script_text=script_text.substring( fun_end, script_text.length );
-					fun_start=script_text.indexOf( fun_sig  );
-				}
-			}
-		}else { // otherwise (not IE) it ought to work like this
-			for( var i in Test.AnotherWay._g_test_iframe) {
-				// Hack to prevent failure in FF3.0b1 (innerWidth/innerHeight) and FF>=3.5 (sessionStorage)
-                if (i == "innerWidth" || i == "innerHeight" || i == "sessionStorage") { continue; }
-                if( typeof( Test.AnotherWay._g_test_iframe[i] )=='function' ) {
-					if( i.substring( 0, 4 )=="test" ) {
-						test_page.test_objects.push( new Test.AnotherWay._test_object_t( i ) );
-					}
-				}
-			}
-		}
-	}else if( test_page.convention=="jsan" ) {
-		// the test object is already filled with results
-		test_page.test_objects.push( Test.AnotherWay._g_test_object_for_jsan );
-	}
-
-	if( test_page.test_objects.length==0 ) {
-		Test.AnotherWay._print_result( test_page.url,  "No test functions defined in the page", "badtest", null );
-		Test.AnotherWay._load_next_page();
-		return;
-	}
-
-	test_page.wait_msg=Test.AnotherWay._print_result( test_page.url, "running tests..<span class=\"counter\">"+test_page.test_objects.length+"</span>", "running", null );
-
-	test_page.test_object_i=0;
-	Test.AnotherWay._run_more_tests();
-}
-
-Test.AnotherWay._handle_exception=function( o, e, title )
-{
-	var s=title+": "+typeof( e )+": ";
-	if( e.message!=null ) {
-		s+=e.message;
-	}else if( e.description!=null ) {
-		s+=e.description;
-	}else {
-		s+=e.toString();
-	}
-//	if( e.location!=null ) {  // XXX figure out how to display exception location if it's present (like in mozilla)
-//		s+=" location: "+e.location.toString();
-//	}
-	o.exception=s;
-	s=[];
-	if( e.stack ) {
-		var lines=e.stack.split( "\n" );
-		for( var i=0; i<lines.length; ++i ) {
-			// format of the line: func_name(args)@file_name:line_no
-			if( lines[i].match( /(\w*)\(([^\)]*)\)@(.*):([^:]*)$/ ) ) {
-				var func_name=RegExp.$1;
-				if( func_name.length==0 ) {
-					func_name="<anonymous>";
-				}
-				s.push( "in "+func_name+"( "+RegExp.$2+") at "+RegExp.$3+" line "+RegExp.$4+"\n" );
-			}
-		}
-	}
-	o.exception_stack=s;
-}
-
-Test.AnotherWay._run_more_tests=function()
-{
-	var test_page=Test.AnotherWay._g_tests_queue[0];
-	while( test_page.test_object_i<test_page.test_objects.length ) {
-		Test.AnotherWay._update_msg_counter( test_page.wait_msg, (1+test_page.test_object_i)+"/"+test_page.test_objects.length );
-		var o=test_page.test_objects[test_page.test_object_i];
-		if( test_page.convention=="anotherway" ) {
-			try {
-				Test.AnotherWay._g_test_iframe[o.name]( o );
-			}catch( e ) {
-				Test.AnotherWay._handle_exception( o, e, "" );
-			}
-		} // for "jsan" convention, test has run already
-		if( o.delay_actions.length>0 || o.wait_result_milliseconds>0 ) {
-			o.delay_total_milliseconds_left+=o.wait_result_milliseconds;
-			Test.AnotherWay._delay_actions_timeout();
-			return;
-		}
-		++test_page.test_object_i;
-	}
-	Test.AnotherWay._unprint_result( test_page.wait_msg );
-	Test.AnotherWay._print_result( test_page.url, null, null, test_page.test_objects );
-	Test.AnotherWay._load_next_page();
-}
-
-Test.AnotherWay._delay_actions_timeout=function()
-{
-	var test_page=Test.AnotherWay._g_tests_queue[0];
-	var test_object=test_page.test_objects[test_page.test_object_i];
-	var finished=true;
-	if( test_object.delay_action_i==null ) {
-		// set up to start first action
-		test_object.delay_action_i=-1;
-	}else {
-		// perform current action
-		var milliseconds_passed=(new Date()).getTime()-test_object.delay_prev_timer_time;
-		test_object.delay_current_milliseconds_left-=milliseconds_passed;
-		test_object.delay_total_milliseconds_left-=milliseconds_passed;
-		finished=Test.AnotherWay._delay_continue_action( test_object, milliseconds_passed );
-	}
-	while( finished && test_object.delay_action_i<test_object.delay_actions.length ) {
-		++test_object.delay_action_i; // start next action
-		finished=Test.AnotherWay._delay_start_action( test_object );
-	}
-	if( test_object.delay_action_i<=test_object.delay_actions.length ) { // any more actions left ?
-		test_object.delay_prev_timer_time=(new Date()).getTime();
-		var next_timeout=Test.AnotherWay._g_timeout_granularity;
-		if( test_object.delay_current_milliseconds_left<next_timeout ) {
-			next_timeout=test_object.delay_current_milliseconds_left;
-		}
-		if( test_object.second_wait_msg!=null ) {
-			Test.AnotherWay._update_msg_counter( test_object.second_wait_msg, (test_object.delay_total_milliseconds_left/1000).toFixed() );
-		}
-		setTimeout( Test.AnotherWay._delay_actions_timeout, next_timeout );
-	}else { // no more actions left. run the next test.
-		if( test_object.second_wait_msg!=null ) {
-			Test.AnotherWay._unprint_result( test_object.second_wait_msg );
-			test_object.second_wait_msg=null;
-		}
-		++test_page.test_object_i;
-		Test.AnotherWay._run_more_tests();
-	}
-}
-Test.AnotherWay._delay_start_action=function( test_object )
-{
-	var finished=false;
-	var wait_msg="";
-	if( test_object.delay_action_i==test_object.delay_actions.length ) {
-		if( test_object.wait_result_milliseconds>0 ) {
-			test_object.delay_current_milliseconds_left=test_object.wait_result_milliseconds; // wait for result
-			wait_msg="waiting for results..";
-		}else {
-			++test_object.delay_action_i; // dont wait for result
-		}
-	}else {
-		var action=test_object.delay_actions[test_object.delay_action_i];
-		if( action.action_kind=="call" ) {
-			test_object.delay_current_milliseconds_left=action.call_delay_milliseconds;
-			wait_msg="performing delayed calls..";
-		}else if( action.action_kind=="window" ) {
-			if( Test.AnotherWay._g_opera_path_correction!=null && action.wnd_url.indexOf( ":" )==-1 ) {
-				action.wnd_url=Test.AnotherWay._g_opera_path_correction+action.wnd_url;
-			}
-			action.wnd_wnd=window.open( action.wnd_url, "_blank" );
-			if( action.wnd_wnd==null ) {
-				finished=true;
-				test_object.fail( "unable to open window for "+action.wnd_url );
-			}else {
-				test_object.delay_current_milliseconds_left=action.wnd_timeout_milliseconds;
-				wait_msg="opening window..";
-			}
-		}else if( action.action_kind=="replay" ) {
-			if( action.replay_events.length==0 ) {
-				finished=true;
-			}else {
-				action.replay_event_i=0;
-				test_object.delay_current_milliseconds_left=action.replay_events[0]["time"];
-				wait_msg="replaying events..";
-			}
-		}
-	}
-	if( test_object.second_wait_msg!=null ) {
-		Test.AnotherWay._unprint_result( test_object.second_wait_msg );
-	}
-	if( wait_msg!="" ) {
-		var test_page=Test.AnotherWay._g_tests_queue[0];
-		test_object.second_wait_msg=Test.AnotherWay._print_counter_result( test_page.url, wait_msg, test_object.delay_total_milliseconds_left, "waiting" );
-	}else {
-		test_object.second_wait_msg=null;
-	}
-	return finished;
-}
-Test.AnotherWay._delay_continue_action=function( test_object, milliseconds_passed )
-{
-	var finished=test_object.delay_current_milliseconds_left<=0;
-	if( test_object.delay_action_i==test_object.delay_actions.length ) { // action is "waiting for results"
-		if( test_object.n_plan!=null && test_object.n_plan==test_object.n_ok+test_object.n_fail ) {
-			finished=true; // if all assertions results are recorded, don't wait any more
-		}
-		if( finished ) {
-			++test_object.delay_action_i; // move on to the next test
-		}
-	}else {
-		var action=test_object.delay_actions[test_object.delay_action_i];
-		if( action.action_kind=="call" ) {
-			if( finished ) {
-				try {
-					action.call_fn();
-				}catch( e ) {
-					Test.AnotherWay._handle_exception( test_object, e, "in delay_call" );
-				}
-			}
-		}else if( action.action_kind=="window" ) {
-			test_object.delay_total_milliseconds_left+=milliseconds_passed; // for "window", the countdown is suspended since it's unknown how long it will take
-			if( Test.AnotherWay._is_url_loaded( action.wnd_url, action.wnd_wnd ) ) {
-				try {
-					action.wnd_fn( action.wnd_wnd );
-				}catch( e ) {
-					Test.AnotherWay._handle_exception( test_object, e, "in open_window function call" );
-				}
-				finished=true;
-			}else if( finished ) {
-				test_object.fail(  "unable to open window for url '"+action.wnd_url+"'. timeout expired" );
-			}
-		}else if( action.action_kind=="replay" ) {
-			if( finished ) {
-//				try {
-					Test.AnotherWay._delay_replay_event( test_object, action.replay_wnd, action.replay_events[action.replay_event_i], action.replay_checkpoints );
-//				}catch( e ) { // disabled, until I know how to gel location info from an exception
-//					Test.AnotherWay._handle_exception( test_object, e, "while replaying event" );
-//				}
-				++action.replay_event_i;
-				finished=action.replay_event_i==action.replay_events.length;
-				if( !finished ) {
-					test_object.delay_current_milliseconds_left=action.replay_events[action.replay_event_i]["time"];
-				}
-			}
-		}
-	}
-	return finished;
-}
-Test.AnotherWay._delay_replay_event=function( test_object, wnd, event, checkpoints )
-{
-	if( event.type=="_checkpoint" ) {
-		var checkpoint_n=event.which;
-		var prev_n_fail=test_object.n_fail;
-		checkpoints[checkpoint_n]( test_object, wnd );
-		var flash_color= prev_n_fail==test_object.n_fail ? "#2f2" : "#f22" ;
-		Test.AnotherWay._record_flash_border( flash_color );
-	}else if( event.type=="click" || event.type=="mouseover" || event.type=="mouseout" || event.type=="mousemove" || event.type=="mousedown" || event.type=="mouseup" ) {
-		var target=Test.AnotherWay._record_node_path_to_node( event["target"], wnd.document );
-		if( target!=null ) {
-			Test.AnotherWay._record_control_update_highlight( target, "ball", event );
-			var e=wnd.document.createEvent( "MouseEvents" );
-			var related_target=Test.AnotherWay._record_node_path_to_node( event["relatedTarget"], wnd.document );
-			e.initMouseEvent(
-				event["type"],
-				event["cancelable"],
-				event["bubbles"],
-				wnd.document.defaultView,
-				event["detail"],
-				event["screenX"],
-				event["screenY"],
-				event["clientX"],
-				event["clientY"],
-				event["ctrlKey"],
-				event["altKey"],
-				event["shiftKey"],
-				event["metaKey"],
-				event["button"],
-				Test.AnotherWay._record_node_path_to_node( event["relatedTarget"], wnd.document )
-			);
-			// Firefox 1.0.6 somehow loses relatedTarget somewhere on the way. Pass through our own, for those who choose to care.
-			e.passThroughRelatedTarget=related_target;
-			target.dispatchEvent( e );
-		}
-	}else if( event.type=="keyup" || event.type=="keydown" || event.type=="keypress" ) {
-		var e=wnd.document.createEvent( "KeyboardEvents" ); // forget it. Apparently it's not supported neither by mozilla nor by opera.
-		e.initKeyboardEvent(
-				event["type"],
-				event["cancelable"],
-				event["bubbles"],
-				wnd.document.defaultView,
-				event["which"],
-				event["which"],
-				event["ctrlKey"],
-				event["altKey"],
-				event["shiftKey"],
-				event["metaKey"],
-				false
-		);
-		wnd.document.dispatchEvent( e );
-	}
-}
-
-Test.AnotherWay._print_counter_result=function( url, msg, milliseconds, style )
-{
-	return Test.AnotherWay._print_result( url, msg+"<span class=\"counter\">"+(milliseconds/1000).toFixed()+"</span>", style, null );
-}
-
-Test.AnotherWay._g_result_count=0; // for assigning unique ids to result paragraphs
-
-// number of pages tested
-Test.AnotherWay._g_ok_pages=0;
-Test.AnotherWay._g_fail_pages=0;
-
-Test.AnotherWay._print_result=function( url, msg, style, test_objects )
-{
-	var results=document.getElementById( "results" );
-	var r=results.appendChild( document.createElement( "p" ) );
-	r.id="result"+Test.AnotherWay._g_result_count;
-	++Test.AnotherWay._g_result_count;
-	r.onclick=Test.AnotherWay._toggle_detail;
-	var text="<span class=\"bullet\">&nbsp;&nbsp;&nbsp;</span>&nbsp;";
-	if( url!="" ) {
-		text+=url+":  ";
-	}
-	if( msg!=null ) {
-		text+=msg;
-	}
-	if( test_objects!=null ) {
-		// compose summary and detail texts
-		var total_ok=0;
-		var total_detail_ok=0;
-		var total_fail=0;
-		var total_detail_fail=0;
-		var no_plan=0;
-
-		var detail=results.appendChild( document.createElement( "div" ) );
-
-		if( r.id.match( /^result(\d+)$/ ) ) {
-			detail.id="result_detail"+RegExp.$1;
-		}
-
-		for( var i=0; i<test_objects.length; ++i ) {
-			var o=test_objects[i];
-			var p;
-			var p_text;
-			p=document.createElement( "P" );
-			Test.AnotherWay._set_css_class( p, "result_detail" );
-			p_text=o.name;
-			if( o.n_fail>0 || o.exception || (o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) || (o.n_plan==null && o.n_ok==0 && o.n_fail==0)) {
-				++total_fail;
-				p_text+=" <span class=\"fail\">";
-				if( o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) {
-					p_text+="planned "+o.n_plan+" assertions but got "+(o.n_ok+o.n_fail)+"; ";
-				}
-				if(o.n_plan==null && o.n_ok==0 && o.n_fail==0) {
-					p_text+="test did not output anything";
-				}else {
-					p_text+=" fail "+o.n_fail;
-				}
-				p_text+="</span>";
-			}else {
-				++total_ok;
-			}
-			p_text+=" ok "+o.n_ok;
-			if( o.n_plan==null ) {
-				no_plan=1;
-				p_text+=" <span class=\"warning\">no plan</span>";
-			}
-			p.innerHTML=p_text;
-			detail.appendChild( p );
-			if( o.exception ) {
-				p=document.createElement( "P" );
-				Test.AnotherWay._set_css_class( p, "result_exception_detail" );
-				p.innerHTML="<span class=\"fail\">exception:</span> "+o.exception;
-				detail.appendChild( p );
-				p=document.createElement( "P" );
-				Test.AnotherWay._set_css_class( p, "result_exception_stack_detail" );
-				p.innerHTML=o.exception_stack.join( "<br/>" );
-				detail.appendChild( p );
-			}
-			for( var ii=0; ii<o.assertions.length; ++ii ) {
-				var oo=o.assertions[ii];
-				var status=oo.ok ? "ok" : "<span class=\"fail\">fail</span>";
-				p=document.createElement( "P" );
-				Test.AnotherWay._set_css_class( p, "result_micro_detail" );
-				p.innerHTML=status;
-				p.appendChild( document.createTextNode( " "+oo.name ) );
-				detail.appendChild( p );
-			}
-			total_detail_ok+=o.n_ok;
-			total_detail_fail+=o.n_fail;
-		}
-		if( total_fail || total_detail_fail ) {
-			text+=" fail "+total_fail;
-		}
-		text+=" ok "+total_ok+" (detailed:";
-		if( total_fail || total_detail_fail ) {
-			text+=" fail "+total_detail_fail;
-		}
-		text+=" ok "+total_detail_ok+")";
-		if( no_plan ) {
-			text+=" <span class=\"warning\">no plan</span>";
-		}
-		style= total_fail==0 ? "ok" : "fail";
-		detail.style.display= style=="fail" ? "block" : "none";
-		detail.style.cursor="text";
-	}
-	if( style!=null ) {
-		Test.AnotherWay._set_css_class( r, style );
-		if( style=="ok" ) {
-			++Test.AnotherWay._g_ok_pages;
-		}else if( style=="fail" || style=="badtest" ) {
-			++Test.AnotherWay._g_fail_pages;
-		}
-		var pages_total="";
-		if( Test.AnotherWay._g_fail_pages>0 ) {
-			pages_total+=" fail "+Test.AnotherWay._g_fail_pages;
-		}
-		pages_total+=" ok "+Test.AnotherWay._g_ok_pages;
-		Test.AnotherWay._update_results_total( pages_total );
-	}
-	r.innerHTML=text;
-	if( results.scrollHeight!=null && results.scrollTop!=null && results.offsetHeight!=null ) {
-		results.scrollTop=results.scrollHeight-results.offsetHeight;
-	}
-	// when test_objects is not null, the results are final - good time to clean up
-	if( test_objects!=null ) {
-		for( var i=0; i<test_objects.length; ++i ) {
-			var actions=test_objects[i].delay_actions;
-			for( var action_i=0; action_i<actions.length; ++action_i ) {
-				var action=actions[action_i];
-				if( action.action_kind=="window" && action.wnd_wnd!=null && !action.wnd_no_close ) {
-					action.wnd_wnd.close();
-					action.wnd_wnd=null;
-				}
-			}
-		}
-	}
-	return r;
-}
-Test.AnotherWay._unprint_result=function( child )
-{
-	var results=document.getElementById( "results" );
-	results.removeChild( child );
-}
-Test.AnotherWay._toggle_detail=function()
-{
-	if( this.id.match( /^result(\d+)$/ ) ) {
-		var detail=document.getElementById( "result_detail"+RegExp.$1 );
-		if( detail!=null ) {
-			if( detail.style.display=="none" ) {
-				detail.style.display="block";
-			}else if( detail.style.display=="block" ) {
-				detail.style.display="none";
-			}
-		}
-	}
-}
-Test.AnotherWay._update_msg_counter=function( msg, text )
-{
-	for( var i=0; i<msg.childNodes.length; ++i ) {
-		var item=msg.childNodes[i];
-		if( item.nodeName=="SPAN" && Test.AnotherWay._get_css_class( item )=="counter" ) {
-			item.innerHTML=text;
-		}
-	}
-}
-Test.AnotherWay._update_results_total=function( msg )
-{
-	var total=document.getElementById( "total" );
-	if( total ) {
-		total.innerHTML=msg;
-	}
-}
-Test.AnotherWay._results_clear_onclick=function()
-{
-	var results=document.getElementById( "results" );
-	results.innerHTML="";
-	Test.AnotherWay._update_results_total( "" );
-	Test.AnotherWay._g_ok_pages=0;
-	Test.AnotherWay._g_fail_pages=0;
-	var debug=document.getElementById( "debug" );
-	debug.innerHTML="";
-}
-
-Test.AnotherWay._get_css_class=function( o )
-{
-	var c=o.getAttribute( "className" );
-	if( c==null || c=="" ) {
-		c=o.getAttribute( "class" );
-	}
-	return c;
-}
-Test.AnotherWay._set_css_class=function( o, css_class )
-{
-	o.setAttribute( "className", css_class );
-	o.setAttribute( "class", css_class );
-}
-
-Test.AnotherWay._tab_onclick=function()
-{
-	var tab=this;
-	var tabs=[ document.getElementById( "debug_tab" ), document.getElementById( "results_tab" ) ];
-	var panes=[ document.getElementById( "debug" ), document.getElementById( "results" ) ];
-	for( var i=0; i<tabs.length; ++i ) {
-		if( tab==tabs[i] ) {
-			Test.AnotherWay._set_css_class( tabs[i], "active_tab" );
-			panes[i].style.display="block";
-		}else {
-			Test.AnotherWay._set_css_class( tabs[i], "inactive_tab" );
-			panes[i].style.display="none";
-		}
-	}
-}
-Test.AnotherWay._tab_mouseover=function()
-{
-	if( Test.AnotherWay._get_css_class( this )=="inactive_tab" ) {
-		Test.AnotherWay._set_css_class( this, "inactive_mouseover_tab" );
-	}
-}
-Test.AnotherWay._tab_mouseout=function()
-{
-	if( Test.AnotherWay._get_css_class( this )=="inactive_mouseover_tab" ) {
-		Test.AnotherWay._set_css_class( this, "inactive_tab" );
-	}
-}
-
-// recording mouse input
-Test.AnotherWay._record_check_onfocus=function()
-{
-	var o=this;
-	var check_select=o.type!="text";
-	var div=document.getElementById( "record_div" );
-	var inputs=div.getElementsByTagName( "input" );
-	for( var i=0; i<inputs.length; ++i ) {
-		var input=inputs[i];
-		if( input.type=="radio" ) {
-			if( input.value=="select" ) {
-				input.checked=check_select;
-			}else if( input.value=="input" ) {
-				input.checked=!check_select;
-			}
-		}
-	}
-}
-
-Test.AnotherWay._g_no_record_msg=null; // not null - recording is unavailable
-Test.AnotherWay._g_record_timeout_cnt=0; // opening window for a page for recording
-Test.AnotherWay._g_record_url=null;
-Test.AnotherWay._g_record_wnd=null;
-Test.AnotherWay._g_record_random_id=null; // added to element ids of record_control div so that they do not clash with ids already in the page for which input is recorded
-Test.AnotherWay._g_record_keydown=null; // recording control - which key is down
-Test.AnotherWay._g_record_ctrl_keydown=false;
-Test.AnotherWay._g_record_shift_keydown=false;
-Test.AnotherWay._g_record_control_visible=true; // recording control ui state
-Test.AnotherWay._g_record_started;
-Test.AnotherWay._g_record_paused;
-Test.AnotherWay._g_record_include_mousemove=false;
-Test.AnotherWay._g_record_start_time; // for time references
-Test.AnotherWay._g_record_pause_start_time;
-Test.AnotherWay._g_record_update_time_interval; // showing time in the control ui
-Test.AnotherWay._g_record_waiting_for_results=false; // waiting for results window to open
-Test.AnotherWay._g_record_events; // recorded events
-Test.AnotherWay._g_record_under_cursor; // track element under cursor
-Test.AnotherWay._g_record_checkpoint_count; // for checkpoint numbering
-Test.AnotherWay._g_record_mouse_over_record_control; // for avoiding record control highlight on mouseover
-Test.AnotherWay._g_record_highlighted_element={ element: null, x: null, y: null };
-
-Test.AnotherWay._record_control_get_element=function( id )
-{
-	if( Test.AnotherWay._g_record_wnd!=null && Test.AnotherWay._g_record_wnd.document!=null ) {
-		return Test.AnotherWay._g_record_wnd.document.getElementById( id+Test.AnotherWay._g_record_random_id );
-	}else {
-		return null;
-	}
-}
-Test.AnotherWay._record_start_onclick=function() // "record" button on the run_tests.html: open a window for a page for which input is recorded
-{
-	if( Test.AnotherWay._g_no_record_msg!=null ) {
-		alert( Test.AnotherWay._g_no_record_msg );
-		return;
-	}
-	if( Test.AnotherWay._g_record_timeout_cnt>0
-	    || (Test.AnotherWay._g_record_wnd!=null && (Test.AnotherWay._g_record_wnd.closed!=null && !Test.AnotherWay._g_record_wnd.closed)) ) { // in opera, closed is null.
-		alert( "there is already window opened for recording input for a page "+Test.AnotherWay._g_record_url );
-		return;
-	}
-	var div=document.getElementById( "record_div" );
-	var inputs=div.getElementsByTagName( "input" );
-	var url=null;
-	for( var i=0; i<inputs.length; ++i ) {
-		var input=inputs[i];
-		if( input.type=="radio" ) {
-			if( input.value=="select" && input.checked ) {
-				var index=document.getElementById( "record_select" ).selectedIndex;
-				if( index>0 ) {
-					url=Test.AnotherWay._g_test_page_urls[index-1].url;
-				}
-			}else if( input.value=="input" && input.checked ) {
-				url=document.getElementById( "record_input" ).value;
-			}
-		}
-	}
-	if( url!=null ) {
-		Test.AnotherWay._g_record_url=url;
-		Test.AnotherWay._g_record_wnd=window.open( url, "_blank" );
-		if( Test.AnotherWay._g_record_wnd==null ) {
-			alert( "unable to open new window for a page: "+url );
-		}else {
-			Test.AnotherWay._g_record_timeout_cnt=50;
-			setTimeout( Test.AnotherWay._record_window_timeout, 100 );
-		}
-	}
-}
-Test.AnotherWay._record_window_timeout=function()
-{
-	if( Test.AnotherWay._is_url_loaded( Test.AnotherWay._g_record_url, Test.AnotherWay._g_record_wnd ) ) {
-		Test.AnotherWay._record_window_setup( Test.AnotherWay._g_record_wnd );
-	}else {
-		if( --Test.AnotherWay._g_record_timeout_cnt>0 ) {
-			setTimeout( Test.AnotherWay._record_window_timeout, 100 );
-		}else {
-			alert( "timeout expired while opening new window for a page: "+Test.AnotherWay._g_record_url );
-			Test.AnotherWay._g_record_wnd=null;
-			Test.AnotherWay._g_record_url=null;
-			Test.AnotherWay._g_record_timeout_cnt=0;
-		}
-	}
-}
-Test.AnotherWay._record_control_randomize_id=function( e, r )
-{
-	if( e.id!="" ) {
-		e.id=e.id+r;
-	}
-	for( var c=e.firstChild; c!=null; c=c.nextSibling ) {
-		Test.AnotherWay._record_control_randomize_id( c, r );
-	}
-}
-Test.AnotherWay._record_window_setup=function( wnd ) // insert recording control into the page for which input is recorded
-{
-	Test.AnotherWay._g_record_timeout_cnt=0;
-	var this_div=document.getElementById( "record_control" );
-	var record_control=wnd.document.importNode( this_div, true );
-	Test.AnotherWay._g_record_random_id=(1000*Math.random()).toFixed();
-	Test.AnotherWay._record_control_randomize_id( record_control, Test.AnotherWay._g_record_random_id );
-	Test.AnotherWay._g_record_control_visible=true;
-	Test.AnotherWay._g_record_started=false;
-	Test.AnotherWay._g_record_paused=false;
-	Test.AnotherWay._g_record_checkpoint_count=0;
-	Test.AnotherWay._g_record_mouse_over_record_control=false;
-	var doc=wnd.document;
-	doc.body.appendChild( record_control );
-	// opera sans-serif font is different
-	if( window.opera ) {
-		cursor_over_indicator=Test.AnotherWay._record_control_get_element( "record_cursor_over" );
-		cursor_over_indicator.style.width="18em";
-		cursor_over_indicator.style.height="2em";
-		cursor_over_indicator.style.fontSize="7pt";
-	}
-	doc.addEventListener( "keydown", Test.AnotherWay._record_control_keydown, true );
-	doc.addEventListener( "keyup", Test.AnotherWay._record_control_keyup, true );
-//	doc.addEventListener( "keypress", Test.AnotherWay._record_event, true ); // replaying is not supported by any known browser
-
-	doc.body.addEventListener( "mousemove", Test.AnotherWay._record_on_mousemove, true );
-	doc.body.addEventListener( "click", Test.AnotherWay._record_event, true );
-	doc.body.addEventListener( "mouseover", Test.AnotherWay._record_event, true );
-	doc.body.addEventListener( "mouseout", Test.AnotherWay._record_event, true );
-	doc.body.addEventListener( "mousedown", Test.AnotherWay._record_event, true );
-	doc.body.addEventListener( "mouseup", Test.AnotherWay._record_event, true );
-}
-Test.AnotherWay._record_control_key_disabled=function( k )
-{
-	if( k=="c" ) {
-		return !Test.AnotherWay._g_record_started;
-	}else if( k=="p" ) {
-		return !Test.AnotherWay._g_record_started;
-	}else if( k=="s" ) {
-		return Test.AnotherWay._g_record_waiting_for_results;
-	}else {
-		return false;
-	}
-}
-
-Test.AnotherWay._record_control_update_ui=function()
-{
-	var keydown_color="#fff";
-	var disabled_color="#aaa";
-	var button_color="#adf";
-	var active_color="#fdf";
-
-	var display={};
-	display[false]="none";
-	display[true]="inline";
-
-	var s_button=Test.AnotherWay._record_control_get_element( "record_s" );
-	var record_on=Test.AnotherWay._record_control_get_element( "record_on" );
-	var record_off=Test.AnotherWay._record_control_get_element( "record_off" );
-
-	s_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "s" ) ? disabled_color
-		: Test.AnotherWay._g_record_keydown=="s" ? keydown_color : Test.AnotherWay._g_record_started ? active_color : button_color;
-	record_on.style.display=display[!Test.AnotherWay._g_record_started];
-	record_off.style.display=display[Test.AnotherWay._g_record_started];
-
-	var h_button=Test.AnotherWay._record_control_get_element( "record_h" );
-	h_button.style.backgroundColor= Test.AnotherWay._g_record_keydown=="h" ? keydown_color : button_color;
-
-	var p_button=Test.AnotherWay._record_control_get_element( "record_p" );
-	var record_pause_on=Test.AnotherWay._record_control_get_element( "record_pause_on" );
-	var record_pause_off=Test.AnotherWay._record_control_get_element( "record_pause_off" );
-	p_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "p" ) ? disabled_color
-		: Test.AnotherWay._g_record_keydown=="p" ? keydown_color : Test.AnotherWay._g_record_paused ? active_color : button_color;
-	record_pause_on.style.display=display[!Test.AnotherWay._g_record_paused];
-	record_pause_off.style.display=display[Test.AnotherWay._g_record_paused];
-
-	var m_button=Test.AnotherWay._record_control_get_element( "record_m" );
-	var record_include_mousemove=Test.AnotherWay._record_control_get_element( "record_include_mousemove" );
-	var record_omit_mousemove=Test.AnotherWay._record_control_get_element( "record_omit_mousemove" );
-	m_button.style.backgroundColor= Test.AnotherWay._g_record_keydown=="m" ? keydown_color : Test.AnotherWay._g_record_include_mousemove ? active_color : button_color;
-	record_include_mousemove.style.display=display[!Test.AnotherWay._g_record_include_mousemove];
-	record_omit_mousemove.style.display=display[Test.AnotherWay._g_record_include_mousemove];
-
-	var c_button=Test.AnotherWay._record_control_get_element( "record_c" );
-	c_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( "c" ) ? disabled_color
-		: Test.AnotherWay._g_record_keydown=="c" ? keydown_color : button_color;
-
-	var record_indicator=Test.AnotherWay._record_control_get_element( "record_indicator" );
-	record_indicator.style.display=display[Test.AnotherWay._g_record_started];
-
-	var pause_indicator=Test.AnotherWay._record_control_get_element( "record_pause_indicator" );
-	pause_indicator.style.display=display[Test.AnotherWay._g_record_paused];
-
-	var record_control=Test.AnotherWay._record_control_get_element( "record_control" );
-	record_control.style.display= Test.AnotherWay._g_record_control_visible ? "block" : "none";
-
-	var shift_button=Test.AnotherWay._record_control_get_element( "record_shift_key" );
-	shift_button.style.backgroundColor= Test.AnotherWay._g_record_shift_keydown ? keydown_color : button_color;
-
-	var ctrl_button=Test.AnotherWay._record_control_get_element( "record_ctrl_key" );
-	ctrl_button.style.backgroundColor= Test.AnotherWay._g_record_ctrl_keydown ? keydown_color : button_color;
-}
-Test.AnotherWay._record_format_time=function( t )
-{
-	t=new Date( t );
-	var m=t.getMinutes();
-	var s=t.getSeconds();
-	var str= m==0 ? "" : m+"m ";
-	str+=s+"s.";
-	return str;
-}
-Test.AnotherWay._record_control_update_time=function()
-{
-	var time_display=Test.AnotherWay._record_control_get_element( "record_time" );
-	if( time_display!=null ) {
-		time_display.innerHTML=Test.AnotherWay._record_format_time( (new Date()).getTime()-Test.AnotherWay._g_record_start_time );
-	}
-}
-Test.AnotherWay._record_control_update_highlight=function( elem, style, event )
-{
-	if( elem==null ) {
-		Test.AnotherWay._record_highlight_border( null );
-	}else {
-		var pos=Test.AnotherWay._get_page_coords( elem );
-		if( style=="ball" || elem!=Test.AnotherWay._g_record_highlighted_element.element || pos.x!=Test.AnotherWay._g_record_highlighted_element.x || pos.y!=Test.AnotherWay._g_record_highlighted_element.y ) {
-			Test.AnotherWay._g_record_highlighted_element={ element: elem, x: pos.x, y: pos.y };
-			Test.AnotherWay._record_highlight_border( elem, style, event );
-		}
-	}
-}
-Test.AnotherWay._record_decode_key=function( event )
-{
-	var k=null;
-	if( event==null ) {
-		k=Test.AnotherWay._g_record_wnd.event.keyCode;
-	}else {
-		k=event.which;
-	}
-	if( k==83 ) {
-		return "s";
-	}else if( k==72 ) {
-		return "h";
-	}else if( k==73 ) {
-		return "i";
-	}else if( k==80 ) {
-		return "p";
-	}else if( k==67 ) {
-		return "c";
-	}else if( k==77 ) {
-		return "m";
-	}else if( k==16 ) {
-		return "shift";
-	}else if( k==17 ) {
-		return "ctrl";
-	}else if( k==18 ) {
-		return "alt";
-	}else if( k==19 ) {
-		return "pause";
-	}else if( k==123 ) {
-		return "f12";
-	}
-	return "";
-}
-Test.AnotherWay._record_control_keydown=function( event )
-{
-	var handled=false;
-	var k=Test.AnotherWay._record_decode_key( event );
-	if( k=="shift" ) {
-		Test.AnotherWay._g_record_shift_keydown=true;
-	}else if( k=="ctrl" ) {
-		Test.AnotherWay._g_record_ctrl_keydown=true;
-	}else if( k!="" && (Test.AnotherWay._g_record_keydown==null || Test.AnotherWay._g_record_keydown==k) ) {
-		if( Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown && !Test.AnotherWay._record_control_key_disabled( k ) ) {
-			Test.AnotherWay._g_record_keydown=k;
-			handled=true;
-		}
-	}else {
-		Test.AnotherWay._g_record_keydown="";
-	}
-	Test.AnotherWay._record_control_update_ui();
-	if( !handled ) {
-//		Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
-	}
-	return;
-}
-Test.AnotherWay._record_control_keyup=function( event )
-{
-	var handled=false;
-	var k=Test.AnotherWay._record_decode_key( event );
-	if( k=="shift" ) {
-		Test.AnotherWay._g_record_shift_keydown=false;
-	}else if( k=="ctrl" ) {
-		Test.AnotherWay._g_record_ctrl_keydown=false;
-	}else if( k!="" && k==Test.AnotherWay._g_record_keydown && Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown  ) {
-		if( k=="s" ) {
-			Test.AnotherWay._g_record_started=!Test.AnotherWay._g_record_started;
-			if( Test.AnotherWay._g_record_started ) {
-				Test.AnotherWay._g_record_events=[];
-				Test.AnotherWay._g_record_start_time=(new Date()).getTime();
-				Test.AnotherWay._record_control_update_time();
-				Test.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );
-			}else {
-				Test.AnotherWay._record_control_update_highlight( null );
-				if( !Test.AnotherWay._g_record_paused ) {
-					window.clearInterval( Test.AnotherWay._g_record_update_time_interval );
-				}
-				Test.AnotherWay._g_record_waiting_for_results=true;
-				// open a new window for self, pass a parameter to dump recorded events as javascript code there
-				// (the easiest way to obtain a document from the same origin, so it's writable, is to open this same page again)
-				Test.AnotherWay._g_record_paused=false;
-				var loc=window.location;
-				loc=loc.protocol+"//"+loc.host+loc.pathname+"?recording_results="+Test.AnotherWay._g_record_random_id;
-				if( window.open( loc, "_blank" )==null ) {
-					alert( "unable to open new window for results" );
-				}
-			}
-			handled=true;
-		}else if( k=="h" ) {
-			Test.AnotherWay._g_record_control_visible=!Test.AnotherWay._g_record_control_visible;
-			handled=true;
-		}else if( k=="p" ) {
-			Test.AnotherWay._g_record_paused=!Test.AnotherWay._g_record_paused;
-			if( Test.AnotherWay._g_record_paused ) {
-				Test.AnotherWay._g_record_pause_start_time=(new Date()).getTime();
-				if( Test.AnotherWay._g_record_started ) {
-					window.clearInterval( Test.AnotherWay._g_record_update_time_interval );
-				}
-				Test.AnotherWay._record_control_update_highlight( null );
-			}else {
-				var pause_duration=(new Date()).getTime()-Test.AnotherWay._g_record_pause_start_time;
-				Test.AnotherWay._g_record_start_time+=pause_duration;
-				Test.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );
-			}
-			handled=true;
-		}else if( k=="m" ) {
-			Test.AnotherWay._g_record_include_mousemove=!Test.AnotherWay._g_record_include_mousemove;
-			handled=true;
-		}else if( k=="c" ) {
-			var o=Test.AnotherWay._record_checkpoint();
-			Test.AnotherWay._record_display_checkpoint( o );
-			Test.AnotherWay._record_flash_border( "#24d" );
-			handled=true;
-		}
-	}
-	Test.AnotherWay._g_record_keydown=null;
-	Test.AnotherWay._record_control_update_ui();
-	if( !handled ) {
-//		Test.AnotherWay._record_event( event ); // replaying is not supported in any known browser
-	}
-	return;
-}
-Test.AnotherWay._record_html_node_path=function( node )
-{
-	if( node==null ) {
-		return null;
-	}
-	var path=[];
-	while( true ) {
-		if( node.id!=null && node.id!="" ) {
-			path.unshift( "#"+node.id+" "+node.nodeName );
-			break;
-		}else {
-			var parent_node=node.parentNode;
-			if( parent_node==null ) {
-				return []; // no BODY up the path - this node is screwed (browsers differ in what's above the body), discard
-			}else {
-				var i=0;
-				var found=false;
-				for( var child=parent_node.firstChild; child!=null; child=child.nextSibling ) {
-					if( child==node ) {
-						found=true;
-						break;
-					}
-					if( child.nodeType==1 ) { // count only HTML element nodes
-						++i;
-					}
-				}
-				if( !found ) {
-					i=-1;
-				}
-				path.unshift( i+" "+node.nodeName );
-				if( parent_node.nodeName=="BODY" || parent_node.nodeName=="body" ) {
-					break;
-				}
-				node=parent_node;
-			}
-		}
-	}
-	return path;
-}
-Test.AnotherWay._record_node_path_to_string=function( path )
-{
-	var s="";
-	if( path!=null ) {
-		for( var i=0; i<path.length; ++i ) {
-			s+= i==0 ? "" : ", ";
-			var elem=path[i].split( " " );
-			if( elem[0].charAt( 0 )=="#" ) {
-				s+=elem[1]+" "+elem[0];
-			}else {
-				s+=elem[1]+" ["+elem[0]+"]";
-			}
-		}
-	}
-	return s;
-}
-Test.AnotherWay._record_node_path_to_node=function( path_str, doc )
-{
-	if( path_str==null ) {
-		return null;
-	}
-	var path=path_str.split( "," );
-	var node=doc.body;
-	for( var i=0; i<path.length; ++i ) {
-		var node_i=path[i].split( " " )[0];
-		if( node_i.charAt( 0 )=="#" ) {
-			node=doc.getElementById( node_i.substring( 1 ) );
-		}else {
-			if( node_i<0 || node_i>=node.childNodes.length ) {
-				node=null;
-			}else {
-				node=node.firstChild;
-				while( node!=null ) {
-					if( node.nodeType==1 ) {  // count only HTML element nodes
-						if( node_i==0 ) {
-							break;
-						}
-						--node_i;
-					}
-					node=node.nextSibling;
-				}
-			}
-		}
-		if( node==null ) {
-			return null;
-		}
-	}
-	return node;
-}
-Test.AnotherWay._record_control_contains_id=function( s )
-{
-	return s.match( /^#record_[\w_]+/ ) && s.match( Test.AnotherWay._g_record_random_id );
-}
-Test.AnotherWay._record_checkpoint=function()
-{
-	var o={ type: "_checkpoint", time: (new Date()).getTime()-Test.AnotherWay._g_record_start_time, which: Test.AnotherWay._g_record_checkpoint_count++,
-			target: Test.AnotherWay._record_html_node_path( Test.AnotherWay._g_record_under_cursor ) };
-	Test.AnotherWay._g_record_events.push( o );
-	return o;
-}
-Test.AnotherWay._record_event=function( event )
-{
-	var unneeded=["rangeOffset","eventPhase","timeStamp","isTrusted","popupWindowFeatures","rangeOffset"];
-	if( Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {
-		var o={};
-		for( var n in event ) {
-			var needed=!n.match( /^[A-Z0-9_]+$/ );
-			if( needed ) {
-				for( var ui=0; ui<unneeded.length; ++ui ) {
-					if( unneeded[ui]==n ) {
-						needed=false;
-						break;
-					}
-				}
-				if( needed ) {
-					var value=event[n];
-					if( typeof( value )!="object" && typeof( value )!="function" ) {
-						o[n]=value;
-					}else if( n=="target" || n=="relatedTarget" ) {
-						o[n]=Test.AnotherWay._record_html_node_path( value );
-					}
-				}
-			}
-		}
-		o["time"]=(new Date()).getTime()-Test.AnotherWay._g_record_start_time;
-		var over_record_control= o["target"]!=null && o["target"][0]!=null && Test.AnotherWay._record_control_contains_id( o["target"][0] );
-		if( !over_record_control ) {
-			Test.AnotherWay._g_record_events.push( o );
-		}
-	}
-	return true;
-}
-Test.AnotherWay._record_on_mousemove=function( event )
-{
-	var path=Test.AnotherWay._record_html_node_path( event.target );
-	var new_mouse_over_record_control= path!=null && path[0]!=null && Test.AnotherWay._record_control_contains_id( path[0] );
-	if( new_mouse_over_record_control!=Test.AnotherWay._g_record_mouse_over_record_control ) {
-		Test.AnotherWay._g_record_mouse_over_record_control=new_mouse_over_record_control;
-		Test.AnotherWay._record_control_update_ui();
-	}
-	if( event.target!=null && event.target!=Test.AnotherWay._g_record_under_cursor ) {
-		Test.AnotherWay._g_record_under_cursor=event.target;
-		var s="";
-		if( path==null || path[0]==null || !Test.AnotherWay._record_control_contains_id( path[0] ) ) {
-			s=Test.AnotherWay._record_node_path_to_string( path );
-		}
-		if( s=="" ) {
-			s="&nbsp;";
-		}
-		var cursor_over_indicator=Test.AnotherWay._record_control_get_element( "record_cursor_over" );
-		cursor_over_indicator.innerHTML=s;
-	}
-
-	var highlight_element=null;
-	if( !Test.AnotherWay._g_record_mouse_over_record_control && Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {
-		highlight_element=event.target;
-	}
-	// highlight border disabled on recording - it causes page to scroll, issuing spurious mouseover/mouseout event
-	//Test.AnotherWay._record_control_update_highlight( highlight_element, "border" );
-
-	if( Test.AnotherWay._g_record_include_mousemove ) {
-		Test.AnotherWay._record_event( event );
-	}
-	return true;
-}
-Test.AnotherWay._record_display_checkpoint=function( o )
-{
-	var checkpoints_div=Test.AnotherWay._record_control_get_element( "record_checkpoints" );
-	var p=checkpoints_div.appendChild( checkpoints_div.ownerDocument.createElement( "div" ) );
-	p.style.marginTop="3px";
-	p.style.font="normal normal 8pt sans-serif";
-	p.style.color="#000";
-	p.style.textAligh="left";
-	p.style.position="relative";
-	p.style.width="100%";
-	var checkpoint_text="";
-	checkpoint_text+="#"+(o.which+1);
-	checkpoint_text+="  "+Test.AnotherWay._record_format_time( o.time );
-	if( o.target!=null ) {
-		checkpoint_text+=Test.AnotherWay._record_node_path_to_string( o.target );
-	}
-	p.appendChild( p.ownerDocument.createTextNode( checkpoint_text ) );
-}
-Test.AnotherWay._record_save_results=function( doc )
-{
-	// strange, but DOM-style append does not work here in opera 8.
-	var append=function( s ) { doc.write( "<div>"+s+"</div>" ); };
-	append( "/* paste this data into your javascript and pass it as an argument to replay_events method */" );
-	append( "{ checkpoints: [" );
-	var first_checkpoint=true;
-	for( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {
-		var o=Test.AnotherWay._g_record_events[i];
-		if( o.type=="_checkpoint" ) {
-			var str= first_checkpoint ? "" : "}, ";
-			str+="function( tst, wnd ) { // #"+o.which+" time "+Test.AnotherWay._record_format_time( o.time )+" cursor was over "+Test.AnotherWay._record_node_path_to_string( o.target );
-			append( str );
-			first_checkpoint=false;
-		}
-	}
-	if( !first_checkpoint ) {
-		append( "}" );
-	}
-	append( "], events: [ " );
-	var prev_time=0;
-	for( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {
-		var o=Test.AnotherWay._g_record_events[i];
-		var s="";
-		s+= "{";
-		var n_first=true;
-		for( var n in o ) {
-			if( n=="time" ) { // convert to relative time
-				var cur_time=o[n]-0;
-				o[n]=cur_time-prev_time;
-				prev_time=cur_time;
-			}
-			s+=n_first ? n : ", "+n;
-			s+=":";
-			if( o[n]==null ) {
-				s+="null";
-			}else {
-				s+="\""+o[n]+"\"";
-			}
-			n_first=false;
-		}
-		s+= i==Test.AnotherWay._g_record_events.length-1 ? "}" : "},";
-		append( s );
-	}
-	append( "] }" );
-	append( ";" );
-}
-
-Test.AnotherWay._g_record_border; // border highlighting element under cursor
-Test.AnotherWay._g_record_border_flashes=[]; // array of { color: color, timeout: milliseconds }
-Test.AnotherWay._g_record_border_flashing=false;
-Test.AnotherWay._g_record_border_normal_color="#d4b";
-Test.AnotherWay._record_flash_border_timeout=function()
-{
-	var color=Test.AnotherWay._g_record_border_normal_color;
-	var timeout=null;
-	if( Test.AnotherWay._g_record_border_flashes.length!=0 ) {
-		color=Test.AnotherWay._g_record_border_flashes[0].color;
-		timeout=Test.AnotherWay._g_record_border_flashes[0].timeout;
-		Test.AnotherWay._g_record_border_flashes.splice( 0, 1 );
-	}
-	if( Test.AnotherWay._g_record_border!=null ) {
-		for( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {
-			Test.AnotherWay._g_record_border[i].style.backgroundColor=color;
-		}
-	}
-	if( timeout!=null ) {
-		setTimeout( Test.AnotherWay._record_flash_border_timeout, timeout );
-	}else {
-		Test.AnotherWay._g_record_border_flashing=false;
-	}
-}
-Test.AnotherWay._get_page_coords=function( elm )
-{
-	var point = { x: 0, y: 0 };
-	while( elm )  {
-		point.x+=elm.offsetLeft;
-		point.y+=elm.offsetTop;
-		elm=elm.offsetParent;
-	 }
-	return point;
-}
-Test.AnotherWay._set_page_coords=function( elm, x, y )
-{
-	var parent_coords={ x: 0, y: 0 };
-	if( elm.offsetParent )  {
-		parent_coords=Test.AnotherWay._get_page_coords( elm.offsetParent );
-	}
-	var new_x=x-parent_coords.x;
-	if( new_x<0 ) {
-		new_x=0;
-	}
-	elm.style.left=new_x+'px';
-	var new_y=y-parent_coords.y;
-	if( new_y<0 ) {
-		new_y=0;
-	}
-	elm.style.top=new_y+'px';
-}
-Test.AnotherWay._record_setup_highlight_positions=function( element, style, coords, positions )
-{
-	if( style=="border" ) {
-		var width=element.clientWidth;
-		var height=element.clientHeight;
-		var step=0;
-		var thickness=2;
-		var fudge_expand=4;
-		positions.push( { x: coords.x-step-thickness, y: coords.y-step-thickness, width: width+2*step+2*thickness+fudge_expand, height: thickness } );
-		positions.push( { x: coords.x+width+step+fudge_expand, y: coords.y-step-thickness, width: thickness, height: height+2*step+2*thickness+fudge_expand } );
-		positions.push( { x:positions[0].x, y:positions[0].y, width:positions[0].width, height:positions[0].height } );
-		positions.push( { x:positions[1].x, y:positions[1].y, width:positions[1].width, height:positions[1].height } );
-		positions[2].y+=height+thickness+2*step+fudge_expand;
-		positions[3].x-=width+thickness+2*step+fudge_expand;
-	}else if( style=="ball" ) {
-		positions.push( { x: coords.x+2, y: coords.y, width: 2, height: 6 } );
-		positions.push( { x: coords.x, y: coords.y+2, width: 6, height: 2 } );
-		positions.push( { x: coords.x+1, y: coords.y+1, width: 4, height: 4 } );
-	}
-}
-Test.AnotherWay._record_highlight_border=function( element, style, event ) // null - hide border
-{
-	if( element!=null ) {
-		if( Test.AnotherWay._g_record_border==null || Test.AnotherWay._g_record_border[0].ownerDocument!=element.ownerDocument ) {
-			Test.AnotherWay._g_record_border=[];
-			var n= style=="border" ? 4 : style=="ball" ? 3 : 0;
-			for( var i=0; i<4; ++i ) {
-				var b=element.ownerDocument.createElement( "div" );
-				b.style.position="absolute";
-				b.style.zIndex="1";
-				b.style.backgroundColor=Test.AnotherWay._g_record_border_normal_color;
-				element.ownerDocument.body.appendChild( b );
-				Test.AnotherWay._g_record_border.push( b );
-			}
-		}
-		var coords=null;
-		if( style=="border" ) {
-			coords=Test.AnotherWay._get_page_coords( element );
-		}else if( style=="ball" ) {
-			if( event!=null ) {
-				if( event.pageX!=null && event.pageY!=null ) {
-					coords={ x: event.pageX-0, y: event.pageY-0 };
-				}else if( event.clientX!=null && event.clientY!=null ) {
-					var doc=element.ownerDocument;
-					if( doc!=null ) {
-						coords={ x: (event.clientX-0)+doc.body.scrollLeft, y: (event.clientY-0)+doc.body.scrollTop };
-					}
-				}
-			}
-		}
-		if( coords!=null && element.clientWidth!=null && element.clientHeight!=null ) {
-			var positions=[];
-			Test.AnotherWay._record_setup_highlight_positions( element, style, coords, positions );
-			for( var i=0; i<positions.length; ++i ) {
-				var b=Test.AnotherWay._g_record_border[i];
-				var p=positions[i];
-				Test.AnotherWay._set_page_coords( b, p.x, p.y );
-				b.style.width=p.width+"px";
-				b.style.height=p.height+"px";
-				b.style.display="block";
-			}
-		}
-	}else {
-		if( Test.AnotherWay._g_record_border!=null ) {
-			for( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {
-				Test.AnotherWay._g_record_border[i].style.display="none";
-			}
-		}
-	}
-}
-Test.AnotherWay._record_flash_border=function( color )
-{
-	if( Test.AnotherWay._g_record_border_flashing ) { //already
-		Test.AnotherWay._g_record_border_flashes.push( { color: Test.AnotherWay._g_record_border_normal_color, timeout:300 } );
-		Test.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );
-	}else {
-		Test.AnotherWay._g_record_border_flashing=true;
-		Test.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );
-		Test.AnotherWay._record_flash_border_timeout();
-	}
-}
-Test.AnotherWay._record_prepare_doc_for_results=function()
-{
-	document.open();
-	document.write( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" );
-	document.write( "<html><head><title> Input recording results</title>" );
-	document.write( "<style type=\"text/css\">" );
-	document.write( "body { font: normal normal smaller sans-serif; }" );
-	document.write( "div { margin-top: 3px; }" );
-	document.write( "</style></head><body>" );
-	// opera and mozilla disagree over who the opener is.
-	if( typeof( window.opener.Test )!="undefined" && typeof( window.opener.Test.AnotherWay )!="undefined" ) {
-		window.opener.Test.AnotherWay._record_save_results( document );
-		window.opener.Test.AnotherWay._g_record_waiting_for_results=false;
-		window.opener.Test.AnotherWay._record_control_update_ui();
-	}else if( typeof( window.opener.opener.Test  )!="undefined" && typeof( window.opener.opener.Test.AnotherWay )!="undefined" ) {
-		window.opener.opener.Test.AnotherWay._record_save_results( document );
-		window.opener.opener.Test.AnotherWay._g_record_waiting_for_results=false;
-		window.opener.opener.Test.AnotherWay._record_control_update_ui();
-	}
-	document.write( "</body>" );
-	document.close();
-}
-
-// global initialization
-onload=function()
-{
-	if( window.opera ) {
-		var good_opera=typeof( window.opera.version )=="function";
-		good_opera=good_opera && window.opera.version().match( /^\s*(\d+)/ );
-		good_opera=good_opera && RegExp.$1>=8;
-	}
-	var span=document.createElement( "SPAN" );
-	span.innerHTML="<!--[if IE]><br /><![endif]-"+"->";
-	var is_ie=span.getElementsByTagName( "BR" ).length>0;
-
-	Test.AnotherWay._g_test_iframe=window.frames.test_iframe;
-
-	var query_str=window.location.search;
-	if( query_str.charAt( 0 )=="?" ) {
-		query_str=query_str.substring( 1 );
-	}
-	var testlist_page="list-tests.html";
-	var auto_run=false;
-	if( query_str!="" ) {
-		var params=[query_str];
-		if( query_str.indexOf( ";" )!=-1 ) {
-			params=query_str.split( ";" );
-		}else if( query_str.indexOf( "&" )!=-1 ) {
-			params=query_str.split( "&" );
-		}
-		for( var param_i=0; param_i<params.length; ++param_i ) {
-			var param=params[param_i].split( "=" );
-			if( param[0]=="recording_results" ) {
-				if( window.opener!=null ) {
-					// we were told to show recording results - replace everything in the document with the results
-					Test.AnotherWay._record_prepare_doc_for_results();
-					return;
-				}
-			}else if( param[0]=="testpage" ) {
-				Test.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), "anotherway" );
-			}else if( param[0]=="jsantestpage" ) {
-				Test.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), "jsan" );
-			}else if( param[0]=="testlist" ) {
-				testlist_page=decodeURIComponent( param[1] );
-			}else if( param[0]=="testframe" ) {
-				if( window.opera && !good_opera ) {
-					Test.AnotherWay._show_error( "testframe parameter does not work in versions of Opera prior to 8.0. Sorry (pathches are welcome)." );
-					// Opera 7 barfs on attempt to access frame.frameElement.
-					// if someone knows a way to assign onload handler to that iframe in Opera 7
-					// without disrupting code that works in other browsers, patches are welcome.
-				}else {
-					var frame_path=param[1].split( "." );
-					var frame=top;
-					for( var frame_path_i=0; frame_path_i<frame_path.length; ++frame_path_i ) {
-						frame=frame[frame_path[frame_path_i]];
-					}
-					if( frame==null ) {
-						Test.AnotherWay._show_error( "unable to find frame specified for loading test pages: "+param[1] );
-					}else {
-						if( frame.frameElement!=null ) { // for the following assignement to onload to work, frameElement is required
-							frame=frame.frameElement;
-						}
-						Test.AnotherWay._g_test_iframe=frame;
-					}
-				}
-			}else if( param[0]=="testframe_no_clear" ) {
-				Test.AnotherWay._g_test_frame_no_clear=true;
-			}else if( param[0]=="windows" ) {
-                if (param[1] == "none") {
-                    Test.AnotherWay._test_object_t.prototype.open_window=null;
-                }
-			}else if( param[0]=="run" ) {
-				auto_run=true;
-				if( param[1]=="all" ) {
-					Test.AnotherWay._g_pages_to_run="all";
-				}else {
-					if( Test.AnotherWay._g_pages_to_run==null || Test.AnotherWay._g_pages_to_run=="all" ) {
-						Test.AnotherWay._g_pages_to_run=[];
-					}
-					var pages=param[1].split( "," );
-					for( var i=0; i<pages.length; ++i ) {
-						Test.AnotherWay._g_pages_to_run.push( pages[i] );
-					}
-				}
-			}
-		}
-	}
-	if( Test.AnotherWay._g_test_page_urls.length==0 ) {  // if no individual pages were given on the command line, load the list
-		var result=Test.AnotherWay._set_iframe_location( window.frames["list_iframe"], testlist_page );
-		if( result.msg!=null ) {
-			Test.AnotherWay._show_error( result.msg );
-		}
-		Test.AnotherWay._g_run_on_list_load=auto_run;
-	}else {
-		Test.AnotherWay._g_run_on_main_load=auto_run;
-	}
-
-	var f=Test.AnotherWay._g_test_iframe;
-	try {
-		if( f.attachEvent!=null ) {
-			f.attachEvent( "onload", Test.AnotherWay._test_page_onload );
-		}else {
-			f.onload=Test.AnotherWay._test_page_onload;
-		}
-		if( Test.AnotherWay._g_test_iframe.nodeType!=null && Test.AnotherWay._g_test_iframe.contentWindow!=null ) { // it's iframe element, not the iframe. we need iframe.
-			Test.AnotherWay._g_test_iframe=Test.AnotherWay._g_test_iframe.contentWindow;
-		}
-	}catch(e) {
-		// ignore stupid opera error if the frame has onload handler assigned in the inline html
-	}
-	var handlers={
-		"run_all": { "onclick": Test.AnotherWay._run_all_onclick },
-		"run_selected": { "onclick": Test.AnotherWay._run_selected_onclick },
-		"unselect_all": { "onclick": Test.AnotherWay._unselect_all_onclick },
-		"record_select": { "onfocus": Test.AnotherWay._record_check_onfocus },
-		"record_input": { "onfocus": Test.AnotherWay._record_check_onfocus },
-		"record_start": { "onclick": Test.AnotherWay._record_start_onclick },
-		"clear_btn": { "onclick": Test.AnotherWay._results_clear_onclick },
-		"results_tab": { "onclick": Test.AnotherWay._tab_onclick, "onmouseover": Test.AnotherWay._tab_mouseover, "onmouseout": Test.AnotherWay._tab_mouseout },
-		"debug_tab": { "onclick": Test.AnotherWay._tab_onclick, "onmouseover": Test.AnotherWay._tab_mouseover, "onmouseout": Test.AnotherWay._tab_mouseout }
-	};
-	for( var hs in handlers ) {
-		var o=document.getElementById( hs );
-		if( o!=null ) {
-			for( var h in handlers[hs] ) {
-				o[h]=handlers[hs][h];
-			}
-		}else {
-			Test.AnotherWay._show_error( "unable to set "+h+" handler: id "+hs+" not found" );
-		}
-	}
-
-	if( window.opera && !good_opera ) {
-		Test.AnotherWay._g_no_record_msg="Input events recording and replaying is not available in opera versions prior to 8.0.";
-	}
-	if( is_ie ) {
-		Test.AnotherWay._g_no_record_msg="Input events recording and replaying is not available in internet explorer.";
-	}
- 	if( Test.AnotherWay._g_no_record_msg!=null ) {
-		var no_record_p=document.getElementById( "record_not_supported" );
-		no_record_p.style.display="block";
-		no_record_p.appendChild( document.createTextNode( Test.AnotherWay._g_no_record_msg ) );
-	}
-
-	Test.AnotherWay._g_main_loaded=true;
-	if( Test.AnotherWay._g_run_on_main_load ) {
-		Test.AnotherWay._g_run_on_main_load=false;
-		Test.AnotherWay._run_pages_to_run();
-	}
-}
-// -->
-</script>
-<script type="text/javascript" src="xml_eq.js"></script>
-<script type="text/javascript" src="geom_eq.js"></script>
-</head><body>
-
-<div id="col1">
-<div id="col1_header">Test pages:</div>
-<div id="scroller">
-<table id="testtable">
-</table>
-</div>
-<div id="run_buttons">
-<input type="button" value=" clear " id="clear_btn" />
-<input type="button" value=" run all " id="run_all" />
-<input type="button" value=" run selected " id="run_selected" />
-<input type="button" value=" unselect all " id="unselect_all" />
-</div>
-<input type="checkbox" id="dont_close_test_windows" /> do not close windows opened by tests
-<div id="error"></div>
-<div id="record_div">
-<p id="record_not_supported" style="display:none"></p>
-<p>Record mouse input for the page:</p>
-<p><input type="radio" name="record_choose" value="select" checked="checked" /> <select id="record_select"><option selected="selected">-- select a page: --</option></select></p>
-<p><input type="radio" name="record_choose" value="input" /> or enter page url: <input type="text" id="record_input" /></p>
-<p><input type="button" value=" record " id="record_start" /></p>
-</div>
-</div>
-
-<div id="col2">
-<div id="right_header">
-<span id="results_count">Results: <span id="total"></span></span>
-<span id="results_tab" class="active_tab" style="visibility:hidden">Results</span>
-<span id="debug_tab" class="inactive_tab" style="visibility:hidden">Debug</span>
-</div>
-<div id="right_frame">
-<div id="results"></div>
-<div id="debug"></div>
-</div>
-</div>
-
-<span style="display:none">
-<iframe name="list_iframe" onload="Test.AnotherWay._list_iframe_onload();"></iframe>
-<iframe name="test_iframe" onload="Test.AnotherWay._test_page_onload();"></iframe>
-
-<!-- record_control div is to be imported into other documents, so all its styles are inline -->
--<div id="record_control" style="position:absolute;bottom:0;left:0;margin:0;padding:0.5em;width:22em;height:22em;border:1px solid;background:#ffd;font: normal normal 8pt sans-serif; color:#000; text-align: left">
-
-<p style="margin:0 0 0 0; padding:0">
-&nbsp;
-<span style="display:none;font-weight:bold;color:#408" id="record_indicator">
-recording. <span style="font-weight:normal">time: <span id="record_time"></span></span><span id="record_pause_indicator"> paused</span>
-</span>
-</p>
-
-<div id="record_cursor_over" style="margin:0;padding:2px;width:14em;height:1.1em;overflow:hidden;float:right;border:1px solid #777;background:#fff;font: normal normal 8pt sans-serif;position:relative;top:3px;color:#000;text-align:left;">&nbsp;</div>
-<p style="margin:2px 0 0 0; padding:0">
-cursor is over
-</p>
-
-<p style="margin:8px 0 0 0; padding:0;">
- keyboard control: press
- <span id="record_ctrl_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">ctrl</span> -
- <span id="record_shift_key" style="border:1px solid #226;background:#adf;padding:0 0.5em">shift</span> -
-</p>
-
-<p style="margin:4px 0 0 0; padding:0">
-<span id="record_s" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">s</span>
-<span id="record_on">to <b>start</b> recording</span>
-<span id="record_off" style="display:none">to <b>stop</b> recording</span>
-</p>
-
-<p style="margin:4px 0 0 0; padding:0">
-<span id="record_h" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">h</span>
-<span>to <b>hide/show</b> this window</span>
-</p>
-
-<p style="margin:4px 0 0 0; padding:0">
-<span id="record_m" style="border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">m</span>
-<span id="record_include_mousemove">to <b> record</b> mousemove</span>
-<span id="record_omit_mousemove" style="display:none">to <b>omit</b> mousemove</span>
-</p>
-
-<p style="margin:4px 0 0 0; padding:0">
-<span id="record_p" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">p</span>
-<span id="record_pause_on">to <b> pause</b> recording</span>
-<span id="record_pause_off" style="display:none">to <b>continue</b> recording</span>
-</p>
-
-<p style="margin:4px 0 0 0; padding:0">
-<span id="record_c" style="border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em">c</span>
-<span>to add checkpoint</span>
-</p>
-
-<p style="margin:6px 0 0 0; padding:0">
-checkpoints:
-</p>
-<div id="record_checkpoints" style="position:relative;width:100%;height:6em;overflow:auto;font: normal normal 8pt sans-serif; color:#000; text-align: left">
-</div>
-</div>
-
-</span>
-<script>
-    if (/noscroll/.test(location.href)) {
-        document.getElementById('scroller').style.height='auto';
-        document.getElementById('right_frame').style.height='auto';
-    }
-</script>
-</body></html>
+        </script>
+    </body>
+</html>

Deleted: sandbox/august/trunk/tests/xml_eq.js
===================================================================
--- sandbox/august/trunk/tests/xml_eq.js	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tests/xml_eq.js	2011-09-22 17:32:00 UTC (rev 12409)
@@ -1,311 +0,0 @@
-/**
- * File: xml_eq.js
- * Adds a xml_eq method to AnotherWay test objects.
- *
- */
-
-(function() {
-
-    /**
-     * Function: createNode
-     * Given a string, try to create an XML DOM node.  Throws string messages
-     *     on failure.
-     * 
-     * Parameters:
-     * text - {String} An XML string.
-     *
-     * Returns:
-     * {DOMElement} An element node.
-     */
-    function createNode(text) {
-        
-        var index = text.indexOf('<');
-        if(index > 0) {
-            text = text.substring(index);
-        }
-        
-        var doc;
-        if(window.ActiveXObject && !this.xmldom) {
-            doc = new ActiveXObject("Microsoft.XMLDOM");
-            try {
-                doc.loadXML(text);
-            } catch(err) {
-                throw "ActiveXObject loadXML failed: " + err;
-            }
-        } else if(window.DOMParser) {
-            try {
-                doc = new DOMParser().parseFromString(text, 'text/xml');
-            } catch(err) {
-                throw "DOMParser.parseFromString failed";
-            }
-            if(doc.documentElement && doc.documentElement.nodeName == "parsererror") {
-                throw "DOMParser.parseFromString returned parsererror";
-            }
-        } else {
-            var req = new XMLHttpRequest();
-            req.open("GET", "data:text/xml;charset=utf-8," +
-                     encodeURIComponent(text), false);
-            if(req.overrideMimeType) {
-                req.overrideMimeType("text/xml");
-            }
-            req.send(null);
-            doc = req.responseXML;
-        }
-        
-        var root = doc.documentElement;
-        if(!root) {
-            throw "no documentElement";
-        }
-        return root;
-    }
-    
-    /**
-     * Function assertEqual
-     * Test two objects for equivalence (based on ==).  Throw an exception
-     *     if not equivalent.
-     * 
-     * Parameters:
-     * got - {Object}
-     * expected - {Object}
-     * msg - {String} The message to be thrown.  This message will be appended
-     *     with ": got {got} but expected {expected}" where got and expected are
-     *     replaced with string representations of the above arguments.
-     */
-    function assertEqual(got, expected, msg) {
-        if(got === undefined) {
-            got = "undefined";
-        } else if (got === null) {
-            got = "null";
-        }
-        if(expected === undefined) {
-            expected = "undefined";
-        } else if (expected === null) {
-            expected = "null";
-        }
-        if(got != expected) {
-            throw msg + ": got '" + got + "' but expected '" + expected + "'";
-        }
-    }
-    
-    /**
-     * Function assertElementNodesEqual
-     * Test two element nodes for equivalence.  Nodes are considered equivalent
-     *     if they are of the same type, have the same name, have the same
-     *     namespace prefix and uri, and if all child nodes are equivalent.
-     *     Throws a message as exception if not equivalent.
-     * 
-     * Parameters:
-     * got - {DOMElement}
-     * expected - {DOMElement}
-     * options - {Object} Optional object for configuring test options.
-     *
-     * Valid options:
-     * prefix - {Boolean} Compare element and attribute
-     *     prefixes (namespace uri always tested).  Default is false.
-     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
-     *     comparing child nodes.  Default is false.
-     */
-    function assertElementNodesEqual(got, expected, options) {
-        var testPrefix = (options && options.prefix === true);
-        
-        // compare types
-        assertEqual(got.nodeType, expected.nodeType, "Node type mismatch");
-        
-        // compare names
-        var gotName = testPrefix ?
-            got.nodeName : got.nodeName.split(":").pop();
-        var expName = testPrefix ?
-            expected.nodeName : expected.nodeName.split(":").pop();
-        assertEqual(gotName, expName, "Node name mismatch");
-        
-        // for text nodes compare value
-        if(got.nodeType == 3) {
-            assertEqual(
-                got.nodeValue, expected.nodeValue, "Node value mismatch"
-            );
-        }
-        // for element type nodes compare namespace, attributes, and children
-        else if(got.nodeType == 1) {
-            
-            // test namespace alias and uri
-            if(got.prefix || expected.prefix) {
-                if(testPrefix) {
-                    assertEqual(
-                        got.prefix, expected.prefix,
-                        "Bad prefix for " + got.nodeName
-                    );
-                }
-            }
-            if(got.namespaceURI || expected.namespaceURI) {
-                assertEqual(
-                    got.namespaceURI, expected.namespaceURI,
-                    "Bad namespaceURI for " + got.nodeName
-                );
-            }
-            
-            // compare attributes - disregard xmlns given namespace handling above
-            var gotAttrLen = 0;
-            var gotAttr = {};
-            var expAttrLen = 0;
-            var expAttr = {};
-            var ga, ea, gn, en;
-            for(var i=0; i<got.attributes.length; ++i) {
-                ga = got.attributes[i];
-                if(ga.specified === undefined || ga.specified === true) {
-                    if(ga.name.split(":").shift() != "xmlns") {
-                        gn = testPrefix ? ga.name : ga.name.split(":").pop();
-                        gotAttr[gn] = ga;
-                        ++gotAttrLen;
-                    }
-                }
-            }
-            for(var i=0; i<expected.attributes.length; ++i) {
-                ea = expected.attributes[i];
-                if(ea.specified === undefined || ea.specified === true) {
-                    if(ea.name.split(":").shift() != "xmlns") {
-                        en = testPrefix ? ea.name : ea.name.split(":").pop();
-                        expAttr[en] = ea;
-                        ++expAttrLen;
-                    }
-                }
-            }
-            assertEqual(
-                gotAttrLen, expAttrLen,
-                "Attributes length mismatch for " + got.nodeName
-            );
-            var gv, ev;
-            for(var name in gotAttr) {
-                if(expAttr[name] == undefined) {
-                    throw "Attribute name " + gotAttr[name].name + " expected for element " + got.nodeName;
-                }
-                // test attribute namespace
-                assertEqual(
-                    gotAttr[name].namespaceURI, expAttr[name].namespaceURI,
-                    "Attribute namespace mismatch for element " +
-                    got.nodeName + " attribute name " + gotAttr[name].name
-                );
-                // test attribute value
-                assertEqual(
-                    gotAttr[name].value, expAttr[name].value,
-                    "Attribute value mismatch for element " + got.nodeName +
-                    " attribute name " + gotAttr[name].name
-                );
-            }
-            
-            // compare children
-            var gotChildNodes = getChildNodes(got, options);
-            var expChildNodes = getChildNodes(expected, options);
-
-            assertEqual(
-                gotChildNodes.length, expChildNodes.length,
-                "Children length mismatch for " + got.nodeName
-            );
-            for(var j=0; j<gotChildNodes.length; ++j) {
-                try {
-                    assertElementNodesEqual(
-                        gotChildNodes[j], expChildNodes[j], options
-                    );
-                } catch(err) {
-                    throw "Bad child " + j + " for element " + got.nodeName + ": " + err;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Function getChildNodes
-     * Returns the child nodes of the specified nodes. By default this method
-     *     will ignore child text nodes which are made up of whitespace content.
-     *     The 'includeWhiteSpace' option is used to control this behaviour.
-     * 
-     * Parameters:
-     * node - {DOMElement}
-     * options - {Object} Optional object for test configuration.
-     * 
-     * Valid options:
-     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
-     *     comparing child nodes.  Default is false.
-     * 
-     * Returns:
-     * {Array} of {DOMElement}
-     */
-    function getChildNodes(node, options) {
-        //check whitespace
-        if (options && options.includeWhiteSpace) {
-            return node.childNodes;
-        }
-        else {
-           nodes = [];
-           for (var i = 0; i < node.childNodes.length; i++ ) {
-              var child = node.childNodes[i];
-              if (child.nodeType == 1) {
-                 //element node, add it 
-                 nodes.push(child);
-              }
-              else if (child.nodeType == 3) {
-                 //text node, add if non empty
-                 if (child.nodeValue && 
-                       child.nodeValue.replace(/^\s*(.*?)\s*$/, "$1") != "" ) { 
-
-                    nodes.push(child);
-                 }
-              }
-           }
-  
-           return nodes;
-        }
-    } 
-    
-    /**
-     * Function: Test.AnotherWay._test_object_t.xml_eq
-     * Test if two XML nodes are equivalent.  Tests for same node types, same
-     *     node names, same namespace URI, same attributes, and recursively
-     *     tests child nodes for same criteria.
-     *
-     * (code)
-     * t.xml_eq(got, expected, message);
-     * (end)
-     * 
-     * Parameters:
-     * got - {DOMElement | String} A DOM node or XML string to test.
-     * expected - {DOMElement | String} The expected DOM node or XML string.
-     * msg - {String} A message to print with test output.
-     * options - {Object} Optional object for configuring test.
-     *
-     * Valid options:
-     * prefix - {Boolean} Compare element and attribute
-     *     prefixes (namespace uri always tested).  Default is false.
-     * includeWhiteSpace - {Boolean} Include whitespace only nodes when
-     *     comparing child nodes.  Default is false.
-     */
-    var proto = Test.AnotherWay._test_object_t.prototype;
-    proto.xml_eq = function(got, expected, msg, options) {
-        // convert arguments to nodes if string
-        if(typeof got == "string") {
-            try {
-                got = createNode(got);
-            } catch(err) {
-                this.fail(msg + ": got argument could not be converted to an XML node: " + err);
-                return;
-            }
-        }
-        if(typeof expected == "string") {
-            try {
-                expected = createNode(expected);
-            } catch(err) {
-                this.fail(msg + ": expected argument could not be converted to an XML node: " + err);
-                return;
-            }
-        }
-        
-        // test nodes for equivalence
-        try {
-            assertElementNodesEqual(got, expected, options);
-            this.ok(true, msg);
-        } catch(err) {
-            this.fail(msg + ": " + err);
-        }
-    }
-    
-})();

Modified: sandbox/august/trunk/tools/closure.py
===================================================================
--- sandbox/august/trunk/tools/closure.py	2011-09-21 03:16:39 UTC (rev 12408)
+++ sandbox/august/trunk/tools/closure.py	2011-09-22 17:32:00 UTC (rev 12409)
@@ -2,20 +2,21 @@
 import os
 import tempfile
 
-path = os.path.abspath(os.path.join(os.path.dirname(__file__), "closure-compiler.jar"))
+path = "../tools/closure-compiler.jar"
 if not os.path.exists(path):
     raise Exception("No closure-compiler.jar at %s; read README.txt!" % path)
 
 def minimize(code):
-    ntf = tempfile.NamedTemporaryFile()
+    ntf = tempfile.NamedTemporaryFile(delete=False)
     ntf.write(code)
     ntf.flush()
 
-    ntf2 = tempfile.NamedTemporaryFile()
+    ntf2 = tempfile.NamedTemporaryFile(delete=False)
+    ntf.close()
+    ntf2.close()
 
     os.system("java -jar %s --js %s --js_output_file %s" % (path, ntf.name, ntf2.name))
-    ntf2.seek(0)
-    data = ntf2.read()
-    ntf.close()
-    ntf2.close()
+    data = open(ntf2.name).read()
+    os.unlink(ntf.name)
+    os.unlink(ntf2.name)
     return data

Copied: sandbox/august/trunk/tools/git_to_svn.sh (from rev 12408, trunk/openlayers/tools/git_to_svn.sh)
===================================================================
--- sandbox/august/trunk/tools/git_to_svn.sh	                        (rev 0)
+++ sandbox/august/trunk/tools/git_to_svn.sh	2011-09-22 17:32:00 UTC (rev 12409)
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+#
+# This script assumes a local clone of the openlayers github repository. This
+# clone needs to be configured with an svn remote to the openlayers svn. Here
+# are the actual steps to get the clone and configure it properly:
+#
+# $ git clone git at github.com:openlayers/openlayers.git
+# $ git svn init -T trunk/openlayers -t tags/openlayers -b branches/openlayers http://svn.openlayers.org/
+#
+# To run this script change to the local clone first:
+#
+# $ cd openlayers
+# $ git_to_svn.sh
+
+git pull origin master
+git svn rebase
+git svn dcommit



More information about the Commits mailing list