[mapguide-commits] r6647 - in trunk/Tools/Maestro: . Install Maestro.Base/UI MgCooker MgCooker/Properties OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Mapping OSGeo.MapGuide.MaestroAPI/Properties OSGeo.MapGuide.MaestroAPI/Resource/Validation OSGeo.MapGuide.MaestroAPI/Tile Properties RtMapInspector Thirdparty

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon May 14 12:08:26 EDT 2012


Author: jng
Date: 2012-05-14 09:08:26 -0700 (Mon, 14 May 2012)
New Revision: 6647

Added:
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/BatchSettings.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/RenderThread.cs
Removed:
   trunk/Tools/Maestro/MgCooker/BatchSettings.cs
   trunk/Tools/Maestro/MgCooker/RenderThread.cs
Modified:
   trunk/Tools/Maestro/Install/Maestro.nsi
   trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.cs
   trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.resx
   trunk/Tools/Maestro/MgCooker/MgCooker.csproj
   trunk/Tools/Maestro/MgCooker/Program.cs
   trunk/Tools/Maestro/MgCooker/Progress.cs
   trunk/Tools/Maestro/MgCooker/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/MgCooker/Properties/Resources.resx
   trunk/Tools/Maestro/MgCooker/SetupRun.cs
   trunk/Tools/Maestro/MgCooker/SetupRun.designer.cs
   trunk/Tools/Maestro/MgCooker/SetupRun.resx
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMap.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs
   trunk/Tools/Maestro/Properties/GlobalAssemblyInfo.cs
   trunk/Tools/Maestro/RtMapInspector/MainForm.Designer.cs
   trunk/Tools/Maestro/RtMapInspector/MainForm.cs
   trunk/Tools/Maestro/RtMapInspector/MainForm.resx
   trunk/Tools/Maestro/Thirdparty/
   trunk/Tools/Maestro/build.bat
Log:
This submission includes the following changes:
 - Move some MgCooker backend classes into the MaestroAPI project. This is the first phase of refactoring MgCooker to have most of the tile-generation classes inside the MaestroAPI, and MgCooker being a thin UI on top of these classes.
 - Fix MgCooker UI bug where maximum allowed MPU was 10000
 - Add basic selection inspection support to RtMapInspector. Currently it just shows the encoded identity property values of each object in the selection set. Definitely more room for improvement.
 - #1957: Workaround a timeout error in Feature Source validation that triggers a NullReferenceException. This is due to the validator doing a full schema walk, which will probably timeout for really large data stores. This submission catches such timeout errors, flags a validation warning and skips the remaining validation tasks. Will need to re-evaluate whether a full schema walk is necessary for the validation we want to do.
 - Lazy load the Selection property of the RuntimeMap class. Also fix incorrect selection deserialization logic from the selection binary blob
 - Add DockPanel UI link to About dialog.
 - build script and NSIS installer updates for 5.0 beta 1

Modified: trunk/Tools/Maestro/Install/Maestro.nsi
===================================================================
--- trunk/Tools/Maestro/Install/Maestro.nsi	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/Install/Maestro.nsi	2012-05-14 16:08:26 UTC (rev 6647)
@@ -176,10 +176,7 @@
 	SetOutPath $INSTDIR
 	
 	# directories / core addins
-	File /r "${INST_OUTPUT_MAESTRO}\AddIns\ExtendedObjectModels"
-    File /r "${INST_OUTPUT_MAESTRO}\AddIns\FdoToolbox"
-    File /r "${INST_OUTPUT_MAESTRO}\AddIns\Scripting"
-    File "${INST_OUTPUT_MAESTRO}\AddIns\Maestro.Base.addin"
+	File /r "${INST_OUTPUT_MAESTRO}\AddIns"
     File /r "${INST_OUTPUT_MAESTRO}\Data"
     File /r "${INST_OUTPUT_MAESTRO}\Schemas"
     File /r "${INST_OUTPUT_MAESTRO}\UserDoc"
@@ -191,8 +188,12 @@
 	File "${INST_OUTPUT_MAESTRO}\license.txt"
 	
 	# data/config files
+    File "${INST_OUTPUT_MAESTRO}\LocalConfigure.exe.config"
     File "${INST_OUTPUT_MAESTRO}\Maestro.exe.config"
     File "${INST_OUTPUT_MAESTRO}\MaestroFsPreview.exe.config"
+    File "${INST_OUTPUT_MAESTRO}\MgCooker.exe.config"
+    File "${INST_OUTPUT_MAESTRO}\MgCookerCmd.exe.config"
+    File "${INST_OUTPUT_MAESTRO}\RtMapInspector.exe.config"
 	File "${INST_OUTPUT_MAESTRO}\ConnectionProviders.xml"
     File "${INST_OUTPUT_MAESTRO}\FsEditorMap.xml"
     File "${INST_OUTPUT_MAESTRO}\OdbcDriverMap.xml"
@@ -203,27 +204,37 @@
 	File "${INST_OUTPUT_MAESTRO}\ICSharpCode.Core.dll"
 	File "${INST_OUTPUT_MAESTRO}\ICSharpCode.Core.WinForms.dll"
     File "${INST_OUTPUT_MAESTRO}\ICSharpCode.SharpZipLib.dll"
-    File "${INST_OUTPUT_MAESTRO}\MapGuideDotNetApi.dll"
+    File "${INST_OUTPUT_MAESTRO}\IronPython.dll"
+    File "${INST_OUTPUT_MAESTRO}\IronPython.Modules.dll"
 	File "${INST_OUTPUT_MAESTRO}\Maestro.Base.dll"
 	File "${INST_OUTPUT_MAESTRO}\Maestro.Editors.dll"
 	File "${INST_OUTPUT_MAESTRO}\Maestro.Login.dll"
     File "${INST_OUTPUT_MAESTRO}\Maestro.Packaging.dll"
 	File "${INST_OUTPUT_MAESTRO}\Maestro.Shared.UI.dll"
+    File "${INST_OUTPUT_MAESTRO}\Microsoft.Dynamic.dll"
+    File "${INST_OUTPUT_MAESTRO}\Microsoft.Scripting.dll"
+    File "${INST_OUTPUT_MAESTRO}\Microsoft.Scripting.Metadata.dll"
     File "${INST_OUTPUT_MAESTRO}\NetTopologySuite.Merged.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ExtendedObjectModels.dll"
 	File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.dll"
 	File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Http.dll"
-    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Native.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Native32-2.2.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.1.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.2.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.3.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-2.3.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-2.4.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LoadProcedure-1.1.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LoadProcedure-2.2.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.MapDefinition-2.3.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.MapDefinition-2.4.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.SymbolDefinition-1.1.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.SymbolDefinition-2.4.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WatermarkDefinition-2.3.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WatermarkDefinition-2.4.0.dll"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WebLayout-1.1.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WebLayout-2.4.0.dll"
+    File "${INST_OUTPUT_MAESTRO}\WeifenLuo.WinFormsUI.Docking.dll"
     
     # pdbs, we'll leave them in for the beta period duration
     File "${INST_OUTPUT_MAESTRO}\Aga.Controls.pdb"
@@ -238,17 +249,23 @@
 	File "${INST_OUTPUT_MAESTRO}\Maestro.Shared.UI.pdb"
 	File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.pdb"
 	File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Http.pdb"
-    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Native.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.MaestroAPI.Native32-2.2.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.1.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.2.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.3.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-2.3.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LayerDefinition-2.4.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LoadProcedure-1.1.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.LoadProcedure-2.2.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.MapDefinition-2.3.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.MapDefinition-2.4.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.SymbolDefinition-1.1.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.SymbolDefinition-2.4.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WatermarkDefinition-2.3.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WatermarkDefinition-2.4.0.pdb"
     File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WebLayout-1.1.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\OSGeo.MapGuide.ObjectModels.WebLayout-2.4.0.pdb"
+    File "${INST_OUTPUT_MAESTRO}\RtMapInspector.pdb"
 	
 	# main executables
 	File "${INST_OUTPUT_MAESTRO}\${EXE_MAESTRO}"
@@ -256,6 +273,7 @@
 	File "${INST_OUTPUT_MAESTRO}\MgCooker.exe"
     File "${INST_OUTPUT_MAESTRO}\MgCookerCmd.exe"
     File "${INST_OUTPUT_MAESTRO}\MaestroFsPreview.exe"
+    File "${INST_OUTPUT_MAESTRO}\RtMapInspector.exe"
 	
 	# create uninstaller
 	WriteUninstaller "$INSTDIR\uninstall.exe"
@@ -327,15 +345,16 @@
 	!endif
 	
 	!insertmacro MUI_LANGDLL_DISPLAY
-  
-	; Check .NET version
-	ReadRegDWORD $0 HKLM 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727' SP
-	
-	; SP level of 1 or higher is enough
-	${If} $0 < 1
-		MessageBox MB_OK|MB_ICONINFORMATION "${INST_PRODUCT_QUALIFIED} requires that the .net Framework 2.0 SP1 or above is installed. Please download and install the .net Framework 2.0 SP1 or above before installing ${INST_PRODUCT}."
-	    Quit
-	${EndIf}
+
+    ; Check for .NET Framework 4.0
+    ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Install
+    IntOp $8 $0 & 1
+    IntCmp $8 1 done noDotNet done 
+
+    noDotNet: 
+        MessageBox MB_OK|MB_ICONINFORMATION "${INST_PRODUCT_QUALIFIED} requires that the .net Framework 4.0 is installed. Please download and install the .net Framework 4.0 before installing ${INST_PRODUCT}."
+        Quit
+    done:
 FunctionEnd
 
 Function LaunchLink

Modified: trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -106,6 +106,7 @@
             this.Localization = new System.Windows.Forms.Label();
             this.ServerVersion = new System.Windows.Forms.Label();
             this.thirdPartyTab = new System.Windows.Forms.TabPage();
+            this.lnkDockPanel = new System.Windows.Forms.LinkLabel();
             this.lnkAdvTreeView = new System.Windows.Forms.LinkLabel();
             this.linkLabel1 = new System.Windows.Forms.LinkLabel();
             this.lnkSharpDevelop = new System.Windows.Forms.LinkLabel();
@@ -118,7 +119,6 @@
             this.licenseTab = new System.Windows.Forms.TabPage();
             this.License = new System.Windows.Forms.TextBox();
             this.tabControl = new System.Windows.Forms.TabControl();
-            this.lnkDockPanel = new System.Windows.Forms.LinkLabel();
             ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.PayPalImage)).BeginInit();
             this.thirdPartyTab.SuspendLayout();
@@ -183,6 +183,13 @@
             this.thirdPartyTab.Name = "thirdPartyTab";
             this.thirdPartyTab.UseVisualStyleBackColor = true;
             // 
+            // lnkDockPanel
+            // 
+            resources.ApplyResources(this.lnkDockPanel, "lnkDockPanel");
+            this.lnkDockPanel.Name = "lnkDockPanel";
+            this.lnkDockPanel.TabStop = true;
+            this.lnkDockPanel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkDockPanel_LinkClicked);
+            // 
             // lnkAdvTreeView
             // 
             resources.ApplyResources(this.lnkAdvTreeView, "lnkAdvTreeView");
@@ -267,13 +274,6 @@
             this.tabControl.Name = "tabControl";
             this.tabControl.SelectedIndex = 0;
             // 
-            // lnkDockPanel
-            // 
-            resources.ApplyResources(this.lnkDockPanel, "lnkDockPanel");
-            this.lnkDockPanel.Name = "lnkDockPanel";
-            this.lnkDockPanel.TabStop = true;
-            this.lnkDockPanel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkDockPanel_LinkClicked);
-            // 
             // AboutDialog
             // 
             resources.ApplyResources(this, "$this");

Modified: trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.resx	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/Maestro.Base/UI/AboutDialog.resx	2012-05-14 16:08:26 UTC (rev 6647)
@@ -1329,7 +1329,7 @@
     <value>84, 23</value>
   </data>
   <data name="colorBrewerlinkLabel.Location" type="System.Drawing.Point, System.Drawing">
-    <value>11, 172</value>
+    <value>8, 193</value>
   </data>
   <data name="colorBrewerlinkLabel.Size" type="System.Drawing.Size, System.Drawing">
     <value>304, 32</value>

