[mapguide-commits] r5208 - in sandbox/maestro-3.0: . Maestro Maestro.Base Maestro.Base/Commands Maestro.Base/UI Maestro.Editors Maestro.Editors/Properties Maestro.Packaging Maestro.Packaging/Properties MaestroAPITests OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Capability OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI.Http

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Sep 29 03:53:06 EDT 2010


Author: jng
Date: 2010-09-29 07:53:06 +0000 (Wed, 29 Sep 2010)
New Revision: 5208

Added:
   sandbox/maestro-3.0/Maestro.Base/Commands/CreatePackageCommand.cs
   sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs
   sandbox/maestro-3.0/Maestro.Packaging/
   sandbox/maestro-3.0/Maestro.Packaging/Maestro.Packaging.csproj
   sandbox/maestro-3.0/Maestro.Packaging/PackageBuilder.cs
   sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.cs
   sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.designer.cs
   sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.resx
   sandbox/maestro-3.0/Maestro.Packaging/Properties/
   sandbox/maestro-3.0/Maestro.Packaging/Properties/AssemblyInfo.cs
   sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.resx
   sandbox/maestro-3.0/Maestro.Packaging/ResourceDataItem.cs
   sandbox/maestro-3.0/Maestro.Packaging/ResourceItem.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ResourcePackageManifest.cs
Removed:
   sandbox/maestro-3.0/Maestro.Base/Commands/Toggle/
Modified:
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
   sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
   sandbox/maestro-3.0/Maestro.Base/UI/OutboundRequestViewer.cs
   sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj
   sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.Designer.cs
   sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.resx
   sandbox/maestro-3.0/Maestro/Maestro.sln
   sandbox/maestro-3.0/MaestroAPITests/CapabilityTests.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpCapabilities.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Capability/ConnectionCapabilities.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IConnectionCapabilities.cs
   sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
Log:
More sandbox changes
 - Fix NRE on Outbound Request Viewer when starting up and not connected.
 - Add IsSupportedResourceType() capability API to determine whether a given resource type is supported
 - Update unit tests to exercise this API
 - Forward-port packaging APIs from 2.x stream


