[mapguide-commits] r5319 - in sandbox/maestro-3.0: ExtendedModels/LayerDefinition-1.1.0 ExtendedModels/LayerDefinition-1.2.0 ExtendedModels/LayerDefinition-1.3.0 ExtendedModels/LoadProcedure-1.1.0 ExtendedModels/LoadProcedure-2.2.0 ExtendedModels/WebLayout-1.1.0 Maestro Maestro.AddIn.ExtendedObjectModels/Commands Maestro.Base Maestro.Base/Commands Maestro.Base/Commands/SiteExplorer Maestro.Base/Editor Maestro.Base/Properties Maestro.Base/Services Maestro.Base/UI Maestro.Editors Maestro.Editors/Common Maestro.Editors/Migration MaestroAPITests OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/CrossConnection OSGeo.MapGuide.MaestroAPI/Properties OSGeo.MapGuide.MaestroAPI/Resource OSGeo.MapGuide.MaestroAPI/Resource/Validation

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Oct 22 03:01:32 EDT 2010


Author: jng
Date: 2010-10-22 00:01:32 -0700 (Fri, 22 Oct 2010)
New Revision: 5319

Added:
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/MigrateSelectedResourcesCommand.cs
   sandbox/maestro-3.0/Maestro.Editors/Migration/
   sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.Designer.cs
   sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.cs
   sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.resx
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/CrossConnection/
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/CrossConnection/ResourceMigrator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLoadProcedureValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseWebLayoutValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/DrawingSourceValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LayerDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LoadProcedureValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/MapDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/PrintLayoutValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorLoader.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolLibraryValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/WebLayoutValidator.cs
Removed:
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLoadProcedureValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseWebLayoutValidator.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ResourceValidatorSet.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs
Modified:
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinitionValidator.cs
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinitionValidator.cs
   sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinitionValidator.cs
   sandbox/maestro-3.0/ExtendedModels/LoadProcedure-1.1.0/LoadProcedureValidator.cs
   sandbox/maestro-3.0/ExtendedModels/LoadProcedure-2.2.0/LoadProcedureValidator.cs
   sandbox/maestro-3.0/ExtendedModels/WebLayout-1.1.0/WebLayoutValidator.cs
   sandbox/maestro-3.0/Maestro.AddIn.ExtendedObjectModels/Commands/StartupCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DisconnectCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/ValidateCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/ValidateResourceCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs
   sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.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/Services/OpenResourceManager.cs
   sandbox/maestro-3.0/Maestro.Base/TabFactory.cs
   sandbox/maestro-3.0/Maestro.Base/UI/NewResourceDialog.cs
   sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.Designer.cs
   sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs
   sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.resx
   sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj
   sandbox/maestro-3.0/Maestro/Maestro.csproj
   sandbox/maestro-3.0/Maestro/Maestro.sln
   sandbox/maestro-3.0/Maestro/Program.cs
   sandbox/maestro-3.0/MaestroAPITests/MaestroAPITests.csproj
   sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