Deleted: trunk/Tools/Maestro/MgCooker/BatchSettings.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/BatchSettings.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/BatchSettings.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -1,712 +0,0 @@
-#region Disclaimer / License
-// Copyright (C) 2009, Kenneth Skovhede
-// http://www.hexad.dk, opensource at hexad.dk
-// 
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// 
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-// 
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-// 
-#endregion
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OSGeo.MapGuide.MaestroAPI;
-using OSGeo.MapGuide.ObjectModels.MapDefinition;
-using OSGeo.MapGuide.ObjectModels.Common;
-
-namespace MgCooker
-{
-    /// <summary>
-    /// This delegate is used to monitor progress on tile rendering
-    /// </summary>
-    /// <param name="map">The map currently being processed</param>
-    /// <param name="group">The group being processed</param>
-    /// <param name="scaleindex">The scaleindex being processed</param>
-    /// <param name="row">The row being processed</param>
-    /// <param name="column">The column being processed</param>
-    /// <param name="cancel">A control flag to stop the tile rendering</param>
-    /// <param name="state">The state that invoked the callback</param>
-    public delegate void ProgressCallback(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel);
-
-    /// <summary>
-    /// This delegate is used to monitor progress on tile rendering
-    /// </summary>
-    /// <param name="map">The map currently being processed</param>
-    /// <param name="group">The group being processed</param>
-    /// <param name="scaleindex">The scaleindex being processed</param>
-    /// <param name="row">The row being processed</param>
-    /// <param name="column">The column being processed</param>
-    /// <param name="state">The state that invoked the callback</param>
-    /// <param name="exception">The exception from the last attempt, set this to null to ignore the exception</param>
-    public delegate void ErrorCallback(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref Exception exception);
-
-    /// <summary>
-    /// These are the avalible states for callbacks
-    /// </summary>
-    public enum CallbackStates
-    {
-        /// <summary>
-        /// All maps are being rendered
-        /// </summary>
-        StartRenderAllMaps,
-        /// <summary>
-        /// A map is being rendered
-        /// </summary>
-        StartRenderMap,
-        /// <summary>
-        /// A group is being rendered
-        /// </summary>
-        StartRenderGroup,
-        /// <summary>
-        /// A scale is being rendered
-        /// </summary>
-        StartRenderScale,
-        /// <summary>
-        /// A tile is being rendered
-        /// </summary>
-        StartRenderTile,
-        /// <summary>
-        /// A tile has been rendered
-        /// </summary>
-        FinishRenderTile,
-        /// <summary>
-        /// A scale has been rendered
-        /// </summary>
-        FinishRenderScale,
-        /// <summary>
-        /// A group has been rendered
-        /// </summary>
-        FinishRenderGroup,
-        /// <summary>
-        /// A map has been rendered
-        /// </summary>
-        FinishRenderMap,
-        /// <summary>
-        /// All maps have been rendered
-        /// </summary>
-        FinishRenderAllMaps,
-        /// <summary>
-        /// A tile has failed to render
-        /// </summary>
-        FailedRenderingTile,
-    }
-
-    /// <summary>
-    /// Class to hold settings for a batch run of tile building
-    /// </summary>
-    public class BatchSettings
-    {
-        /// <summary>
-        /// A reference to the connection
-        /// </summary>
-        private IServerConnection m_connection;
-        /// <summary>
-        /// The list of maps
-        /// </summary>
-        private List<BatchMap> m_maps;
-        /// <summary>
-        /// A default set of tile settings
-        /// </summary>
-        private TileSettings m_tileSettings = new TileSettings();
-
-        /// <summary>
-        /// A flag that indicates the rendering should stop
-        /// </summary>
-        private bool m_cancel;
-
-        /// <summary>
-        /// An event that can be used to pause MgCooker
-        /// </summary>
-        public System.Threading.ManualResetEvent PauseEvent = new System.Threading.ManualResetEvent(true);
-
-        #region Events
-        /// <summary>
-        /// All maps are being rendered
-        /// </summary>
-        public event ProgressCallback BeginRenderingMaps;
-        /// <summary>
-        /// A map is being rendered
-        /// </summary>
-        public event ProgressCallback BeginRenderingMap;
-        /// <summary>
-        /// A group is being rendered
-        /// </summary>
-        public event ProgressCallback BeginRenderingGroup;
-        /// <summary>
-        /// A scale is being rendered
-        /// </summary>
-        public event ProgressCallback BeginRenderingScale;
-        /// <summary>
-        /// A tile is being rendered
-        /// </summary>
-        public event ProgressCallback BeginRenderingTile;
-        /// <summary>
-        /// All maps have been rendered
-        /// </summary>
-        public event ProgressCallback FinishRenderingMaps;
-        /// <summary>
-        /// A map has been rendered
-        /// </summary>
-        public event ProgressCallback FinishRenderingMap;
-        /// <summary>
-        /// A group has been rendered
-        /// </summary>
-        public event ProgressCallback FinishRenderingGroup;
-        /// <summary>
-        /// A scale has been rendered
-        /// </summary>
-        public event ProgressCallback FinishRenderingScale;
-        /// <summary>
-        /// A tile has been rendered
-        /// </summary>
-        public event ProgressCallback FinishRenderingTile;
-        /// <summary>
-        /// A tile has failed to render
-        /// </summary>
-        public event ErrorCallback FailedRenderingTile;
-
-        internal void InvokeBeginRendering(BatchMap batchMap)
-        {
-            if (this.BeginRenderingMap != null)
-                this.BeginRenderingMap(CallbackStates.StartRenderMap, batchMap, null, -1, -1, -1, ref m_cancel);
-            PauseEvent.WaitOne();
-        }
-
-        internal void InvokeFinishRendering(BatchMap batchMap)
-        {
-            if (this.FinishRenderingMap != null)
-                this.FinishRenderingMap(CallbackStates.FinishRenderMap, batchMap, null, -1, -1, -1, ref m_cancel);
-        }
-
-        internal void InvokeBeginRendering(BatchMap batchMap, string group)
-        {
-            if (this.BeginRenderingGroup != null)
-                this.BeginRenderingGroup(CallbackStates.StartRenderGroup, batchMap, group, -1, -1, -1, ref m_cancel);
-            PauseEvent.WaitOne();
-        }
-
-        internal void InvokeFinishRendering(BatchMap batchMap, string group)
-        {
-            if (this.FinishRenderingGroup != null)
-                this.FinishRenderingGroup(CallbackStates.FinishRenderGroup, batchMap, group, -1, -1, -1, ref m_cancel);
-        }
-
-        internal void InvokeBeginRendering(BatchMap batchMap, string group, int scaleindex)
-        {
-            if (this.BeginRenderingScale != null)
-                this.BeginRenderingScale(CallbackStates.StartRenderScale, batchMap, group, scaleindex, -1, -1, ref m_cancel);
-            PauseEvent.WaitOne();
-        }
-
-        internal void InvokeFinishRendering(BatchMap batchMap, string group, int scaleindex)
-        {
-            if (this.FinishRenderingScale != null)
-                this.FinishRenderingScale(CallbackStates.FinishRenderScale, batchMap, group, scaleindex, -1, -1, ref m_cancel);
-        }
-
-        internal void InvokeBeginRendering(BatchMap batchMap, string group, int scaleindex, int row, int col)
-        {
-            if (this.BeginRenderingTile != null)
-                this.BeginRenderingTile(CallbackStates.StartRenderTile, batchMap, group, scaleindex, row, col, ref m_cancel);
-            PauseEvent.WaitOne();
-        }
-
-        internal void InvokeFinishRendering(BatchMap batchMap, string group, int scaleindex, int row, int col)
-        {
-            if (this.FinishRenderingTile != null)
-                this.FinishRenderingTile(CallbackStates.FinishRenderTile, batchMap, group, scaleindex, row, col, ref m_cancel);
-        }
-
-        internal Exception InvokeError(BatchMap batchMap, string group, int scaleindex, int row, int col, ref Exception exception)
-        {
-            if (this.FailedRenderingTile != null)
-                this.FailedRenderingTile(CallbackStates.FailedRenderingTile, batchMap, group, scaleindex, row, col, ref exception);
-
-            return exception;
-        }
-
-        #endregion
-
-        /// <summary>
-        /// Constructs a new batch setup. If no maps are supplied, all maps in the repository is assumed.
-        /// </summary>
-        /// <param name="mapagent">The url to the mapagent.fcgi</param>
-        /// <param name="username">The username to connect with</param>
-        /// <param name="password">The password to connect with</param>
-        /// <param name="maps">A list of maps to process, leave empty to process all layers</param>
-        public BatchSettings(string mapagent, string username, string password, params string[] maps)
-            : this(ConnectionProviderRegistry.CreateConnection("Maestro.Http", "Url", mapagent, "Username", username, "Password", password, "AllowUntestedVersions", "true"), maps)
-        {
-        }
-
-        public BatchSettings(IServerConnection connection)
-        {
-            m_connection = connection;
-            m_maps = new List<BatchMap>();
-        }
-
-        public BatchSettings(IServerConnection connection, params string[] maps)
-        {
-            m_connection = connection;
-            m_maps = new List<BatchMap>();
-
-            if (maps == null || maps.Length == 0 || (maps.Length == 1 && maps[0].Trim().Length == 0))
-            {
-                List<string> tmp = new List<string>();
-                foreach (var doc in m_connection.ResourceService.GetRepositoryResources("Library://", "MapDefinition").Children)
-                    tmp.Add(doc.ResourceId);
-                maps = tmp.ToArray();
-            }
-
-            foreach (string s in maps)
-            {
-                BatchMap bm = new BatchMap(this, s);
-                if (bm.Resolutions > 0)
-                    m_maps.Add(bm);
-            }
-        }
-
-        public void SetScales(int[] scaleindexes)
-        {
-            foreach (BatchMap bm in m_maps)
-                bm.SetScales(scaleindexes);
-        }
-
-        public void SetGroups(string[] groups)
-        {
-            foreach (BatchMap bm in m_maps)
-                bm.SetGroups(groups);
-        }
-
-        public void LimitRows(long limit)
-        {
-            foreach (BatchMap bm in m_maps)
-                bm.LimitRows(limit);
-        }
-
-        public void LimitCols(long limit)
-        {
-            foreach (BatchMap bm in m_maps)
-                bm.LimitCols(limit);
-        }
-
-        /// <summary>
-        /// Renders all tiles in all maps
-        /// </summary>
-        public void RenderAll()
-        {
-            m_cancel = false;
-
-            if (this.BeginRenderingMaps != null)
-                this.BeginRenderingMaps(CallbackStates.StartRenderAllMaps, null, null, -1, -1, -1, ref m_cancel);
-
-            foreach (BatchMap bm in this.Maps)
-                if (m_cancel)
-                    break;
-                else
-                    bm.Render();
-
-            if (this.FinishRenderingMaps != null)
-                this.FinishRenderingMaps(CallbackStates.FinishRenderAllMaps, null, null, -1, -1, -1, ref m_cancel);
-        }
-
-        /// <summary>
-        /// The connection to the server
-        /// </summary>
-        public IServerConnection Connection { get { return m_connection; } }
-        /// <summary>
-        /// The list of maps to proccess
-        /// </summary>
-        public List<BatchMap> Maps { get { return m_maps; } }
-
-        /// <summary>
-        /// The tile settings
-        /// </summary>
-        public TileSettings Config { get { return m_tileSettings; } }
-
-        /// <summary>
-        /// Gets a flag indicating if the rendering process is cancelled
-        /// </summary>
-        public bool Cancel { get { return m_cancel; } }
-    }
-
-    /// <summary>
-    /// Class that represents a single map to build tiles for
-    /// </summary>
-    public class BatchMap
-    {
-        /// <summary>
-        /// A reference to the parent, and thus the connection
-        /// </summary>
-        private BatchSettings m_parent;
-        /// <summary>
-        /// The map read from MapGuide
-        /// </summary>
-        private IMapDefinition m_mapdefinition;
-
-        /// <summary>
-        /// The max extent of the map
-        /// </summary>
-        private IEnvelope m_maxExtent;
-
-        /// <summary>
-        /// The list of baselayer group names
-        /// </summary>
-        private string[] m_groups;
-
-        /// <summary>
-        /// For each entry there is two longs, row and column
-        /// </summary>
-        private long[][] m_dimensions;
-
-        /// <summary>
-        /// The max scale for the map
-        /// </summary>
-        private double m_maxscale;
-
-        /// <summary>
-        /// Conversion from supplied scaleindex to actual scaleindex
-        /// </summary>
-        private int[] m_scaleindexmap;
-
-        /// <summary>
-        /// The number of meters in an inch
-        /// </summary>
-        private const double INCH_TO_METER = 0.0254;
-
-        /// <summary>
-        /// Gets the list of groups
-        /// </summary>
-        public string[] Groups { get { return m_groups; } }
-
-        /// <summary>
-        /// The number of tiles to offset the row counter with
-        /// </summary>
-        private int m_rowTileOffset = 0;
-
-        /// <summary>
-        /// The number of tiles to offset the col counter with
-        /// </summary>
-        private int m_colTileOffset = 0;
-
-        /// <summary>
-        /// The tile offset for row indexes for tiles
-        /// </summary>
-        public int RowTileOffset { get { return m_rowTileOffset; } }
-
-        /// <summary>
-        /// The tile offset for col indexes for tiles
-        /// </summary>
-        public int ColTileOffset { get { return m_colTileOffset; } }
-
-        //The map's scales may have been modified, this array is a map of the new values
-        public int[] ScaleIndexMap { get { return m_scaleindexmap; } }
-
-        /// <summary>
-        /// Constructs a new map to be processed
-        /// </summary>
-        /// <param name="parent">The parent entry</param>
-        /// <param name="map">The resource id for the mapdefinition</param>
-        public BatchMap(BatchSettings parent, string map)
-        {
-            m_parent = parent;
-            m_mapdefinition = (IMapDefinition)parent.Connection.ResourceService.GetResource(map);
-            var baseMap = m_mapdefinition.BaseMap;
-
-            if (baseMap != null &&
-                baseMap.ScaleCount > 0)
-            {
-                m_groups = new string[baseMap.GroupCount];
-                for (int i = 0; i < baseMap.GroupCount; i++)
-                    m_groups[i] = baseMap.GetGroupAt(i).Name;
-
-                m_maxscale = baseMap.GetMaxScale();
-                CalculateDimensions();
-            }
-        }
-
-        public void CalculateDimensions()
-        {
-            int[] tmp = new int[this.Map.BaseMap.ScaleCount];
-            for (int i = 0; i < tmp.Length; i++)
-                tmp[i] = i;
-
-            SetScales(tmp);
-        }
-
-        public void CalculateDimensionsInternal()
-        {
-            if (m_mapdefinition.BaseMap.ScaleCount == 0)
-            {
-                m_scaleindexmap = new int[0];
-                m_dimensions = new long[0][];
-                return;
-            }
-
-            IEnvelope extents = this.MaxExtent ?? m_mapdefinition.Extents;
-            double maxscale = m_maxscale;
-
-            m_dimensions = new long[this.Resolutions][];
-            m_scaleindexmap = new int[m_dimensions.Length];
-            
-            double width_in_meters = Math.Abs(m_parent.Config.MetersPerUnit * (extents.MaxX - extents.MinX));
-            double height_in_meters = Math.Abs(m_parent.Config.MetersPerUnit * (extents.MaxY - extents.MinY));
-
-            m_dimensions = new long[this.Resolutions][];
-            for (int i = this.Resolutions - 1; i >= 0; i--)
-            {
-                long rows, cols;
-                double scale = m_mapdefinition.BaseMap.GetScaleAt(i);
-
-                if (m_parent.Config.UseOfficialMethod)
-                {
-                    //This is the algorithm proposed by the MapGuide team:
-                    //http://www.nabble.com/Pre-Genererate--tiles-for-the-entire-map-at-all-pre-defined-zoom-scales-to6074037.html#a6078663
-                    
-                    //The tile extent in meters
-                    double tileWidth  =((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileWidth) * (scale));
-                    double tileHeight = ((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileHeight) * (scale));
-
-                    //Using this algorithm, yields a negative number of columns/rows, if the max scale is larger than the max extent of the map.
-                    rows = Math.Max(1, (int)Math.Ceiling((height_in_meters / tileHeight)));
-                    cols = Math.Max(1, (int)Math.Ceiling((width_in_meters / tileWidth)));
-
-                    if (m_maxExtent != null)
-                    {
-                        //The extent is overridden, so we need to adjust the start offsets
-                        double offsetX = MaxExtent.MinX - m_mapdefinition.Extents.MinX;
-                        double offsetY = MaxExtent.MinY - m_mapdefinition.Extents.MinY;
-                        m_rowTileOffset = (int)Math.Ceiling(offsetY / tileHeight);
-                        m_colTileOffset = (int)Math.Ceiling(offsetX / tileWidth);
-                    }
-                }
-                else
-                {
-                    //This method assumes that the max scale is displayed on a screen with resolution 1920x1280.
-                    //This display width/height is then multiplied up to calculate the pixelwidth of all subsequent
-                    //scale ranges. Eg. if max scale range is 1:200, then scale range 1:100 is twice the size,
-                    //meaning the full map at 1:100 fills 3840x2560 pixels.
-                    //The width/height is then used to calculate the number of rows and columns of 300x300 pixel tiles.
-                    
-                    //The purpose of this method is to enabled tile generation without access to
-                    //coordinate system properties
-
-                    long pw = (long)(m_parent.Config.DisplayResolutionWidth * (1 / (scale / maxscale)));
-                    long ph = (long)(m_parent.Config.DisplayResolutionHeight * (1 / (scale / maxscale)));
-
-                    rows = (ph + (m_parent.Config.TileHeight - 1)) / m_parent.Config.TileHeight;
-                    cols = (pw + (m_parent.Config.TileWidth - 1)) / m_parent.Config.TileWidth;
-                    rows += rows % 2;
-                    cols += cols % 2;
-                }
-
-
-                m_dimensions[i] = new long[] {rows, cols};
-            }
-        }
-
-        public void SetGroups(string[] groups)
-        {
-            List<string> g = new List<string>();
-            for(int i = 0; i < m_groups.Length; i++)
-                if (Array.IndexOf<string>(groups, m_groups[i]) >= 0)
-                    g.Add(m_groups[i]);
-
-            m_groups = g.ToArray();
-        }
-
-        public void SetScales(int[] scaleindexes)
-        {
-            //TODO: Re-read scales from mapdef?
-            SortedList<int, int> s = new SortedList<int, int>();
-            foreach (int i in scaleindexes)
-                if (!s.ContainsKey(i))
-                    s.Add(i, i);
-
-            List<int> keys = new List<int>(s.Keys);
-            keys.Reverse();
-
-            for (int i = m_mapdefinition.BaseMap.ScaleCount - 1; i >= 0; i--)
-                if (!keys.Contains(i))
-                    m_mapdefinition.BaseMap.RemoveScaleAt(i);
-
-            CalculateDimensionsInternal();
-
-            keys.Reverse();
-
-            //Preserve the original scales
-            m_scaleindexmap = new int[keys.Count];
-            for (int i = 0; i < keys.Count; i++)
-                m_scaleindexmap[i] = keys[i];
-        }
-
-        public void LimitCols(long limit)
-        {
-            foreach (long[] d in m_dimensions)
-                d[1] = Math.Min(limit, d[1]);
-        }
-
-        public void LimitRows(long limit)
-        {
-            foreach (long[] d in m_dimensions)
-                d[0] = Math.Min(limit, d[0]);
-        }
-
-        public long TotalTiles
-        {
-            get
-            {
-                long t = 0;
-                foreach (long[] d in m_dimensions)
-                    t += d[0] * d[1];
-                return t;
-            }
-        }
-
-        /// <summary>
-        /// Gets the number of resolutions for the map
-        /// </summary>
-        public int Resolutions
-        {
-            get
-            {
-                if (m_mapdefinition.BaseMap == null || m_mapdefinition.BaseMap.ScaleCount == 0)
-                    return 0;
-                else
-                    return m_mapdefinition.BaseMap.ScaleCount;
-            }
-        }
-
-
-        /// <summary>
-        /// Renders all tiles in a given scale
-        /// </summary>
-        /// <param name="scaleindex">The scale to render</param>
-        /// <param name="group">The name of the baselayer group</param>
-        public void RenderScale(int scaleindex, string group)
-        {
-            m_parent.InvokeBeginRendering(this, group, scaleindex);
-
-            if (!m_parent.Cancel)
-            {
-                int rows = (int)m_dimensions[scaleindex][0];
-                int cols = (int)m_dimensions[scaleindex][1];
-
-                //If the MaxExtents are different from the actual bounds, we need a start offset offset
-
-                RenderThreads settings = new RenderThreads(this, m_parent, m_scaleindexmap[scaleindex], group, m_mapdefinition.ResourceID, rows, cols, m_rowTileOffset, m_colTileOffset, m_parent.Config.RandomizeTileSequence);
-                
-                settings.RunAndWait();
-
-                if (settings.TileSet.Count != 0 && !m_parent.Cancel)
-                    throw new Exception(Properties.Resources.ThreadFailureError);
-            }
-
-            m_parent.InvokeFinishRendering(this, group, scaleindex);
-
-        }
-
-
-        /// <summary>
-        /// Renders all tiles in all scales
-        /// </summary>
-        /// <param name="group">The name of the baselayer group</param>
-        public void RenderGroup(string group)
-        {
-            m_parent.InvokeBeginRendering(this, group);
-
-            if (!m_parent.Cancel)
-            {
-
-                for (int i = this.Resolutions - 1; i >= 0; i--)
-                    if (m_parent.Cancel)
-                        break;
-                    else
-                        RenderScale(i, group);
-            }
-
-            m_parent.InvokeFinishRendering(this, group);
-
-        }
-
-        /// <summary>
-        /// Renders all tiles in all groups in all scales
-        /// </summary>
-        public void Render()
-        {
-            m_parent.InvokeBeginRendering(this);
-
-            if (!m_parent.Cancel)
-                foreach (string s in m_groups)
-                    if (m_parent.Cancel)
-                        break;
-                    else
-                        RenderGroup(s);
-
-            m_parent.InvokeFinishRendering(this);
-        }
-
-        /// <summary>
-        /// Gets or sets the maximum extent used to calculate the tiles
-        /// </summary>
-        public IEnvelope MaxExtent
-        {
-            get
-            {
-                return m_maxExtent;
-            }
-            set
-            {
-                m_maxExtent = value;
-                CalculateDimensions();
-            }
-        }
-
-        /// <summary>
-        /// Gets the resourceId for the map
-        /// </summary>
-        public string ResourceId { get { return m_mapdefinition.ResourceID; } }
-
-        /// <summary>
-        /// Gets the MapDefintion
-        /// </summary>
-        public IMapDefinition Map { get { return m_mapdefinition; } }
-
-        /// <summary>
-        /// Gets a reference to the parent
-        /// </summary>
-        public BatchSettings Parent { get { return m_parent; } }
-    }
-
-    public class TileSettings
-    {
-        public double MetersPerUnit = 1;
-        public double DPI = 96;
-        public int TileWidth = 300;
-        public int TileHeight = 300;
-        public int RetryCount = 5;
-        public int DisplayResolutionWidth = 1920;
-        public int DisplayResolutionHeight = 1280;
-        public bool UseOfficialMethod = false;
-        public bool RandomizeTileSequence = false;
-        private int m_threadCount = 1;
-        public int ThreadCount
-        {
-            get { return m_threadCount; }
-            set { m_threadCount = Math.Max(1, value); }
-        }
-
-        public RenderMethodDelegate RenderMethod;
-        public delegate void RenderMethodDelegate(string map, string group, int col, int row, int scale);
-    }
-}

