[mapguide-commits] r5321 - in sandbox/maestro-3.0: . Maestro Maestro.Base Maestro.Base/Commands Maestro.Base/Properties Maestro.Base/UI/Preferences Maestro.Login MgCooker MgCooker/Properties MgCooker.Cmd MgCooker.Cmd/Properties OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI.Http

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Oct 22 07:08:30 EDT 2010


Author: jng
Date: 2010-10-22 04:08:30 -0700 (Fri, 22 Oct 2010)
New Revision: 5321

Added:
   sandbox/maestro-3.0/Maestro.Base/Commands/LocalFeatureSourcePreviewCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/MgCookerCommand.cs
   sandbox/maestro-3.0/MgCooker.Cmd/
   sandbox/maestro-3.0/MgCooker.Cmd/MgCooker.Cmd.csproj
   sandbox/maestro-3.0/MgCooker.Cmd/MgCookerLogo.ico
   sandbox/maestro-3.0/MgCooker.Cmd/Program.cs
   sandbox/maestro-3.0/MgCooker.Cmd/Properties/
   sandbox/maestro-3.0/MgCooker.Cmd/Properties/AssemblyInfo.cs
   sandbox/maestro-3.0/MgCooker/
   sandbox/maestro-3.0/MgCooker/BatchSettings.cs
   sandbox/maestro-3.0/MgCooker/CommandLineParser.cs
   sandbox/maestro-3.0/MgCooker/MgCooker.csproj
   sandbox/maestro-3.0/MgCooker/MgCookerLogo.ico
   sandbox/maestro-3.0/MgCooker/Program.cs
   sandbox/maestro-3.0/MgCooker/Progress.cs
   sandbox/maestro-3.0/MgCooker/Progress.designer.cs
   sandbox/maestro-3.0/MgCooker/Progress.resx
   sandbox/maestro-3.0/MgCooker/Properties/
   sandbox/maestro-3.0/MgCooker/Properties/AssemblyInfo.cs
   sandbox/maestro-3.0/MgCooker/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/MgCooker/Properties/Resources.resx
   sandbox/maestro-3.0/MgCooker/Properties/Settings.Designer.cs
   sandbox/maestro-3.0/MgCooker/Properties/Settings.settings
   sandbox/maestro-3.0/MgCooker/RenderThread.cs
   sandbox/maestro-3.0/MgCooker/SetupRun.cs
   sandbox/maestro-3.0/MgCooker/SetupRun.designer.cs
   sandbox/maestro-3.0/MgCooker/SetupRun.resx
Modified:
   sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/OptionsCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/IPreferenceSheet.cs
   sandbox/maestro-3.0/Maestro.Base/UI/Preferences/OptionsDialog.cs
   sandbox/maestro-3.0/Maestro.Login/HttpLoginCtrl.cs
   sandbox/maestro-3.0/Maestro.Login/LoginDialog.cs
   sandbox/maestro-3.0/Maestro.Login/PreferedSite.cs
   sandbox/maestro-3.0/Maestro/Maestro.sln
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ConnectionProviderRegistry.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IServerConnection.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/Envelope.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinitionInterfaces.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs
Log:
3.0 sandbox changes:
 - Port over MgCooker from 2.x
 - Change Options Dialog and API to only prompt restart if changes were applied which requires a restart
 - Add MgCooker.exe shortcuts and MaestroFsPreview.exe shortcuts to the Tools menu

Modified: sandbox/maestro-3.0/Maestro/Maestro.sln
===================================================================
--- sandbox/maestro-3.0/Maestro/Maestro.sln	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro/Maestro.sln	2010-10-22 11:08:30 UTC (rev 5321)
@@ -53,6 +53,10 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maestro.AddIn.ExtendedObjectModels", "..\Maestro.AddIn.ExtendedObjectModels\Maestro.AddIn.ExtendedObjectModels.csproj", "{32BA7DF6-1AFA-441D-9231-5624C5920706}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MgCooker", "..\MgCooker\MgCooker.csproj", "{C7DCF771-5982-4859-A17F-01126E6F9BA6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MgCooker.Cmd", "..\MgCooker.Cmd\MgCooker.Cmd.csproj", "{0FD82B7B-1264-410F-86D1-47E9CCACD68E}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -147,6 +151,14 @@
 		{32BA7DF6-1AFA-441D-9231-5624C5920706}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{32BA7DF6-1AFA-441D-9231-5624C5920706}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{32BA7DF6-1AFA-441D-9231-5624C5920706}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C7DCF771-5982-4859-A17F-01126E6F9BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C7DCF771-5982-4859-A17F-01126E6F9BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C7DCF771-5982-4859-A17F-01126E6F9BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C7DCF771-5982-4859-A17F-01126E6F9BA6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0FD82B7B-1264-410F-86D1-47E9CCACD68E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0FD82B7B-1264-410F-86D1-47E9CCACD68E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0FD82B7B-1264-410F-86D1-47E9CCACD68E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0FD82B7B-1264-410F-86D1-47E9CCACD68E}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -1,4 +1,23 @@
-using System;
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// 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 ICSharpCode.Core;

