[mapguide-commits] r6883 - in branches/2.4/MgDev/Desktop: MapViewer MapViewer/AppLayoutEngine MapViewer/Properties MapViewer/Tasks MgAppLayout SampleExtension SampleExtension/Resources

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Jul 9 09:26:49 PDT 2012


Author: jng
Date: 2012-07-09 09:26:48 -0700 (Mon, 09 Jul 2012)
New Revision: 6883

Added:
   branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.cs
   branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.resx
   branches/2.4/MgDev/Desktop/SampleExtension/BufferHelper.cs
   branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs
   branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.resx
   branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs
   branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.resx
   branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.cs
   branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.resx
   branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.resx
   branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.cs
   branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.resx
   branches/2.4/MgDev/Desktop/SampleExtension/LayerDefinitionFactory.cs
   branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.cs
   branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.resx
   branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx
   branches/2.4/MgDev/Desktop/SampleExtension/MgSampleTaskPaneComponent.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.resx
   branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.cs
   branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.resx
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/BufferLayerDefinition.txt
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/ParcelMarker.txt
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/RecentlyBuilt.txt
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/arearule.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/areatypestyle.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/layerdefinition.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/linerule.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/linetypestyle.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/marksymbol.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointrule.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointtypestyle.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/scalerange.templ
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/textsymbol.templ
   branches/2.4/MgDev/Desktop/SampleExtension/SampleComponents.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.resx
   branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.resx
   branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.cs
   branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.resx
Modified:
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgPrintComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgPrintControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgPropertyPane.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgQueryComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgTaskPane.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgThemeComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsControlImpl.cs
   branches/2.4/MgDev/Desktop/MapViewer/Properties/AssemblyInfo.cs
   branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs
   branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
   branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
Log:
This submission contains the following changes:
 - #2062: Turn the existing SampleExtension project into the mg-desktop equivalent of the MapGuide Developer's Guide samples. This includes all samples except (Digitizing and Redlining) and (Custom Output), which have yet to be implemented.
 - Rename MgControlImpl to MgControlView (a more meaningful name)
 - Expose MgDictionaryPropertyGridAdapter as a public class
 - Make the AppLayout shell a singleton, accessible by Shell.Instance

Modified: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -9,11 +9,29 @@
 
 namespace OSGeo.MapGuide.Viewer.AppLayoutEngine
 {
-    public partial class Shell : Form, IMapStatusBar
+    public partial class Shell : Form, IShell
     {
-        public Shell(AppLayout layout, MgMapViewerProvider provider)
+        private Shell()
         {
             InitializeComponent();
+        }
+
+        private static Shell _instance;
+
+        public static IShell Instance
+        {
+            get
+            {
+                if (null == _instance)
+                {
+                    _instance = new Shell();
+                }
+                return _instance;
+            }
+        }
+
+        public void Initialize(AppLayout layout, MgMapViewerProvider provider)
+        {
             this.Text = layout.Title;
             _menuInvoker = new MgMenuItemComponentInvoker();
             _toolInvoker = new MgToolButtonComponentInvoker();
@@ -41,12 +59,20 @@
                 SetPropertyPaneVisbility(_layout.InfoPane.PropertyPane.Visible);
             }
             SetTaskPaneWidth(_layout.TaskPane.Width);
+            if (!string.IsNullOrEmpty(_layout.TaskPane.InitialComponentID))
+            {
+                var cmp = GetComponent(_layout.TaskPane.InitialComponentID) as MgViewerComponent;
+                if (cmp != null)
+                    taskPane.SetInitialComponent(cmp);
+                else
+                    MessageBox.Show("WARNING: The specified initial task component id (" + _layout.TaskPane.InitialComponentID + ") does not exist in the AppLayout");
+            }
 
             _provider = provider;
             mapViewer.PropertyChanged += new PropertyChangedEventHandler(OnMapViewerPropertyChanged);
         }
 
-        public void SetTaskPaneWidth(uint width)
+        internal void SetTaskPaneWidth(uint width)
         {
             if (appContainer.Panel2Collapsed)
                 appContainer.Panel2Collapsed = false;
@@ -54,7 +80,7 @@
             appContainer.SplitterDistance = (int)(appContainer.Width - width);
         }
 
-        public void SetInfoPaneWidth(uint width)
+        internal void SetInfoPaneWidth(uint width)
         {
             if (infoPaneViewerContainer.Panel1Collapsed)
                 infoPaneViewerContainer.Panel1Collapsed = false;
@@ -62,22 +88,22 @@
             infoPaneViewerContainer.SplitterDistance = (int)width;
         }
 
-        public void SetLegendVisbility(bool visible)
+        internal void SetLegendVisbility(bool visible)
         {
             layerPropertiesContainer.Panel1Collapsed = !visible;
         }
 
-        public void SetPropertyPaneVisbility(bool visible)
+        internal void SetPropertyPaneVisbility(bool visible)
         {
             layerPropertiesContainer.Panel2Collapsed = !visible;
         }
 
-        public void SetTaskPaneVisible(bool visible)
+        internal void SetTaskPaneVisible(bool visible)
         {
             appContainer.Panel2Collapsed = !visible;
         }
 
-        public void SetInfoPaneVisible(bool visible)
+        internal void SetInfoPaneVisible(bool visible)
         {
             infoPaneViewerContainer.Panel1Collapsed = !visible;
         }
@@ -373,26 +399,28 @@
                 if (vc != null)
                 {
                     vc.OwnerParent = this;
+                    if (vc.Target == MgViewerTarget.TaskPane)
+                        vc.TaskPane = taskPane;
                 }
             }
         }
 
-        void IMapStatusBar.SetCursorPositionMessage(string message)
+        public void SetCursorPositionMessage(string message)
         {
             lblCoordinates.Text = message;
         }
 
-        void IMapStatusBar.SetFeatureSelectedMessage(string message)
+        public void SetFeatureSelectedMessage(string message)
         {
             lblSelected.Text = message;
         }
 
-        void IMapStatusBar.SetMapScaleMessage(string message)
+        public void SetMapScaleMessage(string message)
         {
             lblMapScale.Text = message;
         }
 
-        void IMapStatusBar.SetMapSizeMessage(string message)
+        public void SetMapSizeMessage(string message)
         {
             lblMapSize.Text = message;
         }
@@ -401,5 +429,45 @@
         {
             taskPane.LoadInitialTask();
         }
+
+        public MgComponent GetComponent(string componentId)
+        {
+            return _components.ContainsKey(componentId) ? _components[componentId] : null;
+        }
+
+
+        public IMapLegend Legend
+        {
+            get { return legend; }
+        }
+
+        public IPropertyPane PropertyPane
+        {
+            get { return propertyPane; }
+        }
+
+        public MgTaskPane TaskPane
+        {
+            get { return taskPane; }
+        }
+
+        public void ReloadViewer(MgMapViewerProvider provider)
+        {
+            _provider = provider;
+            mapViewer.Init(_provider);
+        }
     }