Modified: trunk/Tools/Maestro/MgCooker/MgCooker.csproj
===================================================================
--- trunk/Tools/Maestro/MgCooker/MgCooker.csproj	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/MgCooker.csproj	2012-05-14 16:08:26 UTC (rev 6647)
@@ -72,7 +72,6 @@
     <Compile Include="..\Properties\GlobalAssemblyInfo.cs">
       <Link>GlobalAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="BatchSettings.cs" />
     <Compile Include="CommandLineParser.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Progress.cs">
@@ -108,7 +107,6 @@
       <DependentUpon>Settings.settings</DependentUpon>
       <DesignTimeSharedInput>True</DesignTimeSharedInput>
     </Compile>
-    <Compile Include="RenderThread.cs" />
     <Compile Include="SetupRun.cs">
       <SubType>Form</SubType>
     </Compile>

Modified: trunk/Tools/Maestro/MgCooker/Program.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/Program.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/Program.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -27,6 +27,7 @@
 using System.Collections.Specialized;
 using OSGeo.MapGuide.ObjectModels;
 using OSGeo.MapGuide.ExtendedObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Tile;
 
 namespace MgCooker
 {

Modified: trunk/Tools/Maestro/MgCooker/Progress.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/Progress.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/Progress.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -24,6 +24,7 @@
 using System.Drawing;
 using System.Text;
 using System.Windows.Forms;
+using OSGeo.MapGuide.MaestroAPI.Tile;
 
 namespace MgCooker
 {

Modified: trunk/Tools/Maestro/MgCooker/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/Properties/Resources.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/Properties/Resources.Designer.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.239
+//     Runtime Version:4.0.30319.225
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -297,15 +297,6 @@
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to All threads crashed, and the tile set was only partially created.
-        /// </summary>
-        internal static string ThreadFailureError {
-            get {
-                return ResourceManager.GetString("ThreadFailureError", resourceCulture);
-            }
-        }
-        
-        /// <summary>
         ///   Looks up a localized string similar to ({0} failed tiles).
         /// </summary>
         internal static string TileErrorCount {

Modified: trunk/Tools/Maestro/MgCooker/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/MgCooker/Properties/Resources.resx	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/Properties/Resources.resx	2012-05-14 16:08:26 UTC (rev 6647)
@@ -112,10 +112,10 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <data name="AlreadyAborting" xml:space="preserve">
     <value>I heard you the first time!
@@ -223,10 +223,6 @@
     <value>{0}, remaining time: {1}</value>
     <comment>Label that displays the remaining time</comment>
   </data>
-  <data name="ThreadFailureError" xml:space="preserve">
-    <value>All threads crashed, and the tile set was only partially created</value>
-    <comment>An error message that displays if the render threads crash</comment>
-  </data>
   <data name="TileErrorCount" xml:space="preserve">
     <value>({0} failed tiles)</value>
     <comment>Text inserted in the CurrentTileCounter if any tiles are failed</comment>

Deleted: trunk/Tools/Maestro/MgCooker/RenderThread.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/RenderThread.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/RenderThread.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -1,374 +0,0 @@
-#region Disclaimer / License
-// Copyright (C) 2009, Kenneth Skovhede
-// http://www.hexad.dk, opensource at hexad.dk
-// 
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// 
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-// 
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-// 
-#endregion
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OSGeo.MapGuide.MaestroAPI;
-using OSGeo.MapGuide.MaestroAPI.Services;
-
-namespace MgCooker
-{
-    public class RenderThreads
-    {
-        private class EventPassing
-        {
-            public enum EventType
-            {
-                Begin,
-                Finish,
-                Error
-            }
-
-            public EventType Type;
-            public int Col;
-            public int Row;
-            public Exception Exception;
-            public System.Threading.EventWaitHandle Event;
-            public object Result = null;
-
-            public EventPassing(EventType type, int row, int col, Exception ex, System.Threading.EventWaitHandle @event)
-            {
-                this.Type = type;
-                this.Event = @event;
-                this.Col = col;
-                this.Row = row;
-                this.Exception = ex;
-            }
-        }
-
-        public Queue<KeyValuePair<int, int>> TileSet;
-        private Queue<EventPassing> RaiseEvents = new Queue<EventPassing>();
-        private object SyncLock;
-        private System.Threading.AutoResetEvent Event;
-        private int CompleteFlag;
-        private BatchSettings Parent;
-        private int Scale;
-        private string Group;
-        private string MapDefinition;
-        private BatchMap Invoker;
-
-        private bool Randomize;
-        private int Rows;
-        private int Cols;
-        private int RowOffset;
-        private int ColOffset;
-
-        private bool FillerComplete = false;
-
-        public RenderThreads(BatchMap invoker, BatchSettings parent, int scale, string group, string mapdef, int rows, int cols, int rowOffset, int colOffset, bool randomize)
-        {
-            TileSet = new Queue<KeyValuePair<int, int>>();
-            SyncLock = new object();
-            Event = new System.Threading.AutoResetEvent(false);
-            CompleteFlag = parent.Config.ThreadCount;
-            RaiseEvents = new Queue<EventPassing>();
-            this.Scale = scale;
-            this.Group = group;
-            this.Parent = parent;
-            this.MapDefinition = mapdef;
-            this.Invoker = invoker;
-            Randomize = randomize;
-            Rows = rows;
-            Cols = cols;
-            this.RowOffset = rowOffset;
-            this.ColOffset = colOffset;
-        }
-
-        public void RunAndWait()
-        {
-            System.Threading.ThreadPool.QueueUserWorkItem(
-                new System.Threading.WaitCallback(QueueFiller));
-
-            for (int i = 0; i < Parent.Config.ThreadCount; i++)
-            {
-                System.Threading.ThreadPool.QueueUserWorkItem(
-                    new System.Threading.WaitCallback(ThreadRender));
-            }
-
-            bool completed = false;
-            while (!completed)
-            {
-                EventPassing eventToRaise = null;
-                while(true)
-                {
-                    lock (SyncLock)
-                        if (RaiseEvents.Count > 0)
-                            eventToRaise = RaiseEvents.Dequeue();
-
-                    if (eventToRaise == null)
-                    {
-                        //No more events
-                        break;
-                    }
-                    else
-                    {
-                        switch (eventToRaise.Type)
-                        {
-                            case EventPassing.EventType.Begin:
-                                Parent.InvokeBeginRendering(
-                                    Invoker,
-                                    Group,
-                                    Scale,
-                                    eventToRaise.Row,
-                                    eventToRaise.Col);
-                                break;
-                            case EventPassing.EventType.Finish:
-                                Parent.InvokeFinishRendering(
-                                    Invoker,
-                                    Group,
-                                    Scale,
-                                    eventToRaise.Row,
-                                    eventToRaise.Col);
-                                break;
-                            case EventPassing.EventType.Error:
-                                eventToRaise.Result = Parent.InvokeError(
-                                    Invoker,
-                                    Group,
-                                    Scale,
-                                    eventToRaise.Row,
-                                    eventToRaise.Col,
-                                    ref eventToRaise.Exception);
-                                break;
-                            default: 
-                                throw new Exception("Bad event type"); //Not translated, because it is an internal error that should never happen
-                        }
-                        eventToRaise.Event.Set();
-                        eventToRaise = null;
-                    }
-                }
-
-                lock (SyncLock)
-                    if (CompleteFlag == 0 && RaiseEvents.Count == 0)
-                        completed = true;
-
-                if (!completed)
-                    Event.WaitOne(5 * 1000, true);
-            }
-        }
-
-        /// <summary>
-        /// Helper that fills the queue from a thread
-        /// </summary>
-        /// <param name="dummy">Unused parameter</param>
-        private void QueueFiller(object dummy)
-        {
-            try
-            {
-                if (Randomize)
-                {
-                    Random ra = new Random();
-                    List<int> rows = new List<int>();
-                    int[] cols_full = new int[Cols];
-                    for (int i = 0; i < Rows; i++)
-                        rows.Add(i);
-
-                    for (int i = 0; i < Cols; i++)
-                        cols_full[i] = i;
-
-                    //TODO: This is not really random, because we select
-                    //a row, and then random columns
-
-                    //Unfortunately, I have yet to find a truly random
-                    //pair generation method that is space efficient :(
-
-                    while (rows.Count > 0)
-                    {
-                        int ri = ra.Next(0, rows.Count);
-                        int r = rows[ri];
-                        rows.RemoveAt(ri);
-
-                        List<int> cols = new List<int>(cols_full);
-
-                        while (cols.Count > 0)
-                        {
-                            int ci = ra.Next(0, cols.Count);
-                            int c = cols[ci];
-                            cols.RemoveAt(ci);
-
-                            AddPairToQueue(r + RowOffset, c + ColOffset);
-                        }
-                    }
-                }
-                else
-                {
-                    //Non-random is straightforward
-                    for (int r = 0; r < Rows; r++)
-                        for (int c = 0; c < Cols; c++)
-                            AddPairToQueue(r + RowOffset, c + ColOffset);
-                }
-            }
-            finally
-            {
-                lock(SyncLock)
-                    FillerComplete = true;
-            }
-
-        }
-
-        /// <summary>
-        /// Helper to add a pair to the queue, but prevents huge queue lists
-        /// </summary>
-        /// <param name="r">The row component of the pair</param>
-        /// <param name="c">The column component of the pair</param>
-        private void AddPairToQueue(int r, int c)
-        {
-            bool added = false;
-            while (!added)
-            {
-                lock (SyncLock)
-                    if (TileSet.Count < 500) //Keep at most 500 items in queue
-                    {
-                        TileSet.Enqueue(new KeyValuePair<int, int>(r, c));
-                        added = true;
-                    }
-
-                if (!added) //Prevent CPU spinning
-                    System.Threading.Thread.Sleep(500);
-            }
-        }
-
-        /// <summary>
-        /// Invokes the render callback method
-        /// </summary>
-        /// <param name="dummy">Unused parameter</param>
-        private void ThreadRender(object dummy)
-        {
-            try
-            {
-                //Create a copy of the connection for local usage
-                IServerConnection con = Parent.Connection.Clone();
-                var tileSvc = (ITileService)con.GetService((int)ServiceType.Tile);
-                System.Threading.AutoResetEvent ev = new System.Threading.AutoResetEvent(false);
-
-
-                while (!Parent.Cancel)
-                {
-                    KeyValuePair<int, int>? round = null;
-
-                    lock (SyncLock)
-                    {
-                        if (TileSet.Count == 0 && FillerComplete)
-                            return; //No more data
-
-                        if (TileSet.Count > 0)
-                            round = TileSet.Dequeue();
-                    }
-
-                    if (Parent.Cancel)
-                        return;
-
-                    if (round == null) //No data, but producer is still running
-                        System.Threading.Thread.Sleep(500);
-                    else
-                        RenderTile(ev, tileSvc, round.Value.Key, round.Value.Value, Scale, Group);
-                }
-
-
-            }
-            catch { }
-            finally
-            {
-                CompleteFlag--;
-                Event.Set();
-            }
-        }
-
-
-        /// <summary>
-        /// Renders a single tile
-        /// </summary>
-        /// <param name="row">The row index of the tile</param>
-        /// <param name="col">The column index of the tile</param>
-        /// <param name="scaleindex">The scale index of the tile</param>
-        /// <param name="group">The name of the baselayer group</param>
-        public void RenderTile(System.Threading.EventWaitHandle ev, ITileService tileSvc, long row, long col, int scaleindex, string group)
-        {
-            ev.Reset();
-            lock (SyncLock)
-            {
-                RaiseEvents.Enqueue(new EventPassing(
-                    EventPassing.EventType.Begin,
-                     (int)row, (int)col, null,
-                     ev
-                    ));
-                Event.Set();
-            }
-            ev.WaitOne(System.Threading.Timeout.Infinite, true);
-
-            int c = Parent.Config.RetryCount;
-            while (c > 0)
-            {
-                c--;
-                try
-                {
-                    if (!Parent.Cancel)
-                        if (Parent.Config.RenderMethod == null)
-                            tileSvc.GetTile(MapDefinition, group, (int)col, (int)row, scaleindex, "PNG").Dispose();
-                        else
-                            Parent.Config.RenderMethod(MapDefinition, group, (int)col, (int)row, scaleindex);
-
-                    break;
-                }
-                catch (Exception ex)
-                {
-                    if (c == 0)
-                    {
-                        Exception pex = ex;
-                        ev.Reset();
-                        EventPassing evobj = new EventPassing(
-                            EventPassing.EventType.Error ,
-                                (int)row, (int)col, ex,
-                                ev
-                                );
-
-                        lock (SyncLock)
-                        {
-                            RaiseEvents.Enqueue(evobj);
-                            Event.Set();
-                        }
-
-                        ev.WaitOne(System.Threading.Timeout.Infinite, true);
-
-                        if (evobj.Result == null)
-                            break;
-
-                        if (pex == evobj.Result)
-                            throw;
-                        else
-                            throw (Exception)evobj.Result;
-                    }
-                }
-            }
-
-            ev.Reset();
-            lock (SyncLock)
-            {
-                RaiseEvents.Enqueue(new EventPassing( 
-                    EventPassing.EventType.Finish,
-                    (int)row, (int)col, null,
-                    ev
-                ));
-                Event.Set();
-            }
-            ev.WaitOne(System.Threading.Timeout.Infinite, true);
-        }
-
-    }
-}

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -29,6 +29,7 @@
 using OSGeo.MapGuide.ObjectModels.MapDefinition;
 using OSGeo.MapGuide.MaestroAPI.Exceptions;
 using System.Collections.Specialized;
+using OSGeo.MapGuide.MaestroAPI.Tile;
 
 namespace MgCooker
 {

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.designer.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.designer.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -50,6 +50,7 @@
             this.txtLowerX = new System.Windows.Forms.TextBox();
             this.label11 = new System.Windows.Forms.Label();
             this.grpDifferentConnection = new System.Windows.Forms.GroupBox();
+            this.chkUseDifferentConnection = new System.Windows.Forms.CheckBox();
             this.UseNativeAPI = new System.Windows.Forms.CheckBox();
             this.Password = new System.Windows.Forms.TextBox();
             this.Username = new System.Windows.Forms.TextBox();
@@ -73,7 +74,6 @@
             this.MaxColLimit = new System.Windows.Forms.NumericUpDown();
             this.label7 = new System.Windows.Forms.Label();
             this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
-            this.chkUseDifferentConnection = new System.Windows.Forms.CheckBox();
             this.panel1.SuspendLayout();
             this.panel2.SuspendLayout();
             this.BoundsOverride.SuspendLayout();
@@ -239,6 +239,12 @@
             this.grpDifferentConnection.Name = "grpDifferentConnection";
             this.grpDifferentConnection.TabStop = false;
             // 
+            // chkUseDifferentConnection
+            // 
+            resources.ApplyResources(this.chkUseDifferentConnection, "chkUseDifferentConnection");
+            this.chkUseDifferentConnection.Name = "chkUseDifferentConnection";
+            this.chkUseDifferentConnection.UseVisualStyleBackColor = true;
+            // 
             // UseNativeAPI
             // 
             resources.ApplyResources(this.UseNativeAPI, "UseNativeAPI");
@@ -349,9 +355,9 @@
             65536});
             resources.ApplyResources(this.MetersPerUnit, "MetersPerUnit");
             this.MetersPerUnit.Maximum = new decimal(new int[] {
-            10000,
+            1410065408,
+            2,
             0,
-            0,
             0});
             this.MetersPerUnit.Name = "MetersPerUnit";
             this.toolTip1.SetToolTip(this.MetersPerUnit, resources.GetString("MetersPerUnit.ToolTip"));
@@ -415,12 +421,6 @@
             resources.ApplyResources(this.label7, "label7");
             this.label7.Name = "label7";
             // 
-            // chkUseDifferentConnection
-            // 
-            resources.ApplyResources(this.chkUseDifferentConnection, "chkUseDifferentConnection");
-            this.chkUseDifferentConnection.Name = "chkUseDifferentConnection";
-            this.chkUseDifferentConnection.UseVisualStyleBackColor = true;
-            // 
             // SetupRun
             // 
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.resx
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.resx	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.resx	2012-05-14 16:08:26 UTC (rev 6647)
@@ -112,23 +112,23 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="button3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Bottom</value>
   </data>
-  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="button3.Location" type="System.Drawing.Point, System.Drawing">
     <value>227, 9</value>
   </data>
   <data name="button3.Size" type="System.Drawing.Size, System.Drawing">
     <value>112, 23</value>
   </data>
-  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="button3.TabIndex" type="System.Int32, mscorlib">
     <value>2</value>
   </data>
@@ -139,7 +139,7 @@
     <value>button3</value>
   </data>
   <data name="&gt;&gt;button3.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;button3.Parent" xml:space="preserve">
     <value>panel1</value>
@@ -166,7 +166,7 @@
     <value>button2</value>
   </data>
   <data name="&gt;&gt;button2.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;button2.Parent" xml:space="preserve">
     <value>panel1</value>
@@ -193,7 +193,7 @@
     <value>button1</value>
   </data>
   <data name="&gt;&gt;button1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;button1.Parent" xml:space="preserve">
     <value>panel1</value>
@@ -217,7 +217,7 @@
     <value>panel1</value>
   </data>
   <data name="&gt;&gt;panel1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;panel1.Parent" xml:space="preserve">
     <value>$this</value>
@@ -231,62 +231,62 @@
   <data name="MapTree.ImageIndex" type="System.Int32, mscorlib">
     <value>0</value>
   </data>
-  <metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>145, 17</value>
   </metadata>
   <data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
     <value>
-        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACC
-        DAAAAk1TRnQBSQFMAgEBBAEAAUwBAAFMAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+        DAAAAk1TRnQBSQFMAgEBBAEAAVQBAAFUAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
         AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKgADHAEoAyQBNgMk
         ATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDGwEmHAADFgEeAVsCWAHGAx0BKgMC
-        AQOgAAP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wMbASYcAAGH
-        Am0B9wH0AeYB4QH/AcoBuwG6Af0BjQGFAYQB+QFNAkwBkQMRAReYAAP9Af8B9QHoAeQB/wH0AeUB4AH/
+        AQOgAAP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wMbASYcAAGG
+        Am0B9wH0AeYB4QH/AccBugG5Af0BjAGEAYMB+QFNAkwBkQMRAReYAAP9Af8B9QHoAeQB/wH0AeUB4AH/
         AfIB4gHdAf8B8QHgAdkB/wHwAd0B1gH/Ae8B2wHTAf8B7gHZAdEB/wHuAdgB0AH/Ae4B2AHQAf8B7gHY
         AdAB/wP9Af8DGwEmGAABLAIrAUMB9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/
-        AakBmwGYAfoBaQJaAfABNgI1AVgDCwEPDAADHQEqAx0BKiAAAwUBBwMdASoDHQEqTAAD/QH/AfcB7QHp
-        Af8B9gHqAeYB/wH0AecB4wH/Ad0BtQGwAf8BvQFrAWYB/wG+AW8BagH/AeMBwgG8Af8B7wHaAdIB/wHu
-        AdgB0AH/Ae4B2AHQAf8D/QH/AxsBJhgAAZECewH4AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
-        Af8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wGeAYkBgwH6AVkCVwHCCwAB/ygAAzABTAMA
-        Af9MAAP9Af8B+AHwAe0B/wHtAdcB0gH/AbkBiQFpAf8BWQGTASkB/wHqAbEBMQH/AegBrgEoAf8B6wHB
-        AVwB/wGxAVMBTgH/Ae4B2QHSAf8B7gHZAdIB/wP9Af8DGwEmFAADQAFwAfUB6QHlAf8B9QHoAeMB/wH0
+        AaYBmQGVAfoBaAJaAfABNgI1AVgDCwEPDAADHQEqAx0BKiAAAwUBBwMdASoDHQEqTAAD/QH/AfcB7QHp
+        Af8B9gHqAeYB/wH0AecB4wH/Ad0BtQGwAf8BvQFqAWUB/wG+AW4BaQH/AeMBwgG8Af8B7wHaAdIB/wHu
+        AdgB0AH/Ae4B2AHQAf8D/QH/AxsBJhgAAY4CegH4AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
+        Af8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wGcAYYBgAH6AVkCVwHCCwAB/ygAAzABTAMA
+        Af9MAAP9Af8B+AHwAe0B/wHtAdcB0gH/AbkBiQFoAf8BWAGTASgB/wHqAbEBMAH/AegBrgEnAf8B6wHB
+        AVsB/wGxAVIBTQH/Ae4B2QHSAf8B7gHZAdIB/wP9Af8DGwEmFAADQAFwAfUB6QHlAf8B9QHoAeMB/wH0
         AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHdAdcB/wHvAdwB1QH/Ae8B2gHT
         Af8DOAFcCwAB/wgAAUYCRQF/AwAEAQECA0UBfQQAAygBPAMlATcEAAMvAUoDAAH/DAADEQEXA1gB0QMA
-        Af8DKAE8EAADOAFcAwAB/xgAA/0B/wH2AeoB5gH/AegBvwGcAf8B+wHLAVwB/wE2Aa0BQwH/AU4BnQEk
-        Af8B/gHEATwB/wH+Ab4BJwH/AfYBtgEdAf8BlwFsAUkB/wHwAd0B1gH/A/0B/wMbASYUAAGYAYcBhQH4
+        Af8DKAE8EAADOAFcAwAB/xgAA/0B/wH2AeoB5gH/AegBvwGcAf8B+wHLAVsB/wE1Aa0BQgH/AU0BnQEj
+        Af8B/gHEATsB/wH+Ab4BJgH/AfYBtgEcAf8BlwFrAUgB/wHwAd0B1gH/A/0B/wMbASYUAAGWAYQBggH4
         AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHd
-        AdcB/wHvAdwB1QH/AXkCYgH2AwQBBgsAAf8LAAH/A0UBfQNIAYUDAAH/BwAB/wMAAf8EAAMvAUoDAAH/
-        EAADQgF0AwAB/xQAAw0BEQNaAdUYAAP9Af8BuQFZAUQB/wH6Ac4BaAH/AaQBtgFQAf8BNgGtAUQB/wE1
-        Aa0BQwH/AckBvwFSAf8B/gHEATsB/wH+AcABLAH/ATQBpQE7Af8BvAFrAWgB/wP9Af8DGwEmEAADUAGe
+        AdcB/wHvAdwB1QH/AXcCYgH2AwQBBgsAAf8LAAH/A0UBfQNIAYUDAAH/BwAB/wMAAf8EAAMvAUoDAAH/
+        EAADQgF0AwAB/xQAAw0BEQNaAdUYAAP9Af8BuQFYAUMB/wH6Ac4BZwH/AaQBtgFPAf8BNQGtAUMB/wE0
+        Aa0BQgH/AckBvwFRAf8B/gHEAToB/wH+AcABKwH/ATMBpQE6Af8BvAFqAWcB/wP9Af8DGwEmEAADUAGe
         AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8B8QHf
-        AdkB/wHwAd0B1wH/Ab0BswGvAfwDKAE8DwAB/ygAAy8BSgMAAf8QAANCAXQDAAH/NAAD/QH/AeoBwwGh
-        Af8B/QHWAYQB/wGbAbYBVgH/ATQBnwEpAf8B8QHYAZEB/wH9AdEBbAH/AZwBsAE9Af8BNgGtAUQB/wE2
-        Aa0BRAH/AZgBZwFGAf8D/QH/AxsBJhAAAZsBiQGIAfcB9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHm
-        AeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8BaQJZAesDAQECDwAB/ygA
-        Ay8BSgMAAf8QAANCAXQDAAH/FAADAgEDA1EBoRgAA/0B/wH6AeIBuQH/ATcBmgEgAf8C1AGbAf8B/QHj
-        AbUB/wH9Ad0BnQH/Af0B1AF1Af8B5AHIAVoB/wE1AawBQgH/AUwBnAEhAf8BngGKAVcB/wP9Af8DGwEm
+        AdkB/wHwAd0B1wH/AbsBsQGtAfwDKAE8DwAB/ygAAy8BSgMAAf8QAANCAXQDAAH/NAAD/QH/AeoBwwGh
+        Af8B/QHWAYQB/wGbAbYBVQH/ATMBnwEoAf8B8QHYAZEB/wH9AdEBawH/AZwBsAE8Af8BNQGtAUMB/wE1
+        Aa0BQwH/AZgBZgFFAf8D/QH/AxsBJhAAAZcBiAGHAfcB9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHm
+        AeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8BaAJZAesDAQECDwAB/ygA
+        Ay8BSgMAAf8QAANCAXQDAAH/FAADAgEDA1EBoRgAA/0B/wH6AeIBuQH/ATYBmgEfAf8C1AGbAf8B/QHj
+        AbUB/wH9Ad0BnQH/Af0B1AF0Af8B5AHIAVkB/wE0AawBQQH/AUsBnAEgAf8BngGKAVYB/wP9Af8DGwEm
         DAABXAJZAckB9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHj
-        Ad0B/wHyAeEB2wH/AfEB3wHZAf8BrAGdAZoB+gMbASYTAAH/KAADLwFKAwAB/xAAA0IBdAMAAf8UAAM+
-        AWsDAAH/GAAD/QH/AWkBkAExAf8BNgGtAUQB/wE2Aa0BRAH/Aa8BwQFwAf8B/QHbAZUB/wH9AdMBcAH/
-        Af4BygFOAf8BPgGaASAB/wE0AZcBGwH/AZwBaQFHAf8D/QH/AxsBJggAAwQBBQGvAaIBoQH6AfcB7QHp
+        Ad0B/wHyAeEB2wH/AfEB3wHZAf8BqQGbAZgB+gMbASYTAAH/KAADLwFKAwAB/xAAA0IBdAMAAf8UAAM+
+        AWsDAAH/GAAD/QH/AWgBkAEwAf8BNQGtAUMB/wE1Aa0BQwH/Aa8BwQFvAf8B/QHbAZUB/wH9AdMBbwH/
+        Af4BygFNAf8BPQGaAR8B/wEzAZcBGgH/AZwBaAFGAf8D/QH/AxsBJggAAwQBBQGsAaABnwH6AfcB7QHp
         Af8B9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHhAdsB/wHx
-        Ad8B2QH/AV0CWQHSFwAB/ygAAy8BSgMAAf8QAANCAXYDAAH/NAAD/QH/Ab4BawFLAf8BNgGtAUQB/wE1
-        AaMBMgH/ATUBrQFDAf8BwAHCAWMB/wH+Ac4BXgH/Af4BxgFAAf8BVQGUARIB/wHCAboBQgH/AcUBgQF0
-        Af8D/QH/AxsBJggAAWQCWgHnAfgB7gHrAf8B9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
-        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AZsBjQGKAfgDEwEaFwAB/ygAAy8BSgMAAf8MAAMI
-        AQsBWgJVAd4DAAH/NAAD/QH/AfcB7QHpAf8BcQGQATUB/wGnAbUBSgH/ATYBkwEUAf8BqgG3AUwB/wFJ
-        AZ4BJQH/AfIBwgE9Af8B/gG9ASIB/wHFAXQBYAH/AfkB8QHuAf8D/QH/AxsBJgQAAxIBGQGwAqQB+gH4
+        Ad8B2QH/AV0CWQHSFwAB/ygAAy8BSgMAAf8QAANCAXYDAAH/NAAD/QH/Ab4BagFKAf8BNQGtAUMB/wE0
+        AaMBMQH/ATQBrQFCAf8BwAHCAWIB/wH+Ac4BXQH/Af4BxgE/Af8BVAGUAREB/wHCAboBQQH/AcUBgQFz
+        Af8D/QH/AxsBJggAAWQCXAHnAfgB7gHrAf8B9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
+        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AZkBigGHAfgDEwEaFwAB/ygAAy8BSgMAAf8MAAMI
+        AQsBWgJWAd4DAAH/NAAD/QH/AfcB7QHpAf8BcAGQATQB/wGnAbUBSQH/ATUBkwETAf8BqgG3AUsB/wFI
+        AZ4BJAH/AfIBwgE8Af8B/gG9ASEB/wHFAXMBXwH/AfkB8QHuAf8D/QH/AxsBJgQAAxIBGQGtAqIB+gH4
         Ae4B6wH/AfcB7QHpAf8B9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
-        Af8B8gHhAdsB/wNUAa8YAAFXAlQB3wFJAkgBhyAAAwsBDwNVAbcBVwJUAd9MAAP9Af8B+QHxAe4B/wHy
-        AeEB2wH/Aa0BhgFRAf8B7gHYAYsB/wFKAZ4BJQH/ATUBrQFDAf8BOwGUARcB/wG7AV4BSgH/AfgB8AHt
-        Af8B+QHxAe4B/wP9Af8DGwEmCAADAQECAVICUQGnAZUCigH5AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/
-        AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AZgBhAF+AfgDDgETmAAD/QH/AfkB8QHuAf8B+QHxAe4B/wH5
+        Af8B8gHhAdsB/wNUAa8YAAFXAlYB3wFJAkgBhyAAAwsBDwNVAbcBVwJWAd9MAAP9Af8B+QHxAe4B/wHy
+        AeEB2wH/Aa0BhgFQAf8B7gHYAYsB/wFJAZ4BJAH/ATQBrQFCAf8BOgGUARYB/wG7AV0BSQH/AfgB8AHt
+        Af8B+QHxAe4B/wP9Af8DGwEmCAADAQECAVICUQGnAZICiQH5AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/
+        AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AZYBgQF9AfgDDgETmAAD/QH/AfkB8QHuAf8B+QHxAe4B/wH5
         AfEB7gH/AewB0gHJAf8B0gGVAYIB/wHUAZoBiQH/AfIB4QHcAf8B+QHxAe4B/wH5AfEB7gH/AfkB8QHu
-        Af8D/QH/AxsBJhQAAx0BKQFhAlgB5AGiAY4BjQH5AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AUkCSAGI
+        Af8D/QH/AxsBJhQAAx0BKQFhAlkB5AGeAY0BjAH5AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AUkCSAGI
         nAAD/QH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0
-        Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8D/QH/AxsBJiAAAz4BawGTAnsB+gGRAnoB+AMHAQqcAAGl
+        Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8D/QH/AxsBJiAAAz4BawGQAnoB+gGOAnkB+AMHAQqcAAGl
         AqAB/wGkAaABnwH/AaQCnwH/AaMCngH/AaICnQH/AaECnAH/AaACmwH/AZ8CmgH/AZ0CmQH/AZwBmAGX
         Af8BmwKWAf8BmQKVAf/IAAFCAU0BPgcAAT4DAAEoAwABQAMAASADAAEBAQABAQYAAQEWAAP/gQABwAEB
         AfwBPwT/AcABAQH8AQ8E/wHAAQEB+AEBAc8B8QL/AcABAQH4AQAB3wH5Av8BwAEBAfABAAHYAUkBwwHP
@@ -311,7 +311,7 @@
     <value>MapTree</value>
   </data>
   <data name="&gt;&gt;MapTree.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TreeView, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;MapTree.Parent" xml:space="preserve">
     <value>$this</value>
@@ -319,7 +319,7 @@
   <data name="&gt;&gt;MapTree.ZOrder" xml:space="preserve">
     <value>0</value>
   </data>
-  <metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
   <data name="saveFileDialog1.Filter" xml:space="preserve">
@@ -353,7 +353,7 @@
     <value>ModfiedOverrideWarning</value>
   </data>
   <data name="&gt;&gt;ModfiedOverrideWarning.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;ModfiedOverrideWarning.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -377,7 +377,7 @@
     <value>ResetBounds</value>
   </data>
   <data name="&gt;&gt;ResetBounds.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;ResetBounds.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -398,7 +398,7 @@
     <value>txtUpperY</value>
   </data>
   <data name="&gt;&gt;txtUpperY.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;txtUpperY.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -422,7 +422,7 @@
     <value>label4</value>
   </data>
   <data name="&gt;&gt;label4.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label4.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -443,7 +443,7 @@
     <value>txtUpperX</value>
   </data>
   <data name="&gt;&gt;txtUpperX.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;txtUpperX.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -467,7 +467,7 @@
     <value>label5</value>
   </data>
   <data name="&gt;&gt;label5.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label5.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -488,7 +488,7 @@
     <value>txtLowerY</value>
   </data>
   <data name="&gt;&gt;txtLowerY.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;txtLowerY.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -512,7 +512,7 @@
     <value>label10</value>
   </data>
   <data name="&gt;&gt;label10.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label10.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -533,7 +533,7 @@
     <value>txtLowerX</value>
   </data>
   <data name="&gt;&gt;txtLowerX.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;txtLowerX.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -557,7 +557,7 @@
     <value>label11</value>
   </data>
   <data name="&gt;&gt;label11.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label11.Parent" xml:space="preserve">
     <value>BoundsOverride</value>
@@ -584,7 +584,7 @@
     <value>BoundsOverride</value>
   </data>
   <data name="&gt;&gt;BoundsOverride.Type" xml:space="preserve">
-    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;BoundsOverride.Parent" xml:space="preserve">
     <value>panel2</value>
@@ -614,7 +614,7 @@
     <value>chkUseDifferentConnection</value>
   </data>
   <data name="&gt;&gt;chkUseDifferentConnection.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;chkUseDifferentConnection.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -637,7 +637,7 @@
   <data name="UseNativeAPI.Text" xml:space="preserve">
     <value>Connect using native API</value>
   </data>
-  <metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>250, 17</value>
   </metadata>
   <data name="UseNativeAPI.ToolTip" xml:space="preserve">
@@ -647,7 +647,7 @@
     <value>UseNativeAPI</value>
   </data>
   <data name="&gt;&gt;UseNativeAPI.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;UseNativeAPI.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -671,7 +671,7 @@
     <value>Password</value>
   </data>
   <data name="&gt;&gt;Password.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;Password.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -698,7 +698,7 @@
     <value>Username</value>
   </data>
   <data name="&gt;&gt;Username.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;Username.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -725,7 +725,7 @@
     <value>MapAgent</value>
   </data>
   <data name="&gt;&gt;MapAgent.Type" xml:space="preserve">
-    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;MapAgent.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -752,7 +752,7 @@
     <value>label3</value>
   </data>
   <data name="&gt;&gt;label3.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label3.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -779,7 +779,7 @@
     <value>label2</value>
   </data>
   <data name="&gt;&gt;label2.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label2.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -806,7 +806,7 @@
     <value>label1</value>
   </data>
   <data name="&gt;&gt;label1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label1.Parent" xml:space="preserve">
     <value>grpDifferentConnection</value>
@@ -827,7 +827,7 @@
     <value>grpDifferentConnection</value>
   </data>
   <data name="&gt;&gt;grpDifferentConnection.Type" xml:space="preserve">
-    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;grpDifferentConnection.Parent" xml:space="preserve">
     <value>panel2</value>
@@ -860,7 +860,7 @@
     <value>RandomTileOrder</value>
   </data>
   <data name="&gt;&gt;RandomTileOrder.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;RandomTileOrder.Parent" xml:space="preserve">
     <value>groupBox3</value>
@@ -884,7 +884,7 @@
     <value>ThreadCount</value>
   </data>
   <data name="&gt;&gt;ThreadCount.Type" xml:space="preserve">
-    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;ThreadCount.Parent" xml:space="preserve">
     <value>groupBox3</value>
@@ -911,7 +911,7 @@
     <value>label9</value>
   </data>
   <data name="&gt;&gt;label9.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label9.Parent" xml:space="preserve">
     <value>groupBox3</value>
@@ -935,7 +935,7 @@
     <value>groupBox3</value>
   </data>
   <data name="&gt;&gt;groupBox3.Type" xml:space="preserve">
-    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;groupBox3.Parent" xml:space="preserve">
     <value>panel2</value>
@@ -962,7 +962,7 @@
     <value>MetersPerUnit</value>
   </data>
   <data name="&gt;&gt;MetersPerUnit.Type" xml:space="preserve">
-    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;MetersPerUnit.Parent" xml:space="preserve">
     <value>OfficialMethodPanel</value>
@@ -989,7 +989,7 @@
     <value>label8</value>
   </data>
   <data name="&gt;&gt;label8.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label8.Parent" xml:space="preserve">
     <value>OfficialMethodPanel</value>
@@ -1013,7 +1013,7 @@
     <value>OfficialMethodPanel</value>
   </data>
   <data name="&gt;&gt;OfficialMethodPanel.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;OfficialMethodPanel.Parent" xml:space="preserve">
     <value>groupBox2</value>
@@ -1043,7 +1043,7 @@
     <value>LimitTileset</value>
   </data>
   <data name="&gt;&gt;LimitTileset.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;LimitTileset.Parent" xml:space="preserve">
     <value>groupBox2</value>
@@ -1073,7 +1073,7 @@
     <value>UseOfficialMethod</value>
   </data>
   <data name="&gt;&gt;UseOfficialMethod.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;UseOfficialMethod.Parent" xml:space="preserve">
     <value>groupBox2</value>
@@ -1097,7 +1097,7 @@
     <value>MaxRowLimit</value>
   </data>
   <data name="&gt;&gt;MaxRowLimit.Type" xml:space="preserve">
-    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;MaxRowLimit.Parent" xml:space="preserve">
     <value>TilesetLimitPanel</value>
@@ -1124,7 +1124,7 @@
     <value>label6</value>
   </data>
   <data name="&gt;&gt;label6.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label6.Parent" xml:space="preserve">
     <value>TilesetLimitPanel</value>
@@ -1148,7 +1148,7 @@
     <value>MaxColLimit</value>
   </data>
   <data name="&gt;&gt;MaxColLimit.Type" xml:space="preserve">
-    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;MaxColLimit.Parent" xml:space="preserve">
     <value>TilesetLimitPanel</value>
@@ -1175,7 +1175,7 @@
     <value>label7</value>
   </data>
   <data name="&gt;&gt;label7.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;label7.Parent" xml:space="preserve">
     <value>TilesetLimitPanel</value>
@@ -1199,7 +1199,7 @@
     <value>TilesetLimitPanel</value>
   </data>
   <data name="&gt;&gt;TilesetLimitPanel.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;TilesetLimitPanel.Parent" xml:space="preserve">
     <value>groupBox2</value>
@@ -1223,7 +1223,7 @@
     <value>groupBox2</value>
   </data>
   <data name="&gt;&gt;groupBox2.Type" xml:space="preserve">
-    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;groupBox2.Parent" xml:space="preserve">
     <value>panel2</value>
@@ -1247,7 +1247,7 @@
     <value>panel2</value>
   </data>
   <data name="&gt;&gt;panel2.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;panel2.Parent" xml:space="preserve">
     <value>$this</value>
@@ -1255,7 +1255,7 @@
   <data name="&gt;&gt;panel2.ZOrder" xml:space="preserve">
     <value>1</value>
   </data>
-  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>
   <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
@@ -1774,24 +1774,24 @@
     <value>imageList1</value>
   </data>
   <data name="&gt;&gt;imageList1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;saveFileDialog1.Name" xml:space="preserve">
     <value>saveFileDialog1</value>
   </data>
   <data name="&gt;&gt;saveFileDialog1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;toolTip1.Name" xml:space="preserve">
     <value>toolTip1</value>
   </data>
   <data name="&gt;&gt;toolTip1.Type" xml:space="preserve">
-    <value>System.Windows.Forms.ToolTip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
   <data name="&gt;&gt;$this.Name" xml:space="preserve">
     <value>SetupRun</value>
   </data>
   <data name="&gt;&gt;$this.Type" xml:space="preserve">
-    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMap.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMap.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMap.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -170,7 +170,6 @@
             }
             this.Layers = new RuntimeMapLayerCollection(this);
             this.Groups = new RuntimeMapGroupCollection(this);
-            this.Selection = new MapSelection(this);
             this.IsDirty = false;
         }
 