Added: sandbox/maestro-3.0/Maestro.Base/Commands/LocalFeatureSourcePreviewCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/LocalFeatureSourcePreviewCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/LocalFeatureSourcePreviewCommand.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,56 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// 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 ICSharpCode.Core;
+using Maestro.Base.UI.Preferences;
+using System.IO;
+using Maestro.Shared.UI;
+using System.Diagnostics;
+
+namespace Maestro.Base.Commands
+{
+    internal class LocalFeatureSourcePreviewCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            string exe = PropertyService.Get(ConfigProperties.LocalFsPreviewPath, "");
+
+            if (!File.Exists(exe))
+            {
+                using (var dlg = DialogFactory.OpenFile())
+                {
+                    dlg.Filter = string.Format(Properties.Resources.LocateExecutable, "MaestroFsPreview.exe");
+                    dlg.Filter = Properties.Resources.FilterExecutables;
+                    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+                    {
+                        exe = dlg.FileName;
+                        PropertyService.Set(ConfigProperties.LocalFsPreviewPath, exe);
+                    }
+                }
+            }
+
+            var procInfo = new ProcessStartInfo(exe);
+            procInfo.WorkingDirectory = Path.GetDirectoryName(exe);
+            var proc = Process.Start(procInfo);
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Base/Commands/MgCookerCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/MgCookerCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/MgCookerCommand.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,56 @@
+#region Disclaimer / License
+// Copyright (C) 2010, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// 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 ICSharpCode.Core;
+using System.Diagnostics;
+using System.IO;
+using Maestro.Shared.UI;
+using Maestro.Base.UI.Preferences;
+
+namespace Maestro.Base.Commands
+{
+    internal class MgCookerCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            string exe = PropertyService.Get(ConfigProperties.MgCookerPath, "");
+
+            if (!File.Exists(exe))
+            {
+                using (var dlg = DialogFactory.OpenFile())
+                {
+                    dlg.Title = string.Format(Properties.Resources.LocateExecutable, "MgCooker.exe");
+                    dlg.Filter = Properties.Resources.FilterExecutables;
+                    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+                    {
+                        exe = dlg.FileName;
+                        PropertyService.Set(ConfigProperties.MgCookerPath, exe);
+                    }
+                }
+            }
+
+            var procInfo = new ProcessStartInfo(exe);
+            procInfo.WorkingDirectory = Path.GetDirectoryName(exe);
+            var proc = Process.Start(procInfo);
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/OptionsCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/OptionsCommand.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/OptionsCommand.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -22,6 +22,7 @@
 using System.Text;
 using ICSharpCode.Core;
 using Maestro.Base.UI.Preferences;
+using System.Windows.Forms;
 
 namespace Maestro.Base.Commands
 {
@@ -32,7 +33,13 @@
             var wb = Workbench.Instance;
             using (var dlg = new OptionsDialog())
             {
-                dlg.ShowDialog(wb);
+                if (dlg.ShowDialog(wb) == System.Windows.Forms.DialogResult.OK)
+                {
+                    if (dlg.RestartRequired && MessageService.AskQuestion(Properties.Resources.PrefsRestartRequired))
+                    {
+                        Application.Restart();
+                    }
+                }
             }
         }
     }

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-10-22 11:08:30 UTC (rev 5321)
@@ -144,6 +144,13 @@
         <MenuItem id="Menu_Tools"
                   type="Menu"
                   label="${res:Menu_Tools}">
+            <MenuItem id="MgCooker"
+                      label="${res:MgCooker}"
+                      class="Maestro.Base.Commands.MgCookerCommand"/>
+            <MenuItem id="LocalFsPreview"
+                      label="${res:LocalFsPreview}"
+                      class="Maestro.Base.Commands.LocalFeatureSourcePreviewCommand"/>
+            <MenuItem type="Separator" />
             <MenuItem id="Menu_Tools_Options"
                       label="${res:Menu_Tools_Options}"
                       icon="application_task"

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-22 11:08:30 UTC (rev 5321)
@@ -59,8 +59,10 @@
     <Compile Include="Commands\CutCommand.cs" />
     <Compile Include="Commands\EditAsXmlCommand.cs" />
     <Compile Include="Commands\LoadPackageCommand.cs" />
+    <Compile Include="Commands\LocalFeatureSourcePreviewCommand.cs" />
     <Compile Include="Commands\LoginCommand.cs" />
     <Compile Include="Commands\LogoutCommand.cs" />
+    <Compile Include="Commands\MgCookerCommand.cs" />
     <Compile Include="Commands\NewItemCommand.cs" />
     <Compile Include="Commands\NotImplementedCommand.cs" />
     <Compile Include="Commands\OptionsCommand.cs" />

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -536,6 +536,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Executables|*.exe.
+        /// </summary>
+        internal static string FilterExecutables {
+            get {
+                return ResourceManager.GetString("FilterExecutables", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Validation detected errors in your resource, please fix them before saving this resource.
         /// </summary>
         internal static string FixErrorsBeforeSaving {
@@ -634,6 +643,24 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Local Feature Source Preview.
+        /// </summary>
+        internal static string LocalFsPreview {
+            get {
+                return ResourceManager.GetString("LocalFsPreview", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Locate executable: {0}.
+        /// </summary>
+        internal static string LocateExecutable {
+            get {
+                return ResourceManager.GetString("LocateExecutable", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Message Log saved to {0}.
         /// </summary>
         internal static string Log_Saved {
@@ -881,6 +908,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to MgCooker.
+        /// </summary>
+        internal static string MgCooker {
+            get {
+                return ResourceManager.GetString("MgCooker", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap navigation {
             get {
                 object obj = ResourceManager.GetObject("navigation", resourceCulture);
@@ -958,7 +994,7 @@
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to A restart is required for some changes to take effect.
+        ///   Looks up a localized string similar to A restart is required for some changes to take effect. Restart now?.
         /// </summary>
         internal static string PrefsRestartRequired {
             get {

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-22 11:08:30 UTC (rev 5321)
@@ -662,7 +662,7 @@
     <value>You are about to reset all preferences to default values. Are you sure you want to do this?</value>
   </data>
   <data name="PrefsRestartRequired" xml:space="preserve">
-    <value>A restart is required for some changes to take effect</value>
+    <value>A restart is required for some changes to take effect. Restart now?</value>
   </data>
   <data name="ItemsCopied" xml:space="preserve">
     <value>{0} items copied and placed in clipboard</value>
@@ -745,4 +745,16 @@
   <data name="SiteExplorer_MigrateResources" xml:space="preserve">
     <value>Migrate Selected Resources</value>
   </data>
+  <data name="FilterExecutables" xml:space="preserve">
+    <value>Executables|*.exe</value>
+  </data>
+  <data name="LocalFsPreview" xml:space="preserve">
+    <value>Local Feature Source Preview</value>
+  </data>
+  <data name="MgCooker" xml:space="preserve">
+    <value>MgCooker</value>
+  </data>
+  <data name="LocateExecutable" xml:space="preserve">
+    <value>Locate executable: {0}</value>
+  </data>
 </root>
\ No newline at end of file

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/ConfigProperties.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -35,15 +35,19 @@
         public const string ShowOutboundRequests = "General.ShowOutboundRequests";
         public const string OpenColor = "General.OpenColor";
         public const string DirtyColor = "General.DirtyColor";
+        public const string MgCookerPath = "General.MgCookerPath";
+        public const string LocalFsPreviewPath = "General.LocalFsPreviewPath";
 
         internal static void ApplyDefaults()
         {
             Props.Set(ConfigProperties.PreviewViewerType, "AJAX");
             Props.Set(ConfigProperties.UserTemplatesDirectory, Path.Combine(FileUtility.ApplicationRootPath, "UserTemplates"));
             Props.Set(ConfigProperties.ShowMessages, true);
-            Props.Set(ConfigProperties.ShowOutboundRequests, false);
+            Props.Set(ConfigProperties.ShowOutboundRequests, true);
             Props.Set(ConfigProperties.OpenColor, Color.LightGreen);
             Props.Set(ConfigProperties.DirtyColor, Color.Pink);
+            Props.Set(ConfigProperties.MgCookerPath, Path.Combine(FileUtility.ApplicationRootPath, "MgCooker.exe"));
+            Props.Set(ConfigProperties.LocalFsPreviewPath, Path.Combine(FileUtility.ApplicationRootPath, "MaestroFsPreview.exe"));
         }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -35,15 +35,29 @@
             this.txtTemplatePath = new System.Windows.Forms.TextBox();
             this.btnBrowseTemplatePath = new System.Windows.Forms.Button();
             this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.chkOutbound = new System.Windows.Forms.CheckBox();
             this.chkMessages = new System.Windows.Forms.CheckBox();
-            this.chkOutbound = new System.Windows.Forms.CheckBox();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.label4 = new System.Windows.Forms.Label();
+            this.btnBrowseMgCooker = new System.Windows.Forms.Button();
+            this.txtMgCooker = new System.Windows.Forms.TextBox();
+            this.btnBrowseFsPreview = new System.Windows.Forms.Button();
+            this.txtFsPreview = new System.Windows.Forms.TextBox();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.label5 = new System.Windows.Forms.Label();
+            this.label6 = new System.Windows.Forms.Label();
+            this.cmbOpenedColor = new Maestro.Editors.Common.ColorComboBox();
+            this.cmbModifiedColor = new Maestro.Editors.Common.ColorComboBox();
             this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            this.groupBox3.SuspendLayout();
             this.SuspendLayout();
             // 
             // label1
             // 
             this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(18, 22);
+            this.label1.Location = new System.Drawing.Point(13, 16);
             this.label1.Name = "label1";
             this.label1.Size = new System.Drawing.Size(182, 13);
             this.label1.TabIndex = 0;
@@ -53,7 +67,7 @@
             // 
             this.rdAjax.AutoSize = true;
             this.rdAjax.Checked = true;
-            this.rdAjax.Location = new System.Drawing.Point(231, 20);
+            this.rdAjax.Location = new System.Drawing.Point(226, 14);
             this.rdAjax.Name = "rdAjax";
             this.rdAjax.Size = new System.Drawing.Size(86, 17);
             this.rdAjax.TabIndex = 1;
@@ -64,7 +78,7 @@
             // rdFusion
             // 
             this.rdFusion.AutoSize = true;
-            this.rdFusion.Location = new System.Drawing.Point(231, 44);
+            this.rdFusion.Location = new System.Drawing.Point(226, 38);
             this.rdFusion.Name = "rdFusion";
             this.rdFusion.Size = new System.Drawing.Size(56, 17);
             this.rdFusion.TabIndex = 2;
@@ -74,7 +88,7 @@
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(18, 89);
+            this.label2.Location = new System.Drawing.Point(13, 83);
             this.label2.Name = "label2";
             this.label2.Size = new System.Drawing.Size(101, 13);
             this.label2.TabIndex = 3;
@@ -84,7 +98,7 @@
             // 
             this.txtTemplatePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                         | System.Windows.Forms.AnchorStyles.Right)));
-            this.txtTemplatePath.Location = new System.Drawing.Point(125, 86);
+            this.txtTemplatePath.Location = new System.Drawing.Point(120, 80);
             this.txtTemplatePath.Name = "txtTemplatePath";
             this.txtTemplatePath.ReadOnly = true;
             this.txtTemplatePath.Size = new System.Drawing.Size(291, 20);
@@ -93,7 +107,7 @@
             // btnBrowseTemplatePath
             // 
             this.btnBrowseTemplatePath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-            this.btnBrowseTemplatePath.Location = new System.Drawing.Point(422, 84);
+            this.btnBrowseTemplatePath.Location = new System.Drawing.Point(417, 78);
             this.btnBrowseTemplatePath.Name = "btnBrowseTemplatePath";
             this.btnBrowseTemplatePath.Size = new System.Drawing.Size(25, 23);
             this.btnBrowseTemplatePath.TabIndex = 5;
@@ -107,37 +121,165 @@
                         | System.Windows.Forms.AnchorStyles.Right)));
             this.groupBox1.Controls.Add(this.chkOutbound);
             this.groupBox1.Controls.Add(this.chkMessages);
-            this.groupBox1.Location = new System.Drawing.Point(21, 113);
+            this.groupBox1.Location = new System.Drawing.Point(16, 107);
             this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new System.Drawing.Size(426, 96);
+            this.groupBox1.Size = new System.Drawing.Size(426, 50);
             this.groupBox1.TabIndex = 6;
             this.groupBox1.TabStop = false;
             this.groupBox1.Text = "Show on Startup";
             // 
+            // chkOutbound
+            // 
+            this.chkOutbound.AutoSize = true;
+            this.chkOutbound.Location = new System.Drawing.Point(116, 19);
+            this.chkOutbound.Name = "chkOutbound";
+            this.chkOutbound.Size = new System.Drawing.Size(121, 17);
+            this.chkOutbound.TabIndex = 1;
+            this.chkOutbound.Text = "Outbound Requests";
+            this.chkOutbound.UseVisualStyleBackColor = true;
+            // 
             // chkMessages
             // 
             this.chkMessages.AutoSize = true;
-            this.chkMessages.Location = new System.Drawing.Point(18, 30);
+            this.chkMessages.Location = new System.Drawing.Point(20, 19);
             this.chkMessages.Name = "chkMessages";
             this.chkMessages.Size = new System.Drawing.Size(74, 17);
             this.chkMessages.TabIndex = 0;
             this.chkMessages.Text = "Messages";
             this.chkMessages.UseVisualStyleBackColor = true;
             // 
-            // chkOutbound
+            // groupBox2
             // 
-            this.chkOutbound.AutoSize = true;
-            this.chkOutbound.Location = new System.Drawing.Point(18, 54);
-            this.chkOutbound.Name = "chkOutbound";
-            this.chkOutbound.Size = new System.Drawing.Size(121, 17);
-            this.chkOutbound.TabIndex = 1;
-            this.chkOutbound.Text = "Outbound Requests";
-            this.chkOutbound.UseVisualStyleBackColor = true;
+            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox2.Controls.Add(this.btnBrowseFsPreview);
+            this.groupBox2.Controls.Add(this.txtFsPreview);
+            this.groupBox2.Controls.Add(this.btnBrowseMgCooker);
+            this.groupBox2.Controls.Add(this.label4);
+            this.groupBox2.Controls.Add(this.txtMgCooker);
+            this.groupBox2.Controls.Add(this.label3);
+            this.groupBox2.Location = new System.Drawing.Point(16, 246);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(426, 78);
+            this.groupBox2.TabIndex = 7;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Tool Paths";
             // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(17, 22);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(76, 13);
+            this.label3.TabIndex = 0;
+            this.label3.Text = "MgCooker.exe";
+            // 
+            // label4
+            // 
+            this.label4.AutoSize = true;
+            this.label4.Location = new System.Drawing.Point(17, 48);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(114, 13);
+            this.label4.TabIndex = 1;
+            this.label4.Text = "MaestroFsPreview.exe";
+            // 
+            // btnBrowseMgCooker
+            // 
+            this.btnBrowseMgCooker.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnBrowseMgCooker.Location = new System.Drawing.Point(386, 17);
+            this.btnBrowseMgCooker.Name = "btnBrowseMgCooker";
+            this.btnBrowseMgCooker.Size = new System.Drawing.Size(25, 23);
+            this.btnBrowseMgCooker.TabIndex = 9;
+            this.btnBrowseMgCooker.Text = "...";
+            this.btnBrowseMgCooker.UseVisualStyleBackColor = true;
+            this.btnBrowseMgCooker.Click += new System.EventHandler(this.btnBrowseMgCooker_Click);
+            // 
+            // txtMgCooker
+            // 
+            this.txtMgCooker.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtMgCooker.Location = new System.Drawing.Point(141, 19);
+            this.txtMgCooker.Name = "txtMgCooker";
+            this.txtMgCooker.ReadOnly = true;
+            this.txtMgCooker.Size = new System.Drawing.Size(239, 20);
+            this.txtMgCooker.TabIndex = 8;
+            // 
+            // btnBrowseFsPreview
+            // 
+            this.btnBrowseFsPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnBrowseFsPreview.Location = new System.Drawing.Point(386, 43);
+            this.btnBrowseFsPreview.Name = "btnBrowseFsPreview";
+            this.btnBrowseFsPreview.Size = new System.Drawing.Size(25, 23);
+            this.btnBrowseFsPreview.TabIndex = 11;
+            this.btnBrowseFsPreview.Text = "...";
+            this.btnBrowseFsPreview.UseVisualStyleBackColor = true;
+            this.btnBrowseFsPreview.Click += new System.EventHandler(this.btnBrowseFsPreview_Click);
+            // 
+            // txtFsPreview
+            // 
+            this.txtFsPreview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtFsPreview.Location = new System.Drawing.Point(141, 45);
+            this.txtFsPreview.Name = "txtFsPreview";
+            this.txtFsPreview.ReadOnly = true;
+            this.txtFsPreview.Size = new System.Drawing.Size(239, 20);
+            this.txtFsPreview.TabIndex = 10;
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox3.Controls.Add(this.cmbModifiedColor);
+            this.groupBox3.Controls.Add(this.cmbOpenedColor);
+            this.groupBox3.Controls.Add(this.label6);
+            this.groupBox3.Controls.Add(this.label5);
+            this.groupBox3.Location = new System.Drawing.Point(16, 163);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(426, 77);
+            this.groupBox3.TabIndex = 8;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Site Explorer";
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(17, 25);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(121, 13);
+            this.label5.TabIndex = 0;
+            this.label5.Text = "Opened Resource Color";
+            // 
+            // label6
+            // 
+            this.label6.AutoSize = true;
+            this.label6.Location = new System.Drawing.Point(17, 52);
+            this.label6.Name = "label6";
+            this.label6.Size = new System.Drawing.Size(123, 13);
+            this.label6.TabIndex = 1;
+            this.label6.Text = "Modified Resource Color";
+            // 
+            // cmbOpenedColor
+            // 
+            this.cmbOpenedColor.FormattingEnabled = true;
+            this.cmbOpenedColor.Location = new System.Drawing.Point(187, 22);
+            this.cmbOpenedColor.Name = "cmbOpenedColor";
+            this.cmbOpenedColor.Size = new System.Drawing.Size(121, 21);
+            this.cmbOpenedColor.TabIndex = 2;
+            // 
+            // cmbModifiedColor
+            // 
+            this.cmbModifiedColor.FormattingEnabled = true;
+            this.cmbModifiedColor.Location = new System.Drawing.Point(187, 49);
+            this.cmbModifiedColor.Name = "cmbModifiedColor";
+            this.cmbModifiedColor.Size = new System.Drawing.Size(121, 21);
+            this.cmbModifiedColor.TabIndex = 3;
+            // 
             // GeneralPreferencesCtrl
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.groupBox2);
             this.Controls.Add(this.groupBox1);
             this.Controls.Add(this.btnBrowseTemplatePath);
             this.Controls.Add(this.txtTemplatePath);
@@ -146,9 +288,13 @@
             this.Controls.Add(this.rdAjax);
             this.Controls.Add(this.label1);
             this.Name = "GeneralPreferencesCtrl";
-            this.Size = new System.Drawing.Size(459, 225);
+            this.Size = new System.Drawing.Size(459, 336);
             this.groupBox1.ResumeLayout(false);
             this.groupBox1.PerformLayout();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -165,5 +311,17 @@
         private System.Windows.Forms.GroupBox groupBox1;
         private System.Windows.Forms.CheckBox chkOutbound;
         private System.Windows.Forms.CheckBox chkMessages;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.Button btnBrowseFsPreview;
+        private System.Windows.Forms.TextBox txtFsPreview;
+        private System.Windows.Forms.Button btnBrowseMgCooker;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.TextBox txtMgCooker;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.Label label5;
+        private Maestro.Editors.Common.ColorComboBox cmbModifiedColor;
+        private Maestro.Editors.Common.ColorComboBox cmbOpenedColor;
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -36,6 +36,8 @@
         public GeneralPreferencesCtrl()
         {
             InitializeComponent();
+            cmbModifiedColor.ResetColors();
+            cmbOpenedColor.ResetColors();
         }
 
         protected override void OnLoad(EventArgs e)
@@ -54,6 +56,12 @@
             chkMessages.Checked = msg;
             var outb = Props.Get(ConfigProperties.ShowOutboundRequests, true);
             chkOutbound.Checked = outb;
+
+            txtFsPreview.Text = Props.Get(ConfigProperties.LocalFsPreviewPath, "");
+            txtMgCooker.Text = Props.Get(ConfigProperties.MgCookerPath, "");
+
+            cmbOpenedColor.CurrentColor = Props.Get(ConfigProperties.OpenColor, Color.LightGreen);
+            cmbModifiedColor.CurrentColor = Props.Get(ConfigProperties.DirtyColor, Color.Pink);
         } 
 
         public string Title
@@ -66,16 +74,39 @@
             get { return this; }
         }
 
-        public void ApplyChanges()
+        private bool Apply(string key, object newValue)
         {
+            if (Props.Get(key).Equals(newValue))
+                return false;
+
+            Props.Set(key, newValue);
+            return true;
+        }
+
+        public bool ApplyChanges()
+        {
+            bool restart = false;
+
+            //These changes can be applied without restart
             if (rdFusion.Checked)
-                Props.Set(ConfigProperties.PreviewViewerType, "FUSION");
+                Apply(ConfigProperties.PreviewViewerType, "FUSION");
             else
-                Props.Set(ConfigProperties.PreviewViewerType, "AJAX");
+                Apply(ConfigProperties.PreviewViewerType, "AJAX");
 
-            Props.Set(ConfigProperties.UserTemplatesDirectory, txtTemplatePath.Text);
-            Props.Set(ConfigProperties.ShowMessages, chkMessages.Checked);
-            Props.Set(ConfigProperties.ShowOutboundRequests, chkOutbound.Checked);
+            Apply(ConfigProperties.UserTemplatesDirectory, txtTemplatePath.Text);
+            Apply(ConfigProperties.MgCookerPath, txtMgCooker.Text);
+            Apply(ConfigProperties.LocalFsPreviewPath, txtFsPreview.Text);
+            Apply(ConfigProperties.OpenColor, (Color)cmbOpenedColor.CurrentColor);
+            Apply(ConfigProperties.DirtyColor, (Color)cmbModifiedColor.CurrentColor);
+
+            //These changes require restart
+            if (Apply(ConfigProperties.ShowMessages, chkMessages.Checked ? "True" : "False"))
+                restart = true;
+
+            if (Apply(ConfigProperties.ShowOutboundRequests, chkOutbound.Checked ? "True" : "False"))
+                restart = true;
+
+            return restart;
         }
 
         private void btnBrowseTemplatePath_Click(object sender, EventArgs e)
@@ -95,9 +126,30 @@
             ConfigProperties.ApplyDefaults();
         }
 
-        public bool RequiresRestart
+        private void btnBrowseMgCooker_Click(object sender, EventArgs e)
         {
-            get { return true; }
+            using (var dlg = DialogFactory.OpenFile())
+            {
+                dlg.Title = string.Format(Properties.Resources.LocateExecutable, "MgCooker.exe");
+                dlg.Filter = Properties.Resources.FilterExecutables;
+                if (dlg.ShowDialog() == DialogResult.OK)
+                {
+                    txtMgCooker.Text = dlg.FileName;
+                }
+            }
         }
+
+        private void btnBrowseFsPreview_Click(object sender, EventArgs e)
+        {
+            using (var dlg = DialogFactory.OpenFile())
+            {
+                dlg.Title = string.Format(Properties.Resources.LocateExecutable, "MaestroFsPreview.exe");
+                dlg.Filter = Properties.Resources.FilterExecutables;
+                if (dlg.ShowDialog() == DialogResult.OK)
+                {
+                    txtFsPreview.Text = dlg.FileName;
+                }
+            }
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/IPreferenceSheet.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/IPreferenceSheet.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/IPreferenceSheet.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -30,10 +30,6 @@
     public interface IPreferenceSheet
     {
         /// <summary>
-        /// Indicates whether a restart is required for the applied values to take effect
-        /// </summary>
-        bool RequiresRestart { get; }
-        /// <summary>
         /// Gets the title.
         /// </summary>
         /// <value>The title.</value>
@@ -46,7 +42,7 @@
         /// <summary>
         /// Applies the changes.
         /// </summary>
-        void ApplyChanges();
+        bool ApplyChanges();
         /// <summary>
         /// Applies default values
         /// </summary>

Modified: sandbox/maestro-3.0/Maestro.Base/UI/Preferences/OptionsDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/Preferences/OptionsDialog.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Base/UI/Preferences/OptionsDialog.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -57,18 +57,22 @@
 
         private void btnOK_Click(object sender, EventArgs e)
         {
-            if (SaveChanges())
-                MessageService.ShowMessage(Properties.Resources.PrefsRestartRequired);
+            this.RestartRequired = SaveChanges();
             this.DialogResult = DialogResult.OK;
         }
 
+        public bool RestartRequired
+        {
+            get;
+            private set;
+        }
+
         private bool SaveChanges()
         {
             bool restart = false;
             foreach (IPreferenceSheet sh in _sheets)
             {
-                sh.ApplyChanges();
-                if (sh.RequiresRestart)
+                if (sh.ApplyChanges())
                     restart = true;
             }
             PropertyService.Save();
@@ -80,8 +84,7 @@
         {
             if (MessageService.AskQuestion(Properties.Resources.ConfirmResetPrefs))
             {
-                if (ApplyDefaults())
-                    MessageService.ShowMessage(Properties.Resources.PrefsRestartRequired);
+                this.RestartRequired = ApplyDefaults();
                 this.DialogResult = DialogResult.OK;
             }
         }
@@ -92,8 +95,7 @@
             foreach (IPreferenceSheet sh in _sheets)
             {
                 sh.ApplyDefaults();
-                if (sh.RequiresRestart)
-                    restart = true;
+                restart = true;
             }
             PropertyService.Save();
             LoggingService.Info("Preferences reset with default values");

Modified: sandbox/maestro-3.0/Maestro.Login/HttpLoginCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Login/HttpLoginCtrl.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Login/HttpLoginCtrl.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -145,7 +145,7 @@
             UpdateLoginStatus();
         }
 
-        public PreferedSiteList SiteList
+        public PreferredSiteList SiteList
         {
             get;
             set;

Modified: sandbox/maestro-3.0/Maestro.Login/LoginDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Login/LoginDialog.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Login/LoginDialog.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -35,7 +35,7 @@
         private ILoginCtrl[] _controls;
         private IServerConnection _conn;
 
-        private PreferedSiteList _siteList;
+        private PreferredSiteList _siteList;
 
         private HttpLoginCtrl _http;
         private LocalNativeLoginCtrl _local;
@@ -70,7 +70,7 @@
 
         protected override void OnLoad(EventArgs e)
         {
-            _siteList = PreferedSiteList.Load();
+            _siteList = PreferredSiteList.Load();
 
             if (_siteList.Sites.Length == 0)
             {

Modified: sandbox/maestro-3.0/Maestro.Login/PreferedSite.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Login/PreferedSite.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/Maestro.Login/PreferedSite.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -26,7 +26,7 @@
 	/// <summary>
 	/// Simple list style container for sites
 	/// </summary>
-	public class PreferedSiteList
+	public class PreferredSiteList
 	{
 		private PreferedSite[] m_sites;
         private string m_systemBrowser;
@@ -162,27 +162,27 @@
             }
         }
 
-        public static PreferedSiteList Load()
+        public static PreferredSiteList Load()
         {
             try
             {
                 if (System.IO.File.Exists(AppSettingFile))
                 {
-                    System.Xml.Serialization.XmlSerializer sz = new System.Xml.Serialization.XmlSerializer(typeof(PreferedSiteList));
+                    System.Xml.Serialization.XmlSerializer sz = new System.Xml.Serialization.XmlSerializer(typeof(PreferredSiteList));
                     using (System.IO.FileStream fs = System.IO.File.Open(AppSettingFile, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None))
-                        return (PreferedSiteList)sz.Deserialize(fs);
+                        return (PreferredSiteList)sz.Deserialize(fs);
                 }
             }
             catch
             {
             }
 
-            return new PreferedSiteList();
+            return new PreferredSiteList();
         }
 
         public void Save()
         {
-            System.Xml.Serialization.XmlSerializer sz = new System.Xml.Serialization.XmlSerializer(typeof(PreferedSiteList));
+            System.Xml.Serialization.XmlSerializer sz = new System.Xml.Serialization.XmlSerializer(typeof(PreferredSiteList));
             using (System.IO.FileStream fs = System.IO.File.Open(AppSettingFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None))
             {
                 fs.SetLength(0);


Property changes on: sandbox/maestro-3.0/MgCooker
___________________________________________________________________
Added: svn:ignore
   + bin
obj


Added: sandbox/maestro-3.0/MgCooker/BatchSettings.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/BatchSettings.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/BatchSettings.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -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 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);
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/CommandLineParser.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/CommandLineParser.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/CommandLineParser.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,62 @@
+#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;
+
+namespace Duplicati.CommandLine
+{
+    public static class CommandLineParser
+    {
+        public static Dictionary<string, string> ExtractOptions(List<string> args)
+        {
+            Dictionary<string, string> options = new Dictionary<string, string>();
+
+            for (int i = 0; i < args.Count; i++)
+            {
+                if (args[i].StartsWith("--"))
+                {
+                    string key = null;
+                    string value = null;
+                    if (args[i].IndexOf("=") > 0)
+                    {
+                        key = args[i].Substring(0, args[i].IndexOf("="));
+                        value = args[i].Substring(args[i].IndexOf("=") + 1);
+                    }
+                    else
+                        key = args[i];
+
+                    //Skip the leading --
+                    key = key.Substring(2).ToLower();
+                    if (!string.IsNullOrEmpty(value) && value.Length > 1 && value.StartsWith("\"") && value.EndsWith("\""))
+                        value = value.Substring(1, value.Length - 2);
+
+                    //This is a bit ugly, but we want to preserve the order of "include" and "exclude"
+                    options.Add(key, value);
+
+                    args.RemoveAt(i);
+                    i--;
+                }
+            }
+
+            return options;
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/MgCooker.csproj
===================================================================
--- sandbox/maestro-3.0/MgCooker/MgCooker.csproj	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/MgCooker.csproj	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C7DCF771-5982-4859-A17F-01126E6F9BA6}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MgCooker</RootNamespace>
+    <AssemblyName>MgCooker</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ApplicationIcon>MgCookerLogo.ico</ApplicationIcon>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\out\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\out\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <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">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Progress.designer.cs">
+      <DependentUpon>Progress.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Progress.resx">
+      <DependentUpon>Progress.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="SetupRun.resx">
+      <DependentUpon>SetupRun.cs</DependentUpon>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <Compile Include="RenderThread.cs" />
+    <Compile Include="SetupRun.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="SetupRun.designer.cs">
+      <DependentUpon>SetupRun.cs</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Maestro.Login\Maestro.Login.csproj">
+      <Project>{07588440-5F9F-4C30-AA06-9CF30BA6DDE6}</Project>
+      <Name>Maestro.Login</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI\OSGeo.MapGuide.MaestroAPI.csproj">
+      <Project>{80FA3158-8B5F-48D1-A393-0378AFE48A7E}</Project>
+      <Name>OSGeo.MapGuide.MaestroAPI</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="MgCookerLogo.ico" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/MgCookerLogo.ico
===================================================================
(Binary files differ)


Property changes on: sandbox/maestro-3.0/MgCooker/MgCookerLogo.ico
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: sandbox/maestro-3.0/MgCooker/Program.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Program.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Program.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,421 @@
+#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 Duplicati.CommandLine;
+using Maestro.Login;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI;
+using System.Collections.Specialized;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+
+namespace MgCooker
+{
+    public class Program
+    {
+        private static DateTime beginMap;
+        private static DateTime beginGroup;
+        private static DateTime beginScale;
+        private static DateTime beginTile;
+        private static DateTime lastUpdate;
+
+        private static List<Exception> exceptionList = new List<Exception>();
+        private static List<TimeSpan> tileRuns;
+        private static long tileCount;
+        private static long totalTiles;
+        private static TimeSpan prevDuration;
+        
+        private static long mapCount;
+        private static long groupCount;
+
+        private static bool m_logableProgress = false;
+
+        private static bool hasConsole = true;
+
+        [STAThread()]
+        public static void Main(string[] args)
+        {
+            System.Windows.Forms.Application.EnableVisualStyles();
+            System.Windows.Forms.Application.DoEvents();
+
+            try
+            {
+                PreferredSiteList sites = PreferredSiteList.Load();
+                if (!string.IsNullOrEmpty(sites.GUILanguage))
+                {
+                    System.Threading.Thread.CurrentThread.CurrentUICulture =
+                    System.Threading.Thread.CurrentThread.CurrentCulture =
+                        System.Globalization.CultureInfo.GetCultureInfo(sites.GUILanguage);
+                }
+            }
+            catch
+            {
+            }
+
+
+            //Parameters:
+            //mapagent=
+            //username=
+            //password=
+            //mapdefinition=
+            //scaleindex=0,1,2,3,4,5
+            //basegroups="x","y"
+            //extentoverride=minx,miny,maxx,maxy
+
+            string mapagent = "http://localhost/mapguide";
+            string username = "Anonymous";
+            string password = "";
+            string mapdefinitions = "";
+            string scaleindex = "";
+            string basegroups = "";
+
+            string limitRows = "";
+            string limitCols = "";
+
+            string tileWidth = "";
+            string tileHeight = "";
+
+            string DPI = "";
+            string metersPerUnit = "";
+
+            IEnvelope overrideExtents = null;
+            
+            List<string> largs = new List<string>(args);
+            Dictionary<string, string> opts = CommandLineParser.ExtractOptions(largs);
+            if (opts.ContainsKey("mapagent"))
+                mapagent = opts["mapagent"];
+            if (opts.ContainsKey("username"))
+                username = opts["username"];
+            if (opts.ContainsKey("password"))
+                password = opts["password"];
+            if (opts.ContainsKey("mapdefinitions"))
+                mapdefinitions = opts["mapdefinitions"];
+            if (opts.ContainsKey("scaleindex"))
+                scaleindex = opts["scaleindex"];
+            if (opts.ContainsKey("basegroups"))
+                basegroups = opts["basegroups"];
+
+            if (opts.ContainsKey("limitrows"))
+                limitRows = opts["limitrows"];
+            if (opts.ContainsKey("limitcols"))
+                limitCols = opts["limitcols"];
+
+            if (opts.ContainsKey("tilewidth"))
+                tileWidth = opts["tilewidth"];
+            if (opts.ContainsKey("tileheight"))
+                tileHeight = opts["tileheight"];
+
+            if (opts.ContainsKey("DPI"))
+                DPI = opts["DPI"];
+            if (opts.ContainsKey("metersperunit"))
+                metersPerUnit = opts["metersperunit"];
+            if (opts.ContainsKey("extentoverride"))
+            {
+                string[] parts = opts["extentoverride"].Split(',');
+                if (parts.Length == 4)
+                {
+                    double minx;
+                    double miny;
+                    double maxx;
+                    double maxy;
+                    if (
+                        double.TryParse(parts[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out minx) &&
+                        double.TryParse(parts[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out miny) &&
+                        double.TryParse(parts[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out maxx) &&
+                        double.TryParse(parts[3], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out maxy)
+                        )
+                    {
+                        overrideExtents = ObjectFactory.CreateEnvelope(minx, miny, maxx, maxy);
+                    }
+                }
+            }
+
+
+            try
+            {
+                Console.Clear();
+            }
+            catch
+            {
+                hasConsole = false;
+            }
+
+
+            IServerConnection connection = null;
+
+            string[] maps = mapdefinitions.Split(',');
+
+            SetupRun sr = null;
+            if (!opts.ContainsKey("username") || (!opts.ContainsKey("mapagent")))
+            {
+                if (largs.IndexOf("/commandline") < 0 && largs.IndexOf("commandline") < 0)
+                {
+                    var frm = new LoginDialog();
+                    if (frm.ShowDialog() != System.Windows.Forms.DialogResult.OK)
+                        return;
+
+                    connection = frm.Connection;
+                    try
+                    {
+                        mapagent = connection.GetCustomProperty("BaseUrl").ToString();
+                    }
+                    catch { }
+
+                    sr = new SetupRun(frm.Username, frm.Password, connection, maps, opts);
+                }
+            }
+
+            if (connection == null)
+            {
+                var initP = new NameValueCollection();
+                if (!opts.ContainsKey("native-connection"))
+                {
+                    initP["Url"] = mapagent;
+                    initP["Username"] = username;
+                    initP["Password"] = password;
+                    initP["Locale"] = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
+                    initP["AllowUntestedVersion"] = "true";
+
+                    connection = ConnectionProviderRegistry.CreateConnection("Maestro.Http", initP);
+                }
+                else
+                {
+                    string serverconfig = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "webconfig.ini");
+
+                    initP["ConfigFile"] = serverconfig;
+                    initP["Username"] = username;
+                    initP["Password"] = password;
+                    initP["Locale"] = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
+
+                    connection = ConnectionProviderRegistry.CreateConnection("Maestro.LocalNative", initP);
+                }
+            }
+
+            
+
+            if (largs.IndexOf("batch") < 0 && largs.IndexOf("/batch") < 0)
+            {
+                if (sr == null)
+                    sr = new SetupRun(connection, maps, opts);
+
+                sr.ShowDialog();
+                return;
+            }
+            
+
+            BatchSettings bx = new BatchSettings(connection, maps);
+            if (!string.IsNullOrEmpty(scaleindex))
+            {
+                List<int> scales = new List<int>();
+                int tmp;
+                foreach (string s in scaleindex.Split(','))
+                    if (int.TryParse(s, out tmp))
+                        scales.Add(tmp);
+                bx.SetScales(scales.ToArray());
+            }
+
+            if (!string.IsNullOrEmpty(basegroups))
+            {
+                List<string> groups = new List<string>();
+                foreach (string s in basegroups.Split(','))
+                {
+                    string f = s;
+                    if (f.StartsWith("\""))
+                        f = f.Substring(1);
+                    if (f.EndsWith("\""))
+                        f = f.Substring(0, f.Length - 1);
+                    groups.Add(f);
+                }
+                bx.SetGroups(groups.ToArray());
+            }
+
+            int x;
+
+            if (!string.IsNullOrEmpty(limitCols) && int.TryParse(limitCols, out x))
+                bx.LimitCols(x);
+            if (!string.IsNullOrEmpty(limitRows) && int.TryParse(limitRows, out x))
+                bx.LimitRows(x);
+
+            if (!string.IsNullOrEmpty(tileWidth) && int.TryParse(tileWidth, out x))
+                bx.Config.TileWidth = x;
+            if (!string.IsNullOrEmpty(tileHeight) && int.TryParse(tileHeight, out x))
+                bx.Config.TileHeight = x;
+
+            if (!string.IsNullOrEmpty(DPI) && int.TryParse(DPI, out x))
+                bx.Config.DPI = x;
+
+            double d;
+            if (!string.IsNullOrEmpty(metersPerUnit) && double.TryParse(metersPerUnit, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentCulture, out d))
+            {
+                bx.Config.MetersPerUnit = d;
+                bx.Config.UseOfficialMethod = true;
+            }
+
+            if (opts.ContainsKey("random-tile-order"))
+                bx.Config.RandomizeTileSequence = true;
+
+            if (opts.ContainsKey("threadcount") && int.TryParse(opts["threadcount"], out x) && x > 0)
+                bx.Config.ThreadCount = x;
+
+            if (overrideExtents != null)
+                foreach (BatchMap bm in bx.Maps)
+                    bm.MaxExtent = overrideExtents;
+
+            if (largs.IndexOf("/commandline") < 0 && largs.IndexOf("commandline") < 0)
+            {
+                Progress pg = new Progress(bx);
+                pg.ShowDialog();
+            }
+            else
+            {
+                bx.BeginRenderingMap += new ProgressCallback(bx_BeginRenderingMap);
+                bx.FinishRenderingMap += new ProgressCallback(bx_FinishRenderingMap);
+                bx.BeginRenderingGroup += new ProgressCallback(bx_BeginRenderingGroup);
+                bx.FinishRenderingGroup += new ProgressCallback(bx_FinishRenderingGroup);
+                bx.BeginRenderingScale += new ProgressCallback(bx_BeginRenderingScale);
+                bx.FinishRenderingScale += new ProgressCallback(bx_FinishRenderingScale);
+                bx.BeginRenderingTile += new ProgressCallback(bx_BeginRenderingTile);
+                bx.FinishRenderingTile += new ProgressCallback(bx_FinishRenderingTile);
+
+                bx.FailedRenderingTile += new ErrorCallback(bx_FailedRenderingTile);
+
+                mapCount = 0;
+                lastUpdate = DateTime.Now;
+
+                bx.RenderAll();
+            }
+        }
+
+        static void bx_FailedRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref Exception exception)
+        {
+            exceptionList.Add(exception);
+            exception = null;
+        }
+
+        static void DisplayProgress(BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            if (hasConsole)
+                Console.Clear();
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleUpdateTime.Replace("\\t", "\t"), DateTime.Now));
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleCurrentMap.Replace("\\t", "\t"), map.ResourceId, mapCount, map.Parent.Maps.Count));
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleCurrentGroup.Replace("\\t", "\t"), group, groupCount, map.Map.BaseMap.GroupCount));
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleCurrentScale.Replace("\\t", "\t"), map.Map.BaseMap.GetScaleAt(Array.IndexOf<int>(map.ScaleIndexMap, scaleindex)), Array.IndexOf<int>(map.ScaleIndexMap, scaleindex) + 1, map.Map.BaseMap.ScaleCount));
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleCurrentTile.Replace("\\t", "\t"), tileCount, totalTiles));
+            Console.WriteLine();
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleGroupDuration.Replace("\\t", "\t"), DateTime.Now - beginGroup));
+            Console.WriteLine(string.Format(Properties.Resources.ConsoleGroupEstimate.Replace("\\t", "\t"), new TimeSpan(prevDuration.Ticks * totalTiles)));
+
+            if (exceptionList.Count != 0)
+            {
+                Console.WriteLine();
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleErrorSummary, exceptionList.Count, exceptionList[exceptionList.Count - 1].ToString()));
+            }
+        }
+
+
+        static void bx_FinishRenderingGroup(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            TimeSpan duration = DateTime.Now - beginGroup;
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationFinishGroup, DateTime.Now, group, duration));
+        }
+
+        static void bx_BeginRenderingGroup(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            groupCount++;
+            beginGroup = DateTime.Now;
+
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationBeginGroup, beginGroup, group, 1, 1));
+
+            tileRuns = new List<TimeSpan>();
+            tileCount = 0;
+            totalTiles = map.TotalTiles;
+        }
+
+        static void bx_FinishRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            tileRuns.Add(DateTime.Now - beginTile);
+            tileCount++;
+
+            //Update display, after 1000 tiles
+            if (tileRuns.Count > 500 || (DateTime.Now - lastUpdate).TotalSeconds > 5)
+            {
+                long d = 0;
+                foreach (TimeSpan ts in tileRuns)
+                    d += ts.Ticks;
+
+                d /= tileRuns.Count;
+
+                //For all other than the first calculation, we use the previous counts too
+                if (tileCount != tileRuns.Count)
+                    d = (d + prevDuration.Ticks) / 2;
+
+                prevDuration = new TimeSpan(d);
+                TimeSpan duration = new TimeSpan(d * totalTiles);
+
+                tileRuns.Clear();
+                lastUpdate = DateTime.Now;
+
+
+                if (m_logableProgress)
+                    Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationFinishTile, tileCount, totalTiles, group, duration));
+                else
+                    DisplayProgress(map, group, scaleindex, row, column, ref cancel);
+            }
+        }
+
+        static void bx_BeginRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            beginTile = DateTime.Now;
+        }
+
+        static void bx_FinishRenderingScale(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            TimeSpan duration = DateTime.Now - beginScale;
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationFinishScale, DateTime.Now, map.Map.BaseMap.GetScaleAt(scaleindex), duration));
+        }
+
+        static void bx_BeginRenderingScale(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            beginScale = DateTime.Now;
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationBeginScale, beginMap, map.Map.BaseMap.GetScaleAt(scaleindex), scaleindex, map.Resolutions));
+        }
+
+        static void bx_FinishRenderingMap(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            groupCount = 0;
+            TimeSpan duration = DateTime.Now - beginMap;
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationFinishMap, DateTime.Now, map.ResourceId, duration));
+        }
+
+        static void bx_BeginRenderingMap(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            mapCount++;
+            beginMap = DateTime.Now;
+            if (m_logableProgress)
+                Console.WriteLine(string.Format(Properties.Resources.ConsoleOperationBeginMap, beginMap, map.ResourceId));
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/Progress.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Progress.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Progress.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,220 @@
+#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.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace MgCooker
+{
+    public partial class Progress : Form
+    {
+        private BatchSettings m_bx;
+        private List<TimeSpan> m_tileRuns;
+        private long m_tileCount;
+        private DateTime m_lastUpdate;
+        private DateTime m_beginTile;
+        private TimeSpan m_prevDuration;
+        private long m_totalTiles;
+        private bool m_cancel = false;
+
+        private long m_grandTotalTiles = 0;
+        private long m_grandTotalTileCount = 0;
+        private DateTime m_grandBegin;
+        private bool m_allowClose = true;
+        private long m_failCount = 0;
+
+        private Progress()
+        {
+            InitializeComponent();
+        }
+
+        public Progress(BatchSettings bx)
+            : this()
+        {
+            m_bx = bx;
+            bx.BeginRenderingMap += new ProgressCallback(bx_BeginRenderingMap);
+            bx.BeginRenderingGroup += new ProgressCallback(bx_BeginRenderingGroup);
+            bx.BeginRenderingScale += new ProgressCallback(bx_BeginRenderingScale);
+            bx.BeginRenderingTile += new ProgressCallback(bx_BeginRenderingTile);
+
+            bx.FinishRenderingTile += new ProgressCallback(bx_FinishRenderingTile);
+            bx.FinishRenderingMaps += new ProgressCallback(bx_FinishRenderingMaps);
+            bx.FailedRenderingTile += new ErrorCallback(bx_FailedRenderingTile);
+            m_tileRuns = new List<TimeSpan>();
+
+            m_grandTotalTiles = 0;
+            foreach (BatchMap bm in m_bx.Maps)
+                m_grandTotalTiles += bm.TotalTiles;
+
+            m_grandBegin = DateTime.Now;
+        }
+
+        void bx_FailedRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref Exception exception)
+        {
+            m_failCount++;
+            exception = null; //Eat it
+        }
+
+        private void DoClose()
+        {
+            m_allowClose = true;
+
+            if (m_cancel)
+                this.DialogResult = DialogResult.Cancel;
+            else
+                this.DialogResult = DialogResult.OK;
+
+            this.Close();
+        }
+
+        void bx_FinishRenderingMaps(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            if (this.InvokeRequired)
+                this.Invoke(new System.Threading.ThreadStart(DoClose));
+            else
+                DoClose();
+        }
+
+        void bx_FinishRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            m_tileRuns.Add(DateTime.Now - m_beginTile);
+            m_tileCount++;
+            m_grandTotalTileCount++;
+
+            //Update display, after 1000 tiles
+            if (m_tileRuns.Count > 500 || (DateTime.Now - m_lastUpdate).TotalSeconds > 5 || m_cancel)
+            {
+                long d = 0;
+                foreach (TimeSpan ts in m_tileRuns)
+                    d += ts.Ticks;
+
+                d /= m_tileRuns.Count;
+
+                //For all other than the first calculation, we use the previous counts too
+                if (m_grandTotalTileCount != m_tileRuns.Count)
+                    d = (d + m_prevDuration.Ticks) / 2;
+
+                m_prevDuration = new TimeSpan(d);
+                TimeSpan duration = new TimeSpan(d * m_totalTiles);
+
+                m_tileRuns.Clear();
+                m_lastUpdate = DateTime.Now;
+
+                DisplayProgress(map, group, scaleindex, row, column, ref cancel);
+            }
+        }
+
+        private delegate void DisplayProgressDelegate(BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel);
+
+        private void DisplayProgress(BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            if (m_cancel)
+                cancel = true;
+
+            if (this.InvokeRequired)
+                this.Invoke(new DisplayProgressDelegate(DisplayProgress), new object[] { map, group, scaleindex, row, column, cancel });
+            else
+            {
+                label1.Text = string.Format(Properties.Resources.CurrentGroupStatus, group, map.ResourceId);
+
+                tilePG.Value = (int)Math.Max(Math.Min((m_tileCount / (double)m_totalTiles) * (tilePG.Maximum - tilePG.Minimum), tilePG.Maximum), tilePG.Minimum);
+                totalPG.Value = (int)Math.Max(Math.Min((m_grandTotalTileCount / (double)m_grandTotalTiles) * (totalPG.Maximum - totalPG.Minimum), totalPG.Maximum), totalPG.Minimum);
+
+                if (m_failCount == 0)
+                    tileCounter.Text = string.Format(Properties.Resources.CurrentTileCounter, m_grandTotalTileCount, m_grandTotalTiles, "");
+                else
+                    tileCounter.Text = string.Format(Properties.Resources.CurrentTileCounter, m_grandTotalTileCount, m_grandTotalTiles, string.Format(Properties.Resources.TileErrorCount, m_failCount));
+
+                TimeSpan elapsed = DateTime.Now - m_grandBegin;
+                DateTime finish = DateTime.Now + (new TimeSpan(m_prevDuration.Ticks * m_grandTotalTiles) - elapsed);
+                TimeSpan remain = finish - DateTime.Now;
+
+                if (finish < DateTime.Now)
+                   finishEstimate.Text = Properties.Resources.InsufficientTimePassed;
+                else
+                    finishEstimate.Text = string.Format(Properties.Resources.RemainingTime, finish.ToShortTimeString(), string.Format("{0}:{1}:{2}", (int)Math.Floor(remain.TotalHours), remain.Minutes.ToString("00"), remain.Seconds.ToString("00")));
+            }
+        }
+
+
+        void bx_BeginRenderingTile(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            m_beginTile = DateTime.Now;
+        }
+
+        void bx_BeginRenderingScale(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+        }
+
+        void bx_BeginRenderingGroup(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            m_totalTiles = map.TotalTiles;
+            m_tileCount = 0;
+        }
+
+        void bx_BeginRenderingMap(CallbackStates state, BatchMap map, string group, int scaleindex, int row, int column, ref bool cancel)
+        {
+            m_tileCount = 0;
+        }
+
+        private void BeginRendering()
+        {
+            m_bx.RenderAll();
+        }
+
+        private void Progress_Load(object sender, EventArgs e)
+        {
+            this.Show();
+            m_allowClose = false;
+            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(BeginRendering));
+            t.IsBackground = true;
+            t.Start();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            if (this.m_cancel)
+                MessageBox.Show(this, Properties.Resources.AlreadyAborting, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+            else
+                this.m_cancel = true;
+        }
+
+        private void Progress_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            if (!m_allowClose)
+            {
+                button1_Click(sender, e);
+                e.Cancel = true;
+            }
+        }
+
+        private void PauseBtn_Click(object sender, EventArgs e)
+        {
+            m_bx.PauseEvent.Reset();
+            MessageBox.Show(this, Properties.Resources.PauseMessage, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+            m_bx.PauseEvent.Set();
+        }
+
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/Progress.designer.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Progress.designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Progress.designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,151 @@
+namespace MgCooker
+{
+    partial class Progress
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Progress));
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.label5 = new System.Windows.Forms.Label();
+            this.tilePG = new System.Windows.Forms.ProgressBar();
+            this.totalPG = new System.Windows.Forms.ProgressBar();
+            this.button1 = new System.Windows.Forms.Button();
+            this.label4 = new System.Windows.Forms.Label();
+            this.finishEstimate = new System.Windows.Forms.Label();
+            this.tileCounter = new System.Windows.Forms.Label();
+            this.PauseBtn = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            resources.ApplyResources(this.label1, "label1");
+            this.label1.AutoEllipsis = true;
+            this.label1.Name = "label1";
+            // 
+            // label2
+            // 
+            resources.ApplyResources(this.label2, "label2");
+            this.label2.Name = "label2";
+            // 
+            // label3
+            // 
+            resources.ApplyResources(this.label3, "label3");
+            this.label3.Name = "label3";
+            // 
+            // label5
+            // 
+            resources.ApplyResources(this.label5, "label5");
+            this.label5.Name = "label5";
+            // 
+            // tilePG
+            // 
+            resources.ApplyResources(this.tilePG, "tilePG");
+            this.tilePG.Maximum = 10000;
+            this.tilePG.Name = "tilePG";
+            this.tilePG.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
+            // 
+            // totalPG
+            // 
+            resources.ApplyResources(this.totalPG, "totalPG");
+            this.totalPG.Maximum = 10000;
+            this.totalPG.Name = "totalPG";
+            this.totalPG.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
+            // 
+            // button1
+            // 
+            resources.ApplyResources(this.button1, "button1");
+            this.button1.Name = "button1";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // label4
+            // 
+            resources.ApplyResources(this.label4, "label4");
+            this.label4.Name = "label4";
+            // 
+            // finishEstimate
+            // 
+            resources.ApplyResources(this.finishEstimate, "finishEstimate");
+            this.finishEstimate.AutoEllipsis = true;
+            this.finishEstimate.Name = "finishEstimate";
+            // 
+            // tileCounter
+            // 
+            resources.ApplyResources(this.tileCounter, "tileCounter");
+            this.tileCounter.AutoEllipsis = true;
+            this.tileCounter.Name = "tileCounter";
+            // 
+            // PauseBtn
+            // 
+            resources.ApplyResources(this.PauseBtn, "PauseBtn");
+            this.PauseBtn.Name = "PauseBtn";
+            this.PauseBtn.UseVisualStyleBackColor = true;
+            this.PauseBtn.Click += new System.EventHandler(this.PauseBtn_Click);
+            // 
+            // Progress
+            // 
+            resources.ApplyResources(this, "$this");
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.PauseBtn);
+            this.Controls.Add(this.tileCounter);
+            this.Controls.Add(this.label4);
+            this.Controls.Add(this.finishEstimate);
+            this.Controls.Add(this.button1);
+            this.Controls.Add(this.totalPG);
+            this.Controls.Add(this.tilePG);
+            this.Controls.Add(this.label5);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "Progress";
+            this.Load += new System.EventHandler(this.Progress_Load);
+            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Progress_FormClosing);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.ProgressBar tilePG;
+        private System.Windows.Forms.ProgressBar totalPG;
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.Label finishEstimate;
+        private System.Windows.Forms.Label tileCounter;
+        private System.Windows.Forms.Button PauseBtn;
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/Progress.resx
===================================================================
--- sandbox/maestro-3.0/MgCooker/Progress.resx	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Progress.resx	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,935 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <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>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.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" />
+  <data name="label1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>72, 16</value>
+  </data>
+  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>432, 16</value>
+  </data>
+  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="label1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="label1.Text" xml:space="preserve">
+    <value>Rendering begins...</value>
+  </data>
+  <data name="&gt;&gt;label1.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
+    <value>10</value>
+  </data>
+  <data name="label2.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 16</value>
+  </data>
+  <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>37, 13</value>
+  </data>
+  <data name="label2.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="label2.Text" xml:space="preserve">
+    <value>Status</value>
+  </data>
+  <data name="&gt;&gt;label2.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label2.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
+    <value>9</value>
+  </data>
+  <data name="label3.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label3.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 64</value>
+  </data>
+  <data name="label3.Size" type="System.Drawing.Size, System.Drawing">
+    <value>36, 13</value>
+  </data>
+  <data name="label3.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="label3.Text" xml:space="preserve">
+    <value>Group</value>
+  </data>
+  <data name="&gt;&gt;label3.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label3.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
+    <value>8</value>
+  </data>
+  <data name="label5.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label5.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 88</value>
+  </data>
+  <data name="label5.Size" type="System.Drawing.Size, System.Drawing">
+    <value>31, 13</value>
+  </data>
+  <data name="label5.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="label5.Text" xml:space="preserve">
+    <value>Total</value>
+  </data>
+  <data name="&gt;&gt;label5.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label5.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label5.ZOrder" xml:space="preserve">
+    <value>7</value>
+  </data>
+  <data name="tilePG.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="tilePG.Location" type="System.Drawing.Point, System.Drawing">
+    <value>72, 64</value>
+  </data>
+  <data name="tilePG.Size" type="System.Drawing.Size, System.Drawing">
+    <value>432, 16</value>
+  </data>
+  <data name="tilePG.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <data name="&gt;&gt;tilePG.Name" xml:space="preserve">
+    <value>tilePG</value>
+  </data>
+  <data name="&gt;&gt;tilePG.Type" xml:space="preserve">
+    <value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;tilePG.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;tilePG.ZOrder" xml:space="preserve">
+    <value>6</value>
+  </data>
+  <data name="totalPG.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="totalPG.Location" type="System.Drawing.Point, System.Drawing">
+    <value>72, 88</value>
+  </data>
+  <data name="totalPG.Size" type="System.Drawing.Size, System.Drawing">
+    <value>432, 16</value>
+  </data>
+  <data name="totalPG.TabIndex" type="System.Int32, mscorlib">
+    <value>8</value>
+  </data>
+  <data name="&gt;&gt;totalPG.Name" xml:space="preserve">
+    <value>totalPG</value>
+  </data>
+  <data name="&gt;&gt;totalPG.Type" xml:space="preserve">
+    <value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;totalPG.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;totalPG.ZOrder" xml:space="preserve">
+    <value>5</value>
+  </data>
+  <data name="button1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="button1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>216, 150</value>
+  </data>
+  <data name="button1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>88, 24</value>
+  </data>
+  <data name="button1.TabIndex" type="System.Int32, mscorlib">
+    <value>10</value>
+  </data>
+  <data name="button1.Text" xml:space="preserve">
+    <value>Stop</value>
+  </data>
+  <data name="&gt;&gt;button1.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;button1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;button1.ZOrder" xml:space="preserve">
+    <value>4</value>
+  </data>
+  <data name="label4.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label4.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 112</value>
+  </data>
+  <data name="label4.Size" type="System.Drawing.Size, System.Drawing">
+    <value>34, 13</value>
+  </data>
+  <data name="label4.TabIndex" type="System.Int32, mscorlib">
+    <value>12</value>
+  </data>
+  <data name="label4.Text" xml:space="preserve">
+    <value>Finish</value>
+  </data>
+  <data name="&gt;&gt;label4.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label4.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="finishEstimate.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="finishEstimate.Location" type="System.Drawing.Point, System.Drawing">
+    <value>72, 112</value>
+  </data>
+  <data name="finishEstimate.Size" type="System.Drawing.Size, System.Drawing">
+    <value>432, 16</value>
+  </data>
+  <data name="finishEstimate.TabIndex" type="System.Int32, mscorlib">
+    <value>11</value>
+  </data>
+  <data name="finishEstimate.Text" xml:space="preserve">
+    <value>Not estimated</value>
+  </data>
+  <data name="&gt;&gt;finishEstimate.Name" xml:space="preserve">
+    <value>finishEstimate</value>
+  </data>
+  <data name="&gt;&gt;finishEstimate.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;finishEstimate.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;finishEstimate.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="tileCounter.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="tileCounter.Location" type="System.Drawing.Point, System.Drawing">
+    <value>72, 40</value>
+  </data>
+  <data name="tileCounter.Size" type="System.Drawing.Size, System.Drawing">
+    <value>432, 16</value>
+  </data>
+  <data name="tileCounter.TabIndex" type="System.Int32, mscorlib">
+    <value>13</value>
+  </data>
+  <data name="&gt;&gt;tileCounter.Name" xml:space="preserve">
+    <value>tileCounter</value>
+  </data>
+  <data name="&gt;&gt;tileCounter.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;tileCounter.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;tileCounter.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="PauseBtn.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom, Right</value>
+  </data>
+  <data name="PauseBtn.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="PauseBtn.Location" type="System.Drawing.Point, System.Drawing">
+    <value>424, 152</value>
+  </data>
+  <data name="PauseBtn.Size" type="System.Drawing.Size, System.Drawing">
+    <value>75, 24</value>
+  </data>
+  <data name="PauseBtn.TabIndex" type="System.Int32, mscorlib">
+    <value>14</value>
+  </data>
+  <data name="PauseBtn.Text" xml:space="preserve">
+    <value>Pause</value>
+  </data>
+  <data name="&gt;&gt;PauseBtn.Name" xml:space="preserve">
+    <value>PauseBtn</value>
+  </data>
+  <data name="&gt;&gt;PauseBtn.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;PauseBtn.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;PauseBtn.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
+    <value>6, 13</value>
+  </data>
+  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
+    <value>527, 184</value>
+  </data>
+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        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
+        AD/8AAA//AAAP/wAAB/8AAAf/AAAH/wAAB/8AAA//AAAP/4AAD/+AAB//wAA//+AAP//wAP//+AH///+
+        P/8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA
+        AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAiIiIiIiIiIgAAAAA
+        j/j4+Pj/j/+AAAAAiIiIiIiPh4iAAAAAj4iIiHiPeY+AAAAAiIiIiPj4iIiAAAAAj4+I+IiIiIiAAAAA
+        iPj4j4+Pj48AAAAACIiIiIeIiIgAAAAACPiHyMjHiIgAAAAAAIfH6O6HyIAAAAAAAHjjLn7uh4AAAAAA
+        CI6GNo7I5nAAAAAAB+hnp2juZ2AAAAAACI56do6GdjgAAAAAeOhneOhnpycAAAAAeHaP746GOmcAAAAA
+        hmeoiOjnZ+cAAAAAhqcn746OJjcAAAAAB3p6do6OY2gAAAAAB2PjaOjn7nAAAAAAAGZ2p2bsiAAAAAAA
+        AAdo56d+hwAAAAAAAAB4Znp3AAAAAAAAAAAAiHgAAAAAAPAADwDwAAcA8AAHAPAABwDwAAcA8AAHAPAA
+        DwD4AA8A+AAPAPwAHwD8AB8A+AAfAPgAHwD4AA8A8AAPAPAADwDwAA8A8AAPAPgADwD4AB8A/AA/AP4A
+        PwD/AP8A/8P/ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
+        AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAiIiIiI
+        iAAAD4iIj/iIAAAIiIiIh4gAAA+Pj4j4iAAACIiIiIj4AAAI+Ih4eIAAAAB3bs6HgAAAAI5yjsYAAAAI
+        53p+hnAAAAiGeOhqcAAACGjvjnZwAAAGY46OenAAAAemPo52cAAAAHdnbugAAAAABoY3eAAAAAAAjngA
+        AADgAwAA4AMAAOADAADgAwAA4AMAAOAHAADwBwAA8A8AAOAHAADgBwAA4AcAAOAHAADgBwAA8A8AAPgP
+        AAD8PwAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAABjYHwAnC0rAJ4w
+        LACdMzMAnzg1AJ85OQCgMy4AqD0vAKA2NgCjOjYAojk4AKtBLgCwSC0Aq0MzAKhDPACrSToAs084ALhX
+        PACmQkEAqExEALRURAC9X0EAsVVMAKNTUgCuXFUAsVlVAL1jRwC7ZFEAtGNZALhjXAC+bF8AmmdoAKNl
+        ZQCsb2AAuWhlALttagCrfGMAt3RvAL1xbACtcXIAp3l5ALx7ewDBak8AwWxSAMN3WgDAb2AAxXlkADmJ
+        BwA5jRMAOZMZADSHIwA3liIAOJcgADiZJAA2kiwAN5kuADidKwA3nj4AOaQ3AEGLCwBEjhMAV4kdAEiR
+        FwBYlBcAUpQbAFmWHQBlmBwATZQiAFqXJwBjiyYAaJwmAHKeJABslDcAcZM4AHmhKwBoojwAcqQ8ADms
+        RgB1lUEAfpdMAHqZSAB9qUYAe6lKAIWlLACOqTYAkqs4ALq0PAD7uB4A26k8AOerJADrriUA4KcoAPa1
+        IgD+uyMA87UoAP29LADmrjAA4q48APy+MQD2vT0A/sE2AIaUSQCci1gAlpNXAK6MXAC1h10Ah6xJAI6w
+        TwCVsU4AkrJWALWrQQCltEsAubhHAKi3VQCeimIAmJdkAKiIYwCwi2YAo5xjAJm3YwC1vmAA369IAMK4
+        QADDv1UA0LlUAOezQQDiskgA67xWAOa7XADNi3gA0ZB7ALrBZwCqwHIAt8R5AMjAWQDWwlUA/cZGAOvA
+        XwDtyVkA/MpXAM3EYgDayWkAxsZzANfLdADmyGoA+81lAP3QagD1zngA59J8APzTdwAXF7QAGRmxADY2
+        rAA2NrQAZGKGAG1qmwBOTKcAUE+qAGZkswB6euQAjIaNAJCNjQCYlZUAnZiYAK2PiwC1j48Aop2dAKmd
+        nQC7lJAAu5iXAL6/jgCIhLgAmZe9AKWhoQCopKQAraqpALijogCxra0AuquqALWysgC5trYAvbm5AMyP
+        hQDOkYcA0paHAMKenADRm5cA1aCSANiikADVrpcA1qWeAN2tmgDIqacAyKqoAN2voADas6MAz7SwAMO8
+        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
+        MwD+wjsAgotGAJmERgCXikoAoYFYAK2IWgC1gloAjqVKAJSvRwCdsUQAhrBTAI6yVgCeuFwAobFAAKOv
+        VACguF8AtLtYAKyzYgDPv00AyL5SAOS2UQDnulIAzot2AM6QfgDRkHkA28JQANDAWwDlwUMA6cFCAOfF
+        TQDqw0oA/sRCAP7HSAD9yE0A7MBfAP7KUgD+zFsAzsVmAM3GaQDExXEA0Mp3AN3PeQDlyWMA7s1pAPLM
+        YwD9zmQA8cZqAP3PaQD90GsA+c9yAPzSdQDx030A/dN5ADExswBSUbAAcnCqAGhltQBISMAAhoGXAK6N
+        jACxgoIAv46LAK+dnQC6lpAAupyZAJiSogCEgbwAp6KiAKyjowCopaUArqurALCtrQC1r68As7CwALWy
+        sgC3tLQAubW0AL22tgC6uLgAvbq6AL+8uwDJi4cAyIuJAM+ShADRlIAA1JuCANGXjgDWno4A2aKHANqj
+        igDBs4MA16CQANupmwDdsZAA4bWTAMqwrgDFubkAwry8AMW+vgC5x4IAu8iCAO/JiQDwzYcA5NOIAPTU
+        hAD71YMA/deIAPfYjQD82YoA6sSdAOjYmQD92pIA8NucAPzcmgDrxaEA8M+gAOjYowDl26gA/d6kAPLS
+        qgD936gA/eKyAJmWwQDDwMAAxcHBAMfExADJxcUAzcbGAMvIyADNyckA0srKANHNzQDUz84A3NPTANvU
+        0wDY1tYA3tXVANrY2ADc2dkA39zcAODX1wDi2NgA5NvbAObe3gD95sAA5eLiAO3l5QDu6ekA7uzsAPLr
+        6gDx7e0A8/DwAPTw8AD39PQA////AAAAAAAAAOLGtbW1s7OzsLCwrq6urquuq66rsAAAAAAAAAAAAADi
+        +f39/f39/f39/Pz9/fn9/Pz8/P35sAAAAAAAAAAAAOL967Ozs7Ozs7Ozs7PG/Pj89/T3/P2wAAAAAAAA
+        AAAA4v3rxsbGxcbFxsXGxuT39/enmt/3/bAAAAAAAAAAAADi/Oeura6urq6urq6us/Pz65uenfT8sAAA
+        AAAAAAAAAOL88fHx8fHx8fHx8fHx8vLxn5ym8fmwAAAAAAAAAAAA4vfx8fHx8fHx8fHx8fHx8fHx5/Hx
+        97AAAAAAAAAAAADk5Obn5+fn5+fk5OTk5OTkx+LH4sa1sAAAAAAAAAAAAADi8PDw8PDw8PDw7/Dr7Ovv
+        7Ozs7LAAAAAAAAAAAAAAALP25+zm7OTk4sa1s7Cz4ufp5+z0qgAAAAAAAAAAAAAA5/Dm5ubH58SiGxkZ
+        oKmqq+bm5uziAAAAAAAAAAAAAAAA4uzGxhwFFny9vbkXAQujxsbsqwAAAAAAAAAAAAAAAAC18KUDaTp2
+        eWJhYnrLugKhs+urAAAAAAAAAAAAAAAAAACkB9JsKypyhGVgX15jyxQatQAAAAAAAAAAAAAAAAAAAAjY
+        h38pSylyhmVlX19ecwyhAAAAAAAAAAAAAAAAAAAV15OSlzNLSy1uhmVgYFtVOQQAAAAAAAAAAAAAAAAA
+        AHvNlZdQLktLSzORhGVkX1UtQCQAAAAAAAAAAAAAAAAe3JaZ0ChLS0o1SZCIhoNcOEs1BAAAAAAAAAAA
+        AAAAAB3bl8/bO0tKNsyZlYl4KCwuSiwNAAAAAAAAAAAAAAAAfdHP1HExT2/T1M+XkkdKS0tLSky3AAAA
+        AAAAAAAAAAC90Yw0Mdre3tvUz5eSbi1LS0opTSQAAAAAAAAAAAAAAL5xMCjJUfXe3dvPmZWSVikpRHe/
+        IwAAAAAAAAAAAAAAaiYtSiwpyN7b1M+XkohYJ1g/MWa2AAAAAAAAAAAAAAARKUtLS0spcNXUz5WShn4x
+        KSwsDgAAAAAAAAAAAAAAACI5S0tLS0spNI2XkomFhD8mMzcGAAAAAAAAAAAAAAAAAGcsS0pDNUpGmJeS
+        hoSERYOCwyMAAAAAAAAAAAAAAAAAID5KQ803JYuKN4+FZWBkX88IAAAAAAAAAAAAAAAAAAAAEjkzdUgn
+        WUguM1aDX1+XIQAAAAAAAAAAAAAAAAAAAAAAEk4vbTiQR0pLSlSEzyG7AAAAAAAAAAAAAAAAAAAAAAAA
+        H2jZjlopS0osMsIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAwRBrU0FBZmcQuQAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAwLzBAAAAAAAAAAAAAAAAAAD8AAAf+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/wA
+        AB/8AAAf/AAAH/4AAD/+AAA//wAAf/8AAH/+AAB//gAAP/wAAD/8AAA//AAAH/wAAB/8AAAf/AAAH/wA
+        AD/8AAA//gAAP/4AAH//AAD//4AA///AA///4Af///4//ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
+        AAAAAAAAAAEAAAABAAAAAAAAfXg9AKVfUwCqWVcAqFlYAJ1pTACbf0QAoH5HAKpqWgCxZVcAsW5eALFp
+        YAC+cmcAuHFrALp3bgCkdnYAunh1AMN2ZADEemcAOpcgADyaJgA9nCkAOJ4zADmgMAA5oTQAPaI1ADum
+        OgA+pDgAOaU8AEqNDABViygAR5omAE6YJABAni0ASZ0oAE2bLABQmiIAWZslAFyXKQBUnS0AQp8yAEyb
+        MABPnDgAVpY3AFmdPABmny0AfYY8AHmJOABnnzEAXKAuAECgMABIojkAWKU7AF6mPwBhoi4AZKItAGKj
+        NAB6pTEAOqpCADqrRQA6rEYAOq1IAGKqRwBuqkQAdqdCAHurQgCGpzEAiKs2AIWrOgCHrT4An7A8ANq1
+        LwDStzAA2LgwAPy7JgD+vCUA8LMpAP6/LwDrsjUA67U9AOG9PgD+vzEA/sAyAPbAOQD+wz4A/sU+AIqe
+        TwCkhVoAj6RLAJuxQwCSs04AmLJLAJ6zSgCVtVQAsLVDALiyUwC+s1YAvbxRALa8WAC+gWAAl7hhALK9
+        YQDGvEsA0L1KAMi/VQDCvlgAxodqAMqCbQDJhG8AzIZvAMuFcgDMhnEA1ZVxANWadgDZnXYA2aN9AN66
+        cQD+xEAA8MRIAP7ISwDyx1IA/spTAP7KVQD+zFQA/sxaAP7NXwDZyWwA68FnAPXHYwD+zWAA/c9nAP7P
+        aQD+0GkA+dFvAP3RbgDv0nsA/dJxAPzSdgD30HsA/dV+AFxbuQBYWMwAvJiVAJiSogCKhroAmZS3AK2o
+        qAC7pqYAvainALSqqgC5qakAtrCwALiysgC8tLMAuLa2ALu4uAC+uroAvry8AMOBgADSlYMA05aEANWb
+        iQDTm5AA05yUANKdmADXoZIA26qaAOa8jQDmuZAAxrOyAMG6uQDBvr4A1dCMAM3RlADi0okA/daFAOvD
+        lwD52pQA/duUAP3cmwD43p0A692tAPvfogD94awA/eS4AL24zwDIv8AAwsDAAMXBwQDHxMQAycXFAMzG
+        xgDLyMgAzcnJAM/MzADQxscA0MrKANTKygDRzc0A1M/PANHL2ADU0NAA19TUANvT0wDY1dUA3tXVANvY
+        2ADg1tYA4dnYAOLd3QDm3d0A6uLiAO7m5gDw6uoA9O7uAPbw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAD///8AAAAAAMa9vb2rq52dnZubmpuam5sAAAAAAAAAAMLV0dHR0dHR0dHV19fV
+        19e9AAAAAAAAAMLPmpeal5qXmpvR1MiMudWrAAAAAAAAAMLPm6qqqqqqqqrP0pGNkNO9AAAAAAAAAL/P
+        z8/Pz8/Pz8/Pz8OPutGrAAAAAAAAAJ3GxsbGxsbGxsbGwsK/wr+bAAAAAAAAAL/Rzs7Rz8/KxsrPysrK
+        ysYAAAAAAAAAAADPxsa/v7+qlJWSl7/Gyp0AAAAAAAAAAAC9wrqODQxrawwED5urz5sAAAAAAAAAAAAA
+        xgtXK2BPTk9/cAOTvQAAAAAAAAAAAAAACadgHDJnVE1KTHQClgAAAAAAAAAAAACiqICFIT0yZnVSSkce
+        EAAAAAAAAAAAAABriohaOj09OHxUTUgWAQAAAAAAAAAAAACwiK8/PTpBfnx4Qzc6Kp4AAAAAAAAAAG62
+        r64wPmSxioZZOj09MggAAAAAAAAAAGu0XSCtuLe0r4ZoGz0bIQUAAAAAAAAAAG5AMjQntbe0r4Z8OSBC
+        RgoAAAAAAAAAAKEpPT06NayxioZ5XhMhIQ0AAAAAAAAAAAAvOj06OiFliHx3dh03VqQAAAAAAAAAAABj
+        KBtdITGHaXl1U0l5EQAAAAAAAAAAAAAABiFiLSVcMkRQSlRyAAAAAAAAAAAAAAAAAAcmW2FFPT04gnCi
+        AAAAAAAAAAAAAAAAAABqc1gjMywuEgAAAAAAAAAAAAAAAAAAAAAAAKagoKUAAAAAAAAAAAAA8AAPAPAA
+        BwDwAAcA8AAHAPAABwDwAAcA8AAPAPgADwD4AA8A/AAfAPwAHwD4AB8A+AAfAPgADwDwAA8A8AAPAPAA
+        DwDwAA8A+AAPAPgAHwD8AD8A/gA/AP8A/wD/w/8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
+        AAAAAQAAAAEAAAAAAACMeE0Arnh1ADmlOgA9pTgAPKg/AFCXHwBmjzcAc4k2AGqQOwBaoi4ATqIxAEql
+        OABWpDUAU6g7AHylLwBlpDcAbao7ADqqQwA6q0UAOqxGAGCSQQBCqUEAXaBAAFmsSQCHiT0Ah5E+AJOr
+        MAC5sjMA27w+APq5IwD+visA7b43APG3NgD+wDMAqoZdAIyvQQCSskwAj6lQAJGyUQCdtVIAqLdNAKm3
+        UQCrvFoArI9gALGOYQCykmoAtZRsAJu5ZQCtvGEAoL5tANq3RADMv1IA8L1JANSWYgDDiXwA1LV+AOKp
+        aQDttmEA4ax9AOXBRgD+xkcA/shNAObHXQD+zFoAxch3AOzIZAD+0W0A+tF3AP3TdwD91HwAZGKsALaD
+        ggCqkpIAvri4AMePggDCj4oA05iCAMGZkwDRppMA2a2bANqrowDEsK8Awr+/AP3VgAD914YA+tuaAP3d
+        oAD95LcAop7NALGqwgDDwMAAysPDAMnGxgDKyMgAzcjIAM/MzADSy8sA0c7OANTOzQDW0M8A1tDQANrR
+        0QDZ1dUA3NXUANrT3gDh19cA5d/eAOnj4wDw6OcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAP///wAAAABlYmJgYF5eXl5eXgAAAAAAbEpKSkpKaG1ZaWIAAAAAAGteXl5cXmZqR1pg
+        AAAAAABoYmZiZmJiYl9iUwAAAAAAYmhoYmJfXmZkaF4AAAAAAGJfUkxLNwJJXl4AAAAAAAAATi0XMyE1
+        NkhTAAAAAAAAADtCBA48Ih4aAAAAAAAAAE1EKxQEKT0gDQEAAAAAAAA7VScYQUU0BBQVAAAAAAAAOBAw
+        WFdVPwwMJgAAAAAAAAgUBDJWRUAPCgcAAAAAAAAsFBYEKEM+HBsjAAAAAAAAAAklBioRHR86AAAAAAAA
+        AAAAGjEkFAw5UQAAAAAAAAAAAABQLy9PAAAAAAAA4AMAAOADAADgAwAA4AMAAOADAADgBwAA8AcAAPAP
+        AADgBwAA4AcAAOAHAADgBwAA4AcAAPAPAAD4DwAA/D8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGtrR2qpqVto56ef6Kd
+        nYGhnJyBn5ubgZ6amoGdmZiBnJeXgZqWloGZlJSBmJOTgZaSkoGVkJCBk4+PgZKOjoGRjY2BkIuLgY+K
+        ioGNiYmBjYiIgYyIiIGLh4eBi4eHgYuHh4GLh4eBi4eHgYuHh4GLh4eBi4eHgYuHh4GMiYl7n5ycUJ2a
+        mgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsq6uBKml
+        pda+urr+x8TE/sfExP7Gw8P+xsPD/sXCwv7EwcH+xMHA/sPAwP7Cv7/+wb6+/sC9vf6/vLz+v7y8/r67
+        u/69urr+vLm5/ry5uf67uLj+u7i4/rq3t/66t7f+ube3/rm3t/65t7f+ube3/rm3t/65t7f+ube3/rm3
+        t/62s7P+mJWV/p+cnGkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAubW1F6ahofn39fX++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj0
+        9P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj0
+        9P749PT++PT0/vj09P759vb+xsPD/qKenp0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAvbq6G6eiovv39vX+9Ozs/t7X1/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3H
+        x/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3Hx/7OyMj+6+Tj/vPr6/7z7Ov+8+vr/vPs
+        6/7z6+v+8enp/vDo6P7z6+v+8+vr/vPs6/728fH+yMbG/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovv39fX+8enp/sG6uv6inZ3+op2d/qKd
+        nf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6jnp7+29TU/vDo
+        6P7w6Oj+8Ojo/vDo5/7i3Nz+qKXB/pmXvf7SztH+7ubm/vDo6P707u7+yMbG/qOgoKMAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovv29PT+7eXl/tvU
+        0/7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szG
+        xf7Ox8b+5t7e/uzk5P7t5OT+7OTk/uvi4v6IhLj+GRmx/hcXtP5QT6r+4tvc/u3k5P7x7Ov+yMbG/qOg
+        oKMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6ei
+        ovv18/P+6eHh/rq0tP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2Y
+        mP6dmJj+nZiY/p2YmP6emZn+1MzM/ujf3/7o39/+6N/f/trS0f5OTKf+Nja0/jY2tP42Nqz+ycLM/ujf
+        3/7v6Oj+yMXF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAvrq6G6eiovv08vL+5t3d/uXb2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb
+        2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb2/7k29v+5dvb/uXb2/7l29v+5dvb/tDHx/5tapv+eXni/nx8
+        5v5mZLP+w7u9/uXb2/7s5ub+yMXF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovvz8fH+4tnZ/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX
+        1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uDW
+        1v6jnJ3+Y2B8/mRihv6Mho3+2c/P/uHX1/7q4+P+x8XF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvbm5G6eiovvy8PD+39bW/t7U1P7e1NT+3tTU/t7U
+        1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U
+        1P7e1NT+3tTU/t7U1P7e1NT+0MbG/snAwP7d09P+3tTU/t7U1P7n4OD+x8XF/qOfn6MAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtrKyFKahoffx7+/+7+rq/u/q
+        6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q
+        6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7x7u7+wsDA/p+c
+        nJkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs6+vBKik
+        pOKxra3+ura2/rq2tv66trb+ura2/rq2tv66trb+ura2/rq2tv66trb+ubW1/rm1tf64tLT+t7Sz/raz
+        sv61srL+tbGx/rOwsP6yr6/+sa6u/rCtrP6vrKz+rqur/q2qqv6sqaj+q6io/qqnp/6ppqb+qaWl/qik
+        pP6moqL+kY2N/puYmG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAK+qqpG6trb+2tfX/tvY2P7b2Nj+29jY/tvY2P7b2Nj+29jY/tvY2P7b2Nj+2tjY/trY
+        2P7a19f+2dfX/tnX1/7Z1tb+2NbW/tjW1v7X1dX+19TU/tbU1P7W1NT+1dPT/tXT0/7U0tL+1NLS/tPS
+        0v7T0dH+09HR/tLQ0P7Ixsb+jIiI9JyYmBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+qqjKsp6f97+7u/t3Z2f7b19f+29fX/tvX1/7b19f+29fX/tvX
+        1/7b19f+29fX/trW1v7X09P+1NDQ/tHNzf7QzMz+0MzM/tDNzf7Tz8/+19PT/trW1v7b19f+29fX/tvX
+        1/7b19f+29fX/tvX1/7b19f+29fX/ufk5P7EwsL+ko6OrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGtrQGppaXP3Nra/t/c3P7Uz8/+1M/P/tTP
+        z/7Uz8/+1M/P/tPOzv7KxcX+xsHB/sfBwf7Jw8P+ycTD/sfAwP7Bu7v+urW1/rWvr/6wq6v+rqmp/rCs
+        rP67trb+yMPD/tPOzv7Uz8/+1M/P/tTPz/7Uz8/+1dHR/u/u7v6al5f+n5ubTQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxrKxsu7e3/uzp
+        6f7RzMz+0cvL/tHLy/7Ry8v+z8nJ/sS+vv7Pycn+1M7O/tTNzf7QwcD+yKqo/sKenP6+mJf+uZiX/rij
+        ov61raz+rqmp/qmkpP6moaH+qaSk/reysv7Qysr+0cvL/tHLy/7Ry8v+29bW/tza2v6LiIjfnJiYBwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AACppaUVpqGh8ejn5/7Tzc3+y8TE/svExP7LxMT+xr+//sfAwP7Iqaf+t3Rv/qhJQ/6hNC3/nzAr/qAz
+        Lv6gMi//ni8s/p0tKv6fODX+o1NS/qd5ef6pnZ3+pqGh/qqkpP7IwcH+y8TE/svExP7LxMT+5uPj/rGv
+        r/6Oi4uDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAApqGhnsrHx/7f29v+xL29/sS8vP7EvLz+u5SQ/qlPRv6qRTz/uGNc/s6R
+        h/7iuaT/79Gw/vXasv7227L/8tWw/ufCqP7UoJP/uWhl/p4wLv6dMzP/o2Vl/rmsrP7EvLz+xLy8/sS8
+        vP7LxcX+6Obm/o+Li/qRjY0iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp6KiM6qlpfvr6en+xb6+/ryrqf6uXlX+qkI3/659
+        Yv91lUH/e6lK/+vQjP/mu1z/369I/9upPv/aqDr/3Ko9/+KySP/rwF//9tWJ//XZr//Mj4X/ojk4/585
+        Of+1j4/+vra2/r63t/7Y1NT+wsDA/oyIiLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApqGhAaagoLvRz8/+z7Sw/qpI
+        O/6yUkb/5sOx/lGTH/42kiz/NIcj/leJHf7QuVT/9r09/vq9NP77vTH/+bos/vO1KP7rriX/4Kco/uKu
+        PP7yy27/89ar/rtuaf+bLCz+rXFy/sK6uv7p5+f+mJWV/ZGNjUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqX
+        lEStj4v+rUc3/r5sX/733rf/8c6E/mOLJv43nj7/OqtI/jmjN/5VlBj/981i/v7DQP7+wTr//sA1/v6/
+        MP7+viv//rwm/va1Iv7nqyT/57NB/vnakP/Smo/+oDY2/rx7e/7Jx8f+jomJzJKOjgQAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAALV0aCmrRjT3wXNj//ritP/rw2v/67xW/6KyS/84miX/Oq1I/zqtSP84nSz/Ypoi/+nL
+        Y//+x0n//sM+//7BOP/+wDL//r4s//68Jv/+uyH/9bQf/+auMP/JxXX/lpNg/6I6Of+WYWL0mn5+OQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAuWJQCbFNOs26YlH++OG4/u3Fb/7zw1r+/sxc/vnUev5CkRT+Oq1I/jqt
+        SP46rUj+OaQ3/kuTGP7RxF/+/shL/v7EQP7+wTn+/sAy/v6+LP7+vCX+/rsf/vu4Hv61q0H+OoYI/p6K
+        Yv6fMzP4qV1cPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtlhEe69HMv7w1Ln+889//vTGYf7+zmT+/s9p/vDU
+        f/5Lkhf+OqxG/jqtSP46rUj+Oq1I/jqoQP5RlBr+989p/v7HSf7+xEH+/sE5/v6/Mv7+vir+/rwk/v67
+        H/66tDz+NYwd/kWPGP6sb2D+oTk406dIRwcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5X0sWsEgy7tSZiP763p3+88do/v3Q
+        af790W7+9taE/l+aJf45ojX+Oq1I/jqtSP46rUj+Oq1I/jqtSP44myj+q7dR/v7LVv7+x0j+/sRA/v7B
+        OP7+vy/+/r0o/v68I/7CuED+N5Yi/jeZLv5skzr+pkJC/qhIR2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3WUN5s085/vjh
+        wf71znn+/M9t/v3Sc/791Hv+vcNs/jiYIf46rUj+Oq1I/jqtSP46rUj+Oq1I/jqsRv45ni3+a50p/v7Q
+        aP7+yVD+/sdG/v7DPf7+wDX+/r8v/v7AMf6Kpi7+OaM2/jmnRf46jxX+qHtj/qE3NtaoSEcCAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlc
+        RQG0UDfWzo16/vzhpv74znL+/dN1/v3VfP792In+jK9M/jmjNf46rUj+Oq1I/jqtSP46rUj+OZol/lGW
+        Hv6UsU3+1cpy/v7PZv7+y1b+/shM/v7IS/7vylr+ubhF/rq3Qv5nmR3+Oqc9/jqtSP44my/+fpdM/qE3
+        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
+        r/61r6/+ta+v/rWvr/61r6/+ta+v/rWvr/61r6/+ta+v/rWvr/69t7b+597e/ufe3v7c09P+UlGw/khI
+        wP5oZbX+5Nvb/vLu7v6em5vBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsq6uue/q
+        6v7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/t7U
+        1P6GgZf+cnCq/piSov7h19f+7+vr/p6bm8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AACxra247enp/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX
+        1/7h19f+4dfX/t/W1v7Tysr+4NfX/uHX1/7u6en+npqawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAKunp6DJxsb+zsvL/s7Ly/7Oy8v+zsvL/s7Ly/7Oy8v+zsrK/s3Kyv7Mycn+y8jI/srH
+        x/7Jxsb+yMXF/sfExP7Gw8P+xcLC/sTBwf7DwMD+wr+//r26uv6Wk5OnAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAArqmpUcbCwv7e29v+3dra/t3a2v7d2tr+3dra/t3a2v7d2tr+3Nra/tza
+        2v7c2dn+29nZ/tvY2P7a2Nj+2tfX/tnX1/7Z1tb+2NbW/tjW1v7Z1tb+tbKy/peTk08AAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxra0GtrGx6eXi4v7Uz8/+1M/P/tTPz/7Uz87+zcjI/svG
+        xv7KxMT+xcDA/r65uf65tLT+t7Ky/ru2tv7GwcH+0s3N/tTPz/7Uz8/+1M/P/uXi4v6fnJznm5iYBQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrpqaM393d/tHLy/7Pycn+z8nJ/sfC
+        wv7Sy8v+yrCu/r+Oi/63e3j+snVz/q95eP6ujYz+rKOj/qeiov6vqqr+zsjI/s/Jyf7Ry8v+2NbW/pOP
+        j4kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKeioifDwMD81M/P/sa+
+        vv7Fubn+tX55/q9WT/67amH/zpB+/9mih//Zo4f/0ZSA/71xaf+iPj3+ol5d/q+dnf7Fvr7+xr6+/tTP
+        z/6yr6/8jouLJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKij
+        o7ff3Nz+upyZ/qtOQ/6hgVj/WJIu/6yzYv/ktlH/5K87/+SuNv/krzv/57pS//DNh//Um4L/pUJB/rGA
+        gP6+trb+3NnZ/pCMjLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAqZqYQbqWkP6zVUf/6sSd/46lSv83nT//Opww/6KxQP/+xEL//sE3//6/L//7uyj/8LEk/+iz
+        Ov/vyYn/tWBb/7Z3d/69u7v+kYyMSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAACzalw4s1ZF+/DPoP7swF/+0MBb/jqeLP46rUj+Op4t/qCxQf79yE/+/sI7/v7A
+        Mv7+vSn+/boh/u+yJv6jr1T+n2NO/ppeXsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAuF1KCLJPO9nrxaH+8cZq/v3NYv740nb+RZsm/jqtSP46rUj+OaQ4/pyw
+        Qv7+yEv+/sM9/v7AMv7+vSf+/rsf/oyhKv5Qkir+pU9J96dNTCkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2VkFszot2/vbThf78z2v+/dN3/n2qQP46qD/+Oq1I/jqt
+        SP46rUj+Qpsn/vLMY/7+x0j+/sI7/v6/L/7+vSb+iaYr/jihOv55hj/+pD49rAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALRQONXy0qr++c9y/v3TeP732I3+PJkk/jqt
+        SP46rUj+OqtE/kScKf5+qT7+781q/v7KUv7+x0j+6sNK/s66Pf5dnif+OqxI/kSYKv6oUkz6qUlIGgAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6XUUiwGtV/vven/7903n+/deF/vzc
+        mf5dnzH+Oq1I/jqrRf5LnCr+5NOI/v3VfP790Gv+/sxb/si+Uv48miT+OaEz/jmnPP46rUj+OaE1/pJ1
+        Sv6lPz1iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZUOFXRkHn+/NmM/v3W
+        gv773Jj+oLhf/kySGf5rqET+hrBT/ujYmf792pH+/daC/v3Scv7+z2f+bqQz/jqtSP46rUj+Oq1I/jqt
+        SP46q0b+e4dB/qI5NpUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt1Y5b9mh
+        h/792ov+xMVx/k+aJ/5NlR7+5duo/v3kt/794rH+/d+l/v3bmP7914j+/dN3/v7PZ/6fskb+OaQ4/jqt
+        SP46rUj+Oqg//jmfL/50kkP+pT06rgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAC4Vjlw2qOK/p64XP5Clh/+PZol/rvIgv5/q0z+/ebA/v3is/7936j+/dya/v3Yif7903j+/s9n/vzN
+        YP6BpzX+OJwp/jmgMf53oin+z79N/sGzg/6kOzavAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAALlYO1etiFr+OIoJ/jmmO/46qkP+OaIz/jmcKf65x4L+/eKw/v3epP7925b+/deH/v3T
+        dv7+zmX+/stW/omoNv48lBn+iqcy/m6cIv5LlBj+gotG/qU8NpcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAv2VJJrB0S/45nSr+Oq1I/jqtSP46rUj+Oq1I/jyeLf6Oslb+8Nuc/v3a
+        kP791YD+/dFx/v7NYP7+yU/+28JQ/k+WHP45ny/+OaQ3/jmiNP6SeUn+qUY/ZQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvmNG2VaWLv46rUj+Oq1I/jqtSP46rUj+Oq1I/jmf
+        Lv5MmCL+0Mp3/v3Td/7+z2j+/stZ/v7HSf7+xUL+cJ0j/j+MCv4/miT+VZkk/q1bTfyuUEgeAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC9YkN0mYRG/jmiNP46rUj+OqpC/lug
+        MP5FnCr+OqpD/mWhMv7x033+/dR2/v7NX/7+yVD+/sRC/v7EQf54oCj+5cFD/ufFTf7htZP+q0c8swAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFqTQu+ZEXfYpIv/jqq
+        Q/5cny3+8tWE/lSZJP48iAX+zcZp/s7FZv5Xmyb+5clj/v7HSv7+wTn+/r4t/v6/Lf7+vij++dOE/rJT
+        R/qwUEYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFr
+        TUC4b0r6UpYr/kabJv60u1j+eKQ2/jiWHv6Kqj3+fqY3/jqoP/4/myb+iag0/unBQv7+vSb+/r4r/v3U
+        d/7Cc2H+sVJFewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAL5mR1u4cEv6dZxC/kePEv6Ur0f+W5oi/u7NaP5tozH+OqxH/jqtSP46q0T+gKQs/v7H
+        Rf7504f+wnNf/rFPP5azVUcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMFsTka+YkPnl4pK/ujYo/7dz3n+mq49/jqfLv46rUj+OqtF/jmj
+        Nf5HlSD+3bGQ/rZYRPi1V0V0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBoSRG9YUOGu1s87bWCWv6Hhz7+fY8//nuQ
+        P/6EiT/+nH1I/rhlTPi1V0Gkt1pGJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBak4GvmRIQ7pa
+        PHi7XUGUu11CmLdWO4K6XUVSvGNNEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAPgAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/8AAAf/AAAH/4A
+        AD/+AAA//gAAf/wAAD/8AAA//AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/wAAB/8AAA//AAAP/4A
+        AH//AAB//4AB///AA///8A//KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAI2KigGxrKyXtbGxv7Ovr8Cxra3Ar6urwK2pqcCrp6fAqaWlwKajo8CloaHAo6CgwKKf
+        n8Cin5/Aop+fwKKfn8Cinp6+nZqabwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ+cnAzPzMz88Ovr/uPd
+        3f7j3d3+493d/uPd3f7j3d3+493d/uPd3f7j3t7+9O7u/vbw8P728PD+9O7u/vbw8P738vH+tLKyzwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGeng3Py8v83tfX/rexsf63sbH+t7Gx/rexsf63sbH+t7Gx/rex
+        sf64srL+59/f/u7m5v7Ry9j+XFu5/r24z/7w6en+tbOz0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGe
+        ng3Oysr829PT/sG6uf7Burn+wbq5/sG6uf7Burn+wbq5/sG6uf7Burr+4dnY/ufd3f6ZlLf+WFjM/oqG
+        uv7q4uL+tbKy0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCeng3Nycn84NbW/t/V1f7f1dX+39XV/t/V
+        1f7f1dX+39XV/t/V1f7f1dX+39XV/t/V1f7Qxsf+mJKi/si/wP7k3Nz+tbKy0AAAAAAAAAAAAAAAAAAA
+        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
+</value>
+  </data>
+  <data name="$this.Text" xml:space="preserve">
+    <value>Progress</value>
+  </data>
+  <data name="&gt;&gt;$this.Name" xml:space="preserve">
+    <value>Progress</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>
+  </data>
+</root>
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/Properties/AssemblyInfo.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Properties/AssemblyInfo.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Properties/AssemblyInfo.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MgCooker")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyProduct("MgCooker")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d7062967-45e9-419a-b577-97f6ebf8e7cc")]