+
+    public interface IShell : IMapStatusBar
+    {
+        MgComponent GetComponent(string componentId);
+
+        IMapLegend Legend { get; }
+
+        IPropertyPane PropertyPane { get; }
+
+        MgTaskPane TaskPane { get; }
+
+        void ReloadViewer(MgMapViewerProvider provider);
+    }
 }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgBufferComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -27,7 +27,7 @@
         [MgComponentProperty]
         public MeasurementUnit DefaultBufferUnits { get; set; }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             return new MgBufferControlImpl(this.Viewer, this.DefaultLayerName, this.DefaultBufferUnits);
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -9,7 +9,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    internal partial class MgBufferControlImpl : MgControlImpl
+    internal partial class MgBufferControlImpl : MgControlView
     {
         private IMapViewer _viewer;
         private MgResourceService _resSvc;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -322,11 +322,13 @@
         /// Creates the associated view. Must be overridden by subclasses
         /// </summary>
         /// <returns></returns>
-        protected virtual MgControlImpl CreateControlImpl() { throw new NotImplementedException(); }
+        protected virtual MgControlView CreateControlView() { throw new NotImplementedException(); }
 
+        internal MgControlView CreateControl() { return CreateControlView(); }
+
         public override void Invoke()
         {
-            var control = CreateControlImpl();
+            var control = CreateControlView();
             control.Dock = DockStyle.Fill;
             if (this.Target == MgViewerTarget.TaskPane)
             {
@@ -341,9 +343,9 @@
         class TaskPaneContentCloser : IContentCloser
         {
             private MgTaskPane _taskPane;
-            private MgControlImpl _control;
+            private MgControlView _control;
 
-            public TaskPaneContentCloser(MgTaskPane taskPane, MgControlImpl control)
+            public TaskPaneContentCloser(MgTaskPane taskPane, MgControlView control)
             {
                 _taskPane = taskPane;
                 _control = control;
@@ -354,6 +356,7 @@
 
             public void Close()
             {
+                _control.Dispose();
                 _taskPane.LoadInitialTask();
             }
         }
@@ -361,9 +364,9 @@
         class NewWindowContentCloser : IContentCloser 
         {
             private Form _frm;
-            private MgControlImpl _control;
+            private MgControlView _control;
 
-            public NewWindowContentCloser(MgControlImpl control, Form owner)
+            public NewWindowContentCloser(MgControlView control, Form owner)
             {
                 _frm = new Form();
                 _control = control;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -10,15 +10,26 @@
     /// Base class for views show by their associated <see cref="T:OSGeo.MapGuide.Viewer.MgViewerComponent"/> instances
     /// </summary>
     [ToolboxItem(false)]
-    public class MgControlImpl : UserControl
+    public class MgControlView : UserControl
     {
         /// <summary>
         /// Gets or set the title to show if this view is shown in a new window
         /// </summary>
         public virtual string Title { get; set; }
 
-        protected MgControlImpl() { this.ModalWindow = false; }
+        protected MgControlView() { this.ModalWindow = false; }
 
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                SubCleanup();
+            }
+            base.Dispose(disposing);
+        }
+
+        protected virtual void SubCleanup() { }
+
         /// <summary>
         /// Gets whether to show as a modal window if parent component chooses to show this component
         /// in a new window. Only applies if parent component shows this component in a new window

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -41,6 +41,7 @@
             var selLayers = sel.GetLayers();
             if (selLayers != null)
             {
+                var selectionSet = new MgSelectionSet(sel, _viewer.GetProvider().AllPropertyMappings);
                 var layers = new Dictionary<string, MgLayerBase>();
                 for (int i = 0; i < selLayers.Count; i++)
                 {
@@ -54,7 +55,6 @@
                         var h = this.SelectionMade;
                         if (h != null)
                         {
-                            var selectionSet = new MgSelectionSet(sel, _viewer.GetProvider().AllPropertyMappings);
                             h(selectionSet);
                         }
                     }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLineMeasureControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -8,7 +8,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    internal partial class MgLineMeasureControlImpl : MgControlImpl
+    internal partial class MgLineMeasureControlImpl : MgControlView
     {
         private IMapViewer _viewer;
         private MgCoordinateSystem _mapCs;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMeasureComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -19,7 +19,7 @@
             this.PreferredUnits = MeasurementUnit.Meters;
         }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             switch (_measureMode)
             {

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgPrintComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgPrintComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgPrintComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -14,7 +14,7 @@
             this.Icon = Properties.Resources.print;
         }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             return new MgPrintControlImpl(this.Viewer);
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgPrintControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgPrintControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgPrintControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -8,7 +8,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    public partial class MgPrintControlImpl : MgControlImpl
+    public partial class MgPrintControlImpl : MgControlView
     {
         private IMapViewer _viewer;
 

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgPropertyPane.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgPropertyPane.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgPropertyPane.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -80,7 +80,7 @@
             var feat = this.CurrentFeature;
             if (feat != null)
             {
-                propGrid.SelectedObject = new DictionaryPropertyGridAdapter(feat.Properties);
+                propGrid.SelectedObject = new MgDictionaryPropertyGridAdapter(feat.Properties);
             }
         }
 
@@ -179,11 +179,11 @@
         }
     }
 
-    internal class DictionaryPropertyGridAdapter : ICustomTypeDescriptor
+    public class MgDictionaryPropertyGridAdapter : ICustomTypeDescriptor
     {
         IDictionary _dictionary;
 
-        public DictionaryPropertyGridAdapter(IDictionary d)
+        public MgDictionaryPropertyGridAdapter(IDictionary d)
         {
             _dictionary = d;
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgQueryComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgQueryComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgQueryComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -17,7 +17,7 @@
             this.Label = this.ToolTipText = Properties.Resources.TitleQuery;
         }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             return new MgQueryControlImpl(this.Viewer);
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgQueryControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -8,7 +8,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    internal partial class MgQueryControlImpl : MgControlImpl
+    internal partial class MgQueryControlImpl : MgControlView
     {
         private IMapViewer _viewer;
         private MgWktReaderWriter _wktRw;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgTaskPane.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgTaskPane.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgTaskPane.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -32,7 +32,7 @@
             c.Dock = DockStyle.Top; //This allows for scrolling
             rootContainer.Controls.Clear();
             rootContainer.Controls.Add(c);
-            var mgc = c as MgControlImpl;
+            var mgc = c as MgControlView;
             if (mgc != null)
                 lblTitle.Text = mgc.Title;
             else
@@ -53,5 +53,12 @@
         {
             LoadInitialTask();
         }
+
+        internal void SetInitialComponent(MgViewerComponent cmp)
+        {
+            if (cmp.Target != MgViewerTarget.TaskPane)
+                throw new InvalidOperationException("The specified component's target is not the Task Pane");
+            this.InitialTask = cmp.CreateControl();
+        }
     }
 }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgThemeComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgThemeComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgThemeComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -14,7 +14,7 @@
             this.Label = this.ToolTipText = Properties.Resources.TitleTheme;
         }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             return new MgThemeControlImpl(this.Viewer);
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -10,7 +10,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    public partial class MgThemeControlImpl : MgControlImpl
+    public partial class MgThemeControlImpl : MgControlView
     {
         private IMapViewer _viewer;
         private BindingList<MgDataPropertyDefinition> _properties;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -57,7 +57,7 @@
             }
         }
 
-        protected override MgControlImpl CreateControlImpl()
+        protected override MgControlView CreateControlView()
         {
             return new MgViewerOptionsControlImpl(this.Viewer, this.PreferencesDirectory);
         }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsControlImpl.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsControlImpl.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgViewerOptionsControlImpl.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -10,7 +10,7 @@
 
 namespace OSGeo.MapGuide.Viewer
 {
-    public partial class MgViewerOptionsControlImpl : MgControlImpl
+    public partial class MgViewerOptionsControlImpl : MgControlView
     {
         private IMapViewer _viewer;
         private string _saveDirectory;

Modified: branches/2.4/MgDev/Desktop/MapViewer/Properties/AssemblyInfo.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Properties/AssemblyInfo.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/Properties/AssemblyInfo.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -35,5 +35,4 @@
 [assembly: AssemblyVersion("1.0.0.0")]
 [assembly: AssemblyFileVersion("1.0.0.0")]
 
-
 [assembly: AssemblyKeyFile("..\\DesktopUnmanagedApi\\DotNet\\MgDesktop.snk")]

Modified: branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MapViewer/Tasks/MgTaskPaneStub.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -9,7 +9,7 @@
 namespace OSGeo.MapGuide.Viewer.Tasks
 {
     [ToolboxItem(false)]
-    internal partial class MgTaskPaneStub : MgControlImpl
+    internal partial class MgTaskPaneStub : MgControlView
     {
         public MgTaskPaneStub()
         {

Modified: branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Program.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -61,9 +61,10 @@
             var resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
             if (resSvc.ResourceExists(mdfId))
                 provider.LoadMap(new MgdMap(mdfId));
-            var frm = new Shell(layout, provider);
+            var frm = Shell.Instance;
+            ((Shell)frm).Initialize(layout, provider);
             Application.ApplicationExit += new EventHandler(OnAppExit);
-            Application.Run(frm);
+            Application.Run((Shell)frm);
         }
 
         static void OnAppExit(object sender, EventArgs e)

Modified: branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	2012-07-09 16:26:48 UTC (rev 6883)
@@ -247,6 +247,7 @@
   </ContextMenu>
   <TaskPane>
     <Width>250</Width>
+    <InitialComponentID>SamplesTaskPane</InitialComponentID>
     <TaskMenu>
       <Items>
         <ItemBase xsi:type="CommandItem">
@@ -448,5 +449,50 @@
       <Assembly>SampleExtension.dll</Assembly>
       <ClassName>SampleExtension.MgStartupComponent</ClassName>
     </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>SamplesTaskPane</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgSampleTaskPaneComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>HelloMap</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgHelloMapComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>HelloViewer</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgHelloViewerComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>InteractingWithLayers</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgInteractingWithLayersComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>WorkingWithFeatureData</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgWorkingWithFeatureDataComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ModifyingMapsAndLayers</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgModifyingMapsAndLayersComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>AnalyzingFeatures</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgAnalyzingFeaturesComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>DigitizingAndRedlining</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgDigitizingAndRedliningComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>CustomOutput</ComponentID>
+      <Assembly>SampleExtension.dll</Assembly>
+      <ClassName>SampleExtension.MgCustomOutputComponent</ClassName>
+    </ComponentDefinition>
   </Components>
 </AppLayout>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,85 @@
+namespace SampleExtension
+{
+    partial class AnalyzingFeatures
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnCreateBuffer = new System.Windows.Forms.Button();
+            this.btnFindFeaturesInBuffer = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(17, 18);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(178, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This samples demonstrates buffering";
+            // 
+            // btnCreateBuffer
+            // 
+            this.btnCreateBuffer.Location = new System.Drawing.Point(20, 80);
+            this.btnCreateBuffer.Name = "btnCreateBuffer";
+            this.btnCreateBuffer.Size = new System.Drawing.Size(175, 23);
+            this.btnCreateBuffer.TabIndex = 1;
+            this.btnCreateBuffer.Text = "Create Buffer";
+            this.btnCreateBuffer.UseVisualStyleBackColor = true;
+            this.btnCreateBuffer.Click += new System.EventHandler(this.btnCreateBuffer_Click);
+            // 
+            // btnFindFeaturesInBuffer
+            // 
+            this.btnFindFeaturesInBuffer.Location = new System.Drawing.Point(20, 110);
+            this.btnFindFeaturesInBuffer.Name = "btnFindFeaturesInBuffer";
+            this.btnFindFeaturesInBuffer.Size = new System.Drawing.Size(175, 23);
+            this.btnFindFeaturesInBuffer.TabIndex = 2;
+            this.btnFindFeaturesInBuffer.Text = "Find Features in Buffer";
+            this.btnFindFeaturesInBuffer.UseVisualStyleBackColor = true;
+            this.btnFindFeaturesInBuffer.Click += new System.EventHandler(this.btnFindFeaturesInBuffer_Click);
+            // 
+            // AnalyzingFeatures
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnFindFeaturesInBuffer);
+            this.Controls.Add(this.btnCreateBuffer);
+            this.Controls.Add(this.label1);
+            this.Name = "AnalyzingFeatures";
+            this.Size = new System.Drawing.Size(244, 359);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnCreateBuffer;
+        private System.Windows.Forms.Button btnFindFeaturesInBuffer;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,331 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
+
+namespace SampleExtension
+{
+    public partial class AnalyzingFeatures : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public AnalyzingFeatures(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = "Analyzing Features";
+            _viewer = viewer;
+        }
+
+        private void btnCreateBuffer_Click(object sender, EventArgs e)
+        {
+            MgSelectionBase selection = _viewer.GetSelection();
+            MgReadOnlyLayerCollection layers = selection.GetLayers();
+            if (layers == null)
+            {
+                MessageBox.Show("Select a parcel");
+                return;
+            }
+            MgLayerBase parcels = null;
+            for (int i = 0; i < layers.GetCount(); i++)
+            {
+                MgLayerBase layer = layers.GetItem(i);
+                if (layer.Name == "Parcels")
+                {
+                    parcels = layer;
+                    break;
+                }
+            }
+            if (parcels == null)
+            {
+                MessageBox.Show("Select a parcel");
+                return;
+            }
+
+            int bufferRingSize = 100; // measured in metres
+            int bufferRingCount = 5;
+
+            // Set up some objects for coordinate conversion
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection mapLayers = map.GetLayers();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            //Casting to MgdFeatureService because we want to use convenience APIs
+            MgFeatureService featureService = (MgdFeatureService)provider.CreateService(MgServiceType.FeatureService);
+
+            String mapWktSrs = map.GetMapSRS();
+            MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
+            MgWktReaderWriter wktReaderWriter = new MgWktReaderWriter();
+            MgCoordinateSystemFactory coordinateSystemFactory = new MgCoordinateSystemFactory();
+            MgCoordinateSystem srs = coordinateSystemFactory.Create(mapWktSrs);
+            MgMeasure srsMeasure = srs.GetMeasure();
+            string sessionId = Guid.NewGuid().ToString();
+
+            BufferHelper helper = new BufferHelper();
+
+            // Check for a buffer layer. If it exists, delete
+            // the current features.
+            // If it does not exist, create a feature source and
+            // a layer to hold the buffer.
+
+            MgdLayer bufferLayer = null;
+            int layerIndex = mapLayers.IndexOf("Buffer");
+            if (layerIndex < 0)
+            {
+                // The layer does not exist and must be created.
+
+                MgResourceIdentifier bufferFeatureResId = new MgResourceIdentifier("Session:" + sessionId + "//Buffer.FeatureSource");
+                helper.CreateBufferFeatureSource(featureService, mapWktSrs, bufferFeatureResId);
+                bufferLayer = helper.CreateBufferLayer(resourceService, bufferFeatureResId, sessionId);
+                mapLayers.Insert(0, bufferLayer);
+            }
+            else
+            {
+                bufferLayer = (MgdLayer)map.GetLayers().GetItem(layerIndex);
+                bufferLayer.DeleteFeatures("ID like '%'");
+            }
+
+            // Get the selected features from the MgSelection object
+            MgFeatureReader featureReader = selection.GetSelectedFeatures(parcels, parcels.GetFeatureClassName(), false);
+
+            // Process each item in the MgFeatureReader. Get the
+            // geometries from all the selected features and
+            // merge them into a single geometry.
+
+            MgGeometryCollection inputGeometries = new MgGeometryCollection();
+            while (featureReader.ReadNext())
+            {
+                MgByteReader featureGeometryData = featureReader.GetGeometry(parcels.GetFeatureGeometryName());
+                MgGeometry featureGeometry = agfReaderWriter.Read(featureGeometryData);
+
+                inputGeometries.Add(featureGeometry);
+            }
+
+            MgGeometryFactory geometryFactory = new MgGeometryFactory();
+            MgGeometry mergedGeometries = geometryFactory.CreateMultiGeometry(inputGeometries);
+
+            // Add buffer features to the temporary feature source.
+            // Create multiple concentric buffers to show area.
+            // If the stylization for the layer draws the features
+            // partially transparent, the concentric rings will be
+            // progressively darker towards the center.
+            // The stylization is set in the layer template file, which
+            // is used in function CreateBufferLayer().
+
+            for (int bufferRing = 0; bufferRing < bufferRingCount; bufferRing++)
+            {
+                double bufferDist = srs.ConvertMetersToCoordinateSystemUnits(bufferRingSize * (bufferRing + 1));
+                MgGeometry bufferGeometry = mergedGeometries.Buffer(bufferDist, srsMeasure);
+
+                MgPropertyCollection properties = new MgPropertyCollection();
+                properties.Add(new MgGeometryProperty("BufferGeometry", agfReaderWriter.Write(bufferGeometry)));
+
+                MgFeatureReader fr = bufferLayer.InsertFeatures(properties);
+                fr.Close();
+            }
+
+            bufferLayer.SetVisible(true);
+            bufferLayer.ForceRefresh();
+            bufferLayer.SetDisplayInLegend(true);
+
+            MessageBox.Show("Buffer created");
+            _viewer.RefreshMap();
+            IMapLegend legend = Shell.Instance.Legend;
+            if (legend != null)
+                legend.RefreshLegend();
+        }
+
+        private void btnFindFeaturesInBuffer_Click(object sender, EventArgs e)
+        {
+            MgSelectionBase selection = _viewer.GetSelection();
+            MgReadOnlyLayerCollection selectedLayers = selection.GetLayers();
+            if (selectedLayers == null)
+            {
+                MessageBox.Show("Select a parcel");
+                return;
+            }
+            MgLayerBase parcels = null;
+            for (int i = 0; i < selectedLayers.GetCount(); i++)
+            {
+                MgLayerBase layer = selectedLayers.GetItem(i);
+                if (layer.Name == "Parcels")
+                {
+                    parcels = layer;
+                    break;
+                }
+            }
+            if (parcels == null)
+            {
+                MessageBox.Show("Select a parcel");
+                return;
+            }
+
+            int bufferRingSize = 500; // measured in metres
+
+            // Set up some objects for coordinate conversion
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection mapLayers = map.GetLayers();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            //Casting to MgdFeatureService because we want to use convenience APIs
+            MgFeatureService featureService = (MgdFeatureService)provider.CreateService(MgServiceType.FeatureService);
+            string sessionId = Guid.NewGuid().ToString();
+
+            String mapWktSrs = map.GetMapSRS();
+            MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
+            MgWktReaderWriter wktReaderWriter = new MgWktReaderWriter();
+            MgCoordinateSystemFactory coordinateSystemFactory = new MgCoordinateSystemFactory();
+            MgCoordinateSystem srs = coordinateSystemFactory.Create(mapWktSrs);
+            MgMeasure srsMeasure = srs.GetMeasure();
+
+            // Check for a buffer layer. If it exists, delete
+            // the current features.
+            // If it does not exist, create a feature source and
+            // a layer to hold the buffer.
+
+            BufferHelper helper = new BufferHelper();
+            MgdLayer bufferLayer = null;
+            int layerIndex = map.GetLayers().IndexOf("Buffer");
+            if (layerIndex < 0)
+            {
+                // The layer does not exist and must be created.
+
+                MgResourceIdentifier bufferFeatureResId = new MgResourceIdentifier("Session:" + sessionId + "//Buffer.FeatureSource");
+                helper.CreateBufferFeatureSource(featureService, mapWktSrs, bufferFeatureResId);
+                bufferLayer = helper.CreateBufferLayer(resourceService, bufferFeatureResId, sessionId);
+                map.GetLayers().Insert(0, bufferLayer);
+            }
+            else
+            {
+                bufferLayer = (MgdLayer)map.GetLayers().GetItem(layerIndex);
+                bufferLayer.DeleteFeatures("ID like '%'");
+            }
+
+            // Check for a parcel marker layer. If it exists, delete
+            // the current features.
+            // If it does not exist, create a feature source and
+            // a layer to hold the parcel markers.
+
+            MgdLayer parcelMarkerLayer = null;
+            layerIndex = map.GetLayers().IndexOf("ParcelMarker");
+            if (layerIndex < 0)
+            {
+                MgResourceIdentifier parcelFeatureResId = new MgResourceIdentifier("Session:" + sessionId + "//ParcelMarker.FeatureSource");
+                helper.CreateParcelMarkerFeatureSource(featureService, mapWktSrs, parcelFeatureResId);
+                parcelMarkerLayer = helper.CreateParcelMarkerLayer(resourceService, parcelFeatureResId, sessionId);
+                map.GetLayers().Insert(0, parcelMarkerLayer);
+            }
+            else
+            {
+                parcelMarkerLayer = (MgdLayer)map.GetLayers().GetItem(layerIndex);
+                parcelMarkerLayer.DeleteFeatures("ID like '%'");
+            }
+
+            // Check each layer in the selection.
+
+            for (int i = 0; i < selectedLayers.GetCount(); i++)
+            {
+                // Only check selected features in the Parcels layer.
+
+                MgdLayer layer = (MgdLayer)selectedLayers.GetItem(i);
+
+                if (layer.GetName() == "Parcels")
+                {
+                    string geomName = layer.GetFeatureGeometryName();
+                    System.Diagnostics.Trace.TraceInformation("Marking all parcels inside the buffer that are of type 'MFG'");
+
+                    MgFeatureReader featureReader = selection.GetSelectedFeatures(layer, layer.GetFeatureClassName(), false);
+
+
+                    // Process each item in the MgFeatureReader. Get the
+                    // geometries from all the selected features and
+                    // merge them into a single geometry.
+
+                    MgGeometryCollection inputGeometries = new MgGeometryCollection();
+                    while (featureReader.ReadNext())
+                    {
+                        MgByteReader featureGeometryData = featureReader.GetGeometry(geomName);
+                        MgGeometry featureGeometry = agfReaderWriter.Read(featureGeometryData);
+
+                        inputGeometries.Add(featureGeometry);
+                    }
+
+                    MgGeometryFactory geometryFactory = new MgGeometryFactory();
+                    MgGeometry mergedGeometries = geometryFactory.CreateMultiGeometry(inputGeometries);
+
+                    // Create a buffer from the merged geometries
+
+                    double bufferDist = srs.ConvertMetersToCoordinateSystemUnits(bufferRingSize);
+                    MgGeometry bufferGeometry = mergedGeometries.Buffer(bufferDist, srsMeasure);
+
+                    // Create a filter to select parcels within the buffer. Combine
+                    // a basic filter and a spatial filter to select all parcels
+                    // within the buffer that are of type "MFG".
+
+                    MgFeatureQueryOptions queryOptions = new MgFeatureQueryOptions();
+                    queryOptions.SetFilter("RTYPE = 'MFG'");
+                    queryOptions.SetSpatialFilter(geomName, bufferGeometry, MgFeatureSpatialOperations.Inside);
+
+                    featureReader = layer.SelectFeatures(queryOptions);
+
+                    // Get the features from the feature source,
+                    // determine the centroid of each selected feature, and
+                    // add a point to the ParcelMarker layer to mark the
+                    // centroid.
+                    // Collect all the points into an MgFeatureCommandCollection,
+                    // so they can all be added in one operation.
+
+                    MgFeatureCommandCollection parcelMarkerCommands = new MgFeatureCommandCollection();
+                    int inserted = 0;
+                    while (featureReader.ReadNext())
+                    {
+                        MgByteReader byteReader = featureReader.GetGeometry(geomName);
+                        MgGeometry geometry = agfReaderWriter.Read(byteReader);
+                        MgPoint point = geometry.GetCentroid();
+
+                        // Create an insert command for this parcel.
+                        MgPropertyCollection properties = new MgPropertyCollection();
+                        properties.Add(new MgGeometryProperty("ParcelLocation", agfReaderWriter.Write(point)));
+                        //parcelMarkerCommands.Add(new MgInsertFeatures("ParcelMarkerClass", properties));
+                        MgFeatureReader fr = parcelMarkerLayer.InsertFeatures(properties);
+                        fr.Close();
+                        inserted++;
+                    }
+                    featureReader.Close();
+
+                    if (inserted == 0)
+                    {
+                        MessageBox.Show("No parcels within the buffer area match.");
+                        return;
+                    }
+
+                    // Create a feature in the buffer feature source to show the area covered by the buffer.
+
+                    MgPropertyCollection props = new MgPropertyCollection();
+                    props.Add(new MgGeometryProperty("BufferGeometry", agfReaderWriter.Write(bufferGeometry)));
+                    bufferLayer.InsertFeatures(props);
+
+                    // Ensure that the buffer layer is visible and in the legend.
+
+                    bufferLayer.SetVisible(true);
+                    bufferLayer.ForceRefresh();
+                    bufferLayer.SetDisplayInLegend(true);
+                    parcelMarkerLayer.SetVisible(true);
+                    parcelMarkerLayer.ForceRefresh();
+
+                    MessageBox.Show("Done");
+                    _viewer.RefreshMap();
+                    IMapLegend legend = Shell.Instance.Legend;
+                    if (legend != null)
+                        legend.RefreshLegend();
+                }
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/AnalyzingFeatures.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/BufferHelper.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/BufferHelper.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/BufferHelper.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,178 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide;
+using System.IO;
+using System.Xml;
+
+namespace SampleExtension
+{
+    public class BufferHelper
+    {
+        public void CreateBufferFeatureSource(MgFeatureService featureService, String wkt, MgResourceIdentifier bufferFeatureResId)
+        {
+            MgClassDefinition bufferClass = new MgClassDefinition();
+            bufferClass.SetName("BufferClass");
+            MgPropertyDefinitionCollection properties = bufferClass.GetProperties();
+
+            MgDataPropertyDefinition idProperty = new MgDataPropertyDefinition("ID");
+            idProperty.SetDataType(MgPropertyType.Int32);
+            idProperty.SetReadOnly(true);
+            idProperty.SetNullable(false);
+            idProperty.SetAutoGeneration(true);
+            properties.Add(idProperty);
+
+            MgGeometricPropertyDefinition polygonProperty = new MgGeometricPropertyDefinition("BufferGeometry");
+            polygonProperty.SetGeometryTypes(MgFeatureGeometricType.Surface);
+            polygonProperty.SetHasElevation(false);
+            polygonProperty.SetHasMeasure(false);
+            polygonProperty.SetReadOnly(false);
+            polygonProperty.SetSpatialContextAssociation("defaultSrs");
+            properties.Add(polygonProperty);
+
+            MgPropertyDefinitionCollection idProperties = bufferClass.GetIdentityProperties();
+            idProperties.Add(idProperty);
+
+            bufferClass.SetDefaultGeometryPropertyName("BufferGeometry");
+
+            MgFeatureSchema bufferSchema = new MgFeatureSchema("BufferLayerSchema", "temporary schema to hold a buffer");
+            bufferSchema.GetClasses().Add(bufferClass);
+
+            MgCreateSdfParams sdfParams = new MgCreateSdfParams("defaultSrs", wkt, bufferSchema);
+
+            featureService.CreateFeatureSource(bufferFeatureResId, sdfParams);
+        }
+
+        public MgdLayer CreateBufferLayer(MgResourceService resourceService, MgResourceIdentifier bufferFeatureResId, String sessionId)
+        {
+            // Load the layer definition template into
+            // a XmlDocument object, find the "ResourceId" element, and
+            // modify its content to reference the temporary
+            // feature source.
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml(Layers.BufferLayerDefinition);
+            XmlNode featureSourceNode = doc.GetElementsByTagName("ResourceId")[0];
+            featureSourceNode.InnerText = bufferFeatureResId.ToString();
+
+            // Get the updated layer definition from the XmlDocument
+            // and save it to the session repository using the
+            // ResourceService object.
+
+            MgByteSource byteSource = null;
+            using (MemoryStream ms = new MemoryStream())
+            {
+                doc.Save(ms);
+                ms.Position = 0L;
+
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] layerDefinition = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(layerDefinition));
+                layerDefinition = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, layerDefinition, 0);
+
+                byteSource = new MgByteSource(layerDefinition, layerDefinition.Length);
+                byteSource.SetMimeType(MgMimeType.Xml);
+            }
+
+            MgResourceIdentifier tempLayerResId = new MgResourceIdentifier("Session:" + sessionId + "//Buffer.LayerDefinition");
+
+            resourceService.SetResource(tempLayerResId, byteSource.GetReader(), null);
+
+            // Create an MgLayer object based on the new layer definition
+            // and return it to the caller.
+
+            MgdLayer bufferLayer = new MgdLayer(tempLayerResId, resourceService);
+            bufferLayer.SetName("Buffer");
+            bufferLayer.SetLegendLabel("Buffer");
+            bufferLayer.SetDisplayInLegend(true);
+            bufferLayer.SetSelectable(false);
+
+            return bufferLayer;
+        }
+
+        public void CreateParcelMarkerFeatureSource(MgFeatureService featureService, String wkt, MgResourceIdentifier parcelMarkerDataResId)
+        {
+            MgClassDefinition parcelClass = new MgClassDefinition();
+            parcelClass.SetName("ParcelMarkerClass");
+            MgPropertyDefinitionCollection properties = parcelClass.GetProperties();
+
+            MgDataPropertyDefinition idProperty = new MgDataPropertyDefinition("ID");
+            idProperty.SetDataType(MgPropertyType.Int32);
+            idProperty.SetReadOnly(true);
+            idProperty.SetNullable(false);
+            idProperty.SetAutoGeneration(true);
+            properties.Add(idProperty);
+
+            MgGeometricPropertyDefinition pointProperty = new MgGeometricPropertyDefinition("ParcelLocation");
+            pointProperty.SetGeometryTypes(MgGeometryType.Point);
+            pointProperty.SetHasElevation(false);
+            pointProperty.SetHasMeasure(false);
+            pointProperty.SetReadOnly(false);
+            pointProperty.SetSpatialContextAssociation("defaultSrs");
+            properties.Add(pointProperty);
+
+            MgPropertyDefinitionCollection idProperties = parcelClass.GetIdentityProperties();
+            idProperties.Add(idProperty);
+
+            parcelClass.SetDefaultGeometryPropertyName("ParcelLocation");
+
+            MgFeatureSchema parcelSchema = new MgFeatureSchema("ParcelLayerSchema", "temporary schema to hold parcel markers");
+            parcelSchema.GetClasses().Add(parcelClass);
+
+            MgCreateSdfParams sdfParams = new MgCreateSdfParams("defaultSrs", wkt, parcelSchema);
+
+            featureService.CreateFeatureSource(parcelMarkerDataResId, sdfParams);
+        }
+
+        public MgdLayer CreateParcelMarkerLayer(MgResourceService resourceService, MgResourceIdentifier parcelMarkerDataResId, String sessionId)
+        {
+            // Load the ParcelMarker layer definition template into
+            // a XmlDocument object, find the "ResourceId" element, and
+            // modify its content to reference the temporary
+            // feature source.
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml(Layers.ParcelMarker);
+            XmlNode featureSourceNode = doc.GetElementsByTagName("ResourceId")[0];
+            featureSourceNode.InnerText = parcelMarkerDataResId.ToString();
+
+            // Get the updated layer definition from the DOM object
+            // and save it to the session repository using the
+            // ResourceService object.
+
+            MgByteSource byteSource = null;
+            using (MemoryStream ms = new MemoryStream())
+            {
+                doc.Save(ms);
+                ms.Position = 0L;
+
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] layerDefinition = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(layerDefinition));
+                layerDefinition = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, layerDefinition, 0);
+
+                byteSource = new MgByteSource(layerDefinition, layerDefinition.Length);
+                byteSource.SetMimeType(MgMimeType.Xml);
+            }
+
+            MgResourceIdentifier tempLayerResId = new MgResourceIdentifier("Session:" + sessionId + "//ParcelMarker.LayerDefinition");
+
+            resourceService.SetResource(tempLayerResId, byteSource.GetReader(), null);
+
+            // Create an MgLayer object based on the new layer definition
+            // and return it to the caller.
+
+            MgdLayer parcelMarkerLayer = new MgdLayer(tempLayerResId, resourceService);
+            parcelMarkerLayer.SetName("ParcelMarker");
+            parcelMarkerLayer.SetLegendLabel("ParcelMarker");
+            parcelMarkerLayer.SetDisplayInLegend(true);
+            parcelMarkerLayer.SetSelectable(false);
+
+            return parcelMarkerLayer;
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,59 @@
+namespace SampleExtension
+{
+    partial class CustomOutput
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(19, 22);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(196, 52);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This sample demonstrates outputting the current map to various output formats";
+            // 
+            // CustomOutput
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.label1);
+            this.Name = "CustomOutput";
+            this.Size = new System.Drawing.Size(231, 436);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+
+namespace SampleExtension
+{
+    public partial class CustomOutput : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public CustomOutput(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = "Custom Output";
+            _viewer = viewer;
+        }
+
+
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,59 @@
+namespace SampleExtension
+{
+    partial class DigitizingAndRedlining
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(18, 16);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(201, 50);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This sample demonstrates digitizing and redlining";
+            // 
+            // DigitizingAndRedlining
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.label1);
+            this.Name = "DigitizingAndRedlining";
+            this.Size = new System.Drawing.Size(236, 472);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+
+namespace SampleExtension
+{
+    public partial class DigitizingAndRedlining : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public DigitizingAndRedlining(IMapViewer viewer)
+        {
+            InitializeComponent();
+            _viewer = viewer;
+            this.Title = "Digitizing and Redlining";
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,99 @@
+namespace SampleExtension
+{
+    partial class HelloMap
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnDisplaySpatialReference = new System.Windows.Forms.Button();
+            this.btnListLayers = new System.Windows.Forms.Button();
+            this.btnListLayerGroups = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(19, 22);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(203, 64);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This sample shows the most basic interaction with a map. It obtains a reference t" +
+                "o the current map and queries information about it";
+            // 
+            // btnDisplaySpatialReference
+            // 
+            this.btnDisplaySpatialReference.Location = new System.Drawing.Point(22, 103);
+            this.btnDisplaySpatialReference.Name = "btnDisplaySpatialReference";
+            this.btnDisplaySpatialReference.Size = new System.Drawing.Size(186, 23);
+            this.btnDisplaySpatialReference.TabIndex = 1;
+            this.btnDisplaySpatialReference.Text = "Display Spatial Reference";
+            this.btnDisplaySpatialReference.UseVisualStyleBackColor = true;
+            this.btnDisplaySpatialReference.Click += new System.EventHandler(this.btnDisplaySpatialReference_Click);
+            // 
+            // btnListLayers
+            // 
+            this.btnListLayers.Location = new System.Drawing.Point(22, 132);
+            this.btnListLayers.Name = "btnListLayers";
+            this.btnListLayers.Size = new System.Drawing.Size(186, 23);
+            this.btnListLayers.TabIndex = 2;
+            this.btnListLayers.Text = "List Layers";
+            this.btnListLayers.UseVisualStyleBackColor = true;
+            this.btnListLayers.Click += new System.EventHandler(this.btnListLayers_Click);
+            // 
+            // btnListLayerGroups
+            // 
+            this.btnListLayerGroups.Location = new System.Drawing.Point(22, 162);
+            this.btnListLayerGroups.Name = "btnListLayerGroups";
+            this.btnListLayerGroups.Size = new System.Drawing.Size(186, 23);
+            this.btnListLayerGroups.TabIndex = 3;
+            this.btnListLayerGroups.Text = "List Layer Groups";
+            this.btnListLayerGroups.UseVisualStyleBackColor = true;
+            this.btnListLayerGroups.Click += new System.EventHandler(this.btnListLayerGroups_Click);
+            // 
+            // HelloMap
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnListLayerGroups);
+            this.Controls.Add(this.btnListLayers);
+            this.Controls.Add(this.btnDisplaySpatialReference);
+            this.Controls.Add(this.label1);
+            this.Name = "HelloMap";
+            this.Size = new System.Drawing.Size(242, 402);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnDisplaySpatialReference;
+        private System.Windows.Forms.Button btnListLayers;
+        private System.Windows.Forms.Button btnListLayerGroups;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public partial class HelloMap : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public HelloMap(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = "Hello Map";
+            _viewer = viewer;
+        }
+
+        private void btnDisplaySpatialReference_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgResourceIdentifier resId = map.MapDefinition;
+            string mapSrs = map.GetMapSRS();
+
+            MessageBox.Show("Map: (" + resId.ToString() + ") uses this reference system: " + Environment.NewLine + Environment.NewLine + mapSrs);
+        }
+
+        private void btnListLayers_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgResourceIdentifier resId = map.MapDefinition;
+            MgLayerCollection layers = map.GetLayers();
+
+            List<string> results = new List<string>();
+            for (int i = 0; i < layers.GetCount(); i++)
+            {
+                MgLayerBase layer = layers.GetItem(i);
+                results.Add(layer.Name + " (" + layer.LegendLabel + ")");
+            }
+
+            MessageBox.Show("Map (" + resId.ToString() + ") has " + layers.GetCount() + " layers: " + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, results.ToArray()));
+        }
+
+        private void btnListLayerGroups_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgResourceIdentifier resId = map.MapDefinition;
+            MgLayerGroupCollection groups = map.GetLayerGroups();
+
+            List<string> results = new List<string>();
+            for (int i = 0; i < groups.GetCount(); i++)
+            {
+                MgLayerGroup group = groups.GetItem(i);
+                results.Add(group.Name + " (" + group.LegendLabel + ")");
+            }
+
+            MessageBox.Show("Map (" + resId.ToString() + ") has " + groups.GetCount() + " layers: " + Environment.NewLine + Environment.NewLine + string.Join(Environment.NewLine, results.ToArray()));
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloMap.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,135 @@
+namespace SampleExtension
+{
+    partial class HelloViewer
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnZoomToLocation = new System.Windows.Forms.Button();
+            this.btnClearSelection = new System.Windows.Forms.Button();
+            this.lblViewerBusyState = new System.Windows.Forms.Label();
+            this.btnCopyMap = new System.Windows.Forms.Button();
+            this.btnInitialView = new System.Windows.Forms.Button();
+            this.lblActiveTool = new System.Windows.Forms.Label();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(18, 18);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(247, 109);
+            this.label1.TabIndex = 1;
+            this.label1.Text = "This sample demonstrates viewer interaction\r\n\r\nAll MgComponent instances contain " +
+                "a reference to the viewer (IMapViewer)";
+            // 
+            // btnZoomToLocation
+            // 
+            this.btnZoomToLocation.Location = new System.Drawing.Point(21, 198);
+            this.btnZoomToLocation.Name = "btnZoomToLocation";
+            this.btnZoomToLocation.Size = new System.Drawing.Size(181, 23);
+            this.btnZoomToLocation.TabIndex = 2;
+            this.btnZoomToLocation.Text = "Zoom To Location";
+            this.btnZoomToLocation.UseVisualStyleBackColor = true;
+            this.btnZoomToLocation.Click += new System.EventHandler(this.btnZoomToLocation_Click);
+            // 
+            // btnClearSelection
+            // 
+            this.btnClearSelection.Location = new System.Drawing.Point(21, 227);
+            this.btnClearSelection.Name = "btnClearSelection";
+            this.btnClearSelection.Size = new System.Drawing.Size(181, 23);
+            this.btnClearSelection.TabIndex = 4;
+            this.btnClearSelection.Text = "Clear Selection";
+            this.btnClearSelection.UseVisualStyleBackColor = true;
+            this.btnClearSelection.Click += new System.EventHandler(this.btnClearSelection_Click);
+            // 
+            // lblViewerBusyState
+            // 
+            this.lblViewerBusyState.AutoSize = true;
+            this.lblViewerBusyState.Location = new System.Drawing.Point(18, 138);
+            this.lblViewerBusyState.Name = "lblViewerBusyState";
+            this.lblViewerBusyState.Size = new System.Drawing.Size(0, 13);
+            this.lblViewerBusyState.TabIndex = 5;
+            // 
+            // btnCopyMap
+            // 
+            this.btnCopyMap.Location = new System.Drawing.Point(21, 256);
+            this.btnCopyMap.Name = "btnCopyMap";
+            this.btnCopyMap.Size = new System.Drawing.Size(181, 23);
+            this.btnCopyMap.TabIndex = 6;
+            this.btnCopyMap.Text = "Copy Map to Clipboard";
+            this.btnCopyMap.UseVisualStyleBackColor = true;
+            this.btnCopyMap.Click += new System.EventHandler(this.btnCopyMap_Click);
+            // 
+            // btnInitialView
+            // 
+            this.btnInitialView.Location = new System.Drawing.Point(21, 285);
+            this.btnInitialView.Name = "btnInitialView";
+            this.btnInitialView.Size = new System.Drawing.Size(181, 23);
+            this.btnInitialView.TabIndex = 7;
+            this.btnInitialView.Text = "Initial View";
+            this.btnInitialView.UseVisualStyleBackColor = true;
+            this.btnInitialView.Click += new System.EventHandler(this.btnInitialView_Click);
+            // 
+            // lblActiveTool
+            // 
+            this.lblActiveTool.AutoSize = true;
+            this.lblActiveTool.Location = new System.Drawing.Point(18, 167);
+            this.lblActiveTool.Name = "lblActiveTool";
+            this.lblActiveTool.Size = new System.Drawing.Size(0, 13);
+            this.lblActiveTool.TabIndex = 8;
+            // 
+            // HelloViewer
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.lblActiveTool);
+            this.Controls.Add(this.btnInitialView);
+            this.Controls.Add(this.btnCopyMap);
+            this.Controls.Add(this.lblViewerBusyState);
+            this.Controls.Add(this.btnClearSelection);
+            this.Controls.Add(this.btnZoomToLocation);
+            this.Controls.Add(this.label1);
+            this.Name = "HelloViewer";
+            this.Size = new System.Drawing.Size(283, 330);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnZoomToLocation;
+        private System.Windows.Forms.Button btnClearSelection;
+        private System.Windows.Forms.Label lblViewerBusyState;
+        private System.Windows.Forms.Button btnCopyMap;
+        private System.Windows.Forms.Button btnInitialView;
+        private System.Windows.Forms.Label lblActiveTool;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public partial class HelloViewer : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public HelloViewer(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = "Hello Viewer";
+            _viewer = viewer;
+
+            _viewer.PropertyChanged += OnViewerPropertyChanged;
+            _viewer.SelectionChanged += OnViewerSelectionChanged;
+            CheckSelectionState();
+            CheckBusyState();
+            CheckActiveTool();
+        }
+
+        protected override void SubCleanup()
+        {
+            //When subscribing to events, be a responsible user and 
+            //unsubscribe on cleanup
+            _viewer.PropertyChanged -= OnViewerPropertyChanged;
+            _viewer.SelectionChanged -= OnViewerSelectionChanged;
+        }
+
+        void OnViewerPropertyChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == "IsBusy")
+                CheckBusyState();
+            else if (e.PropertyName == "ActiveTool")
+                CheckActiveTool();
+        }
+
+        void OnViewerSelectionChanged(object sender, EventArgs e)
+        {
+            CheckSelectionState();
+        }
+
+        private void CheckActiveTool()
+        {
+            lblActiveTool.Text = "Active Tool: " + _viewer.ActiveTool.ToString();
+        }
+
+        private void CheckBusyState()
+        {
+            lblViewerBusyState.Text = "Viewer " + ((_viewer.IsBusy) ? "is busy" : "is not busy");
+        }
+
+        private void CheckSelectionState()
+        {
+            MgSelectionBase selection = _viewer.GetSelection();
+            MgReadOnlyLayerCollection layers = selection.GetLayers();
+            if (layers != null)
+                btnClearSelection.Enabled = true;
+            else
+                btnClearSelection.Enabled = false;
+        }
+
+        private void btnZoomToLocation_Click(object sender, EventArgs e)
+        {
+            _viewer.ZoomToView(-87.732492, 43.743934, 5000, true);
+        }
+
+        private void btnClearSelection_Click(object sender, EventArgs e)
+        {
+            _viewer.ClearSelection();
+        }
+
+        private void btnInitialView_Click(object sender, EventArgs e)
+        {
+            _viewer.InitialMapView();
+        }
+
+        private void btnCopyMap_Click(object sender, EventArgs e)
+        {
+            _viewer.CopyMap();
+            MessageBox.Show("Map image (current view) copied to clipboard");
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/HelloViewer.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,86 @@
+namespace SampleExtension
+{
+    partial class InteractingWithLayers
+    {
+        /// <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 Component 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(InteractingWithLayers));
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnLayerVisibility = new System.Windows.Forms.Button();
+            this.btnRenameRoadsLayer = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(15, 19);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(180, 125);
+            this.label1.TabIndex = 2;
+            this.label1.Text = resources.GetString("label1.Text");
+            // 
+            // btnLayerVisibility
+            // 
+            this.btnLayerVisibility.Location = new System.Drawing.Point(18, 147);
+            this.btnLayerVisibility.Name = "btnLayerVisibility";
+            this.btnLayerVisibility.Size = new System.Drawing.Size(177, 23);
+            this.btnLayerVisibility.TabIndex = 3;
+            this.btnLayerVisibility.Text = "Layer Visibility";
+            this.btnLayerVisibility.UseVisualStyleBackColor = true;
+            this.btnLayerVisibility.Click += new System.EventHandler(this.btnLayerVisibility_Click);
+            // 
+            // btnRenameRoadsLayer
+            // 
+            this.btnRenameRoadsLayer.Location = new System.Drawing.Point(18, 176);
+            this.btnRenameRoadsLayer.Name = "btnRenameRoadsLayer";
+            this.btnRenameRoadsLayer.Size = new System.Drawing.Size(177, 23);
+            this.btnRenameRoadsLayer.TabIndex = 4;
+            this.btnRenameRoadsLayer.Text = "Rename Roads Layer to Streets";
+            this.btnRenameRoadsLayer.UseVisualStyleBackColor = true;
+            this.btnRenameRoadsLayer.Click += new System.EventHandler(this.btnRenameRoadsLayer_Click);
+            // 
+            // InteractingWithLayers
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnRenameRoadsLayer);
+            this.Controls.Add(this.btnLayerVisibility);
+            this.Controls.Add(this.label1);
+            this.Name = "InteractingWithLayers";
+            this.Size = new System.Drawing.Size(216, 362);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnLayerVisibility;
+        private System.Windows.Forms.Button btnRenameRoadsLayer;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
+
+namespace SampleExtension
+{
+    public partial class InteractingWithLayers : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public InteractingWithLayers(IMapViewer viewer)
+        {
+            InitializeComponent();
+            _viewer = viewer;
+            this.Title = "Interacting With Layers";
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            if (layers.IndexOf("Roads") >= 0 && layers.IndexOf("Streets") < 0)
+            {
+                btnRenameRoadsLayer.Text = "Rename Roads Layer to Streets";
+            }
+            else if (layers.IndexOf("Roads") < 0 && layers.IndexOf("Streets") >= 0)
+            {
+                btnRenameRoadsLayer.Text = "Rename Streets Layer to Roads";
+            }
+        }
+
+        private void btnLayerVisibility_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            new LayerVisibilityDialog(layers).ShowDialog();
+        }
+
+        private void btnRenameRoadsLayer_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+
+            bool bRefresh = false;
+            if (layers.IndexOf("Roads") >= 0)
+            {
+                MgLayerBase roads = layers.GetItem("Roads");
+                roads.Name = "Streets";
+                roads.LegendLabel = "Streets";
+
+                MessageBox.Show("Layer (Roads) has been changed to (Streets)");
+                btnRenameRoadsLayer.Text = "Rename Streets Layer to Roads";
+                bRefresh = true;
+            }
+            else if (layers.IndexOf("Streets") >= 0)
+            {
+                MgLayerBase streets = layers.GetItem("Streets");
+                streets.Name = "Roads";
+                streets.LegendLabel = "Roads";
+
+                MessageBox.Show("Layer (Streets) has been changed to (Roads)");
+                btnRenameRoadsLayer.Text = "Rename Roads Layer to Streets";
+                bRefresh = true;
+            }
+
+            if (bRefresh)
+            {
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/InteractingWithLayers.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,127 @@
+<?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="label1.Text" xml:space="preserve">
+    <value>This sample demonstrates layer manipulation and interrogation
+
+Unlike the MapGuide Web Extensions API, layer and group changes are immediately reflected on the map. No Open() or Save() is required on the map object, just a refresh of the viewer afterwards
+
+</value>
+  </data>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/LayerDefinitionFactory.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/LayerDefinitionFactory.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/LayerDefinitionFactory.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SampleExtension
+{
+    public class LayerDefinitionFactory
+    {
+        //Creates Area Rule
+        //Parameters:
+        // legendLabel - string for the legend label
+        // filterText - filter string
+        // fillColor - fill color
+        public String CreateAreaRule(String legendLabel, String filterText, String fillColor)
+        {
+            String areaRule = Layers.arearule;
+            areaRule = TemplateUtil.Substitute(areaRule, legendLabel, filterText, fillColor);
+            return areaRule;
+        }
+
+        //Creates AreaTypeStyle.
+        //Parameters:
+        //areaRules - call CreateAreaRule to create area rules
+        public String CreateAreaTypeStyle(String areaRules)
+        {
+            String style = Layers.areatypestyle;
+            style = TemplateUtil.Substitute(style, areaRules);
+            return style;
+        }
+
+        //Creates line rule
+        //Parameters:
+        //color - color code for the line
+        //legendLabel - string for the legend label
+        //filter - filter string
+        public String CreateLineRule(String legendLabel, String filter, String color)
+        {
+            String lineRule = Layers.linerule;
+            lineRule = TemplateUtil.Substitute(lineRule, legendLabel, filter, color);
+            return lineRule;
+        }
+
+        //Creates LineTypeStyle
+        //Parameters:
+        //lineRules - call CreateLineRule to create line rules
+        public String CreateLineTypeStyle(String lineRules)
+        {
+            String lineStyle = Layers.linetypestyle;
+            lineStyle = TemplateUtil.Substitute(lineStyle, lineRules);
+            return lineStyle;
+        }
+
+        //Creates mark symbol
+        //Parameters:
+        //resourceId - resource identifier for the resource to be used
+        //symbolName - the name of the symbol
+        //width - the width of the symbol
+        //height - the height of the symbol
+        //color - color code for the symbol color
+        public String CreateMarkSymbol(String resourceId, String symbolName, String width, String height, String color)
+        {
+            String markSymbol = Layers.marksymbol;
+            markSymbol = TemplateUtil.Substitute(markSymbol, width, height, resourceId, symbolName, color);
+            return markSymbol;
+        }
+
+        //Creates text symbol
+        //Parameters:
+        //text - string for the text
+        //fontHeight - the height for the font
+        //TODO:Can we pass it as a integer (ex. 10) or string (ex"10")
+        //foregroundColor - color code for the foreground color
+        public String CreateTextSymbol(String text, String fontHeight, String foregroundColor)
+        {
+            String textSymbol = Layers.textsymbol;
+            textSymbol = TemplateUtil.Substitute(textSymbol, fontHeight, fontHeight, text, foregroundColor);
+            return textSymbol;
+        }
+
+        //Creates a point rule
+        //Parameters:
+        //pointSym - point symbolization. Use CreateMarkSymbol to create it
+        //legendlabel - string for the legend label
+        //filter - string for the filter
+        //label - use CreateTextSymbol to create it
+        public String CreatePointRule(String legendLabel, String filter, String label, String pointSym)
+        {
+            String pointRule = Layers.pointrule;
+            pointRule = TemplateUtil.Substitute(pointRule, legendLabel, filter, label, pointSym);
+            return pointRule;
+        }
+
+        //Creates PointTypeStyle
+        //Parameters:
+        //pointRule - use CreatePointRule to define rules
+        public String CreatePointTypeStyle(String pointRule)
+        {
+            String pointTypeStyle = Layers.pointtypestyle;
+            pointTypeStyle = TemplateUtil.Substitute(pointTypeStyle, pointRule);
+            return pointTypeStyle;
+        }
+
+        //Creates ScaleRange
+        //Parameterss
+        //minScale - minimum scale
+        //maxScale - maximum scale
+        //typeStyle - use one CreateAreaTypeStyle, CreateLineTypeStyle, or CreatePointTypeStyle
+        public String CreateScaleRange(String minScale, String maxScale, String typeStyle)
+        {
+            String scaleRange = Layers.scalerange;
+            scaleRange = TemplateUtil.Substitute(scaleRange, minScale, maxScale, typeStyle);
+            return scaleRange;
+        }
+
+        //Creates a layer definition
+        //resourceId - resource identifier for the new layer
+        //featureClass - the name of the feature class
+        //geometry - the name of the geometry
+        //featureClassRange - use CreateScaleRange to define it.
+        public String CreateLayerDefinition(String resourceId, String featureClass, String geometry, String featureClassRange)
+        {
+            String layerDef = Layers.layerdefinition;
+            layerDef = TemplateUtil.Substitute(layerDef, resourceId, featureClass, geometry, featureClassRange);
+            return layerDef;
+        }
+    }
+
+
+    public class TemplateUtil
+    {
+        public static String Substitute(String templ, params String[] vals)
+        {
+            StringBuilder res = new StringBuilder();
+            int index = 0, val = 0;
+            bool found;
+            do
+            {
+                found = false;
+                int i = templ.IndexOf('%', index);
+                if (i != -1)
+                {
+                    found = true;
+                    res.Append(templ.Substring(index, i - index));
+                    if (i < templ.Length - 1)
+                    {
+                        if (templ[i + 1] == '%')
+                            res.Append('%');
+                        else if (templ[i + 1] == 's')
+                            res.Append(vals[val++]);
+                        else
+                            res.Append('@');    //add a character illegal in jscript so we know the template was incorrect
+                        index = i + 2;
+                    }
+                }
+            } while (found);
+            res.Append(templ.Substring(index));
+            return res.ToString();
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,122 @@
+namespace SampleExtension
+{
+    partial class LayerVisibilityDialog
+    {
+        /// <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(LayerVisibilityDialog));
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.COL_IS_VISIBLE = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            this.COL_GET_VISIBLE = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            this.COL_LAYER = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            this.grdLayers = new System.Windows.Forms.DataGridView();
+            ((System.ComponentModel.ISupportInitialize)(this.grdLayers)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(25, 227);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(354, 105);
+            this.label1.TabIndex = 1;
+            this.label1.Text = resources.GetString("label1.Text");
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(22, 9);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(102, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Layers in draw order";
+            // 
+            // COL_IS_VISIBLE
+            // 
+            this.COL_IS_VISIBLE.HeaderText = "IsVisible()";
+            this.COL_IS_VISIBLE.Name = "COL_IS_VISIBLE";
+            this.COL_IS_VISIBLE.ReadOnly = true;
+            // 
+            // COL_GET_VISIBLE
+            // 
+            this.COL_GET_VISIBLE.HeaderText = "GetVisible()";
+            this.COL_GET_VISIBLE.Name = "COL_GET_VISIBLE";
+            this.COL_GET_VISIBLE.ReadOnly = true;
+            // 
+            // COL_LAYER
+            // 
+            this.COL_LAYER.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
+            this.COL_LAYER.HeaderText = "Layer";
+            this.COL_LAYER.Name = "COL_LAYER";
+            this.COL_LAYER.ReadOnly = true;
+            // 
+            // grdLayers
+            // 
+            this.grdLayers.AllowUserToAddRows = false;
+            this.grdLayers.AllowUserToDeleteRows = false;
+            this.grdLayers.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                        | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.grdLayers.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.grdLayers.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.COL_LAYER,
+            this.COL_GET_VISIBLE,
+            this.COL_IS_VISIBLE});
+            this.grdLayers.Location = new System.Drawing.Point(25, 39);
+            this.grdLayers.Name = "grdLayers";
+            this.grdLayers.ReadOnly = true;
+            this.grdLayers.Size = new System.Drawing.Size(354, 185);
+            this.grdLayers.TabIndex = 0;
+            // 
+            // LayerVisibilityDialog
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(413, 341);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.grdLayers);
+            this.Name = "LayerVisibilityDialog";
+            this.Text = "Layer Visibility";
+            ((System.ComponentModel.ISupportInitialize)(this.grdLayers)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.DataGridViewTextBoxColumn COL_IS_VISIBLE;
+        private System.Windows.Forms.DataGridViewTextBoxColumn COL_GET_VISIBLE;
+        private System.Windows.Forms.DataGridViewTextBoxColumn COL_LAYER;
+        private System.Windows.Forms.DataGridView grdLayers;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public partial class LayerVisibilityDialog : Form
+    {
+        public LayerVisibilityDialog(MgLayerCollection layers)
+        {
+            InitializeComponent();
+            for (int i = 0; i < layers.GetCount(); i++)
+            {
+                MgLayerBase layer = layers.GetItem(i);
+                grdLayers.Rows.Add(layer.LegendLabel, layer.GetVisible(), layer.IsVisible());
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/LayerVisibilityDialog.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,134 @@
+<?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="label1.Text" xml:space="preserve">
+    <value>GetVisible() returns the state of the visibility flag for a given layer (the check box in the legend)
+
+IsVisible() returns the actual visibility of the layer, based on its visibility flag, the visibility flag of any groups that include the layer, and whether the layer has a defined style for the current view scale</value>
+  </data>
+  <metadata name="COL_IS_VISIBLE.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <metadata name="COL_GET_VISIBLE.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <metadata name="COL_LAYER.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,296 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.5420
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace SampleExtension {
+    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 Layers {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Layers() {
+        }
+        
+        /// <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("SampleExtension.Layers", typeof(Layers).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 <AreaRule>
+        ///  <LegendLabel>%s</LegendLabel>
+        ///  <Filter>%s</Filter>
+        ///  <AreaSymbolization2D>
+        ///    <Fill>
+        ///      <FillPattern>Solid</FillPattern>
+        ///      <ForegroundColor>%s</ForegroundColor>
+        ///      <BackgroundColor>FF000000</BackgroundColor>
+        ///    </Fill>
+        ///    <Stroke>
+        ///      <LineStyle>Solid</LineStyle>
+        ///      <Thickness>1</Thickness>
+        ///      <Color>FF000000</Color>
+        ///      <Unit>Points</Unit>
+        ///      <SizeContext>DeviceUnits</SizeContext>
+        ///    </Stroke>
+        ///  </AreaSymbolization2D>
+        ///</AreaRule>
+        ///.
+        /// </summary>
+        internal static string arearule {
+            get {
+                return ResourceManager.GetString("arearule", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <AreaTypeStyle>%s</AreaTypeStyle>
+        ///.
+        /// </summary>
+        internal static string areatypestyle {
+            get {
+                return ResourceManager.GetString("areatypestyle", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?>
+        ///
+        ///  <LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.1.0.xsd" version="1.1.0">
+        ///    <VectorLayerDefinition>
+        ///      <ResourceId></ResourceId>
+        ///      <FeatureName>BufferClass</FeatureName>
+        ///      <FeatureNameType>FeatureClass</FeatureNameType>
+        ///      <Geometry>BufferGeometry</Geometry>
+        ///      <VectorScaleRange>
+        ///        <AreaTypeStyle>
+        ///          <AreaRule>
+        ///         [rest of string was truncated]";.
+        /// </summary>
+        internal static string BufferLayerDefinition {
+            get {
+                return ResourceManager.GetString("BufferLayerDefinition", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?>
+        ///<LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LayerDefinition-2.4.0.xsd" version="2.4.0">
+        ///  <VectorLayerDefinition>
+        ///    <ResourceId>%s</ResourceId>
+        ///    <FeatureName>%s</FeatureName>
+        ///    <FeatureNameType>FeatureClass</FeatureNameType>
+        ///    <Geometry>%s</Geometry>
+        ///    %s
+        ///  </VectorLayerDefinition>
+        ///</LayerDefinition>
+        ///.
+        /// </summary>
+        internal static string layerdefinition {
+            get {
+                return ResourceManager.GetString("layerdefinition", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <LineRule>
+        ///  <LegendLabel>%s</LegendLabel>
+        ///  <Filter>%s</Filter>
+        ///  <LineSymbolization2D>
+        ///    <LineStyle>Solid</LineStyle>
+        ///    <Thickness>1</Thickness>
+        ///    <Color>%s</Color>
+        ///    <Unit>Points</Unit>
+        ///    <SizeContext>DeviceUnits</SizeContext>
+        ///  </LineSymbolization2D>
+        ///</LineRule>
+        ///.
+        /// </summary>
+        internal static string linerule {
+            get {
+                return ResourceManager.GetString("linerule", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <LineTypeStyle>%s</LineTypeStyle>
+        ///.
+        /// </summary>
+        internal static string linetypestyle {
+            get {
+                return ResourceManager.GetString("linetypestyle", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <W2D>
+        ///  <Unit>Points</Unit>
+        ///  <SizeContext>DeviceUnits</SizeContext>
+        ///  <SizeX>%s</SizeX>
+        ///  <SizeY>%s</SizeY>
+        ///  <Rotation>0</Rotation>
+        ///  <MaintainAspect>true</MaintainAspect>
+        ///  <W2DSymbol>
+        ///    <ResourceId>%s</ResourceId>
+        ///    <LibraryItemName>%s</LibraryItemName>
+        ///  </W2DSymbol>
+        ///  <FillColor>%s</FillColor>
+        ///  <LineColor>FF000000</LineColor>
+        ///  <TextColor>FF000000</TextColor>
+        ///</W2D>.
+        /// </summary>
+        internal static string marksymbol {
+            get {
+                return ResourceManager.GetString("marksymbol", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?>
+        ///<LayerDefinition version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.1.0.xsd">
+        ///  <VectorLayerDefinition>
+        ///    <ResourceId></ResourceId>
+        ///    <FeatureName>ParcelMarkerClass</FeatureName>
+        ///    <FeatureNameType>FeatureClass</FeatureNameType>
+        ///    <Geometry>ParcelLocation</Geometry>
+        ///    <VectorScaleRange>
+        ///      <MinScale>0</MinScale>
+        ///      <MaxScale>10000</MaxScale>
+        /// [rest of string was truncated]";.
+        /// </summary>
+        internal static string ParcelMarker {
+            get {
+                return ResourceManager.GetString("ParcelMarker", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <PointRule>
+        ///  <LegendLabel>%s</LegendLabel>
+        ///  <Filter>%s</Filter>
+        ///  <Label>%s</Label>
+        ///  <PointSymbolization2D>%s</PointSymbolization2D>
+        ///</PointRule>
+        ///.
+        /// </summary>
+        internal static string pointrule {
+            get {
+                return ResourceManager.GetString("pointrule", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <PointTypeStyle>
+        ///  <DisplayAsText>false</DisplayAsText>
+        ///  <AllowOverpost>false</AllowOverpost>
+        ///  %s
+        ///</PointTypeStyle>
+        ///.
+        /// </summary>
+        internal static string pointtypestyle {
+            get {
+                return ResourceManager.GetString("pointtypestyle", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?>
+        ///<LayerDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LayerDefinition-1.3.0.xsd">
+        ///	<VectorLayerDefinition>
+        ///		<ResourceId>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</ResourceId>
+        ///		<FeatureName>SHP_Schema:Parcels</FeatureName>
+        ///		<FeatureNameType>FeatureClass</FeatureNameType>
+        ///		<PropertyMapping>
+        ///			<Name>NAME</Name>
+        ///			<Value>NAME</Value>
+        ///		</ [rest of string was truncated]";.
+        /// </summary>
+        internal static string RecentlyBuilt {
+            get {
+                return ResourceManager.GetString("RecentlyBuilt", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <VectorScaleRange>
+        ///  <MinScale>%s</MinScale>
+        ///  <MaxScale>%s</MaxScale>
+        ///  %s
+        ///</VectorScaleRange>
+        ///.
+        /// </summary>
+        internal static string scalerange {
+            get {
+                return ResourceManager.GetString("scalerange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to <Unit>Points</Unit>
+        ///<SizeContext>DeviceUnits</SizeContext>
+        ///<SizeX>%s</SizeX>
+        ///<SizeY>%s</SizeY>
+        ///<Rotation>0</Rotation>
+        ///<Text>%s</Text>
+        ///<FontName>Arial</FontName>
+        ///<ForegroundColor>%s</ForegroundColor>
+        ///<BackgroundColor>FF000000</BackgroundColor>
+        ///<BackgroundStyle>Transparent</BackgroundStyle>
+        ///<HorizontalAlignment>Center</HorizontalAlignment>
+        ///<VerticalAlignment>Baseline</VerticalAlignment>
+        ///<Bold>false</Bold>
+        ///<Italic>false</Italic>
+        ///<Underlined>false</Underlined>
+        ///.
+        /// </summary>
+        internal static string textsymbol {
+            get {
+                return ResourceManager.GetString("textsymbol", resourceCulture);
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="arearule" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\arearule.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="areatypestyle" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\areatypestyle.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="layerdefinition" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\layerdefinition.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="linerule" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\linerule.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="linetypestyle" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\linetypestyle.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="marksymbol" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\marksymbol.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="pointrule" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\pointrule.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="pointtypestyle" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\pointtypestyle.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="RecentlyBuilt" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\RecentlyBuilt.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="scalerange" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\scalerange.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="textsymbol" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\textsymbol.templ;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="BufferLayerDefinition" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\BufferLayerDefinition.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="ParcelMarker" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\ParcelMarker.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/MgSampleTaskPaneComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/MgSampleTaskPaneComponent.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/MgSampleTaskPaneComponent.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.Viewer;
+
+namespace SampleExtension
+{
+    public class MgSampleTaskPaneComponent : MgViewerComponent
+    {
+        public MgSampleTaskPaneComponent() 
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new SamplesTaskPane(this.Viewer);
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,111 @@
+namespace SampleExtension
+{
+    partial class ModifyingMapsAndLayers
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnShowBuildings = new System.Windows.Forms.Button();
+            this.btnCreateSquareFootage = new System.Windows.Forms.Button();
+            this.btnCreateHydroLine = new System.Windows.Forms.Button();
+            this.btnCreatePointsOfInterest = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(15, 23);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(282, 58);
+            this.label1.TabIndex = 1;
+            this.label1.Text = "This sample demonstrates basic map and layer manipulation";
+            // 
+            // btnShowBuildings
+            // 
+            this.btnShowBuildings.Location = new System.Drawing.Point(18, 102);
+            this.btnShowBuildings.Name = "btnShowBuildings";
+            this.btnShowBuildings.Size = new System.Drawing.Size(217, 23);
+            this.btnShowBuildings.TabIndex = 2;
+            this.btnShowBuildings.Text = "Show buildings built after 1980";
+            this.btnShowBuildings.UseVisualStyleBackColor = true;
+            this.btnShowBuildings.Click += new System.EventHandler(this.btnShowBuildings_Click);
+            // 
+            // btnCreateSquareFootage
+            // 
+            this.btnCreateSquareFootage.Location = new System.Drawing.Point(18, 131);
+            this.btnCreateSquareFootage.Name = "btnCreateSquareFootage";
+            this.btnCreateSquareFootage.Size = new System.Drawing.Size(217, 23);
+            this.btnCreateSquareFootage.TabIndex = 3;
+            this.btnCreateSquareFootage.Text = "Create square footage layer";
+            this.btnCreateSquareFootage.UseVisualStyleBackColor = true;
+            this.btnCreateSquareFootage.Click += new System.EventHandler(this.btnCreateSquareFootage_Click);
+            // 
+            // btnCreateHydroLine
+            // 
+            this.btnCreateHydroLine.Location = new System.Drawing.Point(18, 160);
+            this.btnCreateHydroLine.Name = "btnCreateHydroLine";
+            this.btnCreateHydroLine.Size = new System.Drawing.Size(217, 23);
+            this.btnCreateHydroLine.TabIndex = 4;
+            this.btnCreateHydroLine.Text = "Create hydro line layer";
+            this.btnCreateHydroLine.UseVisualStyleBackColor = true;
+            this.btnCreateHydroLine.Click += new System.EventHandler(this.btnCreateHydroLine_Click);
+            // 
+            // btnCreatePointsOfInterest
+            // 
+            this.btnCreatePointsOfInterest.Location = new System.Drawing.Point(18, 189);
+            this.btnCreatePointsOfInterest.Name = "btnCreatePointsOfInterest";
+            this.btnCreatePointsOfInterest.Size = new System.Drawing.Size(217, 23);
+            this.btnCreatePointsOfInterest.TabIndex = 5;
+            this.btnCreatePointsOfInterest.Text = "Create points of interest layer";
+            this.btnCreatePointsOfInterest.UseVisualStyleBackColor = true;
+            this.btnCreatePointsOfInterest.Click += new System.EventHandler(this.btnCreatePointsOfInterest_Click);
+            // 
+            // ModifyingMapsAndLayers
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnCreatePointsOfInterest);
+            this.Controls.Add(this.btnCreateHydroLine);
+            this.Controls.Add(this.btnCreateSquareFootage);
+            this.Controls.Add(this.btnShowBuildings);
+            this.Controls.Add(this.label1);
+            this.Name = "ModifyingMapsAndLayers";
+            this.Size = new System.Drawing.Size(314, 419);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnShowBuildings;
+        private System.Windows.Forms.Button btnCreateSquareFootage;
+        private System.Windows.Forms.Button btnCreateHydroLine;
+        private System.Windows.Forms.Button btnCreatePointsOfInterest;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,545 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using System.Xml;
+using System.IO;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
+
+namespace SampleExtension
+{
+    public partial class ModifyingMapsAndLayers : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public ModifyingMapsAndLayers(IMapViewer viewer)
+        {
+            InitializeComponent();
+            _viewer = viewer;
+            this.Title = "Modifying Maps and Layers";
+        }
+
+        private void btnShowBuildings_Click(object sender, EventArgs e)
+        {
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+
+            string layerName = "RecentlyBuilt";
+            string legendLabel = "Built after 1980";
+            string groupName = "Analysis";
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerGroupCollection groups = map.GetLayerGroups();
+
+            if (layers.IndexOf(layerName) >= 0)
+            {
+                MessageBox.Show("Layer (" + layerName + ") already created");
+                return;
+            }
+
+            //NOTE: mg-desktop has no formal concept of a session repository, but we still
+            //support session-based resources as a form of temporary resource (for the duration
+            //of the application). Session ids in mg-desktop can be any arbitrary string
+            string sessionId = Guid.NewGuid().ToString();
+
+            XmlDocument domDocument = new XmlDocument();
+            domDocument.LoadXml(Layers.RecentlyBuilt);
+
+            // Get a list of all the <AreaRule><Filter> elements in
+            // the XML.
+            XmlNodeList nodes = domDocument.SelectNodes("//AreaRule/Filter");
+            // Find the correct node and change it
+            foreach (XmlNode node in nodes)
+            {
+                if (node.InnerText == "YRBUILT > 1950")
+                {
+                    node.InnerText = "YRBUILT > 1980";
+                }
+            }
+
+            // Get a list of all the <LegendLabel> elements in the
+            // XML.
+            nodes = domDocument.SelectNodes("//LegendLabel");
+            // Find the correct node and change it
+            foreach (XmlNode node in nodes)
+            {
+                if (node.InnerText == "Built after 1950")
+                {
+                    node.InnerText = "Built after 1980";
+                }
+            }
+
+            //Add the layer to the map
+            // TODO: Should probably validate this XML content
+            using (MemoryStream ms = new MemoryStream())
+            {
+                domDocument.Save(ms);
+                ms.Position = 0L;
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] layerDefinition = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(layerDefinition));
+                layerDefinition = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, layerDefinition, 0);
+                // Save the new layer definition to the session repository  
+                MgByteSource byteSource = new MgByteSource(layerDefinition, layerDefinition.Length);
+                MgResourceIdentifier resourceID = new MgResourceIdentifier("Session:" + sessionId + "//" + layerName + ".LayerDefinition");
+                resourceService.SetResource(resourceID, byteSource.GetReader(), null);
+
+                //Insert this layer to our map
+                MgdLayer newLayer = new MgdLayer(resourceID, resourceService);
+                newLayer.Name = layerName;
+                newLayer.LegendLabel = legendLabel;
+                newLayer.DisplayInLegend = true;
+                newLayer.SetVisible(true);
+                layers.Insert(0, newLayer);
+
+                //Create analysis group if not already created
+                if (groups.IndexOf(groupName) < 0)
+                {
+                    MgLayerGroup group = new MgLayerGroup(groupName);
+                    group.LegendLabel = groupName;
+                    group.DisplayInLegend = true;
+                    groups.Add(group);
+                    newLayer.Group = group;
+                }
+
+                //Turn off square footage if it exists
+                if (layers.IndexOf("SquareFootage") >= 0)
+                {
+                    MgLayerBase layer = layers.GetItem("SquareFootage");
+                    layer.SetVisible(false);
+                }
+
+                MessageBox.Show("Layer (" + layerName + ") created");
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+
+        private void btnCreateSquareFootage_Click(object sender, EventArgs e)
+        {
+            string layerName = "SquareFootage";
+            string legendLabel = "Square Footage";
+            string groupName = "Analysis";
+
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerGroupCollection groups = map.GetLayerGroups();
+
+            //NOTE: mg-desktop has no formal concept of a session repository, but we still
+            //support session-based resources as a form of temporary resource (for the duration
+            //of the application). Session ids in mg-desktop can be any arbitrary string
+            string sessionId = Guid.NewGuid().ToString();
+
+            if (layers.IndexOf(layerName) >= 0)
+            {
+                MessageBox.Show("Layer (" + layerName + ") already created");
+                return;
+            }
+
+            //---------------------------------------------------//
+            // Create a new layer
+            LayerDefinitionFactory factory = new LayerDefinitionFactory();
+
+            /// Create three area rules for three different
+            // scale ranges.
+            String areaRule1 = factory.CreateAreaRule("1 to 800",
+              "SQFT >= 1 AND SQFT < 800", "FFFFFF00");
+            String areaRule2 = factory.CreateAreaRule("800 to 1600",
+              "SQFT >= 800 AND SQFT < 1600", "FFFFBF20");
+            String areaRule3 = factory.CreateAreaRule("1600 to 2400",
+              "SQFT >= 1600 AND SQFT < 2400", "FFFF8040");
+
+            // Create an area type style.
+            String areaTypeStyle = factory.CreateAreaTypeStyle(areaRule1 + areaRule2 + areaRule3);
+
+            // Create a scale range.
+            String minScale = "0";
+            String maxScale = "10000";
+            String areaScaleRange = factory.CreateScaleRange(minScale, maxScale, areaTypeStyle);
+
+            // Create the layer definiton.
+            String featureClass = "Library://Samples/Sheboygan/Data/Parcels.FeatureSource";
+            String featureName = "SHP_Schema:Parcels";
+            String geometry = "SHPGEOM";
+            String layerDefinition = factory.CreateLayerDefinition(featureClass, featureName, geometry, areaScaleRange);
+
+            XmlDocument domDocument = new XmlDocument();
+            domDocument.LoadXml(layerDefinition);
+
+            //Add the layer to the map
+            // TODO: Should probably validate this XML content
+            using (MemoryStream ms = new MemoryStream())
+            {
+                domDocument.Save(ms);
+                ms.Position = 0L;
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] ldfBytes = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(ldfBytes));
+                ldfBytes = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, ldfBytes, 0);
+                // Save the new layer definition to the session repository  
+                MgByteSource byteSource = new MgByteSource(ldfBytes, ldfBytes.Length);
+                MgResourceIdentifier resourceID = new MgResourceIdentifier("Session:" + sessionId + "//" + layerName + ".LayerDefinition");
+                resourceService.SetResource(resourceID, byteSource.GetReader(), null);
+
+                //Insert this layer to our map
+                MgdLayer newLayer = new MgdLayer(resourceID, resourceService);
+                newLayer.Name = layerName;
+                newLayer.LegendLabel = legendLabel;
+                newLayer.DisplayInLegend = true;
+                newLayer.SetVisible(true);
+                layers.Insert(0, newLayer);
+
+                //Create analysis group if not already created
+                if (groups.IndexOf(groupName) < 0)
+                {
+                    MgLayerGroup group = new MgLayerGroup(groupName);
+                    group.LegendLabel = groupName;
+                    group.DisplayInLegend = true;
+                    groups.Add(group);
+                    newLayer.Group = group;
+                }
+
+                //Turn off recently built if it exists
+                if (layers.IndexOf("RecentlyBuilt") >= 0)
+                {
+                    MgLayerBase layer = layers.GetItem("RecentlyBuilt");
+                    layer.SetVisible(false);
+                }
+
+                MessageBox.Show("Layer (" + layerName + ") created");
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+
+        private void btnCreateHydroLine_Click(object sender, EventArgs e)
+        {
+            string layerName = "Hydro";
+            string legendLabel = "Hydro";
+            string groupName = "Analysis";
+
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerGroupCollection groups = map.GetLayerGroups();
+
+            //NOTE: mg-desktop has no formal concept of a session repository, but we still
+            //support session-based resources as a form of temporary resource (for the duration
+            //of the application). Session ids in mg-desktop can be any arbitrary string
+            string sessionId = Guid.NewGuid().ToString();
+
+            if (layers.IndexOf(layerName) >= 0)
+            {
+                MessageBox.Show("Layer (" + layerName + ") already created");
+                return;
+            }
+
+            //---------------------------------------------------//
+            // Create a new layer
+
+            LayerDefinitionFactory factory = new LayerDefinitionFactory();
+
+            // Create a line rule.
+            String ruleLegendLabel = "";
+            String filter = "";
+            String color = "FF0000FF";
+            String lineRule = factory.CreateLineRule(ruleLegendLabel, filter, color);
+
+            // Create a line type style.
+            String lineTypeStyle = factory.CreateLineTypeStyle(lineRule);
+
+            // Create a scale range.
+            String minScale = "0";
+            String maxScale = "1000000000000";
+            String lineScaleRange = factory.CreateScaleRange(minScale, maxScale, lineTypeStyle);
+
+            // Create the layer definiton.
+            String featureClass = "Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource";
+            String featureName = "SHP_Schema:HydrographicLines";
+            String geometry = "SHPGEOM";
+            String layerDefinition = factory.CreateLayerDefinition(featureClass, featureName, geometry, lineScaleRange);
+
+            //---------------------------------------------------//
+            // ...
+
+            XmlDocument domDocument = new XmlDocument();
+            domDocument.LoadXml(layerDefinition);
+
+            //Add the layer to the map
+            // TODO: Should probably validate this XML content
+            using (MemoryStream ms = new MemoryStream())
+            {
+                domDocument.Save(ms);
+                ms.Position = 0L;
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] ldfBytes = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(ldfBytes));
+                ldfBytes = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, ldfBytes, 0);
+                // Save the new layer definition to the session repository  
+                MgByteSource byteSource = new MgByteSource(ldfBytes, ldfBytes.Length);
+                MgResourceIdentifier resourceID = new MgResourceIdentifier("Session:" + sessionId + "//" + layerName + ".LayerDefinition");
+                resourceService.SetResource(resourceID, byteSource.GetReader(), null);
+
+                //Insert this layer to our map
+                MgdLayer newLayer = new MgdLayer(resourceID, resourceService);
+                newLayer.Name = layerName;
+                newLayer.LegendLabel = legendLabel;
+                newLayer.DisplayInLegend = true;
+                newLayer.SetVisible(true);
+                layers.Insert(0, newLayer);
+
+                //Create analysis group if not already created
+                if (groups.IndexOf(groupName) < 0)
+                {
+                    MgLayerGroup group = new MgLayerGroup(groupName);
+                    group.LegendLabel = groupName;
+                    group.DisplayInLegend = true;
+                    groups.Add(group);
+                    newLayer.Group = group;
+                }
+
+                MessageBox.Show("Layer (" + layerName + ") created");
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+
+        private void btnCreatePointsOfInterest_Click(object sender, EventArgs e)
+        {
+            string layerName = "Points";
+            string legendLabel = "Points of Interest";
+            string groupName = "Analysis";
+
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            //We use MgdFeatureService instead of MgFeatureService as this sample demonstrates APIs unique to mg-desktop
+            MgdFeatureService featureService = (MgdFeatureService)provider.CreateService(MgServiceType.FeatureService);
+
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerGroupCollection groups = map.GetLayerGroups();
+
+            //NOTE: mg-desktop has no formal concept of a session repository, but we still
+            //support session-based resources as a form of temporary resource (for the duration
+            //of the application). Session ids in mg-desktop can be any arbitrary string
+            string sessionId = Guid.NewGuid().ToString();
+
+            if (layers.IndexOf(layerName) >= 0)
+            {
+                MessageBox.Show("Layer (" + layerName + ") already created");
+                return;
+            }
+
+            //---------------------------------------------------//
+            // Create a feature source with point data.
+            // (The Sheboygan sample data does not contain such data,
+            // so we"ll create it.)
+
+            // Create a feature class definition for the new feature source
+            MgClassDefinition classDefinition = new MgClassDefinition();
+            classDefinition.SetName("Points");
+            classDefinition.SetDescription("Feature class with point data.");
+            classDefinition.SetDefaultGeometryPropertyName("GEOM");
+
+            MgPropertyDefinitionCollection idProps = classDefinition.GetIdentityProperties();
+            MgPropertyDefinitionCollection clsProps = classDefinition.GetProperties();
+
+            // Create an identify property
+            MgDataPropertyDefinition identityProperty = new MgDataPropertyDefinition("KEY");
+            identityProperty.SetDataType(MgPropertyType.Int32);
+            identityProperty.SetAutoGeneration(true);
+            identityProperty.SetReadOnly(true);
+            // Add the identity property to the class definition
+            clsProps.Add(identityProperty);
+            idProps.Add(identityProperty);
+
+            // Create a name property
+            MgDataPropertyDefinition nameProperty = new MgDataPropertyDefinition("NAME");
+            nameProperty.SetDataType(MgPropertyType.String);
+            // Add the name property to the class definition
+            clsProps.Add(nameProperty);
+
+            // Create a geometry property
+            MgGeometricPropertyDefinition geometryProperty = new MgGeometricPropertyDefinition("GEOM");
+            geometryProperty.SetGeometryTypes(MgFeatureGeometricType.Point);
+            // Add the geometry property to the class definition
+            clsProps.Add(geometryProperty);
+
+            // Create a feature schema
+            MgFeatureSchema featureSchema = new MgFeatureSchema("PointSchema", "Point schema");
+            MgClassDefinitionCollection classes = featureSchema.GetClasses();
+            // Add the feature schema to the class definition
+            classes.Add(classDefinition);
+
+            // Create the feature source
+            String featureSourceName = "Library://Samples/DevGuide/Data/points.FeatureSource";
+            MgResourceIdentifier resourceIdentifier = new MgResourceIdentifier(featureSourceName);
+            //wkt = "LOCALCS[\"*XY-MT*\",LOCAL_DATUM[\"*X-Y*\",10000],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
+            String wkt = "GEOGCS[\"LL84\",DATUM[\"WGS84\",SPHEROID[\"WGS84\",6378137.000,298.25722293]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.01745329251994]]";
+            MgCreateSdfParams sdfParams = new MgCreateSdfParams("LatLong", wkt, featureSchema);
+            featureService.CreateFeatureSource(resourceIdentifier, sdfParams);
+
+            // We need to add some data to the sdf before using it.  The spatial context
+            // reader must have an extent.
+            MgBatchPropertyCollection batchPropertyCollection = new MgBatchPropertyCollection();
+            MgWktReaderWriter wktReaderWriter = new MgWktReaderWriter();
+            MgAgfReaderWriter agfReaderWriter = new MgAgfReaderWriter();
+            MgGeometryFactory geometryFactory = new MgGeometryFactory();
+
+            // Make four points
+            batchPropertyCollection.Add(MakePoint("Point A", -87.727, 43.748, wktReaderWriter, agfReaderWriter));
+
+            batchPropertyCollection.Add(MakePoint("Point B", -87.728, 43.730, wktReaderWriter, agfReaderWriter));
+
+            batchPropertyCollection.Add(MakePoint("Point C", -87.726, 43.750, wktReaderWriter, agfReaderWriter));
+
+            batchPropertyCollection.Add(MakePoint("Point D", -87.728, 43.750, wktReaderWriter, agfReaderWriter));
+
+            // Old way commented out
+            
+            /*
+            // Add the batch property collection to the feature source
+            MgInsertFeatures cmd = new MgInsertFeatures("Points", batchPropertyCollection);
+            MgFeatureCommandCollection featureCommandCollection = new MgFeatureCommandCollection();
+            featureCommandCollection.Add(cmd);
+
+            // Execute the "add" commands
+            featureService.UpdateFeatures(resourceIdentifier, featureCommandCollection, false);
+            */
+
+            // Here's the mg-desktop way
+            MgPropertyCollection insertResult = featureService.InsertFeatures(resourceIdentifier, "Points", batchPropertyCollection);
+            for (int i = 0; i < insertResult.GetCount(); i++)
+            {
+                MgFeatureProperty fp = insertResult.GetItem(i) as MgFeatureProperty;
+                if (fp != null)
+                {
+                    MgFeatureReader fr = fp.GetValue();
+                    fr.Close();
+                }
+            }
+
+            // ...
+            //---------------------------------------------------//
+            // Create a new layer
+
+            LayerDefinitionFactory factory = new LayerDefinitionFactory();
+
+            // Create a mark symbol
+            String resourceId = "Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary";
+            String symbolName = "PushPin";
+            String width = "24";  // unit = points
+            String height = "24"; // unit = points
+            String color = "FFFF0000";
+            String markSymbol = factory.CreateMarkSymbol(resourceId, symbolName, width, height, color);
+
+            // Create a text symbol
+            String text = "ID";
+            String fontHeight = "12";
+            String foregroundColor = "FF000000";
+            String textSymbol = factory.CreateTextSymbol(text, fontHeight, foregroundColor);
+
+            // Create a point rule.
+            String ruleLegendLabel = "trees";
+            String filter = "";
+            String pointRule = factory.CreatePointRule(ruleLegendLabel, filter, textSymbol, markSymbol);
+
+            // Create a point type style.
+            String pointTypeStyle = factory.CreatePointTypeStyle(pointRule);
+
+            // Create a scale range.
+            String minScale = "0";
+            String maxScale = "1000000000000";
+            String pointScaleRange = factory.CreateScaleRange(minScale, maxScale, pointTypeStyle);
+
+            // Create the layer definiton.
+            String featureName = "PointSchema:Points";
+            String geometry = "GEOM";
+            String layerDefinition = factory.CreateLayerDefinition(featureSourceName, featureName, geometry, pointScaleRange);
+            //---------------------------------------------------//
+            // ...
+
+            XmlDocument domDocument = new XmlDocument();
+            domDocument.LoadXml(layerDefinition);
+
+            //Add the layer to the map
+            // TODO: Should probably validate this XML content
+            using (MemoryStream ms = new MemoryStream())
+            {
+                domDocument.Save(ms);
+                ms.Position = 0L;
+                //Note we do this to ensure our XML content is free of any BOM characters
+                byte[] ldfBytes = ms.ToArray();
+                Encoding utf8 = Encoding.UTF8;
+                String layerDefStr = new String(utf8.GetChars(ldfBytes));
+                ldfBytes = new byte[layerDefStr.Length - 1];
+                int byteCount = utf8.GetBytes(layerDefStr, 1, layerDefStr.Length - 1, ldfBytes, 0);
+                // Save the new layer definition to the session repository  
+                MgByteSource byteSource = new MgByteSource(ldfBytes, ldfBytes.Length);
+                MgResourceIdentifier resourceID = new MgResourceIdentifier("Session:" + sessionId + "//" + layerName + ".LayerDefinition");
+                resourceService.SetResource(resourceID, byteSource.GetReader(), null);
+
+                //Insert this layer to our map
+                MgdLayer newLayer = new MgdLayer(resourceID, resourceService);
+                newLayer.Name = layerName;
+                newLayer.LegendLabel = legendLabel;
+                newLayer.DisplayInLegend = true;
+                newLayer.SetVisible(true);
+                layers.Insert(0, newLayer);
+
+                //Create analysis group if not already created
+                if (groups.IndexOf(groupName) < 0)
+                {
+                    MgLayerGroup group = new MgLayerGroup(groupName);
+                    group.LegendLabel = groupName;
+                    group.DisplayInLegend = true;
+                    groups.Add(group);
+                    newLayer.Group = group;
+                }
+
+                MessageBox.Show("Layer (" + layerName + ") created");
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+
+        MgPropertyCollection MakePoint(String name, double x, double y, MgWktReaderWriter wktReaderWriter, MgAgfReaderWriter agfReaderWriter)
+        {
+            MgPropertyCollection propertyCollection = new MgPropertyCollection();
+            MgStringProperty nameProperty = new MgStringProperty("NAME", name);
+            propertyCollection.Add(nameProperty);
+
+            MgGeometry geometry = wktReaderWriter.Read("POINT XY (" + x + " " + y + ")");
+            MgByteReader geometryByteReader = agfReaderWriter.Write(geometry);
+            MgGeometryProperty geometryProperty = new MgGeometryProperty("GEOM", geometryByteReader);
+            propertyCollection.Add(geometryProperty);
+
+            return propertyCollection;
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ModifyingMapsAndLayers.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,61 @@
+namespace SampleExtension
+{
+    partial class ParcelQueryResultWindow
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.lstResults = new System.Windows.Forms.ListBox();
+            this.SuspendLayout();
+            // 
+            // lstResults
+            // 
+            this.lstResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                        | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.lstResults.FormattingEnabled = true;
+            this.lstResults.Location = new System.Drawing.Point(13, 13);
+            this.lstResults.Name = "lstResults";
+            this.lstResults.Size = new System.Drawing.Size(259, 225);
+            this.lstResults.TabIndex = 0;
+            // 
+            // QueryResultWindow
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(284, 262);
+            this.Controls.Add(this.lstResults);
+            this.Name = "QueryResultWindow";
+            this.Text = "Properties Owned by Schmitt";
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.ListBox lstResults;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace SampleExtension
+{
+    public partial class ParcelQueryResultWindow : Form
+    {
+        public ParcelQueryResultWindow(List<string> results)
+        {
+            InitializeComponent();
+            lstResults.DataSource = results;
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/ParcelQueryResultWindow.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file


Property changes on: branches/2.4/MgDev/Desktop/SampleExtension/Resources
___________________________________________________________________
Added: bugtraq:number
   + true

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/BufferLayerDefinition.txt
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/BufferLayerDefinition.txt	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/BufferLayerDefinition.txt	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+  <LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.1.0.xsd" version="1.1.0">
+    <VectorLayerDefinition>
+      <ResourceId></ResourceId>
+      <FeatureName>BufferClass</FeatureName>
+      <FeatureNameType>FeatureClass</FeatureNameType>
+      <Geometry>BufferGeometry</Geometry>
+      <VectorScaleRange>
+        <AreaTypeStyle>
+          <AreaRule>
+            <LegendLabel>Buffer</LegendLabel>
+            <AreaSymbolization2D>
+              <Fill>
+                <FillPattern>Solid</FillPattern>
+                <ForegroundColor>22AA00AA</ForegroundColor>
+                <BackgroundColor>FF000000</BackgroundColor>
+              </Fill>
+              <Stroke>
+                <LineStyle>Solid</LineStyle>
+                <Thickness>0</Thickness>
+                <Color>FF666666</Color>
+                <Unit>Inches</Unit>
+                <SizeContext>DeviceUnits</SizeContext>
+              </Stroke>
+            </AreaSymbolization2D>
+          </AreaRule>
+        </AreaTypeStyle>
+      </VectorScaleRange>
+    </VectorLayerDefinition>
+  </LayerDefinition>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/ParcelMarker.txt
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/ParcelMarker.txt	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/ParcelMarker.txt	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LayerDefinition version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.1.0.xsd">
+  <VectorLayerDefinition>
+    <ResourceId></ResourceId>
+    <FeatureName>ParcelMarkerClass</FeatureName>
+    <FeatureNameType>FeatureClass</FeatureNameType>
+    <Geometry>ParcelLocation</Geometry>
+    <VectorScaleRange>
+      <MinScale>0</MinScale>
+      <MaxScale>10000</MaxScale>
+      <PointTypeStyle>
+        <DisplayAsText>false</DisplayAsText>
+        <AllowOverpost>false</AllowOverpost>
+        <PointRule>
+          <LegendLabel></LegendLabel>
+          <PointSymbolization2D>
+            <Mark>
+             <Unit>Inches</Unit>
+             <SizeContext>DeviceUnits</SizeContext>
+             <SizeX>.1</SizeX>
+             <SizeY>.1</SizeY>
+             <Rotation>0</Rotation>
+             <Shape>X</Shape>
+             <Fill>
+              <FillPattern>Solid</FillPattern>
+              <ForegroundColor>FFFF0000</ForegroundColor>
+              <BackgroundColor>ff000000</BackgroundColor>
+             </Fill>
+             <Edge>
+              <LineStyle>Solid</LineStyle>
+              <Thickness>0.0</Thickness>
+              <Color>ff000000</Color>
+              <Unit>Centimeters</Unit>
+              <SizeContext>DeviceUnits</SizeContext>
+             </Edge>
+            </Mark>
+          </PointSymbolization2D>
+        </PointRule>
+      </PointTypeStyle>
+    </VectorScaleRange>
+  </VectorLayerDefinition>
+</LayerDefinition>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/RecentlyBuilt.txt
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/RecentlyBuilt.txt	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/RecentlyBuilt.txt	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LayerDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LayerDefinition-1.3.0.xsd">
+	<VectorLayerDefinition>
+		<ResourceId>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</ResourceId>
+		<FeatureName>SHP_Schema:Parcels</FeatureName>
+		<FeatureNameType>FeatureClass</FeatureNameType>
+		<PropertyMapping>
+			<Name>NAME</Name>
+			<Value>NAME</Value>
+		</PropertyMapping>
+		<PropertyMapping>
+			<Name>ID</Name>
+			<Value>ID</Value>
+		</PropertyMapping>
+		<PropertyMapping>
+			<Name>YRBUILT</Name>
+			<Value>YRBUILT</Value>
+		</PropertyMapping>
+		<Geometry>SHPGEOM</Geometry>
+		<VectorScaleRange>
+			<MaxScale>10000</MaxScale>
+			<AreaTypeStyle>
+				<AreaRule>
+					<LegendLabel>Built after 1950</LegendLabel>
+					<Filter>YRBUILT > 1950</Filter>
+					<Label>
+						<Unit>Points</Unit>
+						<SizeContext>DeviceUnits</SizeContext>
+						<SizeX>0.3</SizeX>
+						<SizeY>10</SizeY>
+						<Text>YRBUILT</Text>
+						<FontName>Arial</FontName>
+						<ForegroundColor>FF000000</ForegroundColor>
+						<BackgroundColor>FFFFFFFF</BackgroundColor>
+						<BackgroundStyle>Transparent</BackgroundStyle>
+						<HorizontalAlignment>'Center'</HorizontalAlignment>
+						<VerticalAlignment>'Baseline'</VerticalAlignment>
+					</Label>
+					<AreaSymbolization2D>
+						<Fill>
+							<FillPattern>Solid</FillPattern>
+							<ForegroundColor>FFFFFF00</ForegroundColor>
+							<BackgroundColor>FF000000</BackgroundColor>
+						</Fill>
+						<Stroke>
+							<LineStyle>Solid</LineStyle>
+							<Thickness>0</Thickness>
+							<Color>FF000000</Color>
+							<Unit>Inches</Unit>
+							<SizeContext>DeviceUnits</SizeContext>
+						</Stroke>
+					</AreaSymbolization2D>
+				</AreaRule>
+			</AreaTypeStyle>
+		</VectorScaleRange>
+	</VectorLayerDefinition>
+</LayerDefinition>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/arearule.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/arearule.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/arearule.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,18 @@
+<AreaRule>
+  <LegendLabel>%s</LegendLabel>
+  <Filter>%s</Filter>
+  <AreaSymbolization2D>
+    <Fill>
+      <FillPattern>Solid</FillPattern>
+      <ForegroundColor>%s</ForegroundColor>
+      <BackgroundColor>FF000000</BackgroundColor>
+    </Fill>
+    <Stroke>
+      <LineStyle>Solid</LineStyle>
+      <Thickness>1</Thickness>
+      <Color>FF000000</Color>
+      <Unit>Points</Unit>
+      <SizeContext>DeviceUnits</SizeContext>
+    </Stroke>
+  </AreaSymbolization2D>
+</AreaRule>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/areatypestyle.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/areatypestyle.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/areatypestyle.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1 @@
+<AreaTypeStyle>%s</AreaTypeStyle>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/layerdefinition.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/layerdefinition.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/layerdefinition.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LayerDefinition-2.4.0.xsd" version="2.4.0">
+  <VectorLayerDefinition>
+    <ResourceId>%s</ResourceId>
+    <FeatureName>%s</FeatureName>
+    <FeatureNameType>FeatureClass</FeatureNameType>
+    <Geometry>%s</Geometry>
+    %s
+  </VectorLayerDefinition>
+</LayerDefinition>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/linerule.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/linerule.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/linerule.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,11 @@
+<LineRule>
+  <LegendLabel>%s</LegendLabel>
+  <Filter>%s</Filter>
+  <LineSymbolization2D>
+    <LineStyle>Solid</LineStyle>
+    <Thickness>1</Thickness>
+    <Color>%s</Color>
+    <Unit>Points</Unit>
+    <SizeContext>DeviceUnits</SizeContext>
+  </LineSymbolization2D>
+</LineRule>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/linetypestyle.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/linetypestyle.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/linetypestyle.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1 @@
+<LineTypeStyle>%s</LineTypeStyle>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/marksymbol.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/marksymbol.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/marksymbol.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,15 @@
+<W2D>
+  <Unit>Points</Unit>
+  <SizeContext>DeviceUnits</SizeContext>
+  <SizeX>%s</SizeX>
+  <SizeY>%s</SizeY>
+  <Rotation>0</Rotation>
+  <MaintainAspect>true</MaintainAspect>
+  <W2DSymbol>
+    <ResourceId>%s</ResourceId>
+    <LibraryItemName>%s</LibraryItemName>
+  </W2DSymbol>
+  <FillColor>%s</FillColor>
+  <LineColor>FF000000</LineColor>
+  <TextColor>FF000000</TextColor>
+</W2D>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointrule.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointrule.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointrule.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,6 @@
+<PointRule>
+  <LegendLabel>%s</LegendLabel>
+  <Filter>%s</Filter>
+  <Label>%s</Label>
+  <PointSymbolization2D>%s</PointSymbolization2D>
+</PointRule>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointtypestyle.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointtypestyle.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/pointtypestyle.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,5 @@
+<PointTypeStyle>
+  <DisplayAsText>false</DisplayAsText>
+  <AllowOverpost>false</AllowOverpost>
+  %s
+</PointTypeStyle>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/scalerange.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/scalerange.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/scalerange.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,5 @@
+<VectorScaleRange>
+  <MinScale>%s</MinScale>
+  <MaxScale>%s</MaxScale>
+  %s
+</VectorScaleRange>

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/textsymbol.templ
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/textsymbol.templ	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/textsymbol.templ	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,15 @@
+<Unit>Points</Unit>
+<SizeContext>DeviceUnits</SizeContext>
+<SizeX>%s</SizeX>
+<SizeY>%s</SizeY>
+<Rotation>0</Rotation>
+<Text>%s</Text>
+<FontName>Arial</FontName>
+<ForegroundColor>%s</ForegroundColor>
+<BackgroundColor>FF000000</BackgroundColor>
+<BackgroundStyle>Transparent</BackgroundStyle>
+<HorizontalAlignment>Center</HorizontalAlignment>
+<VerticalAlignment>Baseline</VerticalAlignment>
+<Bold>false</Bold>
+<Italic>false</Italic>
+<Underlined>false</Underlined>

Added: branches/2.4/MgDev/Desktop/SampleExtension/SampleComponents.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SampleComponents.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SampleComponents.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OSGeo.MapGuide.Viewer;
+
+namespace SampleExtension
+{
+    // Components are the entry points to your custom functionality
+    //
+    // Components are akin to Commands in the AJAX viewer and Widgets in Fusion.
+    // As you can see below, all these components are simply creating MgControlView
+    // instances which will either be housed in the application's Task Pane, or in
+    // a new window. For these examples, all UI views are housed in the Task Pane
+
+    public class MgHelloMapComponent : MgViewerComponent
+    {
+        public MgHelloMapComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new HelloMap(this.Viewer);
+        }
+    }
+
+    public class MgHelloViewerComponent : MgViewerComponent
+    {
+        public MgHelloViewerComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new HelloViewer(this.Viewer);
+        }
+    }
+
+    public class MgInteractingWithLayersComponent : MgViewerComponent
+    {
+        public MgInteractingWithLayersComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new InteractingWithLayers(this.Viewer);
+        }
+    }
+
+    public class MgWorkingWithFeatureDataComponent : MgViewerComponent
+    {
+        public MgWorkingWithFeatureDataComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new WorkingWithFeatureData(this.Viewer);
+        }
+    }
+
+    public class MgModifyingMapsAndLayersComponent : MgViewerComponent
+    {
+        public MgModifyingMapsAndLayersComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new ModifyingMapsAndLayers(this.Viewer);
+        }
+    }
+
+    public class MgAnalyzingFeaturesComponent : MgViewerComponent
+    {
+        public MgAnalyzingFeaturesComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new AnalyzingFeatures(this.Viewer);
+        }
+    }
+
+    public class MgDigitizingAndRedliningComponent : MgViewerComponent
+    {
+        public MgDigitizingAndRedliningComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new DigitizingAndRedlining(this.Viewer);
+        }
+    }
+
+    public class MgCustomOutputComponent : MgViewerComponent
+    {
+        public MgCustomOutputComponent()
+        {
+            this.Target = MgViewerTarget.TaskPane;
+        }
+
+        protected override MgControlView CreateControlView()
+        {
+            return new CustomOutput(this.Viewer);
+        }
+    }
+}

Modified: branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	2012-07-09 12:06:43 UTC (rev 6882)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	2012-07-09 16:26:48 UTC (rev 6883)
@@ -69,6 +69,55 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AnalyzingFeatures.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AnalyzingFeatures.Designer.cs">
+      <DependentUpon>AnalyzingFeatures.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BufferHelper.cs" />
+    <Compile Include="CustomOutput.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="CustomOutput.Designer.cs">
+      <DependentUpon>CustomOutput.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DigitizingAndRedlining.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DigitizingAndRedlining.Designer.cs">
+      <DependentUpon>DigitizingAndRedlining.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HelloMap.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HelloMap.Designer.cs">
+      <DependentUpon>HelloMap.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HelloViewer.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HelloViewer.Designer.cs">
+      <DependentUpon>HelloViewer.cs</DependentUpon>
+    </Compile>
+    <Compile Include="InteractingWithLayers.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="InteractingWithLayers.Designer.cs">
+      <DependentUpon>InteractingWithLayers.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LayerDefinitionFactory.cs" />
+    <Compile Include="Layers.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Layers.resx</DependentUpon>
+    </Compile>
+    <Compile Include="LayerVisibilityDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="LayerVisibilityDialog.Designer.cs">
+      <DependentUpon>LayerVisibilityDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="MgProfileComponent.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -78,13 +127,49 @@
     <Compile Include="MgStartupComponent.cs">
       <SubType>Component</SubType>
     </Compile>
+    <Compile Include="ModifyingMapsAndLayers.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ModifyingMapsAndLayers.Designer.cs">
+      <DependentUpon>ModifyingMapsAndLayers.cs</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ParcelQueryResultWindow.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ParcelQueryResultWindow.Designer.cs">
+      <DependentUpon>ParcelQueryResultWindow.cs</DependentUpon>
+    </Compile>
     <Compile Include="ResourceIdDialog.cs">
       <SubType>Form</SubType>
     </Compile>
     <Compile Include="ResourceIdDialog.Designer.cs">
       <DependentUpon>ResourceIdDialog.cs</DependentUpon>
     </Compile>
+    <Compile Include="SampleComponents.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="SamplesTaskPane.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="SamplesTaskPane.Designer.cs">
+      <DependentUpon>SamplesTaskPane.cs</DependentUpon>
+    </Compile>
+    <Compile Include="MgSampleTaskPaneComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="SelectedFeaturesWindow.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="SelectedFeaturesWindow.Designer.cs">
+      <DependentUpon>SelectedFeaturesWindow.cs</DependentUpon>
+    </Compile>
+    <Compile Include="WorkingWithFeatureData.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="WorkingWithFeatureData.Designer.cs">
+      <DependentUpon>WorkingWithFeatureData.cs</DependentUpon>
+    </Compile>
     <Compile Include="XmlResponseDialog.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -94,19 +179,82 @@
     <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\MapViewer.Desktop\MapViewer.Desktop.csproj">
+      <Project>{E2001B46-F226-4F7B-911E-252B9644236E}</Project>
+      <Name>MapViewer.Desktop</Name>
+    </ProjectReference>
     <ProjectReference Include="..\MapViewer\MapViewer.csproj">
       <Project>{D46ED17B-329B-4D80-9181-FEF8307EFCBB}</Project>
       <Name>MapViewer</Name>
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
+    <EmbeddedResource Include="AnalyzingFeatures.resx">
+      <DependentUpon>AnalyzingFeatures.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="CustomOutput.resx">
+      <DependentUpon>CustomOutput.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="DigitizingAndRedlining.resx">
+      <DependentUpon>DigitizingAndRedlining.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="HelloMap.resx">
+      <DependentUpon>HelloMap.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="HelloViewer.resx">
+      <DependentUpon>HelloViewer.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="InteractingWithLayers.resx">
+      <DependentUpon>InteractingWithLayers.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Layers.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Layers.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <EmbeddedResource Include="LayerVisibilityDialog.resx">
+      <DependentUpon>LayerVisibilityDialog.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ModifyingMapsAndLayers.resx">
+      <DependentUpon>ModifyingMapsAndLayers.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="ParcelQueryResultWindow.resx">
+      <DependentUpon>ParcelQueryResultWindow.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="ResourceIdDialog.resx">
       <DependentUpon>ResourceIdDialog.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="SamplesTaskPane.resx">
+      <DependentUpon>SamplesTaskPane.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="SelectedFeaturesWindow.resx">
+      <DependentUpon>SelectedFeaturesWindow.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="WorkingWithFeatureData.resx">
+      <DependentUpon>WorkingWithFeatureData.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="XmlResponseDialog.resx">
       <DependentUpon>XmlResponseDialog.cs</DependentUpon>
     </EmbeddedResource>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\arearule.templ" />
+    <None Include="Resources\areatypestyle.templ" />
+    <None Include="Resources\layerdefinition.templ" />
+    <None Include="Resources\linerule.templ" />
+    <None Include="Resources\linetypestyle.templ" />
+    <None Include="Resources\marksymbol.templ" />
+    <None Include="Resources\pointrule.templ" />
+    <None Include="Resources\pointtypestyle.templ" />
+    <None Include="Resources\RecentlyBuilt.txt" />
+    <None Include="Resources\scalerange.templ" />
+    <None Include="Resources\textsymbol.templ" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\BufferLayerDefinition.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\ParcelMarker.txt" />
+  </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.

Added: branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,197 @@
+namespace SampleExtension
+{
+    partial class SamplesTaskPane
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.btnHelloMap = new System.Windows.Forms.Button();
+            this.btnHelloViewer = new System.Windows.Forms.Button();
+            this.btnInteractingWithLayers = new System.Windows.Forms.Button();
+            this.btnWorkingWithFeatureData = new System.Windows.Forms.Button();
+            this.btnModifyingMapsAndLayers = new System.Windows.Forms.Button();
+            this.btnAnalyzingFeatures = new System.Windows.Forms.Button();
+            this.btnDigitizingAndRedlining = new System.Windows.Forms.Button();
+            this.btnCustomOutput = new System.Windows.Forms.Button();
+            this.label2 = new System.Windows.Forms.Label();
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnReload = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // btnHelloMap
+            // 
+            this.btnHelloMap.Location = new System.Drawing.Point(23, 75);
+            this.btnHelloMap.Name = "btnHelloMap";
+            this.btnHelloMap.Size = new System.Drawing.Size(173, 23);
+            this.btnHelloMap.TabIndex = 0;
+            this.btnHelloMap.Tag = "HelloMap";
+            this.btnHelloMap.Text = "Hello Map";
+            this.btnHelloMap.UseVisualStyleBackColor = true;
+            this.btnHelloMap.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnHelloViewer
+            // 
+            this.btnHelloViewer.Location = new System.Drawing.Point(23, 104);
+            this.btnHelloViewer.Name = "btnHelloViewer";
+            this.btnHelloViewer.Size = new System.Drawing.Size(173, 23);
+            this.btnHelloViewer.TabIndex = 1;
+            this.btnHelloViewer.Tag = "HelloViewer";
+            this.btnHelloViewer.Text = "Hello Viewer";
+            this.btnHelloViewer.UseVisualStyleBackColor = true;
+            this.btnHelloViewer.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnInteractingWithLayers
+            // 
+            this.btnInteractingWithLayers.Location = new System.Drawing.Point(23, 133);
+            this.btnInteractingWithLayers.Name = "btnInteractingWithLayers";
+            this.btnInteractingWithLayers.Size = new System.Drawing.Size(173, 23);
+            this.btnInteractingWithLayers.TabIndex = 2;
+            this.btnInteractingWithLayers.Tag = "InteractingWithLayers";
+            this.btnInteractingWithLayers.Text = "Interacting With Layers";
+            this.btnInteractingWithLayers.UseVisualStyleBackColor = true;
+            this.btnInteractingWithLayers.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnWorkingWithFeatureData
+            // 
+            this.btnWorkingWithFeatureData.Location = new System.Drawing.Point(23, 162);
+            this.btnWorkingWithFeatureData.Name = "btnWorkingWithFeatureData";
+            this.btnWorkingWithFeatureData.Size = new System.Drawing.Size(173, 23);
+            this.btnWorkingWithFeatureData.TabIndex = 3;
+            this.btnWorkingWithFeatureData.Tag = "WorkingWithFeatureData";
+            this.btnWorkingWithFeatureData.Text = "Working With Feature Data";
+            this.btnWorkingWithFeatureData.UseVisualStyleBackColor = true;
+            this.btnWorkingWithFeatureData.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnModifyingMapsAndLayers
+            // 
+            this.btnModifyingMapsAndLayers.Location = new System.Drawing.Point(23, 191);
+            this.btnModifyingMapsAndLayers.Name = "btnModifyingMapsAndLayers";
+            this.btnModifyingMapsAndLayers.Size = new System.Drawing.Size(173, 23);
+            this.btnModifyingMapsAndLayers.TabIndex = 4;
+            this.btnModifyingMapsAndLayers.Tag = "ModifyingMapsAndLayers";
+            this.btnModifyingMapsAndLayers.Text = "Modifying Maps and Layers";
+            this.btnModifyingMapsAndLayers.UseVisualStyleBackColor = true;
+            this.btnModifyingMapsAndLayers.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnAnalyzingFeatures
+            // 
+            this.btnAnalyzingFeatures.Location = new System.Drawing.Point(23, 220);
+            this.btnAnalyzingFeatures.Name = "btnAnalyzingFeatures";
+            this.btnAnalyzingFeatures.Size = new System.Drawing.Size(173, 23);
+            this.btnAnalyzingFeatures.TabIndex = 5;
+            this.btnAnalyzingFeatures.Tag = "AnalyzingFeatures";
+            this.btnAnalyzingFeatures.Text = "Analyzing Features";
+            this.btnAnalyzingFeatures.UseVisualStyleBackColor = true;
+            this.btnAnalyzingFeatures.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnDigitizingAndRedlining
+            // 
+            this.btnDigitizingAndRedlining.Location = new System.Drawing.Point(23, 249);
+            this.btnDigitizingAndRedlining.Name = "btnDigitizingAndRedlining";
+            this.btnDigitizingAndRedlining.Size = new System.Drawing.Size(173, 23);
+            this.btnDigitizingAndRedlining.TabIndex = 6;
+            this.btnDigitizingAndRedlining.Tag = "DigitizingAndRedlining";
+            this.btnDigitizingAndRedlining.Text = "Digitizing and Redlining";
+            this.btnDigitizingAndRedlining.UseVisualStyleBackColor = true;
+            this.btnDigitizingAndRedlining.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // btnCustomOutput
+            // 
+            this.btnCustomOutput.Location = new System.Drawing.Point(23, 278);
+            this.btnCustomOutput.Name = "btnCustomOutput";
+            this.btnCustomOutput.Size = new System.Drawing.Size(173, 23);
+            this.btnCustomOutput.TabIndex = 7;
+            this.btnCustomOutput.Tag = "CustomOutput";
+            this.btnCustomOutput.Text = "Custom Output";
+            this.btnCustomOutput.UseVisualStyleBackColor = true;
+            this.btnCustomOutput.Click += new System.EventHandler(this.OnActionClick);
+            // 
+            // label2
+            // 
+            this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label2.Location = new System.Drawing.Point(20, 13);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(203, 48);
+            this.label2.TabIndex = 8;
+            this.label2.Text = "At any time, click \"Initial Task\" in the task bar to return to this list of sampl" +
+                "es\r\n\r\n";
+            // 
+            // label1
+            // 
+            this.label1.Location = new System.Drawing.Point(23, 324);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(200, 45);
+            this.label1.TabIndex = 9;
+            this.label1.Text = "To reload the map (and discard all layers created by these samples), click the bu" +
+                "tton below";
+            // 
+            // btnReload
+            // 
+            this.btnReload.Location = new System.Drawing.Point(23, 372);
+            this.btnReload.Name = "btnReload";
+            this.btnReload.Size = new System.Drawing.Size(173, 23);
+            this.btnReload.TabIndex = 10;
+            this.btnReload.Text = "Reload Map";
+            this.btnReload.UseVisualStyleBackColor = true;
+            this.btnReload.Click += new System.EventHandler(this.btnReload_Click);
+            // 
+            // SamplesTaskPane
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnReload);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.label2);
+            this.Controls.Add(this.btnCustomOutput);
+            this.Controls.Add(this.btnDigitizingAndRedlining);
+            this.Controls.Add(this.btnAnalyzingFeatures);
+            this.Controls.Add(this.btnModifyingMapsAndLayers);
+            this.Controls.Add(this.btnWorkingWithFeatureData);
+            this.Controls.Add(this.btnInteractingWithLayers);
+            this.Controls.Add(this.btnHelloViewer);
+            this.Controls.Add(this.btnHelloMap);
+            this.Name = "SamplesTaskPane";
+            this.Size = new System.Drawing.Size(247, 413);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button btnHelloMap;
+        private System.Windows.Forms.Button btnHelloViewer;
+        private System.Windows.Forms.Button btnInteractingWithLayers;
+        private System.Windows.Forms.Button btnWorkingWithFeatureData;
+        private System.Windows.Forms.Button btnModifyingMapsAndLayers;
+        private System.Windows.Forms.Button btnAnalyzingFeatures;
+        private System.Windows.Forms.Button btnDigitizingAndRedlining;
+        private System.Windows.Forms.Button btnCustomOutput;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnReload;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.Desktop;
+
+namespace SampleExtension
+{
+    public partial class SamplesTaskPane : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public SamplesTaskPane(IMapViewer viewer)
+        {
+            InitializeComponent();
+            _viewer = viewer;
+            this.Title = "mg-desktop API Samples";
+        }
+
+        private void OnActionClick(object sender, EventArgs e)
+        {
+            string componentId = ((Button)sender).Tag.ToString();
+            IShell shell = Shell.Instance;
+            MgComponent component = shell.GetComponent(componentId);
+            if (component != null)
+                component.Invoke();
+            else
+                MessageBox.Show("ERROR: Component (" + componentId + ") not found in AppLayout");
+        }
+
+        private void btnReload_Click(object sender, EventArgs e)
+        {
+            _viewer.ClearSelection();
+            MgResourceIdentifier mdfId = new MgResourceIdentifier("Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition");
+            MgdMap map = new MgdMap(mdfId);
+            MgDesktopMapViewerProvider provider = new MgDesktopMapViewerProvider(map);
+            Shell.Instance.ReloadViewer(provider);
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SamplesTaskPane.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,92 @@
+namespace SampleExtension
+{
+    partial class SelectedFeaturesWindow
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.cmbLayer = new System.Windows.Forms.ComboBox();
+            this.dataGridView1 = new System.Windows.Forms.DataGridView();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(13, 13);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(33, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Layer";
+            // 
+            // cmbLayer
+            // 
+            this.cmbLayer.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbLayer.FormattingEnabled = true;
+            this.cmbLayer.Location = new System.Drawing.Point(84, 10);
+            this.cmbLayer.Name = "cmbLayer";
+            this.cmbLayer.Size = new System.Drawing.Size(121, 21);
+            this.cmbLayer.TabIndex = 1;
+            this.cmbLayer.SelectedIndexChanged += new System.EventHandler(this.cmbLayer_SelectedIndexChanged);
+            // 
+            // dataGridView1
+            // 
+            this.dataGridView1.AllowUserToAddRows = false;
+            this.dataGridView1.AllowUserToDeleteRows = false;
+            this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                        | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.dataGridView1.Location = new System.Drawing.Point(16, 46);
+            this.dataGridView1.Name = "dataGridView1";
+            this.dataGridView1.ReadOnly = true;
+            this.dataGridView1.Size = new System.Drawing.Size(543, 237);
+            this.dataGridView1.TabIndex = 2;
+            // 
+            // SelectedFeaturesWindow
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(580, 295);
+            this.Controls.Add(this.dataGridView1);
+            this.Controls.Add(this.cmbLayer);
+            this.Controls.Add(this.label1);
+            this.Name = "SelectedFeaturesWindow";
+            this.Text = "Selected Features";
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.ComboBox cmbLayer;
+        private System.Windows.Forms.DataGridView dataGridView1;
+    }
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+
+namespace SampleExtension
+{
+    public partial class SelectedFeaturesWindow : Form
+    {
+        private MgSelectionSet _set;
+
+        public SelectedFeaturesWindow(MgSelectionSet set)
+        {
+            InitializeComponent();
+            _set = set;
+            cmbLayer.DataSource = _set.LayerNames;
+            cmbLayer.SelectedIndex = 0;
+        }
+
+        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            if (cmbLayer.SelectedItem != null)
+            {
+                string layerName = cmbLayer.SelectedItem.ToString();
+                bool bSetHeader = false;
+                dataGridView1.Rows.Clear();
+                foreach (var feat in _set.GetFeaturesForLayer(layerName))
+                {
+                    if (!bSetHeader)
+                    {
+                        dataGridView1.Columns.Clear();
+                        foreach (var name in feat.Properties.Keys)
+                        {
+                            dataGridView1.Columns.Add(name.ToString(), name.ToString());
+                        }
+                        bSetHeader = true;
+                    }
+                    object[] values = new object[feat.Properties.Keys.Count];
+                    int i = 0;
+                    foreach (var name in feat.Properties.Keys)
+                    {
+                        values[i] = feat.Properties[name];
+                        i++;
+                    }
+                    dataGridView1.Rows.Add(values);
+                }
+            }
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SelectedFeaturesWindow.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.Designer.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.Designer.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,112 @@
+namespace SampleExtension
+{
+    partial class WorkingWithFeatureData
+    {
+        /// <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 Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnZoomToDistrict1 = new System.Windows.Forms.Button();
+            this.btnQueryDistrict1 = new System.Windows.Forms.Button();
+            this.btnSelectDistrict1 = new System.Windows.Forms.Button();
+            this.btnListSelected = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.label1.Location = new System.Drawing.Point(15, 20);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(210, 58);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This sample demonstrates basic feature querying and programmatic manipulation of " +
+                "the active selection";
+            // 
+            // btnZoomToDistrict1
+            // 
+            this.btnZoomToDistrict1.Location = new System.Drawing.Point(27, 95);
+            this.btnZoomToDistrict1.Name = "btnZoomToDistrict1";
+            this.btnZoomToDistrict1.Size = new System.Drawing.Size(167, 23);
+            this.btnZoomToDistrict1.TabIndex = 1;
+            this.btnZoomToDistrict1.Text = "Zoom to District 1";
+            this.btnZoomToDistrict1.UseVisualStyleBackColor = true;
+            this.btnZoomToDistrict1.Click += new System.EventHandler(this.btnZoomToDistrict1_Click);
+            // 
+            // btnQueryDistrict1
+            // 
+            this.btnQueryDistrict1.Location = new System.Drawing.Point(27, 124);
+            this.btnQueryDistrict1.Name = "btnQueryDistrict1";
+            this.btnQueryDistrict1.Size = new System.Drawing.Size(167, 42);
+            this.btnQueryDistrict1.TabIndex = 2;
+            this.btnQueryDistrict1.Text = "Query: Properties in District 1 owned by Schmitt";
+            this.btnQueryDistrict1.UseVisualStyleBackColor = true;
+            this.btnQueryDistrict1.Click += new System.EventHandler(this.btnQueryDistrict1_Click);
+            // 
+            // btnSelectDistrict1
+            // 
+            this.btnSelectDistrict1.Location = new System.Drawing.Point(27, 172);
+            this.btnSelectDistrict1.Name = "btnSelectDistrict1";
+            this.btnSelectDistrict1.Size = new System.Drawing.Size(167, 42);
+            this.btnSelectDistrict1.TabIndex = 3;
+            this.btnSelectDistrict1.Text = "Select: Properties in District 1 owned by Schmitt";
+            this.btnSelectDistrict1.UseVisualStyleBackColor = true;
+            this.btnSelectDistrict1.Click += new System.EventHandler(this.btnSelectDistrict1_Click);
+            // 
+            // btnListSelected
+            // 
+            this.btnListSelected.Location = new System.Drawing.Point(27, 220);
+            this.btnListSelected.Name = "btnListSelected";
+            this.btnListSelected.Size = new System.Drawing.Size(167, 27);
+            this.btnListSelected.TabIndex = 4;
+            this.btnListSelected.Text = "List Selected Features";
+            this.btnListSelected.UseVisualStyleBackColor = true;
+            this.btnListSelected.Click += new System.EventHandler(this.btnListSelected_Click);
+            // 
+            // WorkingWithFeatureData
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnListSelected);
+            this.Controls.Add(this.btnSelectDistrict1);
+            this.Controls.Add(this.btnQueryDistrict1);
+            this.Controls.Add(this.btnZoomToDistrict1);
+            this.Controls.Add(this.label1);
+            this.Name = "WorkingWithFeatureData";
+            this.Size = new System.Drawing.Size(238, 359);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnZoomToDistrict1;
+        private System.Windows.Forms.Button btnQueryDistrict1;
+        private System.Windows.Forms.Button btnSelectDistrict1;
+        private System.Windows.Forms.Button btnListSelected;
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.cs	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,171 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+
+namespace SampleExtension
+{
+    public partial class WorkingWithFeatureData : MgControlView
+    {
+        private IMapViewer _viewer;
+
+        public WorkingWithFeatureData(IMapViewer viewer)
+        {
+            InitializeComponent();
+            _viewer = viewer;
+            this.Title = "Working With Feature Data";
+            _viewer.SelectionChanged += OnSelectionChanged;
+            CheckSelectionState();
+        }
+
+        protected override void SubCleanup()
+        {
+            //When subscribing to events, be a responsible user and 
+            //unsubscribe on cleanup
+            _viewer.SelectionChanged -= OnSelectionChanged;
+        }
+
+        void OnSelectionChanged(object sender, EventArgs e)
+        {
+            CheckSelectionState();
+        }
+
+        void CheckSelectionState()
+        {
+            MgSelectionBase selection = _viewer.GetSelection();
+            MgReadOnlyLayerCollection layers = selection.GetLayers();
+            btnListSelected.Enabled = (layers != null);
+        }
+
+        private void btnZoomToDistrict1_Click(object sender, EventArgs e)
+        {
+            _viewer.ZoomToView(-87.726134, 43.770338, 8000, true);
+        }
+
+        private void btnQueryDistrict1_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerBase districts = layers.GetItem("Districts");
+            MgLayerBase parcels = layers.GetItem("Parcels");
+
+            //Query the geometry of district 1
+            MgFeatureQueryOptions districtQuery = new MgFeatureQueryOptions();
+            districtQuery.SetFilter("Autogenerated_SDF_ID = 1");
+
+            MgFeatureReader reader = districts.SelectFeatures(districtQuery);
+            MgGeometry districtGeom = null;
+            MgAgfReaderWriter agfRw = new MgAgfReaderWriter();
+            try
+            {
+                reader.ReadNext();
+                MgByteReader geomAgf = reader.GetGeometry(districts.GetFeatureGeometryName());
+                districtGeom = agfRw.Read(geomAgf);
+            }
+            finally
+            {
+                reader.Close();
+            }
+
+            //Now use this geometry as the basis of our 2nd query
+
+            MgFeatureQueryOptions parcelQuery = new MgFeatureQueryOptions();
+            parcelQuery.SetFilter("RNAME LIKE 'SCHMITT%'");
+            parcelQuery.SetSpatialFilter(parcels.GetFeatureGeometryName(), districtGeom, MgFeatureSpatialOperations.Inside);
+
+            //Select the features
+            reader = parcels.SelectFeatures(parcelQuery);
+            List<string> results = new List<string>();
+            try
+            {
+                while (reader.ReadNext())
+                {
+                    if (!reader.IsNull("RPROPAD"))
+                        results.Add(reader.GetString("RPROPAD"));
+                }
+            }
+            finally
+            {
+                reader.Close();
+            }
+
+            new ParcelQueryResultWindow(results).ShowDialog();
+        }
+
+        private void btnSelectDistrict1_Click(object sender, EventArgs e)
+        {
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            MgLayerBase districts = layers.GetItem("Districts");
+            MgLayerBase parcels = layers.GetItem("Parcels");
+
+            //Query the geometry of district 1
+            MgFeatureQueryOptions districtQuery = new MgFeatureQueryOptions();
+            districtQuery.SetFilter("Autogenerated_SDF_ID = 1");
+
+            MgFeatureReader reader = districts.SelectFeatures(districtQuery);
+            MgGeometry districtGeom = null;
+            MgAgfReaderWriter agfRw = new MgAgfReaderWriter();
+            try
+            {
+                reader.ReadNext();
+                MgByteReader geomAgf = reader.GetGeometry(districts.GetFeatureGeometryName());
+                districtGeom = agfRw.Read(geomAgf);
+            }
+            finally
+            {
+                reader.Close();
+            }
+
+            //Now use this geometry as the basis of our 2nd query
+
+            MgFeatureQueryOptions parcelQuery = new MgFeatureQueryOptions();
+            parcelQuery.SetFilter("RNAME LIKE 'SCHMITT%'");
+            parcelQuery.SetSpatialFilter(parcels.GetFeatureGeometryName(), districtGeom, MgFeatureSpatialOperations.Inside);
+
+            //Select the features
+            reader = parcels.SelectFeatures(parcelQuery);
+
+            MgSelectionBase selection = _viewer.GetSelection();
+            try
+            {
+                selection.FromXml(""); //Clear existing selection data
+                selection.AddFeatures(parcels, reader, 0);
+            }
+            finally
+            {
+                reader.Close();
+            }
+
+            //Because we manipulated the active selection outside the viewer
+            //We need to call UpdateSelection() to instruct the viewer to
+            //re-render the active selection. The "true" parameter instructs
+            //the viewer to raise the SelectionChanged event as well, so that
+            //subscribers like the Property Pane get updated as well.
+            _viewer.UpdateSelection(true);
+            _viewer.RefreshMap();
+        }
+
+        private void btnListSelected_Click(object sender, EventArgs e)
+        {
+            // There's two ways to process a selection
+            // 
+            // 1. Iterate through the layers of a MgSelectionSet and process
+            // the feature reader for each layer
+            //
+            // 2. Use an MgSelectionSet helper class
+            //
+            // This example shows the 2nd way, which is the simpler one
+            MgSelectionBase selection = _viewer.GetSelection();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgSelectionSet sset = new MgSelectionSet(selection);
+
+            new SelectedFeaturesWindow(sset).ShowDialog();
+        }
+    }
+}

Added: branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.resx	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/WorkingWithFeatureData.resx	2012-07-09 16:26:48 UTC (rev 6883)
@@ -0,0 +1,120 @@
+<?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>
+</root>
\ No newline at end of file



More information about the mapguide-commits mailing list