@@ -938,14 +937,25 @@
             return t;
         }
 
+        private MapSelection _selection;
+
         /// <summary>
         /// Gets the selection set
         /// </summary>
         /// <value>The selection.</value>
         public MapSelection Selection
         {
-            get;
-            private set;
+            get
+            {
+                if (null == _selection)
+                {
+                    _selection = new MapSelection(this);
+                    var resId = this.ResourceID.Replace(".Map", ".Selection");
+                    var ser = new MgBinaryDeserializer(this.ResourceService.GetResourceData(resId, "RuntimeData"), this.CurrentConnection.SiteVersion);
+                    _selection.Deserialize(ser);
+                }
+                return _selection;
+            }
         }
 
         /// <summary>

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2012-05-14 16:08:26 UTC (rev 6647)
@@ -385,6 +385,8 @@
     <Compile Include="Services\NsDoc.cs" />
     <Compile Include="Services\ServiceType.cs" />
     <Compile Include="SiteVersion.cs" />
+    <Compile Include="Tile\BatchSettings.cs" />
+    <Compile Include="Tile\RenderThread.cs" />
     <Compile Include="Utf8XmlWriter.cs" />
     <Compile Include="Utility.cs" />
     <Compile Include="XmlValidator.cs" />

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.239
+//     Runtime Version:4.0.30319.225
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -576,6 +576,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Maestro could not fully validate the feature source due to a a mapagent error. Assuming it is because of timeout: {0}.
+        /// </summary>
+        internal static string FS_ValidationTimeout {
+            get {
+                return ResourceManager.GetString("FS_ValidationTimeout", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Infinity.
         /// </summary>
         internal static string Infinity {
@@ -1125,6 +1134,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to All threads crashed, and the tile set was only partially created.
+        /// </summary>
+        internal static string TS_ThreadFailureError {
+            get {
+                return ResourceManager.GetString("TS_ThreadFailureError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Unknown layer version: .
         /// </summary>
         internal static string UnknownLayerVersion {

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2012-05-14 16:08:26 UTC (rev 6647)
@@ -112,10 +112,10 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <data name="ADF_MapInvalidError" xml:space="preserve">
     <value>Map with ID {0} does not point to a valid map</value>
@@ -478,7 +478,7 @@
   <data name="ADF_Widget_ZoomOut_Label" xml:space="preserve">
     <value>Zoom Out</value>
   </data>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="BaseTemplate_ApplicationDefinition" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\BaseTemplate.ApplicationDefinition.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1</value>
   </data>
@@ -563,4 +563,11 @@
   <data name="MDF_LayerWithNullExtent" xml:space="preserve">
     <value>Map Definition references feature source {0} which has a null extent. Most likely caused by feature source having no actual data inside it</value>
   </data>
+  <data name="TS_ThreadFailureError" xml:space="preserve">
+    <value>All threads crashed, and the tile set was only partially created</value>
+    <comment>An error message that displays if the render threads crash</comment>
+  </data>
+  <data name="FS_ValidationTimeout" xml:space="preserve">
+    <value>Maestro could not fully validate the feature source due to a a mapagent error. Assuming it is because of timeout: {0}</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -83,24 +83,35 @@
             FeatureSourceDescription fsd = null;
             try
             {
+                //FIXME: Can we do this without a full schema walk? Really large schemas will timeout
                 fsd = context.DescribeFeatureSource(feature.ResourceID);
                 if (fsd == null || fsd.Schemas.Length == 0)
                     issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_NoSchemasFound, Properties.Resources.FS_SchemasMissingWarning));
             }
             catch (Exception ex)
             {
-                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
-                issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Properties.Resources.FS_SchemaReadError, msg)));
+                var wex = ex as System.Net.WebException;
+                if (wex != null) //Most likely timeout due to really large schema
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, ValidationStatusCode.Warning_FeatureSource_Validation_Timeout, string.Format(Properties.Resources.FS_ValidationTimeout, msg)));
+                }
+                else
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Error, ValidationStatusCode.Error_FeatureSource_SchemaReadError, string.Format(Properties.Resources.FS_SchemaReadError, msg)));
+                }
             }
 