Modified: sandbox/maestro-3.0/Maestro/Maestro.sln
===================================================================
--- sandbox/maestro-3.0/Maestro/Maestro.sln	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro/Maestro.sln	2010-09-29 07:53:06 UTC (rev 5208)
@@ -50,6 +50,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maestro.AddIn.LayerDefinition-1.3.0", "..\Maestro.AddIn.LayerDefinition-1.3.0\Maestro.AddIn.LayerDefinition-1.3.0.csproj", "{A49487F7-FCDD-4818-8C7E-2CADABA51B06}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maestro.Packaging", "..\Maestro.Packaging\Maestro.Packaging.csproj", "{0EA33E36-9C33-4D60-B378-B87FADAA0F40}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -148,6 +150,10 @@
 		{A49487F7-FCDD-4818-8C7E-2CADABA51B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{A49487F7-FCDD-4818-8C7E-2CADABA51B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{A49487F7-FCDD-4818-8C7E-2CADABA51B06}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0EA33E36-9C33-4D60-B378-B87FADAA0F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0EA33E36-9C33-4D60-B378-B87FADAA0F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0EA33E36-9C33-4D60-B378-B87FADAA0F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0EA33E36-9C33-4D60-B378-B87FADAA0F40}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

Added: sandbox/maestro-3.0/Maestro.Base/Commands/CreatePackageCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/CreatePackageCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/CreatePackageCommand.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ICSharpCode.Core;
+
+namespace Maestro.Base.Commands
+{
+    internal class CreatePackageCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Base/Commands/LoadPackageCommand.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ICSharpCode.Core;
+
+namespace Maestro.Base.Commands
+{
+    internal class LoadPackageCommand : AbstractMenuCommand
+    {
+        public override void Run()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.addin	2010-09-29 07:53:06 UTC (rev 5208)
@@ -119,15 +119,6 @@
                       icon="application_task"
                       class="Maestro.Base.Commands.NotImplementedCommand"/>
         </MenuItem>
-        <MenuItem id="Menu_View"
-                  type="Menu"
-                  label="${res:Menu_View}">
-            <MenuItem id="Menu_View_MessageLog"
-                      icon="reports_stack"
-                      label="${res:Menu_View_MessageLog}"
-                      type="CheckBox"
-                      class="Maestro.Base.Commands.Toggle.ToggleMessagesCommand" />
-        </MenuItem>
         <MenuItem id="Menu_Help"
                   type="Menu"
                   label="${res:Menu_Help}">
@@ -252,7 +243,7 @@
             <Condition action="Disable" name="SelectedItem">
                 <ToolbarItem id="DeleteItem"
                              icon="cross_script"
-                             class="Maestro.Base.Commands.NotImplementedCommand" />
+                             class="Maestro.Base.Commands.SiteExplorer.DeleteSelectedItemsCommand" />
             </Condition>
             <ToolbarItem id="SiteExplorer_Refresh"
                          icon="arrow-circle-045-left"
@@ -282,10 +273,10 @@
             <MenuItem type="Separator" />
             <MenuItem id="CreatePackage"
                       label="${res:SiteExplorer_SelectedFolder_CreatePackage}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.CreatePackageCommand" />
             <MenuItem id="LoadPackage"
                       label="${res:SiteExplorer_SelectedFolder_LoadPackage}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.LoadPackageCommand" />
             <MenuItem type="Separator" />
             <Condition action="Disable" name="IsNotRoot">
                 <MenuItem id="Copy"
@@ -315,7 +306,7 @@
         <Condition action="Disable" name="MultipleSelected">
             <MenuItem id="CreatePackage"
                       label="${res:SiteExplorer_SelectedFolder_CreatePackage}"
-                      class="Maestro.Base.Commands.NotImplementedCommand" />
+                      class="Maestro.Base.Commands.CreatePackageCommand" />
             <MenuItem id="Delete"
                       label="${res:SiteExplorer_SelectedItem_Delete}"
                       class="Maestro.Base.Commands.SiteExplorer.DeleteSelectedItemsCommand" />
@@ -401,7 +392,7 @@
             <MenuItem type="Separator" />
             <MenuItem id="CreatePackage"
                      label="${res:SiteExplorer_SelectedFolder_CreatePackage}"
-                     class="Maestro.Base.Commands.NotImplementedCommand" />
+                     class="Maestro.Base.Commands.CreatePackageCommand" />
             <MenuItem type="Separator" />
             <MenuItem id="Copy"
                       label="${res:SiteExplorer_SelectedItem_Copy}"

Modified: sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Base/Maestro.Base.csproj	2010-09-29 07:53:06 UTC (rev 5208)
@@ -50,7 +50,9 @@
     <Compile Include="Commands\Conditions\SelectedItemConditionEvaluator.cs" />
     <Compile Include="Commands\Conditions\SelectedRootItemConditionEvaluator.cs" />
     <Compile Include="Commands\CopyCommand.cs" />
+    <Compile Include="Commands\CreatePackageCommand.cs" />
     <Compile Include="Commands\CutCommand.cs" />
+    <Compile Include="Commands\LoadPackageCommand.cs" />
     <Compile Include="Commands\LoginCommand.cs" />
     <Compile Include="Commands\LogoutCommand.cs" />
     <Compile Include="Commands\NewItemCommand.cs" />
@@ -77,7 +79,6 @@
     <Compile Include="Commands\Test\OpenSymbolBrowserCommand.cs" />
     <Compile Include="Commands\Test\OpenUnmanagedResourceCommand.cs" />
     <Compile Include="Commands\Test\SelectFdoProviderCommand.cs" />
-    <Compile Include="Commands\Toggle\ToggleMessagesCommand.cs" />
     <Compile Include="Commands\ValidateResourceCommand.cs" />
     <Compile Include="Commands\XmlEditCommand.cs" />
     <Compile Include="Editor\DrawingSourceEditor.cs">

Modified: sandbox/maestro-3.0/Maestro.Base/UI/OutboundRequestViewer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Base/UI/OutboundRequestViewer.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Base/UI/OutboundRequestViewer.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -46,10 +46,12 @@
             //TODO: Re-evaluate design when we decide to support multiple site connections
             var wb = Workbench.Instance;
             var exp = wb.ActiveSiteExplorer;
-
-            var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
-            var conn = connMgr.GetConnection(exp.ConnectionName);
-            conn.RequestDispatched += new OSGeo.MapGuide.MaestroAPI.RequestEventHandler(OnRequestDispatched);
+            if (exp != null)
+            {
+                var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
+                var conn = connMgr.GetConnection(exp.ConnectionName);
+                conn.RequestDispatched += new OSGeo.MapGuide.MaestroAPI.RequestEventHandler(OnRequestDispatched);
+            }
         }
 
         void OnRequestDispatched(object sender, OSGeo.MapGuide.MaestroAPI.RequestEventArgs e)

Modified: sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Editors/Maestro.Editors.csproj	2010-09-29 07:53:06 UTC (rev 5208)
@@ -35,6 +35,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\Thirdparty\TreeViewAdv\Aga.Controls\obj\Debug\Aga.Controls.dll</HintPath>
     </Reference>
+    <Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Thirdparty\SharpZipLib\ICSharpCode.SharpZipLib.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Design" />
@@ -821,6 +825,10 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\Maestro.Packaging\Maestro.Packaging.csproj">
+      <Project>{0EA33E36-9C33-4D60-B378-B87FADAA0F40}</Project>
+      <Name>Maestro.Packaging</Name>
+    </ProjectReference>
     <ProjectReference Include="..\Maestro.Shared.UI\Maestro.Shared.UI.csproj">
       <Project>{CFD19053-2172-41D3-8460-0FD2123A1E88}</Project>
       <Name>Maestro.Shared.UI</Name>

Modified: sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.Designer.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.Designer.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -60,6 +60,24 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to All types.
+        /// </summary>
+        internal static string AllResourceTypes {
+            get {
+                return ResourceManager.GetString("AllResourceTypes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to You must enter a alternate name, or remove the checkmark.
+        /// </summary>
+        internal static string AlternateNameMissing {
+            get {
+                return ResourceManager.GetString("AlternateNameMissing", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap application__arrow {
             get {
                 object obj = ResourceManager.GetObject("application--arrow", resourceCulture);
@@ -246,6 +264,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to The content file does not exist.
+        /// </summary>
+        internal static string ContentFileMissing {
+            get {
+                return ResourceManager.GetString("ContentFileMissing", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap control {
             get {
                 object obj = ResourceManager.GetObject("control", resourceCulture);
@@ -314,6 +341,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Do you want to remove the selected item?.
+        /// </summary>
+        internal static string DeleteConfirmation {
+            get {
+                return ResourceManager.GetString("DeleteConfirmation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Diverging.
         /// </summary>
         internal static string DivergingName {
@@ -406,6 +442,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to An error occured while copying file: {0}.
+        /// </summary>
+        internal static string FileCopyError {
+            get {
+                return ResourceManager.GetString("FileCopyError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to File Downloaded.
         /// </summary>
         internal static string FileDownloaded {
@@ -415,6 +460,42 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Failed to validate the filenames: {0}.
+        /// </summary>
+        internal static string FilenameValidationError {
+            get {
+                return ResourceManager.GetString("FilenameValidationError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to All files ({0}).
+        /// </summary>
+        internal static string FiletypeAll {
+            get {
+                return ResourceManager.GetString("FiletypeAll", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to MapGuide Packages ({0}).
+        /// </summary>
+        internal static string FiletypeMGP {
+            get {
+                return ResourceManager.GetString("FiletypeMGP", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Zip files ({0}).
+        /// </summary>
+        internal static string FiletypeZip {
+            get {
+                return ResourceManager.GetString("FiletypeZip", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to All File Types (*.*)|*.*.
         /// </summary>
         internal static string FilterAll {
@@ -499,6 +580,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to The folder must start with \&quot;Library://\&quot;, do you want the starting folder to become:\n {0} ?.
+        /// </summary>
+        internal static string FolderMissingPrefix {
+            get {
+                return ResourceManager.GetString("FolderMissingPrefix", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Cannot Preview Font &quot;{0}&quot;.
         /// </summary>
         internal static string FontPreviewError {
@@ -608,6 +698,15 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to The header file does not exist.
+        /// </summary>
+        internal static string HeaderFileMissing {
+            get {
+                return ResourceManager.GetString("HeaderFileMissing", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap icon_back {
             get {
                 object obj = ResourceManager.GetObject("icon_back", resourceCulture);
@@ -1195,6 +1294,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to An error occured while validating the restore path: {0}\nIt should have the format: \&quot;Libray://folder/folder/\&quot;..
+        /// </summary>
+        internal static string InvalidRestorePathError {
+            get {
+                return ResourceManager.GetString("InvalidRestorePathError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Invalid value.
         /// </summary>
         internal static string InvalidValueError {
@@ -1323,6 +1431,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to New folder.
+        /// </summary>
+        internal static string NewFolder {
+            get {
+                return ResourceManager.GetString("NewFolder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to No values found in selected column.
         /// </summary>
         internal static string NoColumnValuesError {
@@ -1332,6 +1449,35 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to You have not selected a starting folder, do you want to back up the entire site?.
+        /// </summary>
+        internal static string NoFolderSelected {
+            get {
+                return ResourceManager.GetString("NoFolderSelected", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to You have selected to restore the package at another location, but not entered one.
+        ///This will cause the package to be restored a the root of the resource tree.
+        ///Are you sure this is what you want?.
+        /// </summary>
+        internal static string NoRestorePathWarning {
+            get {
+                return ResourceManager.GetString("NoRestorePathWarning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to You must select at least one type.
+        /// </summary>
+        internal static string NoTypesSelected {
+            get {
+                return ResourceManager.GetString("NoTypesSelected", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Operation Cancelled.
         /// </summary>
         internal static string OperationCancelled {
@@ -1349,6 +1495,42 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to You must enter a full path to the output file.
+        /// </summary>
+        internal static string OutputFileMissing {
+            get {
+                return ResourceManager.GetString("OutputFileMissing", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occured while building package: {0}.
+        /// </summary>
+        internal static string PackageBuildError {
+            get {
+                return ResourceManager.GetString("PackageBuildError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to create package, error message: {0}.
+        /// </summary>
+        internal static string PackageCreationFailedError {
+            get {
+                return ResourceManager.GetString("PackageCreationFailedError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to read package. Error message was: {0}.
+        /// </summary>
+        internal static string PackageReadError {
+            get {
+                return ResourceManager.GetString("PackageReadError", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap plus_circle {
             get {
                 object obj = ResourceManager.GetObject("plus-circle", resourceCulture);
@@ -1398,6 +1580,18 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to You have selected to restore the package at the root.
+        ///You have also selected to delete the target before restoring.
+        ///This will result in the entire repository being deleted and replaced with this package.
+        ///Are you absolutely sure that is what you want?.
+        /// </summary>
+        internal static string RepositoryWipeWarning {
+            get {
+                return ResourceManager.GetString("RepositoryWipeWarning", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap ruler {
             get {
                 object obj = ResourceManager.GetObject("ruler", resourceCulture);
@@ -1438,6 +1632,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Select the package file to edit.
+        /// </summary>
+        internal static string SelectPackageFile {
+            get {
+                return ResourceManager.GetString("SelectPackageFile", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Sequential.
         /// </summary>
         internal static string SequentialName {
@@ -1619,6 +1822,24 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Unknown types.
+        /// </summary>
+        internal static string UnknownResourceTypes {
+            get {
+                return ResourceManager.GetString("UnknownResourceTypes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occured while validating the output file path: {0}.
+        /// </summary>
+        internal static string ValidateOutputfileError {
+            get {
+                return ResourceManager.GetString("ValidateOutputfileError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Document is valid.
         /// </summary>
         internal static string XmlDocIsValid {

Modified: sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.resx	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/Maestro.Editors/Properties/Resources.resx	2010-09-29 07:53:06 UTC (rev 5208)
@@ -769,4 +769,105 @@
   <data name="FilterShp" xml:space="preserve">
     <value>ESRI Shape File (*.shp)|*.*</value>
   </data>
+  <data name="AllResourceTypes" xml:space="preserve">
+    <value>All types</value>
+    <comment>The list entry that represents all resource types</comment>
+  </data>
+  <data name="AlternateNameMissing" xml:space="preserve">
+    <value>You must enter a alternate name, or remove the checkmark</value>
+    <comment>A message displayed when the user has not entered an alternate name for a resource</comment>
+  </data>
+  <data name="ContentFileMissing" xml:space="preserve">
+    <value>The content file does not exist</value>
+    <comment>A message displayed when the user selects a non-existing file</comment>
+  </data>
+  <data name="DeleteConfirmation" xml:space="preserve">
+    <value>Do you want to remove the selected item?</value>
+    <comment>A confirmation message displayed when deleting a resource</comment>
+  </data>
+  <data name="FileCopyError" xml:space="preserve">
+    <value>An error occured while copying file: {0}</value>
+    <comment>A message displayed when a file copy fails</comment>
+  </data>
+  <data name="FilenameValidationError" xml:space="preserve">
+    <value>Failed to validate the filenames: {0}</value>
+    <comment>A message displayed when the user enters an invalid filename</comment>
+  </data>
+  <data name="FiletypeAll" xml:space="preserve">
+    <value>All files ({0})</value>
+    <comment>The text displayed when browsing for all file types</comment>
+  </data>
+  <data name="FiletypeMGP" xml:space="preserve">
+    <value>MapGuide Packages ({0})</value>
+    <comment>The text displayed when browsing for MGP files</comment>
+  </data>
+  <data name="FiletypeZip" xml:space="preserve">
+    <value>Zip files ({0})</value>
+    <comment>The text displayed when browsing for zip files</comment>
+  </data>
+  <data name="FolderMissingPrefix" xml:space="preserve">
+    <value>The folder must start with \"Library://\", do you want the starting folder to become:\n {0} ?</value>
+    <comment>A message that is displayed when the user has not entered a folder starting with Library://</comment>
+  </data>
+  <data name="HeaderFileMissing" xml:space="preserve">
+    <value>The header file does not exist</value>
+    <comment>A message displayed when the user selects a non-existing file</comment>
+  </data>
+  <data name="InvalidRestorePathError" xml:space="preserve">
+    <value>An error occured while validating the restore path: {0}\nIt should have the format: \"Libray://folder/folder/\".</value>
+    <comment>A message that is displayed when the restore path does not validate</comment>
+  </data>
+  <data name="NewFolder" xml:space="preserve">
+    <value>New folder</value>
+    <comment>The default name of a new folder</comment>
+  </data>
+  <data name="NoFolderSelected" xml:space="preserve">
+    <value>You have not selected a starting folder, do you want to back up the entire site?</value>
+    <comment>A message that is displayed when the user has not selected a folder to create  a folder from</comment>
+  </data>
+  <data name="NoRestorePathWarning" xml:space="preserve">
+    <value>You have selected to restore the package at another location, but not entered one.
+This will cause the package to be restored a the root of the resource tree.
+Are you sure this is what you want?</value>
+    <comment>A message displayed when the user has not entered a restore path</comment>
+  </data>
+  <data name="NoTypesSelected" xml:space="preserve">
+    <value>You must select at least one type</value>
+    <comment>A message that is displayed when the user has not selected any resource types</comment>
+  </data>
+  <data name="OutputFileMissing" xml:space="preserve">
+    <value>You must enter a full path to the output file</value>
+    <comment>A message that is displayed when the user has not entered an output file</comment>
+  </data>
+  <data name="PackageBuildError" xml:space="preserve">
+    <value>An error occured while building package: {0}</value>
+    <comment>A message displayed when the package creation fails</comment>
+  </data>
+  <data name="PackageCreationFailedError" xml:space="preserve">
+    <value>Failed to create package, error message: {0}</value>
+    <comment>A message displayed when the package creation fails</comment>
+  </data>
+  <data name="PackageReadError" xml:space="preserve">
+    <value>Failed to read package. Error message was: {0}</value>
+    <comment>A message displayed when the package could not be read</comment>
+  </data>
+  <data name="RepositoryWipeWarning" xml:space="preserve">
+    <value>You have selected to restore the package at the root.
+You have also selected to delete the target before restoring.
+This will result in the entire repository being deleted and replaced with this package.
+Are you absolutely sure that is what you want?</value>
+    <comment>A confirmation message displayed to the user, when creating a package that will completely wipe a repository</comment>
+  </data>
+  <data name="SelectPackageFile" xml:space="preserve">
+    <value>Select the package file to edit</value>
+    <comment>The title of the dialog that the is used to pick the package file to edit</comment>
+  </data>
+  <data name="UnknownResourceTypes" xml:space="preserve">
+    <value>Unknown types</value>
+    <comment>The list entry that represents unknown resource types</comment>
+  </data>
+  <data name="ValidateOutputfileError" xml:space="preserve">
+    <value>An error occured while validating the output file path: {0}</value>
+    <comment>A message that is displayed to the user when the output path is invalid</comment>
+  </data>
 </root>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/Maestro.Packaging.csproj
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/Maestro.Packaging.csproj	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/Maestro.Packaging.csproj	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0EA33E36-9C33-4D60-B378-B87FADAA0F40}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Maestro.Packaging</RootNamespace>
+    <AssemblyName>Maestro.Packaging</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkSubset>
+    </TargetFrameworkSubset>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Thirdparty\SharpZipLib\ICSharpCode.SharpZipLib.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="PackageBuilder.cs" />
+    <Compile Include="PackageProgress.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="PackageProgress.designer.cs">
+      <DependentUpon>PackageProgress.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="ResourceDataItem.cs" />
+    <Compile Include="ResourceItem.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="PackageProgress.resx">
+      <DependentUpon>PackageProgress.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Maestro.Shared.UI\Maestro.Shared.UI.csproj">
+      <Project>{CFD19053-2172-41D3-8460-0FD2123A1E88}</Project>
+      <Name>Maestro.Shared.UI</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI\OSGeo.MapGuide.MaestroAPI.csproj">
+      <Project>{80FA3158-8B5F-48D1-A393-0378AFE48A7E}</Project>
+      <Name>OSGeo.MapGuide.MaestroAPI</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/PackageBuilder.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/PackageBuilder.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/PackageBuilder.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,923 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+
+namespace Maestro.Packaging
+{
+    /// <summary>
+    /// Enumeration used to signal the type of operation currently running
+    /// </summary>
+    public enum ProgressType
+    {
+        /// <summary>
+        /// The file list is being fetched from MapGuide
+        /// </summary>
+        ReadingFileList,
+        /// <summary>
+        /// Files are downloaded in temporary folder
+        /// </summary>
+        PreparingFolder,
+        /// <summary>
+        /// Resource references are updated to use the new folder
+        /// </summary>
+        MovingResources,
+        /// <summary>
+        /// The files are being compressed
+        /// </summary>
+        Compressing,
+        /// <summary>
+        /// The package opertion has completed
+        /// </summary>
+        Done,
+        /// <summary>
+        /// The package is being uploaded
+        /// </summary>
+        Uploading,
+        /// <summary>
+        /// Extracting filenames from package
+        /// </summary>
+        ListingFiles
+    }
+
+    /// <summary>
+    /// Defines the type of entry
+    /// </summary>
+    public enum EntryTypeEnum
+    {
+        /// <summary>
+        /// The item already exists in the package
+        /// </summary>
+        Regular,
+        /// <summary>
+        /// The item is deleted from the package
+        /// </summary>
+        Deleted,
+        /// <summary>
+        /// The item is added to the package
+        /// </summary>
+        Added
+    }
+
+    /// <summary>
+    /// A delegate for reporting package creation progress
+    /// </summary>
+    /// <param name="type">The progress type that is currently running</param>
+    /// <param name="maxValue">The max value, meaning that when value equals maxValue, progress is equal to 100%</param>
+    /// <param name="value">The current item being progressed</param>
+    /// <param name="resourceId">The name of the resource being processed, if any</param>
+    public delegate void ProgressDelegate(ProgressType type, string resourceId, int maxValue, int value);
+
+    public class PackageBuilder
+    {
+        /// <summary>
+        /// The connection object
+        /// </summary>
+        private IServerConnection m_connection;
+
+        /// <summary>
+        /// Constructs a new package builder instance
+        /// </summary>
+        /// <param name="connection">The connection used to serialize and fetch items</param>
+        public PackageBuilder(IServerConnection connection)
+        {
+            if (connection == null)
+                throw new ArgumentNullException("connection");
+            m_connection = connection;
+        }
+
+        /// <summary>
+        /// This event is invoked to report progress to the caller
+        /// </summary>
+        public event ProgressDelegate Progress;
+
+        /// <summary>
+        /// Keep track of the last pg sent, to avoid excessive events
+        /// </summary>
+        private long m_lastPg = -1;
+
+        /// <summary>
+        /// Uploads a package to the server
+        /// </summary>
+        /// <param name="sourceFile"></param>
+        public void UploadPackage(string sourceFile)
+        {
+            if (Progress != null)
+                Progress(ProgressType.Uploading, sourceFile, 100, 0);
+            
+            m_lastPg = -1;
+            m_connection.ResourceService.UploadPackage(sourceFile, new Utility.StreamCopyProgressDelegate(ProgressCallback_Upload));
+
+            if (Progress != null)
+                Progress(ProgressType.Uploading, sourceFile, 100, 100);
+        }
+
+        private void ProgressCallback_Upload(long copied, long remain, long total)
+        {
+            if (Progress != null)
+            {
+                if (m_lastPg < 0 || remain == 0 || copied - m_lastPg > 1024 * 50)
+                {
+                    Progress(ProgressType.Uploading, "", (int)(total / 1024), (int)(copied / 1024));
+                    m_lastPg = copied;
+                }
+            }
+        }
+
+
+        /// <summary>
+        /// Creates a package
+        /// </summary>
+        /// <param name="folderResourceId">The folder to create the package from</param>
+        /// <param name="zipfilename">The name of the output file to create</param>
+        /// <param name="allowedExtensions">A list of allowed extensions without leading dot, or null to include all file types. The special item &quot;*&quot; matches all unknown types.</param>
+        /// <param name="removeExistingFiles">A value indicating if a delete operation is included in the package to remove existing files before restoring the package</param>
+        /// <param name="alternateTargetResourceId">An optional target folder resourceId, use null or an empty string to restore the files at the original locations</param>
+        public void CreatePackage(string folderResourceId, string zipfilename, IList<string> allowedExtensions, bool removeExistingFiles, string alternateTargetResourceId)
+        {
+            if (Progress != null)
+                Progress(ProgressType.ReadingFileList, folderResourceId, 100, 0);
+
+            ResourceList items = m_connection.ResourceService.GetRepositoryResources(folderResourceId);
+
+            List<ResourceListResourceDocument> files = new List<ResourceListResourceDocument>();
+            List<ResourceListResourceFolder> folders = new List<ResourceListResourceFolder>();
+            Dictionary<string, List<ResourceDataListResourceData>> resourceData = new Dictionary<string, List<ResourceDataListResourceData>>();
+            ResourcePackageManifest manifest = new ResourcePackageManifest();
+            manifest.Description = "MapGuide Package created with Maestro";
+            manifest.Operations = new ResourcePackageManifestOperations();
+            manifest.Operations.Operation = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperation>();
+            //System.Collections.Hashtable knownTypes = ((ServerConnectionBase)m_connection).ResourceTypeLookup;
+
+            foreach (object o in items.Items)
+                if (o as ResourceListResourceDocument != null)
+                {
+                    ResourceListResourceDocument doc = o as ResourceListResourceDocument;
+                    var extension = ResourceIdentifier.GetResourceType(doc.ResourceId);
+                    if (allowedExtensions == null || allowedExtensions.Count == 0)
+                        files.Add(doc);
+                    else if (m_connection.Capabilities.IsSupportedResourceType(extension) && allowedExtensions.Contains(extension.ToString()))
+                        files.Add(doc);
+                    else if (!m_connection.Capabilities.IsSupportedResourceType(extension) && allowedExtensions.Contains("*"))
+                        files.Add(doc);
+                }
+                else if (o as ResourceListResourceFolder != null)
+                {
+                    folders.Add(o as ResourceListResourceFolder);
+                }
+
+            if (Progress != null)
+            {
+                Progress(ProgressType.ReadingFileList, folderResourceId, 100, 100);
+                Progress(ProgressType.PreparingFolder, "", files.Count + folders.Count + 1, 0);
+            }
+
+            string temppath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
+
+            //All files have random names on disk, but a full path in the zip file
+            List<KeyValuePair<string, string>> filemap = new List<KeyValuePair<string, string>>();
+
+            try
+            {
+                System.IO.Directory.CreateDirectory(temppath);
+                int opno = 1;
+
+                foreach (ResourceListResourceFolder folder in folders)
+                {
+
+                    if (Progress != null)
+                        Progress(ProgressType.PreparingFolder, folder.ResourceId, files.Count + folders.Count + 1, opno);
+                    AddFolderResource(manifest, temppath, folder, removeExistingFiles, m_connection, filemap);
+                    if (Progress != null)
+                        Progress(ProgressType.PreparingFolder, folder.ResourceId, files.Count + folders.Count + 1, opno++);
+                }
+
+                foreach (ResourceListResourceDocument doc in files)
+                {
+                    if (Progress != null)
+                        Progress(ProgressType.PreparingFolder, doc.ResourceId, files.Count + folders.Count + 1, opno);
+                    string filebase = CreateFolderForResource(doc.ResourceId, temppath);
+
+                    resourceData[doc.ResourceId] = new List<ResourceDataListResourceData>();
+                    ResourceDataList rdl = m_connection.ResourceService.EnumerateResourceData(doc.ResourceId);
+                    foreach (ResourceDataListResourceData rd in rdl.ResourceData)
+                        resourceData[doc.ResourceId].Add(rd);
+
+                    int itemCount = resourceData[doc.ResourceId].Count + 1;
+
+                    filemap.Add(new KeyValuePair<string, string>(filebase + "_CONTENT.xml", System.IO.Path.Combine(temppath, Guid.NewGuid().ToString())));
+                    using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                    {
+                        using (var s = m_connection.ResourceService.GetResourceXmlData(doc.ResourceId))
+                        {
+                            var data = Utility.StreamAsArray(s);
+                            fs.Write(data, 0, data.Length);
+                        }
+                    }
+
+                    AddFileResource(manifest, temppath, doc, filemap[filemap.Count - 1].Key, removeExistingFiles, m_connection, filemap);
+
+                    foreach (ResourceDataListResourceData rd in rdl.ResourceData)
+                    {
+                        filemap.Add(new KeyValuePair<string, string>(filebase + "_DATA_" + EncodeFilename(rd.Name), System.IO.Path.Combine(temppath, Guid.NewGuid().ToString())));
+                        System.IO.FileInfo fi = new System.IO.FileInfo(filemap[filemap.Count - 1].Value);
+                        using (System.IO.FileStream fs = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                            m_connection.ResourceService.GetResourceData(doc.ResourceId, rd.Name).WriteTo(fs);
+
+                        AddResourceData(manifest, temppath, doc, fi, filemap[filemap.Count - 1].Key, rd, m_connection);
+                    }
+
+                    if (Progress != null)
+                        Progress(ProgressType.PreparingFolder, doc.ResourceId, files.Count + folders.Count + 1, opno++);
+                }
+
+                if (Progress != null)
+                    Progress(ProgressType.PreparingFolder, Properties.Resources.ProgressDone, files.Count + folders.Count + 1, files.Count + folders.Count + 1);
+
+                if (!string.IsNullOrEmpty(alternateTargetResourceId))
+                {
+                    if (Progress != null)
+                        Progress(ProgressType.MovingResources, Properties.Resources.ProgressUpdatingReferences, 100, 0);
+                    RemapFiles(m_connection, manifest, temppath, folderResourceId, alternateTargetResourceId, filemap);
+                    if (Progress != null)
+                        Progress(ProgressType.MovingResources, Properties.Resources.ProgressUpdatedReferences, 100, 100);
+                }
+
+                filemap.Add(new KeyValuePair<string, string>(System.IO.Path.Combine(temppath, "MgResourcePackageManifest.xml"), System.IO.Path.Combine(temppath, Guid.NewGuid().ToString())));
+                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                    m_connection.ResourceService.SerializeObject(manifest, fs);
+
+
+                if (Progress != null)
+                    Progress(ProgressType.MovingResources, zipfilename, filemap.Count, 0);
+
+                ZipDirectory(zipfilename, temppath, "MapGuide Package created by Maestro", filemap);
+
+                if (Progress != null)
+                {
+                    Progress(ProgressType.MovingResources, zipfilename, filemap.Count, filemap.Count);
+                    Progress(ProgressType.Done, "", filemap.Count, filemap.Count);
+                }
+
+            }
+            finally
+            {
+                try
+                {
+                    if (System.IO.Directory.Exists(temppath))
+                        System.IO.Directory.Delete(temppath, true);
+                }
+                catch
+                { }
+            }
+        }
+
+        private void AddResourceData(ResourcePackageManifest manifest, string temppath, ResourceListResourceDocument doc, System.IO.FileInfo fi, string resourcePath, ResourceDataListResourceData rd, IServerConnection connection)
+        {
+            string contentType = "application/octet-stream";
+
+            /*
+            try
+            {
+                if (connection as HttpServerConnection != null)
+                    contentType = (connection as HttpServerConnection).LastResponseHeaders[System.Net.HttpResponseHeader.ContentType];
+            }
+            catch
+            {
+            }
+             */
+            string name = rd.Name;
+            string type = rd.Type.ToString();
+            string resourceId = doc.ResourceId;
+            string filename = RelativeName(resourcePath, temppath).Replace('\\', '/');
+            long size = fi.Length;
+
+            AddResourceData(manifest, resourceId, contentType, type, name, filename, size);
+        }
+
+        private void AddResourceData(ResourcePackageManifest manifest, string resourceId, string contentType, string type, string name, string filename, long size)
+        {
+            ResourcePackageManifestOperationsOperation op = new ResourcePackageManifestOperationsOperation();
+            op.Name = "SETRESOURCEDATA";
+            op.Version = "1.0.0";
+            op.Parameters = new ResourcePackageManifestOperationsOperationParameters();
+            op.Parameters.Parameter = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+            ResourcePackageManifestOperationsOperationParametersParameter param = new ResourcePackageManifestOperationsOperationParametersParameter();
+
+            param.Name = "DATA";
+            param.Value = filename;
+            param.ContentType = contentType;
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "DATALENGTH";
+            param.Value = size.ToString();
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "DATANAME";
+            param.Value = name;
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "DATATYPE";
+            param.Value = type;
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "RESOURCEID";
+            param.Value = resourceId;
+            op.Parameters.Parameter.Add(param);
+
+            manifest.Operations.Operation.Add(op);
+        }
+
+        private void AddFileResource(ResourcePackageManifest manifest, string temppath, ResourceListResourceDocument doc, string contentfilename, bool eraseFirst, IServerConnection connection, List<KeyValuePair<string, string>> filemap)
+        {
+            string filebase = CreateFolderForResource(doc.ResourceId, temppath);
+
+            filemap.Add(new KeyValuePair<string, string>(filebase + "_HEADER.xml", System.IO.Path.Combine(temppath, Guid.NewGuid().ToString())));
+            using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                connection.ResourceService.SerializeObject(connection.ResourceService.GetResourceHeader(doc.ResourceId), fs);
+
+            string headerpath = RelativeName(filemap[filemap.Count - 1].Key, temppath).Replace('\\', '/');
+            string contentpath = RelativeName(contentfilename, temppath).Replace('\\', '/');
+            AddFileResource(manifest, doc.ResourceId, headerpath, contentpath, eraseFirst);
+        }
+
+        private void AddFileResource(ResourcePackageManifest manifest, string resourceId, string headerpath, string contentpath, bool eraseFirst)
+        {
+            if (eraseFirst)
+            {
+                ResourcePackageManifestOperationsOperation delop = new ResourcePackageManifestOperationsOperation();
+                delop.Name = "DELETERESOURCE";
+                delop.Version = "1.0.0";
+                delop.Parameters = new ResourcePackageManifestOperationsOperationParameters();
+                delop.Parameters.Parameter = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+                ResourcePackageManifestOperationsOperationParametersParameter delparam = new ResourcePackageManifestOperationsOperationParametersParameter();
+
+                delparam.Name = "RESOURCEID";
+                delparam.Value = resourceId;
+                delop.Parameters.Parameter.Add(delparam);
+                manifest.Operations.Operation.Add(delop);
+            }
+
+            ResourcePackageManifestOperationsOperation op = new ResourcePackageManifestOperationsOperation();
+            op.Name = "SETRESOURCE";
+            op.Version = "1.0.0";
+            op.Parameters = new ResourcePackageManifestOperationsOperationParameters();
+            op.Parameters.Parameter = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+            ResourcePackageManifestOperationsOperationParametersParameter param = new ResourcePackageManifestOperationsOperationParametersParameter();
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "CONTENT";
+            param.Value = contentpath;
+            param.ContentType = "text/xml";
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "HEADER";
+            param.Value = headerpath;
+            param.ContentType = "text/xml";
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "RESOURCEID";
+            param.Value = resourceId;
+            op.Parameters.Parameter.Add(param);
+
+            manifest.Operations.Operation.Add(op);
+        }
+
+        private void AddFolderResource(ResourcePackageManifest manifest, string temppath, ResourceListResourceFolder folder, bool eraseFirst, IServerConnection connection, List<KeyValuePair<string, string>> filemap)
+        {
+            string filebase = System.IO.Path.GetDirectoryName(CreateFolderForResource(folder.ResourceId + "dummy.xml", temppath));
+
+            filemap.Add(new KeyValuePair<string, string>(System.IO.Path.Combine(filebase, "_HEADER.xml"), System.IO.Path.Combine(temppath, Guid.NewGuid().ToString())));
+            using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                connection.ResourceService.SerializeObject(connection.ResourceService.GetFolderHeader(folder.ResourceId), fs);
+
+            if (!filebase.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
+                filebase += System.IO.Path.DirectorySeparatorChar;
+
+            string headerpath = RelativeName(filebase + "_HEADER.xml", temppath).Replace('\\', '/');
+
+            AddFolderResource(manifest, folder.ResourceId, headerpath, eraseFirst);
+        }
+
+
+        private void AddFolderResource(ResourcePackageManifest manifest, string resourceId, string headerpath, bool eraseFirst)
+        {
+            if (eraseFirst)
+            {
+                ResourcePackageManifestOperationsOperation delop = new ResourcePackageManifestOperationsOperation();
+                delop.Name = "DELETERESOURCE";
+                delop.Version = "1.0.0";
+                delop.Parameters = new ResourcePackageManifestOperationsOperationParameters();
+                delop.Parameters.Parameter = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+                ResourcePackageManifestOperationsOperationParametersParameter delparam = new ResourcePackageManifestOperationsOperationParametersParameter();
+
+                delparam.Name = "RESOURCEID";
+                delparam.Value = resourceId;
+                delop.Parameters.Parameter.Add(delparam);
+                manifest.Operations.Operation.Add(delop);
+            }
+
+            ResourcePackageManifestOperationsOperation op = new ResourcePackageManifestOperationsOperation();
+            if (resourceId.EndsWith("//"))
+                op.Name = "UPDATEREPOSITORY";
+            else
+                op.Name = "SETRESOURCE";
+            op.Version = "1.0.0";
+            op.Parameters = new ResourcePackageManifestOperationsOperationParameters();
+            op.Parameters.Parameter = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+            ResourcePackageManifestOperationsOperationParametersParameter param = new ResourcePackageManifestOperationsOperationParametersParameter();
+
+            param.Name = "HEADER";
+            param.Value = headerpath;
+            param.ContentType = "text/xml";
+            op.Parameters.Parameter.Add(param);
+
+            param = new ResourcePackageManifestOperationsOperationParametersParameter();
+            param.Name = "RESOURCEID";
+            param.Value = resourceId;
+            op.Parameters.Parameter.Add(param);
+
+            manifest.Operations.Operation.Add(op);
+        }
+
+        private string RelativeName(string filebase, string temppath)
+        {
+            if (!filebase.StartsWith(temppath))
+                throw new Exception(string.Format(Properties.Resources.FilenameRelationInternalError, filebase, temppath));
+            if (!temppath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
+                temppath += System.IO.Path.DirectorySeparatorChar;
+            return filebase.Substring(temppath.Length);
+        }
+
+        private System.Text.RegularExpressions.Regex m_filenameTransformer = new System.Text.RegularExpressions.Regex(@"[^A-Za-z0-9\.-\/]", System.Text.RegularExpressions.RegexOptions.Compiled);
+
+        //There are some problems with the Zip reader in MapGuide and international characters :(
+        private string EncodeFilename(string filename)
+        {
+            System.Text.RegularExpressions.Match m = m_filenameTransformer.Match(filename);
+            System.Text.StringBuilder sb = new System.Text.StringBuilder();
+            int previndex = 0;
+
+            while (m != null && m.Success)
+            {
+                string replaceval = string.Format("-x{0:x2}-", (int)m.Value[0]);
+
+                sb.Append(filename.Substring(previndex, m.Index - previndex));
+                sb.Append(replaceval);
+                previndex = m.Index + m.Value.Length;
+
+                m = m.NextMatch();
+            }
+
+            if (sb.Length == 0)
+                return filename;
+            else
+            {
+                sb.Append(filename.Substring(previndex));
+                return sb.ToString();
+            }
+        }
+
+        private string CreateFolderForResource(string resourceId, string temppath)
+        {
+            var rid = new ResourceIdentifier(resourceId);
+            string filebase = EncodeFilename(rid.Name);
+            string folder = "Library/" + EncodeFilename(rid.Path);
+            folder = folder.Substring(0, folder.Length - filebase.Length);
+            filebase += resourceId.Substring(resourceId.LastIndexOf('.'));
+
+            folder = folder.Replace('/', System.IO.Path.DirectorySeparatorChar);
+            folder = System.IO.Path.Combine(temppath, folder);
+
+            return System.IO.Path.Combine(folder, filebase);
+        }
+
+        private void RemapFiles(IServerConnection connection, ResourcePackageManifest manifest, string tempdir, string origpath, string newpath, List<KeyValuePair<string, string>> filemap)
+        {
+            if (!newpath.EndsWith("/"))
+                newpath += "/";
+            if (!origpath.EndsWith("/"))
+                origpath += "/";
+
+            Dictionary<string, string> lookup = new Dictionary<string, string>();
+            foreach (KeyValuePair<string, string> p in filemap)
+                lookup.Add(p.Key, p.Value);
+
+            foreach (ResourcePackageManifestOperationsOperation op in manifest.Operations.Operation)
+            {
+                op.Parameters.SetParameterValue("RESOURCEID", newpath + op.Parameters.GetParameterValue("RESOURCEID").Substring(origpath.Length));
+                if (op.Parameters.GetParameterValue("CONTENT") != null)
+                {
+                    string path = System.IO.Path.Combine(tempdir, op.Parameters.GetParameterValue("CONTENT").Replace('/', System.IO.Path.DirectorySeparatorChar));
+                    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
+                    doc.Load(lookup[path]);
+                    ((ServerConnectionBase)connection).UpdateResourceReferences(doc, origpath, newpath, true);
+                    System.IO.MemoryStream ms = new System.IO.MemoryStream();
+                    doc.Save(ms);
+                    System.IO.MemoryStream ms2 = Utility.RemoveUTF8BOM(ms);
+                    if (ms2 != ms)
+                        ms.Dispose();
+
+                    ms2.Position = 0;
+                    using (System.IO.FileStream fs = new System.IO.FileStream(lookup[path], System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                        ms2.WriteTo(fs);
+                    ms2.Dispose();
+                }
+            }
+        }
+
+        private void ZipDirectory(string zipfile, string folder, string comment, List<KeyValuePair<string, string>> filemap)
+        {
+            ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = System.Text.Encoding.UTF8.CodePage;
+            ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
+            using (System.IO.FileStream ofs = new System.IO.FileStream(zipfile, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+            using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zip = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(ofs))
+            {
+                try
+                {
+                    zip.SetLevel(9);
+                    if (!string.IsNullOrEmpty(comment))
+                        zip.SetComment(comment);
+
+                    int i = 0;
+
+                    foreach (KeyValuePair<string, string> f in filemap)
+                    {
+                        if (Progress != null)
+                            Progress(ProgressType.Compressing, f.Key, filemap.Count, i);
+
+                        System.IO.FileInfo fi = new System.IO.FileInfo(f.Value);
+                        ICSharpCode.SharpZipLib.Zip.ZipEntry ze = new ICSharpCode.SharpZipLib.Zip.ZipEntry(RelativeName(f.Key, folder).Replace('\\', '/'));
+                        ze.DateTime = fi.LastWriteTime;
+                        ze.Size = fi.Length;
+                        zip.PutNextEntry(ze);
+                        using (System.IO.FileStream fs = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None))
+                            Utility.CopyStream(fs, zip);
+
+                        if (Progress != null)
+                            Progress(ProgressType.Compressing, f.Key, filemap.Count, i++);
+                    }
+
+                    zip.Finish();
+                }
+                finally
+                {
+                    try { zip.Close(); }
+                    catch { }
+                }
+            }
+        }
+
+
+        private const string DEFAULT_HEADER =
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+            "<ResourceFolderHeader xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"ResourceFolderHeader-1.0.0.xsd\">\n" +
+            "	<Security xsi:noNamespaceSchemaLocation=\"ResourceSecurity-1.0.0.xsd\">\n" +
+            "		<Inherited>true</Inherited>\n" +
+            "	</Security>\n" +
+            "</ResourceFolderHeader>";
+
+
+        private string MapResourcePathToFolder(string tempfolder, string resourcename)
+        {
+            return CreateFolderForResource(resourcename, tempfolder);
+        }
+
+        /// <summary>
+        /// Builds a package with the specified content
+        /// </summary>
+        /// <param name="sourcePackageFile">The MGP file to read existing items from</param>
+        /// <param name="items">The list of items that should be present in the new package</param>
+        /// <param name="insertEraseCommands">True if each resource should have a delete operation inserted before the actual operation, false otherwise</param>
+        /// <param name="targetfile">The output package filename</param>
+        public void RebuildPackage(string sourcePackageFile, List<ResourceItem> items, string targetfile, bool insertEraseCommands)
+        {
+            string tempfolder = System.IO.Path.GetTempPath();
+            int opno = 1;
+            try
+            {
+                if (Progress != null)
+                    Progress(ProgressType.ReadingFileList, sourcePackageFile, 100, 0);
+
+                //Step 1: Create the file system layout
+                if (!System.IO.Directory.Exists(tempfolder))
+                    System.IO.Directory.CreateDirectory(tempfolder);
+
+                string zipfilecomment;
+
+                List<KeyValuePair<string, string>> filemap = new List<KeyValuePair<string, string>>();
+
+                ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = System.Text.Encoding.UTF8.CodePage;
+                using (ICSharpCode.SharpZipLib.Zip.ZipFile zipfile = new ICSharpCode.SharpZipLib.Zip.ZipFile(sourcePackageFile))
+                {
+                    zipfilecomment = zipfile.ZipFileComment;
+
+                    if (Progress != null)
+                        Progress(ProgressType.ReadingFileList, sourcePackageFile, 100, 100);
+
+                    if (Progress != null)
+                        Progress(ProgressType.PreparingFolder, "", items.Count, 0);
+
+                    foreach (ResourceItem ri in items)
+                    {
+                        if (Progress != null)
+                            Progress(ProgressType.PreparingFolder, ri.ResourcePath, items.Count, opno);
+
+                        string filebase;
+                        if (ri.IsFolder)
+                        {
+                            filebase = System.IO.Path.GetDirectoryName(MapResourcePathToFolder(tempfolder, ri.ResourcePath + "dummy.xml"));
+                            if (!filebase.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
+                                filebase += System.IO.Path.DirectorySeparatorChar;
+                        }
+                        else
+                            filebase = MapResourcePathToFolder(tempfolder, ri.ResourcePath);
+
+                        string headerpath = filebase + "_HEADER.xml";
+                        string contentpath = filebase + "_CONTENT.xml";
+
+                        if (ri.EntryType == EntryTypeEnum.Added)
+                        {
+                            if (string.IsNullOrEmpty(ri.Headerpath))
+                            {
+                                filemap.Add(new KeyValuePair<string, string>(headerpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                {
+                                    byte[] data = System.Text.Encoding.UTF8.GetBytes(DEFAULT_HEADER);
+                                    fs.Write(data, 0, data.Length);
+                                }
+                            }
+                            else if (!ri.IsFolder)
+                            {
+                                filemap.Add(new KeyValuePair<string, string>(headerpath, ri.Headerpath));
+                                System.IO.File.Copy(ri.Headerpath, headerpath);
+                            }
+
+                            if (!string.IsNullOrEmpty(ri.Contentpath))
+                                filemap.Add(new KeyValuePair<string, string>(contentpath, ri.Contentpath));
+                        }
+                        else if (ri.EntryType == EntryTypeEnum.Regular)
+                        {
+                            if (string.IsNullOrEmpty(ri.Headerpath))
+                            {
+                                filemap.Add(new KeyValuePair<string, string>(headerpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                {
+                                    byte[] data = System.Text.Encoding.UTF8.GetBytes(DEFAULT_HEADER);
+                                    fs.Write(data, 0, data.Length);
+                                }
+                            }
+                            else
+                            {
+                                int index = FindZipEntry(zipfile, ri.Headerpath);
+                                if (index < 0)
+                                    throw new Exception(string.Format(Properties.Resources.FileMissingError, ri.Headerpath));
+
+                                filemap.Add(new KeyValuePair<string, string>(headerpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                    Utility.CopyStream(zipfile.GetInputStream(index), fs);
+                            }
+
+                            if (!ri.IsFolder)
+                            {
+                                int index = FindZipEntry(zipfile, ri.Contentpath);
+                                if (index < 0)
+                                    throw new Exception(string.Format(Properties.Resources.FileMissingError, ri.Contentpath));
+
+                                filemap.Add(new KeyValuePair<string, string>(contentpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                    Utility.CopyStream(zipfile.GetInputStream(index), fs);
+                            }
+
+                        }
+
+                        ri.Headerpath = headerpath;
+                        ri.Contentpath = contentpath;
+
+                        foreach (ResourceDataItem rdi in ri.Items)
+                        {
+                            string targetpath = filebase + "_DATA_" + EncodeFilename(rdi.ResourceName);
+                            if (rdi.EntryType == EntryTypeEnum.Added)
+                            {
+                                filemap.Add(new KeyValuePair<string, string>(targetpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                            }
+                            else
+                            {
+                                int index = FindZipEntry(zipfile, rdi.Filename);
+                                if (index < 0)
+                                    throw new Exception(string.Format(Properties.Resources.FileMissingError, rdi.Filename));
+
+                                filemap.Add(new KeyValuePair<string, string>(targetpath, System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                    Utility.CopyStream(zipfile.GetInputStream(index), fs);
+                            }
+                            rdi.Filename = targetpath;
+                        }
+
+                        if (Progress != null)
+                            Progress(ProgressType.PreparingFolder, ri.ResourcePath, items.Count, opno++);
+                    }
+                }
+
+                int i = 0;
+
+                Dictionary<string, string> filemap_lookup = new Dictionary<string, string>();
+                foreach (KeyValuePair<string, string> kv in filemap)
+                    filemap_lookup[kv.Key] = kv.Value;
+
+                //Step 2: Repoint all resources with respect to the update
+                foreach (ResourceItem ri in items)
+                {
+                    if (Progress != null)
+                        Progress(ProgressType.MovingResources, Properties.Resources.ProgressUpdatingResources, items.Count, i);
+
+                    if (ri.OriginalResourcePath != ri.ResourcePath)
+                    {
+                        foreach (ResourceItem rix in items)
+                        {
+                            if (!rix.IsFolder)
+                            {
+                                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
+                                doc.Load(filemap_lookup[rix.Contentpath]);
+                                ((ServerConnectionBase)m_connection).UpdateResourceReferences(doc, ri.OriginalResourcePath, ri.ResourcePath, ri.IsFolder);
+                                System.IO.MemoryStream ms = new System.IO.MemoryStream();
+                                doc.Save(ms);
+                                System.IO.MemoryStream ms2 = Utility.RemoveUTF8BOM(ms);
+                                if (ms2 != ms)
+                                    ms.Dispose();
+
+                                ms2.Position = 0;
+                                using (System.IO.FileStream fs = new System.IO.FileStream(filemap_lookup[rix.Contentpath], System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                                    ms2.WriteTo(fs);
+                                ms2.Dispose();
+                            }
+                        }
+                    }
+                    if (Progress != null)
+                        Progress(ProgressType.MovingResources, Properties.Resources.ProgressUpdatingResources, items.Count, i++);
+                }
+
+                if (Progress != null)
+                    Progress(ProgressType.MovingResources, Properties.Resources.ProgressUpdatedResources, items.Count, items.Count);
+
+                //Step 3: Create an updated definition file
+                ResourcePackageManifest manifest = new ResourcePackageManifest();
+                manifest.Description = "MapGuide Package created by Maestro";
+                manifest.Operations = new ResourcePackageManifestOperations();
+                manifest.Operations.Operation = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperation>();
+
+                foreach (ResourceItem ri in items)
+                    if (ri.IsFolder)
+                    {
+                        AddFolderResource(
+                            manifest,
+                            ri.ResourcePath,
+                            RelativeName(ri.Headerpath, tempfolder).Replace('\\', '/'),
+                            insertEraseCommands);
+                    }
+                    else
+                    {
+                        AddFileResource(
+                            manifest,
+                            ri.ResourcePath,
+                            RelativeName(ri.Headerpath, tempfolder).Replace('\\', '/'),
+                            RelativeName(ri.Contentpath, tempfolder).Replace('\\', '/'),
+                            insertEraseCommands);
+
+                        foreach (ResourceDataItem rdi in ri.Items)
+                            AddResourceData(
+                                manifest,
+                                ri.ResourcePath,
+                                rdi.ContentType,
+                                rdi.DataType,
+                                rdi.ResourceName,
+                                RelativeName(rdi.Filename, tempfolder).Replace('\\', '/'),
+                                new System.IO.FileInfo(filemap_lookup[rdi.Filename]).Length);
+                    }
+
+                filemap.Add(new KeyValuePair<string, string>(System.IO.Path.Combine(tempfolder, "MgResourcePackageManifest.xml"), System.IO.Path.Combine(tempfolder, Guid.NewGuid().ToString())));
+                using (System.IO.FileStream fs = new System.IO.FileStream(filemap[filemap.Count - 1].Value, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write, System.IO.FileShare.None))
+                    m_connection.ResourceService.SerializeObject(manifest, fs);
+
+                if (Progress != null)
+                    Progress(ProgressType.Compressing, Properties.Resources.ProgressCompressing, 100, 0);
+
+                //Step 4: Create the zip file
+                ZipDirectory(targetfile, tempfolder, zipfilecomment, filemap);
+
+                if (Progress != null)
+                    Progress(ProgressType.Compressing, Properties.Resources.ProgressCompressed, 100, 100);
+            }
+            finally
+            {
+                try { System.IO.Directory.Delete(tempfolder, true); }
+                catch { }
+            }
+        }
+
+        private int FindZipEntry(ICSharpCode.SharpZipLib.Zip.ZipFile file, string path)
+        {
+            string p = path.Replace('\\', '/');
+            foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in file)
+                if (ze.Name.Replace('\\', '/').Equals(p))
+                    return (int)ze.ZipFileIndex;
+
+            return -1;
+        }
+
+        /// <summary>
+        /// Reads the contents of a package file
+        /// </summary>
+        /// <param name="packageFile">The file to read</param>
+        /// <returns>A dictionary of items, the key is the resourceId</returns>
+        public Dictionary<string, ResourceItem> ListPackageContents(string packageFile)
+        {
+            if (Progress != null)
+                Progress(ProgressType.ListingFiles, packageFile, 100, 0);
+
+            Dictionary<string, ResourceItem> resourceList = new Dictionary<string, ResourceItem>();
+
+            ResourcePackageManifest manifest;
+            ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = System.Text.Encoding.UTF8.CodePage;
+            using (ICSharpCode.SharpZipLib.Zip.ZipFile zipfile = new ICSharpCode.SharpZipLib.Zip.ZipFile(packageFile))
+            {
+                int index = FindZipEntry(zipfile, "MgResourcePackageManifest.xml");
+                if (index < 0)
+                    throw new Exception(Properties.Resources.InvalidPackageFileError);
+
+                manifest = m_connection.ResourceService.DeserializeObject<ResourcePackageManifest>(zipfile.GetInputStream(index));
+            }
+
+            int i = 0;
+            if (Progress != null)
+                Progress(ProgressType.ListingFiles, packageFile, manifest.Operations.Operation.Count, i);
+
+            //TODO: Much of this assumes that the package is correctly constructed, ea.: no SETRESOURCEDATA, before a SETRESOURCE and so on.
+            foreach (ResourcePackageManifestOperationsOperation op in manifest.Operations.Operation)
+            {
+                if (Progress != null)
+                    Progress(ProgressType.ListingFiles, packageFile, manifest.Operations.Operation.Count, i++);
+
+                if (op.Name.ToLower().Equals("setresource"))
+                {
+                    string id = op.Parameters.GetParameterValue("RESOURCEID");
+                    string header;
+                    if (op.Parameters.GetParameterValue("HEADER") != null)
+                        header = op.Parameters.GetParameterValue("HEADER");
+                    else
+                        header = null;
+                    string content = op.Parameters.GetParameterValue("CONTENT") == null ? null : op.Parameters.GetParameterValue("CONTENT");
+
+                    resourceList.Add(id, new ResourceItem(id, header, content));
+                }
+                else if (op.Name.ToLower().Equals("setresourcedata"))
+                {
+                    string id = op.Parameters.GetParameterValue("RESOURCEID");
+                    ResourceItem ri = resourceList[id];
+                    string name = op.Parameters.GetParameterValue("DATANAME");
+                    string file = op.Parameters.GetParameterValue("DATA");
+                    string contentType = op.Parameters.GetParameterValue("DATA");
+                    string dataType = op.Parameters.GetParameterValue("DATATYPE");
+
+                    ri.Items.Add(new ResourceDataItem(name, contentType, file, dataType));
+                }
+
+                //TODO: What to do with "DELETERESOURCE" ?
+            }
+
+            return resourceList;
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,309 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.MaestroAPI;
+
+namespace Maestro.Packaging
+{
+    public partial class PackageProgress : Form
+    {
+        /// <summary>
+        /// The stages required to build a package
+        /// </summary>
+        private readonly static ProgressType[] BUILD_STAGES = null;
+
+        static PackageProgress()
+        {
+            BUILD_STAGES = 
+            new ProgressType[] {
+                ProgressType.ReadingFileList,
+                ProgressType.PreparingFolder,
+                ProgressType.MovingResources,
+                ProgressType.Compressing
+            };
+        }
+
+        private bool m_allowClose = true;
+        private volatile System.Threading.Thread m_thread;
+
+        private PackageBuilder m_invokeObj = null;
+        private object[] m_invokeArgs = null;
+        private System.Reflection.MethodInfo m_invokeMethod = null;
+        private object m_invokeResult = null;
+
+        /// <summary>
+        /// Lets the user choose a file to upload, and then transfers it
+        /// </summary>
+        /// <param name="owner">The owner form</param>
+        /// <param name="con">The connection to use</param>
+        /// <returns>A DialogResult object that indicates the upload result</returns>
+        public static DialogResult UploadPackage(Form owner, IServerConnection con)
+        {
+            OpenFileDialog dlg = Maestro.Shared.UI.DialogFactory.OpenFile();
+            //Mono does NOT like this one
+            //dlg.AutoUpgradeEnabled = true;
+            dlg.CheckFileExists = true;
+            dlg.CheckPathExists = true;
+            dlg.DefaultExt = ".mgp";
+            dlg.Filter = Properties.Resources.UploadPackageDialogFilter;
+            dlg.FilterIndex = 0;
+            dlg.Multiselect = false;
+            dlg.ValidateNames = true;
+            dlg.Title = Properties.Resources.UploadPackageDialogTitle;
+
+            if (dlg.ShowDialog(owner) == DialogResult.OK)
+            {
+                return UploadPackage(owner, con, dlg.FileName);
+            }
+            else
+                return DialogResult.Cancel;
+        }
+
+        /// <summary>
+        /// Lists the contents of a package
+        /// </summary>
+        /// <param name="owner">The owner form</param>
+        /// <param name="connection">The connection used to deserialize the items</param>
+        /// <param name="packageFile">The package file to read</param>
+        /// <returns>A list of resources in the package</returns>
+        public static Dictionary<string, ResourceItem> ListPackageContents(Form owner, IServerConnection connection, string packageFile)
+        {
+            PackageProgress pkgp = new PackageProgress();
+            pkgp.m_invokeArgs = new object[] { packageFile };
+            pkgp.m_invokeObj = new PackageBuilder(connection);
+            pkgp.m_invokeMethod = pkgp.m_invokeObj.GetType().GetMethod("ListPackageContents");
+
+            if (pkgp.ShowDialog(owner) == DialogResult.OK)
+                return (Dictionary<string, ResourceItem>)pkgp.m_invokeResult;
+            else
+                return null;
+        }
+
+        /// <summary>
+        /// Uploads a package file to the server
+        /// </summary>
+        /// <param name="owner">The owner form</param>
+        /// <param name="connection">The connection used to upload the package</param>
+        /// <param name="packageFile">The package file to upload</param>
+        /// <returns>A DialogResult object that indicates the result of the operation</returns>
+        public static DialogResult UploadPackage(Form owner, IServerConnection connection, string packageFile)
+        {
+            PackageProgress pkgp = new PackageProgress();
+            pkgp.m_invokeArgs = new object[] { packageFile };
+            pkgp.m_invokeObj = new PackageBuilder(connection);
+            pkgp.m_invokeMethod = pkgp.m_invokeObj.GetType().GetMethod("UploadPackage");
+
+            return pkgp.ShowDialog(owner);
+        }
+
+        /// <summary>
+        /// Rebuilds a package
+        /// </summary>
+        /// <param name="owner">The owner form</param>
+        /// <param name="connection">The connection used to serialize the items</param>
+        /// <param name="sourcePackageFile">The package file that the new file is based on</param>
+        /// <param name="items">The items that describes the layout of the new package</param>
+        /// <param name="targetfile">The output package file</param>
+        /// <param name="insertEraseCommands">True if each resource should have a delete operation inserted before the actual operation, false otherwise</param>
+        /// <returns>A DialogResult object that indicates the result of the operation</returns>
+        public static DialogResult RebuildPackage(Form owner, IServerConnection connection, string sourcePackageFile, List<ResourceItem> items, string targetfile, bool insertEraseCommands)
+        {
+            PackageProgress pkgp = new PackageProgress();
+            pkgp.m_invokeArgs = new object[] { sourcePackageFile, items, targetfile, insertEraseCommands };
+            pkgp.m_invokeObj = new PackageBuilder(connection);
+            pkgp.m_invokeMethod = pkgp.m_invokeObj.GetType().GetMethod("RebuildPackage");
+
+            return pkgp.ShowDialog(owner);
+        }
+
+        /// <summary>
+        /// Creates a new package from a server folder
+        /// </summary>
+        /// <param name="owner">The owner form</param>
+        /// <param name="connection">The connection used to retrieve the resources</param>
+        /// <param name="folderResourceId">The folder to create the package from</param>
+        /// <param name="zipfilename">The name of the output package file</param>
+        /// <param name="allowedExtensions">A list of allowed extensions, set to null for all types. The special value &quot;*&quot; matches all unknown extensions.</param>
+        /// <param name="removeExistingFiles">A flag indicating if the package should contain a delete instruction to delete the target area before restore</param>
+        /// <param name="alternateTargetResourceId">The folder path where the package should be restore, set to null or empty string to use the source path</param>
+        /// <returns></returns>
+        public static DialogResult CreatePackage(Form owner, IServerConnection connection, string folderResourceId, string zipfilename, List<string> allowedExtensions, bool removeExistingFiles, string alternateTargetResourceId)
+        {
+            PackageProgress pkgp = new PackageProgress();
+            pkgp.m_invokeArgs = new object[] {folderResourceId, zipfilename, allowedExtensions, removeExistingFiles, alternateTargetResourceId };
+            pkgp.m_invokeObj = new PackageBuilder(connection);
+            pkgp.m_invokeMethod = pkgp.m_invokeObj.GetType().GetMethod("CreatePackage");
+
+            return pkgp.ShowDialog(owner);
+        }
+
+        private PackageProgress()
+        {
+            InitializeComponent();
+        }
+
+        private void PackageProgress_Load(object sender, EventArgs e)
+        {
+            m_allowClose = false;
+            backgroundWorker.RunWorkerAsync();
+            m_invokeObj.Progress += new ProgressDelegate(SetCurrentProgress);
+        }
+
+        private void PackageProgress_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            if (m_thread != null && !m_allowClose && e.CloseReason == CloseReason.UserClosing)
+            {
+                if (MessageBox.Show(this, Properties.Resources.CancelConfirmation, Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3) == DialogResult.Yes)
+                {
+                    try { m_thread.Abort(); }
+                    catch { }
+                }
+                else
+                    e.Cancel = true;
+            }
+        }
+
+        private delegate void SetCurrentProgressDelegate(ProgressType type, string resource, int total, int pg);
+        private void SetCurrentProgress(ProgressType type, string resource, int total, int pg)
+        {
+            if (this.InvokeRequired)
+                this.Invoke(new SetCurrentProgressDelegate(SetCurrentProgress), new object[] { type, resource, total, pg });
+            else
+            {
+                int span = this.CurrentProgress.Maximum - this.CurrentProgress.Minimum;
+                double v = (((double)pg / total) * span) + this.CurrentProgress.Minimum;
+                this.CurrentProgress.Value = (int)Math.Max(Math.Min(v, this.CurrentProgress.Maximum), this.CurrentProgress.Minimum);
+                OperationLabel.Text = resource;
+
+                int largePg = (int)Array.IndexOf(BUILD_STAGES, type);
+                if (largePg >= 0)
+                {
+                    this.TotalProgress.Maximum = 100;
+                    this.TotalProgress.Minimum = 0;
+
+                    double tick = 100 / BUILD_STAGES.Length;
+                    double lv = (tick * largePg) + (tick * ((double)pg / total));
+
+                    this.TotalProgress.Value = (int)Math.Max(Math.Min((int)lv, this.TotalProgress.Maximum), this.TotalProgress.Minimum);
+                }
+                
+                if (type == ProgressType.Uploading)
+                {
+                    HideTotal();
+                    if (pg == total)
+                    {
+                        OperationLabel.Text = Properties.Resources.ProgressWaitingForServer;
+                        CurrentProgress.Style = ProgressBarStyle.Marquee;
+                    }
+                    else
+                    {
+                        OperationLabel.Text = string.Format(Properties.Resources.ProgressUploading, ((double)pg / 1024), ((double)total / 1024));
+                        this.Refresh();
+                    }
+                }
+                else if (type == ProgressType.ListingFiles)
+                {
+                    HideTotal();
+                    OperationLabel.Text = Properties.Resources.ProgressReadingPackage;
+                    CurrentProgress.Style = ProgressBarStyle.Marquee;
+                }
+                else if (type == ProgressType.Compressing)
+                {
+                    OperationLabel.Text = Properties.Resources.ProgressCompressing;
+                }
+                else if (type == ProgressType.MovingResources)
+                {
+                    OperationLabel.Text = Properties.Resources.ProgressUpdatingReferences;
+                }
+                else if (type == ProgressType.PreparingFolder)
+                {
+                    OperationLabel.Text = resource;
+                }
+
+            }
+        }
+
+        private void HideTotal()
+        {
+            if (TotalProgress.Visible)
+            {
+                this.Height -= TotalProgress.Height;
+                TotalProgress.Visible = false;
+                TotalLabel.Visible = false;
+            }
+        }
+
+        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
+        {
+            try
+            {
+                m_thread = System.Threading.Thread.CurrentThread;
+                e.Result = m_invokeMethod.Invoke(m_invokeObj, m_invokeArgs);
+            }
+            catch (System.Threading.ThreadAbortException)
+            {
+                System.Threading.Thread.ResetAbort();
+                e.Cancel = true;
+            }
+            catch (System.Reflection.TargetInvocationException tai)
+            {
+                throw tai.InnerException;
+            }
+            finally
+            {
+                m_thread = null;
+            }
+        }
+
+        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+        {
+            m_allowClose = true;
+            if (e.Cancelled)
+            {
+                this.DialogResult = DialogResult.Cancel;
+                this.Close();
+                return;
+            }
+            else if (e.Error != null)
+                throw e.Error;
+
+            m_invokeResult = e.Result;
+            this.DialogResult = DialogResult.OK;
+            this.Close();
+        }
+
+        private void CancelBtn_Click(object sender, EventArgs e)
+        {
+            FormClosingEventArgs ev = new FormClosingEventArgs(CloseReason.UserClosing, false);
+            PackageProgress_FormClosing(sender, ev);
+            if (!ev.Cancel)
+            {
+                try { m_thread.Abort(); }
+                catch { }
+            }
+        }
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.designer.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,119 @@
+namespace Maestro.Packaging
+{
+    partial class PackageProgress
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PackageProgress));
+            this.CurrentProgress = new System.Windows.Forms.ProgressBar();
+            this.TotalProgress = new System.Windows.Forms.ProgressBar();
+            this.label1 = new System.Windows.Forms.Label();
+            this.TotalLabel = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.OperationLabel = new System.Windows.Forms.Label();
+            this.CancelBtn = new System.Windows.Forms.Button();
+            this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
+            this.SuspendLayout();
+            // 
+            // CurrentProgress
+            // 
+            resources.ApplyResources(this.CurrentProgress, "CurrentProgress");
+            this.CurrentProgress.Name = "CurrentProgress";
+            // 
+            // TotalProgress
+            // 
+            resources.ApplyResources(this.TotalProgress, "TotalProgress");
+            this.TotalProgress.Name = "TotalProgress";
+            // 
+            // label1
+            // 
+            resources.ApplyResources(this.label1, "label1");
+            this.label1.Name = "label1";
+            // 
+            // TotalLabel
+            // 
+            resources.ApplyResources(this.TotalLabel, "TotalLabel");
+            this.TotalLabel.Name = "TotalLabel";
+            // 
+            // label3
+            // 
+            resources.ApplyResources(this.label3, "label3");
+            this.label3.Name = "label3";
+            // 
+            // OperationLabel
+            // 
+            resources.ApplyResources(this.OperationLabel, "OperationLabel");
+            this.OperationLabel.AutoEllipsis = true;
+            this.OperationLabel.Name = "OperationLabel";
+            // 
+            // CancelBtn
+            // 
+            resources.ApplyResources(this.CancelBtn, "CancelBtn");
+            this.CancelBtn.Name = "CancelBtn";
+            this.CancelBtn.UseVisualStyleBackColor = true;
+            this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
+            // 
+            // backgroundWorker
+            // 
+            this.backgroundWorker.WorkerSupportsCancellation = true;
+            this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork);
+            this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted);
+            // 
+            // PackageProgress
+            // 
+            resources.ApplyResources(this, "$this");
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.CancelBtn);
+            this.Controls.Add(this.OperationLabel);
+            this.Controls.Add(this.label3);
+            this.Controls.Add(this.TotalLabel);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.TotalProgress);
+            this.Controls.Add(this.CurrentProgress);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "PackageProgress";
+            this.Load += new System.EventHandler(this.PackageProgress_Load);
+            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.PackageProgress_FormClosing);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.ProgressBar TotalProgress;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label TotalLabel;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label OperationLabel;
+        private System.Windows.Forms.Button CancelBtn;
+        public System.Windows.Forms.ProgressBar CurrentProgress;
+        private System.ComponentModel.BackgroundWorker backgroundWorker;
+    }
+}
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.resx	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/PackageProgress.resx	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="CurrentProgress.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 40</value>
+  </data>
+  <data name="CurrentProgress.Size" type="System.Drawing.Size, System.Drawing">
+    <value>384, 23</value>
+  </data>
+  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="CurrentProgress.TabIndex" type="System.Int32, mscorlib">
+    <value>0</value>
+  </data>
+  <data name="&gt;&gt;CurrentProgress.Name" xml:space="preserve">
+    <value>CurrentProgress</value>
+  </data>
+  <data name="&gt;&gt;CurrentProgress.Type" xml:space="preserve">
+    <value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;CurrentProgress.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;CurrentProgress.ZOrder" xml:space="preserve">
+    <value>6</value>
+  </data>
+  <data name="TotalProgress.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 72</value>
+  </data>
+  <data name="TotalProgress.Size" type="System.Drawing.Size, System.Drawing">
+    <value>384, 23</value>
+  </data>
+  <data name="TotalProgress.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="&gt;&gt;TotalProgress.Name" xml:space="preserve">
+    <value>TotalProgress</value>
+  </data>
+  <data name="&gt;&gt;TotalProgress.Type" xml:space="preserve">
+    <value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;TotalProgress.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;TotalProgress.ZOrder" xml:space="preserve">
+    <value>5</value>
+  </data>
+  <data name="label1.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 40</value>
+  </data>
+  <data name="label1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>23, 13</value>
+  </data>
+  <data name="label1.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="label1.Text" xml:space="preserve">
+    <value>File</value>
+  </data>
+  <data name="&gt;&gt;label1.Name" xml:space="preserve">
+    <value>label1</value>
+  </data>
+  <data name="&gt;&gt;label1.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;label1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
+    <value>4</value>
+  </data>
+  <data name="TotalLabel.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="TotalLabel.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 72</value>
+  </data>
+  <data name="TotalLabel.Size" type="System.Drawing.Size, System.Drawing">
+    <value>31, 13</value>
+  </data>
+  <data name="TotalLabel.TabIndex" type="System.Int32, mscorlib">
+    <value>3</value>
+  </data>
+  <data name="TotalLabel.Text" xml:space="preserve">
+    <value>Total</value>
+  </data>
+  <data name="&gt;&gt;TotalLabel.Name" xml:space="preserve">
+    <value>TotalLabel</value>
+  </data>
+  <data name="&gt;&gt;TotalLabel.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;TotalLabel.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;TotalLabel.ZOrder" xml:space="preserve">
+    <value>3</value>
+  </data>
+  <data name="label3.AutoSize" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="label3.Location" type="System.Drawing.Point, System.Drawing">
+    <value>16, 8</value>
+  </data>
+  <data name="label3.Size" type="System.Drawing.Size, System.Drawing">
+    <value>53, 13</value>
+  </data>
+  <data name="label3.TabIndex" type="System.Int32, mscorlib">
+    <value>4</value>
+  </data>
+  <data name="label3.Text" xml:space="preserve">
+    <value>Operation</value>
+  </data>
+  <data name="&gt;&gt;label3.Name" xml:space="preserve">
+    <value>label3</value>
+  </data>
+  <data name="&gt;&gt;label3.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;label3.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
+    <value>2</value>
+  </data>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="OperationLabel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Top, Left, Right</value>
+  </data>
+  <data name="OperationLabel.Location" type="System.Drawing.Point, System.Drawing">
+    <value>88, 8</value>
+  </data>
+  <data name="OperationLabel.Size" type="System.Drawing.Size, System.Drawing">
+    <value>384, 13</value>
+  </data>
+  <data name="OperationLabel.TabIndex" type="System.Int32, mscorlib">
+    <value>5</value>
+  </data>
+  <data name="OperationLabel.Text" xml:space="preserve">
+    <value>OperationLabel</value>
+  </data>
+  <data name="&gt;&gt;OperationLabel.Name" xml:space="preserve">
+    <value>OperationLabel</value>
+  </data>
+  <data name="&gt;&gt;OperationLabel.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;OperationLabel.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;OperationLabel.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="CancelBtn.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="CancelBtn.Location" type="System.Drawing.Point, System.Drawing">
+    <value>184, 112</value>
+  </data>
+  <data name="CancelBtn.Size" type="System.Drawing.Size, System.Drawing">
+    <value>112, 24</value>
+  </data>
+  <data name="CancelBtn.TabIndex" type="System.Int32, mscorlib">
+    <value>6</value>
+  </data>
+  <data name="CancelBtn.Text" xml:space="preserve">
+    <value>Cancel</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Name" xml:space="preserve">
+    <value>CancelBtn</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <metadata name="backgroundWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
+    <value>6, 13</value>
+  </data>
+  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
+    <value>489, 146</value>
+  </data>
+  <data name="$this.Text" xml:space="preserve">
+    <value>Building package</value>
+  </data>
+  <data name="&gt;&gt;backgroundWorker.Name" xml:space="preserve">
+    <value>backgroundWorker</value>
+  </data>
+  <data name="&gt;&gt;backgroundWorker.Type" xml:space="preserve">
+    <value>System.ComponentModel.BackgroundWorker, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;$this.Name" xml:space="preserve">
+    <value>PackageProgress</value>
+  </data>
+  <data name="&gt;&gt;$this.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+</root>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/Properties/AssemblyInfo.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/Properties/AssemblyInfo.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/Properties/AssemblyInfo.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Maestro.Packaging")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Maestro.Packaging")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("898031bf-637e-4c1b-a87a-3d0e5403cb2c")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.Designer.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.Designer.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.Designer.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,225 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.4952
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Maestro.Packaging.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Maestro.Packaging.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Do you want to cancel?.
+        /// </summary>
+        internal static string CancelConfirmation {
+            get {
+                return ResourceManager.GetString("CancelConfirmation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to find file {0} in archive.
+        /// </summary>
+        internal static string FileMissingError {
+            get {
+                return ResourceManager.GetString("FileMissingError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Filename &quot;{0}&quot; is not relative to &quot;{1}&quot;.
+        /// </summary>
+        internal static string FilenameRelationInternalError {
+            get {
+                return ResourceManager.GetString("FilenameRelationInternalError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed to locate file MgResourcePackageManifest.xml in zip file. Most likely the file is not a MapGuide package..
+        /// </summary>
+        internal static string InvalidPackageFileError {
+            get {
+                return ResourceManager.GetString("InvalidPackageFileError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Compressed.
+        /// </summary>
+        internal static string ProgressCompressed {
+            get {
+                return ResourceManager.GetString("ProgressCompressed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Compressing ....
+        /// </summary>
+        internal static string ProgressCompressing {
+            get {
+                return ResourceManager.GetString("ProgressCompressing", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Compressing files ....
+        /// </summary>
+        internal static string ProgressCompressing1 {
+            get {
+                return ResourceManager.GetString("ProgressCompressing1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Done.
+        /// </summary>
+        internal static string ProgressDone {
+            get {
+                return ResourceManager.GetString("ProgressDone", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Reading package contents ....
+        /// </summary>
+        internal static string ProgressReadingPackage {
+            get {
+                return ResourceManager.GetString("ProgressReadingPackage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Updated references.
+        /// </summary>
+        internal static string ProgressUpdatedReferences {
+            get {
+                return ResourceManager.GetString("ProgressUpdatedReferences", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Updated resources.
+        /// </summary>
+        internal static string ProgressUpdatedResources {
+            get {
+                return ResourceManager.GetString("ProgressUpdatedResources", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Updating references ....
+        /// </summary>
+        internal static string ProgressUpdatingReferences {
+            get {
+                return ResourceManager.GetString("ProgressUpdatingReferences", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Updating resource references ....
+        /// </summary>
+        internal static string ProgressUpdatingReferences1 {
+            get {
+                return ResourceManager.GetString("ProgressUpdatingReferences1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Updating resources ....
+        /// </summary>
+        internal static string ProgressUpdatingResources {
+            get {
+                return ResourceManager.GetString("ProgressUpdatingResources", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Uploading, {0:0.00} of {1:0.00} mb ....
+        /// </summary>
+        internal static string ProgressUploading {
+            get {
+                return ResourceManager.GetString("ProgressUploading", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Awating server processing ....
+        /// </summary>
+        internal static string ProgressWaitingForServer {
+            get {
+                return ResourceManager.GetString("ProgressWaitingForServer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to MapGuide Packages (*.mgp)|*.mgp|Zip files (*.zip)|*.zip|All files (*.*)|*.*.
+        /// </summary>
+        internal static string UploadPackageDialogFilter {
+            get {
+                return ResourceManager.GetString("UploadPackageDialogFilter", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Select the package to upload.
+        /// </summary>
+        internal static string UploadPackageDialogTitle {
+            get {
+                return ResourceManager.GetString("UploadPackageDialogTitle", resourceCulture);
+            }
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.resx
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.resx	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/Properties/Resources.resx	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="CancelConfirmation" xml:space="preserve">
+    <value>Do you want to cancel?</value>
+    <comment>A confirmation message displayed when the user presses the cancel button</comment>
+  </data>
+  <data name="FileMissingError" xml:space="preserve">
+    <value>Failed to find file {0} in archive</value>
+    <comment>An error message that is displayed if a file is missing in a package</comment>
+  </data>
+  <data name="FilenameRelationInternalError" xml:space="preserve">
+    <value>Filename "{0}" is not relative to "{1}"</value>
+    <comment>An internal error that is displayed when a filename inconsistency is encountered</comment>
+  </data>
+  <data name="InvalidPackageFileError" xml:space="preserve">
+    <value>Failed to locate file MgResourcePackageManifest.xml in zip file. Most likely the file is not a MapGuide package.</value>
+    <comment>An error message that is displayed if the package file is invalid</comment>
+  </data>
+  <data name="ProgressCompressed" xml:space="preserve">
+    <value>Compressed</value>
+    <comment>A progress message that is displayed when the files are compressed</comment>
+  </data>
+  <data name="ProgressCompressing" xml:space="preserve">
+    <value>Compressing ...</value>
+    <comment>A progress message that is displayed while compressing files</comment>
+  </data>
+  <data name="ProgressCompressing1" xml:space="preserve">
+    <value>Compressing files ...</value>
+    <comment>A message that is displayed while compressing files</comment>
+  </data>
+  <data name="ProgressDone" xml:space="preserve">
+    <value>Done</value>
+    <comment>A progress message that is displayed when the operation is done</comment>
+  </data>
+  <data name="ProgressReadingPackage" xml:space="preserve">
+    <value>Reading package contents ...</value>
+    <comment>A message that is displayed while reading the package contents</comment>
+  </data>
+  <data name="ProgressUpdatedReferences" xml:space="preserve">
+    <value>Updated references</value>
+    <comment>A progress message that is displayed when references are updated</comment>
+  </data>
+  <data name="ProgressUpdatedResources" xml:space="preserve">
+    <value>Updated resources</value>
+    <comment>A progress message that is displayed when resources are updated</comment>
+  </data>
+  <data name="ProgressUpdatingReferences" xml:space="preserve">
+    <value>Updating references ...</value>
+    <comment>A progress message that is displayed while updating references</comment>
+  </data>
+  <data name="ProgressUpdatingReferences1" xml:space="preserve">
+    <value>Updating resource references ...</value>
+    <comment>A message that is displayed while updating resource references</comment>
+  </data>
+  <data name="ProgressUpdatingResources" xml:space="preserve">
+    <value>Updating resources ...</value>
+    <comment>A progress message that is displayed while updating resources</comment>
+  </data>
+  <data name="ProgressUploading" xml:space="preserve">
+    <value>Uploading, {0:0.00} of {1:0.00} mb ...</value>
+    <comment>A message that is displayed while uploading the file</comment>
+  </data>
+  <data name="ProgressWaitingForServer" xml:space="preserve">
+    <value>Awating server processing ...</value>
+    <comment>A message that is displayed after the file is uploaded, and the server restores the file</comment>
+  </data>
+  <data name="UploadPackageDialogFilter" xml:space="preserve">
+    <value>MapGuide Packages (*.mgp)|*.mgp|Zip files (*.zip)|*.zip|All files (*.*)|*.*</value>
+    <comment>A filename filter for selecting a MapGuide package</comment>
+  </data>
+  <data name="UploadPackageDialogTitle" xml:space="preserve">
+    <value>Select the package to upload</value>
+    <comment>The title for the file browse dialog when uploading a package</comment>
+  </data>
+</root>
\ No newline at end of file

Added: sandbox/maestro-3.0/Maestro.Packaging/ResourceDataItem.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/ResourceDataItem.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/ResourceDataItem.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,85 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Maestro.Packaging
+{
+    /// <summary>
+    /// Represents a data item on a resource
+    /// </summary>
+    public class ResourceDataItem
+    {
+        private string m_resourceName;
+        private string m_contentType;
+        private string m_filename;
+        private string m_dataType;
+        private EntryTypeEnum m_entryType;
+
+        public ResourceDataItem(string resourceName, string contentType, string filename, string dataType)
+        {
+            m_resourceName = resourceName;
+            m_contentType = contentType;
+            m_filename = filename;
+            m_dataType = dataType;
+            m_entryType = EntryTypeEnum.Regular;
+        }
+
+        public ResourceDataItem(ResourceDataItem rdi)
+        {
+            m_resourceName = rdi.m_resourceName;
+            m_contentType = rdi.m_contentType;
+            m_filename = rdi.m_filename;
+            m_dataType = rdi.m_dataType;
+            m_entryType = rdi.m_entryType;
+        }
+
+        public string ResourceName
+        {
+            get { return m_resourceName; }
+            set { m_resourceName = value; }
+        }
+
+        public string ContentType
+        {
+            get { return m_contentType; }
+            set { m_contentType = value; }
+        }
+
+        public string Filename
+        {
+            get { return m_filename; }
+            set { m_filename = value; }
+        }
+
+        public EntryTypeEnum EntryType
+        {
+            get { return m_entryType; }
+            set { m_entryType = value; }
+        }
+
+        public string DataType
+        {
+            get { return m_dataType; }
+            set { m_dataType = value; }
+        }
+    }
+}

Added: sandbox/maestro-3.0/Maestro.Packaging/ResourceItem.cs
===================================================================
--- sandbox/maestro-3.0/Maestro.Packaging/ResourceItem.cs	                        (rev 0)
+++ sandbox/maestro-3.0/Maestro.Packaging/ResourceItem.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,106 @@
+#region Disclaimer / License
+// Copyright (C) 2009, Kenneth Skovhede
+// http://www.hexad.dk, opensource at hexad.dk
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Maestro.Packaging
+{
+    /// <summary>
+    /// Represents a resource item from a package
+    /// </summary>
+    public class ResourceItem
+    {
+
+        public ResourceItem(string resourcePath, string headerPath, string contentPath)
+        {
+            m_originalResourcePath = m_resourcePath = resourcePath;
+            m_headerpath = headerPath;
+            m_contentpath = contentPath;
+            m_entryType = EntryTypeEnum.Regular;
+            m_items = new List<ResourceDataItem>();
+            m_isFolder = m_originalResourcePath.EndsWith("/");
+        }
+
+        public ResourceItem(ResourceItem ri)
+        {
+            m_originalResourcePath = ri.m_originalResourcePath;
+            m_headerpath = ri.m_headerpath;
+            m_contentpath = ri.m_contentpath;
+            m_resourcePath = ri.m_resourcePath;
+            m_entryType = ri.m_entryType;
+            m_isFolder = ri.m_isFolder;
+            m_items = new List<ResourceDataItem>();
+            foreach (ResourceDataItem rdi in ri.m_items)
+                m_items.Add(new ResourceDataItem(rdi));
+        }
+
+        private string m_originalResourcePath;
+        private string m_headerpath;
+        private string m_contentpath;
+        private string m_resourcePath;
+        private EntryTypeEnum m_entryType;
+        private List<ResourceDataItem> m_items;
+        private bool m_isFolder;
+
+        public bool IsFolder
+        {
+            get { return m_isFolder; }
+            set { m_isFolder = true; }
+        }
+
+        public List<ResourceDataItem> Items
+        {
+            get { return m_items; }
+            set { m_items = value; }
+        }
+
+        public EntryTypeEnum EntryType
+        {
+            get { return m_entryType; }
+            set { m_entryType = value; }
+        }
+
+
+        public string OriginalResourcePath
+        {
+            get { return m_originalResourcePath; }
+            set { m_originalResourcePath = value; }
+        }
+
+        public string ResourcePath
+        {
+            get { return m_resourcePath; }
+            set { m_resourcePath = value; }
+        }
+
+        public string Contentpath
+        {
+            get { return m_contentpath; }
+            set { m_contentpath = value; }
+        }
+
+        public string Headerpath
+        {
+            get { return m_headerpath; }
+            set { m_headerpath = value; }
+        }
+    }
+}

Modified: sandbox/maestro-3.0/MaestroAPITests/CapabilityTests.cs
===================================================================
--- sandbox/maestro-3.0/MaestroAPITests/CapabilityTests.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/MaestroAPITests/CapabilityTests.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -161,6 +161,14 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                if (rt != ResourceTypes.ApplicationDefinition && rt != ResourceTypes.SymbolDefinition)
+                    Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+                else
+                    Assert.IsFalse(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
 
         [Test]
@@ -290,6 +298,14 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                if (rt != ResourceTypes.ApplicationDefinition && rt != ResourceTypes.SymbolDefinition)
+                    Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+                else
+                    Assert.IsFalse(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
 
         [Test]
@@ -412,6 +428,14 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                if (rt != ResourceTypes.ApplicationDefinition)
+                    Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+                else
+                    Assert.IsFalse(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
 
         [Test]
@@ -527,6 +551,11 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
 
         [Test]
@@ -642,6 +671,11 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
 
         [Test]
@@ -757,6 +791,11 @@
                         break;
                 }
             }
+
+            foreach (ResourceTypes rt in Enum.GetValues(typeof(ResourceTypes)))
+            {
+                Assert.IsTrue(caps.IsSupportedResourceType(rt), rt.ToString());
+            }
         }
     }
 }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Capability/ConnectionCapabilities.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Capability/ConnectionCapabilities.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/Capability/ConnectionCapabilities.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -51,5 +51,12 @@
         {
             get { return false; }
         }
+
+        public abstract bool IsSupportedResourceType(string resourceType);
+
+        public bool IsSupportedResourceType(ResourceTypes resType)
+        {
+            return IsSupportedResourceType(resType.ToString());
+        }
     }
 }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IConnectionCapabilities.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IConnectionCapabilities.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/IConnectionCapabilities.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -51,5 +51,19 @@
         /// Indicates whether previewing capabilities are possible with this connection
         /// </summary>
         bool SupportsResourcePreviews { get; }
+
+        /// <summary>
+        /// Indicates if this current connection supports the specified resource type
+        /// </summary>
+        /// <param name="resType"></param>
+        /// <returns></returns>
+        bool IsSupportedResourceType(string resType);
+
+        /// <summary>
+        /// Indicates if this current connection supports the specified resource type
+        /// </summary>
+        /// <param name="resType"></param>
+        /// <returns></returns>
+        bool IsSupportedResourceType(ResourceTypes resType);
     }
 }

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2010-09-29 07:53:06 UTC (rev 5208)
@@ -198,6 +198,7 @@
     <Compile Include="ObjectModels\PrintLayout.cs" />
     <Compile Include="ObjectModels\ResourceItems.cs" />
     <Compile Include="ObjectModels\ResourceList.cs" />
+    <Compile Include="ObjectModels\ResourcePackageManifest.cs" />
     <Compile Include="ObjectModels\SymbolDefinition.cs" />
     <Compile Include="ObjectModels\SymbolLibrary.cs" />
     <Compile Include="ObjectModels\UnmanagedDataList.cs" />

Added: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ResourcePackageManifest.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ResourcePackageManifest.cs	                        (rev 0)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI/ObjectModels/ResourcePackageManifest.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OSGeo.MapGuide.ObjectModels.Common
+{
+    partial class ResourcePackageManifestOperationsOperationParameters
+    {
+        public string GetParameterValue(string name)
+        {
+            if (this.parameterField != null)
+            {
+                foreach (var p in this.parameterField)
+                {
+                    if (p.Name.Equals(name))
+                    {
+                        return p.Value;
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void SetParameterValue(string name, string value)
+        {
+            if (this.parameterField == null)
+                this.parameterField = new System.ComponentModel.BindingList<ResourcePackageManifestOperationsOperationParametersParameter>();
+
+            foreach (var p in this.parameterField)
+            {
+                if (p.Name.Equals(name))
+                {
+                    p.Value = value;
+                    return;
+                }
+            }
+
+            this.parameterField.Add(new ResourcePackageManifestOperationsOperationParametersParameter()
+            {
+                Name = name,
+                Value = value
+            });
+        }
+    }
+}

Modified: sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpCapabilities.cs
===================================================================
--- sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpCapabilities.cs	2010-09-29 05:53:44 UTC (rev 5207)
+++ sandbox/maestro-3.0/OSGeo.MapGuide.MaestroAPI.Http/HttpCapabilities.cs	2010-09-29 07:53:06 UTC (rev 5208)
@@ -22,10 +22,11 @@
 using System.Text;
 using OSGeo.MapGuide.MaestroAPI.Services;
 using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.MaestroAPI.Capability;
 
 namespace OSGeo.MapGuide.MaestroAPI.Http
 {
-    internal class HttpCapabilities : IConnectionCapabilities
+    internal class HttpCapabilities : ConnectionCapabilities
     {
         private IServerConnection _parent;
 
@@ -34,7 +35,7 @@
             _parent = parent;
         }
 
-        public Version GetMaxSupportedResourceVersion(ResourceTypes resourceType)
+        public override Version GetMaxSupportedResourceVersion(ResourceTypes resourceType)
         {
             Version ver = new Version(1, 0, 0);
             switch (resourceType)
@@ -109,7 +110,7 @@
             return new Version(1, 0, 0);
         }
 
-        public int[] SupportedCommands
+        public override int[] SupportedCommands
         {
             get 
             {
@@ -121,7 +122,7 @@
             }
         }
 
-        public int[] SupportedServices
+        public override int[] SupportedServices
         {
             get 
             {
@@ -149,14 +150,30 @@
             }
         }
 
-        public bool SupportsResourcePreviews
+        public override bool SupportsResourcePreviews
         {
             get { return true; }
         }
 
-        public bool IsMultithreaded
+        public override bool IsMultithreaded
         {
             get { return false; }
         }
+
+        public override bool IsSupportedResourceType(string resourceType)
+        {
+            Check.NotEmpty(resourceType, "resourceType");
+            var ver = _parent.SiteVersion;
+            var rt = (ResourceTypes)Enum.Parse(typeof(ResourceTypes), resourceType);
+            switch (rt)
+            {
+                case ResourceTypes.ApplicationDefinition: //Introduced in 2.0.0
+                    return (ver >= new Version(2, 0));
+                case ResourceTypes.SymbolDefinition: //Introduced in 1.2.0
+                    return (ver >= new Version(1, 2));
+            }
+
+            return true;
+        }
     }
 }



More information about the mapguide-commits mailing list