Log:
3.0 sandbox changes:
 - Fix #1490: Remember last selected category in New Resource Dialog
 - Fix #1489: Add drawing layer validation rules
 - Fix #1488: Prevent dangling editors as a result of deleting the underlying resource or disconnecting
 - Fix #1487: Support drag/drop in data files section of Generic XML editor
 - Fix #1482: Move disconnect button to main toolbar and include a label for it.
 - #1112: Add new *experimental* resource migration option in context menu for selected resources.
 - Remove the Maestro.ResourceValidation library and move existing validators into the MaestroAPI project
 - Fix incorrect resource (not document) validation when using Generic XML editor


Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinitionValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.1.0/LayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -23,6 +23,7 @@
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using OSGeo.MapGuide.ObjectModels.FeatureSource;
 using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition_1_1_0
 {

Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinitionValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.2.0/LayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -23,6 +23,7 @@
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using OSGeo.MapGuide.ObjectModels.FeatureSource;
 using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition_1_2_0
 {

Modified: sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinitionValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/LayerDefinition-1.3.0/LayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -23,6 +23,7 @@
 using OSGeo.MapGuide.MaestroAPI.Resource;
 using OSGeo.MapGuide.ObjectModels.FeatureSource;
 using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.LayerDefinition_1_3_0
 {

Modified: sandbox/maestro-3.0/ExtendedModels/LoadProcedure-1.1.0/LoadProcedureValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LoadProcedure-1.1.0/LoadProcedureValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/LoadProcedure-1.1.0/LoadProcedureValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -21,6 +21,7 @@
 using System.Collections.Generic;
 using System.Text;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.LoadProcedure_1_1_0
 {

Modified: sandbox/maestro-3.0/ExtendedModels/LoadProcedure-2.2.0/LoadProcedureValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/LoadProcedure-2.2.0/LoadProcedureValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/LoadProcedure-2.2.0/LoadProcedureValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -21,6 +21,7 @@
 using System.Collections.Generic;
 using System.Text;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.LoadProcedure_2_2_0
 {

Modified: sandbox/maestro-3.0/ExtendedModels/WebLayout-1.1.0/WebLayoutValidator.cs
===================================================================
--- sandbox/maestro-3.0/ExtendedModels/WebLayout-1.1.0/WebLayoutValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/ExtendedModels/WebLayout-1.1.0/WebLayoutValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -21,6 +21,7 @@
 using System.Collections.Generic;
 using System.Text;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace OSGeo.MapGuide.ObjectModels.WebLayout_1_1_0
 {

Modified: sandbox/maestro-3.0/Maestro/Maestro.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro/Maestro.csproj	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro/Maestro.csproj	2010-10-22 07:01:32 UTC (rev 5319)
@@ -727,10 +727,6 @@
       <Project>{F1E2F468-5030-4DBA-968C-9620284AFAA1}</Project>
       <Name>Maestro.Base</Name>
     </ProjectReference>
-    <ProjectReference Include="..\Maestro.ResourceValidation\Maestro.ResourceValidation.csproj">
-      <Project>{3B29C138-666C-46D0-A55D-824E5192C091}</Project>
-      <Name>Maestro.ResourceValidation</Name>
-    </ProjectReference>
     <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI.Http\OSGeo.MapGuide.MaestroAPI.Http.csproj">
       <Project>{6EF1E775-444B-4E5F-87FB-D687C43A68D7}</Project>
       <Name>OSGeo.MapGuide.MaestroAPI.Http</Name>

Modified: sandbox/maestro-3.0/Maestro/Maestro.sln
===================================================================
--- sandbox/maestro-3.0/Maestro/Maestro.sln	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro/Maestro.sln	2010-10-22 07:01:32 UTC (rev 5319)
@@ -28,8 +28,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaestroBaseTests", "..\MaestroBaseTests\MaestroBaseTests.csproj", "{CE5F281C-0162-4832-87BB-A677D13D116F}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maestro.ResourceValidation", "..\Maestro.ResourceValidation\Maestro.ResourceValidation.csproj", "{3B29C138-666C-46D0-A55D-824E5192C091}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSGeo.MapGuide.ObjectModels.LayerDefinition-1.1.0", "..\ExtendedModels\LayerDefinition-1.1.0\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.1.0.csproj", "{B5EA049C-6AB7-4686-A2F4-4BA2EAC0E585}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSGeo.MapGuide.ObjectModels.LayerDefinition-1.2.0", "..\ExtendedModels\LayerDefinition-1.2.0\OSGeo.MapGuide.ObjectModels.LayerDefinition-1.2.0.csproj", "{EDDB0F74-6FE7-4969-80B0-817A629722CD}"
@@ -109,10 +107,6 @@
 		{CE5F281C-0162-4832-87BB-A677D13D116F}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CE5F281C-0162-4832-87BB-A677D13D116F}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CE5F281C-0162-4832-87BB-A677D13D116F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{3B29C138-666C-46D0-A55D-824E5192C091}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{3B29C138-666C-46D0-A55D-824E5192C091}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{3B29C138-666C-46D0-A55D-824E5192C091}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{3B29C138-666C-46D0-A55D-824E5192C091}.Release|Any CPU.Build.0 = Release|Any CPU
 		{B5EA049C-6AB7-4686-A2F4-4BA2EAC0E585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{B5EA049C-6AB7-4686-A2F4-4BA2EAC0E585}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{B5EA049C-6AB7-4686-A2F4-4BA2EAC0E585}.Release|Any CPU.ActiveCfg = Release|Any CPU

Modified: sandbox/maestro-3.0/Maestro/Program.cs
===================================================================
--- sandbox/maestro-3.0/Maestro/Program.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro/Program.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -28,7 +28,7 @@
 using Maestro.Base.UI;
 using OSGeo.MapGuide.MaestroAPI;
 using ICSharpCode.Core.WinForms;
-using Maestro.ResourceValidation;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro
 {

Modified: sandbox/maestro-3.0/Maestro.AddIn.ExtendedObjectModels/Commands/StartupCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.AddIn.ExtendedObjectModels/Commands/StartupCommand.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.AddIn.ExtendedObjectModels/Commands/StartupCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -34,6 +34,7 @@
 using Lp220 = OSGeo.MapGuide.ObjectModels.LoadProcedure_2_2_0;
 using WL110 = OSGeo.MapGuide.ObjectModels.WebLayout_1_1_0;
 using OSGeo.MapGuide.ObjectModels.LoadProcedure;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro.AddIn.ExtendedObjectModels.Commands
 {

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DeleteSelectedItemsCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -25,6 +25,7 @@
 using Maestro.Shared.UI;
 using Maestro.Base.UI;
 using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
 
 namespace Maestro.Base.Commands.SiteExplorer
 {
@@ -34,6 +35,7 @@
         {
             var wb = Workbench.Instance;
             var svc = ServiceRegistry.GetService<ServerConnectionManager>();
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
             var exp = wb.ActiveSiteExplorer;
             if (exp != null)
             {
@@ -44,7 +46,15 @@
                 {
                     if (MessageService.AskQuestion(Properties.Resources.ConfirmDelete))
                     {
-                        DoDelete(wb, resSvc, items);
+                        if (ConfirmDeleteOpenResources(items, omgr.OpenEditors))
+                        {
+                            //Close any open editors on these resources before deleting them
+                            foreach (var i in items)
+                            {
+                                omgr.CloseEditors(i.ResourceId, true);
+                            }
+                            DoDelete(wb, resSvc, items);
+                        }
                     }
 
                     //Refresh the parent. Multi-select is only allowed from same parent
@@ -58,6 +68,31 @@
             }
         }
 
+        private static bool ConfirmDeleteOpenResources(RepositoryItem[] items, Maestro.Base.Editor.IEditorViewContent[] editors)
+        {
+            Check.NotNull(items, "items");
+            Check.NotNull(editors, "editors");
+            Dictionary<string, string> resIds = new Dictionary<string, string>();
+            foreach (var item in items)
+            {
+                resIds.Add(item.ResourceId, item.ResourceId);
+            }
+            bool isDeletingOpenResource = false;
+            foreach (var ed in editors)
+            {
+                if (resIds.ContainsKey(ed.EditorService.ResourceID))
+                {
+                    isDeletingOpenResource = true;
+                    break;
+                }
+            }
+
+            if (isDeletingOpenResource && !MessageService.AskQuestion(Properties.Resources.ConfirmDeleteOpenResource))
+                return false;
+
+            return true;
+        }
+
         private void DoDelete(Workbench wb, OSGeo.MapGuide.MaestroAPI.Services.IResourceService resSvc, RepositoryItem[] items)
         {
             var pdlg = new ProgressDialog();

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DisconnectCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DisconnectCommand.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/DisconnectCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -31,8 +31,32 @@
         {
             var wb = Workbench.Instance;
             var svc = ServiceRegistry.GetService<ServerConnectionManager>();
+            var omgr = ServiceRegistry.GetService<OpenResourceManager>();
             if (wb.ActiveSiteExplorer != null)
             {
+                var openEditors = omgr.OpenEditors;
+                if (openEditors.Length > 0)
+                {
+                    bool dirty = false;
+                    foreach (var ed in openEditors)
+                    {
+                        if (ed.IsDirty)
+                        {
+                            dirty = true;
+                            break;
+                        }
+                    }
+
+                    if (dirty && !MessageService.AskQuestion(Properties.Resources.ConfirmCloseEditors))
+                        return;
+                }
+
+                var editors = omgr.OpenEditors;
+                foreach (var ed in openEditors)
+                {
+                    ed.Close(true);
+                }
+
                 var name = wb.ActiveSiteExplorer.ConnectionName;
                 svc.RemoveConnection(name);
             }

Added: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/MigrateSelectedResourcesCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/MigrateSelectedResourcesCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/MigrateSelectedResourcesCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,109 @@
+#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.Services;
+using Maestro.Login;
+using Maestro.Editors.Migration;
+using OSGeo.MapGuide.MaestroAPI.CrossConnection;
+using Maestro.Shared.UI;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace Maestro.Base.Commands.SiteExplorer
+{
+    internal class MigrateSelectedResourcesCommand : AbstractCommand
+    {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var svc = ServiceRegistry.GetService<ServerConnectionManager>();
+            var exp = wb.ActiveSiteExplorer;
+            if (exp.SelectedItems.Length > 0)
+            {
+                var source = svc.GetConnection(exp.ConnectionName);
+                var login = new LoginDialog();
+                if (login.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+                {
+                    var target = login.Connection;
+                    var migrate = new ResourceMigrationDialog(source, target);
+
+                    var srcIds = new List<string>();
+                    foreach (var item in exp.SelectedItems)
+                    {
+                        srcIds.Add(item.ResourceId);
+                    }
+
+                    migrate.SourceResourceIds = srcIds.ToArray();
+
+                    if (migrate.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+                    {
+                        int affected = DoMigrate(source, target, migrate);
+                        MessageService.ShowMessage(string.Format(Properties.Resources.ItemsMigrated, affected));
+                        if (affected > 0 && migrate.SelectedAction == MigrationAction.Move)
+                        {
+                            var parent = exp.SelectedItems[0].Parent;
+                            if (parent != null)
+                                exp.RefreshModel(parent.ResourceId);
+                            else
+                                exp.RefreshModel("Library://");
+                        }
+                    }
+                }
+            }
+        }
+
+        private static int DoMigrate(OSGeo.MapGuide.MaestroAPI.IServerConnection source, OSGeo.MapGuide.MaestroAPI.IServerConnection target, ResourceMigrationDialog migrate)
+        {
+            var diag = new ProgressDialog();
+            diag.CancelAbortsThread = true;
+            var method = new ProgressDialog.DoBackgroundWork((worker, e, args) =>
+            {
+                var src = (IServerConnection)args[0];
+                var dst = (IServerConnection)args[1];
+                var ids = (string[])args[2];
+                var folder = (string)args[3];
+                var overwrite = (bool)args[4];
+                var act = (MigrationAction)args[5];
+
+                var cb = new LengthyOperationProgressCallBack((sender, cbe) =>
+                {
+                    worker.ReportProgress(cbe.Progress, cbe.StatusMessage);
+                });
+
+                var migrator = new ResourceMigrator(source, target);
+                int affected = 0;
+                switch (act)
+                {
+                    case MigrationAction.Copy:
+                        affected = migrator.CopyResources(ids, folder, overwrite, cb);
+                        break;
+                    case MigrationAction.Move:
+                        affected = migrator.MoveResources(ids, folder, overwrite, cb);
+                        break;
+                }
+                return affected;
+            });
+
+            return (int)diag.RunOperationAsync(Workbench.Instance, method, source, target, migrate.SourceResourceIds, migrate.TargetFolder, migrate.OverwriteResources, migrate.SelectedAction);
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/ValidateCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/ValidateCommand.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/SiteExplorer/ValidateCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -28,6 +28,7 @@
 using OSGeo.MapGuide.MaestroAPI;
 using OSGeo.MapGuide.MaestroAPI.Exceptions;
 using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro.Base.Commands.SiteExplorer
 {

Modified: sandbox/maestro-3.0/Maestro.Base/Commands/ValidateResourceCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/ValidateResourceCommand.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/ValidateResourceCommand.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -28,6 +28,7 @@
 using Maestro.Shared.UI;
 using OSGeo.MapGuide.MaestroAPI;
 using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro.Base.Commands
 {

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/EditorContentBase.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -28,6 +28,7 @@
 using OSGeo.MapGuide.MaestroAPI;
 using Maestro.Editors;
 using ICSharpCode.Core;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro.Base.Editor
 {
@@ -247,9 +248,21 @@
             return new ResourcePreviewEngine(mapguideRootUrl, this.EditorService).GeneratePreviewUrl(previewCopy);
         }
 
-        public void SyncSessionCopy()
+        public virtual void SyncSessionCopy()
         {
             this.EditorService.SyncSessionCopy();
         }
+
+        public bool DiscardChangesOnClose
+        {
+            get;
+            private set;
+        }
+
+        public virtual void Close(bool discardChanges)
+        {
+            this.DiscardChangesOnClose = discardChanges;
+            base.Close();
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/IEditorViewContent.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -39,6 +39,18 @@
         IResource Resource { get; }
 
         /// <summary>
+        /// Gets whether to discard unsaved changes when <see cref="Close"/> is called. If true,
+        /// the normal user prompt to save unsaved changes is suppressed.
+        /// </summary>
+        bool DiscardChangesOnClose { get; }
+
+        /// <summary>
+        /// Closes this view
+        /// </summary>
+        /// <param name="discardChanges">indicates whether to discard any unsaved changes.</param>
+        void Close(bool discardChanges);
+
+        /// <summary>
         /// Gets the XML content of the edited resource
         /// </summary>
         /// <returns></returns>

Modified: sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Editor/XmlEditor.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -32,6 +32,7 @@
 using System.Xml;
 using Maestro.Editors;
 using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace Maestro.Base.Editor
 {
@@ -136,5 +137,12 @@
                 return false; //We're already in the XML editor!
             }
         }
+
+        public override void SyncSessionCopy()
+        {
+            //Write our XML changes back into the edited resource copy and re-read
+            _edSvc.ResourceService.SetResourceXmlData(_edSvc.EditedResourceID, new MemoryStream(Encoding.UTF8.GetBytes(this.XmlContent)));
+            //base.SyncSessionCopy();
+        }
     }
 }

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-10-22 07:01:32 UTC (rev 5319)
@@ -208,6 +208,11 @@
                          label="${res:Menu_File_NewResource}"
                          tooltip="${res:Menu_File_NewResource}"
                          class="Maestro.Base.Commands.NewItemCommand" />
+            <ToolbarItem id="Disconnect"
+                         icon="plug--minus"
+                         label="${res:SiteExplorer_Disconnect}"
+                         tooltip="${res:SiteExplorer_Disconnect}"
+                         class="Maestro.Base.Commands.SiteExplorer.DisconnectCommand" />
             <ToolbarItem type="Separator" />
             <Condition action="Disable" name="CanCutOrCopy">
                 <ToolbarItem id="CopyItem"
@@ -296,9 +301,6 @@
             <ToolbarItem id="SiteExplorer_Refresh"
                          icon="arrow-circle-045-left"
                          class="Maestro.Base.Commands.SiteExplorer.RefreshCommand" />
-            <ToolbarItem id="SiteExplorer_Disconnect"
-                         icon="plug--minus"
-                         class="Maestro.Base.Commands.SiteExplorer.DisconnectCommand" />
         </Condition>
     </Path>
     
@@ -410,6 +412,10 @@
                           class="Maestro.Base.Commands.CutCommand" />
             </Condition>
             <MenuItem type="Separator" />
+            <MenuItem id="Migrate"
+                      label="${res:SiteExplorer_MigrateResources}"
+                      class="Maestro.Base.Commands.SiteExplorer.MigrateSelectedResourcesCommand" />
+            <MenuItem type="Separator" />
             <MenuItem id="Validate"
                       icon="tick"
                       label="${res:SiteExplorer_ValidateResources}"
@@ -442,6 +448,11 @@
                           label="${res:SiteExplorer_SelectedItem_Cut}"
                           class="Maestro.Base.Commands.CutCommand" />
             </Condition>
+            <MenuItem type="Separator" />
+            <MenuItem id="Migrate"
+                      label="${res:SiteExplorer_MigrateResources}"
+                      class="Maestro.Base.Commands.SiteExplorer.MigrateSelectedResourcesCommand" />
+            <MenuItem type="Separator" />
             <MenuItem id="Validate"
                       icon="tick"
                       label="${res:SiteExplorer_ValidateResources}"

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-10-22 07:01:32 UTC (rev 5319)
@@ -72,6 +72,7 @@
     <Compile Include="Commands\SaveResourceCommand.cs" />
     <Compile Include="Commands\SiteExplorer\DeleteSelectedItemsCommand.cs" />
     <Compile Include="Commands\SiteExplorer\DisconnectCommand.cs" />
+    <Compile Include="Commands\SiteExplorer\MigrateSelectedResourcesCommand.cs" />
     <Compile Include="Commands\SiteExplorer\NewFolderCommand.cs" />
     <Compile Include="Commands\SiteExplorer\OpenResourceCommand.cs" />
     <Compile Include="Commands\SiteExplorer\OpenWithXmlEditorCommand.cs" />

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.Designer.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -283,6 +283,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to You have open editors with unsaved changes. Continue anyway?.
+        /// </summary>
+        internal static string ConfirmCloseEditors {
+            get {
+                return ResourceManager.GetString("ConfirmCloseEditors", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Are you sure you want to delete?.
         /// </summary>
         internal static string ConfirmDelete {
@@ -292,6 +301,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to You are about to delete one or more resources which are currently open in an editor. Close these editors and proceed with delete?.
+        /// </summary>
+        internal static string ConfirmDeleteOpenResource {
+            get {
+                return ResourceManager.GetString("ConfirmDeleteOpenResource", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Are you sure you want to move the following resources?.
         /// </summary>
         internal static string ConfirmMove {
@@ -583,6 +601,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to {0} items migrated.
+        /// </summary>
+        internal static string ItemsMigrated {
+            get {
+                return ResourceManager.GetString("ItemsMigrated", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap layer {
             get {
                 object obj = ResourceManager.GetObject("layer", resourceCulture);
@@ -1206,6 +1233,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Migrate Selected Resources.
+        /// </summary>
+        internal static string SiteExplorer_MigrateResources {
+            get {
+                return ResourceManager.GetString("SiteExplorer_MigrateResources", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to New Folder.
         /// </summary>
         internal static string SiteExplorer_NewFolder {
@@ -1322,6 +1358,24 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Close this tab.
+        /// </summary>
+        internal static string TabClose {
+            get {
+                return ResourceManager.GetString("TabClose", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Close all tabs except this.
+        /// </summary>
+        internal static string TabCloseExceptThis {
+            get {
+                return ResourceManager.GetString("TabCloseExceptThis", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap tick {
             get {
                 object obj = ResourceManager.GetObject("tick", resourceCulture);

Modified: sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Properties/Resources.resx	2010-10-22 07:01:32 UTC (rev 5319)
@@ -727,4 +727,22 @@
   <data name="LayerSubTypeNotSupported" xml:space="preserve">
     <value>Could not determine the sub-layer type or this type is not currently supported</value>
   </data>
+  <data name="ConfirmCloseEditors" xml:space="preserve">
+    <value>You have open editors with unsaved changes. Continue anyway?</value>
+  </data>
+  <data name="ConfirmDeleteOpenResource" xml:space="preserve">
+    <value>You are about to delete one or more resources which are currently open in an editor. Close these editors and proceed with delete?</value>
+  </data>
+  <data name="TabClose" xml:space="preserve">
+    <value>Close this tab</value>
+  </data>
+  <data name="TabCloseExceptThis" xml:space="preserve">
+    <value>Close all tabs except this</value>
+  </data>
+  <data name="ItemsMigrated" xml:space="preserve">
+    <value>{0} items migrated</value>
+  </data>
+  <data name="SiteExplorer_MigrateResources" xml:space="preserve">
+    <value>Migrate Selected Resources</value>
+  </data>
 </root>
\ No newline at end of file

Modified: sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/Services/OpenResourceManager.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -34,6 +34,32 @@
 
         private Dictionary<ResourceTypeDescriptor, IEditorFactory> _factories;
 
+        public IEditorViewContent[] OpenEditors
+        {
+            get { return new List<IEditorViewContent>(_openItems.Values).ToArray(); }
+        }
+
+        public void CloseEditors(string resourceId, bool discardChanges)
+        {
+            if (_openItems.ContainsKey(resourceId))
+            {
+                var ed = _openItems[resourceId];
+                ed.Close(discardChanges);
+            }
+        }
+
+        public void CloseEditorsExceptFor(string resourceId, bool discardChanges)
+        {
+            var eds = new List<IEditorViewContent>(_openItems.Values);
+            if (_openItems.ContainsKey(resourceId))
+                eds.Remove(_openItems[resourceId]);
+
+            foreach (var ed in eds)
+            {
+                ed.Close(discardChanges);
+            }
+        }
+
         public override void Initialize()
         {
             base.Initialize();
@@ -101,7 +127,7 @@
                 _openItems[resourceId] = ed;
                 ed.ViewContentClosing += (sender, e) =>
                 {
-                    if (ed.IsDirty)
+                    if (ed.IsDirty && !ed.DiscardChangesOnClose)
                     {
                         if (!MessageService.AskQuestion(Properties.Resources.CloseUnsavedResource))
                         {

Modified: sandbox/maestro-3.0/Maestro.Base/TabFactory.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/TabFactory.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/TabFactory.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -51,6 +51,7 @@
             page.Text = content.Title; 
             page.ToolTipText = content.Description;
             page.Tag = content;
+
             content.TitleChanged += (sender, e) => 
             {
                 page.Text = content.Title; 

Modified: sandbox/maestro-3.0/Maestro.Base/UI/NewResourceDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/NewResourceDialog.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Base/UI/NewResourceDialog.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -33,6 +33,8 @@
 {
     public partial class NewResourceDialog : Form
     {
+        private static string _lastSelectedCategory;
+
         private NewResourceDialog()
         {
             InitializeComponent();
@@ -55,6 +57,13 @@
         protected override void OnLoad(EventArgs e)
         {
             lstCategories.DataSource = _nits.GetCategories();
+
+            if (!string.IsNullOrEmpty(_lastSelectedCategory))
+            {
+                var idx = lstCategories.Items.IndexOf(_lastSelectedCategory);
+                if (idx >= 0)
+                    lstCategories.SelectedIndex = idx;
+            }
         }
 
         private void btnCancel_Click(object sender, EventArgs e)
@@ -136,6 +145,7 @@
 
         private void btnOK_Click(object sender, EventArgs e)
         {
+            RememberSelectedCategory();
             this.DialogResult = DialogResult.OK;
         }
 
@@ -154,6 +164,11 @@
             }
         }
 
+        private void RememberSelectedCategory()
+        {
+            _lastSelectedCategory = lstCategories.SelectedItem.ToString();
+        }
+
         private void lstTemplates_MouseDoubleClick(object sender, MouseEventArgs e)
         {
             var item = lstTemplates.GetItemAt(e.X, e.Y);
@@ -162,6 +177,7 @@
                 lstTemplates.SelectedItems.Clear();
                 item.Selected = true;
 
+                RememberSelectedCategory();
                 this.DialogResult = DialogResult.OK;
             }
         }

Modified: sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.Designer.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.Designer.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -92,6 +92,7 @@
             // 
             // lstDataFiles
             // 
+            this.lstDataFiles.AllowDrop = true;
             this.lstDataFiles.Dock = System.Windows.Forms.DockStyle.Fill;
             this.lstDataFiles.Location = new System.Drawing.Point(0, 25);
             this.lstDataFiles.MultiSelect = false;
@@ -103,6 +104,8 @@
             this.lstDataFiles.UseCompatibleStateImageBehavior = false;
             this.lstDataFiles.View = System.Windows.Forms.View.List;
             this.lstDataFiles.SelectedIndexChanged += new System.EventHandler(this.lstDataFiles_SelectedIndexChanged);
+            this.lstDataFiles.DragDrop += new System.Windows.Forms.DragEventHandler(this.lstDataFiles_DragDrop);
+            this.lstDataFiles.DragEnter += new System.Windows.Forms.DragEventHandler(this.lstDataFiles_DragEnter);
             // 
             // imgIcons
             // 

Modified: sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -275,6 +275,50 @@
             if (handler != null)
                 handler(this, name);
         }
+
+        private void lstDataFiles_DragEnter(object sender, DragEventArgs e)
+        {
+            if (e.Data.GetDataPresent(DataFormats.FileDrop))
+            {
+                Array a = e.Data.GetData(DataFormats.FileDrop) as Array;
+                if (a != null && a.Length > 0)
+                {
+                    e.Effect = DragDropEffects.Copy;
+                }
+                else
+                    e.Effect = DragDropEffects.None;
+            }
+            else
+                e.Effect = DragDropEffects.None;
+        }
+
+        private void lstDataFiles_DragDrop(object sender, DragEventArgs e)
+        {
+            Array a = e.Data.GetData(DataFormats.FileDrop) as Array;
+            bool refresh = false;
+            if (a != null && a.Length > 0)
+            {
+                for (int i = 0; i < a.Length; i++)
+                {
+                    string file = a.GetValue(i).ToString();
+                    try
+                    {
+                        using (var fs = new FileStream(file, FileMode.Open))
+                        {
+                            IResource res = _edSvc.GetEditedResource();
+                            res.SetResourceData(Path.GetFileName(file), ResourceDataType.File, fs);
+                            refresh = true;
+                        }
+                    }
+                    catch { }
+                }
+            }
+            if (refresh)
+            {
+                LoadResourceData();
+                OnDataListChanged();
+            }
+        }
     }
 
     public delegate void ResourceDataSelectionEventHandler(object sender, string dataName);

Modified: sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.resx	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Editors/Common/ResourceDataCtrl.resx	2010-10-22 07:01:32 UTC (rev 5319)
@@ -128,7 +128,7 @@
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAK
-        CAAAAk1TRnQBSQFMAwEBAAEgAQABIAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA
+        CAAAAk1TRnQBSQFMAwEBAAEoAQABKAEAARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMA
         AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA
         AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA
         AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm

Modified: sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj	2010-10-22 07:01:32 UTC (rev 5319)
@@ -480,6 +480,12 @@
     </Compile>
     <Compile Include="MapDefinition\MapTreeModels.cs" />
     <Compile Include="MapDefinition\ScaleListGenerator.cs" />
+    <Compile Include="Migration\ResourceMigrationDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Migration\ResourceMigrationDialog.Designer.cs">
+      <DependentUpon>ResourceMigrationDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="PrintLayout\LogoDialog.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -847,6 +853,9 @@
       <DependentUpon>MapSettingsSectionCtrl.cs</DependentUpon>
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Migration\ResourceMigrationDialog.resx">
+      <DependentUpon>ResourceMigrationDialog.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="PrintLayout\LogoDialog.resx">
       <DependentUpon>LogoDialog.cs</DependentUpon>
     </EmbeddedResource>

Added: sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.Designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.Designer.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,263 @@
+namespace Maestro.Editors.Migration
+{
+    partial class ResourceMigrationDialog
+    {
+        /// <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.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.lstResources = new System.Windows.Forms.ListBox();
+            this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+            this.btnAddResource = new System.Windows.Forms.ToolStripButton();
+            this.btnAddFolder = new System.Windows.Forms.ToolStripButton();
+            this.btnRemove = new System.Windows.Forms.ToolStripButton();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.btnBrowseTarget = new System.Windows.Forms.Button();
+            this.txtTargetFolder = new System.Windows.Forms.TextBox();
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.chkOverwrite = new System.Windows.Forms.CheckBox();
+            this.cmbAction = new System.Windows.Forms.ComboBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.groupBox1.SuspendLayout();
+            this.toolStrip1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            this.groupBox3.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Controls.Add(this.lstResources);
+            this.groupBox1.Controls.Add(this.toolStrip1);
+            this.groupBox1.Location = new System.Drawing.Point(13, 13);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(521, 154);
+            this.groupBox1.TabIndex = 0;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Source";
+            // 
+            // lstResources
+            // 
+            this.lstResources.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.lstResources.FormattingEnabled = true;
+            this.lstResources.Location = new System.Drawing.Point(3, 41);
+            this.lstResources.Name = "lstResources";
+            this.lstResources.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple;
+            this.lstResources.Size = new System.Drawing.Size(515, 108);
+            this.lstResources.TabIndex = 1;
+            this.lstResources.SelectedIndexChanged += new System.EventHandler(this.lstResources_SelectedIndexChanged);
+            // 
+            // toolStrip1
+            // 
+            this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.btnAddResource,
+            this.btnAddFolder,
+            this.btnRemove});
+            this.toolStrip1.Location = new System.Drawing.Point(3, 16);
+            this.toolStrip1.Name = "toolStrip1";
+            this.toolStrip1.Size = new System.Drawing.Size(515, 25);
+            this.toolStrip1.TabIndex = 0;
+            this.toolStrip1.Text = "toolStrip1";
+            // 
+            // btnAddResource
+            // 
+            this.btnAddResource.Image = global::Maestro.Editors.Properties.Resources.document__plus;
+            this.btnAddResource.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.btnAddResource.Name = "btnAddResource";
+            this.btnAddResource.Size = new System.Drawing.Size(100, 22);
+            this.btnAddResource.Text = "Add Resource";
+            this.btnAddResource.Click += new System.EventHandler(this.btnAddResource_Click);
+            // 
+            // btnAddFolder
+            // 
+            this.btnAddFolder.Image = global::Maestro.Editors.Properties.Resources.folder__plus;
+            this.btnAddFolder.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.btnAddFolder.Name = "btnAddFolder";
+            this.btnAddFolder.Size = new System.Drawing.Size(85, 22);
+            this.btnAddFolder.Text = "Add Folder";
+            this.btnAddFolder.Click += new System.EventHandler(this.btnAddFolder_Click);
+            // 
+            // btnRemove
+            // 
+            this.btnRemove.Enabled = false;
+            this.btnRemove.Image = global::Maestro.Editors.Properties.Resources.cross_script;
+            this.btnRemove.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.btnRemove.Name = "btnRemove";
+            this.btnRemove.Size = new System.Drawing.Size(70, 22);
+            this.btnRemove.Text = "Remove";
+            this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Controls.Add(this.btnBrowseTarget);
+            this.groupBox2.Controls.Add(this.txtTargetFolder);
+            this.groupBox2.Controls.Add(this.label1);
+            this.groupBox2.Location = new System.Drawing.Point(13, 173);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(521, 61);
+            this.groupBox2.TabIndex = 1;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Target";
+            // 
+            // btnBrowseTarget
+            // 
+            this.btnBrowseTarget.Location = new System.Drawing.Point(478, 24);
+            this.btnBrowseTarget.Name = "btnBrowseTarget";
+            this.btnBrowseTarget.Size = new System.Drawing.Size(27, 23);
+            this.btnBrowseTarget.TabIndex = 2;
+            this.btnBrowseTarget.Text = "...";
+            this.btnBrowseTarget.UseVisualStyleBackColor = true;
+            this.btnBrowseTarget.Click += new System.EventHandler(this.btnBrowseTarget_Click);
+            // 
+            // txtTargetFolder
+            // 
+            this.txtTargetFolder.Location = new System.Drawing.Point(78, 26);
+            this.txtTargetFolder.Name = "txtTargetFolder";
+            this.txtTargetFolder.ReadOnly = true;
+            this.txtTargetFolder.Size = new System.Drawing.Size(394, 20);
+            this.txtTargetFolder.TabIndex = 1;
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(26, 29);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(36, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Folder";
+            // 
+            // btnOK
+            // 
+            this.btnOK.Enabled = false;
+            this.btnOK.Location = new System.Drawing.Point(378, 352);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 2;
+            this.btnOK.Text = "OK";
+            this.btnOK.UseVisualStyleBackColor = true;
+            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+            // 
+            // btnCancel
+            // 
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(459, 352);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 3;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Controls.Add(this.chkOverwrite);
+            this.groupBox3.Controls.Add(this.cmbAction);
+            this.groupBox3.Controls.Add(this.label2);
+            this.groupBox3.Location = new System.Drawing.Point(13, 240);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(521, 106);
+            this.groupBox3.TabIndex = 4;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Migration Options";
+            // 
+            // chkOverwrite
+            // 
+            this.chkOverwrite.AutoSize = true;
+            this.chkOverwrite.Location = new System.Drawing.Point(29, 64);
+            this.chkOverwrite.Name = "chkOverwrite";
+            this.chkOverwrite.Size = new System.Drawing.Size(212, 17);
+            this.chkOverwrite.TabIndex = 2;
+            this.chkOverwrite.Text = "Overwrite Resources of the same name";
+            this.chkOverwrite.UseVisualStyleBackColor = true;
+            // 
+            // cmbAction
+            // 
+            this.cmbAction.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbAction.FormattingEnabled = true;
+            this.cmbAction.Location = new System.Drawing.Point(130, 26);
+            this.cmbAction.Name = "cmbAction";
+            this.cmbAction.Size = new System.Drawing.Size(121, 21);
+            this.cmbAction.TabIndex = 1;
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(26, 29);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(83, 13);
+            this.label2.TabIndex = 0;
+            this.label2.Text = "Migration Action";
+            // 
+            // ResourceMigrationDialog
+            // 
+            this.AcceptButton = this.btnOK;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(546, 387);
+            this.ControlBox = false;
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnOK);
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
+            this.Name = "ResourceMigrationDialog";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+            this.Text = "Migrate Resources";
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.toolStrip1.ResumeLayout(false);
+            this.toolStrip1.PerformLayout();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.Button btnOK;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.CheckBox chkOverwrite;
+        private System.Windows.Forms.ComboBox cmbAction;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.ListBox lstResources;
+        private System.Windows.Forms.ToolStrip toolStrip1;
+        private System.Windows.Forms.ToolStripButton btnAddResource;
+        private System.Windows.Forms.ToolStripButton btnAddFolder;
+        private System.Windows.Forms.ToolStripButton btnRemove;
+        private System.Windows.Forms.Button btnBrowseTarget;
+        private System.Windows.Forms.TextBox txtTargetFolder;
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,175 @@
+#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.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.MaestroAPI;
+using Maestro.Editors.Generic;
+
+namespace Maestro.Editors.Migration
+{
+    public partial class ResourceMigrationDialog : Form
+    {
+        private ResourceMigrationDialog()
+        {
+            InitializeComponent();
+            cmbAction.DataSource = Enum.GetValues(typeof(MigrationAction));
+        }
+
+        private IServerConnection _source;
+        private IServerConnection _target;
+
+        public ResourceMigrationDialog(IServerConnection source, IServerConnection target)
+            : this()
+        {
+            _source = source;
+            _target = target;
+        }
+
+        private void lstResources_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            EvaluateCommandState();
+        }
+
+        private void btnAddResource_Click(object sender, EventArgs e)
+        {
+            using (var picker = new ResourcePicker(_source.ResourceService, ResourcePickerMode.OpenResource))
+            {
+                if (picker.ShowDialog() == DialogResult.OK)
+                {
+                    if (!lstResources.Items.Contains(picker.ResourceID))
+                        lstResources.Items.Add(picker.ResourceID);
+
+                    EvaluateCommandState();
+                }
+            }
+        }
+
+        private void btnAddFolder_Click(object sender, EventArgs e)
+        {
+            using (var picker = new ResourcePicker(_source.ResourceService, ResourcePickerMode.OpenFolder))
+            {
+                if (picker.ShowDialog() == DialogResult.OK)
+                {
+                    var folderId = picker.ResourceID;
+                    var list = _target.ResourceService.GetRepositoryResources(folderId);
+
+                    foreach (var item in list.Children)
+                    {
+                        if (!item.IsFolder && !lstResources.Items.Contains(item.ResourceId))
+                            lstResources.Items.Add(item.ResourceId);
+                    }
+                    EvaluateCommandState();
+                }
+            }
+        }
+
+        private void btnRemove_Click(object sender, EventArgs e)
+        {
+            var items = lstResources.SelectedItems;
+            if (items != null && items.Count > 0)
+            {
+                for (int i = 0; i < items.Count; i++)
+                {
+                    lstResources.Items.Remove(items[i]);
+                    EvaluateCommandState();
+                }
+            }
+        }
+
+        private void btnOK_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.OK;
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+        }
+
+        public string TargetFolder
+        {
+            get { return txtTargetFolder.Text; }
+            set { txtTargetFolder.Text = value; }
+        }
+
+        public string[] SourceResourceIds
+        {
+            get
+            {
+                List<string> resIds = new List<string>();
+                foreach (var item in lstResources.Items)
+                {
+                    resIds.Add(item.ToString());
+                }
+                return resIds.ToArray();
+            }
+            set
+            {
+                lstResources.Items.Clear();
+                foreach (var resId in value)
+                {
+                    lstResources.Items.Add(resId);
+                }
+                EvaluateCommandState();
+            }
+        }
+
+        public MigrationAction SelectedAction
+        {
+            get { return (MigrationAction)cmbAction.SelectedItem; }
+            set { cmbAction.SelectedItem = value ; }
+        }
+
+        public bool OverwriteResources
+        {
+            get { return chkOverwrite.Checked; }
+            set { chkOverwrite.Checked = value; }
+        }
+
+        private void btnBrowseTarget_Click(object sender, EventArgs e)
+        {
+            using (var picker = new ResourcePicker(_target.ResourceService, ResourcePickerMode.OpenFolder))
+            {
+                if (picker.ShowDialog() == DialogResult.OK)
+                {
+                    txtTargetFolder.Text = picker.ResourceID;
+                    EvaluateCommandState();
+                }
+            }
+        }
+
+        private void EvaluateCommandState()
+        {
+            btnRemove.Enabled = (lstResources.SelectedItem != null) || (lstResources.SelectedItems != null && lstResources.SelectedItems.Count > 0);
+            btnOK.Enabled = (lstResources.Items.Count > 0) && !string.IsNullOrEmpty(txtTargetFolder.Text);
+        }
+    }
+
+    public enum MigrationAction
+    { 
+        Copy,
+        Move
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.resx	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Editors/Migration/ResourceMigrationDialog.resx	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,123 @@
+<?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>
+  <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
\ No newline at end of file

Modified: sandbox/maestro-3.0/MaestroAPITests/MaestroAPITests.csproj
===================================================================
--- sandbox/maestro-3.0/MaestroAPITests/MaestroAPITests.csproj	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/MaestroAPITests/MaestroAPITests.csproj	2010-10-22 07:01:32 UTC (rev 5319)
@@ -60,10 +60,6 @@
     <Compile Include="ValidationTests.cs" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\Maestro.ResourceValidation\Maestro.ResourceValidation.csproj">
-      <Project>{3B29C138-666C-46D0-A55D-824E5192C091}</Project>
-      <Name>Maestro.ResourceValidation</Name>
-    </ProjectReference>
     <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI.Http\OSGeo.MapGuide.MaestroAPI.Http.csproj">
       <Project>{6EF1E775-444B-4E5F-87FB-D687C43A68D7}</Project>
       <Name>OSGeo.MapGuide.MaestroAPI.Http</Name>

Modified: sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs
===================================================================
--- sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/MaestroAPITests/ValidationTests.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -27,8 +27,8 @@
 using LoadProc = OSGeo.MapGuide.ObjectModels.LoadProcedure;
 using OSGeo.MapGuide.MaestroAPI.ObjectModels;
 using OSGeo.MapGuide.MaestroAPI;
-using Maestro.ResourceValidation;
 using OSGeo.MapGuide.ObjectModels.LoadProcedure;
+using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
 
 namespace MaestroAPITests
 {

Added: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/CrossConnection/ResourceMigrator.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/CrossConnection/ResourceMigrator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/CrossConnection/ResourceMigrator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,168 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+
+namespace OSGeo.MapGuide.MaestroAPI.CrossConnection
+{
+    /// <summary>
+    /// A helper class that copies/moves resources from one
+    /// connection to another
+    /// </summary>
+    public class ResourceMigrator
+    {
+        private IServerConnection _source;
+        private IServerConnection _target;
+
+        public ResourceMigrator(IServerConnection source, IServerConnection target)
+        {
+            Check.NotNull(source, "source");
+            Check.NotNull(target, "target");
+            _source = source;
+            _target = target;
+        }
+
+        /// <summary>
+        /// Copies resources from the source connection to another connection. The resources in question will
+        /// be copied to the specified folder. Folder structure of the source is discarded
+        /// </summary>
+        /// <param name="resourceIds"></param>
+        /// <param name="folderId"></param>
+        /// <param name="overwrite"></param>
+        /// <param name="callback"></param>
+        /// <returns></returns>
+        public int CopyResources(string[] resourceIds, string folderId, bool overwrite, LengthyOperationProgressCallBack callback)
+        {
+            var cb = callback;
+            if (cb == null)
+            {
+                cb = new LengthyOperationProgressCallBack((s, e) =>
+                {
+                    //Do nothing
+                });
+            }
+
+            int copied = 0;
+            int unit = 100 / resourceIds.Length;
+            int progress = 0;
+            foreach (var resId in resourceIds)
+            {
+                string targetId = folderId + ResourceIdentifier.GetName(resId) + "." + ResourceIdentifier.GetResourceType(resId);
+                string message = "";
+                IResource res = _source.ResourceService.GetResource(resId);
+
+                //Skip if target exists and overwrite is not specified
+                if (!overwrite && _target.ResourceService.ResourceExists(targetId))
+                {
+                    continue;
+                }
+                else
+                {
+                    //Save resource
+                    _target.ResourceService.SaveResourceAs(res, targetId);
+                    //Copy resource data
+                    foreach (var data in res.EnumerateResourceData())
+                    {
+                        using (var stream = res.GetResourceData(data.Name))
+                        {
+                            stream.Position = 0L;
+                            _target.ResourceService.SetResourceData(targetId, data.Name, data.Type, stream);
+                        }
+                    }
+
+                    copied++;
+                    message = string.Format(Properties.Resources.CopiedResource, resId);
+                }
+                progress += unit;
+                cb(this, new LengthyOperationProgressArgs(message, progress));
+            }
+            return copied;
+        }
+
+        /// <summary>
+        /// Moves resources from the source connection to the specified folder on the target connection. Folder structure of the source is discarded
+        /// </summary>
+        /// <param name="resourceIds"></param>
+        /// <param name="folderId"></param>
+        /// <param name="overwrite"></param>
+        /// <param name="callback"></param>
+        /// <returns></returns>
+        public int MoveResources(string[] resourceIds, string folderId, bool overwrite, LengthyOperationProgressCallBack callback)
+        {
+            var cb = callback;
+            if (cb == null)
+            {
+                cb = new LengthyOperationProgressCallBack((s, e) =>
+                {
+                    //Do nothing
+                });
+            }
+
+            int moved = 0;
+            int unit = 100 / resourceIds.Length;
+            int progress = 0;
+            foreach (var resId in resourceIds)
+            {
+                string targetId = folderId + ResourceIdentifier.GetName(resId) + "." + ResourceIdentifier.GetResourceType(resId);
+                string message = "";
+                IResource res = _source.ResourceService.GetResource(resId);
+
+                //Skip if target exists and overwrite is not specified
+                if (!overwrite && _target.ResourceService.ResourceExists(targetId))
+                {
+                    continue;
+                }
+                else
+                {
+                    //Save resource
+                    _target.ResourceService.SaveResourceAs(res, targetId);
+                    //Copy resource data
+                    foreach (var data in res.EnumerateResourceData())
+                    {
+                        using (var stream = res.GetResourceData(data.Name))
+                        {
+                            stream.Position = 0L;
+                            _target.ResourceService.SetResourceData(targetId, data.Name, data.Type, stream);
+                        }
+                    }
+
+                    moved++;
+                    _source.ResourceService.DeleteResource(resId);
+                    message = string.Format(Properties.Resources.CopiedResource, resId);
+                }
+                progress += unit;
+                cb(this, new LengthyOperationProgressArgs(message, progress));
+            }
+            return moved;
+        }
+
+        public IServerConnection Source
+        {
+            get { return _source; }
+        }
+
+        public IServerConnection Target
+        {
+            get { return _target; }
+        }
+    }
+}

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-10-22 07:01:32 UTC (rev 5319)
@@ -191,6 +191,7 @@
     <Compile Include="Mapping\MapSelectionBase.cs" />
     <Compile Include="Mapping\RuntimeLayerBase.cs" />
     <Compile Include="Mapping\RuntimeMapBase.cs" />
+    <Compile Include="CrossConnection\ResourceMigrator.cs" />
     <Compile Include="ObjectModels\ApplicationDefinition.cs" />
     <Compile Include="ObjectModels\DrawingSource.cs" />
     <Compile Include="ObjectModels\DrawingSourceInterfaces.cs" />
@@ -228,9 +229,10 @@
       <DependentUpon>Resources.resx</DependentUpon>
     </Compile>
     <Compile Include="ResourceTypeRegistry.cs" />
-    <Compile Include="Resource\BaseLayerDefinitionValidator.cs" />
-    <Compile Include="Resource\BaseLoadProcedureValidator.cs" />
-    <Compile Include="Resource\BaseWebLayoutValidator.cs" />
+    <Compile Include="Resource\Validation\ApplicationDefinitionValidator.cs" />
+    <Compile Include="Resource\Validation\BaseLayerDefinitionValidator.cs" />
+    <Compile Include="Resource\Validation\BaseLoadProcedureValidator.cs" />
+    <Compile Include="Resource\Validation\BaseWebLayoutValidator.cs" />
     <Compile Include="Resource\Conversion\IResourceConverter.cs" />
     <Compile Include="Resource\Conversion\ResourceConverter.cs" />
     <Compile Include="Resource\Conversion\ResourceUpgrader.cs" />
@@ -241,8 +243,18 @@
     <Compile Include="Resource\ResourceSchemaChain.cs" />
     <Compile Include="Resource\ResourceTypeDescriptor.cs" />
     <Compile Include="Resource\ResourceContentVersionChecker.cs" />
-    <Compile Include="Resource\ResourceValidatorSet.cs" />
-    <Compile Include="Resource\ValidationResultSet.cs" />
+    <Compile Include="Resource\Validation\DrawingSourceValidator.cs" />
+    <Compile Include="Resource\Validation\FeatureSourceValidator.cs" />
+    <Compile Include="Resource\Validation\LayerDefinitionValidator.cs" />
+    <Compile Include="Resource\Validation\LoadProcedureValidator.cs" />
+    <Compile Include="Resource\Validation\MapDefinitionValidator.cs" />
+    <Compile Include="Resource\Validation\PrintLayoutValidator.cs" />
+    <Compile Include="Resource\Validation\ResourceValidatorLoader.cs" />
+    <Compile Include="Resource\Validation\ResourceValidatorSet.cs" />
+    <Compile Include="Resource\Validation\SymbolDefinitionValidator.cs" />
+    <Compile Include="Resource\Validation\SymbolLibraryValidator.cs" />
+    <Compile Include="Resource\Validation\ValidationResultSet.cs" />
+    <Compile Include="Resource\Validation\WebLayoutValidator.cs" />
     <Compile Include="Serialization\Enums.cs" />
     <Compile Include="Serialization\IBinarySerializeable.cs" />
     <Compile Include="Serialization\MgBinaryDeserializer.cs" />

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -61,6 +61,69 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Map with ID {0} does not point to a valid map.
+        /// </summary>
+        internal static string ADF_MapInvalidError {
+            get {
+                return ResourceManager.GetString("ADF_MapInvalidError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Fusion application does not specify a map.
+        /// </summary>
+        internal static string ADF_MapMissingError {
+            get {
+                return ResourceManager.GetString("ADF_MapMissingError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Error validating MapDefinition {0}, message: {1}.
+        /// </summary>
+        internal static string ADF_MapValidationError {
+            get {
+                return ResourceManager.GetString("ADF_MapValidationError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Fusion application specifies a start view that is outside the map&apos;s initial extents.
+        /// </summary>
+        internal static string ADF_ViewOutsideMapExtents {
+            get {
+                return ResourceManager.GetString("ADF_ViewOutsideMapExtents", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Copied resource: {0}.
+        /// </summary>
+        internal static string CopiedResource {
+            get {
+                return ResourceManager.GetString("CopiedResource", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No coordinate system specified. The coordinate system if not specified will default to LL84.
+        /// </summary>
+        internal static string DS_NoCoordinateSpace {
+            get {
+                return ResourceManager.GetString("DS_NoCoordinateSpace", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No source DWF file specified.
+        /// </summary>
+        internal static string DS_NoSourceSpecified {
+            get {
+                return ResourceManager.GetString("DS_NoSourceSpecified", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Bad Document: Expected attributes at the root level node.
         /// </summary>
         internal static string ERR_BAD_DOCUMENT_NO_ROOT_ATTRIBUTES {
@@ -169,26 +232,107 @@
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Only vector layers and raster layers are currently validated.
+        ///   Looks up a localized string similar to Connection test failed.
         /// </summary>
-        internal static string LDF_DrawingLayerDefinitionNotSupportedWarning {
+        internal static string FS_ConnectionTestFailed {
             get {
-                return ResourceManager.GetString("LDF_DrawingLayerDefinitionNotSupportedWarning", resourceCulture);
+                return ResourceManager.GetString("FS_ConnectionTestFailed", resourceCulture);
             }
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Maestro does not support DrawingLayers.
+        ///   Looks up a localized string similar to Spatial context extent appears to be invalid (or default).
         /// </summary>
-        internal static string LDF_DrawingLayerNotSupportedWarning {
+        internal static string FS_DefaultSpatialContextWarning {
             get {
-                return ResourceManager.GetString("LDF_DrawingLayerNotSupportedWarning", resourceCulture);
+                return ResourceManager.GetString("FS_DefaultSpatialContextWarning", resourceCulture);
             }
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Failed to load featuresource.
+        ///   Looks up a localized string similar to Empty spatial context extent detected.
         /// </summary>
+        internal static string FS_EmptySpatialContextWarning {
+            get {
+                return ResourceManager.GetString("FS_EmptySpatialContextWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Could not obtain identity properties for {0}. This class either has no identity properties and/or is derived from a view with no uniquely identifiable columns. Attempting to create feature joins from this class may produce unexpected results..
+        /// </summary>
+        internal static string FS_NoPrimaryKeyOrView {
+            get {
+                return ResourceManager.GetString("FS_NoPrimaryKeyOrView", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No spatial contexts found. If this feature source is strictly used for Feature Joins, this warning can be safely ignored.
+        /// </summary>
+        internal static string FS_NoSpatialContextWarning {
+            get {
+                return ResourceManager.GetString("FS_NoSpatialContextWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No primary key defined for class: {0}, features will not be selectable and feature joins on this class may produce unexpected results.
+        /// </summary>
+        internal static string FS_PrimaryKeyMissingInformation {
+            get {
+                return ResourceManager.GetString("FS_PrimaryKeyMissingInformation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to read identity properties: {0}.
+        /// </summary>
+        internal static string FS_PrimaryKeyReadError {
+            get {
+                return ResourceManager.GetString("FS_PrimaryKeyReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to read schema description: {0}.
+        /// </summary>
+        internal static string FS_SchemaReadError {
+            get {
+                return ResourceManager.GetString("FS_SchemaReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No schemas found in datasource.
+        /// </summary>
+        internal static string FS_SchemasMissingWarning {
+            get {
+                return ResourceManager.GetString("FS_SchemasMissingWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to read spatial context: {0}.
+        /// </summary>
+        internal static string FS_SpatialContextReadError {
+            get {
+                return ResourceManager.GetString("FS_SpatialContextReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to load specified Drawing Source.
+        /// </summary>
+        internal static string LDF_DrawingSourceError {
+            get {
+                return ResourceManager.GetString("LDF_DrawingSourceError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to load specified Feature Source.
+        /// </summary>
         internal static string LDF_FeatureSourceLoadError {
             get {
                 return ResourceManager.GetString("LDF_FeatureSourceLoadError", resourceCulture);
@@ -286,6 +430,24 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Referenced sheet layer {0} not found in sheet {1} of referenced Drawing Source.
+        /// </summary>
+        internal static string LDF_SheetLayerNotFound {
+            get {
+                return ResourceManager.GetString("LDF_SheetLayerNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Referenced sheet {0} not found in referenced Drawing Source.
+        /// </summary>
+        internal static string LDF_SheetNotFound {
+            get {
+                return ResourceManager.GetString("LDF_SheetNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to The layer has no type, or the type is unsupported by Maestro.
         /// </summary>
         internal static string LDF_UnsupportedLayerTypeWarning {
@@ -358,6 +520,159 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Data from {0} is not visible in the map&apos;s start extent.
+        /// </summary>
+        internal static string MDF_DataOutsideMapWarning {
+            get {
+                return ResourceManager.GetString("MDF_DataOutsideMapWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has a different coordinate system than the map, this will impact performance as the coordinates are transformed while rendering the map. Maestro cannot validate the extent of the data..
+        /// </summary>
+        internal static string MDF_DataReprojectionWarning {
+            get {
+                return ResourceManager.GetString("MDF_DataReprojectionWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0}&apos;s FeatureSource could not be read: {1}.
+        /// </summary>
+        internal static string MDF_FeatureSourceReadError {
+            get {
+                return ResourceManager.GetString("MDF_FeatureSourceReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Group {0} has the default legend label.
+        /// </summary>
+        internal static string MDF_GroupHasDefaultLabelInformation {
+            get {
+                return ResourceManager.GetString("MDF_GroupHasDefaultLabelInformation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Group {0} does not have a legend label.
+        /// </summary>
+        internal static string MDF_GroupMissingLabelInformation {
+            get {
+                return ResourceManager.GetString("MDF_GroupMissingLabelInformation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0} does not have a legend label.
+        /// </summary>
+        internal static string MDF_LayerMissingLabelInformation {
+            get {
+                return ResourceManager.GetString("MDF_LayerMissingLabelInformation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The layer name {0} is used for both &quot;{1}&quot; and &quot;{2}&quot;.
+        /// </summary>
+        internal static string MDF_LayerNameDuplicateWarning {
+            get {
+                return ResourceManager.GetString("MDF_LayerNameDuplicateWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0} could not be read: {1}.
+        /// </summary>
+        internal static string MDF_LayerReadError {
+            get {
+                return ResourceManager.GetString("MDF_LayerReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0} has no geometry column.
+        /// </summary>
+        internal static string MDF_MissingLayerGeometryColumnError {
+            get {
+                return ResourceManager.GetString("MDF_MissingLayerGeometryColumnError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0} has an invalid Schema.
+        /// </summary>
+        internal static string MDF_MissingLayerSchemaError {
+            get {
+                return ResourceManager.GetString("MDF_MissingLayerSchemaError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has no spatial context (eg. no coordinate system).
+        /// </summary>
+        internal static string MDF_MissingSpatialContextWarning {
+            get {
+                return ResourceManager.GetString("MDF_MissingSpatialContextWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has more than one spatial context, the following test results may be inacurate.
+        /// </summary>
+        internal static string MDF_MultipleSpatialContextsInformation {
+            get {
+                return ResourceManager.GetString("MDF_MultipleSpatialContextsInformation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} is a raster layer, and in another coordinate system than the map. No data will be displayed by the layer.
+        /// </summary>
+        internal static string MDF_RasterReprojectionError {
+            get {
+                return ResourceManager.GetString("MDF_RasterReprojectionError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} could not be processed for spatial info: {1}.
+        /// </summary>
+        internal static string MDF_ResourceReadError {
+            get {
+                return ResourceManager.GetString("MDF_ResourceReadError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Layer {0} is a type that is unsupported by Maestro.
+        /// </summary>
+        internal static string MDF_UnsupportedLayerTypeWarning {
+            get {
+                return ResourceManager.GetString("MDF_UnsupportedLayerTypeWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Moved resource: {0}.
+        /// </summary>
+        internal static string MovedResource {
+            get {
+                return ResourceManager.GetString("MovedResource", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Not a folder resource id: {0}.
+        /// </summary>
+        internal static string NotAFolder {
+            get {
+                return ResourceManager.GetString("NotAFolder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to There web layout has more than one command named: {0}.
         /// </summary>
         internal static string WL_DuplicateCommandName {

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2010-10-22 07:01:32 UTC (rev 5319)
@@ -117,6 +117,31 @@
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+  <data name="ADF_MapInvalidError" xml:space="preserve">
+    <value>Map with ID {0} does not point to a valid map</value>
+    <comment>An error message that is displayed if there is a MapID that does not reference a valid map</comment>
+  </data>
+  <data name="ADF_MapMissingError" xml:space="preserve">
+    <value>Fusion application does not specify a map</value>
+    <comment>An error message that is displayed if the map is missing</comment>
+  </data>
+  <data name="ADF_MapValidationError" xml:space="preserve">
+    <value>Error validating MapDefinition {0}, message: {1}</value>
+    <comment>An error message that is displayed if an error occurs while validating a map</comment>
+  </data>
+  <data name="ADF_ViewOutsideMapExtents" xml:space="preserve">
+    <value>Fusion application specifies a start view that is outside the map's initial extents</value>
+    <comment>An error message that is displayed if the start view is outside the defined map</comment>
+  </data>
+  <data name="CopiedResource" xml:space="preserve">
+    <value>Copied resource: {0}</value>
+  </data>
+  <data name="DS_NoCoordinateSpace" xml:space="preserve">
+    <value>No coordinate system specified. The coordinate system if not specified will default to LL84</value>
+  </data>
+  <data name="DS_NoSourceSpecified" xml:space="preserve">
+    <value>No source DWF file specified</value>
+  </data>
   <data name="ERR_BAD_DOCUMENT_NO_ROOT_ATTRIBUTES" xml:space="preserve">
     <value>Bad Document: Expected attributes at the root level node</value>
   </data>
@@ -154,16 +179,51 @@
   <data name="ERR_SERIALIZER_ALREADY_REGISTERED" xml:space="preserve">
     <value>A resource serializer has already been registered for {0} v{1}</value>
   </data>
-  <data name="LDF_DrawingLayerDefinitionNotSupportedWarning" xml:space="preserve">
-    <value>Only vector layers and raster layers are currently validated</value>
-    <comment>A warning message that is displayed if the layer is not Grid or Vector</comment>
+  <data name="FS_ConnectionTestFailed" xml:space="preserve">
+    <value>Connection test failed</value>
+    <comment>An error message that is displayed if a connection test on the feature source failed</comment>
   </data>
-  <data name="LDF_DrawingLayerNotSupportedWarning" xml:space="preserve">
-    <value>Maestro does not support DrawingLayers</value>
-    <comment>A warning message that is displayed if the layer is a DrawingLayer type</comment>
+  <data name="FS_DefaultSpatialContextWarning" xml:space="preserve">
+    <value>Spatial context extent appears to be invalid (or default)</value>
+    <comment>A warning message that is displayed if the spatial context has the default extent</comment>
   </data>
+  <data name="FS_EmptySpatialContextWarning" xml:space="preserve">
+    <value>Empty spatial context extent detected</value>
+    <comment>A warning message that is displayed when the spatial context is empty</comment>
+  </data>
+  <data name="FS_NoPrimaryKeyOrView" xml:space="preserve">
+    <value>Could not obtain identity properties for {0}. This class either has no identity properties and/or is derived from a view with no uniquely identifiable columns. Attempting to create feature joins from this class may produce unexpected results.</value>
+    <comment>A warning message that is displayed when we can't obtain identity properties from a class because it is a view</comment>
+  </data>
+  <data name="FS_NoSpatialContextWarning" xml:space="preserve">
+    <value>No spatial contexts found. If this feature source is strictly used for Feature Joins, this warning can be safely ignored</value>
+    <comment>A warning message that is displayed when the featuresource fails to report its spatial context</comment>
+  </data>
+  <data name="FS_PrimaryKeyMissingInformation" xml:space="preserve">
+    <value>No primary key defined for class: {0}, features will not be selectable and feature joins on this class may produce unexpected results</value>
+    <comment>An information message that is displayed if the schema has no primary key defined</comment>
+  </data>
+  <data name="FS_PrimaryKeyReadError" xml:space="preserve">
+    <value>Failed to read identity properties: {0}</value>
+    <comment>An error message that is displayed if the primary key information could not be read</comment>
+  </data>
+  <data name="FS_SchemaReadError" xml:space="preserve">
+    <value>Failed to read schema description: {0}</value>
+    <comment>An error message that is displayed if the schema information could not be read</comment>
+  </data>
+  <data name="FS_SchemasMissingWarning" xml:space="preserve">
+    <value>No schemas found in datasource</value>
+    <comment>A warning message that is displayed if the featuresource has no schemas</comment>
+  </data>
+  <data name="FS_SpatialContextReadError" xml:space="preserve">
+    <value>Failed to read spatial context: {0}</value>
+    <comment>An error message that is displayed if the spatial context could not be read</comment>
+  </data>
+  <data name="LDF_DrawingSourceError" xml:space="preserve">
+    <value>Failed to load specified Drawing Source</value>
+  </data>
   <data name="LDF_FeatureSourceLoadError" xml:space="preserve">
-    <value>Failed to load featuresource</value>
+    <value>Failed to load specified Feature Source</value>
     <comment>An error message that is displayed if the featuresource fails to load</comment>
   </data>
   <data name="LDF_GeometryMissingError" xml:space="preserve">
@@ -206,6 +266,12 @@
     <value>Failed to find schema {0} in featuresource {1}</value>
     <comment>An error message that is displayed if the selected schema is not present in the FeatureSource</comment>
   </data>
+  <data name="LDF_SheetLayerNotFound" xml:space="preserve">
+    <value>Referenced sheet layer {0} not found in sheet {1} of referenced Drawing Source</value>
+  </data>
+  <data name="LDF_SheetNotFound" xml:space="preserve">
+    <value>Referenced sheet {0} not found in referenced Drawing Source</value>
+  </data>
   <data name="LDF_UnsupportedLayerTypeWarning" xml:space="preserve">
     <value>The layer has no type, or the type is unsupported by Maestro</value>
     <comment>A  warning message that is displayed if the layer type is unknown</comment>
@@ -238,6 +304,72 @@
     <value>Source file not found: {0}</value>
     <comment>An error message indicating that a source file in the load procedure does not exist</comment>
   </data>
+  <data name="MDF_DataOutsideMapWarning" xml:space="preserve">
+    <value>Data from {0} is not visible in the map's start extent</value>
+    <comment>A warning message that is displayed if a layer reports an extent that is outside the map's extent</comment>
+  </data>
+  <data name="MDF_DataReprojectionWarning" xml:space="preserve">
+    <value>{0} has a different coordinate system than the map, this will impact performance as the coordinates are transformed while rendering the map. Maestro cannot validate the extent of the data.</value>
+    <comment>A warning message that is displayed if a layer reports a coordinate system that differs from the map's.</comment>
+  </data>
+  <data name="MDF_FeatureSourceReadError" xml:space="preserve">
+    <value>Layer {0}'s FeatureSource could not be read: {1}</value>
+    <comment>An error message that is displayed if a FeatureSource fails to load</comment>
+  </data>
+  <data name="MDF_GroupHasDefaultLabelInformation" xml:space="preserve">
+    <value>Group {0} has the default legend label</value>
+    <comment>An information message that is displayed if a group is assigned the default group label</comment>
+  </data>
+  <data name="MDF_GroupMissingLabelInformation" xml:space="preserve">
+    <value>Group {0} does not have a legend label</value>
+    <comment>An information message that is displayed if a group has a blank legend label</comment>
+  </data>
+  <data name="MDF_LayerMissingLabelInformation" xml:space="preserve">
+    <value>Layer {0} does not have a legend label</value>
+    <comment>An information message that is displayed if a layer has a blank legend label</comment>
+  </data>
+  <data name="MDF_LayerNameDuplicateWarning" xml:space="preserve">
+    <value>The layer name {0} is used for both "{1}" and "{2}"</value>
+    <comment>A warning message that is displayed if two layers share the same layer name</comment>
+  </data>
+  <data name="MDF_LayerReadError" xml:space="preserve">
+    <value>Layer {0} could not be read: {1}</value>
+    <comment>An error message that is displayed if a LayerDefinition fails to load</comment>
+  </data>
+  <data name="MDF_MissingLayerGeometryColumnError" xml:space="preserve">
+    <value>Layer {0} has no geometry column</value>
+    <comment>An error message that is displayed if a layer has no geometry column specified</comment>
+  </data>
+  <data name="MDF_MissingLayerSchemaError" xml:space="preserve">
+    <value>Layer {0} has an invalid Schema</value>
+    <comment>An error message that is displayed if the layer has no schema specified</comment>
+  </data>
+  <data name="MDF_MissingSpatialContextWarning" xml:space="preserve">
+    <value>{0} has no spatial context (eg. no coordinate system)</value>
+    <comment>A warning message that is displayed if the FeatureSource reports no spatial context</comment>
+  </data>
+  <data name="MDF_MultipleSpatialContextsInformation" xml:space="preserve">
+    <value>{0} has more than one spatial context, the following test results may be inacurate</value>
+    <comment>An information message that is displayed if a FeatureSource reports multiple spatial contexts</comment>
+  </data>
+  <data name="MDF_RasterReprojectionError" xml:space="preserve">
+    <value>{0} is a raster layer, and in another coordinate system than the map. No data will be displayed by the layer</value>
+    <comment>An error message that is displayed if a raster layer reports a different projection than the map, and the MapGuide server version does not support raster reprojection</comment>
+  </data>
+  <data name="MDF_ResourceReadError" xml:space="preserve">
+    <value>{0} could not be processed for spatial info: {1}</value>
+    <comment>An error message that is displayed if a resource fails to load</comment>
+  </data>
+  <data name="MDF_UnsupportedLayerTypeWarning" xml:space="preserve">
+    <value>Layer {0} is a type that is unsupported by Maestro</value>
+    <comment>A warning message that is displayed if a layer has a type that is not supported by Maestro</comment>
+  </data>
+  <data name="MovedResource" xml:space="preserve">
+    <value>Moved resource: {0}</value>
+  </data>
+  <data name="NotAFolder" xml:space="preserve">
+    <value>Not a folder resource id: {0}</value>
+  </data>
   <data name="WL_DuplicateCommandName" xml:space="preserve">
     <value>There web layout has more than one command named: {0}</value>
   </data>

Deleted: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -1,183 +0,0 @@
-#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 OSGeo.MapGuide.ObjectModels.LayerDefinition;
-using OSGeo.MapGuide.ObjectModels.FeatureSource;
-
-namespace OSGeo.MapGuide.MaestroAPI.Resource
-{
-    /// <summary>
-    /// A base layer definition validator class the provides the common validation logic. Because this is working against
-    /// the layer definition interfaces, this common logic can apply to all versions of the layer definition schema (that
-    /// implement these interfaces)
-    /// </summary>
-    public abstract class BaseLayerDefinitionValidator : IResourceValidator
-    {
-        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
-        {
-            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
-                return null;
-
-            return ValidateBase(resource, recurse);
-        }
-
-        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
-        {
-            var ldef = resource as ILayerDefinition;
-            var vldef = ldef.SubLayer as IVectorLayerDefinition;
-            var gldef = ldef.SubLayer as IRasterLayerDefinition;
-            var dldef = ldef.SubLayer as IDrawingLayerDefinition;
-
-            List<ValidationIssue> issues = new List<ValidationIssue>();
-
-            if (ldef.SubLayer == null)
-                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_LayerNullError));
-            else if (vldef == null && gldef == null)
-                issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_DrawingLayerDefinitionNotSupportedWarning));
-
-            if (vldef != null)
-            {
-                if (string.IsNullOrEmpty(vldef.FeatureName))
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingFeatureSourceError));
-                if (string.IsNullOrEmpty(vldef.Geometry))
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingGeometryError));
-
-                if (vldef.VectorScaleRange == null || !vldef.HasVectorScaleRanges())
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingScaleRangesError));
-                else
-                {
-                    //Test for overlapping scale ranges
-                    List<KeyValuePair<double, double>> ranges = new List<KeyValuePair<double, double>>();
-                    foreach (IVectorScaleRange vsr in vldef.VectorScaleRange)
-                    {
-                        ranges.Add(new KeyValuePair<double, double>(
-                            vsr.MaxScale.HasValue ? vsr.MaxScale.Value : double.PositiveInfinity,
-                            vsr.MinScale.HasValue ? vsr.MinScale.Value : double.NegativeInfinity));
-                    }
-
-                    double min = double.PositiveInfinity;
-                    double max = double.NegativeInfinity;
-                    foreach (KeyValuePair<double, double> sr in ranges)
-                    {
-                        min = Math.Min(min, sr.Value);
-                        max = Math.Max(max, sr.Key);
-                        if (sr.Key < sr.Value)
-                            issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_MinAndMaxScaleSwappedError, sr.Value, sr.Key)));
-                    }
-
-                    //TODO: Detect gaps in scale ranges
-                    for (int i = 0; i < ranges.Count; i++)
-                        for (int j = i + 1; j < ranges.Count; j++)
-                            if (ranges[i].Key > ranges[j].Value || ranges[i].Value > ranges[j].Value)
-                                issues.Add(new ValidationIssue(resource, ValidationStatus.Information, string.Format(Properties.Resources.LDF_ScaleRangesOverlapInformation, ranges[i].Value, ranges[i].Key, ranges[j].Value, ranges[j].Key)));
-
-                }
-            }
-            else if (gldef != null)
-            {
-                if (gldef.GridScaleRange == null || gldef.GridScaleRange.Count == 0)
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingScaleRangesError));
-                else if (gldef.GridScaleRange.Count != 1)
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_MultipleScaleRangesWarning));
-            }
-            else if (dldef != null)
-                issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_DrawingLayerNotSupportedWarning));
-            else
-                issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_UnsupportedLayerTypeWarning));
-
-            if (recurse)
-            {
-                try
-                {
-                    FeatureSourceType fs = (FeatureSourceType)ldef.CurrentConnection.ResourceService.GetResource(ldef.SubLayer.ResourceId);
-                    issues.AddRange(ResourceValidatorSet.Validate(fs, recurse));
-
-                    try
-                    {
-                        if (vldef != null || gldef != null)
-                        {
-                            string schema = vldef == null ? gldef.FeatureName : vldef.FeatureName;
-                            string geometry = vldef == null ? gldef.Geometry : vldef.Geometry;
-
-                            bool foundSchema = false;
-                            bool foundGeometry = false;
-
-                            FeatureSourceDescription desc = fs.Describe();
-                            foreach (ClassDefinition scm in desc.Classes)
-                                if (scm.QualifiedNameDecoded == schema)
-                                {
-                                    foundSchema = true;
-
-                                    foreach (FeatureSetColumn col in scm.Columns)
-                                        if (col.Name == geometry)
-                                        {
-                                            foundGeometry = true;
-                                            break;
-                                        }
-
-
-                                    if (vldef != null && vldef.PropertyMapping != null)
-                                        foreach (INameStringPair s in vldef.PropertyMapping)
-                                        {
-                                            bool found = false;
-                                            foreach (FeatureSetColumn col in scm.Columns)
-                                            {
-                                                if (col.Name == s.Name)
-                                                {
-                                                    found = true;
-                                                    break;
-                                                }
-                                            }
-                                            if (!found)
-                                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaMissingError, schema, fs.ResourceID)));
-
-                                        }
-
-                                    break;
-                                }
-
-                            if (!foundSchema)
-                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaMissingError, schema, fs.ResourceID)));
-                            else if (!foundGeometry)
-                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_GeometryMissingError, geometry, schema, fs.ResourceID)));
-                        }
-                    }
-                    catch (Exception)
-                    {
-                        issues.Add(new ValidationIssue(fs, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaAndColumnReadFailedError)));
-                    }
-                }
-                catch (Exception)
-                {
-                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_FeatureSourceLoadError)));
-                }
-            }
-
-            return issues.ToArray();
-        }
-
-        public abstract ResourceTypeDescriptor SupportedResourceAndVersion
-        {
-            get;
-        }
-    }
-}

Deleted: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLoadProcedureValidator.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLoadProcedureValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLoadProcedureValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -1,76 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OSGeo.MapGuide.ObjectModels.LoadProcedure;
-
-namespace OSGeo.MapGuide.MaestroAPI.Resource
-{
-    public abstract class BaseLoadProcedureValidator : IResourceValidator
-    {
-        public abstract ResourceTypeDescriptor SupportedResourceAndVersion { get; }
-
-        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
-        {
-            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
-                return null;
-
-            return ValidateBase(resource, recurse);
-        }
-
-        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
-        {
-            if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.LoadProcedure)
-                return null;
-
-            if (resource.ResourceVersion != new Version(1, 0, 0))
-                return null;
-
-            var set = new ValidationResultSet();
-
-            var loadProc = (resource as ILoadProcedure).SubType;
-
-            if (loadProc.Type == LoadType.Dwg)
-            {
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_DWGNotSupported));
-                return set.GetAllIssues(); //all she wrote
-            }
-
-            if (loadProc.Type == LoadType.Raster)
-            {
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_RasterNotSupported));
-                return set.GetAllIssues(); //all she wrote
-            }
-
-            if (loadProc.Type == LoadType.Sdf)
-            {
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_Sdf2OptionsNotSupported));
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
-            }
-
-            if (loadProc.Type == LoadType.Shp)
-            {
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_ConvertToSdf3NotSupported));
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
-            }
-
-            if (loadProc.Type == LoadType.Sqlite)
-            {
-                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
-            }
-
-            var fproc = loadProc as IBaseLoadProcedure;
-            if (fproc != null)
-            {
-                foreach (var fn in fproc.SourceFile)
-                {
-                    if (!System.IO.File.Exists(fn))
-                    {
-                        set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, string.Format(Properties.Resources.LPROC_SourceFileNotFound, fn)));
-                    }
-                }
-            }
-
-            return set.GetAllIssues();
-        }
-    }
-}

Deleted: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseWebLayoutValidator.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseWebLayoutValidator.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseWebLayoutValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -1,127 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using OSGeo.MapGuide.ObjectModels.Common;
-using OSGeo.MapGuide.ObjectModels.MapDefinition;
-using OSGeo.MapGuide.ObjectModels.WebLayout;
-using OSGeo.MapGuide.MaestroAPI.Exceptions;
-using OSGeo.MapGuide.MaestroAPI.ObjectModels;
-
-namespace OSGeo.MapGuide.MaestroAPI.Resource
-{
-    public abstract class BaseWebLayoutValidator : IResourceValidator
-    {
-        public abstract ResourceTypeDescriptor SupportedResourceAndVersion
-        {
-            get;
-        }
-
-        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
-        {
-            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
-                return null;
-
-            return ValidateBase(resource, recurse);
-        }
-
-        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
-        {
-            if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.WebLayout)
-                return null;
-
-            List<ValidationIssue> issues = new List<ValidationIssue>();
-
-            IWebLayout layout = resource as IWebLayout;
-            if (layout.Map == null || layout.Map.ResourceId == null)
-            {
-                issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_MissingMapError)));
-            }
-            else
-            {
-                //Check for duplicate command names
-                var cmdSet = layout.CommandSet;
-                Dictionary<string, ICommand> cmds = new Dictionary<string, ICommand>();
-                foreach (ICommand cmd in cmdSet.Commands)
-                {
-                    if (cmds.ContainsKey(cmd.Name))
-                        issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_DuplicateCommandName, cmd.Name)));
-                    else
-                        cmds[cmd.Name] = cmd;
-                }
-
-                //Check for duplicate property references in search commands
-                foreach (ICommand cmd in cmdSet.Commands)
-                {
-                    if (cmd is ISearchCommand)
-                    {
-                        ISearchCommand search = (ISearchCommand)cmd;
-                        Dictionary<string, string> resColProps = new Dictionary<string, string>();
-                        foreach (IResultColumn resCol in search.ResultColumns.Column)
-                        {
-                            if (resColProps.ContainsKey(resCol.Property))
-                                issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_DuplicateSearchResultColumn, search.Name, resCol.Property)));
-                            else
-                                resColProps.Add(resCol.Property, resCol.Property);
-                        }
-                    }
-                }
-
-                //Check for command references to non-existent commands
-                foreach (IUIItem item in layout.ContextMenu.Items)
-                {
-                    if (item.Function == UIItemFunctionType.Command)
-                    {
-                        ICommandItem cmdRef = (ICommandItem)item;
-                        if (!cmds.ContainsKey(cmdRef.Command))
-                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentMenuCommandReference, cmdRef.Command)));
-                    }
-                }
-
-                foreach (IUIItem item in layout.TaskPane.TaskBar.Items)
-                {
-                    if (item.Function == UIItemFunctionType.Command)
-                    {
-                        ICommandItem cmdRef = (ICommandItem)item;
-                        if (!cmds.ContainsKey(cmdRef.Command))
-                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentTaskPaneCommandReference, cmdRef.Command)));
-                    }
-                }
-
-                foreach (IUIItem item in layout.ToolBar.Items)
-                {
-                    if (item.Function == UIItemFunctionType.Command)
-                    {
-                        ICommandItem cmdRef = (ICommandItem)item;
-                        if (!cmds.ContainsKey(cmdRef.Command))
-                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentToolbarCommandReference, cmdRef.Command)));
-                    }
-                }
-
-                if (recurse)
-                {
-                    try
-                    {
-                        IMapDefinition mdef = (IMapDefinition)layout.CurrentConnection.ResourceService.GetResource(layout.Map.ResourceId);
-
-                        issues.AddRange(ResourceValidatorSet.Validate(mdef, true));
-
-                        if (layout.Map.InitialView != null)
-                        {
-                            var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MaxX, mdef.Extents.MinY, mdef.Extents.MaxY);
-                            if (!mapEnv.Contains(layout.Map.InitialView.CenterX, layout.Map.InitialView.CenterY))
-                                issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, string.Format(Properties.Resources.WL_StartViewOutsideExtentsWarning)));
-                        }
-
-                    }
-                    catch (Exception ex)
-                    {
-                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
-                        issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_MapValidationError, layout.Map.ResourceId, msg)));
-                    }
-                }
-            }
-
-            return issues.ToArray();
-        }
-    }
-}

Deleted: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ResourceValidatorSet.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ResourceValidatorSet.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ResourceValidatorSet.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -1,99 +0,0 @@
-#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 OSGeo.MapGuide.MaestroAPI.Exceptions;
-
-namespace OSGeo.MapGuide.MaestroAPI.Resource
-{
-    /// <summary>
-    /// A collection of resource validators
-    /// </summary>
-    public static class ResourceValidatorSet
-    {
-        private static List<IResourceValidator> m_validators = new List<IResourceValidator>();
-
-        public static void RegisterValidator(IResourceValidator validator)
-        {
-            Check.NotNull(validator, "validator");
-
-            if (!m_validators.Contains(validator))
-                m_validators.Add(validator);
-        }
-
-        public static ValidationIssue[] Validate(IEnumerable<IResource> items, bool recurse)
-        {
-            Check.NotNull(items, "items");
-
-            var issues = new List<ValidationIssue>();
-            foreach (var item in items)
-            {
-                issues.AddRange(Validate(item, true));
-            }
-            return issues.ToArray();
-        }
-
-        public static ValidationIssue[] Validate(IResource item, bool recurse)
-        {
-            Check.NotNull(item, "item");
-
-            var issueSet = new ValidationResultSet();
-            List<ValidationIssue> issues = new List<ValidationIssue>();
-            if (!HasValidator(item.ResourceType, item.ResourceVersion))
-            {
-                issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Warning, string.Format(Properties.Resources.ERR_NO_REGISTERED_VALIDATOR, item.ResourceType, item.ResourceVersion)));
-            }
-            else
-            {
-                foreach (IResourceValidator v in m_validators)
-                {
-                    try
-                    {
-                        ValidationIssue[] tmp = v.Validate(item, recurse);
-                        if (tmp != null)
-                            issueSet.AddIssues(tmp);
-                    }
-                    catch (Exception ex)
-                    {
-                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
-                        issues.Add(new ValidationIssue(item, ValidationStatus.Error, "Failed in validator: " + msg));
-                    }
-                }
-            }
-            return issueSet.GetAllIssues();
-        }
-
-        public static bool HasValidator(ResourceTypes resourceTypes, Version version)
-        {
-            bool found = false;
-            var find = new ResourceTypeDescriptor(resourceTypes, version.ToString());
-            foreach (var v in m_validators)
-            {
-                if (v.SupportedResourceAndVersion.Equals(find))
-                {
-                    found = true;
-                    break;
-                }
-            }
-            return found;
-        }
-    }
-}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/ApplicationDefinitionValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ApplicationDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,92 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.ApplicationDefinition;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class ApplicationDefinitionValidator : IResourceValidator
+    {
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.ApplicationDefinition)
+                return null;
+
+            List<ValidationIssue> issues = new List<ValidationIssue>();
+
+            ApplicationDefinitionType fusionApp = resource as ApplicationDefinitionType;
+            if (fusionApp.MapSet == null || fusionApp.MapSet.Count == 0)
+                issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, string.Format(Properties.Resources.ADF_MapMissingError)));
+            else
+            {
+                if (recurse)
+                {
+                    foreach (MapGroupType mapGroup in fusionApp.MapSet)
+                        foreach (OSGeo.MapGuide.ObjectModels.ApplicationDefinition.MapType map in mapGroup.Map)
+                        {
+                            try
+                            {
+
+                                if (map.Extension == null || map.Extension.GetElement("ResourceId") == null)
+                                {
+                                    issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, string.Format(Properties.Resources.ADF_MapInvalidError, mapGroup.id)));
+                                }
+                                else
+                                {
+                                    MapDefinition mdef = (MapDefinition)fusionApp.CurrentConnection.ResourceService.GetResource(map.Extension.GetElement("ResourceId").InnerText);
+
+                                    issues.AddRange(ResourceValidatorSet.Validate(mdef, true));
+
+                                    IEnvelope mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MaxX, mdef.Extents.MinY, mdef.Extents.MaxY);
+
+                                    if (mapGroup.InitialView != null)
+                                    {
+                                        if (!mapEnv.Contains(mapGroup.InitialView.CenterX, mapGroup.InitialView.CenterY))
+                                            issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, string.Format(Properties.Resources.ADF_ViewOutsideMapExtents)));
+                                    }
+                                }
+
+
+                            }
+                            catch (Exception ex)
+                            {
+                                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                                issues.Add(new ValidationIssue(fusionApp, ValidationStatus.Error, string.Format(Properties.Resources.ADF_MapValidationError, mapGroup.id, msg)));
+                            }
+                        }
+                }
+            }
+
+            return issues.ToArray();
+        }
+
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(OSGeo.MapGuide.MaestroAPI.ResourceTypes.ApplicationDefinition, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs (from rev 5318, sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLayerDefinitionValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,254 @@
+#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 OSGeo.MapGuide.ObjectModels.LayerDefinition;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.ObjectModels.Common;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    /// <summary>
+    /// A base layer definition validator class the provides the common validation logic. Because this is working against
+    /// the layer definition interfaces, this common logic can apply to all versions of the layer definition schema (that
+    /// implement these interfaces)
+    /// </summary>
+    public abstract class BaseLayerDefinitionValidator : IResourceValidator
+    {
+        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
+                return null;
+
+            return ValidateBase(resource, recurse);
+        }
+
+        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
+        {
+            var ldef = resource as ILayerDefinition;
+            var vldef = ldef.SubLayer as IVectorLayerDefinition;
+            var gldef = ldef.SubLayer as IRasterLayerDefinition;
+            var dldef = ldef.SubLayer as IDrawingLayerDefinition;
+
+            List<ValidationIssue> issues = new List<ValidationIssue>();
+
+            if (ldef.SubLayer == null)
+                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_LayerNullError));
+            
+            if (vldef != null)
+            {
+                if (string.IsNullOrEmpty(vldef.FeatureName))
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingFeatureSourceError));
+                if (string.IsNullOrEmpty(vldef.Geometry))
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingGeometryError));
+
+                if (vldef.VectorScaleRange == null || !vldef.HasVectorScaleRanges())
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingScaleRangesError));
+                else
+                {
+                    //Test for overlapping scale ranges
+                    List<KeyValuePair<double, double>> ranges = new List<KeyValuePair<double, double>>();
+                    foreach (IVectorScaleRange vsr in vldef.VectorScaleRange)
+                    {
+                        ranges.Add(new KeyValuePair<double, double>(
+                            vsr.MaxScale.HasValue ? vsr.MaxScale.Value : double.PositiveInfinity,
+                            vsr.MinScale.HasValue ? vsr.MinScale.Value : double.NegativeInfinity));
+                    }
+
+                    double min = double.PositiveInfinity;
+                    double max = double.NegativeInfinity;
+                    foreach (KeyValuePair<double, double> sr in ranges)
+                    {
+                        min = Math.Min(min, sr.Value);
+                        max = Math.Max(max, sr.Key);
+                        if (sr.Key < sr.Value)
+                            issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_MinAndMaxScaleSwappedError, sr.Value, sr.Key)));
+                    }
+
+                    //TODO: Detect gaps in scale ranges
+                    for (int i = 0; i < ranges.Count; i++)
+                        for (int j = i + 1; j < ranges.Count; j++)
+                            if (ranges[i].Key > ranges[j].Value || ranges[i].Value > ranges[j].Value)
+                                issues.Add(new ValidationIssue(resource, ValidationStatus.Information, string.Format(Properties.Resources.LDF_ScaleRangesOverlapInformation, ranges[i].Value, ranges[i].Key, ranges[j].Value, ranges[j].Key)));
+
+                }
+            }
+            else if (gldef != null)
+            {
+                if (gldef.GridScaleRange == null || gldef.GridScaleRange.Count == 0)
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_MissingScaleRangesError));
+                else if (gldef.GridScaleRange.Count != 1)
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_MultipleScaleRangesWarning));
+            }
+            else if (dldef != null)
+            {
+                IDrawingSource dws = null;
+                try
+                {
+                    dws = (IDrawingSource)ldef.CurrentConnection.ResourceService.GetResource(dldef.ResourceId);
+                }
+                catch (Exception)
+                {
+                    issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.LDF_DrawingSourceError));
+                }
+
+                if (dws != null)
+                {
+                    if (Array.IndexOf(ldef.CurrentConnection.Capabilities.SupportedServices, (int)ServiceType.Drawing) >= 0)
+                    {
+                        var dwSvc = (IDrawingService)ldef.CurrentConnection.GetService((int)ServiceType.Drawing);
+
+                        //Check if specified section exists
+                        var shtList = dwSvc.EnumerateDrawingSections(dws.ResourceID);
+                        DrawingSectionListSection sheet = null;
+                        foreach (var sht in shtList.Section)
+                        {
+                            if (sht.Name.Equals(dldef.Sheet))
+                            {
+                                sheet = sht;
+                                break;
+                            }
+                        }
+
+                        if (sheet == null)
+                        {
+                            issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SheetNotFound, dldef.Sheet)));
+                        }
+                        else
+                        {
+                            //null or empty filter means all layers, in that case do nothing
+                            if (!string.IsNullOrEmpty(dldef.LayerFilter))
+                            {
+                                //Check if specified layers all exist in specified section
+                                var specifiedLayers = dldef.LayerFilter.Split(',');
+                                var dwLayers = new Dictionary<string, string>();
+
+                                var shtLayers = dwSvc.EnumerateDrawingLayers(dws.ResourceID, sheet.Name);
+                                foreach (var sl in shtLayers)
+                                {
+                                    dwLayers.Add(sl, sl);
+                                }
+
+                                foreach (var sl in specifiedLayers)
+                                {
+                                    if (!dwLayers.ContainsKey(sl.Trim()))
+                                        issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SheetLayerNotFound, sl.Trim(), sheet.Name)));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                issues.Add(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LDF_UnsupportedLayerTypeWarning));
+            }
+
+            if (recurse)
+            {
+                if (vldef != null || gldef != null)
+                {
+                    //Load referenced feature source
+                    IFeatureSource fs = null;
+
+                    try
+                    {
+                        fs = (IFeatureSource)ldef.CurrentConnection.ResourceService.GetResource(ldef.SubLayer.ResourceId);
+                        issues.AddRange(ResourceValidatorSet.Validate(fs, recurse));
+                    }
+                    catch (Exception)
+                    {
+                        issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_FeatureSourceLoadError)));
+                    }
+
+                    if (fs != null)
+                    {
+                        //Verify specified feature class and geometry check out
+                        try
+                        {
+                            string schema = vldef == null ? gldef.FeatureName : vldef.FeatureName;
+                            string geometry = vldef == null ? gldef.Geometry : vldef.Geometry;
+
+                            bool foundSchema = false;
+                            bool foundGeometry = false;
+
+                            FeatureSourceDescription desc = fs.Describe();
+                            foreach (ClassDefinition scm in desc.Classes)
+                            {
+                                if (scm.QualifiedNameDecoded == schema)
+                                {
+                                    foundSchema = true;
+
+                                    foreach (FeatureSetColumn col in scm.Columns)
+                                    {
+                                        if (col.Name == geometry)
+                                        {
+                                            foundGeometry = true;
+                                            break;
+                                        }
+                                    }
+
+                                    if (vldef != null && vldef.PropertyMapping != null)
+                                    {
+                                        foreach (INameStringPair s in vldef.PropertyMapping)
+                                        {
+                                            bool found = false;
+                                            foreach (FeatureSetColumn col in scm.Columns)
+                                            {
+                                                if (col.Name == s.Name)
+                                                {
+                                                    found = true;
+                                                    break;
+                                                }
+                                            }
+                                            if (!found)
+                                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaMissingError, schema, fs.ResourceID)));
+                                        }
+                                    }
+
+                                    break;
+                                }
+                            }
+
+                            if (!foundSchema)
+                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaMissingError, schema, fs.ResourceID)));
+                            else if (!foundGeometry)
+                                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, string.Format(Properties.Resources.LDF_GeometryMissingError, geometry, schema, fs.ResourceID)));
+                        }
+                        catch (Exception)
+                        {
+                            issues.Add(new ValidationIssue(fs, ValidationStatus.Error, string.Format(Properties.Resources.LDF_SchemaAndColumnReadFailedError)));
+                        }
+                    }
+                }
+            }
+
+            return issues.ToArray();
+        }
+
+        public abstract ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get;
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLoadProcedureValidator.cs (from rev 5318, sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseLoadProcedureValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLoadProcedureValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseLoadProcedureValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.ObjectModels.LoadProcedure;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public abstract class BaseLoadProcedureValidator : IResourceValidator
+    {
+        public abstract ResourceTypeDescriptor SupportedResourceAndVersion { get; }
+
+        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
+                return null;
+
+            return ValidateBase(resource, recurse);
+        }
+
+        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.LoadProcedure)
+                return null;
+
+            if (resource.ResourceVersion != new Version(1, 0, 0))
+                return null;
+
+            var set = new ValidationResultSet();
+
+            var loadProc = (resource as ILoadProcedure).SubType;
+
+            if (loadProc.Type == LoadType.Dwg)
+            {
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_DWGNotSupported));
+                return set.GetAllIssues(); //all she wrote
+            }
+
+            if (loadProc.Type == LoadType.Raster)
+            {
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_RasterNotSupported));
+                return set.GetAllIssues(); //all she wrote
+            }
+
+            if (loadProc.Type == LoadType.Sdf)
+            {
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_Sdf2OptionsNotSupported));
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
+            }
+
+            if (loadProc.Type == LoadType.Shp)
+            {
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_ConvertToSdf3NotSupported));
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
+            }
+
+            if (loadProc.Type == LoadType.Sqlite)
+            {
+                set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, Properties.Resources.LPROC_GeneralizationNotSupported));
+            }
+
+            var fproc = loadProc as IBaseLoadProcedure;
+            if (fproc != null)
+            {
+                foreach (var fn in fproc.SourceFile)
+                {
+                    if (!System.IO.File.Exists(fn))
+                    {
+                        set.AddIssue(new ValidationIssue(resource, ValidationStatus.Warning, string.Format(Properties.Resources.LPROC_SourceFileNotFound, fn)));
+                    }
+                }
+            }
+
+            return set.GetAllIssues();
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseWebLayoutValidator.cs (from rev 5318, sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/BaseWebLayoutValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseWebLayoutValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/BaseWebLayoutValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels.WebLayout;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public abstract class BaseWebLayoutValidator : IResourceValidator
+    {
+        public abstract ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get;
+        }
+
+        public virtual ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (!resource.GetResourceTypeDescriptor().Equals(this.SupportedResourceAndVersion))
+                return null;
+
+            return ValidateBase(resource, recurse);
+        }
+
+        protected static ValidationIssue[] ValidateBase(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != OSGeo.MapGuide.MaestroAPI.ResourceTypes.WebLayout)
+                return null;
+
+            List<ValidationIssue> issues = new List<ValidationIssue>();
+
+            IWebLayout layout = resource as IWebLayout;
+            if (layout.Map == null || layout.Map.ResourceId == null)
+            {
+                issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_MissingMapError)));
+            }
+            else
+            {
+                //Check for duplicate command names
+                var cmdSet = layout.CommandSet;
+                Dictionary<string, ICommand> cmds = new Dictionary<string, ICommand>();
+                foreach (ICommand cmd in cmdSet.Commands)
+                {
+                    if (cmds.ContainsKey(cmd.Name))
+                        issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_DuplicateCommandName, cmd.Name)));
+                    else
+                        cmds[cmd.Name] = cmd;
+                }
+
+                //Check for duplicate property references in search commands
+                foreach (ICommand cmd in cmdSet.Commands)
+                {
+                    if (cmd is ISearchCommand)
+                    {
+                        ISearchCommand search = (ISearchCommand)cmd;
+                        Dictionary<string, string> resColProps = new Dictionary<string, string>();
+                        foreach (IResultColumn resCol in search.ResultColumns.Column)
+                        {
+                            if (resColProps.ContainsKey(resCol.Property))
+                                issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_DuplicateSearchResultColumn, search.Name, resCol.Property)));
+                            else
+                                resColProps.Add(resCol.Property, resCol.Property);
+                        }
+                    }
+                }
+
+                //Check for command references to non-existent commands
+                foreach (IUIItem item in layout.ContextMenu.Items)
+                {
+                    if (item.Function == UIItemFunctionType.Command)
+                    {
+                        ICommandItem cmdRef = (ICommandItem)item;
+                        if (!cmds.ContainsKey(cmdRef.Command))
+                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentMenuCommandReference, cmdRef.Command)));
+                    }
+                }
+
+                foreach (IUIItem item in layout.TaskPane.TaskBar.Items)
+                {
+                    if (item.Function == UIItemFunctionType.Command)
+                    {
+                        ICommandItem cmdRef = (ICommandItem)item;
+                        if (!cmds.ContainsKey(cmdRef.Command))
+                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentTaskPaneCommandReference, cmdRef.Command)));
+                    }
+                }
+
+                foreach (IUIItem item in layout.ToolBar.Items)
+                {
+                    if (item.Function == UIItemFunctionType.Command)
+                    {
+                        ICommandItem cmdRef = (ICommandItem)item;
+                        if (!cmds.ContainsKey(cmdRef.Command))
+                            issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_NonExistentToolbarCommandReference, cmdRef.Command)));
+                    }
+                }
+
+                if (recurse)
+                {
+                    try
+                    {
+                        IMapDefinition mdef = (IMapDefinition)layout.CurrentConnection.ResourceService.GetResource(layout.Map.ResourceId);
+
+                        issues.AddRange(ResourceValidatorSet.Validate(mdef, true));
+
+                        if (layout.Map.InitialView != null)
+                        {
+                            var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MaxX, mdef.Extents.MinY, mdef.Extents.MaxY);
+                            if (!mapEnv.Contains(layout.Map.InitialView.CenterX, layout.Map.InitialView.CenterY))
+                                issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, string.Format(Properties.Resources.WL_StartViewOutsideExtentsWarning)));
+                        }
+
+                    }
+                    catch (Exception ex)
+                    {
+                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                        issues.Add(new ValidationIssue(layout, ValidationStatus.Error, string.Format(Properties.Resources.WL_MapValidationError, layout.Map.ResourceId, msg)));
+                    }
+                }
+            }
+
+            return issues.ToArray();
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/DrawingSourceValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/DrawingSourceValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/DrawingSourceValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/DrawingSourceValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,53 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class DrawingSourceValidator : IResourceValidator
+    {
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.DrawingSource)
+                return null;
+
+            var issues = new List<ValidationIssue>();
+
+            IDrawingSource dws = (IDrawingSource)resource;
+            if (string.IsNullOrEmpty(dws.SourceName))
+                issues.Add(new ValidationIssue(resource, ValidationStatus.Error, Properties.Resources.DS_NoSourceSpecified));
+
+            if (string.IsNullOrEmpty(dws.CoordinateSpace))
+                issues.Add(new ValidationIssue(resource, ValidationStatus.Information, Properties.Resources.DS_NoCoordinateSpace));
+
+            return issues.ToArray();
+        }
+
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(OSGeo.MapGuide.MaestroAPI.ResourceTypes.DrawingSource, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/FeatureSourceValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/FeatureSourceValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,95 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.ObjectModels.Common;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class FeatureSourceValidator : IResourceValidator
+    {
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.FeatureSource)
+                return null;
+
+            List<ValidationIssue> issues = new List<ValidationIssue>();
+
+            IFeatureSource feature = (IFeatureSource)resource;
+            //Note: Must be saved!
+            string s = feature.CurrentConnection.FeatureService.TestConnection(feature.ResourceID);
+            if (s.Trim().ToUpper() != true.ToString().ToUpper())
+                return new ValidationIssue[] { new ValidationIssue(feature, ValidationStatus.Error, Properties.Resources.FS_ConnectionTestFailed) };
+
+            try
+            {
+                System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InvariantCulture;
+                FdoSpatialContextList lst = feature.GetSpatialInfo(false);
+                if (lst == null || lst.SpatialContext == null || lst.SpatialContext.Count == 0)
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Properties.Resources.FS_NoSpatialContextWarning));
+                else
+                    foreach (FdoSpatialContextListSpatialContext c in lst.SpatialContext)
+                        if (c.Extent == null || c.Extent.LowerLeftCoordinate == null || c.Extent.UpperRightCoordinate == null)
+                            issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Properties.Resources.FS_EmptySpatialContextWarning));
+                        else if (double.Parse(c.Extent.LowerLeftCoordinate.X, ci) <= -1000000 && double.Parse(c.Extent.LowerLeftCoordinate.Y, ci) <= -1000000 && double.Parse(c.Extent.UpperRightCoordinate.X, ci) >= 1000000 && double.Parse(c.Extent.UpperRightCoordinate.Y, ci) >= 1000000)
+                            issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Properties.Resources.FS_DefaultSpatialContextWarning));
+            }
+            catch (Exception ex)
+            {
+                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                issues.Add(new ValidationIssue(feature, ValidationStatus.Error, string.Format(Properties.Resources.FS_SpatialContextReadError, msg)));
+            }
+
+            List<string> classes = new List<string>();
+            FeatureSourceDescription fsd = null;
+            try
+            {
+                fsd = feature.Describe();
+                if (fsd == null || fsd.Classes == null || fsd.Classes.Length == 0)
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Warning, Properties.Resources.FS_SchemasMissingWarning));
+            }
+            catch (Exception ex)
+            {
+                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                issues.Add(new ValidationIssue(feature, ValidationStatus.Error, string.Format(Properties.Resources.FS_SchemaReadError, msg)));
+            }
+
+
+            foreach (var cl in fsd.Classes)
+            {
+                string[] ids = cl.GetIdentityProperties();
+                if (ids == null || ids.Length == 0)
+                    issues.Add(new ValidationIssue(feature, ValidationStatus.Information, string.Format(Properties.Resources.FS_PrimaryKeyMissingInformation, cl)));
+            }
+
+            return issues.ToArray();
+        }
+
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(ResourceTypes.FeatureSource, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LayerDefinitionValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/LayerDefinitionValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LayerDefinitionValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LayerDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,37 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.LayerDefinition;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class LayerDefinitionValidator : BaseLayerDefinitionValidator
+    {
+        public override ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(ResourceTypes.LayerDefinition, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LoadProcedureValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/LoadProcedureValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LoadProcedureValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/LoadProcedureValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,35 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.LoadProcedure;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class LoadProcedureValidator : BaseLoadProcedureValidator
+    {
+        public override ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(OSGeo.MapGuide.MaestroAPI.ResourceTypes.LoadProcedure, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/MapDefinitionValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/MapDefinitionValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/MapDefinitionValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/MapDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,164 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels.LayerDefinition;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class MapDefinitionValidator : IResourceValidator
+    {
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.MapDefinition)
+                return null;
+
+            List<ValidationIssue> issues = new List<ValidationIssue>();
+
+            IMapDefinition mdef = resource as IMapDefinition;
+
+            foreach (IMapLayerGroup g in mdef.MapLayerGroup)
+                if (g.ShowInLegend && (g.LegendLabel == null || g.LegendLabel.Trim().Length == 0))
+                    issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, string.Format(Properties.Resources.MDF_GroupMissingLabelInformation, g.Name)));
+                else if (g.ShowInLegend && g.LegendLabel.Trim().ToLower() == "layer group")
+                    issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, string.Format(Properties.Resources.MDF_GroupHasDefaultLabelInformation, g.Name)));
+
+            List<IBaseMapLayer> layers = new List<IBaseMapLayer>();
+            foreach (IBaseMapLayer l in mdef.MapLayer)
+                layers.Add(l);
+
+            if (mdef.BaseMap != null && mdef.BaseMap.HasGroups())
+                foreach (IBaseMapGroup g in mdef.BaseMap.BaseMapLayerGroup)
+                    foreach (IBaseMapLayer l in g.BaseMapLayer)
+                        layers.Add(l);
+
+            Dictionary<string, IBaseMapLayer> nameCounter = new Dictionary<string, IBaseMapLayer>();
+
+            foreach (IBaseMapLayer l in layers)
+            {
+                if (nameCounter.ContainsKey(l.Name))
+                    issues.Add(new ValidationIssue(mdef, ValidationStatus.Warning, string.Format(Properties.Resources.MDF_LayerNameDuplicateWarning, l.Name, l.ResourceId, nameCounter[l.Name].ResourceId)));
+                else
+                    nameCounter.Add(l.Name, l);
+
+                if (l.ShowInLegend && (string.IsNullOrEmpty(l.LegendLabel) || l.LegendLabel.Trim().Length == 0))
+                    issues.Add(new ValidationIssue(mdef, ValidationStatus.Information, string.Format(Properties.Resources.MDF_LayerMissingLabelInformation, l.Name)));
+
+                if (recurse)
+                {
+                    var mapEnv = ObjectFactory.CreateEnvelope(mdef.Extents.MinX, mdef.Extents.MaxX, mdef.Extents.MinY, mdef.Extents.MaxY);
+
+                    try
+                    {
+                        ILayerDefinition layer = null;
+                        IResource res = mdef.CurrentConnection.ResourceService.GetResource(l.ResourceId);
+                        if (!ResourceValidatorSet.HasValidator(res.ResourceType, res.ResourceVersion))
+                        {
+                            //Need to trap the no registered validator message
+                            issues.AddRange(ResourceValidatorSet.Validate(res, true));
+                            continue;
+                        }
+
+                        layer = (ILayerDefinition)res;
+                        issues.AddRange(ResourceValidatorSet.Validate(layer, true));
+
+                        IVectorLayerDefinition vl = null;
+                        if (layer.SubLayer.LayerType == LayerType.Vector)
+                            vl = (IVectorLayerDefinition)layer.SubLayer;
+
+                        if (vl != null)
+                        {
+                            try
+                            {
+                                IFeatureSource fs = (IFeatureSource)layer.CurrentConnection.ResourceService.GetResource(vl.ResourceId);
+                                //The layer recurses on the FeatureSource
+                                //issues.AddRange(Validation.Validate(fs, true));
+
+                                try
+                                {
+                                    FdoSpatialContextList context = fs.GetSpatialInfo(false);
+                                    if (context.SpatialContext == null || context.SpatialContext.Count == 0)
+                                        issues.Add(new ValidationIssue(fs, ValidationStatus.Warning, string.Format(Properties.Resources.MDF_MissingSpatialContextWarning, fs.ResourceID)));
+                                    else
+                                    {
+                                        if (context.SpatialContext.Count > 1)
+                                            issues.Add(new ValidationIssue(fs, ValidationStatus.Information, string.Format(Properties.Resources.MDF_MultipleSpatialContextsInformation, fs.ResourceID)));
+
+
+                                        bool skipGeomCheck = false;
+
+                                        //TODO: Switch to the correct version (2.1), once released
+                                        if (context.SpatialContext[0].CoordinateSystemWkt != mdef.CoordinateSystem)
+                                        {
+                                            if (layer.SubLayer.LayerType == LayerType.Raster && mdef.CurrentConnection.SiteVersion <= SiteVersions.GetVersion(OSGeo.MapGuide.MaestroAPI.KnownSiteVersions.MapGuideOS2_0_2))
+                                                issues.Add(new ValidationIssue(fs, ValidationStatus.Error, string.Format(Properties.Resources.MDF_RasterReprojectionError, fs.ResourceID)));
+                                            else
+                                                issues.Add(new ValidationIssue(fs, ValidationStatus.Warning, string.Format(Properties.Resources.MDF_DataReprojectionWarning, fs.ResourceID)));
+
+                                            skipGeomCheck = true;
+                                        }
+
+                                        if (vl.Geometry != null && !skipGeomCheck)
+                                        {
+                                            var env = fs.GetSpatialExtent(vl.FeatureName, vl.Geometry);
+                                            if (!env.Intersects(mapEnv))
+                                                issues.Add(new ValidationIssue(fs, ValidationStatus.Warning, string.Format(Properties.Resources.MDF_DataOutsideMapWarning, fs.ResourceID)));
+                                        }
+                                    }
+                                }
+                                catch (Exception ex)
+                                {
+                                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                                    issues.Add(new ValidationIssue(layer, ValidationStatus.Error, string.Format(Properties.Resources.MDF_ResourceReadError, fs.ResourceID, msg)));
+                                }
+                            }
+                            catch (Exception ex)
+                            {
+                                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                                issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, string.Format(Properties.Resources.MDF_FeatureSourceReadError, l.ResourceId, msg)));
+                            }
+                        }
+
+                    }
+                    catch (Exception ex)
+                    {
+                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                        issues.Add(new ValidationIssue(mdef, ValidationStatus.Error, string.Format(Properties.Resources.MDF_LayerReadError, l.ResourceId, msg)));
+                    }
+                }
+            }
+
+            return issues.ToArray();
+        }
+
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(ResourceTypes.MapDefinition, "1.0.0"); }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/PrintLayoutValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/PrintLayoutValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/PrintLayoutValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/PrintLayoutValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,46 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.PrintLayout;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class PrintLayoutValidator : IResourceValidator
+    {
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return ResourceTypeDescriptor.PrintLayout; }
+        }
+
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.PrintLayout)
+                return null;
+
+            //TODO: What problems could there possibly be?
+
+            return new ValidationIssue[0];
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorLoader.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/ResourceValidatorLoader.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorLoader.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorLoader.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,53 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    /// <summary>
+    /// Utility class that initializes the default set of resource validators
+    /// </summary>
+    public static class ResourceValidatorLoader
+    {
+        private static bool m_initialized = false;
+
+        public static void LoadStockValidators()
+        {
+            if (m_initialized)
+                return;
+
+            ResourceValidatorSet.RegisterValidator(new DrawingSourceValidator());
+            ResourceValidatorSet.RegisterValidator(new FeatureSourceValidator());
+            ResourceValidatorSet.RegisterValidator(new LayerDefinitionValidator());
+            ResourceValidatorSet.RegisterValidator(new MapDefinitionValidator());
+            ResourceValidatorSet.RegisterValidator(new WebLayoutValidator());
+            ResourceValidatorSet.RegisterValidator(new ApplicationDefinitionValidator());
+            ResourceValidatorSet.RegisterValidator(new LoadProcedureValidator());
+            ResourceValidatorSet.RegisterValidator(new SymbolDefinitionValidator());
+            ResourceValidatorSet.RegisterValidator(new SymbolLibraryValidator());
+            ResourceValidatorSet.RegisterValidator(new PrintLayoutValidator());
+
+            m_initialized = true;
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs (from rev 5318, sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ResourceValidatorSet.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ResourceValidatorSet.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,98 @@
+#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 OSGeo.MapGuide.MaestroAPI.Exceptions;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    /// <summary>
+    /// A collection of resource validators
+    /// </summary>
+    public static class ResourceValidatorSet
+    {
+        private static List<IResourceValidator> m_validators = new List<IResourceValidator>();
+
+        public static void RegisterValidator(IResourceValidator validator)
+        {
+            Check.NotNull(validator, "validator");
+
+            if (!m_validators.Contains(validator))
+                m_validators.Add(validator);
+        }
+
+        public static ValidationIssue[] Validate(IEnumerable<IResource> items, bool recurse)
+        {
+            Check.NotNull(items, "items");
+
+            var issues = new List<ValidationIssue>();
+            foreach (var item in items)
+            {
+                issues.AddRange(Validate(item, true));
+            }
+            return issues.ToArray();
+        }
+
+        public static ValidationIssue[] Validate(IResource item, bool recurse)
+        {
+            Check.NotNull(item, "item");
+
+            var issueSet = new ValidationResultSet();
+            if (!HasValidator(item.ResourceType, item.ResourceVersion))
+            {
+                issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Warning, string.Format(Properties.Resources.ERR_NO_REGISTERED_VALIDATOR, item.ResourceType, item.ResourceVersion)));
+            }
+            else
+            {
+                foreach (IResourceValidator v in m_validators)
+                {
+                    try
+                    {
+                        ValidationIssue[] tmp = v.Validate(item, recurse);
+                        if (tmp != null)
+                            issueSet.AddIssues(tmp);
+                    }
+                    catch (Exception ex)
+                    {
+                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                        issueSet.AddIssue(new ValidationIssue(item, ValidationStatus.Error, "Failed in validator: " + msg));
+                    }
+                }
+            }
+            return issueSet.GetAllIssues();
+        }
+
+        public static bool HasValidator(ResourceTypes resourceTypes, Version version)
+        {
+            bool found = false;
+            var find = new ResourceTypeDescriptor(resourceTypes, version.ToString());
+            foreach (var v in m_validators)
+            {
+                if (v.SupportedResourceAndVersion.Equals(find))
+                {
+                    found = true;
+                    break;
+                }
+            }
+            return found;
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolDefinitionValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/SymbolDefinitionValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolDefinitionValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolDefinitionValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,45 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class SymbolDefinitionValidator : IResourceValidator
+    {
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return ResourceTypeDescriptor.SymbolDefinition; }
+        }
+
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.SymbolDefinition)
+                return null;
+
+            //TODO: What problems could there possibly be?
+
+            return new ValidationIssue[0];
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolLibraryValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/SymbolLibraryValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolLibraryValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/SymbolLibraryValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,45 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class SymbolLibraryValidator : IResourceValidator
+    {
+        public ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return ResourceTypeDescriptor.SymbolLibrary; }
+        }
+
+        public ValidationIssue[] Validate(IResource resource, bool recurse)
+        {
+            if (resource.ResourceType != ResourceTypes.SymbolLibrary)
+                return null;
+
+            //TODO: What problems could there possibly be?
+
+            return new ValidationIssue[0];
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs (from rev 5318, sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,107 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    /// <summary>
+    /// A "bucket" class that filters out redundant validation messages
+    /// </summary>
+    public class ValidationResultSet
+    {
+        //HACK: Abusing the Key component of Dictionary<K, V> because there is no
+        //Set<T> collection in .net fx 2.0!
+        private Dictionary<string, Dictionary<ValidationIssue, ValidationIssue>> _issues;
+
+        public ValidationResultSet()
+        {
+            _issues = new Dictionary<string, Dictionary<ValidationIssue, ValidationIssue>>();
+        }
+
+        public ValidationResultSet(IEnumerable<ValidationIssue> issues) : this()
+        {
+            Check.NotNull(issues, "issues");
+
+            AddIssues(issues);
+        }
+
+        public string[] ResourceIDs
+        {
+            get { return new List<string>(_issues.Keys).ToArray(); }
+        }
+
+        public ICollection<ValidationIssue> GetIssuesForResource(string resourceId)
+        {
+            Check.NotEmpty(resourceId, "resourceId");
+
+            if (_issues.ContainsKey(resourceId))
+                return _issues[resourceId].Keys;
+            return new List<ValidationIssue>();
+        }
+
+        public ICollection<ValidationIssue> GetIssuesForResource(string resourceId, ValidationStatus statType)
+        {
+            var issues = new List<ValidationIssue>();
+            foreach (var issue in GetIssuesForResource(resourceId))
+            {
+                if (issue.Status == statType)
+                    issues.Add(issue);
+            }
+            return issues;
+        }
+
+        public ValidationIssue[] GetAllIssues()
+        {
+            var issues = new List<ValidationIssue>();
+            foreach (string resId in _issues.Keys)
+            {
+                issues.AddRange(_issues[resId].Keys);
+            }
+            return issues.ToArray();
+        }
+
+        public void AddIssue(ValidationIssue issue)
+        {
+            Check.NotNull(issue, "issue");
+            Check.NotNull(issue.Resource, "issue.Resource");
+            Check.NotEmpty(issue.Resource.ResourceID, "issue.Resource.ResourceID");
+
+            if (!_issues.ContainsKey(issue.Resource.ResourceID))
+                _issues[issue.Resource.ResourceID] = new Dictionary<ValidationIssue, ValidationIssue>();
+
+            _issues[issue.Resource.ResourceID][issue] = issue;
+        }
+
+        public void AddIssues(IEnumerable<ValidationIssue> issues)
+        {
+            if (issues == null)
+                return;
+
+            foreach (var issue in issues)
+            {
+                AddIssue(issue);
+            }
+        }
+    }
+}

Copied: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/WebLayoutValidator.cs (from rev 5318, sandbox/maestro-3.0/Maestro.ResourceValidation/WebLayoutValidator.cs)
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/WebLayoutValidator.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/Validation/WebLayoutValidator.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -0,0 +1,39 @@
+#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 OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.WebLayout;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.MaestroAPI.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+
+namespace OSGeo.MapGuide.MaestroAPI.Resource.Validation
+{
+    public class WebLayoutValidator : BaseWebLayoutValidator
+    {
+        public override ResourceTypeDescriptor SupportedResourceAndVersion
+        {
+            get { return new ResourceTypeDescriptor(OSGeo.MapGuide.MaestroAPI.ResourceTypes.WebLayout, "1.0.0"); }
+        }
+    }
+}

Deleted: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs	2010-10-21 14:49:18 UTC (rev 5318)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Resource/ValidationResultSet.cs	2010-10-22 07:01:32 UTC (rev 5319)
@@ -1,107 +0,0 @@
-#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 OSGeo.MapGuide.MaestroAPI.Resource;
-using OSGeo.MapGuide.MaestroAPI;
-
-namespace OSGeo.MapGuide.MaestroAPI.Resource
-{
-    /// <summary>
-    /// A "bucket" class that filters out redundant validation messages
-    /// </summary>
-    public class ValidationResultSet
-    {
-        //HACK: Abusing the Key component of Dictionary<K, V> because there is no
-        //Set<T> collection in .net fx 2.0!
-        private Dictionary<string, Dictionary<ValidationIssue, ValidationIssue>> _issues;
-
-        public ValidationResultSet()
-        {
-            _issues = new Dictionary<string, Dictionary<ValidationIssue, ValidationIssue>>();
-        }
-
-        public ValidationResultSet(IEnumerable<ValidationIssue> issues) : this()
-        {
-            Check.NotNull(issues, "issues");
-
-            AddIssues(issues);
-        }
-
-        public string[] ResourceIDs
-        {
-            get { return new List<string>(_issues.Keys).ToArray(); }
-        }
-
-        public ICollection<ValidationIssue> GetIssuesForResource(string resourceId)
-        {
-            Check.NotEmpty(resourceId, "resourceId");
-
-            if (_issues.ContainsKey(resourceId))
-                return _issues[resourceId].Keys;
-            return new List<ValidationIssue>();
-        }
-
-        public ICollection<ValidationIssue> GetIssuesForResource(string resourceId, ValidationStatus statType)
-        {
-            var issues = new List<ValidationIssue>();
-            foreach (var issue in GetIssuesForResource(resourceId))
-            {
-                if (issue.Status == statType)
-                    issues.Add(issue);
-            }
-            return issues;
-        }
-
-        public ValidationIssue[] GetAllIssues()
-        {
-            var issues = new List<ValidationIssue>();
-            foreach (string resId in _issues.Keys)
-            {
-                issues.AddRange(_issues[resId].Keys);
-            }
-            return issues.ToArray();
-        }
-
-        public void AddIssue(ValidationIssue issue)
-        {
-            Check.NotNull(issue, "issue");
-            Check.NotNull(issue.Resource, "issue.Resource");
-            Check.NotEmpty(issue.Resource.ResourceID, "issue.Resource.ResourceID");
-
-            if (!_issues.ContainsKey(issue.Resource.ResourceID))
-                _issues[issue.Resource.ResourceID] = new Dictionary<ValidationIssue, ValidationIssue>();
-
-            _issues[issue.Resource.ResourceID][issue] = issue;
-        }
-
-        public void AddIssues(IEnumerable<ValidationIssue> issues)
-        {
-            if (issues == null)
-                return;
-
-            foreach (var issue in issues)
-            {
-                AddIssue(issue);
-            }
-        }
-    }
-}



More information about the mapguide-commits mailing list