-
-            foreach (var cl in fsd.AllClasses)
+            if (fsd != null)
             {
-                var ids = cl.IdentityProperties;
-                if (ids.Count == 0)
-                    issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, cl.QualifiedName)));
+                foreach (var cl in fsd.AllClasses)
+                {
+                    var ids = cl.IdentityProperties;
+                    if (ids.Count == 0)
+                        issues.Add(new ValidationIssue(feature, ValidationStatus.Information, ValidationStatusCode.Info_FeatureSource_NoPrimaryKey, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, cl.QualifiedName)));
+                }
             }
-
             context.MarkValidated(resource.ResourceID);
 
             return issues.ToArray();

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationStatusCode.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -104,6 +104,12 @@
         Warning_FeatureSource_NoSchemasFound,
 
         /// <summary>
+        /// A mapagent error occurred during Feature Source validation. Most likely because of timeout. As a result, the full validity of the
+        /// Feature Source cannot be determined
+        /// </summary>
+        Warning_FeatureSource_Validation_Timeout,
+
+        /// <summary>
         /// DWG Load Procedures not supported. This is a limitation of Maestro
         /// </summary>
         Warning_LoadProcedure_DwgNotSupported = 3201,


Property changes on: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile
___________________________________________________________________
Added: bugtraq:number
   + true