Added: sandbox/maestro-3.0/MgCooker/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Properties/Resources.Designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Properties/Resources.Designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,317 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.4952
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MgCooker.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MgCooker.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to I heard you the first time!
+        ///Please be patient..
+        /// </summary>
+        internal static string AlreadyAborting {
+            get {
+                return ResourceManager.GetString("AlreadyAborting", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to connect: {0}.
+        /// </summary>
+        internal static string ConnectionError {
+            get {
+                return ResourceManager.GetString("ConnectionError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Current Group: \t{0} ({1} of {2}).
+        /// </summary>
+        internal static string ConsoleCurrentGroup {
+            get {
+                return ResourceManager.GetString("ConsoleCurrentGroup", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Current Map:   \t{0} ({1} of {2}).
+        /// </summary>
+        internal static string ConsoleCurrentMap {
+            get {
+                return ResourceManager.GetString("ConsoleCurrentMap", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Current Scale: \t1:{0} ({1} of {2}).
+        /// </summary>
+        internal static string ConsoleCurrentScale {
+            get {
+                return ResourceManager.GetString("ConsoleCurrentScale", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Current Tile:  \t{0} of {1}.
+        /// </summary>
+        internal static string ConsoleCurrentTile {
+            get {
+                return ResourceManager.GetString("ConsoleCurrentTile", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Error count: {0}, last exception: {1}.
+        /// </summary>
+        internal static string ConsoleErrorSummary {
+            get {
+                return ResourceManager.GetString("ConsoleErrorSummary", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Group estimate:  \t{0}.
+        /// </summary>
+        internal static string ConsoleGroupDuration {
+            get {
+                return ResourceManager.GetString("ConsoleGroupDuration", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Group duration:  \t{0}.
+        /// </summary>
+        internal static string ConsoleGroupEstimate {
+            get {
+                return ResourceManager.GetString("ConsoleGroupEstimate", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendering group {1} ({3} of {4}).
+        /// </summary>
+        internal static string ConsoleOperationBeginGroup {
+            get {
+                return ResourceManager.GetString("ConsoleOperationBeginGroup", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendering map {1}.
+        /// </summary>
+        internal static string ConsoleOperationBeginMap {
+            get {
+                return ResourceManager.GetString("ConsoleOperationBeginMap", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendering scale 1:{1} ({2} of {3}).
+        /// </summary>
+        internal static string ConsoleOperationBeginScale {
+            get {
+                return ResourceManager.GetString("ConsoleOperationBeginScale", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendered group {1} in {2}.
+        /// </summary>
+        internal static string ConsoleOperationFinishGroup {
+            get {
+                return ResourceManager.GetString("ConsoleOperationFinishGroup", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendered map {1} in {2}.
+        /// </summary>
+        internal static string ConsoleOperationFinishMap {
+            get {
+                return ResourceManager.GetString("ConsoleOperationFinishMap", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}: Rendered scale 1:{1} in {2}.
+        /// </summary>
+        internal static string ConsoleOperationFinishScale {
+            get {
+                return ResourceManager.GetString("ConsoleOperationFinishScale", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Processed {0} of {1} tiles in {2}, expected duration: {3}.
+        /// </summary>
+        internal static string ConsoleOperationFinishTile {
+            get {
+                return ResourceManager.GetString("ConsoleOperationFinishTile", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Update time:   \t{0}.
+        /// </summary>
+        internal static string ConsoleUpdateTime {
+            get {
+                return ResourceManager.GetString("ConsoleUpdateTime", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} in {1}.
+        /// </summary>
+        internal static string CurrentGroupStatus {
+            get {
+                return ResourceManager.GetString("CurrentGroupStatus", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Tile {0:###,###,###,###} of {1:###,###,###,###} {2}.
+        /// </summary>
+        internal static string CurrentTileCounter {
+            get {
+                return ResourceManager.GetString("CurrentTileCounter", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to All files ({0}).
+        /// </summary>
+        internal static string FileTypeAllFiles {
+            get {
+                return ResourceManager.GetString("FileTypeAllFiles", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Shell Script ({0}).
+        /// </summary>
+        internal static string FileTypeShellScript {
+            get {
+                return ResourceManager.GetString("FileTypeShellScript", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to &lt; Inaccurate measure of remaining time &gt;.
+        /// </summary>
+        internal static string InsufficientTimePassed {
+            get {
+                return ResourceManager.GetString("InsufficientTimePassed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An internal error occured: {0}.
+        /// </summary>
+        internal static string InternalError {
+            get {
+                return ResourceManager.GetString("InternalError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The file {0} was not found, unable to use the Native connection method.
+        ///Either copy in the file, or do not use the Native connection method.
+        /// </summary>
+        internal static string MissingWebConfigFile {
+            get {
+                return ResourceManager.GetString("MissingWebConfigFile", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to MgCooker is now paused, click OK to resume rendering.
+        /// </summary>
+        internal static string PauseMessage {
+            get {
+                return ResourceManager.GetString("PauseMessage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0}, remaining time: {1}.
+        /// </summary>
+        internal static string RemainingTime {
+            get {
+                return ResourceManager.GetString("RemainingTime", resourceCulture);
+            }
+        }
+        
+        /// <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 {
+            get {
+                return ResourceManager.GetString("TileErrorCount", resourceCulture);
+            }
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/MgCooker/Properties/Resources.resx	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Properties/Resources.resx	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <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>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="AlreadyAborting" xml:space="preserve">
+    <value>I heard you the first time!
+Please be patient.</value>
+    <comment>A message that is displayed when the user clicks quit more than once</comment>
+  </data>
+  <data name="ConnectionError" xml:space="preserve">
+    <value>Unable to connect: {0}</value>
+    <comment>An error message that is displayed, when the initial connection fails</comment>
+  </data>
+  <data name="ConsoleCurrentGroup" xml:space="preserve">
+    <value>Current Group: \t{0} ({1} of {2})</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleCurrentMap" xml:space="preserve">
+    <value>Current Map:   \t{0} ({1} of {2})</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleCurrentScale" xml:space="preserve">
+    <value>Current Scale: \t1:{0} ({1} of {2})</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleCurrentTile" xml:space="preserve">
+    <value>Current Tile:  \t{0} of {1}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleErrorSummary" xml:space="preserve">
+    <value>Error count: {0}, last exception: {1}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleGroupDuration" xml:space="preserve">
+    <value>Group estimate:  \t{0}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleGroupEstimate" xml:space="preserve">
+    <value>Group duration:  \t{0}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationBeginGroup" xml:space="preserve">
+    <value>{0}: Rendering group {1} ({3} of {4})</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationBeginMap" xml:space="preserve">
+    <value>{0}: Rendering map {1}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationBeginScale" xml:space="preserve">
+    <value>{0}: Rendering scale 1:{1} ({2} of {3})</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationFinishGroup" xml:space="preserve">
+    <value>{0}: Rendered group {1} in {2}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationFinishMap" xml:space="preserve">
+    <value>{0}: Rendered map {1} in {2}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationFinishScale" xml:space="preserve">
+    <value>{0}: Rendered scale 1:{1} in {2}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleOperationFinishTile" xml:space="preserve">
+    <value>Processed {0} of {1} tiles in {2}, expected duration: {3}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="ConsoleUpdateTime" xml:space="preserve">
+    <value>Update time:   \t{0}</value>
+    <comment>Text displayed in the console to report progress</comment>
+  </data>
+  <data name="CurrentGroupStatus" xml:space="preserve">
+    <value>{0} in {1}</value>
+    <comment>Label that identifies the current group and map, like &lt;group&gt; in &lt;map&gt;</comment>
+  </data>
+  <data name="CurrentTileCounter" xml:space="preserve">
+    <value>Tile {0:###,###,###,###} of {1:###,###,###,###} {2}</value>
+    <comment>Label that displays the current tile and the total number of tiles and number of failed tiles, eg: tile 1 of 100 (5 failed tiles)</comment>
+  </data>
+  <data name="FileTypeAllFiles" xml:space="preserve">
+    <value>All files ({0})</value>
+    <comment>The name displayed for the *.* filetype when the user is prompted to save a file</comment>
+  </data>
+  <data name="FileTypeShellScript" xml:space="preserve">
+    <value>Shell Script ({0})</value>
+    <comment>The name displayed for the *.sh filetype when the user is prompted to save a file</comment>
+  </data>
+  <data name="InsufficientTimePassed" xml:space="preserve">
+    <value>&lt; Inaccurate measure of remaining time &gt;</value>
+    <comment>Text displayed when it is not possible to predict the remaning time</comment>
+  </data>
+  <data name="InternalError" xml:space="preserve">
+    <value>An internal error occured: {0}</value>
+    <comment>An error message that is displayed if an internal error occurs</comment>
+  </data>
+  <data name="MissingWebConfigFile" xml:space="preserve">
+    <value>The file {0} was not found, unable to use the Native connection method.
+Either copy in the file, or do not use the Native connection method</value>
+    <comment>A message displayed when the webconfig.ini file is missing</comment>
+  </data>
+  <data name="PauseMessage" xml:space="preserve">
+    <value>MgCooker is now paused, click OK to resume rendering</value>
+    <comment>A text message displayed when MgCooker is paused</comment>
+  </data>
+  <data name="RemainingTime" xml:space="preserve">
+    <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>
+  </data>
+</root>
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/Properties/Settings.Designer.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/Properties/Settings.Designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Properties/Settings.Designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.4952
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MgCooker.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/Properties/Settings.settings
===================================================================
--- sandbox/maestro-3.0/MgCooker/Properties/Settings.settings	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/Properties/Settings.settings	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

Added: sandbox/maestro-3.0/MgCooker/RenderThread.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/RenderThread.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/RenderThread.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,374 @@
+#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);
+        }
+
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/SetupRun.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/SetupRun.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/SetupRun.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,552 @@
+#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.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using System.Collections.Specialized;
+
+namespace MgCooker
+{
+    public partial class SetupRun : Form
+    {
+        private IServerConnection m_connection;
+        private Dictionary<string, string> m_commandlineargs;
+        private Dictionary<string, IEnvelope> m_coordinateOverrides;
+        private bool m_isUpdating = false;
+
+        private SetupRun()
+        {
+            InitializeComponent();
+        }
+
+        internal SetupRun(string userName, string password, IServerConnection connection, string[] maps, Dictionary<string, string> args)
+            : this(connection, maps, args)
+        {
+            Username.Text = userName;
+            Password.Text = password;
+        }
+
+        public SetupRun(IServerConnection connection, string[] maps, Dictionary<string, string> args)
+            : this()
+        {
+            m_connection = connection;
+            m_commandlineargs = args;
+            m_coordinateOverrides = new Dictionary<string, IEnvelope>();
+
+            //HttpServerConnection hc = connection as HttpServerConnection;
+            var url = connection.GetCustomProperty("BaseUrl");
+            if (url != null)
+                MapAgent.Text = url.ToString();
+
+            if (m_commandlineargs.ContainsKey("mapdefinitions"))
+                m_commandlineargs.Remove("mapdefinitions");
+            if (m_commandlineargs.ContainsKey("scaleindex"))
+                m_commandlineargs.Remove("scaleindex");
+            if (m_commandlineargs.ContainsKey("basegroups"))
+                m_commandlineargs.Remove("basegroups");
+
+            if (m_commandlineargs.ContainsKey("mapagent"))
+                MapAgent.Text = m_commandlineargs["mapagent"];
+            if (m_commandlineargs.ContainsKey("username"))
+                Username.Text = m_commandlineargs["username"];
+            if (m_commandlineargs.ContainsKey("password"))
+                Password.Text = m_commandlineargs["password"];
+
+            if (m_commandlineargs.ContainsKey("native-connection"))
+                UseNativeAPI.Checked = true;
+
+            if (m_commandlineargs.ContainsKey("limitrows"))
+            {
+                int i;
+                if (int.TryParse(m_commandlineargs["limitrows"], out i) && i > 0)
+                {
+                    MaxRowLimit.Value = i;
+                    TilesetLimitPanel.Enabled = true;
+                }
+            }
+
+            if (m_commandlineargs.ContainsKey("limitcols"))
+            {
+                int i;
+                if (int.TryParse(m_commandlineargs["limitcols"], out i) && i > 0)
+                {
+                    MaxColLimit.Value = i;
+                    TilesetLimitPanel.Enabled = true;
+                }
+            }
+
+            if (m_commandlineargs.ContainsKey("metersperunit"))
+            {
+                double d;
+                if (
+                    double.TryParse(m_commandlineargs["metersperunit"], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d)
+                    || double.TryParse(m_commandlineargs["metersperunit"], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d)
+                    )
+                    if (d >= (double)MetersPerUnit.Minimum && d <= (double)MetersPerUnit.Maximum)
+                    {
+                        UseOfficialMethod.Checked = true;
+                        MetersPerUnit.Value = (decimal)d;
+                    }
+            }
+
+            if (maps == null || maps.Length == 0 || (maps.Length == 1 && maps[0].Trim().Length == 0))
+            {
+                List<string> tmp = new List<string>();
+                foreach (ResourceListResourceDocument doc in m_connection.ResourceService.GetRepositoryResources("Library://", "MapDefinition").Items)
+                    tmp.Add(doc.ResourceId);
+                maps = tmp.ToArray();
+            }
+
+            MapTree.Nodes.Clear();
+            foreach (string m in maps)
+            {
+                IMapDefinition mdef = (IMapDefinition)m_connection.ResourceService.GetResource(m);
+                IBaseMapDefinition baseMap = mdef.BaseMap;
+                if (baseMap != null &&
+                    baseMap.ScaleCount > 0 && 
+                    baseMap.HasGroups())
+                {
+                    TreeNode mn = MapTree.Nodes.Add(m);
+                    //mn.Checked = true;
+                    mn.ImageIndex = mn.SelectedImageIndex = 0;
+                    mn.Tag = mdef;
+                    foreach (var g in baseMap.BaseMapLayerGroup)
+                    {
+                        TreeNode gn = mn.Nodes.Add(g.Name);
+                        gn.Tag = g;
+                        //gn.Checked = true;
+                        gn.ImageIndex = gn.SelectedImageIndex = 1;
+
+                        foreach (double d in baseMap.FiniteDisplayScale)
+                        {
+                            TreeNode sn = gn.Nodes.Add(d.ToString(System.Globalization.CultureInfo.CurrentUICulture));
+                            //sn.Checked = true;
+                            sn.ImageIndex = sn.SelectedImageIndex = 3;
+                        }
+                    }
+
+                    mn.Expand();
+                }
+            }
+        }
+
+        private void panel1_Paint(object sender, PaintEventArgs e)
+        {
+
+        }
+
+        private void button2_Click(object sender, EventArgs e)
+        {
+            this.Close();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            IServerConnection con = null;
+
+            if (UseNativeAPI.Checked)
+            {
+                string webconfig = System.IO.Path.Combine(Application.StartupPath, "webconfig.ini");
+                if (!System.IO.File.Exists(webconfig))
+                {
+                    MessageBox.Show(this, string.Format(Properties.Resources.MissingWebConfigFile, webconfig), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+                    return;
+                }
+
+                try
+                {
+                    var initP = new NameValueCollection();
+
+                    initP["ConfigFile"] = webconfig;
+                    initP["Username"] = Username.Text;
+                    initP["Password"] = Password.Text;
+
+                    con = ConnectionProviderRegistry.CreateConnection("Maestro.LocalNative", initP);
+                }
+                catch (Exception ex)
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    MessageBox.Show(this, string.Format(Properties.Resources.ConnectionError, msg), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+                    return;
+                }
+            }
+            else
+            {
+                try
+                {
+                    var initP = new NameValueCollection();
+
+                    initP["Url"] = MapAgent.Text;
+                    initP["Username"] = Username.Text;
+                    initP["Password"] = Password.Text;
+                    initP["AllowUntestedVersion"] = "true";
+
+                    con = ConnectionProviderRegistry.CreateConnection("Maestro.Http", initP);
+                }
+                catch (Exception ex)
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    MessageBox.Show(this, string.Format(Properties.Resources.ConnectionError, msg), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+                    return;
+                }
+            }
+
+            try
+            {
+                BatchSettings bx = new BatchSettings(con);
+
+                if (LimitTileset.Checked)
+                {
+                    if (MaxRowLimit.Value > 0)
+                        bx.LimitRows((int)MaxRowLimit.Value);
+                    if (MaxColLimit.Value > 0)
+                        bx.LimitCols((int)MaxColLimit.Value);
+                }
+
+                if (UseOfficialMethod.Checked)
+                {
+                    bx.Config.MetersPerUnit = (double)MetersPerUnit.Value;
+                    bx.Config.UseOfficialMethod = true;
+                }
+
+                bx.Config.ThreadCount = (int)ThreadCount.Value;
+                bx.Config.RandomizeTileSequence = RandomTileOrder.Checked;
+
+                foreach (Config c in ReadTree())
+                {
+                    BatchMap bm = new BatchMap(bx, c.MapDefinition);
+                    bm.SetGroups(new string[] { c.Group });
+                    bm.SetScales(c.ScaleIndexes);
+                    if (c.ExtentOverride != null)
+                        bm.MaxExtent = c.ExtentOverride;
+                    bx.Maps.Add(bm);
+                }
+
+                Progress p = new Progress(bx);
+                if (p.ShowDialog(this) != DialogResult.Cancel)
+                    this.Close();
+            }
+            catch (Exception ex)
+            {
+                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                MessageBox.Show(this, string.Format(Properties.Resources.InternalError, msg), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+            }
+        }
+
+        private List<Config> ReadTree()
+        {
+            List<Config> lst = new List<Config>();
+            foreach(TreeNode mn in MapTree.Nodes)
+                if (mn.Checked)
+                {
+                    foreach(TreeNode gn in mn.Nodes)
+                        if (gn.Checked)
+                        {
+                            List<int> ix = new List<int>();
+                            foreach (TreeNode sn in gn.Nodes)
+                                if (sn.Checked)
+                                    ix.Add(sn.Index);
+
+                            if (ix.Count > 0)
+                                lst.Add(new Config(mn.Text, gn.Text, ix.ToArray(), (m_coordinateOverrides.ContainsKey(mn.Text) ? m_coordinateOverrides[mn.Text] : null)));
+                        }
+                }
+
+            return lst;
+        }
+
+        private class Config
+        {
+            public string MapDefinition;
+            public string Group;
+            public int[] ScaleIndexes;
+            public IEnvelope ExtentOverride = null;
+
+            public Config(string MapDefinition, string Group, int[] ScaleIndexes, IEnvelope ExtentOverride)
+            {
+                this.MapDefinition = MapDefinition;
+                this.Group = Group;
+                this.ScaleIndexes = ScaleIndexes;
+                this.ExtentOverride = ExtentOverride;
+            }
+        }
+
+        private void button3_Click(object sender, EventArgs e)
+        {
+            if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+                saveFileDialog1.Filter = 
+                    string.Format(Properties.Resources.FileTypeShellScript + "|{0}", "*.sh") +
+                    string.Format(Properties.Resources.FileTypeAllFiles + "|{0}", "*.*");
+
+            if (saveFileDialog1.ShowDialog(this) == DialogResult.OK)
+            {
+                StringBuilder args = new StringBuilder();
+                args.Append("--mapagent=\"" + MapAgent.Text + "\" ");
+                args.Append("--username=\"" + Username.Text + "\" ");
+                args.Append("--password=\"" + Password.Text + "\" ");
+
+                if (LimitTileset.Checked)
+                {
+                    if (MaxRowLimit.Value > 0)
+                        args.Append("--limitrows=\"" + ((int)MaxRowLimit.Value).ToString() + "\" ");
+                    if (MaxColLimit.Value > 0)
+                        args.Append("--limitcols=\"" + ((int)MaxColLimit.Value).ToString() + "\" ");
+                }
+
+                if (UseNativeAPI.Checked)
+                    args.Append("--native-connection ");
+                if (UseOfficialMethod.Checked)
+                    args.Append("--metersperunit=" + ((double)MetersPerUnit.Value).ToString(System.Globalization.CultureInfo.InvariantCulture) + " ");
+
+                args.Append("--threadcount=" + ((int)ThreadCount.Value).ToString() + " ");
+                if (RandomTileOrder.Checked)
+                    args.Append("--random-tile-order ");
+
+
+                string executable = System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location);
+
+                //Windows has problems with console output from GUI applications...
+                if (System.Environment.OSVersion.Platform != PlatformID.Unix && executable == "MgCooker.exe" && System.IO.File.Exists(System.IO.Path.Combine(Application.StartupPath, "MgCookerCommandline.exe")))
+                    executable = System.IO.Path.Combine(Application.StartupPath, "MgCookerCommandline.exe");
+                else
+                    executable = System.IO.Path.Combine(Application.StartupPath, executable);
+
+                string exeName = System.IO.Path.GetFileName(executable);
+                string exePath = System.IO.Path.GetDirectoryName(executable);
+
+                executable = "\"" + executable + "\"";
+
+                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(saveFileDialog1.FileName))
+                {
+                    if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+                    {
+                        sw.WriteLine("#!/bin/sh");
+                        executable = "mono " + executable;
+                    }
+                    else
+                    {
+                        sw.WriteLine("@echo off");
+                    }
+
+                    //If on windows, wrap the exe call in a pushd/popd so that the executable is 
+                    //executed from its own directory
+
+                    if (System.Environment.OSVersion.Platform != PlatformID.MacOSX ||
+                        System.Environment.OSVersion.Platform != PlatformID.Unix)
+                    {
+                        sw.WriteLine("pushd \"" + exePath + "\"");
+                    }
+
+                    foreach (Config c in ReadTree())
+                    {
+                        if (System.Environment.OSVersion.Platform != PlatformID.MacOSX ||
+                            System.Environment.OSVersion.Platform != PlatformID.Unix)
+                        {
+                            sw.Write(exeName);
+                        }
+                        else
+                        {
+                            sw.Write(executable);
+                        }
+                        sw.Write(" batch");
+                        sw.Write(" --mapdefinitions=\"");
+                        sw.Write(c.MapDefinition);
+                        sw.Write("\" --basegroups=\"");
+                        sw.Write(c.Group);
+                        sw.Write("\" --scaleindex=");
+                        for (int i = 0; i < c.ScaleIndexes.Length; i++)
+                        {
+                            if (i != 0)
+                                sw.Write(",");
+                            sw.Write(c.ScaleIndexes[i].ToString());
+                        }
+                        sw.Write(" "); // dont forget the space after the list of scaleindexes ticket #1316
+                        if (c.ExtentOverride != null)
+                        {
+                            sw.Write(" --extentoverride=");
+                            sw.Write(c.ExtentOverride.MinX.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MinY.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MaxX.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MaxY.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                        }
+
+                        sw.Write(args.ToString());
+                        sw.WriteLine();
+                    }
+
+                    if (System.Environment.OSVersion.Platform != PlatformID.MacOSX ||
+                        System.Environment.OSVersion.Platform != PlatformID.Unix)
+                    {
+                        sw.WriteLine("popd");
+                    }
+                }
+            }
+        }
+
+        private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
+        {
+            bool byuser = e.Action == TreeViewAction.ByKeyboard || e.Action == TreeViewAction.ByMouse;
+
+            if (e.Node == null)
+                return;
+
+            if (byuser)
+            {
+                foreach (TreeNode n in e.Node.Nodes)
+                {
+                    foreach (TreeNode tn in n.Nodes)
+                        tn.Checked = e.Node.Checked;
+                    
+                    n.Checked = e.Node.Checked;
+                }
+
+                if (e.Node.Parent != null)
+                {
+                    int c = 0;
+
+                    foreach (TreeNode n in e.Node.Parent.Nodes)
+                        if (n.Checked)
+                            c++;
+
+                    if (c > 0)
+                    {
+                        e.Node.Parent.Checked = true;
+                        if (e.Node.Parent.Parent != null)
+                            e.Node.Parent.Parent.Checked = true;
+                    }
+                }
+            }
+        }
+
+        private void label8_Click(object sender, EventArgs e)
+        {
+
+        }
+
+        private void numericUpDown5_ValueChanged(object sender, EventArgs e)
+        {
+
+        }
+
+        private void LimitTileset_CheckedChanged(object sender, EventArgs e)
+        {
+            TilesetLimitPanel.Enabled = LimitTileset.Checked;
+        }
+
+        private void UseOfficialMethod_CheckedChanged(object sender, EventArgs e)
+        {
+            OfficialMethodPanel.Enabled = UseOfficialMethod.Checked;
+            MapTree_AfterSelect(null, null);
+        }
+
+        private void MapTree_AfterSelect(object sender, TreeViewEventArgs e)
+        {
+            if (m_isUpdating)
+                return;
+
+            if (MapTree.SelectedNode == null || !UseOfficialMethod.Checked)
+            {
+                BoundsOverride.Enabled = false;
+                BoundsOverride.Tag = null;
+            }
+            else
+            {
+                BoundsOverride.Enabled = true;
+                TreeNode root = MapTree.SelectedNode;
+                while (root.Parent != null)
+                    root = root.Parent;
+
+                IEnvelope box;
+                if (m_coordinateOverrides.ContainsKey(root.Text))
+                    box = m_coordinateOverrides[root.Text];
+                else
+                    box = ((MapDefinition)root.Tag).Extents;
+
+                BoundsOverride.Tag = root;
+
+                try
+                {
+                    m_isUpdating = true;
+                    txtLowerX.Text = box.MinX.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtLowerY.Text = box.MinY.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtUpperX.Text = box.MaxX.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtUpperY.Text = box.MaxY.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                }
+                finally
+                {
+                    m_isUpdating = false;
+                }
+
+                ModfiedOverrideWarning.Visible = m_coordinateOverrides.ContainsKey(root.Text);
+            }
+        }
+
+        private void ResetBounds_Click(object sender, EventArgs e)
+        {
+            if (BoundsOverride.Tag as TreeNode == null)
+                return;
+
+            TreeNode root = BoundsOverride.Tag as TreeNode;
+
+            if (m_coordinateOverrides.ContainsKey(root.Text))
+                m_coordinateOverrides.Remove(root.Text);
+
+            MapTree_AfterSelect(null, null);
+        }
+
+        private void CoordinateItem_TextChanged(object sender, EventArgs e)
+        {
+            if (BoundsOverride.Tag as TreeNode == null || m_isUpdating)
+                return;
+
+            TreeNode root = BoundsOverride.Tag as TreeNode;
+
+            if (!m_coordinateOverrides.ContainsKey(root.Text))
+            {
+                //IEnvelope newbox = new OSGeo.MapGuide.IEnvelope();
+                IEnvelope origbox = ((MapDefinition)root.Tag).Extents;
+                IEnvelope newbox = origbox.Clone();
+
+                m_coordinateOverrides.Add(root.Text, newbox);
+            }
+
+            double d;
+            if (double.TryParse(txtLowerX.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MinX = d;
+            if (double.TryParse(txtLowerY.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MinY = d;
+            if (double.TryParse(txtUpperX.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MaxX = d;
+            if (double.TryParse(txtUpperY.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MaxY = d;
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker/SetupRun.designer.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker/SetupRun.designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/SetupRun.designer.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,492 @@
+namespace MgCooker
+{
+    partial class SetupRun
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SetupRun));
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.button3 = new System.Windows.Forms.Button();
+            this.button2 = new System.Windows.Forms.Button();
+            this.button1 = new System.Windows.Forms.Button();
+            this.MapTree = new System.Windows.Forms.TreeView();
+            this.imageList1 = new System.Windows.Forms.ImageList(this.components);
+            this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
+            this.panel2 = new System.Windows.Forms.Panel();
+            this.BoundsOverride = new System.Windows.Forms.GroupBox();
+            this.ModfiedOverrideWarning = new System.Windows.Forms.Label();
+            this.ResetBounds = new System.Windows.Forms.Button();
+            this.txtUpperY = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.txtUpperX = new System.Windows.Forms.TextBox();
+            this.label5 = new System.Windows.Forms.Label();
+            this.txtLowerY = new System.Windows.Forms.TextBox();
+            this.label10 = new System.Windows.Forms.Label();
+            this.txtLowerX = new System.Windows.Forms.TextBox();
+            this.label11 = new System.Windows.Forms.Label();
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.UseNativeAPI = new System.Windows.Forms.CheckBox();
+            this.Password = new System.Windows.Forms.TextBox();
+            this.Username = new System.Windows.Forms.TextBox();
+            this.MapAgent = new System.Windows.Forms.TextBox();
+            this.label3 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label1 = new System.Windows.Forms.Label();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.RandomTileOrder = new System.Windows.Forms.CheckBox();
+            this.ThreadCount = new System.Windows.Forms.NumericUpDown();
+            this.label9 = new System.Windows.Forms.Label();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.OfficialMethodPanel = new System.Windows.Forms.Panel();
+            this.MetersPerUnit = new System.Windows.Forms.NumericUpDown();
+            this.label8 = new System.Windows.Forms.Label();
+            this.LimitTileset = new System.Windows.Forms.CheckBox();
+            this.UseOfficialMethod = new System.Windows.Forms.CheckBox();
+            this.TilesetLimitPanel = new System.Windows.Forms.Panel();
+            this.MaxRowLimit = new System.Windows.Forms.NumericUpDown();
+            this.label6 = new System.Windows.Forms.Label();
+            this.MaxColLimit = new System.Windows.Forms.NumericUpDown();
+            this.label7 = new System.Windows.Forms.Label();
+            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+            this.panel1.SuspendLayout();
+            this.panel2.SuspendLayout();
+            this.BoundsOverride.SuspendLayout();
+            this.groupBox1.SuspendLayout();
+            this.groupBox3.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.ThreadCount)).BeginInit();
+            this.groupBox2.SuspendLayout();
+            this.OfficialMethodPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.MetersPerUnit)).BeginInit();
+            this.TilesetLimitPanel.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.MaxRowLimit)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.MaxColLimit)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // panel1
+            // 
+            this.panel1.Controls.Add(this.button3);
+            this.panel1.Controls.Add(this.button2);
+            this.panel1.Controls.Add(this.button1);
+            resources.ApplyResources(this.panel1, "panel1");
+            this.panel1.Name = "panel1";
+            this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
+            // 
+            // button3
+            // 
+            resources.ApplyResources(this.button3, "button3");
+            this.button3.Name = "button3";
+            this.button3.UseVisualStyleBackColor = true;
+            this.button3.Click += new System.EventHandler(this.button3_Click);
+            // 
+            // button2
+            // 
+            resources.ApplyResources(this.button2, "button2");
+            this.button2.Name = "button2";
+            this.button2.UseVisualStyleBackColor = true;
+            this.button2.Click += new System.EventHandler(this.button2_Click);
+            // 
+            // button1
+            // 
+            resources.ApplyResources(this.button1, "button1");
+            this.button1.Name = "button1";
+            this.button1.UseVisualStyleBackColor = true;
+            this.button1.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // MapTree
+            // 
+            this.MapTree.CheckBoxes = true;
+            resources.ApplyResources(this.MapTree, "MapTree");
+            this.MapTree.ImageList = this.imageList1;
+            this.MapTree.Name = "MapTree";
+            this.MapTree.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCheck);
+            this.MapTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.MapTree_AfterSelect);
+            // 
+            // imageList1
+            // 
+            this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
+            this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
+            this.imageList1.Images.SetKeyName(0, "Map.ico");
+            this.imageList1.Images.SetKeyName(1, "Layer.ico");
+            this.imageList1.Images.SetKeyName(2, "Range.ico");
+            this.imageList1.Images.SetKeyName(3, "Scale.ico");
+            // 
+            // saveFileDialog1
+            // 
+            resources.ApplyResources(this.saveFileDialog1, "saveFileDialog1");
+            // 
+            // panel2
+            // 
+            this.panel2.Controls.Add(this.BoundsOverride);
+            this.panel2.Controls.Add(this.groupBox1);
+            this.panel2.Controls.Add(this.groupBox3);
+            this.panel2.Controls.Add(this.groupBox2);
+            resources.ApplyResources(this.panel2, "panel2");
+            this.panel2.Name = "panel2";
+            // 
+            // BoundsOverride
+            // 
+            resources.ApplyResources(this.BoundsOverride, "BoundsOverride");
+            this.BoundsOverride.Controls.Add(this.ModfiedOverrideWarning);
+            this.BoundsOverride.Controls.Add(this.ResetBounds);
+            this.BoundsOverride.Controls.Add(this.txtUpperY);
+            this.BoundsOverride.Controls.Add(this.label4);
+            this.BoundsOverride.Controls.Add(this.txtUpperX);
+            this.BoundsOverride.Controls.Add(this.label5);
+            this.BoundsOverride.Controls.Add(this.txtLowerY);
+            this.BoundsOverride.Controls.Add(this.label10);
+            this.BoundsOverride.Controls.Add(this.txtLowerX);
+            this.BoundsOverride.Controls.Add(this.label11);
+            this.BoundsOverride.Name = "BoundsOverride";
+            this.BoundsOverride.TabStop = false;
+            // 
+            // ModfiedOverrideWarning
+            // 
+            resources.ApplyResources(this.ModfiedOverrideWarning, "ModfiedOverrideWarning");
+            this.ModfiedOverrideWarning.Name = "ModfiedOverrideWarning";
+            // 
+            // ResetBounds
+            // 
+            resources.ApplyResources(this.ResetBounds, "ResetBounds");
+            this.ResetBounds.Name = "ResetBounds";
+            this.ResetBounds.UseVisualStyleBackColor = true;
+            this.ResetBounds.Click += new System.EventHandler(this.ResetBounds_Click);
+            // 
+            // txtUpperY
+            // 
+            resources.ApplyResources(this.txtUpperY, "txtUpperY");
+            this.txtUpperY.Name = "txtUpperY";
+            this.txtUpperY.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label4
+            // 
+            this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            resources.ApplyResources(this.label4, "label4");
+            this.label4.Name = "label4";
+            // 
+            // txtUpperX
+            // 
+            resources.ApplyResources(this.txtUpperX, "txtUpperX");
+            this.txtUpperX.Name = "txtUpperX";
+            this.txtUpperX.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label5
+            // 
+            this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            resources.ApplyResources(this.label5, "label5");
+            this.label5.Name = "label5";
+            // 
+            // txtLowerY
+            // 
+            resources.ApplyResources(this.txtLowerY, "txtLowerY");
+            this.txtLowerY.Name = "txtLowerY";
+            this.txtLowerY.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label10
+            // 
+            this.label10.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            resources.ApplyResources(this.label10, "label10");
+            this.label10.Name = "label10";
+            // 
+            // txtLowerX
+            // 
+            resources.ApplyResources(this.txtLowerX, "txtLowerX");
+            this.txtLowerX.Name = "txtLowerX";
+            this.txtLowerX.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label11
+            // 
+            this.label11.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            resources.ApplyResources(this.label11, "label11");
+            this.label11.Name = "label11";
+            // 
+            // groupBox1
+            // 
+            resources.ApplyResources(this.groupBox1, "groupBox1");
+            this.groupBox1.Controls.Add(this.UseNativeAPI);
+            this.groupBox1.Controls.Add(this.Password);
+            this.groupBox1.Controls.Add(this.Username);
+            this.groupBox1.Controls.Add(this.MapAgent);
+            this.groupBox1.Controls.Add(this.label3);
+            this.groupBox1.Controls.Add(this.label2);
+            this.groupBox1.Controls.Add(this.label1);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.TabStop = false;
+            // 
+            // UseNativeAPI
+            // 
+            resources.ApplyResources(this.UseNativeAPI, "UseNativeAPI");
+            this.UseNativeAPI.Name = "UseNativeAPI";
+            this.toolTip1.SetToolTip(this.UseNativeAPI, resources.GetString("UseNativeAPI.ToolTip"));
+            this.UseNativeAPI.UseVisualStyleBackColor = true;
+            // 
+            // Password
+            // 
+            resources.ApplyResources(this.Password, "Password");
+            this.Password.Name = "Password";
+            this.toolTip1.SetToolTip(this.Password, resources.GetString("Password.ToolTip"));
+            this.Password.UseSystemPasswordChar = true;
+            // 
+            // Username
+            // 
+            resources.ApplyResources(this.Username, "Username");
+            this.Username.Name = "Username";
+            this.toolTip1.SetToolTip(this.Username, resources.GetString("Username.ToolTip"));
+            // 
+            // MapAgent
+            // 
+            resources.ApplyResources(this.MapAgent, "MapAgent");
+            this.MapAgent.Name = "MapAgent";
+            this.toolTip1.SetToolTip(this.MapAgent, resources.GetString("MapAgent.ToolTip"));
+            // 
+            // label3
+            // 
+            resources.ApplyResources(this.label3, "label3");
+            this.label3.Name = "label3";
+            // 
+            // label2
+            // 
+            resources.ApplyResources(this.label2, "label2");
+            this.label2.Name = "label2";
+            // 
+            // label1
+            // 
+            resources.ApplyResources(this.label1, "label1");
+            this.label1.Name = "label1";
+            // 
+            // groupBox3
+            // 
+            resources.ApplyResources(this.groupBox3, "groupBox3");
+            this.groupBox3.Controls.Add(this.RandomTileOrder);
+            this.groupBox3.Controls.Add(this.ThreadCount);
+            this.groupBox3.Controls.Add(this.label9);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.TabStop = false;
+            // 
+            // RandomTileOrder
+            // 
+            resources.ApplyResources(this.RandomTileOrder, "RandomTileOrder");
+            this.RandomTileOrder.Name = "RandomTileOrder";
+            this.toolTip1.SetToolTip(this.RandomTileOrder, resources.GetString("RandomTileOrder.ToolTip"));
+            this.RandomTileOrder.UseVisualStyleBackColor = true;
+            // 
+            // ThreadCount
+            // 
+            resources.ApplyResources(this.ThreadCount, "ThreadCount");
+            this.ThreadCount.Maximum = new decimal(new int[] {
+            512,
+            0,
+            0,
+            0});
+            this.ThreadCount.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.ThreadCount.Name = "ThreadCount";
+            this.toolTip1.SetToolTip(this.ThreadCount, resources.GetString("ThreadCount.ToolTip"));
+            this.ThreadCount.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            // 
+            // label9
+            // 
+            resources.ApplyResources(this.label9, "label9");
+            this.label9.Name = "label9";
+            // 
+            // groupBox2
+            // 
+            resources.ApplyResources(this.groupBox2, "groupBox2");
+            this.groupBox2.Controls.Add(this.OfficialMethodPanel);
+            this.groupBox2.Controls.Add(this.LimitTileset);
+            this.groupBox2.Controls.Add(this.UseOfficialMethod);
+            this.groupBox2.Controls.Add(this.TilesetLimitPanel);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.TabStop = false;
+            // 
+            // OfficialMethodPanel
+            // 
+            this.OfficialMethodPanel.Controls.Add(this.MetersPerUnit);
+            this.OfficialMethodPanel.Controls.Add(this.label8);
+            resources.ApplyResources(this.OfficialMethodPanel, "OfficialMethodPanel");
+            this.OfficialMethodPanel.Name = "OfficialMethodPanel";
+            // 
+            // MetersPerUnit
+            // 
+            this.MetersPerUnit.DecimalPlaces = 4;
+            this.MetersPerUnit.Increment = new decimal(new int[] {
+            1,
+            0,
+            0,
+            65536});
+            resources.ApplyResources(this.MetersPerUnit, "MetersPerUnit");
+            this.MetersPerUnit.Maximum = new decimal(new int[] {
+            10000,
+            0,
+            0,
+            0});
+            this.MetersPerUnit.Name = "MetersPerUnit";
+            this.toolTip1.SetToolTip(this.MetersPerUnit, resources.GetString("MetersPerUnit.ToolTip"));
+            this.MetersPerUnit.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.MetersPerUnit.ValueChanged += new System.EventHandler(this.numericUpDown5_ValueChanged);
+            // 
+            // label8
+            // 
+            resources.ApplyResources(this.label8, "label8");
+            this.label8.Name = "label8";
+            this.label8.Click += new System.EventHandler(this.label8_Click);
+            // 
+            // LimitTileset
+            // 
+            resources.ApplyResources(this.LimitTileset, "LimitTileset");
+            this.LimitTileset.Name = "LimitTileset";
+            this.toolTip1.SetToolTip(this.LimitTileset, resources.GetString("LimitTileset.ToolTip"));
+            this.LimitTileset.UseVisualStyleBackColor = true;
+            this.LimitTileset.CheckedChanged += new System.EventHandler(this.LimitTileset_CheckedChanged);
+            // 
+            // UseOfficialMethod
+            // 
+            resources.ApplyResources(this.UseOfficialMethod, "UseOfficialMethod");
+            this.UseOfficialMethod.Name = "UseOfficialMethod";
+            this.toolTip1.SetToolTip(this.UseOfficialMethod, resources.GetString("UseOfficialMethod.ToolTip"));
+            this.UseOfficialMethod.UseVisualStyleBackColor = true;
+            this.UseOfficialMethod.CheckedChanged += new System.EventHandler(this.UseOfficialMethod_CheckedChanged);
+            // 
+            // TilesetLimitPanel
+            // 
+            this.TilesetLimitPanel.Controls.Add(this.MaxRowLimit);
+            this.TilesetLimitPanel.Controls.Add(this.label6);
+            this.TilesetLimitPanel.Controls.Add(this.MaxColLimit);
+            this.TilesetLimitPanel.Controls.Add(this.label7);
+            resources.ApplyResources(this.TilesetLimitPanel, "TilesetLimitPanel");
+            this.TilesetLimitPanel.Name = "TilesetLimitPanel";
+            // 
+            // MaxRowLimit
+            // 
+            resources.ApplyResources(this.MaxRowLimit, "MaxRowLimit");
+            this.MaxRowLimit.Name = "MaxRowLimit";
+            this.toolTip1.SetToolTip(this.MaxRowLimit, resources.GetString("MaxRowLimit.ToolTip"));
+            // 
+            // label6
+            // 
+            resources.ApplyResources(this.label6, "label6");
+            this.label6.Name = "label6";
+            // 
+            // MaxColLimit
+            // 
+            resources.ApplyResources(this.MaxColLimit, "MaxColLimit");
+            this.MaxColLimit.Name = "MaxColLimit";
+            this.toolTip1.SetToolTip(this.MaxColLimit, resources.GetString("MaxColLimit.ToolTip"));
+            // 
+            // label7
+            // 
+            resources.ApplyResources(this.label7, "label7");
+            this.label7.Name = "label7";
+            // 
+            // SetupRun
+            // 
+            resources.ApplyResources(this, "$this");
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.MapTree);
+            this.Controls.Add(this.panel2);
+            this.Controls.Add(this.panel1);
+            this.Name = "SetupRun";
+            this.panel1.ResumeLayout(false);
+            this.panel2.ResumeLayout(false);
+            this.BoundsOverride.ResumeLayout(false);
+            this.BoundsOverride.PerformLayout();
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.ThreadCount)).EndInit();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            this.OfficialMethodPanel.ResumeLayout(false);
+            this.OfficialMethodPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.MetersPerUnit)).EndInit();
+            this.TilesetLimitPanel.ResumeLayout(false);
+            this.TilesetLimitPanel.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.MaxRowLimit)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.MaxColLimit)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button button2;
+        private System.Windows.Forms.Button button1;
+        private System.Windows.Forms.TreeView MapTree;
+        private System.Windows.Forms.Button button3;
+        private System.Windows.Forms.SaveFileDialog saveFileDialog1;
+        private System.Windows.Forms.ImageList imageList1;
+        private System.Windows.Forms.Panel panel2;
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.CheckBox UseNativeAPI;
+        private System.Windows.Forms.TextBox Password;
+        private System.Windows.Forms.TextBox Username;
+        private System.Windows.Forms.TextBox MapAgent;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.NumericUpDown ThreadCount;
+        private System.Windows.Forms.Label label9;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.CheckBox LimitTileset;
+        private System.Windows.Forms.CheckBox UseOfficialMethod;
+        private System.Windows.Forms.NumericUpDown MetersPerUnit;
+        private System.Windows.Forms.Label label8;
+        private System.Windows.Forms.NumericUpDown MaxColLimit;
+        private System.Windows.Forms.NumericUpDown MaxRowLimit;
+        private System.Windows.Forms.Label label7;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.Panel OfficialMethodPanel;
+        private System.Windows.Forms.Panel TilesetLimitPanel;
+        private System.Windows.Forms.ToolTip toolTip1;
+        private System.Windows.Forms.CheckBox RandomTileOrder;
+        private System.Windows.Forms.GroupBox BoundsOverride;
+        private System.Windows.Forms.TextBox txtUpperY;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.TextBox txtUpperX;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.TextBox txtLowerY;
+        private System.Windows.Forms.Label label10;
+        private System.Windows.Forms.TextBox txtLowerX;
+        private System.Windows.Forms.Label label11;
+        private System.Windows.Forms.Button ResetBounds;
+        private System.Windows.Forms.Label ModfiedOverrideWarning;
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker/SetupRun.resx
===================================================================
--- sandbox/maestro-3.0/MgCooker/SetupRun.resx	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker/SetupRun.resx	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,1776 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <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>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.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" />
+  <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" />
+  <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" />
+  <data name="button3.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="button3.Text" xml:space="preserve">
+    <value>Save as script...</value>
+  </data>
+  <data name="&gt;&gt;button3.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;button3.Parent" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;button3.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="button2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="button2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>355, 8</value>
+  </data>
+  <data name="button2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>112, 23</value>
+  </data>
+  <data name="button2.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="button2.Text" xml:space="preserve">
+    <value>Close</value>
+  </data>
+  <data name="&gt;&gt;button2.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;button2.Parent" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;button2.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="button1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="button1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>99, 8</value>
+  </data>
+  <data name="button1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>112, 23</value>
+  </data>
+  <data name="button1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="button1.Text" xml:space="preserve">
+    <value>Build tiles now</value>
+  </data>
+  <data name="&gt;&gt;button1.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;button1.Parent" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;button1.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>0, 537</value>
+  </data>
+  <data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>565, 41</value>
+  </data>
+  <data name="panel1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="&gt;&gt;panel1.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;panel1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;panel1.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="MapTree.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
+    <value>Fill</value>
+  </data>
+  <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">
+    <value>145, 17</value>
+  </metadata>
+  <data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
+    <value>
+        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACE
+        DAAAAk1TRnQBSQFMAgEBBAEAAUQBAAFEAQABEAEAARABAAT/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/wMbASYcAAGI
+        Am0B9wH0AeYB4QH/Ac0BvAG7Af0BjgGGAYUB+QFNAkwBkQMRAReYAAP9Af8B9QHoAeQB/wH0AeUB4AH/
+        AfIB4gHdAf8B8QHgAdkB/wHwAd0B1gH/Ae8B2wHTAf8B7gHZAdEB/wHuAdgB0AH/Ae4B2AHQAf8B7gHY
+        AdAB/wP9Af8DGwEmGAABLAIrAUMB9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/
+        AawBnQGaAfoBagJaAfABNgI1AVgDCwEPDAADHQEqAx0BKiAAAwUBBwMdASoDHQEqTAAD/QH/AfcB7QHp
+        Af8B9gHqAeYB/wH0AecB4wH/Ad0BtQGwAf8BvQFsAWcB/wG+AXABawH/AeMBwgG8Af8B7wHaAdIB/wHu
+        AdgB0AH/Ae4B2AHQAf8D/QH/AxsBJhgAAZMCfAH4AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
+        Af8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wGgAYwBhgH6AVkCVwHCCwAB/ygAAzABTAMA
+        Af9MAAP9Af8B+AHwAe0B/wHtAdcB0gH/AbkBiQFqAf8BWgGTASoB/wHqAbEBMgH/AegBrgEpAf8B6wHB
+        AV0B/wGxAVQBTwH/Ae4B2QHSAf8B7gHZAdIB/wP9Af8DGwEmFAADQAFwAfUB6QHlAf8B9QHoAeMB/wH0
+        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHdAdcB/wHvAdwB1QH/Ae8B2gHT
+        Af8DOAFcCwAB/wgAAUYCRQF/AwAEAQECA0UBfQQAAygBPAMlATcEAAMvAUoDAAH/DAADEQEXA1gB0QMA
+        Af8DKAE8EAADOAFcAwAB/xgAA/0B/wH2AeoB5gH/AegBvwGcAf8B+wHLAV0B/wE3Aa0BRAH/AU8BnQEl
+        Af8B/gHEAT0B/wH+Ab4BKAH/AfYBtgEeAf8BlwFtAUoB/wHwAd0B1gH/A/0B/wMbASYUAAGaAYoBiAH4
+        AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHd
+        AdcB/wHvAdwB1QH/AXsCYgH2AwQBBgsAAf8LAAH/A0UBfQNIAYUDAAH/BwAB/wMAAf8EAAMvAUoDAAH/
+        EAADQgF0AwAB/xQAAw0BEQFaAlkB1RgAA/0B/wG5AVoBRQH/AfoBzgFpAf8BpAG2AVEB/wE3Aa0BRQH/
+        ATYBrQFEAf8ByQG/AVMB/wH+AcQBPAH/Af4BwAEtAf8BNQGlATwB/wG8AWwBaQH/A/0B/wMbASYQAANQ
+        AZ4B9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHhAdsB/wHx
+        Ad8B2QH/AfAB3QHXAf8BvwG1AbEB/AMoATwPAAH/KAADLwFKAwAB/xAAA0IBdAMAAf80AAP9Af8B6gHD
+        AaEB/wH9AdYBhAH/AZsBtgFXAf8BNQGfASoB/wHxAdgBkQH/Af0B0QFtAf8BnAGwAT4B/wE3Aa0BRQH/
+        ATcBrQFFAf8BmAFoAUcB/wP9Af8DGwEmEAABnwGKAYkB9wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
+        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHdAdcB/wFqAlkB6wMBAQIPAAH/
+        KAADLwFKAwAB/xAAA0IBdAMAAf8UAAMCAQMDUQGhGAAD/QH/AfoB4gG5Af8BOAGaASEB/wLUAZsB/wH9
+        AeMBtQH/Af0B3QGdAf8B/QHUAXYB/wHkAcgBWwH/ATYBrAFDAf8BTQGcASIB/wGeAYoBWAH/A/0B/wMb
+        ASYMAAFcAlkByQH3Ae0B6QH/AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/AfQB5gHhAf8B8wHkAd8B/wHy
+        AeMB3QH/AfIB4QHbAf8B8QHfAdkB/wGvAZ8BnAH6AxsBJhMAAf8oAAMvAUoDAAH/EAADQgF0AwAB/xQA
+        Az4BawMAAf8YAAP9Af8BagGQATIB/wE3Aa0BRQH/ATcBrQFFAf8BrwHBAXEB/wH9AdsBlQH/Af0B0wFx
+        Af8B/gHKAU8B/wE/AZoBIQH/ATUBlwEcAf8BnAFqAUgB/wP9Af8DGwEmCAADBAEFAbMBpAGjAfoB9wHt
+        AekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/
+        AfEB3wHZAf8BXQJZAdIXAAH/KAADLwFKAwAB/xAAA0IBdgMAAf80AAP9Af8BvgFsAUwB/wE3Aa0BRQH/
+        ATYBowEzAf8BNgGtAUQB/wHAAcIBZAH/Af4BzgFfAf8B/gHGAUEB/wFWAZQBEwH/AcIBugFDAf8BxQGB
+        AXUB/wP9Af8DGwEmCAABZQJYAecB+AHuAesB/wH3Ae0B6QH/AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/
+        AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8BngGQAY0B+AMTARoXAAH/KAADLwFKAwAB/wwA
+        AwgBCwFaAlQB3gMAAf80AAP9Af8B9wHtAekB/wFyAZABNgH/AacBtQFLAf8BNwGTARUB/wGqAbcBTQH/
+        AUoBngEmAf8B8gHCAT4B/wH+Ab0BIwH/AcUBdQFhAf8B+QHxAe4B/wP9Af8DGwEmBAADEgEZAbUCpgH6
+        AfgB7gHrAf8B9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHj
+        Ad0B/wHyAeEB2wH/A1QBrxgAAVcCUQHfAUkCSAGHIAADCwEPA1UBtwFXAlEB30wAA/0B/wH5AfEB7gH/
+        AfIB4QHbAf8BrQGGAVIB/wHuAdgBiwH/AUsBngEmAf8BNgGtAUQB/wE8AZQBGAH/AbsBXwFLAf8B+AHw
+        Ae0B/wH5AfEB7gH/A/0B/wMbASYIAAMBAQIBUgJRAacBmQKLAfkB9gHrAecB/wH1AekB5QH/AfUB6AHj
+        Af8B9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8BmgGHAYEB+AMOAROYAAP9Af8B+QHxAe4B/wH5AfEB7gH/
+        AfkB8QHuAf8B7AHSAckB/wHSAZUBggH/AdQBmgGJAf8B8gHhAdwB/wH5AfEB7gH/AfkB8QHuAf8B+QHx
+        Ae4B/wP9Af8DGwEmFAADHQEpAWECVgHkAaYBkAGOAfkB9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8BSQJI
+        AYicAAP9Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2
+        AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wP9Af8DGwEmIAADPgFrAZYCfAH6AZMCewH4AwcBCpwA
+        AaUCoAH/AaQBoAGfAf8BpAKfAf8BowKeAf8BogKdAf8BoQKcAf8BoAKbAf8BnwKaAf8BnQKZAf8BnAGY
+        AZcB/wGbApYB/wGZApUB/8gAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/+BAAHA
+        AQEB/AE/BP8BwAEBAfwBDwT/AcABAQH4AQEBzwHxAv8BwAEBAfgBAAHfAfkC/wHAAQEB8AEAAdgBSQHD
+        Ac8BwAEBAfABAAHYAUkB5wHPAcABAQHgAQEB3wH5AecB/wHAAQEB4AEBAd8B+QHnAc8BwAEBAcABAwHf
+        AfkB5wHPAcABAQGAAQcB3wH5AecB/wHAAQEBgAEHAd8B+QHHAf8BwAEBAQABDwHPAfEC/wHAAQEBgAEP
+        BP8BwAEBAfABHwT/AcABAQH+AR8E/wHAAQMG/ws=
+</value>
+  </data>
+  <data name="MapTree.Location" type="System.Drawing.Point, System.Drawing">
+    <value>0, 0</value>
+  </data>
+  <data name="MapTree.SelectedImageIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="MapTree.Size" type="System.Drawing.Size, System.Drawing">
+    <value>293, 537</value>
+  </data>
+  <data name="MapTree.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="&gt;&gt;MapTree.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;MapTree.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <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">
+    <value>17, 17</value>
+  </metadata>
+  <data name="saveFileDialog1.Filter" xml:space="preserve">
+    <value>Batch Files (*.bat)|*.bat|All files (*.*)|*.*</value>
+  </data>
+  <data name="saveFileDialog1.Title" xml:space="preserve">
+    <value>Select file to save script to</value>
+  </data>
+  <data name="BoundsOverride.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="ModfiedOverrideWarning.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="ModfiedOverrideWarning.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 96</value>
+  </data>
+  <data name="ModfiedOverrideWarning.Size" type="System.Drawing.Size, System.Drawing">
+    <value>105, 13</value>
+  </data>
+  <data name="ModfiedOverrideWarning.TabIndex" type="System.Int32, mscorlib">
+    <value>19</value>
+  </data>
+  <data name="ModfiedOverrideWarning.Text" xml:space="preserve">
+    <value>Coordinates modified</value>
+  </data>
+  <data name="ModfiedOverrideWarning.Visible" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
+  <data name="&gt;&gt;ModfiedOverrideWarning.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;ModfiedOverrideWarning.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;ModfiedOverrideWarning.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="ResetBounds.Location" type="System.Drawing.Point, System.Drawing">
+    <value>136, 88</value>
+  </data>
+  <data name="ResetBounds.Size" type="System.Drawing.Size, System.Drawing">
+    <value>88, 24</value>
+  </data>
+  <data name="ResetBounds.TabIndex" type="System.Int32, mscorlib">
+    <value>18</value>
+  </data>
+  <data name="ResetBounds.Text" xml:space="preserve">
+    <value>Reset</value>
+  </data>
+  <data name="&gt;&gt;ResetBounds.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;ResetBounds.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;ResetBounds.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="txtUpperY.Location" type="System.Drawing.Point, System.Drawing">
+    <value>144, 56</value>
+  </data>
+  <data name="txtUpperY.Size" type="System.Drawing.Size, System.Drawing">
+    <value>80, 20</value>
+  </data>
+  <data name="txtUpperY.TabIndex" type="System.Int32, mscorlib">
+    <value>17</value>
+  </data>
+  <data name="&gt;&gt;txtUpperY.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;txtUpperY.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;txtUpperY.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="label4.Location" type="System.Drawing.Point, System.Drawing">
+    <value>120, 56</value>
+  </data>
+  <data name="label4.Size" type="System.Drawing.Size, System.Drawing">
+    <value>16, 16</value>
+  </data>
+  <data name="label4.TabIndex" type="System.Int32, mscorlib">
+    <value>16</value>
+  </data>
+  <data name="label4.Text" xml:space="preserve">
+    <value>Y</value>
+  </data>
+  <data name="&gt;&gt;label4.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label4.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;label4.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="txtUpperX.Location" type="System.Drawing.Point, System.Drawing">
+    <value>32, 56</value>
+  </data>
+  <data name="txtUpperX.Size" type="System.Drawing.Size, System.Drawing">
+    <value>72, 20</value>
+  </data>
+  <data name="txtUpperX.TabIndex" type="System.Int32, mscorlib">
+    <value>15</value>
+  </data>
+  <data name="&gt;&gt;txtUpperX.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;txtUpperX.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;txtUpperX.ZOrder" xml:space="preserve">
+    <value>4</value>
+  </data>
+  <data name="label5.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 56</value>
+  </data>
+  <data name="label5.Size" type="System.Drawing.Size, System.Drawing">
+    <value>16, 16</value>
+  </data>
+  <data name="label5.TabIndex" type="System.Int32, mscorlib">
+    <value>14</value>
+  </data>
+  <data name="label5.Text" xml:space="preserve">
+    <value>X</value>
+  </data>
+  <data name="&gt;&gt;label5.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label5.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;label5.ZOrder" xml:space="preserve">
+    <value>5</value>
+  </data>
+  <data name="txtLowerY.Location" type="System.Drawing.Point, System.Drawing">
+    <value>144, 24</value>
+  </data>
+  <data name="txtLowerY.Size" type="System.Drawing.Size, System.Drawing">
+    <value>80, 20</value>
+  </data>
+  <data name="txtLowerY.TabIndex" type="System.Int32, mscorlib">
+    <value>13</value>
+  </data>
+  <data name="&gt;&gt;txtLowerY.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;txtLowerY.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;txtLowerY.ZOrder" xml:space="preserve">
+    <value>6</value>
+  </data>
+  <data name="label10.Location" type="System.Drawing.Point, System.Drawing">
+    <value>120, 24</value>
+  </data>
+  <data name="label10.Size" type="System.Drawing.Size, System.Drawing">
+    <value>16, 16</value>
+  </data>
+  <data name="label10.TabIndex" type="System.Int32, mscorlib">
+    <value>12</value>
+  </data>
+  <data name="label10.Text" xml:space="preserve">
+    <value>Y</value>
+  </data>
+  <data name="&gt;&gt;label10.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label10.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;label10.ZOrder" xml:space="preserve">
+    <value>7</value>
+  </data>
+  <data name="txtLowerX.Location" type="System.Drawing.Point, System.Drawing">
+    <value>32, 24</value>
+  </data>
+  <data name="txtLowerX.Size" type="System.Drawing.Size, System.Drawing">
+    <value>72, 20</value>
+  </data>
+  <data name="txtLowerX.TabIndex" type="System.Int32, mscorlib">
+    <value>11</value>
+  </data>
+  <data name="&gt;&gt;txtLowerX.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;txtLowerX.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;txtLowerX.ZOrder" xml:space="preserve">
+    <value>8</value>
+  </data>
+  <data name="label11.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 24</value>
+  </data>
+  <data name="label11.Size" type="System.Drawing.Size, System.Drawing">
+    <value>16, 16</value>
+  </data>
+  <data name="label11.TabIndex" type="System.Int32, mscorlib">
+    <value>10</value>
+  </data>
+  <data name="label11.Text" xml:space="preserve">
+    <value>X</value>
+  </data>
+  <data name="&gt;&gt;label11.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label11.Parent" xml:space="preserve">
+    <value>BoundsOverride</value>
+  </data>
+  <data name="&gt;&gt;label11.ZOrder" xml:space="preserve">
+    <value>9</value>
+  </data>
+  <data name="BoundsOverride.Enabled" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
+  <data name="BoundsOverride.Location" type="System.Drawing.Point, System.Drawing">
+    <value>12, 424</value>
+  </data>
+  <data name="BoundsOverride.Size" type="System.Drawing.Size, System.Drawing">
+    <value>248, 120</value>
+  </data>
+  <data name="BoundsOverride.TabIndex" type="System.Int32, mscorlib">
+    <value>12</value>
+  </data>
+  <data name="BoundsOverride.Text" xml:space="preserve">
+    <value>Override bounds</value>
+  </data>
+  <data name="&gt;&gt;BoundsOverride.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;BoundsOverride.Parent" xml:space="preserve">
+    <value>panel2</value>
+  </data>
+  <data name="&gt;&gt;BoundsOverride.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="groupBox1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="UseNativeAPI.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="UseNativeAPI.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 104</value>
+  </data>
+  <data name="UseNativeAPI.Size" type="System.Drawing.Size, System.Drawing">
+    <value>146, 17</value>
+  </data>
+  <data name="UseNativeAPI.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <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">
+    <value>250, 17</value>
+  </metadata>
+  <data name="UseNativeAPI.ToolTip" xml:space="preserve">
+    <value>Using the Native API is potentially faster, but requires binary files, open ports and a webconfig.ini file</value>
+  </data>
+  <data name="&gt;&gt;UseNativeAPI.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;UseNativeAPI.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;UseNativeAPI.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="Password.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 72</value>
+  </data>
+  <data name="Password.Size" type="System.Drawing.Size, System.Drawing">
+    <value>144, 20</value>
+  </data>
+  <data name="Password.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name="Password.ToolTip" xml:space="preserve">
+    <value>Password used to connect to the server</value>
+  </data>
+  <data name="&gt;&gt;Password.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;Password.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;Password.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="Username.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 48</value>
+  </data>
+  <data name="Username.Size" type="System.Drawing.Size, System.Drawing">
+    <value>144, 20</value>
+  </data>
+  <data name="Username.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="Username.Text" xml:space="preserve">
+    <value>Anonymous</value>
+  </data>
+  <data name="Username.ToolTip" xml:space="preserve">
+    <value>Username used to connect to the server</value>
+  </data>
+  <data name="&gt;&gt;Username.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;Username.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;Username.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="MapAgent.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 24</value>
+  </data>
+  <data name="MapAgent.Size" type="System.Drawing.Size, System.Drawing">
+    <value>144, 20</value>
+  </data>
+  <data name="MapAgent.TabIndex" type="System.Int32, mscorlib">
+    <value>3</value>
+  </data>
+  <data name="MapAgent.Text" xml:space="preserve">
+    <value>http://localhost/mapguide/mapagent/mapagent.fcgi</value>
+  </data>
+  <data name="MapAgent.ToolTip" xml:space="preserve">
+    <value>Enter the URL for the MapAgent</value>
+  </data>
+  <data name="&gt;&gt;MapAgent.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;MapAgent.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;MapAgent.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="label3.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label3.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 72</value>
+  </data>
+  <data name="label3.Size" type="System.Drawing.Size, System.Drawing">
+    <value>53, 13</value>
+  </data>
+  <data name="label3.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="label3.Text" xml:space="preserve">
+    <value>Password</value>
+  </data>
+  <data name="&gt;&gt;label3.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label3.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
+    <value>4</value>
+  </data>
+  <data name="label2.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 48</value>
+  </data>
+  <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>55, 13</value>
+  </data>
+  <data name="label2.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="label2.Text" xml:space="preserve">
+    <value>Username</value>
+  </data>
+  <data name="&gt;&gt;label2.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label2.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
+    <value>5</value>
+  </data>
+  <data name="label1.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 24</value>
+  </data>
+  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>56, 13</value>
+  </data>
+  <data name="label1.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="label1.Text" xml:space="preserve">
+    <value>MapAgent</value>
+  </data>
+  <data name="&gt;&gt;label1.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label1.Parent" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
+    <value>6</value>
+  </data>
+  <data name="groupBox1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>12, 8</value>
+  </data>
+  <data name="groupBox1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>248, 128</value>
+  </data>
+  <data name="groupBox1.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name="groupBox1.Text" xml:space="preserve">
+    <value>MapAgent</value>
+  </data>
+  <data name="&gt;&gt;groupBox1.Name" xml:space="preserve">
+    <value>groupBox1</value>
+  </data>
+  <data name="&gt;&gt;groupBox1.Type" xml:space="preserve">
+    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;groupBox1.Parent" xml:space="preserve">
+    <value>panel2</value>
+  </data>
+  <data name="&gt;&gt;groupBox1.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="groupBox3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="RandomTileOrder.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="RandomTileOrder.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 48</value>
+  </data>
+  <data name="RandomTileOrder.Size" type="System.Drawing.Size, System.Drawing">
+    <value>159, 17</value>
+  </data>
+  <data name="RandomTileOrder.TabIndex" type="System.Int32, mscorlib">
+    <value>11</value>
+  </data>
+  <data name="RandomTileOrder.Text" xml:space="preserve">
+    <value>Randomize generation order</value>
+  </data>
+  <data name="RandomTileOrder.ToolTip" xml:space="preserve">
+    <value>Select tiles at random, rather than sequentially</value>
+  </data>
+  <data name="&gt;&gt;RandomTileOrder.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;RandomTileOrder.Parent" xml:space="preserve">
+    <value>groupBox3</value>
+  </data>
+  <data name="&gt;&gt;RandomTileOrder.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="ThreadCount.Location" type="System.Drawing.Point, System.Drawing">
+    <value>128, 24</value>
+  </data>
+  <data name="ThreadCount.Size" type="System.Drawing.Size, System.Drawing">
+    <value>104, 20</value>
+  </data>
+  <data name="ThreadCount.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name="ThreadCount.ToolTip" xml:space="preserve">
+    <value>Number of concurrent request to server</value>
+  </data>
+  <data name="&gt;&gt;ThreadCount.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;ThreadCount.Parent" xml:space="preserve">
+    <value>groupBox3</value>
+  </data>
+  <data name="&gt;&gt;ThreadCount.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="label9.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label9.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 24</value>
+  </data>
+  <data name="label9.Size" type="System.Drawing.Size, System.Drawing">
+    <value>102, 13</value>
+  </data>
+  <data name="label9.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="label9.Text" xml:space="preserve">
+    <value>Concurrent requests</value>
+  </data>
+  <data name="&gt;&gt;label9.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label9.Parent" xml:space="preserve">
+    <value>groupBox3</value>
+  </data>
+  <data name="&gt;&gt;label9.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="groupBox3.Location" type="System.Drawing.Point, System.Drawing">
+    <value>12, 328</value>
+  </data>
+  <data name="groupBox3.Size" type="System.Drawing.Size, System.Drawing">
+    <value>248, 80</value>
+  </data>
+  <data name="groupBox3.TabIndex" type="System.Int32, mscorlib">
+    <value>7</value>
+  </data>
+  <data name="groupBox3.Text" xml:space="preserve">
+    <value>Threading</value>
+  </data>
+  <data name="&gt;&gt;groupBox3.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;groupBox3.Parent" xml:space="preserve">
+    <value>panel2</value>
+  </data>
+  <data name="&gt;&gt;groupBox3.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="groupBox2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="MetersPerUnit.Location" type="System.Drawing.Point, System.Drawing">
+    <value>104, 0</value>
+  </data>
+  <data name="MetersPerUnit.Size" type="System.Drawing.Size, System.Drawing">
+    <value>104, 20</value>
+  </data>
+  <data name="MetersPerUnit.TabIndex" type="System.Int32, mscorlib">
+    <value>9</value>
+  </data>
+  <data name="MetersPerUnit.ToolTip" xml:space="preserve">
+    <value>The number of meters pr. map unit</value>
+  </data>
+  <data name="&gt;&gt;MetersPerUnit.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;MetersPerUnit.Parent" xml:space="preserve">
+    <value>OfficialMethodPanel</value>
+  </data>
+  <data name="&gt;&gt;MetersPerUnit.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="label8.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label8.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 0</value>
+  </data>
+  <data name="label8.Size" type="System.Drawing.Size, System.Drawing">
+    <value>74, 13</value>
+  </data>
+  <data name="label8.TabIndex" type="System.Int32, mscorlib">
+    <value>8</value>
+  </data>
+  <data name="label8.Text" xml:space="preserve">
+    <value>Meters pr. unit</value>
+  </data>
+  <data name="&gt;&gt;label8.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label8.Parent" xml:space="preserve">
+    <value>OfficialMethodPanel</value>
+  </data>
+  <data name="&gt;&gt;label8.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="OfficialMethodPanel.Enabled" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
+  <data name="OfficialMethodPanel.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 128</value>
+  </data>
+  <data name="OfficialMethodPanel.Size" type="System.Drawing.Size, System.Drawing">
+    <value>216, 24</value>
+  </data>
+  <data name="OfficialMethodPanel.TabIndex" type="System.Int32, mscorlib">
+    <value>13</value>
+  </data>
+  <data name="&gt;&gt;OfficialMethodPanel.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;OfficialMethodPanel.Parent" xml:space="preserve">
+    <value>groupBox2</value>
+  </data>
+  <data name="&gt;&gt;OfficialMethodPanel.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="LimitTileset.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="LimitTileset.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 24</value>
+  </data>
+  <data name="LimitTileset.Size" type="System.Drawing.Size, System.Drawing">
+    <value>118, 17</value>
+  </data>
+  <data name="LimitTileset.TabIndex" type="System.Int32, mscorlib">
+    <value>11</value>
+  </data>
+  <data name="LimitTileset.Text" xml:space="preserve">
+    <value>Limit number of tiles</value>
+  </data>
+  <data name="LimitTileset.ToolTip" xml:space="preserve">
+    <value>Set a limit on the number of tiles generated, note that this may prevent all tiles from being created</value>
+  </data>
+  <data name="&gt;&gt;LimitTileset.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;LimitTileset.Parent" xml:space="preserve">
+    <value>groupBox2</value>
+  </data>
+  <data name="&gt;&gt;LimitTileset.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="UseOfficialMethod.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="UseOfficialMethod.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 104</value>
+  </data>
+  <data name="UseOfficialMethod.Size" type="System.Drawing.Size, System.Drawing">
+    <value>116, 17</value>
+  </data>
+  <data name="UseOfficialMethod.TabIndex" type="System.Int32, mscorlib">
+    <value>10</value>
+  </data>
+  <data name="UseOfficialMethod.Text" xml:space="preserve">
+    <value>Use official method</value>
+  </data>
+  <data name="UseOfficialMethod.ToolTip" xml:space="preserve">
+    <value>The official method is the most accurate, but requires that the meters per map unit is entered</value>
+  </data>
+  <data name="&gt;&gt;UseOfficialMethod.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;UseOfficialMethod.Parent" xml:space="preserve">
+    <value>groupBox2</value>
+  </data>
+  <data name="&gt;&gt;UseOfficialMethod.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="MaxRowLimit.Location" type="System.Drawing.Point, System.Drawing">
+    <value>104, 0</value>
+  </data>
+  <data name="MaxRowLimit.Size" type="System.Drawing.Size, System.Drawing">
+    <value>104, 20</value>
+  </data>
+  <data name="MaxRowLimit.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <data name="MaxRowLimit.ToolTip" xml:space="preserve">
+    <value>The maximum number of rows to generate tiles for</value>
+  </data>
+  <data name="&gt;&gt;MaxRowLimit.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;MaxRowLimit.Parent" xml:space="preserve">
+    <value>TilesetLimitPanel</value>
+  </data>
+  <data name="&gt;&gt;MaxRowLimit.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="label6.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label6.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 0</value>
+  </data>
+  <data name="label6.Size" type="System.Drawing.Size, System.Drawing">
+    <value>52, 13</value>
+  </data>
+  <data name="label6.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="label6.Text" xml:space="preserve">
+    <value>Max rows</value>
+  </data>
+  <data name="&gt;&gt;label6.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label6.Parent" xml:space="preserve">
+    <value>TilesetLimitPanel</value>
+  </data>
+  <data name="&gt;&gt;label6.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="MaxColLimit.Location" type="System.Drawing.Point, System.Drawing">
+    <value>104, 24</value>
+  </data>
+  <data name="MaxColLimit.Size" type="System.Drawing.Size, System.Drawing">
+    <value>104, 20</value>
+  </data>
+  <data name="MaxColLimit.TabIndex" type="System.Int32, mscorlib">
+    <value>7</value>
+  </data>
+  <data name="MaxColLimit.ToolTip" xml:space="preserve">
+    <value>The maximum number of cols to generate tiles for</value>
+  </data>
+  <data name="&gt;&gt;MaxColLimit.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;MaxColLimit.Parent" xml:space="preserve">
+    <value>TilesetLimitPanel</value>
+  </data>
+  <data name="&gt;&gt;MaxColLimit.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <data name="label7.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label7.Location" type="System.Drawing.Point, System.Drawing">
+    <value>8, 24</value>
+  </data>
+  <data name="label7.Size" type="System.Drawing.Size, System.Drawing">
+    <value>49, 13</value>
+  </data>
+  <data name="label7.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name="label7.Text" xml:space="preserve">
+    <value>Max cols</value>
+  </data>
+  <data name="&gt;&gt;label7.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;label7.Parent" xml:space="preserve">
+    <value>TilesetLimitPanel</value>
+  </data>
+  <data name="&gt;&gt;label7.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="TilesetLimitPanel.Enabled" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
+  <data name="TilesetLimitPanel.Location" type="System.Drawing.Point, System.Drawing">
+    <value>24, 48</value>
+  </data>
+  <data name="TilesetLimitPanel.Size" type="System.Drawing.Size, System.Drawing">
+    <value>216, 48</value>
+  </data>
+  <data name="TilesetLimitPanel.TabIndex" type="System.Int32, mscorlib">
+    <value>12</value>
+  </data>
+  <data name="&gt;&gt;TilesetLimitPanel.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;TilesetLimitPanel.Parent" xml:space="preserve">
+    <value>groupBox2</value>
+  </data>
+  <data name="&gt;&gt;TilesetLimitPanel.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="groupBox2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>12, 144</value>
+  </data>
+  <data name="groupBox2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>248, 168</value>
+  </data>
+  <data name="groupBox2.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <data name="groupBox2.Text" xml:space="preserve">
+    <value>Tilesettings</value>
+  </data>
+  <data name="&gt;&gt;groupBox2.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;groupBox2.Parent" xml:space="preserve">
+    <value>panel2</value>
+  </data>
+  <data name="&gt;&gt;groupBox2.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="panel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
+    <value>Right</value>
+  </data>
+  <data name="panel2.Location" type="System.Drawing.Point, System.Drawing">
+    <value>293, 0</value>
+  </data>
+  <data name="panel2.Size" type="System.Drawing.Size, System.Drawing">
+    <value>272, 537</value>
+  </data>
+  <data name="panel2.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="&gt;&gt;panel2.Name" xml:space="preserve">
+    <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>
+  </data>
+  <data name="&gt;&gt;panel2.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <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">
+    <value>True</value>
+  </metadata>
+  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
+    <value>6, 13</value>
+  </data>
+  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
+    <value>565, 578</value>
+  </data>
+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        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
+        AD/8AAA//AAAP/wAAB/8AAAf/AAAH/wAAB/8AAA//AAAP/4AAD/+AAB//wAA//+AAP//wAP//+AH///+
+        P/8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA
+        AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAiIiIiIiIiIgAAAAA
+        j/j4+Pj/j/+AAAAAiIiIiIiPh4iAAAAAj4iIiHiPeY+AAAAAiIiIiPj4iIiAAAAAj4+I+IiIiIiAAAAA
+        iPj4j4+Pj48AAAAACIiIiIeIiIgAAAAACPiHyMjHiIgAAAAAAIfH6O6HyIAAAAAAAHjjLn7uh4AAAAAA
+        CI6GNo7I5nAAAAAAB+hnp2juZ2AAAAAACI56do6GdjgAAAAAeOhneOhnpycAAAAAeHaP746GOmcAAAAA
+        hmeoiOjnZ+cAAAAAhqcn746OJjcAAAAAB3p6do6OY2gAAAAAB2PjaOjn7nAAAAAAAGZ2p2bsiAAAAAAA
+        AAdo56d+hwAAAAAAAAB4Znp3AAAAAAAAAAAAiHgAAAAAAPAADwDwAAcA8AAHAPAABwDwAAcA8AAHAPAA
+        DwD4AA8A+AAPAPwAHwD8AB8A+AAfAPgAHwD4AA8A8AAPAPAADwDwAA8A8AAPAPgADwD4AB8A/AA/AP4A
+        PwD/AP8A/8P/ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
+        AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAiIiIiI
+        iAAAD4iIj/iIAAAIiIiIh4gAAA+Pj4j4iAAACIiIiIj4AAAI+Ih4eIAAAAB3bs6HgAAAAI5yjsYAAAAI
+        53p+hnAAAAiGeOhqcAAACGjvjnZwAAAGY46OenAAAAemPo52cAAAAHdnbugAAAAABoY3eAAAAAAAjngA
+        AADgAwAA4AMAAOADAADgAwAA4AMAAOAHAADwBwAA8A8AAOAHAADgBwAA4AcAAOAHAADgBwAA8A8AAPgP
+        AAD8PwAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAABjYHwAnC0rAJ4w
+        LACdMzMAnzg1AJ85OQCgMy4AqD0vAKA2NgCjOjYAojk4AKtBLgCwSC0Aq0MzAKhDPACrSToAs084ALhX
+        PACmQkEAqExEALRURAC9X0EAsVVMAKNTUgCuXFUAsVlVAL1jRwC7ZFEAtGNZALhjXAC+bF8AmmdoAKNl
+        ZQCsb2AAuWhlALttagCrfGMAt3RvAL1xbACtcXIAp3l5ALx7ewDBak8AwWxSAMN3WgDAb2AAxXlkADmJ
+        BwA5jRMAOZMZADSHIwA3liIAOJcgADiZJAA2kiwAN5kuADidKwA3nj4AOaQ3AEGLCwBEjhMAV4kdAEiR
+        FwBYlBcAUpQbAFmWHQBlmBwATZQiAFqXJwBjiyYAaJwmAHKeJABslDcAcZM4AHmhKwBoojwAcqQ8ADms
+        RgB1lUEAfpdMAHqZSAB9qUYAe6lKAIWlLACOqTYAkqs4ALq0PAD7uB4A26k8AOerJADrriUA4KcoAPa1
+        IgD+uyMA87UoAP29LADmrjAA4q48APy+MQD2vT0A/sE2AIaUSQCci1gAlpNXAK6MXAC1h10Ah6xJAI6w
+        TwCVsU4AkrJWALWrQQCltEsAubhHAKi3VQCeimIAmJdkAKiIYwCwi2YAo5xjAJm3YwC1vmAA369IAMK4
+        QADDv1UA0LlUAOezQQDiskgA67xWAOa7XADNi3gA0ZB7ALrBZwCqwHIAt8R5AMjAWQDWwlUA/cZGAOvA
+        XwDtyVkA/MpXAM3EYgDayWkAxsZzANfLdADmyGoA+81lAP3QagD1zngA59J8APzTdwAXF7QAGRmxADY2
+        rAA2NrQAZGKGAG1qmwBOTKcAUE+qAGZkswB6euQAjIaNAJCNjQCYlZUAnZiYAK2PiwC1j48Aop2dAKmd
+        nQC7lJAAu5iXAL6/jgCIhLgAmZe9AKWhoQCopKQAraqpALijogCxra0AuquqALWysgC5trYAvbm5AMyP
+        hQDOkYcA0paHAMKenADRm5cA1aCSANiikADVrpcA1qWeAN2tmgDIqacAyKqoAN2voADas6MAz7SwAMO8
+        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
+        MwD+wjsAgotGAJmERgCXikoAoYFYAK2IWgC1gloAjqVKAJSvRwCdsUQAhrBTAI6yVgCeuFwAobFAAKOv
+        VACguF8AtLtYAKyzYgDPv00AyL5SAOS2UQDnulIAzot2AM6QfgDRkHkA28JQANDAWwDlwUMA6cFCAOfF
+        TQDqw0oA/sRCAP7HSAD9yE0A7MBfAP7KUgD+zFsAzsVmAM3GaQDExXEA0Mp3AN3PeQDlyWMA7s1pAPLM
+        YwD9zmQA8cZqAP3PaQD90GsA+c9yAPzSdQDx030A/dN5ADExswBSUbAAcnCqAGhltQBISMAAhoGXAK6N
+        jACxgoIAv46LAK+dnQC6lpAAupyZAJiSogCEgbwAp6KiAKyjowCopaUArqurALCtrQC1r68As7CwALWy
+        sgC3tLQAubW0AL22tgC6uLgAvbq6AL+8uwDJi4cAyIuJAM+ShADRlIAA1JuCANGXjgDWno4A2aKHANqj
+        igDBs4MA16CQANupmwDdsZAA4bWTAMqwrgDFubkAwry8AMW+vgC5x4IAu8iCAO/JiQDwzYcA5NOIAPTU
+        hAD71YMA/deIAPfYjQD82YoA6sSdAOjYmQD92pIA8NucAPzcmgDrxaEA8M+gAOjYowDl26gA/d6kAPLS
+        qgD936gA/eKyAJmWwQDDwMAAxcHBAMfExADJxcUAzcbGAMvIyADNyckA0srKANHNzQDUz84A3NPTANvU
+        0wDY1tYA3tXVANrY2ADc2dkA39zcAODX1wDi2NgA5NvbAObe3gD95sAA5eLiAO3l5QDu6ekA7uzsAPLr
+        6gDx7e0A8/DwAPTw8AD39PQA////AAAAAAAAAOLGtbW1s7OzsLCwrq6urquuq66rsAAAAAAAAAAAAADi
+        +f39/f39/f39/Pz9/fn9/Pz8/P35sAAAAAAAAAAAAOL967Ozs7Ozs7Ozs7PG/Pj89/T3/P2wAAAAAAAA
+        AAAA4v3rxsbGxcbFxsXGxuT39/enmt/3/bAAAAAAAAAAAADi/Oeura6urq6urq6us/Pz65uenfT8sAAA
+        AAAAAAAAAOL88fHx8fHx8fHx8fHx8vLxn5ym8fmwAAAAAAAAAAAA4vfx8fHx8fHx8fHx8fHx8fHx5/Hx
+        97AAAAAAAAAAAADk5Obn5+fn5+fk5OTk5OTkx+LH4sa1sAAAAAAAAAAAAADi8PDw8PDw8PDw7/Dr7Ovv
+        7Ozs7LAAAAAAAAAAAAAAALP25+zm7OTk4sa1s7Cz4ufp5+z0qgAAAAAAAAAAAAAA5/Dm5ubH58SiGxkZ
+        oKmqq+bm5uziAAAAAAAAAAAAAAAA4uzGxhwFFny9vbkXAQujxsbsqwAAAAAAAAAAAAAAAAC18KUDaTp2
+        eWJhYnrLugKhs+urAAAAAAAAAAAAAAAAAACkB9JsKypyhGVgX15jyxQatQAAAAAAAAAAAAAAAAAAAAjY
+        h38pSylyhmVlX19ecwyhAAAAAAAAAAAAAAAAAAAV15OSlzNLSy1uhmVgYFtVOQQAAAAAAAAAAAAAAAAA
+        AHvNlZdQLktLSzORhGVkX1UtQCQAAAAAAAAAAAAAAAAe3JaZ0ChLS0o1SZCIhoNcOEs1BAAAAAAAAAAA
+        AAAAAB3bl8/bO0tKNsyZlYl4KCwuSiwNAAAAAAAAAAAAAAAAfdHP1HExT2/T1M+XkkdKS0tLSky3AAAA
+        AAAAAAAAAAC90Yw0Mdre3tvUz5eSbi1LS0opTSQAAAAAAAAAAAAAAL5xMCjJUfXe3dvPmZWSVikpRHe/
+        IwAAAAAAAAAAAAAAaiYtSiwpyN7b1M+XkohYJ1g/MWa2AAAAAAAAAAAAAAARKUtLS0spcNXUz5WShn4x
+        KSwsDgAAAAAAAAAAAAAAACI5S0tLS0spNI2XkomFhD8mMzcGAAAAAAAAAAAAAAAAAGcsS0pDNUpGmJeS
+        hoSERYOCwyMAAAAAAAAAAAAAAAAAID5KQ803JYuKN4+FZWBkX88IAAAAAAAAAAAAAAAAAAAAEjkzdUgn
+        WUguM1aDX1+XIQAAAAAAAAAAAAAAAAAAAAAAEk4vbTiQR0pLSlSEzyG7AAAAAAAAAAAAAAAAAAAAAAAA
+        H2jZjlopS0osMsIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAwRBrU0FBZmcQuQAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAwLzBAAAAAAAAAAAAAAAAAAD8AAAf+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/wA
+        AB/8AAAf/AAAH/4AAD/+AAA//wAAf/8AAH/+AAB//gAAP/wAAD/8AAA//AAAH/wAAB/8AAAf/AAAH/wA
+        AD/8AAA//gAAP/4AAH//AAD//4AA///AA///4Af///4//ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
+        AAAAAAAAAAEAAAABAAAAAAAAfXg9AKVfUwCqWVcAqFlYAJ1pTACbf0QAoH5HAKpqWgCxZVcAsW5eALFp
+        YAC+cmcAuHFrALp3bgCkdnYAunh1AMN2ZADEemcAOpcgADyaJgA9nCkAOJ4zADmgMAA5oTQAPaI1ADum
+        OgA+pDgAOaU8AEqNDABViygAR5omAE6YJABAni0ASZ0oAE2bLABQmiIAWZslAFyXKQBUnS0AQp8yAEyb
+        MABPnDgAVpY3AFmdPABmny0AfYY8AHmJOABnnzEAXKAuAECgMABIojkAWKU7AF6mPwBhoi4AZKItAGKj
+        NAB6pTEAOqpCADqrRQA6rEYAOq1IAGKqRwBuqkQAdqdCAHurQgCGpzEAiKs2AIWrOgCHrT4An7A8ANq1
+        LwDStzAA2LgwAPy7JgD+vCUA8LMpAP6/LwDrsjUA67U9AOG9PgD+vzEA/sAyAPbAOQD+wz4A/sU+AIqe
+        TwCkhVoAj6RLAJuxQwCSs04AmLJLAJ6zSgCVtVQAsLVDALiyUwC+s1YAvbxRALa8WAC+gWAAl7hhALK9
+        YQDGvEsA0L1KAMi/VQDCvlgAxodqAMqCbQDJhG8AzIZvAMuFcgDMhnEA1ZVxANWadgDZnXYA2aN9AN66
+        cQD+xEAA8MRIAP7ISwDyx1IA/spTAP7KVQD+zFQA/sxaAP7NXwDZyWwA68FnAPXHYwD+zWAA/c9nAP7P
+        aQD+0GkA+dFvAP3RbgDv0nsA/dJxAPzSdgD30HsA/dV+AFxbuQBYWMwAvJiVAJiSogCKhroAmZS3AK2o
+        qAC7pqYAvainALSqqgC5qakAtrCwALiysgC8tLMAuLa2ALu4uAC+uroAvry8AMOBgADSlYMA05aEANWb
+        iQDTm5AA05yUANKdmADXoZIA26qaAOa8jQDmuZAAxrOyAMG6uQDBvr4A1dCMAM3RlADi0okA/daFAOvD
+        lwD52pQA/duUAP3cmwD43p0A692tAPvfogD94awA/eS4AL24zwDIv8AAwsDAAMXBwQDHxMQAycXFAMzG
+        xgDLyMgAzcnJAM/MzADQxscA0MrKANTKygDRzc0A1M/PANHL2ADU0NAA19TUANvT0wDY1dUA3tXVANvY
+        2ADg1tYA4dnYAOLd3QDm3d0A6uLiAO7m5gDw6uoA9O7uAPbw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAD///8AAAAAAMa9vb2rq52dnZubmpuam5sAAAAAAAAAAMLV0dHR0dHR0dHV19fV
+        19e9AAAAAAAAAMLPmpeal5qXmpvR1MiMudWrAAAAAAAAAMLPm6qqqqqqqqrP0pGNkNO9AAAAAAAAAL/P
+        z8/Pz8/Pz8/Pz8OPutGrAAAAAAAAAJ3GxsbGxsbGxsbGwsK/wr+bAAAAAAAAAL/Rzs7Rz8/KxsrPysrK
+        ysYAAAAAAAAAAADPxsa/v7+qlJWSl7/Gyp0AAAAAAAAAAAC9wrqODQxrawwED5urz5sAAAAAAAAAAAAA
+        xgtXK2BPTk9/cAOTvQAAAAAAAAAAAAAACadgHDJnVE1KTHQClgAAAAAAAAAAAACiqICFIT0yZnVSSkce
+        EAAAAAAAAAAAAABriohaOj09OHxUTUgWAQAAAAAAAAAAAACwiK8/PTpBfnx4Qzc6Kp4AAAAAAAAAAG62
+        r64wPmSxioZZOj09MggAAAAAAAAAAGu0XSCtuLe0r4ZoGz0bIQUAAAAAAAAAAG5AMjQntbe0r4Z8OSBC
+        RgoAAAAAAAAAAKEpPT06NayxioZ5XhMhIQ0AAAAAAAAAAAAvOj06OiFliHx3dh03VqQAAAAAAAAAAABj
+        KBtdITGHaXl1U0l5EQAAAAAAAAAAAAAABiFiLSVcMkRQSlRyAAAAAAAAAAAAAAAAAAcmW2FFPT04gnCi
+        AAAAAAAAAAAAAAAAAABqc1gjMywuEgAAAAAAAAAAAAAAAAAAAAAAAKagoKUAAAAAAAAAAAAA8AAPAPAA
+        BwDwAAcA8AAHAPAABwDwAAcA8AAPAPgADwD4AA8A/AAfAPwAHwD4AB8A+AAfAPgADwDwAA8A8AAPAPAA
+        DwDwAA8A+AAPAPgAHwD8AD8A/gA/AP8A/wD/w/8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
+        AAAAAQAAAAEAAAAAAACMeE0Arnh1ADmlOgA9pTgAPKg/AFCXHwBmjzcAc4k2AGqQOwBaoi4ATqIxAEql
+        OABWpDUAU6g7AHylLwBlpDcAbao7ADqqQwA6q0UAOqxGAGCSQQBCqUEAXaBAAFmsSQCHiT0Ah5E+AJOr
+        MAC5sjMA27w+APq5IwD+visA7b43APG3NgD+wDMAqoZdAIyvQQCSskwAj6lQAJGyUQCdtVIAqLdNAKm3
+        UQCrvFoArI9gALGOYQCykmoAtZRsAJu5ZQCtvGEAoL5tANq3RADMv1IA8L1JANSWYgDDiXwA1LV+AOKp
+        aQDttmEA4ax9AOXBRgD+xkcA/shNAObHXQD+zFoAxch3AOzIZAD+0W0A+tF3AP3TdwD91HwAZGKsALaD
+        ggCqkpIAvri4AMePggDCj4oA05iCAMGZkwDRppMA2a2bANqrowDEsK8Awr+/AP3VgAD914YA+tuaAP3d
+        oAD95LcAop7NALGqwgDDwMAAysPDAMnGxgDKyMgAzcjIAM/MzADSy8sA0c7OANTOzQDW0M8A1tDQANrR
+        0QDZ1dUA3NXUANrT3gDh19cA5d/eAOnj4wDw6OcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAP///wAAAABlYmJgYF5eXl5eXgAAAAAAbEpKSkpKaG1ZaWIAAAAAAGteXl5cXmZqR1pg
+        AAAAAABoYmZiZmJiYl9iUwAAAAAAYmhoYmJfXmZkaF4AAAAAAGJfUkxLNwJJXl4AAAAAAAAATi0XMyE1
+        NkhTAAAAAAAAADtCBA48Ih4aAAAAAAAAAE1EKxQEKT0gDQEAAAAAAAA7VScYQUU0BBQVAAAAAAAAOBAw
+        WFdVPwwMJgAAAAAAAAgUBDJWRUAPCgcAAAAAAAAsFBYEKEM+HBsjAAAAAAAAAAklBioRHR86AAAAAAAA
+        AAAAGjEkFAw5UQAAAAAAAAAAAABQLy9PAAAAAAAA4AMAAOADAADgAwAA4AMAAOADAADgBwAA8AcAAPAP
+        AADgBwAA4AcAAOAHAADgBwAA4AcAAPAPAAD4DwAA/D8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGtrR2qpqVto56ef6Kd
+        nYGhnJyBn5ubgZ6amoGdmZiBnJeXgZqWloGZlJSBmJOTgZaSkoGVkJCBk4+PgZKOjoGRjY2BkIuLgY+K
+        ioGNiYmBjYiIgYyIiIGLh4eBi4eHgYuHh4GLh4eBi4eHgYuHh4GLh4eBi4eHgYuHh4GMiYl7n5ycUJ2a
+        mgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsq6uBKml
+        pda+urr+x8TE/sfExP7Gw8P+xsPD/sXCwv7EwcH+xMHA/sPAwP7Cv7/+wb6+/sC9vf6/vLz+v7y8/r67
+        u/69urr+vLm5/ry5uf67uLj+u7i4/rq3t/66t7f+ube3/rm3t/65t7f+ube3/rm3t/65t7f+ube3/rm3
+        t/62s7P+mJWV/p+cnGkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAubW1F6ahofn39fX++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj0
+        9P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj09P749PT++PT0/vj0
+        9P749PT++PT0/vj09P759vb+xsPD/qKenp0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAvbq6G6eiovv39vX+9Ozs/t7X1/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3H
+        x/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3Hx/7Nx8f+zcfH/s3Hx/7OyMj+6+Tj/vPr6/7z7Ov+8+vr/vPs
+        6/7z6+v+8enp/vDo6P7z6+v+8+vr/vPs6/728fH+yMbG/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovv39fX+8enp/sG6uv6inZ3+op2d/qKd
+        nf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6inZ3+op2d/qKdnf6jnp7+29TU/vDo
+        6P7w6Oj+8Ojo/vDo5/7i3Nz+qKXB/pmXvf7SztH+7ubm/vDo6P707u7+yMbG/qOgoKMAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovv29PT+7eXl/tvU
+        0/7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szGxf7MxsX+zMbF/szG
+        xf7Ox8b+5t7e/uzk5P7t5OT+7OTk/uvi4v6IhLj+GRmx/hcXtP5QT6r+4tvc/u3k5P7x7Ov+yMbG/qOg
+        oKMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvrq6G6ei
+        ovv18/P+6eHh/rq0tP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2YmP6dmJj+nZiY/p2Y
+        mP6dmJj+nZiY/p2YmP6emZn+1MzM/ujf3/7o39/+6N/f/trS0f5OTKf+Nja0/jY2tP42Nqz+ycLM/ujf
+        3/7v6Oj+yMXF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAvrq6G6eiovv08vL+5t3d/uXb2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb
+        2/7k29v+5Nvb/uTb2/7k29v+5Nvb/uTb2/7k29v+5dvb/uXb2/7l29v+5dvb/tDHx/5tapv+eXni/nx8
+        5v5mZLP+w7u9/uXb2/7s5ub+yMXF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAvrq6G6eiovvz8fH+4tnZ/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX
+        1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uDW
+        1v6jnJ3+Y2B8/mRihv6Mho3+2c/P/uHX1/7q4+P+x8XF/qOfn6MAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvbm5G6eiovvy8PD+39bW/t7U1P7e1NT+3tTU/t7U
+        1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U1P7e1NT+3tTU/t7U
+        1P7e1NT+3tTU/t7U1P7e1NT+0MbG/snAwP7d09P+3tTU/t7U1P7n4OD+x8XF/qOfn6MAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtrKyFKahoffx7+/+7+rq/u/q
+        6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q
+        6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7v6ur+7+rq/u/q6v7x7u7+wsDA/p+c
+        nJkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs6+vBKik
+        pOKxra3+ura2/rq2tv66trb+ura2/rq2tv66trb+ura2/rq2tv66trb+ubW1/rm1tf64tLT+t7Sz/raz
+        sv61srL+tbGx/rOwsP6yr6/+sa6u/rCtrP6vrKz+rqur/q2qqv6sqaj+q6io/qqnp/6ppqb+qaWl/qik
+        pP6moqL+kY2N/puYmG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAK+qqpG6trb+2tfX/tvY2P7b2Nj+29jY/tvY2P7b2Nj+29jY/tvY2P7b2Nj+2tjY/trY
+        2P7a19f+2dfX/tnX1/7Z1tb+2NbW/tjW1v7X1dX+19TU/tbU1P7W1NT+1dPT/tXT0/7U0tL+1NLS/tPS
+        0v7T0dH+09HR/tLQ0P7Ixsb+jIiI9JyYmBkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+qqjKsp6f97+7u/t3Z2f7b19f+29fX/tvX1/7b19f+29fX/tvX
+        1/7b19f+29fX/trW1v7X09P+1NDQ/tHNzf7QzMz+0MzM/tDNzf7Tz8/+19PT/trW1v7b19f+29fX/tvX
+        1/7b19f+29fX/tvX1/7b19f+29fX/ufk5P7EwsL+ko6OrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGtrQGppaXP3Nra/t/c3P7Uz8/+1M/P/tTP
+        z/7Uz8/+1M/P/tPOzv7KxcX+xsHB/sfBwf7Jw8P+ycTD/sfAwP7Bu7v+urW1/rWvr/6wq6v+rqmp/rCs
+        rP67trb+yMPD/tPOzv7Uz8/+1M/P/tTPz/7Uz8/+1dHR/u/u7v6al5f+n5ubTQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxrKxsu7e3/uzp
+        6f7RzMz+0cvL/tHLy/7Ry8v+z8nJ/sS+vv7Pycn+1M7O/tTNzf7QwcD+yKqo/sKenP6+mJf+uZiX/rij
+        ov61raz+rqmp/qmkpP6moaH+qaSk/reysv7Qysr+0cvL/tHLy/7Ry8v+29bW/tza2v6LiIjfnJiYBwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AACppaUVpqGh8ejn5/7Tzc3+y8TE/svExP7LxMT+xr+//sfAwP7Iqaf+t3Rv/qhJQ/6hNC3/nzAr/qAz
+        Lv6gMi//ni8s/p0tKv6fODX+o1NS/qd5ef6pnZ3+pqGh/qqkpP7IwcH+y8TE/svExP7LxMT+5uPj/rGv
+        r/6Oi4uDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAApqGhnsrHx/7f29v+xL29/sS8vP7EvLz+u5SQ/qlPRv6qRTz/uGNc/s6R
+        h/7iuaT/79Gw/vXasv7227L/8tWw/ufCqP7UoJP/uWhl/p4wLv6dMzP/o2Vl/rmsrP7EvLz+xLy8/sS8
+        vP7LxcX+6Obm/o+Li/qRjY0iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp6KiM6qlpfvr6en+xb6+/ryrqf6uXlX+qkI3/659
+        Yv91lUH/e6lK/+vQjP/mu1z/369I/9upPv/aqDr/3Ko9/+KySP/rwF//9tWJ//XZr//Mj4X/ojk4/585
+        Of+1j4/+vra2/r63t/7Y1NT+wsDA/oyIiLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApqGhAaagoLvRz8/+z7Sw/qpI
+        O/6yUkb/5sOx/lGTH/42kiz/NIcj/leJHf7QuVT/9r09/vq9NP77vTH/+bos/vO1KP7rriX/4Kco/uKu
+        PP7yy27/89ar/rtuaf+bLCz+rXFy/sK6uv7p5+f+mJWV/ZGNjUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqX
+        lEStj4v+rUc3/r5sX/733rf/8c6E/mOLJv43nj7/OqtI/jmjN/5VlBj/981i/v7DQP7+wTr//sA1/v6/
+        MP7+viv//rwm/va1Iv7nqyT/57NB/vnakP/Smo/+oDY2/rx7e/7Jx8f+jomJzJKOjgQAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAALV0aCmrRjT3wXNj//ritP/rw2v/67xW/6KyS/84miX/Oq1I/zqtSP84nSz/Ypoi/+nL
+        Y//+x0n//sM+//7BOP/+wDL//r4s//68Jv/+uyH/9bQf/+auMP/JxXX/lpNg/6I6Of+WYWL0mn5+OQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAuWJQCbFNOs26YlH++OG4/u3Fb/7zw1r+/sxc/vnUev5CkRT+Oq1I/jqt
+        SP46rUj+OaQ3/kuTGP7RxF/+/shL/v7EQP7+wTn+/sAy/v6+LP7+vCX+/rsf/vu4Hv61q0H+OoYI/p6K
+        Yv6fMzP4qV1cPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtlhEe69HMv7w1Ln+889//vTGYf7+zmT+/s9p/vDU
+        f/5Lkhf+OqxG/jqtSP46rUj+Oq1I/jqoQP5RlBr+989p/v7HSf7+xEH+/sE5/v6/Mv7+vir+/rwk/v67
+        H/66tDz+NYwd/kWPGP6sb2D+oTk406dIRwcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5X0sWsEgy7tSZiP763p3+88do/v3Q
+        af790W7+9taE/l+aJf45ojX+Oq1I/jqtSP46rUj+Oq1I/jqtSP44myj+q7dR/v7LVv7+x0j+/sRA/v7B
+        OP7+vy/+/r0o/v68I/7CuED+N5Yi/jeZLv5skzr+pkJC/qhIR2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3WUN5s085/vjh
+        wf71znn+/M9t/v3Sc/791Hv+vcNs/jiYIf46rUj+Oq1I/jqtSP46rUj+Oq1I/jqsRv45ni3+a50p/v7Q
+        aP7+yVD+/sdG/v7DPf7+wDX+/r8v/v7AMf6Kpi7+OaM2/jmnRf46jxX+qHtj/qE3NtaoSEcCAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlc
+        RQG0UDfWzo16/vzhpv74znL+/dN1/v3VfP792In+jK9M/jmjNf46rUj+Oq1I/jqtSP46rUj+OZol/lGW
+        Hv6UsU3+1cpy/v7PZv7+y1b+/shM/v7IS/7vylr+ubhF/rq3Qv5nmR3+Oqc9/jqtSP44my/+fpdM/qE3
+        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
+        r/61r6/+ta+v/rWvr/61r6/+ta+v/rWvr/61r6/+ta+v/rWvr/69t7b+597e/ufe3v7c09P+UlGw/khI
+        wP5oZbX+5Nvb/vLu7v6em5vBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsq6uue/q
+        6v7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/uLY2P7i2Nj+4tjY/t7U
+        1P6GgZf+cnCq/piSov7h19f+7+vr/p6bm8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AACxra247enp/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX1/7h19f+4dfX/uHX
+        1/7h19f+4dfX/t/W1v7Tysr+4NfX/uHX1/7u6en+npqawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAKunp6DJxsb+zsvL/s7Ly/7Oy8v+zsvL/s7Ly/7Oy8v+zsrK/s3Kyv7Mycn+y8jI/srH
+        x/7Jxsb+yMXF/sfExP7Gw8P+xcLC/sTBwf7DwMD+wr+//r26uv6Wk5OnAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAArqmpUcbCwv7e29v+3dra/t3a2v7d2tr+3dra/t3a2v7d2tr+3Nra/tza
+        2v7c2dn+29nZ/tvY2P7a2Nj+2tfX/tnX1/7Z1tb+2NbW/tjW1v7Z1tb+tbKy/peTk08AAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACxra0GtrGx6eXi4v7Uz8/+1M/P/tTPz/7Uz87+zcjI/svG
+        xv7KxMT+xcDA/r65uf65tLT+t7Ky/ru2tv7GwcH+0s3N/tTPz/7Uz8/+1M/P/uXi4v6fnJznm5iYBQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACrpqaM393d/tHLy/7Pycn+z8nJ/sfC
+        wv7Sy8v+yrCu/r+Oi/63e3j+snVz/q95eP6ujYz+rKOj/qeiov6vqqr+zsjI/s/Jyf7Ry8v+2NbW/pOP
+        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
+        P/6EiT/+nH1I/rhlTPi1V0Gkt1pGJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBak4GvmRIQ7pa
+        PHi7XUGUu11CmLdWO4K6XUVSvGNNEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAPgAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/4AAAP+AAAD/gAAA/8AAAf/AAAH/4A
+        AD/+AAA//gAAf/wAAD/8AAA//AAAH/gAAB/4AAAf+AAAH/gAAB/4AAAf+AAAH/wAAB/8AAA//AAAP/4A
+        AH//AAB//4AB///AA///8A//KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAI2KigGxrKyXtbGxv7Ovr8Cxra3Ar6urwK2pqcCrp6fAqaWlwKajo8CloaHAo6CgwKKf
+        n8Cin5/Aop+fwKKfn8Cinp6+nZqabwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ+cnAzPzMz88Ovr/uPd
+        3f7j3d3+493d/uPd3f7j3d3+493d/uPd3f7j3t7+9O7u/vbw8P728PD+9O7u/vbw8P738vH+tLKyzwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGeng3Py8v83tfX/rexsf63sbH+t7Gx/rexsf63sbH+t7Gx/rex
+        sf64srL+59/f/u7m5v7Ry9j+XFu5/r24z/7w6en+tbOz0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGe
+        ng3Oysr829PT/sG6uf7Burn+wbq5/sG6uf7Burn+wbq5/sG6uf7Burr+4dnY/ufd3f6ZlLf+WFjM/oqG
+        uv7q4uL+tbKy0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCeng3Nycn84NbW/t/V1f7f1dX+39XV/t/V
+        1f7f1dX+39XV/t/V1f7f1dX+39XV/t/V1f7Qxsf+mJKi/si/wP7k3Nz+tbKy0AAAAAAAAAAAAAAAAAAA
+        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
+</value>
+  </data>
+  <data name="$this.MinimumSize" type="System.Drawing.Size, System.Drawing">
+    <value>581, 568</value>
+  </data>
+  <data name="$this.Text" xml:space="preserve">
+    <value>Setup a tile build</value>
+  </data>
+  <data name="&gt;&gt;imageList1.Name" xml:space="preserve">
+    <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>
+  </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>
+  </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>
+  </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>
+  </data>
+</root>
\ No newline at end of file


Property changes on: sandbox/maestro-3.0/MgCooker.Cmd
___________________________________________________________________
Added: svn:ignore
   + bin
obj


Added: sandbox/maestro-3.0/MgCooker.Cmd/MgCooker.Cmd.csproj
===================================================================
--- sandbox/maestro-3.0/MgCooker.Cmd/MgCooker.Cmd.csproj	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker.Cmd/MgCooker.Cmd.csproj	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0FD82B7B-1264-410F-86D1-47E9CCACD68E}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MgCooker.Cmd</RootNamespace>
+    <AssemblyName>MgCookerCmd</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ApplicationIcon>MgCookerLogo.ico</ApplicationIcon>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\out\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\out\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\Properties\GlobalAssemblyInfo.cs">
+      <Link>GlobalAssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\MgCooker\MgCooker.csproj">
+      <Project>{C7DCF771-5982-4859-A17F-01126E6F9BA6}</Project>
+      <Name>MgCooker</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="MgCookerLogo.ico" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: sandbox/maestro-3.0/MgCooker.Cmd/MgCookerLogo.ico
===================================================================
(Binary files differ)


Property changes on: sandbox/maestro-3.0/MgCooker.Cmd/MgCookerLogo.ico
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: sandbox/maestro-3.0/MgCooker.Cmd/Program.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker.Cmd/Program.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker.Cmd/Program.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,37 @@
+#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;
+
+namespace MgCooker.Cmd
+{
+    class Program
+    {
+        [STAThread()]
+        static void Main(string[] args)
+        {
+            //Append the "/commandline" switch
+            List<string> tmp = new List<string>(args);
+            tmp.Add("/commandline");
+            MgCooker.Program.Main(tmp.ToArray());
+        }
+    }
+}

Added: sandbox/maestro-3.0/MgCooker.Cmd/Properties/AssemblyInfo.cs
===================================================================
--- sandbox/maestro-3.0/MgCooker.Cmd/Properties/AssemblyInfo.cs	                        (rev 0)
+++ sandbox/maestro-3.0/MgCooker.Cmd/Properties/AssemblyInfo.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MgCooker.Cmd")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyProduct("MgCooker.Cmd")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("65ba1ff4-e207-4a90-b795-e5ba9c07d173")]
\ No newline at end of file

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ConnectionProviderRegistry.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ConnectionProviderRegistry.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ConnectionProviderRegistry.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -155,6 +155,61 @@
             return conn;
         }
 
+        /// <summary>
+        /// Creates an initialized <see cref="IServerConnection"/> object given the provider name and the initalization parameters
+        /// </summary>
+        /// <param name="provider"></param>
+        /// <param name="connInitParams"></param>
+        /// <returns></returns>
+        public static IServerConnection CreateConnection(string provider, NameValueCollection connInitParams)
+        {
+            string name = provider.ToUpper();
+            if (!_ctors.ContainsKey(name))
+                throw new ArgumentException("Provider not registered: " + provider);
+
+            ConnectionProviderEntry prv = FindProvider(provider);
+            if (prv != null && !prv.IsMultiPlatform && Platform.IsRunningOnMono)
+                throw new NotSupportedException("The specified provider is not usable in your operating system");
+
+            Type t = _ctors[name];
+            BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance;
+            IServerConnection conn = (IServerConnection)t.InvokeMember(null, flags, null, null, new object[] { connInitParams });
+            return conn;
+        }
+
+        /// <summary>
+        /// Creates an initialized <see cref="IServerConnection"/> object given the provider name and the initalization parameters.
+        /// </summary>
+        /// <param name="provider"></param>
+        /// <param name="initParameters">A variable list of initialization parameters. They must be specified in the form: [Param1], [Value1], [Param2], [Value2], etc</param>
+        /// <returns></returns>
+        public static IServerConnection CreateConnection(string provider, params string[] initParameters)
+        {
+            var initP = new NameValueCollection();
+            string name = null;
+            string value = null;
+
+            foreach (var p in initParameters)
+            {
+                if (name == null)
+                {
+                    name = p;
+                }
+                else if (value == null)
+                {
+                    value = p;
+                }
+                else
+                {
+                    initP[name] = value;
+                    name = null;
+                    value = null;
+                }
+            }
+
+            return CreateConnection(provider, initP);
+        }
+
         private static ConnectionProviderEntry FindProvider(string provider)
         {
             foreach (var prv in _providers)

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IServerConnection.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IServerConnection.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IServerConnection.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -30,6 +30,12 @@
     public interface IServerConnection
     {
         /// <summary>
+        /// Returns a clone copy of this connection
+        /// </summary>
+        /// <returns></returns>
+        IServerConnection Clone();
+
+        /// <summary>
         /// Executes the specified load procedure
         /// </summary>
         /// <param name="loadProc"></param>

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/Envelope.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/Envelope.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/Envelope.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -21,6 +21,8 @@
 using System.Collections.Generic;
 using System.Text;
 using System.ComponentModel;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI;
 
 namespace OSGeo.MapGuide.ObjectModels.Common
 {
@@ -37,12 +39,20 @@
 
     public static class EnvelopeExtensions
     {
+        public static IEnvelope Clone(this IEnvelope env)
+        {
+            Check.NotNull(env, "env");
+            return ObjectFactory.CreateEnvelope(env.MinX, env.MinY, env.MaxX, env.MaxY);
+        }
+
         /// <summary>
         /// Expands this envelope to accomodate the given envelope
         /// </summary>
         /// <param name="env"></param>
         public static void ExpandToInclude(this IEnvelope env, IEnvelope e1)
         {
+            Check.NotNull(env, "env");
+
             if (e1.MinX < env.MinX)
                 env.MinX = e1.MinX;
 
@@ -64,6 +74,8 @@
         /// <returns></returns>
         public static bool Contains(this IEnvelope env, double x, double y)
         {
+            Check.NotNull(env, "env");
+
             return env.MinX <= x &&
                    env.MaxX >= x &&
                    env.MinY <= y &&
@@ -77,6 +89,8 @@
         /// <returns></returns>
         public static bool Intersects(this IEnvelope env, IEnvelope other)
         {
+            Check.NotNull(env, "env");
+
             if (other == null)
                 return false;
 

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -480,6 +480,31 @@
             set;
         }
 
+        void IBaseMapDefinition.RemoveScaleAt(int index)
+        {
+            this.FiniteDisplayScale.RemoveAt(index);
+        }
+
+        double IBaseMapDefinition.GetScaleAt(int index)
+        {
+            return this.FiniteDisplayScale[index];
+        }
+
+        int IBaseMapDefinition.GroupCount
+        {
+            get { return this.BaseMapLayerGroup.Count; }
+        }
+
+        IBaseMapGroup IBaseMapDefinition.GetGroupAt(int index)
+        {
+            return this.BaseMapLayerGroup[index];
+        }
+
+        int IBaseMapDefinition.ScaleCount
+        {
+            get { return this.FiniteDisplayScale.Count; }
+        }
+
         IEnumerable<double> IBaseMapDefinition.FiniteDisplayScale
         {
             get 

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinitionInterfaces.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinitionInterfaces.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinitionInterfaces.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -108,6 +108,28 @@
 
     public static class BaseMapDefinitionExtensions
     {
+        public static double GetMinScale(this IBaseMapDefinition map)
+        {
+            Check.NotNull(map, "map");
+            if (map.ScaleCount == 0)
+                return 0.0;
+
+            var scales = new List<double>(map.FiniteDisplayScale);
+            scales.Sort();
+            return scales[0];
+        }
+
+        public static double GetMaxScale(this IBaseMapDefinition map)
+        {
+            Check.NotNull(map, "map");
+            if (map.ScaleCount == 0)
+                return 0.0;
+
+            var scales = new List<double>(map.FiniteDisplayScale);
+            scales.Sort();
+            return scales[scales.Count - 1];
+        }
+
         public static bool HasLayers(this IBaseMapGroup grp)
         {
             Check.NotNull(grp, "grp");
@@ -268,8 +290,18 @@
 
         void RemoveFiniteDisplayScale(double value);
 
+        int ScaleCount { get; }
+
+        void RemoveScaleAt(int index);
+
+        double GetScaleAt(int index);
+
         IEnumerable<IBaseMapGroup> BaseMapLayerGroup { get; }
 
+        int GroupCount { get; }
+
+        IBaseMapGroup GetGroupAt(int index);
+
         IBaseMapGroup AddBaseLayerGroup(string name);
 
         void RemoveBaseLayerGroup(IBaseMapGroup group);

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ServerConnectionBase.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -1649,5 +1649,7 @@
         public abstract string[] GetSchemas(string resourceId);
 
         public abstract string[] GetClassNames(string resourceId, string schemaName);
+
+        public abstract IServerConnection Clone();
     }
 }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2010-10-22 07:02:27 UTC (rev 5320)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2010-10-22 11:08:30 UTC (rev 5321)
@@ -1894,5 +1894,13 @@
                 return sc.Item.ToArray();
             }
         }
+
+        public override IServerConnection Clone()
+        {
+            if (this.IsAnonymous)
+                return new HttpServerConnection(new Uri(this.ServerURI), "Anonymous", "", null, true);
+            else
+                return new HttpServerConnection(new Uri(this.ServerURI), this.SessionID, null, true);
+        }
     }
 }



More information about the mapguide-commits mailing list