Added: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/BatchSettings.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/BatchSettings.cs	                        (rev 0)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/BatchSettings.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -0,0 +1,712 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels.Common;
+
+namespace OSGeo.MapGuide.MaestroAPI.Tile
+{
+    /// <summary>
+    /// This delegate is used to monitor progress on tile rendering
+    /// </summary>
+    /// <param name="map">The map currently being processed</param>
+    /// <param name="group">The group being processed</param>
+    /// <param name="scaleindex">The scaleindex being processed</param>
+    /// <param name="row">The row being processed</param>
+    /// <param name="column">The column being processed</param>
+    /// <param name="cancel">A control flag to stop the tile rendering</param>
+    /// <param name="state">The state that invoked the callback</param>
+    public delegate void ProgressCallback(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel);
+
+    /// <summary>
+    /// This delegate is used to monitor progress on tile rendering
+    /// </summary>
+    /// <param name="map">The map currently being processed</param>
+    /// <param name="group">The group being processed</param>
+    /// <param name="scaleindex">The scaleindex being processed</param>
+    /// <param name="row">The row being processed</param>
+    /// <param name="column">The column being processed</param>
+    /// <param name="state">The state that invoked the callback</param>
+    /// <param name="exception">The exception from the last attempt, set this to null to ignore the exception</param>
+    public delegate void ErrorCallback(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref Exception exception);
+
+    /// <summary>
+    /// These are the avalible states for callbacks
+    /// </summary>
+    public enum CallbackStates
+    {
+        /// <summary>
+        /// All maps are being rendered
+        /// </summary>
+        StartRenderAllMaps,
+        /// <summary>
+        /// A map is being rendered
+        /// </summary>
+        StartRenderMap,
+        /// <summary>
+        /// A group is being rendered
+        /// </summary>
+        StartRenderGroup,
+        /// <summary>
+        /// A scale is being rendered
+        /// </summary>
+        StartRenderScale,
+        /// <summary>
+        /// A tile is being rendered
+        /// </summary>
+        StartRenderTile,
+        /// <summary>
+        /// A tile has been rendered
+        /// </summary>
+        FinishRenderTile,
+        /// <summary>
+        /// A scale has been rendered
+        /// </summary>
+        FinishRenderScale,
+        /// <summary>
+        /// A group has been rendered
+        /// </summary>
+        FinishRenderGroup,
+        /// <summary>
+        /// A map has been rendered
+        /// </summary>
+        FinishRenderMap,
+        /// <summary>
+        /// All maps have been rendered
+        /// </summary>
+        FinishRenderAllMaps,
+        /// <summary>
+        /// A tile has failed to render
+        /// </summary>
+        FailedRenderingTile,
+    }
+
+    /// <summary>
+    /// Class to hold settings for a batch run of tile building
+    /// </summary>
+    public class BatchSettings
+    {
+        /// <summary>
+        /// A reference to the connection
+        /// </summary>
+        private IServerConnection m_connection;
+        /// <summary>
+        /// The list of maps
+        /// </summary>
+        private List<BatchMap> m_maps;
+        /// <summary>
+        /// A default set of tile settings
+        /// </summary>
+        private TileSettings m_tileSettings = new TileSettings();
+
+        /// <summary>
+        /// A flag that indicates the rendering should stop
+        /// </summary>
+        private bool m_cancel;
+
+        /// <summary>
+        /// An event that can be used to pause MgCooker
+        /// </summary>
+        public System.Threading.ManualResetEvent PauseEvent = new System.Threading.ManualResetEvent(true);
+
+        #region Events
+        /// <summary>
+        /// All maps are being rendered
+        /// </summary>
+        public event ProgressCallback BeginRenderingMaps;
+        /// <summary>
+        /// A map is being rendered
+        /// </summary>
+        public event ProgressCallback BeginRenderingMap;
+        /// <summary>
+        /// A group is being rendered
+        /// </summary>
+        public event ProgressCallback BeginRenderingGroup;
+        /// <summary>
+        /// A scale is being rendered
+        /// </summary>
+        public event ProgressCallback BeginRenderingScale;
+        /// <summary>
+        /// A tile is being rendered
+        /// </summary>
+        public event ProgressCallback BeginRenderingTile;
+        /// <summary>
+        /// All maps have been rendered
+        /// </summary>
+        public event ProgressCallback FinishRenderingMaps;
+        /// <summary>
+        /// A map has been rendered
+        /// </summary>
+        public event ProgressCallback FinishRenderingMap;
+        /// <summary>
+        /// A group has been rendered
+        /// </summary>
+        public event ProgressCallback FinishRenderingGroup;
+        /// <summary>
+        /// A scale has been rendered
+        /// </summary>
+        public event ProgressCallback FinishRenderingScale;
+        /// <summary>
+        /// A tile has been rendered
+        /// </summary>
+        public event ProgressCallback FinishRenderingTile;
+        /// <summary>
+        /// A tile has failed to render
+        /// </summary>
+        public event ErrorCallback FailedRenderingTile;
+
+        internal void InvokeBeginRendering(BatchMap batchMap)
+        {
+            if (this.BeginRenderingMap != null)
+                this.BeginRenderingMap(CallbackStates.StartRenderMap, batchMap, null, -1, -1, -1, ref m_cancel);
+            PauseEvent.WaitOne();
+        }
+
+        internal void InvokeFinishRendering(BatchMap batchMap)
+        {
+            if (this.FinishRenderingMap != null)
+                this.FinishRenderingMap(CallbackStates.FinishRenderMap, batchMap, null, -1, -1, -1, ref m_cancel);
+        }
+
+        internal void InvokeBeginRendering(BatchMap batchMap, string group)
+        {
+            if (this.BeginRenderingGroup != null)
+                this.BeginRenderingGroup(CallbackStates.StartRenderGroup, batchMap, group, -1, -1, -1, ref m_cancel);
+            PauseEvent.WaitOne();
+        }
+
+        internal void InvokeFinishRendering(BatchMap batchMap, string group)
+        {
+            if (this.FinishRenderingGroup != null)
+                this.FinishRenderingGroup(CallbackStates.FinishRenderGroup, batchMap, group, -1, -1, -1, ref m_cancel);
+        }
+
+        internal void InvokeBeginRendering(BatchMap batchMap, string group, int scaleindex)
+        {
+            if (this.BeginRenderingScale != null)
+                this.BeginRenderingScale(CallbackStates.StartRenderScale, batchMap, group, scaleindex, -1, -1, ref m_cancel);
+            PauseEvent.WaitOne();
+        }
+
+        internal void InvokeFinishRendering(BatchMap batchMap, string group, int scaleindex)
+        {
+            if (this.FinishRenderingScale != null)
+                this.FinishRenderingScale(CallbackStates.FinishRenderScale, batchMap, group, scaleindex, -1, -1, ref m_cancel);
+        }
+
+        internal void InvokeBeginRendering(BatchMap batchMap, string group, int scaleindex, int row, int col)
+        {
+            if (this.BeginRenderingTile != null)
+                this.BeginRenderingTile(CallbackStates.StartRenderTile, batchMap, group, scaleindex, row, col, ref m_cancel);
+            PauseEvent.WaitOne();
+        }
+
+        internal void InvokeFinishRendering(BatchMap batchMap, string group, int scaleindex, int row, int col)
+        {
+            if (this.FinishRenderingTile != null)
+                this.FinishRenderingTile(CallbackStates.FinishRenderTile, batchMap, group, scaleindex, row, col, ref m_cancel);
+        }
+
+        internal Exception InvokeError(BatchMap batchMap, string group, int scaleindex, int row, int col, ref Exception exception)
+        {
+            if (this.FailedRenderingTile != null)
+                this.FailedRenderingTile(CallbackStates.FailedRenderingTile, batchMap, group, scaleindex, row, col, ref exception);
+
+            return exception;
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Constructs a new batch setup. If no maps are supplied, all maps in the repository is assumed.
+        /// </summary>
+        /// <param name="mapagent">The url to the mapagent.fcgi</param>
+        /// <param name="username">The username to connect with</param>
+        /// <param name="password">The password to connect with</param>
+        /// <param name="maps">A list of maps to process, leave empty to process all layers</param>
+        public BatchSettings(string mapagent, string username, string password, params string[] maps)
+            : this(ConnectionProviderRegistry.CreateConnection("Maestro.Http", "Url", mapagent, "Username", username, "Password", password, "AllowUntestedVersions", "true"), maps)
+        {
+        }
+
+        public BatchSettings(IServerConnection connection)
+        {
+            m_connection = connection;
+            m_maps = new List<BatchMap>();
+        }
+
+        public BatchSettings(IServerConnection connection, params string[] maps)
+        {
+            m_connection = connection;
+            m_maps = new List<BatchMap>();
+
+            if (maps == null || maps.Length == 0 || (maps.Length == 1 && maps[0].Trim().Length == 0))
+            {
+                List<string> tmp = new List<string>();
+                foreach (var doc in m_connection.ResourceService.GetRepositoryResources("Library://", "MapDefinition").Children)
+                    tmp.Add(doc.ResourceId);
+                maps = tmp.ToArray();
+            }
+
+            foreach (string s in maps)
+            {
+                BatchMap bm = new BatchMap(this, s);
+                if (bm.Resolutions > 0)
+                    m_maps.Add(bm);
+            }
+        }
+
+        public void SetScales(int[] scaleindexes)
+        {
+            foreach (BatchMap bm in m_maps)
+                bm.SetScales(scaleindexes);
+        }
+
+        public void SetGroups(string[] groups)
+        {
+            foreach (BatchMap bm in m_maps)
+                bm.SetGroups(groups);
+        }
+
+        public void LimitRows(long limit)
+        {
+            foreach (BatchMap bm in m_maps)
+                bm.LimitRows(limit);
+        }
+
+        public void LimitCols(long limit)
+        {
+            foreach (BatchMap bm in m_maps)
+                bm.LimitCols(limit);
+        }
+
+        /// <summary>
+        /// Renders all tiles in all maps
+        /// </summary>
+        public void RenderAll()
+        {
+            m_cancel = false;
+
+            if (this.BeginRenderingMaps != null)
+                this.BeginRenderingMaps(CallbackStates.StartRenderAllMaps, null, null, -1, -1, -1, ref m_cancel);
+
+            foreach (BatchMap bm in this.Maps)
+                if (m_cancel)
+                    break;
+                else
+                    bm.Render();
+
+            if (this.FinishRenderingMaps != null)
+                this.FinishRenderingMaps(CallbackStates.FinishRenderAllMaps, null, null, -1, -1, -1, ref m_cancel);
+        }
+
+        /// <summary>
+        /// The connection to the server
+        /// </summary>
+        public IServerConnection Connection { get { return m_connection; } }
+        /// <summary>
+        /// The list of maps to proccess
+        /// </summary>
+        public List<BatchMap> Maps { get { return m_maps; } }
+
+        /// <summary>
+        /// The tile settings
+        /// </summary>
+        public TileSettings Config { get { return m_tileSettings; } }
+
+        /// <summary>
+        /// Gets a flag indicating if the rendering process is cancelled
+        /// </summary>
+        public bool Cancel { get { return m_cancel; } }
+    }
+
+    /// <summary>
+    /// Class that represents a single map to build tiles for
+    /// </summary>
+    public class BatchMap
+    {
+        /// <summary>
+        /// A reference to the parent, and thus the connection
+        /// </summary>
+        private BatchSettings m_parent;
+        /// <summary>
+        /// The map read from MapGuide
+        /// </summary>
+        private IMapDefinition m_mapdefinition;
+
+        /// <summary>
+        /// The max extent of the map
+        /// </summary>
+        private IEnvelope m_maxExtent;
+
+        /// <summary>
+        /// The list of baselayer group names
+        /// </summary>
+        private string[] m_groups;
+
+        /// <summary>
+        /// For each entry there is two longs, row and column
+        /// </summary>
+        private long[][] m_dimensions;
+
+        /// <summary>
+        /// The max scale for the map
+        /// </summary>
+        private double m_maxscale;
+
+        /// <summary>
+        /// Conversion from supplied scaleindex to actual scaleindex
+        /// </summary>
+        private int[] m_scaleindexmap;
+
+        /// <summary>
+        /// The number of meters in an inch
+        /// </summary>
+        private const double INCH_TO_METER = 0.0254;
+
+        /// <summary>
+        /// Gets the list of groups
+        /// </summary>
+        public string[] Groups { get { return m_groups; } }
+
+        /// <summary>
+        /// The number of tiles to offset the row counter with
+        /// </summary>
+        private int m_rowTileOffset = 0;
+
+        /// <summary>
+        /// The number of tiles to offset the col counter with
+        /// </summary>
+        private int m_colTileOffset = 0;
+
+        /// <summary>
+        /// The tile offset for row indexes for tiles
+        /// </summary>
+        public int RowTileOffset { get { return m_rowTileOffset; } }
+
+        /// <summary>
+        /// The tile offset for col indexes for tiles
+        /// </summary>
+        public int ColTileOffset { get { return m_colTileOffset; } }
+
+        //The map's scales may have been modified, this array is a map of the new values
+        public int[] ScaleIndexMap { get { return m_scaleindexmap; } }
+
+        /// <summary>
+        /// Constructs a new map to be processed
+        /// </summary>
+        /// <param name="parent">The parent entry</param>
+        /// <param name="map">The resource id for the mapdefinition</param>
+        public BatchMap(BatchSettings parent, string map)
+        {
+            m_parent = parent;
+            m_mapdefinition = (IMapDefinition)parent.Connection.ResourceService.GetResource(map);
+            var baseMap = m_mapdefinition.BaseMap;
+
+            if (baseMap != null &&
+                baseMap.ScaleCount > 0)
+            {
+                m_groups = new string[baseMap.GroupCount];
+                for (int i = 0; i < baseMap.GroupCount; i++)
+                    m_groups[i] = baseMap.GetGroupAt(i).Name;
+
+                m_maxscale = baseMap.GetMaxScale();
+                CalculateDimensions();
+            }
+        }
+
+        public void CalculateDimensions()
+        {
+            int[] tmp = new int[this.Map.BaseMap.ScaleCount];
+            for (int i = 0; i < tmp.Length; i++)
+                tmp[i] = i;
+
+            SetScales(tmp);
+        }
+
+        public void CalculateDimensionsInternal()
+        {
+            if (m_mapdefinition.BaseMap.ScaleCount == 0)
+            {
+                m_scaleindexmap = new int[0];
+                m_dimensions = new long[0][];
+                return;
+            }
+
+            IEnvelope extents = this.MaxExtent ?? m_mapdefinition.Extents;
+            double maxscale = m_maxscale;
+
+            m_dimensions = new long[this.Resolutions][];
+            m_scaleindexmap = new int[m_dimensions.Length];
+            
+            double width_in_meters = Math.Abs(m_parent.Config.MetersPerUnit * (extents.MaxX - extents.MinX));
+            double height_in_meters = Math.Abs(m_parent.Config.MetersPerUnit * (extents.MaxY - extents.MinY));
+
+            m_dimensions = new long[this.Resolutions][];
+            for (int i = this.Resolutions - 1; i >= 0; i--)
+            {
+                long rows, cols;
+                double scale = m_mapdefinition.BaseMap.GetScaleAt(i);
+
+                if (m_parent.Config.UseOfficialMethod)
+                {
+                    //This is the algorithm proposed by the MapGuide team:
+                    //http://www.nabble.com/Pre-Genererate--tiles-for-the-entire-map-at-all-pre-defined-zoom-scales-to6074037.html#a6078663
+                    
+                    //The tile extent in meters
+                    double tileWidth  =((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileWidth) * (scale));
+                    double tileHeight = ((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileHeight) * (scale));
+
+                    //Using this algorithm, yields a negative number of columns/rows, if the max scale is larger than the max extent of the map.
+                    rows = Math.Max(1, (int)Math.Ceiling((height_in_meters / tileHeight)));
+                    cols = Math.Max(1, (int)Math.Ceiling((width_in_meters / tileWidth)));
+
+                    if (m_maxExtent != null)
+                    {
+                        //The extent is overridden, so we need to adjust the start offsets
+                        double offsetX = MaxExtent.MinX - m_mapdefinition.Extents.MinX;
+                        double offsetY = MaxExtent.MinY - m_mapdefinition.Extents.MinY;
+                        m_rowTileOffset = (int)Math.Ceiling(offsetY / tileHeight);
+                        m_colTileOffset = (int)Math.Ceiling(offsetX / tileWidth);
+                    }
+                }
+                else
+                {
+                    //This method assumes that the max scale is displayed on a screen with resolution 1920x1280.
+                    //This display width/height is then multiplied up to calculate the pixelwidth of all subsequent
+                    //scale ranges. Eg. if max scale range is 1:200, then scale range 1:100 is twice the size,
+                    //meaning the full map at 1:100 fills 3840x2560 pixels.
+                    //The width/height is then used to calculate the number of rows and columns of 300x300 pixel tiles.
+                    
+                    //The purpose of this method is to enabled tile generation without access to
+                    //coordinate system properties
+
+                    long pw = (long)(m_parent.Config.DisplayResolutionWidth * (1 / (scale / maxscale)));
+                    long ph = (long)(m_parent.Config.DisplayResolutionHeight * (1 / (scale / maxscale)));
+
+                    rows = (ph + (m_parent.Config.TileHeight - 1)) / m_parent.Config.TileHeight;
+                    cols = (pw + (m_parent.Config.TileWidth - 1)) / m_parent.Config.TileWidth;
+                    rows += rows % 2;
+                    cols += cols % 2;
+                }
+
+
+                m_dimensions[i] = new long[] {rows, cols};
+            }
+        }
+
+        public void SetGroups(string[] groups)
+        {
+            List<string> g = new List<string>();
+            for(int i = 0; i < m_groups.Length; i++)
+                if (Array.IndexOf<string>(groups, m_groups[i]) >= 0)
+                    g.Add(m_groups[i]);
+
+            m_groups = g.ToArray();
+        }
+
+        public void SetScales(int[] scaleindexes)
+        {
+            //TODO: Re-read scales from mapdef?
+            SortedList<int, int> s = new SortedList<int, int>();
+            foreach (int i in scaleindexes)
+                if (!s.ContainsKey(i))
+                    s.Add(i, i);
+
+            List<int> keys = new List<int>(s.Keys);
+            keys.Reverse();
+
+            for (int i = m_mapdefinition.BaseMap.ScaleCount - 1; i >= 0; i--)
+                if (!keys.Contains(i))
+                    m_mapdefinition.BaseMap.RemoveScaleAt(i);
+
+            CalculateDimensionsInternal();
+
+            keys.Reverse();
+
+            //Preserve the original scales
+            m_scaleindexmap = new int[keys.Count];
+            for (int i = 0; i < keys.Count; i++)
+                m_scaleindexmap[i] = keys[i];
+        }
+
+        public void LimitCols(long limit)
+        {
+            foreach (long[] d in m_dimensions)
+                d[1] = Math.Min(limit, d[1]);
+        }
+
+        public void LimitRows(long limit)
+        {
+            foreach (long[] d in m_dimensions)
+                d[0] = Math.Min(limit, d[0]);
+        }
+
+        public long TotalTiles
+        {
+            get
+            {
+                long t = 0;
+                foreach (long[] d in m_dimensions)
+                    t += d[0] * d[1];
+                return t;
+            }
+        }
+
+        /// <summary>
+        /// Gets the number of resolutions for the map
+        /// </summary>
+        public int Resolutions
+        {
+            get
+            {
+                if (m_mapdefinition.BaseMap == null || m_mapdefinition.BaseMap.ScaleCount == 0)
+                    return 0;
+                else
+                    return m_mapdefinition.BaseMap.ScaleCount;
+            }
+        }
+
+
+        /// <summary>
+        /// Renders all tiles in a given scale
+        /// </summary>
+        /// <param name="scaleindex">The scale to render</param>
+        /// <param name="group">The name of the baselayer group</param>
+        public void RenderScale(int scaleindex, string group)
+        {
+            m_parent.InvokeBeginRendering(this, group, scaleindex);
+
+            if (!m_parent.Cancel)
+            {
+                int rows = (int)m_dimensions[scaleindex][0];
+                int cols = (int)m_dimensions[scaleindex][1];
+
+                //If the MaxExtents are different from the actual bounds, we need a start offset offset
+
+                RenderThreads settings = new RenderThreads(this, m_parent, m_scaleindexmap[scaleindex], group, m_mapdefinition.ResourceID, rows, cols, m_rowTileOffset, m_colTileOffset, m_parent.Config.RandomizeTileSequence);
+                
+                settings.RunAndWait();
+
+                if (settings.TileSet.Count != 0 && !m_parent.Cancel)
+                    throw new Exception(Properties.Resources.TS_ThreadFailureError);
+            }
+
+            m_parent.InvokeFinishRendering(this, group, scaleindex);
+
+        }
+
+
+        /// <summary>
+        /// Renders all tiles in all scales
+        /// </summary>
+        /// <param name="group">The name of the baselayer group</param>
+        public void RenderGroup(string group)
+        {
+            m_parent.InvokeBeginRendering(this, group);
+
+            if (!m_parent.Cancel)
+            {
+
+                for (int i = this.Resolutions - 1; i >= 0; i--)
+                    if (m_parent.Cancel)
+                        break;
+                    else
+                        RenderScale(i, group);
+            }
+
+            m_parent.InvokeFinishRendering(this, group);
+
+        }
+
+        /// <summary>
+        /// Renders all tiles in all groups in all scales
+        /// </summary>
+        public void Render()
+        {
+            m_parent.InvokeBeginRendering(this);
+
+            if (!m_parent.Cancel)
+                foreach (string s in m_groups)
+                    if (m_parent.Cancel)
+                        break;
+                    else
+                        RenderGroup(s);
+
+            m_parent.InvokeFinishRendering(this);
+        }
+
+        /// <summary>
+        /// Gets or sets the maximum extent used to calculate the tiles
+        /// </summary>
+        public IEnvelope MaxExtent
+        {
+            get
+            {
+                return m_maxExtent;
+            }
+            set
+            {
+                m_maxExtent = value;
+                CalculateDimensions();
+            }
+        }
+
+        /// <summary>
+        /// Gets the resourceId for the map
+        /// </summary>
+        public string ResourceId { get { return m_mapdefinition.ResourceID; } }
+
+        /// <summary>
+        /// Gets the MapDefintion
+        /// </summary>
+        public IMapDefinition Map { get { return m_mapdefinition; } }
+
+        /// <summary>
+        /// Gets a reference to the parent
+        /// </summary>
+        public BatchSettings Parent { get { return m_parent; } }
+    }
+
+    public class TileSettings
+    {
+        public double MetersPerUnit = 1;
+        public double DPI = 96;
+        public int TileWidth = 300;
+        public int TileHeight = 300;
+        public int RetryCount = 5;
+        public int DisplayResolutionWidth = 1920;
+        public int DisplayResolutionHeight = 1280;
+        public bool UseOfficialMethod = false;
+        public bool RandomizeTileSequence = false;
+        private int m_threadCount = 1;
+        public int ThreadCount
+        {
+            get { return m_threadCount; }
+            set { m_threadCount = Math.Max(1, value); }
+        }
+
+        public RenderMethodDelegate RenderMethod;
+        public delegate void RenderMethodDelegate(string map, string group, int col, int row, int scale);
+    }
+}

Added: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/RenderThread.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/RenderThread.cs	                        (rev 0)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Tile/RenderThread.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -0,0 +1,375 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using System.Threading;
+
+namespace OSGeo.MapGuide.MaestroAPI.Tile
+{
+    public class RenderThreads
+    {
+        private class EventPassing
+        {
+            public enum EventType
+            {
+                Begin,
+                Finish,
+                Error
+            }
+
+            public EventType Type;
+            public int Col;
+            public int Row;
+            public Exception Exception;
+            public EventWaitHandle Event;
+            public object Result = null;
+
+            public EventPassing(EventType type, int row, int col, Exception ex, EventWaitHandle @event)
+            {
+                this.Type = type;
+                this.Event = @event;
+                this.Col = col;
+                this.Row = row;
+                this.Exception = ex;
+            }
+        }
+
+        public Queue<KeyValuePair<int, int>> TileSet;
+        private Queue<EventPassing> RaiseEvents = new Queue<EventPassing>();
+        private object SyncLock;
+        private AutoResetEvent Event;
+        private int CompleteFlag;
+        private BatchSettings Parent;
+        private int Scale;
+        private string Group;
+        private string MapDefinition;
+        private BatchMap Invoker;
+
+        private bool Randomize;
+        private int Rows;
+        private int Cols;
+        private int RowOffset;
+        private int ColOffset;
+
+        private bool FillerComplete = false;
+
+        public RenderThreads(BatchMap invoker, BatchSettings parent, int scale, string group, string mapdef, int rows, int cols, int rowOffset, int colOffset, bool randomize)
+        {
+            TileSet = new Queue<KeyValuePair<int, int>>();
+            SyncLock = new object();
+            Event = new AutoResetEvent(false);
+            CompleteFlag = parent.Config.ThreadCount;
+            RaiseEvents = new Queue<EventPassing>();
+            this.Scale = scale;
+            this.Group = group;
+            this.Parent = parent;
+            this.MapDefinition = mapdef;
+            this.Invoker = invoker;
+            Randomize = randomize;
+            Rows = rows;
+            Cols = cols;
+            this.RowOffset = rowOffset;
+            this.ColOffset = colOffset;
+        }
+
+        public void RunAndWait()
+        {
+            ThreadPool.QueueUserWorkItem(
+                new WaitCallback(QueueFiller));
+
+            for (int i = 0; i < Parent.Config.ThreadCount; i++)
+            {
+                ThreadPool.QueueUserWorkItem(
+                    new WaitCallback(ThreadRender));
+            }
+
+            bool completed = false;
+            while (!completed)
+            {
+                EventPassing eventToRaise = null;
+                while(true)
+                {
+                    lock (SyncLock)
+                        if (RaiseEvents.Count > 0)
+                            eventToRaise = RaiseEvents.Dequeue();
+
+                    if (eventToRaise == null)
+                    {
+                        //No more events
+                        break;
+                    }
+                    else
+                    {
+                        switch (eventToRaise.Type)
+                        {
+                            case EventPassing.EventType.Begin:
+                                Parent.InvokeBeginRendering(
+                                    Invoker,
+                                    Group,
+                                    Scale,
+                                    eventToRaise.Row,
+                                    eventToRaise.Col);
+                                break;
+                            case EventPassing.EventType.Finish:
+                                Parent.InvokeFinishRendering(
+                                    Invoker,
+                                    Group,
+                                    Scale,
+                                    eventToRaise.Row,
+                                    eventToRaise.Col);
+                                break;
+                            case EventPassing.EventType.Error:
+                                eventToRaise.Result = Parent.InvokeError(
+                                    Invoker,
+                                    Group,
+                                    Scale,
+                                    eventToRaise.Row,
+                                    eventToRaise.Col,
+                                    ref eventToRaise.Exception);
+                                break;
+                            default: 
+                                throw new Exception("Bad event type"); //Not translated, because it is an internal error that should never happen
+                        }
+                        eventToRaise.Event.Set();
+                        eventToRaise = null;
+                    }
+                }
+
+                lock (SyncLock)
+                    if (CompleteFlag == 0 && RaiseEvents.Count == 0)
+                        completed = true;
+
+                if (!completed)
+                    Event.WaitOne(5 * 1000, true);
+            }
+        }
+
+        /// <summary>
+        /// Helper that fills the queue from a thread
+        /// </summary>
+        /// <param name="dummy">Unused parameter</param>
+        private void QueueFiller(object dummy)
+        {
+            try
+            {
+                if (Randomize)
+                {
+                    Random ra = new Random();
+                    List<int> rows = new List<int>();
+                    int[] cols_full = new int[Cols];
+                    for (int i = 0; i < Rows; i++)
+                        rows.Add(i);
+
+                    for (int i = 0; i < Cols; i++)
+                        cols_full[i] = i;
+
+                    //TODO: This is not really random, because we select
+                    //a row, and then random columns
+
+                    //Unfortunately, I have yet to find a truly random
+                    //pair generation method that is space efficient :(
+
+                    while (rows.Count > 0)
+                    {
+                        int ri = ra.Next(0, rows.Count);
+                        int r = rows[ri];
+                        rows.RemoveAt(ri);
+
+                        List<int> cols = new List<int>(cols_full);
+
+                        while (cols.Count > 0)
+                        {
+                            int ci = ra.Next(0, cols.Count);
+                            int c = cols[ci];
+                            cols.RemoveAt(ci);
+
+                            AddPairToQueue(r + RowOffset, c + ColOffset);
+                        }
+                    }
+                }
+                else
+                {
+                    //Non-random is straightforward
+                    for (int r = 0; r < Rows; r++)
+                        for (int c = 0; c < Cols; c++)
+                            AddPairToQueue(r + RowOffset, c + ColOffset);
+                }
+            }
+            finally
+            {
+                lock(SyncLock)
+                    FillerComplete = true;
+            }
+
+        }
+
+        /// <summary>
+        /// Helper to add a pair to the queue, but prevents huge queue lists
+        /// </summary>
+        /// <param name="r">The row component of the pair</param>
+        /// <param name="c">The column component of the pair</param>
+        private void AddPairToQueue(int r, int c)
+        {
+            bool added = false;
+            while (!added)
+            {
+                lock (SyncLock)
+                    if (TileSet.Count < 500) //Keep at most 500 items in queue
+                    {
+                        TileSet.Enqueue(new KeyValuePair<int, int>(r, c));
+                        added = true;
+                    }
+
+                if (!added) //Prevent CPU spinning
+                    Thread.Sleep(500);
+            }
+        }
+
+        /// <summary>
+        /// Invokes the render callback method
+        /// </summary>
+        /// <param name="dummy">Unused parameter</param>
+        private void ThreadRender(object dummy)
+        {
+            try
+            {
+                //Create a copy of the connection for local usage
+                IServerConnection con = Parent.Connection.Clone();
+                var tileSvc = (ITileService)con.GetService((int)ServiceType.Tile);
+                AutoResetEvent ev = new AutoResetEvent(false);
+
+
+                while (!Parent.Cancel)
+                {
+                    KeyValuePair<int, int>? round = null;
+
+                    lock (SyncLock)
+                    {
+                        if (TileSet.Count == 0 && FillerComplete)
+                            return; //No more data
+
+                        if (TileSet.Count > 0)
+                            round = TileSet.Dequeue();
+                    }
+
+                    if (Parent.Cancel)
+                        return;
+
+                    if (round == null) //No data, but producer is still running
+                        Thread.Sleep(500);
+                    else
+                        RenderTile(ev, tileSvc, round.Value.Key, round.Value.Value, Scale, Group);
+                }
+
+
+            }
+            catch { }
+            finally
+            {
+                CompleteFlag--;
+                Event.Set();
+            }
+        }
+
+
+        /// <summary>
+        /// Renders a single tile
+        /// </summary>
+        /// <param name="row">The row index of the tile</param>
+        /// <param name="col">The column index of the tile</param>
+        /// <param name="scaleindex">The scale index of the tile</param>
+        /// <param name="group">The name of the baselayer group</param>
+        public void RenderTile(EventWaitHandle ev, ITileService tileSvc, long row, long col, int scaleindex, string group)
+        {
+            ev.Reset();
+            lock (SyncLock)
+            {
+                RaiseEvents.Enqueue(new EventPassing(
+                    EventPassing.EventType.Begin,
+                     (int)row, (int)col, null,
+                     ev
+                    ));
+                Event.Set();
+            }
+            ev.WaitOne(Timeout.Infinite, true);
+
+            int c = Parent.Config.RetryCount;
+            while (c > 0)
+            {
+                c--;
+                try
+                {
+                    if (!Parent.Cancel)
+                        if (Parent.Config.RenderMethod == null)
+                            tileSvc.GetTile(MapDefinition, group, (int)col, (int)row, scaleindex, "PNG").Dispose();
+                        else
+                            Parent.Config.RenderMethod(MapDefinition, group, (int)col, (int)row, scaleindex);
+
+                    break;
+                }
+                catch (Exception ex)
+                {
+                    if (c == 0)
+                    {
+                        Exception pex = ex;
+                        ev.Reset();
+                        EventPassing evobj = new EventPassing(
+                            EventPassing.EventType.Error ,
+                                (int)row, (int)col, ex,
+                                ev
+                                );
+
+                        lock (SyncLock)
+                        {
+                            RaiseEvents.Enqueue(evobj);
+                            Event.Set();
+                        }
+
+                        ev.WaitOne(Timeout.Infinite, true);
+
+                        if (evobj.Result == null)
+                            break;
+
+                        if (pex == evobj.Result)
+                            throw;
+                        else
+                            throw (Exception)evobj.Result;
+                    }
+                }
+            }
+
+            ev.Reset();
+            lock (SyncLock)
+            {
+                RaiseEvents.Enqueue(new EventPassing( 
+                    EventPassing.EventType.Finish,
+                    (int)row, (int)col, null,
+                    ev
+                ));
+                Event.Set();
+            }
+            ev.WaitOne(Timeout.Infinite, true);
+        }
+
+    }
+}

Modified: trunk/Tools/Maestro/Properties/GlobalAssemblyInfo.cs
===================================================================
--- trunk/Tools/Maestro/Properties/GlobalAssemblyInfo.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/Properties/GlobalAssemblyInfo.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -35,5 +35,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("5.0.0.6514")]
-[assembly: AssemblyFileVersion("5.0.0.6514")]
+[assembly: AssemblyVersion("5.0.0.6640")]
+[assembly: AssemblyFileVersion("5.0.0.6640")]

Modified: trunk/Tools/Maestro/RtMapInspector/MainForm.Designer.cs
===================================================================
--- trunk/Tools/Maestro/RtMapInspector/MainForm.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/RtMapInspector/MainForm.Designer.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -39,13 +39,20 @@
             this.rdResourceId = new System.Windows.Forms.RadioButton();
             this.rdMapName = new System.Windows.Forms.RadioButton();
             this.groupBox2 = new System.Windows.Forms.GroupBox();
-            this.trvLayersAndGroups = new System.Windows.Forms.TreeView();
             this.imgList = new System.Windows.Forms.ImageList(this.components);
             this.groupBox3 = new System.Windows.Forms.GroupBox();
             this.properties = new System.Windows.Forms.PropertyGrid();
+            this.tabControl1 = new System.Windows.Forms.TabControl();
+            this.trvLayersAndGroups = new System.Windows.Forms.TreeView();
+            this.TAB_LAYERS = new System.Windows.Forms.TabPage();
+            this.TAB_SELECTION = new System.Windows.Forms.TabPage();
+            this.trvSelection = new System.Windows.Forms.TreeView();
             this.groupBox1.SuspendLayout();
             this.groupBox2.SuspendLayout();
             this.groupBox3.SuspendLayout();
+            this.tabControl1.SuspendLayout();
+            this.TAB_LAYERS.SuspendLayout();
+            this.TAB_SELECTION.SuspendLayout();
             this.SuspendLayout();
             // 
             // groupBox1
@@ -141,26 +148,14 @@
             this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                         | System.Windows.Forms.AnchorStyles.Left)
                         | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox2.Controls.Add(this.trvLayersAndGroups);
+            this.groupBox2.Controls.Add(this.tabControl1);
             this.groupBox2.Location = new System.Drawing.Point(13, 155);
             this.groupBox2.Name = "groupBox2";
             this.groupBox2.Size = new System.Drawing.Size(321, 328);
             this.groupBox2.TabIndex = 1;
             this.groupBox2.TabStop = false;
-            this.groupBox2.Text = "Layers and Groups";
+            this.groupBox2.Text = "Runtime Map";
             // 
-            // trvLayersAndGroups
-            // 
-            this.trvLayersAndGroups.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.trvLayersAndGroups.ImageIndex = 0;
-            this.trvLayersAndGroups.ImageList = this.imgList;
-            this.trvLayersAndGroups.Location = new System.Drawing.Point(3, 16);
-            this.trvLayersAndGroups.Name = "trvLayersAndGroups";
-            this.trvLayersAndGroups.SelectedImageIndex = 0;
-            this.trvLayersAndGroups.Size = new System.Drawing.Size(315, 309);
-            this.trvLayersAndGroups.TabIndex = 0;
-            this.trvLayersAndGroups.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.trvLayersAndGroups_AfterSelect);
-            // 
             // imgList
             // 
             this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream")));
@@ -191,6 +186,61 @@
             this.properties.Size = new System.Drawing.Size(264, 309);
             this.properties.TabIndex = 0;
             // 
+            // tabControl1
+            // 
+            this.tabControl1.Controls.Add(this.TAB_LAYERS);
+            this.tabControl1.Controls.Add(this.TAB_SELECTION);
+            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl1.Location = new System.Drawing.Point(3, 16);
+            this.tabControl1.Name = "tabControl1";
+            this.tabControl1.SelectedIndex = 0;
+            this.tabControl1.Size = new System.Drawing.Size(315, 309);
+            this.tabControl1.TabIndex = 1;
+            // 
+            // trvLayersAndGroups
+            // 
+            this.trvLayersAndGroups.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.trvLayersAndGroups.ImageIndex = 0;
+            this.trvLayersAndGroups.ImageList = this.imgList;
+            this.trvLayersAndGroups.Location = new System.Drawing.Point(3, 3);
+            this.trvLayersAndGroups.Name = "trvLayersAndGroups";
+            this.trvLayersAndGroups.SelectedImageIndex = 0;
+            this.trvLayersAndGroups.Size = new System.Drawing.Size(301, 277);
+            this.trvLayersAndGroups.TabIndex = 0;
+            this.trvLayersAndGroups.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.trvLayersAndGroups_AfterSelect);
+            // 
+            // TAB_LAYERS
+            // 
+            this.TAB_LAYERS.Controls.Add(this.trvLayersAndGroups);
+            this.TAB_LAYERS.Location = new System.Drawing.Point(4, 22);
+            this.TAB_LAYERS.Name = "TAB_LAYERS";
+            this.TAB_LAYERS.Padding = new System.Windows.Forms.Padding(3);
+            this.TAB_LAYERS.Size = new System.Drawing.Size(307, 283);
+            this.TAB_LAYERS.TabIndex = 0;
+            this.TAB_LAYERS.Text = "Layers and Groups";
+            this.TAB_LAYERS.UseVisualStyleBackColor = true;
+            // 
+            // TAB_SELECTION
+            // 
+            this.TAB_SELECTION.Controls.Add(this.trvSelection);
+            this.TAB_SELECTION.Location = new System.Drawing.Point(4, 22);
+            this.TAB_SELECTION.Name = "TAB_SELECTION";
+            this.TAB_SELECTION.Size = new System.Drawing.Size(307, 283);
+            this.TAB_SELECTION.TabIndex = 1;
+            this.TAB_SELECTION.Text = "Current Selection";
+            this.TAB_SELECTION.UseVisualStyleBackColor = true;
+            // 
+            // trvSelection
+            // 
+            this.trvSelection.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.trvSelection.ImageIndex = 0;
+            this.trvSelection.ImageList = this.imgList;
+            this.trvSelection.Location = new System.Drawing.Point(0, 0);
+            this.trvSelection.Name = "trvSelection";
+            this.trvSelection.SelectedImageIndex = 0;
+            this.trvSelection.Size = new System.Drawing.Size(307, 283);
+            this.trvSelection.TabIndex = 0;
+            // 
             // MainForm
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -206,6 +256,9 @@
             this.groupBox1.PerformLayout();
             this.groupBox2.ResumeLayout(false);
             this.groupBox3.ResumeLayout(false);
+            this.tabControl1.ResumeLayout(false);
+            this.TAB_LAYERS.ResumeLayout(false);
+            this.TAB_SELECTION.ResumeLayout(false);
             this.ResumeLayout(false);
 
         }
@@ -221,10 +274,14 @@
         private System.Windows.Forms.RadioButton rdMapName;
         private System.Windows.Forms.Button btnLoad;
         private System.Windows.Forms.GroupBox groupBox2;
-        private System.Windows.Forms.TreeView trvLayersAndGroups;
         private System.Windows.Forms.GroupBox groupBox3;
         private System.Windows.Forms.PropertyGrid properties;
         private System.Windows.Forms.ImageList imgList;
+        private System.Windows.Forms.TabControl tabControl1;
+        private System.Windows.Forms.TabPage TAB_LAYERS;
+        private System.Windows.Forms.TreeView trvLayersAndGroups;
+        private System.Windows.Forms.TabPage TAB_SELECTION;
+        private System.Windows.Forms.TreeView trvSelection;
     }
 }
 

Modified: trunk/Tools/Maestro/RtMapInspector/MainForm.cs
===================================================================
--- trunk/Tools/Maestro/RtMapInspector/MainForm.cs	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/RtMapInspector/MainForm.cs	2012-05-14 16:08:26 UTC (rev 6647)
@@ -446,6 +446,7 @@
             _rtMap = null;
             properties.SelectedObject = null;
             trvLayersAndGroups.Nodes.Clear();
+            trvSelection.Nodes.Clear();
             if (rdMapName.Checked)
             {
                 _rtMap = _mappingSvc.OpenMap(string.Format("Session:{0}//{1}.Map", txtSessionId.Text, txtMapName.Text));
@@ -515,8 +516,43 @@
             {
                 trvLayersAndGroups.EndUpdate();
             }
+
+            var sel = _rtMap.Selection;
+            if (sel != null)
+            {
+                try
+                {
+                    trvSelection.BeginUpdate();
+                    for (int i = 0; i < sel.Count; i++)
+                    {
+                        var rtLayer = sel[i].Layer;
+                        var node = new TreeNode(rtLayer.Name + " (" + sel[i].Count + " objects selected)");
+                        node.Tag = new LayerDecorator(rtLayer);
+                        node.ImageIndex = node.SelectedImageIndex = IDX_LAYER;
+                        trvSelection.Nodes.Add(node);
+                        for (int j = 0; j < sel[i].Count; j++)
+                        {
+                            node.Nodes.Add(Stringify(sel[i][j]));
+                        }
+                    }
+                }
+                finally
+                {
+                    trvSelection.EndUpdate();
+                }
+            }
         }
 
+        static string Stringify(object[] values)
+        {
+            string[] list = new string[values.Length];
+            for (int i = 0; i < values.Length; i++)
+            {
+                list[i] = values[i].ToString();
+            }
+            return string.Join("', '", list);
+        }
+
         private void trvLayersAndGroups_AfterSelect(object sender, TreeViewEventArgs e)
         {
             properties.SelectedObject = e.Node.Tag;

Modified: trunk/Tools/Maestro/RtMapInspector/MainForm.resx
===================================================================
--- trunk/Tools/Maestro/RtMapInspector/MainForm.resx	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/RtMapInspector/MainForm.resx	2012-05-14 16:08:26 UTC (rev 6647)
@@ -112,20 +112,20 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="imgList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+  <metadata name="imgList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
   <data name="imgList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
     <value>
-        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAE
-        DAAAAk1TRnQBSQFMAgEBBQEAAQgBAAEIAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+        DAAAAk1TRnQBSQFMAgEBBQEAARABAAEQAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
         AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
         AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
         AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@@ -154,17 +154,17 @@
         AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
         AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
         AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wEAD/8xAAG8DQcBvDEA
-        AQcB9Qv0AfUBBzEAAe4B9AZzAngBHAKZAfQB7jEAAe4B9AFzARwBeAFzAngBmQEcAZ8BwwEIAfQB7jEA
-        AbwB9AFzARwBeAFzAXgCmQGYAZ8BGwEHAfQBvDEAAbwB9ANzA3gBmAKZAQgBuwH0AbwxAAG8AfUBcwN4
-        ApkBnwGZARsBGQG7AfUBvDEAAbwB9QFzA3gCmQGfAZkB8QHcAboB9QG8MQAB8AH1AXMBeAGZAXgBmQGf
-        AcMBCAEJAdwBugH1AfAxAAHwAfUDeAOZAQgCuwK6AfUB8DEAAfAB/wF4A5kBwwEbAfEBuwLcAboB/wHw
+        AQcB/wv0Af8BBzEAAbwB9AZzAngBHAKZAfQBvDEAAbwB9AFzARwBeAFzAngBmQEcAZ8BwwEIAfQBvDEA
+        AbwB9AFzARwBeAFzAXgCmQGYAZ8BGwEHAfQBvDEAAbwB9ANzA3gBmAKZAQgBuwH0AbwxAAG8Af8BcwN4
+        ApkBnwGZARsBGQG7Af8BvDEAAbwB/wFzA3gCmQGfAZkB8QHcAboB/wG8MQAB8AH/AXMBeAGZAXgBmQGf
+        AcMBCAEJAdwBugH/AfAxAAHwAf8DeAOZAQgCuwK6Af8B8DEAAfAB/wF4A5kBwwEbAfEBuwLcAboB/wHw
         MQAB8AH/AXgDmQHDAcIBCQG6AdwB2wG6Af8B8DEAAfAB/wF4AZgCmQEIArsDugG0Af8B8DEAAfEN/wHx
         MQAB8w3yAfMxAAH/AfQBHAp0ARwB9AL/AfQBHAp0ARwB9CP/AXQImgFSAZoBdAHyA/8BdAiaAVIBmgF0
         AfIC/wHzDLwB8wL/AfMMvAHzAf8CAAGZAZoGegGaAXQBmgHaAZkBAAGTAW4ERQFLA3oBmgF0AZoB2gGZ
         AgAB8QHwCvIB8AHxAgAB8QHwBvIBbgVFAZMCAAGZAZoGegGaAXQBmgHaAZkBAAFvBeMBRQN6AZoBdAGa
         AdoBmQIAAfAM8gHwAgAB8AfyAUUF4wFvAgABmQiaAXQBmgHzAZkBAAGTAW8ERgFMBJoBdAGaAfMBmQIA
         AfAM8gHwAgAB8AfyAW8ERgFFAZMCAAGZCJoBdAGaAfQBmQMAAZkImgF0AZoB9AGZAgAB8QzyAfECAAHx
-        DPIB8QMAAZkImgF0AZoB9QGZAwABmQiaAXQBmgH1AZkCAAHxAfML8gHxAgAB8QHzC/IB8QMAAZkImgJ5
+        DPIB8QMAAZkImgF0AZoB/wGZAwABmQiaAXQBmgH/AZkCAAHxAfML8gHxAgAB8QHzC/IB8QMAAZkImgJ5
         Af8BmQMAAZkImgJ5Af8BmQIAAfEB8wvyAfECAAHxAfML8gHxAwABmQmaAXkBmQH0AwABmQmaAXkBmQH0
         AgAB8QPzCfIB8QIAAfED8wnyAfEDAAGZCZoBoAGZBAABmQmaAaABmQMAAfIG8wfyAgAB8gbzB/IDAAEa
         AaAImgGgARoEAAEaAaAImgGgARoDAAHyAfQK8wH0AfICAAHyAfQK8wH0AfIDAAEaAaAImgGgARoEAAEa


Property changes on: trunk/Tools/Maestro/Thirdparty
___________________________________________________________________
Added: svn:ignore
   + bin


Modified: trunk/Tools/Maestro/build.bat
===================================================================
--- trunk/Tools/Maestro/build.bat	2012-05-13 04:07:19 UTC (rev 6646)
+++ trunk/Tools/Maestro/build.bat	2012-05-14 16:08:26 UTC (rev 6647)
@@ -2,7 +2,7 @@
 SET TYPEACTION=build
 SET TYPEBUILD=Release
 SET PLATFORM=Any CPU
-SET RELEASE_VERSION=5.0.0
+SET RELEASE_VERSION=5.0b1
 SET OLDPATH=%PATH%
 SET PATH=%PATH%;%CD%\Thirdparty\NSIS;C:\Windows\Microsoft.NET\Framework\v4.0.30319
 SET SLNDIR=%CD%
@@ -75,6 +75,10 @@
 pushd Maestro
 %MSBUILD% Maestro_All.sln
 popd
+rem GeoRest addin not ready for prime-time so remove this from output dir
+pushd out\%TYPEBUILD%\AddIns
+rd /S /Q GeoRest
+popd
 pushd UserDoc
 call make.bat html
 popd



More information about the mapguide-commits mailing list