[mapguide-commits] r6646 - in trunk/MgDev/Desktop: MapViewer MapViewer/Properties MapViewer/Resources MapViewer.Desktop MapViewerTest MgDesktop MgDesktop/Services MgDesktop/Services/Feature

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sun May 13 00:07:19 EDT 2012


Author: jng
Date: 2012-05-12 21:07:19 -0700 (Sat, 12 May 2012)
New Revision: 6646

Added:
   trunk/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs
   trunk/MgDev/Desktop/MapViewer/MgThemeComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.Designer.cs
   trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.resx
   trunk/MgDev/Desktop/MapViewer/Resources/AreaRuleTemplate.txt
   trunk/MgDev/Desktop/MapViewer/Util.cs
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/BooleanDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/ByteDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/DataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/DateTimeDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/DoubleDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/GeometryDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int16DataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int32DataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int64DataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/Matrix.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/SingleDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/StringDataReaderCreator.h
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/UniqueFunction.h
Modified:
   trunk/MgDev/Desktop/MapViewer.Desktop/MgDesktopMapViewerProvider.cs
   trunk/MgDev/Desktop/MapViewer/IMapViewer.cs
   trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj
   trunk/MgDev/Desktop/MapViewer/MapViewer.csproj
   trunk/MgDev/Desktop/MapViewer/MapViewerController.cs
   trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs
   trunk/MgDev/Desktop/MapViewer/MgComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs
   trunk/MgDev/Desktop/MapViewer/MgMapViewer.cs
   trunk/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs
   trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
   trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx
   trunk/MgDev/Desktop/MapViewerTest/CompactViewer.cs
   trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.Designer.cs
   trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.cs
   trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.resx
   trunk/MgDev/Desktop/MapViewerTest/Program.cs
   trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
   trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj
   trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters
   trunk/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.h
   trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
   trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.h
Log:
Merge in r6641, r6642, r6644 and r6645

Modified: trunk/MgDev/Desktop/MapViewer/IMapViewer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/IMapViewer.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/IMapViewer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -257,7 +257,7 @@
         /// <summary>
         /// Raised when the viewer has been initialized
         /// </summary>
-        event EventHandler ViewerInitialized;
+        event EventHandler MapLoaded;
 
         /// <summary>
         /// Raised when the map cursor position has changed
@@ -284,6 +284,11 @@
         /// implemented
         /// </summary>
         bool ConvertTiledGroupsToNonTiled { get; set; }
+
+        /// <summary>
+        /// Gets whether this viewer has a map loaded into it
+        /// </summary>
+        bool HasLoadedMap { get; }
     }
 
     /// <summary>

Modified: trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MapViewer.Net40.csproj	2012-05-13 04:07:19 UTC (rev 6646)
@@ -117,6 +117,9 @@
     <Compile Include="MgInvokeComponent.cs">
       <SubType>Component</SubType>
     </Compile>
+    <Compile Include="MgLayerSelectionHandler.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="MgLineMeasureControlImpl.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -177,6 +180,15 @@
     <Compile Include="MgTaskPane.Designer.cs">
       <DependentUpon>MgTaskPane.cs</DependentUpon>
     </Compile>
+    <Compile Include="MgThemeComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgThemeControlImpl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MgThemeControlImpl.Designer.cs">
+      <DependentUpon>MgThemeControlImpl.cs</DependentUpon>
+    </Compile>
     <Compile Include="MgViewerOptionsComponent.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -198,6 +210,7 @@
     <Compile Include="Tasks\MgTaskPaneStub.Designer.cs">
       <DependentUpon>MgTaskPaneStub.cs</DependentUpon>
     </Compile>
+    <Compile Include="Util.cs" />
     <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
   </ItemGroup>
   <ItemGroup>
@@ -229,6 +242,9 @@
     <EmbeddedResource Include="MgTaskPane.resx">
       <DependentUpon>MgTaskPane.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="MgThemeControlImpl.resx">
+      <DependentUpon>MgThemeControlImpl.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="MgViewerOptionsControlImpl.resx">
       <DependentUpon>MgViewerOptionsControlImpl.cs</DependentUpon>
     </EmbeddedResource>
@@ -448,7 +464,6 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="MapViewer.csproj" />
-    <Content Include="MapViewer.csproj.user" />
     <Content Include="Resources\icon_home.gif" />
     <Content Include="Resources\icon_tasks.gif" />
     <Content Include="Resources\load_package.gif" />

Modified: trunk/MgDev/Desktop/MapViewer/MapViewer.csproj
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MapViewer.csproj	2012-05-13 04:07:19 UTC (rev 6646)
@@ -151,12 +151,24 @@
       <DependentUpon>MgQueryResultsDialog.cs</DependentUpon>
     </Compile>
     <Compile Include="MgReadOnlyStream.cs" />
+    <Compile Include="MgLayerSelectionHandler.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="MgTaskPane.cs">
       <SubType>UserControl</SubType>
     </Compile>
     <Compile Include="MgTaskPane.Designer.cs">
       <DependentUpon>MgTaskPane.cs</DependentUpon>
     </Compile>
+    <Compile Include="MgThemeComponent.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="MgThemeControlImpl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MgThemeControlImpl.Designer.cs">
+      <DependentUpon>MgThemeControlImpl.cs</DependentUpon>
+    </Compile>
     <Compile Include="MgViewerOptionsComponent.cs">
       <SubType>Component</SubType>
     </Compile>
@@ -178,6 +190,7 @@
     <Compile Include="Tasks\MgTaskPaneStub.Designer.cs">
       <DependentUpon>MgTaskPaneStub.cs</DependentUpon>
     </Compile>
+    <Compile Include="Util.cs" />
     <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
   </ItemGroup>
   <ItemGroup>
@@ -209,6 +222,9 @@
     <EmbeddedResource Include="MgTaskPane.resx">
       <DependentUpon>MgTaskPane.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="MgThemeControlImpl.resx">
+      <DependentUpon>MgThemeControlImpl.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="MgViewerOptionsControlImpl.resx">
       <DependentUpon>MgViewerOptionsControlImpl.cs</DependentUpon>
     </EmbeddedResource>
@@ -408,6 +424,7 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="Resources\AreaLayerDef.txt" />
+    <None Include="Resources\AreaRuleTemplate.txt" />
     <None Include="Resources\view_log.gif" />
     <None Include="Resources\monitor_status.gif" />
     <None Include="Resources\load_package.gif" />

Modified: trunk/MgDev/Desktop/MapViewer/MapViewerController.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MapViewerController.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MapViewerController.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -61,7 +61,7 @@
             _viewer.MapScaleChanged += new EventHandler(OnMapScaleChanged);
             _viewer.SelectionChanged += new EventHandler(OnMapSelectionChanged);
             _viewer.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnMapPropertyChanged);
-            _viewer.ViewerInitialized += new EventHandler(OnViewerInitialized);
+            _viewer.MapLoaded += new EventHandler(OnViewerMapLoaded);
             _viewer.MouseMapPositionChanged += new EventHandler<MapPointEventArgs>(OnMouseMapPositionChanged);
             if (_legend != null)
             {
@@ -93,7 +93,7 @@
             _viewer.RefreshMap();
         }
 
-        void OnViewerInitialized(object sender, EventArgs e)
+        void OnViewerMapLoaded(object sender, EventArgs e)
         {
             if (_legend != null)
             {

Modified: trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgBufferControlImpl.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -116,7 +116,7 @@
                 MgResourceIdentifier fsId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.FeatureSource");
                 MgResourceIdentifier ldfId = new MgResourceIdentifier("Session:" + _sessionId + "//" + txtBufferLayer.Text + "_Buffer.LayerDefinition");
 
-                MgLayerBase layer = FindLayer(layers, txtBufferLayer.Text);
+                MgLayerBase layer = Util.FindLayer(layers, txtBufferLayer.Text);
                 string[] layerNames = GetLayerNames();
 
                 double distance = Convert.ToDouble(numBufferDistance.Value);
@@ -134,7 +134,7 @@
                         break;
                 }
 
-                String srsDefMap = GetMapSrs(map);
+                String srsDefMap = Util.GetMapSrs(map);
                 MgCoordinateSystem srsMap = provider.GetMapCoordinateSystem();
                 string mapSrsUnits = "";
                 bool arbitraryMapSrs = (srsMap.GetType() == MgCoordinateSystemType.Arbitrary);
@@ -142,9 +142,9 @@
                     mapSrsUnits = srsMap.GetUnits();
 
                 String xtrans = String.Format("{0:x2}", ((int)(255 * Convert.ToInt32(numFillTransparency.Value) / 100)));
-                var lineColor = ToHtmlColor(pnlBorderColor.BackColor);
-                var foreColor = ToHtmlColor(pnlFillColor.BackColor);
-                var backColor = ToHtmlColor(pnlFillBackColor.BackColor);
+                var lineColor = Util.ToHtmlColor(pnlBorderColor.BackColor);
+                var foreColor = Util.ToHtmlColor(pnlFillColor.BackColor);
+                var backColor = Util.ToHtmlColor(pnlFillBackColor.BackColor);
                 String layerTempl = string.Format(Properties.Resources.AreaLayerDef,
                         fsId.ToString(),
                         "BufferSchema:Buffer",
@@ -213,7 +213,7 @@
                 {
                     //data source already exist. clear its content
                     //
-                    ClearDataSource(_featSvc, fsId, "BufferSchema:Buffer");
+                    Util.ClearDataSource(_featSvc, fsId, "BufferSchema:Buffer");
                 }
 
                 var sel = _viewer.GetSelection();
@@ -331,7 +331,7 @@
                                 {
                                     if (srsXform != null)
                                         geomBuffer = (MgGeometry)geomBuffer.Transform(srsXform);
-                                    AddFeatureToCollection(propCollection, agfRW, featId++, geomBuffer);
+                                    Util.AddFeatureToCollection(propCollection, agfRW, featId++, geomBuffer);
                                     bufferFeatures++;
                                 }
                             }
@@ -363,7 +363,7 @@
                         geomBuffer = geomFactory.CreateMultiGeometry(inputGeometries).Buffer(dist, measure);
                         if (geomBuffer != null)
                         {
-                            AddFeatureToCollection(propCollection, agfRW, featId, geomBuffer);
+                            Util.AddFeatureToCollection(propCollection, agfRW, featId, geomBuffer);
                             bufferFeatures = 1;
                         }
                     }
@@ -375,7 +375,7 @@
 
                     //Insert the features in the temporary data source
                     //
-                    ReleaseReader(_featSvc.UpdateFeatures(fsId, commands, false), commands);
+                    Util.ReleaseReader(_featSvc.UpdateFeatures(fsId, commands, false), commands);
                 }
 
                 // Save the new map state
@@ -401,86 +401,6 @@
             }
             return items.ToArray();
         }
-
-        static string ToHtmlColor(Color color)
-        {
-            return String.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
-        }
-
-        static MgLayerBase FindLayer(MgLayerCollection layers, String layerName)
-        {
-            MgLayerBase layer = null;
-            int i = 0;
-            for (i = 0; i < layers.GetCount(); i++)
-            {
-                MgLayerBase layer1 = layers.GetItem(i);
-
-                if (layer1.GetName() == layerName)
-                {
-                    layer = layer1;
-                    break;
-                }
-            }
-            return layer;
-        }
-
-        static string GetMapSrs(MgMapBase map)
-        {
-            try
-            {
-                String srs = map.GetMapSRS();
-                if (srs != "")
-                    return srs;
-            }
-            catch (MgException e)
-            {
-            }
-
-            //No SRS, set to ArbitrayXY meters
-            //
-            return "LOCALCS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
-        }
-
-        static void ClearDataSource(MgFeatureService featSvc, MgResourceIdentifier fsId, String featureName)
-        {
-            MgDeleteFeatures deleteCmd = new MgDeleteFeatures(featureName, "ID >= 0");
-            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
-            commands.Add(deleteCmd);
-            featSvc.UpdateFeatures(fsId, commands, false);
-        }
-
-        static void ReleaseReader(MgPropertyCollection res, MgFeatureCommandCollection commands)
-        {
-            if (res == null)
-                return;
-
-            for (int i = 0; i < res.GetCount(); i++)
-            {
-                MgFeatureCommand cmd = commands.GetItem(i);
-                if (cmd is MgInsertFeatures)
-                {
-                    MgFeatureProperty resProp = res.GetItem(i) as MgFeatureProperty;
-                    if (resProp != null)
-                    {
-                        MgFeatureReader reader = resProp.GetValue() as MgFeatureReader;
-                        if (reader == null)
-                            return;
-                        reader.Close();
-                    }
-                }
-            }
-        }
-
-        static void AddFeatureToCollection(MgBatchPropertyCollection propCollection, MgAgfReaderWriter agfRW, int featureId, MgGeometry featureGeom)
-        {
-            MgPropertyCollection bufferProps = new MgPropertyCollection();
-            MgInt32Property idProp = new MgInt32Property("ID", featureId);
-            bufferProps.Add(idProp);
-            MgByteReader geomReader = agfRW.Write(featureGeom);
-            MgGeometryProperty geomProp = new MgGeometryProperty("GEOM", geomReader);
-            bufferProps.Add(geomProp);
-            propCollection.Add(bufferProps);
-        }
     }
 
     public enum StockPattern

Modified: trunk/MgDev/Desktop/MapViewer/MgComponent.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgComponent.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgComponent.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -74,9 +74,37 @@
         protected virtual void SubscribeViewerEvents(IMapViewer viewer)
         {
             if (viewer != null)
+            {
                 viewer.PropertyChanged += OnViewerPropertyChanged;
+                viewer.MapLoaded += OnViewerMapLoaded;
+
+                if (this.RequiresLoadedMap)
+                {
+                    foreach (var l in _listeners)
+                        l.SetEnabled(viewer.HasLoadedMap);
+                }
+            }
         }
 
+        /// <summary>
+        /// Unsubscribes events from the specified viewer instance
+        /// </summary>
+        /// <param name="viewer"></param>
+        protected virtual void UnsubscribeViewerEvents(IMapViewer viewer)
+        {
+            if (viewer != null)
+            {
+                viewer.PropertyChanged -= OnViewerPropertyChanged;
+                viewer.MapLoaded -= OnViewerMapLoaded;
+            }
+        }
+
+        protected virtual void OnViewerMapLoaded(object sender, EventArgs e)
+        {
+            foreach (var l in _listeners)
+                l.SetEnabled(this.Viewer.HasLoadedMap);
+        }
+
         protected virtual void OnViewerPropertyChanged(object sender, PropertyChangedEventArgs e)
         {
             if (e.PropertyName == "IsBusy")
@@ -86,7 +114,7 @@
                 if (this.DisableWhenMapIsLoading)
                 {
                     foreach (var l in _listeners)
-                        l.SetDisabled(busy);
+                        l.SetEnabled(!busy);
                 }
             }
             else if (e.PropertyName == "DigitizingType")
@@ -95,26 +123,25 @@
                 if (this.DisableWhenDigitizing)
                 {
                     foreach (var l in _listeners)
-                        l.SetDisabled(bDigitizing);
+                        l.SetEnabled(!bDigitizing);
                 }
             }
         }
-
+        
         /// <summary>
-        /// Unsubscribes events from the specified viewer instance
+        /// Gets whether this component requires a loaded map. If true, and no map is loaded this
+        /// component will be disabled until a map is loaded. If false, this component stays enabled
+        /// and can operate without a loaded map
         /// </summary>
-        /// <param name="viewer"></param>
-        protected virtual void UnsubscribeViewerEvents(IMapViewer viewer)
-        {
-            if (viewer != null)
-                viewer.PropertyChanged -= OnViewerPropertyChanged;
-        }
+        protected virtual bool RequiresLoadedMap { get { return true; } }
 
         protected List<IButtonStateListener> _listeners = new List<IButtonStateListener>();
 
         public void AddListener(IButtonStateListener listener)
         {
             _listeners.Add(listener);
+            if (this.RequiresLoadedMap)
+                listener.SetEnabled(this.Viewer != null && this.Viewer.HasLoadedMap);
         }
 
         public void RemoveListener(IButtonStateListener listener)
@@ -135,7 +162,7 @@
 
     public interface IButtonStateListener
     {
-        void SetDisabled(bool busy);
+        void SetEnabled(bool enabled);
         void SetActive(bool outlined);
         void SetText(string text);
         void SetIcon(Image icon);

Modified: trunk/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgGenericInvokeComponent.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -13,6 +13,24 @@
             this.Icon = Properties.Resources.invoke_script;
         }
 
+        [Category("MapGuide Viewer")]
+        [Description("Indicates whether this component can be invoked without a loaded map")]
+        public bool CanInvokeWithoutLoadedMap
+        {
+            get;
+            set;
+        }
+
+        protected override bool RequiresLoadedMap
+        {
+            get
+            {
+                return !this.CanInvokeWithoutLoadedMap;
+            }
+        }
+
+        [Category("MapGuide Viewer")]
+        [Description("Raised when this component has been invoked")]
         public event EventHandler Invoked;
 
         public override void Invoke()

Modified: trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgInvokeComponent.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -21,129 +21,203 @@
         MgComponent TargetComponent { get; set; }
     }
 
-    /// <summary>
-    /// A specialized instance of <see cref="T:System.Windows.Forms.ToolStripButton"/> that can
-    /// invoke the assigned <see cref="T:OSGeo.MapGuide.Viewer.MgComponent"/> instance.
-    /// </summary>
-    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip)]
-    public class MgInvokeComponentButton : ToolStripButton, IButtonStateListener, IInvokeViewerComponent
+    [ToolboxItem(false)]
+    public class ComponentInvokerBase<T> : Component where T : ToolStripItem
     {
-        private MgComponent _component;
+        protected Dictionary<T, MgComponent> _bindings;
 
-        /// <summary>
-        /// Gets or sets the target component to be invoked
-        /// </summary>
-        [Category("MapGuide Component Properties")]
-        [Description("The target component to invoke when this component is clicked. All other UI properties are inherited from this compoent")]
-        public MgComponent TargetComponent
+        protected ComponentInvokerBase() { _bindings = new Dictionary<T, MgComponent>(); }
+
+        [Category("MapGuide Viewer")]
+        [DisplayName("Target Component")]
+        [Description("The target MapGuide component to invoke when this item is clicked")]
+        [DefaultValue(null)]
+        public MgComponent GetTargetComponent(T component)
         {
-            get { return _component; }
-            set 
+            if (_bindings.ContainsKey(component))
+                return _bindings[component];
+            else
+                return null;
+        }
+
+        void OnComponentClicked(object sender, EventArgs e)
+        {
+            var item = sender as T;
+            var binding = item.Tag as ComponentBinding;
+            if (binding != null)
+                binding.Component.Invoke();
+        }
+
+        protected virtual void SetupComponent(T component, MgComponent value)
+        {
+            component.Click += OnComponentClicked;
+        }
+
+        protected virtual void TeardownComponent(T component, MgComponent value)
+        {
+            component.Click -= OnComponentClicked;
+        }
+
+        public void SetTargetComponent(T component, MgComponent value)
+        {
+            if (value == null)
             {
-                if (_component != null)
-                    _component.RemoveListener(this);
-                _component = value;
-                if (_component != null)
+                //Un-bind existing component if it exists, otherwise nothing needs to be done
+                if (_bindings.ContainsKey(component))
                 {
-                    base.ToolTipText = _component.ToolTipText;
-                    base.Text = _component.Label;
-                    base.Image = _component.Icon;
-                    _component.AddListener(this);
+                    TeardownComponent(component, _bindings[component]);
+                    _bindings.Remove(component);
                 }
             }
+            else
+            {
+                if (_bindings.ContainsKey(component))
+                {
+                    TeardownComponent(component, _bindings[component]);
+                    _bindings[component] = value;
+                    SetupComponent(component, value);
+                }
+                else
+                {
+                    _bindings[component] = value;
+                    SetupComponent(component, value);
+                }
+            }
         }
+    }
 
-        protected override void OnClick(EventArgs e)
-        {
-            if (this.TargetComponent == null)
-                throw new InvalidOperationException("No target component assigned to this component");
+    abstract class ComponentBinding : IButtonStateListener 
+    {
+        public MgComponent Component { get; protected set; }
 
-            this.TargetComponent.Invoke();
+        protected ComponentBinding(MgComponent component) { this.Component = component; }
 
-            base.OnClick(e);
+        public abstract void SetEnabled(bool enabled);
+
+        public abstract void SetActive(bool outlined);
+
+        public abstract void SetText(string text);
+
+        public abstract void SetIcon(Image icon);
+    }
+
+    class ToolbarButtonComponentBinding : ComponentBinding
+    {
+        private ToolStripButton _item;
+
+        public ToolbarButtonComponentBinding(ToolStripButton item, MgComponent component) 
+            : base(component)
+        {
+            _item = item;
         }
 
-        public void SetDisabled(bool busy)
+        public override void SetEnabled(bool enabled)
         {
-            this.Enabled = !busy;
+            _item.Enabled = enabled;
         }
 
-        public void SetActive(bool outlined)
+        public override void SetActive(bool outlined)
         {
-            this.Checked = outlined;
+            _item.Checked = outlined;
         }
 
-        public void SetText(string text)
+        public override void SetText(string text)
         {
-            this.Text = text;
+            _item.Text = text;
         }
 
-        public void SetIcon(Image icon)
+        public override void SetIcon(Image icon)
         {
-            this.Image = icon;
+            _item.Image = icon;
         }
     }
 
-    /// <summary>
-    /// A specialized instance of <see cref="T:System.Windows.Forms.ToolStripMenuItem"/> that can
-    /// invoke the assigned <see cref="T:OSGeo.MapGuide.Viewer.MgComponent"/> instance.
-    /// </summary>
-    [ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ContextMenuStrip | ToolStripItemDesignerAvailability.MenuStrip)]
-    public class MgInvokeComponentMenuItem : ToolStripMenuItem, IButtonStateListener, IInvokeViewerComponent
+    class MenuItemComponentBinding : ComponentBinding
     {
-        private MgComponent _component;
+        private ToolStripMenuItem _item;
 
-        /// <summary>
-        /// Gets or sets the target component to be invoked
-        /// </summary>
-        [Category("MapGuide Component Properties")]
-        [Description("The target component to invoke when this component is clicked. All other UI properties are inherited from this compoent")]
-        public MgComponent TargetComponent
+        public MenuItemComponentBinding(ToolStripMenuItem item, MgComponent component) 
+            : base(component)
+        { 
+            _item = item;
+        }
+
+        public override void SetEnabled(bool enabled)
         {
-            get { return _component; }
-            set
-            {
-                if (_component != null)
-                    _component.RemoveListener(this);
-                _component = value;
-                if (_component != null)
-                {
-                    base.ToolTipText = _component.ToolTipText;
-                    base.Text = _component.Label;
-                    base.Image = _component.Icon;
-                    _component.AddListener(this);
-                }
-            }
+            _item.Enabled = enabled;
         }
 
-        protected override void OnClick(EventArgs e)
+        public override void SetActive(bool outlined)
         {
-            if (this.TargetComponent == null)
-                throw new InvalidOperationException("No target component assigned to this component");
+            _item.Checked = outlined;
+        }
 
-            this.TargetComponent.Invoke();
+        public override void SetText(string text)
+        {
+            _item.Text = text;
+        }
 
-            base.OnClick(e);
+        public override void SetIcon(Image icon)
+        {
+            _item.Image = icon;
         }
+    }
 
-        public void SetDisabled(bool busy)
+    [ToolboxItem(true)]
+    [ProvideProperty("TargetComponent", typeof(ToolStripMenuItem))]
+    public class MgMenuItemComponentInvoker : ComponentInvokerBase<ToolStripMenuItem>, IExtenderProvider
+    {
+        public bool CanExtend(object extendee)
         {
-            this.Enabled = !busy;
+            return typeof(ToolStripMenuItem) == extendee.GetType();
         }
 
-        public void SetActive(bool outlined)
+        protected override void SetupComponent(ToolStripMenuItem component, MgComponent value)
         {
-            this.Checked = outlined;
+            component.ToolTipText = value.ToolTipText;
+            component.Text = value.Label;
+            component.Image = value.Icon;
+            var listener = new MenuItemComponentBinding(component, value);
+            component.Tag = listener;
+            value.AddListener(listener);
+            base.SetupComponent(component, value);
         }
 
-        public void SetText(string text)
+        protected override void TeardownComponent(ToolStripMenuItem component, MgComponent value)
         {
-            this.Text = text;
+            var listener = component.Tag as MenuItemComponentBinding;
+            if (listener != null)
+                value.RemoveListener(listener);
+            base.TeardownComponent(component, value);
         }
+    }
 
-        public void SetIcon(Image icon)
+    [ToolboxItem(true)]
+    [ProvideProperty("TargetComponent", typeof(ToolStripButton))]
+    public class MgToolButtonComponentInvoker : ComponentInvokerBase<ToolStripButton>, IExtenderProvider
+    {
+        public bool CanExtend(object extendee)
         {
-            this.Image = icon;
+            return typeof(ToolStripButton) == extendee.GetType();
         }
+
+        protected override void SetupComponent(ToolStripButton component, MgComponent value)
+        {
+            component.ToolTipText = value.ToolTipText;
+            component.Text = value.Label;
+            component.Image = value.Icon;
+            var listener = new ToolbarButtonComponentBinding(component, value);
+            component.Tag = listener;
+            value.AddListener(listener);
+            base.SetupComponent(component, value);
+        }
+
+        protected override void TeardownComponent(ToolStripButton component, MgComponent value)
+        {
+            var listener = component.Tag as ToolbarButtonComponentBinding;
+            if (listener != null)
+                value.RemoveListener(listener);
+            base.TeardownComponent(component, value);
+        }
     }
 }

Copied: trunk/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgLayerSelectionHandler.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    public delegate void MgLayerSelectionEventHandler(string layerName, MgFeatureReader selectedFeatures);
+
+    [DefaultEvent("SelectionMade")]
+    [ToolboxItem(true)]
+    public class MgLayerSelectionHandler : Component
+    {
+        [Category("MapGuide Viewer")]
+        [Description("The map layers that this component will listen for selections")]
+        public string[] Layers { get; set; }
+
+        private IMapViewer _viewer;
+
+        [Category("MapGuide Viewer")]
+        [Description("The map viewer instance")]
+        public IMapViewer Viewer
+        {
+            get { return _viewer; }
+            set 
+            {
+                if (_viewer != null)
+                    _viewer.SelectionChanged -= OnViewerSelectionChanged;
+                _viewer = value; 
+                if (_viewer != null)
+                    _viewer.SelectionChanged += OnViewerSelectionChanged;
+            }
+        }
+
+        void OnViewerSelectionChanged(object sender, EventArgs e)
+        {
+            if (this.Layers == null || this.Layers.Length == 0)
+                return;
+
+            var sel = _viewer.GetSelection();
+            var selLayers = sel.GetLayers();
+            if (selLayers != null)
+            {
+                var layers = new Dictionary<string, MgLayerBase>();
+                for (int i = 0; i < selLayers.Count; i++)
+                {
+                    var layerItem = selLayers.GetItem(i);
+                    layers.Add(layerItem.Name, layerItem);
+                }
+                foreach (var layerName in this.Layers)
+                {
+                    if (layers.ContainsKey(layerName))
+                    {
+                        var h = this.SelectionMade;
+                        if (h != null)
+                        {
+                            var reader = sel.GetSelectedFeatures(layers[layerName], layers[layerName].FeatureClassName, false);
+                            h(layerName, reader);
+                        }
+                    }
+                }
+            }
+        }
+
+        [Category("MapGuide Viewer")]
+        [Description("Raised when a selection on any of the specified layers has been made")]
+        public event MgLayerSelectionEventHandler SelectionMade;
+    }
+}

Modified: trunk/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgLoadPackageComponent.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -15,6 +15,14 @@
             this.Icon = Properties.Resources.load_package;
         }
 
+        protected override bool RequiresLoadedMap
+        {
+            get
+            {
+                return false;
+            }
+        }
+
         public override void Invoke()
         {
             using (var open = new OpenFileDialog())
@@ -30,7 +38,7 @@
                     var br = source.GetReader();
 
                     resSvc.ApplyResourcePackage(br);
-                    MessageBox.Show(Properties.Resources.TextLoadPackage);
+                    MessageBox.Show(Properties.Resources.TextPackageLoaded);
                 }
             }
         }

Modified: trunk/MgDev/Desktop/MapViewer/MgMapViewer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -35,8 +35,6 @@
 
         private Color _mapBgColor;
 
-        private bool firstRun = true;
-
         private double _orgX1;
         private double _orgX2;
         private double _orgY1;
@@ -965,8 +963,17 @@
             return new MgViewerRenderingOptions("PNG", (1 | 4), new MgColor(red, green, blue));
         }
 
+        public void LoadMap(MgMapBase map)
+        {
+            if (_provider == null)
+                throw new InvalidOperationException("Viewer not initialized via Init()");
+
+            _provider.LoadMap(map);
+        }
+
         /// <summary>
-        /// Initializes this viewer with the specified runtime map
+        /// Initializes this viewer with the specified viewer provider, if the provider contains a map
+        /// it will load that as well. Otherwise a call to <see cref="LoadMap"/> is required afterwards
         /// </summary>
         /// <param name="provider">The provider.</param>
         public void Init(MgMapViewerProvider provider)
@@ -981,21 +988,35 @@
                 _geomFact = new MgGeometryFactory();
 
             _provider = provider;
-            
-            _mapCs = _provider.GetMapCoordinateSystem();
-            _mapMeasure = _mapCs.GetMeasure();
 
-            if (_resSvc == null)
+            if (_resSvc != null) //Forward looking, dispose the existing one as it may be of a different implementation
             {
-                if (_resSvc == null)
-                    _resSvc = (MgResourceService)_provider.CreateService(MgServiceType.ResourceService);
+                _resSvc.Dispose();
+                _resSvc = null;
             }
-            
+            _resSvc = (MgResourceService)_provider.CreateService(MgServiceType.ResourceService);
+
             _overlayRenderOpts = CreateMapRenderingOptions(0, 0, 255);
             _selectionRenderOpts = CreateSelectionRenderingOptions(0, 0, 255);
 
+            if (_provider != null)
+            {
+                _provider.MapLoaded -= OnMapSetOnProvider;
+                _provider = null;
+            }
+
             _provider = provider;
-            _map = provider.GetMap();
+            _provider.MapLoaded += OnMapSetOnProvider;
+            var map = _provider.GetMap();
+            if (map != null)
+                OnMapSetOnProvider(this, EventArgs.Empty);
+        }
+
+        private void OnMapSetOnProvider(object sender, EventArgs e)
+        {
+            _map = _provider.GetMap();
+            _mapCs = _provider.GetMapCoordinateSystem();
+            _mapMeasure = _mapCs.GetMeasure();
             var bgColor = _map.GetBackgroundColor();
             if (bgColor.Length == 8 || bgColor.Length == 6)
             {
@@ -1032,15 +1053,12 @@
                 }
             }
 
-            _provider.RebuildLayerInfoCache();
-            _provider.CacheGeometryProperties(_map.GetLayers());
-
 #if VIEWER_DEBUG
             CreateDebugFeatureSource();
 #endif
             this.Focus();
 
-            var handler = this.ViewerInitialized;
+            var handler = this.MapLoaded;
             if (handler != null)
                 handler(this, EventArgs.Empty);
 
@@ -1083,7 +1101,7 @@
         /// </summary>
         [Category("MapGuide Viewer")]
         [Description("Raised when the viewer has been initialized with a runtime map")]
-        public event EventHandler ViewerInitialized;
+        public event EventHandler MapLoaded;
 
         private System.Timers.Timer _delayedResizeTimer;
 
@@ -2510,5 +2528,7 @@
             if (handler != null)
                 handler(this, new PropertyChangedEventArgs(name));
         }
+
+        public bool HasLoadedMap { get { return _map != null; } }
     }
 }

Modified: trunk/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/MgMapViewerProvider.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -50,14 +50,41 @@
         /// </summary>
         protected MgResourceService _resSvc;
 
-        protected MgMapViewerProvider(MgMapBase map, MgResourceService resSvc)
+        protected MgMapViewerProvider(MgMapBase map)
         {
-            _map = map;
-            _resSvc = resSvc;
+            SubInit();
+            LoadMap(map);
         }
 
+        protected virtual void SubInit() { }
+
         public MgMapBase GetMap() { return _map; }
 
+        protected virtual void DisposeExistingMap()
+        {
+            if (_map != null)
+            {
+                _map.Dispose();
+                _map = null;
+            }
+        }
+
+        internal void LoadMap(MgMapBase map)
+        {
+            if (map == null)
+                return;
+
+            DisposeExistingMap();
+            _map = map;
+            RebuildLayerInfoCache();
+            CacheGeometryProperties(_map.GetLayers());
+            var h = this.MapLoaded;
+            if (h != null)
+                h(this, EventArgs.Empty);
+        }
+
+        internal event EventHandler MapLoaded;
+
         /// <summary>
         /// The coordinate system factory
         /// </summary>
@@ -133,11 +160,14 @@
         private Dictionary<string, XmlDocument> _cachedLayerDefinitions = new Dictionary<string, XmlDocument>();
         private Dictionary<string, string> _tooltipExpressions = new Dictionary<string, string>();
 
-        public void RebuildLayerInfoCache()
+        protected void RebuildLayerInfoCache()
         {
             _cachedLayerDefinitions.Clear();
             _tooltipExpressions.Clear();
             _propertyMappings.Clear();
+            if (_resSvc == null)
+                _resSvc = (MgResourceService)CreateService(MgServiceType.ResourceService);
+
             //Pre-cache layer definitions and tooltip properties
             var layers = _map.GetLayers();
             MgStringCollection resIds = new MgStringCollection();

Copied: trunk/MgDev/Desktop/MapViewer/MgThemeComponent.cs (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/MgThemeComponent.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgThemeComponent.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgThemeComponent.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    [ToolboxItem(true)]
+    public class MgThemeComponent : MgViewerComponent
+    {
+        public MgThemeComponent()
+        {
+            this.Icon = Properties.Resources.lc_theme;
+            this.Label = this.ToolTipText = Properties.Resources.TitleTheme;
+        }
+
+        protected override MgControlImpl CreateControlImpl()
+        {
+            return new MgThemeControlImpl(this.Viewer);
+        }
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.Designer.cs (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.Designer.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.Designer.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,511 @@
+namespace OSGeo.MapGuide.Viewer
+{
+    partial class MgThemeControlImpl
+    {
+        /// <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.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.txtThemeName = new System.Windows.Forms.TextBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.cmbLayer = new System.Windows.Forms.ComboBox();
+            this.label1 = new System.Windows.Forms.Label();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.numRules = new System.Windows.Forms.NumericUpDown();
+            this.cmbScaleRange = new System.Windows.Forms.ComboBox();
+            this.label8 = new System.Windows.Forms.Label();
+            this.txtMax = new System.Windows.Forms.TextBox();
+            this.txtMin = new System.Windows.Forms.TextBox();
+            this.cmbDistribution = new System.Windows.Forms.ComboBox();
+            this.cmbProperty = new System.Windows.Forms.ComboBox();
+            this.label7 = new System.Windows.Forms.Label();
+            this.label6 = new System.Windows.Forms.Label();
+            this.label5 = new System.Windows.Forms.Label();
+            this.label4 = new System.Windows.Forms.Label();
+            this.label3 = new System.Windows.Forms.Label();
+            this.groupBox3 = new System.Windows.Forms.GroupBox();
+            this.btnToBorderColor = new System.Windows.Forms.Button();
+            this.pnlToBorderColor = new System.Windows.Forms.Panel();
+            this.btnFromBorderColor = new System.Windows.Forms.Button();
+            this.btnToFillColor = new System.Windows.Forms.Button();
+            this.pnlFromBorderColor = new System.Windows.Forms.Panel();
+            this.btnFromFillColor = new System.Windows.Forms.Button();
+            this.pnlToFillColor = new System.Windows.Forms.Panel();
+            this.pnlFromFillColor = new System.Windows.Forms.Panel();
+            this.label14 = new System.Windows.Forms.Label();
+            this.label15 = new System.Windows.Forms.Label();
+            this.label13 = new System.Windows.Forms.Label();
+            this.label12 = new System.Windows.Forms.Label();
+            this.label11 = new System.Windows.Forms.Label();
+            this.label10 = new System.Windows.Forms.Label();
+            this.numFillTransparency = new System.Windows.Forms.NumericUpDown();
+            this.label9 = new System.Windows.Forms.Label();
+            this.btnApply = new System.Windows.Forms.Button();
+            this.colorDialog = new System.Windows.Forms.ColorDialog();
+            this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numRules)).BeginInit();
+            this.groupBox3.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Controls.Add(this.txtThemeName);
+            this.groupBox1.Controls.Add(this.label2);
+            this.groupBox1.Controls.Add(this.cmbLayer);
+            this.groupBox1.Controls.Add(this.label1);
+            this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox1.Location = new System.Drawing.Point(0, 0);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(269, 112);
+            this.groupBox1.TabIndex = 0;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "General";
+            // 
+            // txtThemeName
+            // 
+            this.txtThemeName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtThemeName.Location = new System.Drawing.Point(15, 79);
+            this.txtThemeName.Name = "txtThemeName";
+            this.txtThemeName.Size = new System.Drawing.Size(237, 20);
+            this.txtThemeName.TabIndex = 3;
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(12, 63);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(71, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Theme Name";
+            // 
+            // cmbLayer
+            // 
+            this.cmbLayer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbLayer.DisplayMember = "Name";
+            this.cmbLayer.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbLayer.FormattingEnabled = true;
+            this.cmbLayer.Location = new System.Drawing.Point(15, 35);
+            this.cmbLayer.Name = "cmbLayer";
+            this.cmbLayer.Size = new System.Drawing.Size(237, 21);
+            this.cmbLayer.TabIndex = 1;
+            this.cmbLayer.SelectedIndexChanged += new System.EventHandler(this.cmbLayer_SelectedIndexChanged);
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(12, 19);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(57, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "Map Layer";
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Controls.Add(this.numRules);
+            this.groupBox2.Controls.Add(this.cmbScaleRange);
+            this.groupBox2.Controls.Add(this.label8);
+            this.groupBox2.Controls.Add(this.txtMax);
+            this.groupBox2.Controls.Add(this.txtMin);
+            this.groupBox2.Controls.Add(this.cmbDistribution);
+            this.groupBox2.Controls.Add(this.cmbProperty);
+            this.groupBox2.Controls.Add(this.label7);
+            this.groupBox2.Controls.Add(this.label6);
+            this.groupBox2.Controls.Add(this.label5);
+            this.groupBox2.Controls.Add(this.label4);
+            this.groupBox2.Controls.Add(this.label3);
+            this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox2.Location = new System.Drawing.Point(0, 112);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(269, 276);
+            this.groupBox2.TabIndex = 1;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Theme Conditions";
+            // 
+            // numRules
+            // 
+            this.numRules.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.numRules.Location = new System.Drawing.Point(110, 198);
+            this.numRules.Name = "numRules";
+            this.numRules.Size = new System.Drawing.Size(141, 20);
+            this.numRules.TabIndex = 12;
+            // 
+            // cmbScaleRange
+            // 
+            this.cmbScaleRange.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbScaleRange.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbScaleRange.FormattingEnabled = true;
+            this.cmbScaleRange.Location = new System.Drawing.Point(15, 241);
+            this.cmbScaleRange.Name = "cmbScaleRange";
+            this.cmbScaleRange.Size = new System.Drawing.Size(237, 21);
+            this.cmbScaleRange.TabIndex = 11;
+            // 
+            // label8
+            // 
+            this.label8.AutoSize = true;
+            this.label8.Location = new System.Drawing.Point(12, 225);
+            this.label8.Name = "label8";
+            this.label8.Size = new System.Drawing.Size(69, 13);
+            this.label8.TabIndex = 10;
+            this.label8.Text = "Scale Range";
+            // 
+            // txtMax
+            // 
+            this.txtMax.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtMax.Location = new System.Drawing.Point(15, 123);
+            this.txtMax.Name = "txtMax";
+            this.txtMax.Size = new System.Drawing.Size(237, 20);
+            this.txtMax.TabIndex = 9;
+            // 
+            // txtMin
+            // 
+            this.txtMin.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtMin.Location = new System.Drawing.Point(15, 79);
+            this.txtMin.Name = "txtMin";
+            this.txtMin.Size = new System.Drawing.Size(237, 20);
+            this.txtMin.TabIndex = 8;
+            // 
+            // cmbDistribution
+            // 
+            this.cmbDistribution.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbDistribution.DisplayMember = "Value";
+            this.cmbDistribution.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbDistribution.FormattingEnabled = true;
+            this.cmbDistribution.Location = new System.Drawing.Point(15, 167);
+            this.cmbDistribution.Name = "cmbDistribution";
+            this.cmbDistribution.Size = new System.Drawing.Size(237, 21);
+            this.cmbDistribution.TabIndex = 7;
+            this.cmbDistribution.ValueMember = "Key";
+            this.cmbDistribution.SelectedIndexChanged += new System.EventHandler(this.cmbDistribution_SelectedIndexChanged);
+            // 
+            // cmbProperty
+            // 
+            this.cmbProperty.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.cmbProperty.DisplayMember = "Name";
+            this.cmbProperty.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cmbProperty.FormattingEnabled = true;
+            this.cmbProperty.Location = new System.Drawing.Point(15, 36);
+            this.cmbProperty.Name = "cmbProperty";
+            this.cmbProperty.Size = new System.Drawing.Size(237, 21);
+            this.cmbProperty.TabIndex = 6;
+            this.cmbProperty.SelectedIndexChanged += new System.EventHandler(this.cmbProperty_SelectedIndexChanged);
+            // 
+            // label7
+            // 
+            this.label7.AutoSize = true;
+            this.label7.Location = new System.Drawing.Point(12, 200);
+            this.label7.Name = "label7";
+            this.label7.Size = new System.Drawing.Size(86, 13);
+            this.label7.TabIndex = 4;
+            this.label7.Text = "Number of Rules";
+            // 
+            // label6
+            // 
+            this.label6.AutoSize = true;
+            this.label6.Location = new System.Drawing.Point(12, 151);
+            this.label6.Name = "label6";
+            this.label6.Size = new System.Drawing.Size(59, 13);
+            this.label6.TabIndex = 3;
+            this.label6.Text = "Distribution";
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(12, 107);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(27, 13);
+            this.label5.TabIndex = 2;
+            this.label5.Text = "Max";
+            // 
+            // label4
+            // 
+            this.label4.AutoSize = true;
+            this.label4.Location = new System.Drawing.Point(12, 63);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(24, 13);
+            this.label4.TabIndex = 1;
+            this.label4.Text = "Min";
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(12, 20);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(46, 13);
+            this.label3.TabIndex = 0;
+            this.label3.Text = "Property";
+            // 
+            // groupBox3
+            // 
+            this.groupBox3.Controls.Add(this.btnToBorderColor);
+            this.groupBox3.Controls.Add(this.pnlToBorderColor);
+            this.groupBox3.Controls.Add(this.btnFromBorderColor);
+            this.groupBox3.Controls.Add(this.btnToFillColor);
+            this.groupBox3.Controls.Add(this.pnlFromBorderColor);
+            this.groupBox3.Controls.Add(this.btnFromFillColor);
+            this.groupBox3.Controls.Add(this.pnlToFillColor);
+            this.groupBox3.Controls.Add(this.pnlFromFillColor);
+            this.groupBox3.Controls.Add(this.label14);
+            this.groupBox3.Controls.Add(this.label15);
+            this.groupBox3.Controls.Add(this.label13);
+            this.groupBox3.Controls.Add(this.label12);
+            this.groupBox3.Controls.Add(this.label11);
+            this.groupBox3.Controls.Add(this.label10);
+            this.groupBox3.Controls.Add(this.numFillTransparency);
+            this.groupBox3.Controls.Add(this.label9);
+            this.groupBox3.Dock = System.Windows.Forms.DockStyle.Top;
+            this.groupBox3.Location = new System.Drawing.Point(0, 388);
+            this.groupBox3.Name = "groupBox3";
+            this.groupBox3.Size = new System.Drawing.Size(269, 162);
+            this.groupBox3.TabIndex = 2;
+            this.groupBox3.TabStop = false;
+            this.groupBox3.Text = "Style Ramp";
+            // 
+            // btnToBorderColor
+            // 
+            this.btnToBorderColor.Location = new System.Drawing.Point(222, 123);
+            this.btnToBorderColor.Name = "btnToBorderColor";
+            this.btnToBorderColor.Size = new System.Drawing.Size(29, 23);
+            this.btnToBorderColor.TabIndex = 13;
+            this.btnToBorderColor.Text = "...";
+            this.btnToBorderColor.UseVisualStyleBackColor = true;
+            this.btnToBorderColor.Click += new System.EventHandler(this.btnToBorderColor_Click);
+            // 
+            // pnlToBorderColor
+            // 
+            this.pnlToBorderColor.BackColor = System.Drawing.Color.Black;
+            this.pnlToBorderColor.Location = new System.Drawing.Point(178, 123);
+            this.pnlToBorderColor.Name = "pnlToBorderColor";
+            this.pnlToBorderColor.Size = new System.Drawing.Size(38, 23);
+            this.pnlToBorderColor.TabIndex = 12;
+            // 
+            // btnFromBorderColor
+            // 
+            this.btnFromBorderColor.Location = new System.Drawing.Point(110, 123);
+            this.btnFromBorderColor.Name = "btnFromBorderColor";
+            this.btnFromBorderColor.Size = new System.Drawing.Size(29, 23);
+            this.btnFromBorderColor.TabIndex = 11;
+            this.btnFromBorderColor.Text = "...";
+            this.btnFromBorderColor.UseVisualStyleBackColor = true;
+            this.btnFromBorderColor.Click += new System.EventHandler(this.btnFromBorderColor_Click);
+            // 
+            // btnToFillColor
+            // 
+            this.btnToFillColor.Location = new System.Drawing.Point(222, 71);
+            this.btnToFillColor.Name = "btnToFillColor";
+            this.btnToFillColor.Size = new System.Drawing.Size(29, 23);
+            this.btnToFillColor.TabIndex = 11;
+            this.btnToFillColor.Text = "...";
+            this.btnToFillColor.UseVisualStyleBackColor = true;
+            this.btnToFillColor.Click += new System.EventHandler(this.btnToFillColor_Click);
+            // 
+            // pnlFromBorderColor
+            // 
+            this.pnlFromBorderColor.BackColor = System.Drawing.Color.Black;
+            this.pnlFromBorderColor.Location = new System.Drawing.Point(66, 123);
+            this.pnlFromBorderColor.Name = "pnlFromBorderColor";
+            this.pnlFromBorderColor.Size = new System.Drawing.Size(38, 23);
+            this.pnlFromBorderColor.TabIndex = 10;
+            // 
+            // btnFromFillColor
+            // 
+            this.btnFromFillColor.Location = new System.Drawing.Point(110, 71);
+            this.btnFromFillColor.Name = "btnFromFillColor";
+            this.btnFromFillColor.Size = new System.Drawing.Size(29, 23);
+            this.btnFromFillColor.TabIndex = 9;
+            this.btnFromFillColor.Text = "...";
+            this.btnFromFillColor.UseVisualStyleBackColor = true;
+            this.btnFromFillColor.Click += new System.EventHandler(this.btnFromFillColor_Click);
+            // 
+            // pnlToFillColor
+            // 
+            this.pnlToFillColor.BackColor = System.Drawing.Color.Blue;
+            this.pnlToFillColor.Location = new System.Drawing.Point(178, 71);
+            this.pnlToFillColor.Name = "pnlToFillColor";
+            this.pnlToFillColor.Size = new System.Drawing.Size(38, 23);
+            this.pnlToFillColor.TabIndex = 10;
+            // 
+            // pnlFromFillColor
+            // 
+            this.pnlFromFillColor.BackColor = System.Drawing.Color.Red;
+            this.pnlFromFillColor.Location = new System.Drawing.Point(66, 71);
+            this.pnlFromFillColor.Name = "pnlFromFillColor";
+            this.pnlFromFillColor.Size = new System.Drawing.Size(38, 23);
+            this.pnlFromFillColor.TabIndex = 8;
+            // 
+            // label14
+            // 
+            this.label14.AutoSize = true;
+            this.label14.Location = new System.Drawing.Point(152, 128);
+            this.label14.Name = "label14";
+            this.label14.Size = new System.Drawing.Size(20, 13);
+            this.label14.TabIndex = 7;
+            this.label14.Text = "To";
+            // 
+            // label15
+            // 
+            this.label15.AutoSize = true;
+            this.label15.Location = new System.Drawing.Point(30, 128);
+            this.label15.Name = "label15";
+            this.label15.Size = new System.Drawing.Size(30, 13);
+            this.label15.TabIndex = 6;
+            this.label15.Text = "From";
+            // 
+            // label13
+            // 
+            this.label13.AutoSize = true;
+            this.label13.Location = new System.Drawing.Point(152, 76);
+            this.label13.Name = "label13";
+            this.label13.Size = new System.Drawing.Size(20, 13);
+            this.label13.TabIndex = 5;
+            this.label13.Text = "To";
+            // 
+            // label12
+            // 
+            this.label12.AutoSize = true;
+            this.label12.Location = new System.Drawing.Point(30, 76);
+            this.label12.Name = "label12";
+            this.label12.Size = new System.Drawing.Size(30, 13);
+            this.label12.TabIndex = 4;
+            this.label12.Text = "From";
+            // 
+            // label11
+            // 
+            this.label11.AutoSize = true;
+            this.label11.Location = new System.Drawing.Point(12, 107);
+            this.label11.Name = "label11";
+            this.label11.Size = new System.Drawing.Size(65, 13);
+            this.label11.TabIndex = 3;
+            this.label11.Text = "Border Color";
+            // 
+            // label10
+            // 
+            this.label10.AutoSize = true;
+            this.label10.Location = new System.Drawing.Point(12, 52);
+            this.label10.Name = "label10";
+            this.label10.Size = new System.Drawing.Size(46, 13);
+            this.label10.TabIndex = 2;
+            this.label10.Text = "Fill Color";
+            // 
+            // numFillTransparency
+            // 
+            this.numFillTransparency.Location = new System.Drawing.Point(123, 25);
+            this.numFillTransparency.Name = "numFillTransparency";
+            this.numFillTransparency.Size = new System.Drawing.Size(65, 20);
+            this.numFillTransparency.TabIndex = 1;
+            // 
+            // label9
+            // 
+            this.label9.AutoSize = true;
+            this.label9.Location = new System.Drawing.Point(12, 27);
+            this.label9.Name = "label9";
+            this.label9.Size = new System.Drawing.Size(104, 13);
+            this.label9.TabIndex = 0;
+            this.label9.Text = "Fill Transparency (%)";
+            // 
+            // btnApply
+            // 
+            this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnApply.Location = new System.Drawing.Point(177, 556);
+            this.btnApply.Name = "btnApply";
+            this.btnApply.Size = new System.Drawing.Size(75, 23);
+            this.btnApply.TabIndex = 3;
+            this.btnApply.Text = "Apply";
+            this.btnApply.UseVisualStyleBackColor = true;
+            this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
+            // 
+            // MgThemeControlImpl
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnApply);
+            this.Controls.Add(this.groupBox3);
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
+            this.Name = "MgThemeControlImpl";
+            this.Size = new System.Drawing.Size(269, 593);
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.groupBox2.ResumeLayout(false);
+            this.groupBox2.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numRules)).EndInit();
+            this.groupBox3.ResumeLayout(false);
+            this.groupBox3.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.numFillTransparency)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.ComboBox cmbLayer;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TextBox txtThemeName;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.ComboBox cmbScaleRange;
+        private System.Windows.Forms.Label label8;
+        private System.Windows.Forms.TextBox txtMax;
+        private System.Windows.Forms.TextBox txtMin;
+        private System.Windows.Forms.ComboBox cmbDistribution;
+        private System.Windows.Forms.ComboBox cmbProperty;
+        private System.Windows.Forms.Label label7;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.GroupBox groupBox3;
+        private System.Windows.Forms.Button btnToBorderColor;
+        private System.Windows.Forms.Panel pnlToBorderColor;
+        private System.Windows.Forms.Button btnFromBorderColor;
+        private System.Windows.Forms.Button btnToFillColor;
+        private System.Windows.Forms.Panel pnlFromBorderColor;
+        private System.Windows.Forms.Button btnFromFillColor;
+        private System.Windows.Forms.Panel pnlToFillColor;
+        private System.Windows.Forms.Panel pnlFromFillColor;
+        private System.Windows.Forms.Label label14;
+        private System.Windows.Forms.Label label15;
+        private System.Windows.Forms.Label label13;
+        private System.Windows.Forms.Label label12;
+        private System.Windows.Forms.Label label11;
+        private System.Windows.Forms.Label label10;
+        private System.Windows.Forms.NumericUpDown numFillTransparency;
+        private System.Windows.Forms.Label label9;
+        private System.Windows.Forms.Button btnApply;
+        private System.Windows.Forms.NumericUpDown numRules;
+        private System.Windows.Forms.ColorDialog colorDialog;
+    }
+}

Copied: trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/MgThemeControlImpl.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,509 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Xml;
+using System.Globalization;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    public partial class MgThemeControlImpl : MgControlImpl
+    {
+        private IMapViewer _viewer;
+        private BindingList<MgDataPropertyDefinition> _properties;
+        private BindingList<MgLayerBase> _layers;
+        private MgResourceService _resSvc;
+        private string _sessionId;
+
+        private Dictionary<string, string> _distros;
+
+        public MgThemeControlImpl(IMapViewer viewer)
+        {
+            InitializeComponent();
+            this.Title = Properties.Resources.TitleTheme;
+            this.Disposed += new EventHandler(OnDisposed);
+            _viewer = viewer;
+            _properties = new BindingList<MgDataPropertyDefinition>();
+            _layers = new BindingList<MgLayerBase>();
+
+            numRules.Minimum = Int32.MinValue;
+            numRules.Maximum = Int32.MaxValue;
+
+            _distros = new Dictionary<string,string>() 
+            {
+                { THEME_INDIVIDUAL, "Individual" },
+                { THEME_EQUAL, "Equal" },
+                { THEME_STDDEV, "Standard Deviation" },
+                { THEME_QUANT, "Quantile" },
+                { THEME_JENK, "Jenks (Natural Breaks)"}
+            };
+
+            cmbLayer.DataSource = _layers;
+            cmbProperty.DataSource = _properties;
+            cmbDistribution.DataSource = GetDistroValues(THEME_INDIVIDUAL, THEME_EQUAL, THEME_STDDEV, THEME_QUANT, THEME_JENK);
+
+            var map = viewer.GetMap();
+            var layers = map.GetLayers();
+            for (var i = 0; i < layers.GetCount(); i++)
+            {
+                _layers.Add(layers.GetItem(i));
+            }
+            cmbLayer.SelectedIndex = 0;
+            cmbLayer_SelectedIndexChanged(this, EventArgs.Empty);
+            cmbDistribution.SelectedIndex = 0;
+            _sessionId = Guid.NewGuid().ToString();
+        }
+
+        private KeyValuePair<string, string>[] GetDistroValues(params string[] distroKeys)
+        {
+            var values = new List<KeyValuePair<string, string>>();
+            foreach (var key in distroKeys)
+            {
+                if (_distros.ContainsKey(key))
+                    values.Add(new KeyValuePair<string, string>(key, _distros[key]));
+            }
+            return values.ToArray();
+        }
+
+        void OnDisposed(object sender, EventArgs e)
+        {
+            _properties.Clear();
+            _layers.Clear();
+            if (_resSvc != null)
+            {
+                _resSvc.Dispose();
+                _resSvc = null;
+            }
+        }
+
+        private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            var layer = cmbLayer.SelectedItem as MgLayerBase;
+            if (layer != null)
+            {
+                var cls = layer.GetClassDefinition();
+                var clsProps = cls.GetProperties();
+                _properties.Clear();
+                for (var i = 0; i < clsProps.GetCount(); i++)
+                {
+                    var prop = clsProps.GetItem(i);
+                    if (prop.GetPropertyType() == MgFeaturePropertyType.DataProperty)
+                    {
+                        _properties.Add((MgDataPropertyDefinition)prop);
+                    }
+                }
+                cmbProperty.SelectedIndex = 0;
+                cmbProperty_SelectedIndexChanged(this, EventArgs.Empty);
+                cmbScaleRange.DataSource = GetScaleRanges(layer);
+            }
+        }
+
+        private string[] GetScaleRanges(MgLayerBase layer)
+        {
+            if (_resSvc == null)
+            {
+                var provider = _viewer.GetProvider();
+                _resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            }
+
+            MgResourceIdentifier layerDefResId = layer.GetLayerDefinition();
+            MgByteReader byteReader = _resSvc.GetResourceContent(layerDefResId);
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml(byteReader.ToString());
+            XmlNodeList nodeList = doc.GetElementsByTagName("VectorScaleRange");
+
+            var scaleRanges = new List<string>();
+            foreach (XmlElement node in nodeList)
+            {
+                String range = null;
+
+                XmlNodeList minNodeList = node.GetElementsByTagName("MinScale");
+                if (minNodeList.Count > 0)
+                {
+                    range = minNodeList.Item(0).FirstChild.Value;
+                }
+                else
+                {
+                    range = "0";
+                }
+
+                XmlNodeList maxNodeList = node.GetElementsByTagName("MaxScale");
+                if (maxNodeList.Count > 0)
+                {
+                    range = range + " - " + maxNodeList.Item(0).FirstChild.Value;
+                }
+                else
+                {
+                    range = range + " - Infinity";
+                }
+
+                scaleRanges.Add(range);
+            }
+            return scaleRanges.ToArray();
+        }
+
+        private int featureCount;
+        private int ruleCount = 8;
+
+        private void cmbDistribution_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            if (cmbDistribution.SelectedIndex == 0)
+            {
+                numRules.Enabled = false;
+                numRules.Value = featureCount;
+            }
+            else
+            {
+                numRules.Enabled = true;
+                numRules.Value = ruleCount;
+            }
+        }
+
+        private void cmbProperty_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            var layer = cmbLayer.SelectedItem as MgLayerBase;
+            var prop = cmbProperty.SelectedItem as MgDataPropertyDefinition;
+            if (layer != null && prop != null)
+            {
+                SetPropertyMinMaxCount(layer, prop);
+                cmbDistribution.DataSource = GetDistributionsForDataType(prop.DataType);
+            }
+        }
+
+        private void btnFromFillColor_Click(object sender, EventArgs e)
+        {
+            if (colorDialog.ShowDialog() == DialogResult.OK)
+            {
+                pnlFromFillColor.BackColor = colorDialog.Color;
+            }
+        }
+
+        private void btnToFillColor_Click(object sender, EventArgs e)
+        {
+            if (colorDialog.ShowDialog() == DialogResult.OK)
+            {
+                pnlToFillColor.BackColor = colorDialog.Color;
+            }
+        }
+
+        private void btnFromBorderColor_Click(object sender, EventArgs e)
+        {
+            if (colorDialog.ShowDialog() == DialogResult.OK)
+            {
+                pnlFromBorderColor.BackColor = colorDialog.Color;
+            }
+        }
+
+        private void btnToBorderColor_Click(object sender, EventArgs e)
+        {
+            if (colorDialog.ShowDialog() == DialogResult.OK)
+            {
+                pnlToBorderColor.BackColor = colorDialog.Color;
+            }
+        }
+
+        private void btnApply_Click(object sender, EventArgs e)
+        {
+            var tp = new ThemeParams() 
+            {
+                borderFrom = Util.ToHtmlColor(pnlFromBorderColor.BackColor),
+                borderTo = Util.ToHtmlColor(pnlToBorderColor.BackColor),
+                distro = cmbDistribution.SelectedValue.ToString(),
+                fillFrom = Util.ToHtmlColor(pnlFromFillColor.BackColor),
+                fillTo = Util.ToHtmlColor(pnlToFillColor.BackColor),
+                fillTrans = Convert.ToInt32(numFillTransparency.Value),
+                layer = (MgLayerBase)cmbLayer.SelectedItem,
+                maxValue = txtMax.Text,
+                minValue = txtMin.Text,
+                numRules = Convert.ToInt32(numRules.Value),
+                property = (MgDataPropertyDefinition)cmbProperty.SelectedItem,
+                scaleRangeIndex = cmbScaleRange.SelectedIndex,
+                themeName = txtThemeName.Text
+            };
+            string name = ApplyTheme(tp);
+            _viewer.RefreshMap();
+            MessageBox.Show("Theme layer (" + name + ") created");
+        }
+
+        private void SetPropertyMinMaxCount(MgLayerBase layer, MgDataPropertyDefinition prop)
+        {
+            var provider = _viewer.GetProvider();
+
+            var featureService = (MgFeatureService)provider.CreateService(MgServiceType.FeatureService);
+            MgResourceIdentifier resId = new MgResourceIdentifier(layer.GetFeatureSourceId());
+
+            String minValue = null;
+            String maxValue = null;
+            int count = 0;
+
+            MgFeatureQueryOptions queryOptions = new MgFeatureQueryOptions();
+            queryOptions.AddFeatureProperty(prop.Name);
+
+            MgFeatureReader featureReader = featureService.SelectFeatures(resId, layer.GetFeatureClassName(), queryOptions);
+            while (featureReader.ReadNext())
+            {
+                String value = Util.GetFeaturePropertyValue(featureReader, prop.Name);
+                int propertyType = featureReader.GetPropertyType(prop.Name);
+                if (count == 0)
+                {
+                    maxValue = value;
+                    minValue = value;
+                }
+                switch (propertyType)
+                {
+                    case MgPropertyType.String:
+                        if (value.Length > 0)
+                        {
+                            if (value.CompareTo(maxValue) > 0)
+                                maxValue = value;
+                            if (value.CompareTo(minValue) < 0)
+                                minValue = value;
+                        }
+                        break;
+                    case MgPropertyType.Byte:
+                    case MgPropertyType.Int16:
+                    case MgPropertyType.Int32:
+                    case MgPropertyType.Int64:
+                        if (value.Length > 0)
+                        {
+                            if (Int64.Parse(value) > Int64.Parse(maxValue))
+                                maxValue = value;
+                            if (Int64.Parse(value) < Int64.Parse(minValue))
+                                minValue = value;
+                        }
+                        break;
+                    case MgPropertyType.Single:
+                    case MgPropertyType.Double:
+                        if (value != null)
+                        {
+                            if (Double.Parse(value) > Double.Parse(maxValue))
+                                maxValue = value;
+                            if (Double.Parse(value) < Double.Parse(minValue))
+                                minValue = value;
+                        }
+                        count++;
+                        break;
+                    case MgPropertyType.Boolean:
+                    case MgPropertyType.DateTime:
+                    case MgPropertyType.Null:
+                    case MgPropertyType.Blob:
+                    case MgPropertyType.Clob:
+                    case MgPropertyType.Feature:
+                    case MgPropertyType.Geometry:
+                        break;
+                }
+                count++;
+            }
+            featureReader.Close();
+
+            txtMin.Text = minValue;
+            txtMax.Text = maxValue;
+            numRules.Value = featureCount = count;
+        }
+
+        const string THEME_INDIVIDUAL = "INDIV_DIST";
+        const string THEME_EQUAL = "EQUAL_DIST";
+        const string THEME_STDDEV = "STDEV_DIST";
+        const string THEME_QUANT = "QUANT_DIST";
+        const string THEME_JENK = "JENK_DIST";
+
+        class ThemeParams
+        {
+            public MgLayerBase layer;
+            public MgDataPropertyDefinition property;
+            public int scaleRangeIndex;
+            public int numRules;
+            public string distro;
+            public string fillFrom;
+            public string fillTo;
+            public string borderFrom;
+            public string borderTo;
+            public int fillTrans;
+            public string minValue;
+            public string maxValue;
+            public string themeName;
+            //public string layerName;
+        }
+
+        private string ApplyTheme(ThemeParams themeParams)
+        {
+            var provider = _viewer.GetProvider();
+            var map = _viewer.GetMap();
+            var layers = map.GetLayers();
+
+            MgResourceService resourceService = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+            MgFeatureService featureService = (MgFeatureService)provider.CreateService(MgServiceType.FeatureService);
+
+            MgResourceIdentifier resId = new MgResourceIdentifier(themeParams.layer.GetFeatureSourceId());
+            MgResourceIdentifier layerDefResId = themeParams.layer.GetLayerDefinition();
+            MgByteReader byteReader = resourceService.GetResourceContent(layerDefResId);
+
+            // Load the Layer Definition and Navigate to the specified <VectorScaleRange>
+
+            XmlDocument doc = new XmlDocument();
+            String xmlLayerDef = byteReader.ToString();
+            doc.LoadXml(xmlLayerDef);
+            XmlNodeList nodeList = doc.GetElementsByTagName("VectorScaleRange");
+
+            XmlElement vectorScaleRangecElement = (XmlElement)nodeList.Item(themeParams.scaleRangeIndex);
+            XmlElement areaTypeStyle = (XmlElement)vectorScaleRangecElement.GetElementsByTagName("AreaTypeStyle").Item(0);
+
+            // Remove any existing <AreaRule> elements.
+
+            XmlNodeList areaRuleList = areaTypeStyle.GetElementsByTagName("AreaRule");
+            int count = areaRuleList.Count;
+            for (int i = 0; i < count; i++)
+            {
+                //The areaRuleList shrinks as we remove items, so always
+                //remove the first item (don't use the index i)
+                areaTypeStyle.RemoveChild(areaRuleList.Item(0));
+            }
+
+            // Now create the new <AreaRule> elements.
+
+            String areaRuleTemplate = Properties.Resources.AreaRuleTemplate;
+            MgFeatureAggregateOptions aggregateOptions = new MgFeatureAggregateOptions();
+
+            String value = null;
+            String filterText = null;
+            String areaRuleXML = null;
+            XmlDocument areaDoc = null;
+            XmlNode areaNode = null;
+            double portion = 0.0;
+            double increment = (themeParams.numRules > 1) ? 1.0 / (themeParams.numRules - 1) : 1.0;
+
+            if (THEME_INDIVIDUAL == themeParams.distro)
+            {
+                aggregateOptions.AddFeatureProperty(themeParams.property.Name);
+                aggregateOptions.SelectDistinct(true);
+
+                MgDataReader dataReader = featureService.SelectAggregate(resId, themeParams.layer.GetFeatureClassName(), aggregateOptions);
+                while (dataReader.ReadNext())
+                {
+                    value = Util.GetFeaturePropertyValue(dataReader, themeParams.property.Name);
+
+                    filterText = "&quot;" + themeParams.property.Name + "&quot; = ";
+                    if (themeParams.property.DataType == MgPropertyType.String)
+                        filterText = filterText + "'" + value + "'";
+                    else
+                        filterText = filterText + value;
+
+                    areaRuleXML = String.Format(areaRuleTemplate,
+                                                themeParams.property.Name + ":" + value,
+                                                filterText,
+                                                Util.InterpolateColor(portion, themeParams.fillFrom, themeParams.fillTo, themeParams.fillTrans),
+                                                Util.InterpolateColor(portion, themeParams.borderFrom, themeParams.borderTo, 0));
+                    areaDoc = new XmlDocument();
+                    areaDoc.LoadXml(areaRuleXML);
+                    areaNode = doc.ImportNode(areaDoc.DocumentElement, true);
+                    areaTypeStyle.AppendChild(areaNode);
+
+                    portion = portion + increment;
+                }
+                dataReader.Close();
+            }
+            else
+            {
+                var values = new List<string>();
+
+                var expr = themeParams.distro + "(\"" + themeParams.property.Name + "\"," + themeParams.numRules + "," + themeParams.minValue + "," + themeParams.maxValue + ")";
+                aggregateOptions.AddComputedProperty("THEME_VALUE", expr);
+                MgDataReader dataReader = featureService.SelectAggregate(resId, themeParams.layer.GetFeatureClassName(), aggregateOptions);
+                while (dataReader.ReadNext())
+                {
+                    value = Util.GetFeaturePropertyValue(dataReader, "THEME_VALUE");
+                    values.Add(value);
+                }
+                dataReader.Close();
+
+                for (int i = 0; i < values.Count - 1; i++)
+                {
+                    filterText = "&quot;" + themeParams.property.Name + "&quot; &gt;= " + values[i] + " AND &quot;" + themeParams.property.Name;
+                    if (i == values.Count - 1)
+                        filterText = filterText + "&quot; &lt;= " + values[i + 1];
+                    else
+                        filterText = filterText + "&quot; &lt; " + values[i + 1];
+
+                    areaRuleXML = String.Format(areaRuleTemplate,
+                                                themeParams.property.Name + ":" + values[i] + " - " + values[i + 1],
+                                                filterText,
+                                                Util.InterpolateColor(portion, themeParams.fillFrom, themeParams.fillTo, themeParams.fillTrans),
+                                                Util.InterpolateColor(portion, themeParams.borderFrom, themeParams.borderTo, 0));
+
+                    areaDoc = new XmlDocument();
+                    areaDoc.LoadXml(areaRuleXML);
+                    areaNode = doc.ImportNode(areaDoc.DocumentElement, true);
+                    areaTypeStyle.AppendChild(areaNode);
+
+                    portion = portion + increment;
+                }
+            }
+
+            // Now save our new layer definition to the session and add it to the map.
+
+            String xmlString = doc.DocumentElement.OuterXml;
+            String uniqueName = Util.MakeUniqueLayerName(map, themeParams.layer.Name, themeParams.themeName);
+            String legendLabel = themeParams.layer.GetLegendLabel();
+            if (!string.IsNullOrEmpty(themeParams.themeName))
+                legendLabel = legendLabel + " (" + themeParams.themeName + ")";
+
+            MgResourceIdentifier layerResId = new MgResourceIdentifier("Session:" + _sessionId + "//" + uniqueName + ".LayerDefinition");
+            resourceService.SetResource(layerResId, new MgByteReader(xmlString, "text/xml"), null);
+
+            var newLayer = provider.CreateLayer(layerResId);
+            newLayer.SetName(uniqueName);
+            newLayer.SetLegendLabel(legendLabel);
+            newLayer.SetDisplayInLegend(themeParams.layer.GetDisplayInLegend());
+            newLayer.SetVisible(true);
+            newLayer.SetSelectable(themeParams.layer.GetSelectable());
+
+            layers.Insert(layers.IndexOf(themeParams.layer), newLayer);
+
+            //map.Save(resourceService);
+
+            return uniqueName;
+        }
+
+        private KeyValuePair<string, string>[] GetDistributionsForDataType(int type)
+        {
+            var distroTypes = new List<string>();
+
+            switch (type)
+            {
+                case MgPropertyType.String:
+                    distroTypes.Add(THEME_INDIVIDUAL);
+                    break;
+                case MgPropertyType.Byte:
+                case MgPropertyType.Int16:
+                case MgPropertyType.Int32:
+                case MgPropertyType.Int64:
+                    distroTypes.Add(THEME_INDIVIDUAL);
+                    distroTypes.Add(THEME_EQUAL);
+                    distroTypes.Add(THEME_STDDEV);
+                    distroTypes.Add(THEME_QUANT);
+                    distroTypes.Add(THEME_JENK);
+                    break;
+                case MgPropertyType.Single:
+                case MgPropertyType.Double:
+                    distroTypes.Add(THEME_EQUAL);
+                    distroTypes.Add(THEME_STDDEV);
+                    distroTypes.Add(THEME_QUANT);
+                    distroTypes.Add(THEME_JENK);
+                    break;
+                case MgPropertyType.Boolean:
+                case MgPropertyType.DateTime:
+                case MgPropertyType.Blob:
+                case MgPropertyType.Clob:
+                case MgPropertyType.Feature:
+                case MgPropertyType.Geometry:
+                case MgPropertyType.Null:
+                    break;
+            }
+            return GetDistroValues(distroTypes.ToArray());
+        }
+    }
+}

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

Modified: trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/Properties/Resources.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -89,6 +89,32 @@
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to &lt;AreaRule&gt;
+        /// &lt;LegendLabel&gt;{0}&lt;/LegendLabel&gt;
+        /// &lt;Filter&gt;{1}&lt;/Filter&gt;
+        /// &lt;AreaSymbolization2D&gt;
+        ///  &lt;Fill&gt;
+        ///   &lt;FillPattern&gt;Solid&lt;/FillPattern&gt;
+        ///   &lt;ForegroundColor&gt;{2}&lt;/ForegroundColor&gt;
+        ///   &lt;BackgroundColor&gt;FF000000&lt;/BackgroundColor&gt;
+        ///  &lt;/Fill&gt;
+        ///  &lt;Stroke&gt;
+        ///   &lt;LineStyle&gt;Solid&lt;/LineStyle&gt;
+        ///   &lt;Thickness&gt;0&lt;/Thickness&gt;
+        ///   &lt;Color&gt;{3}&lt;/Color&gt;
+        ///   &lt;Unit&gt;Inches&lt;/Unit&gt;
+        ///  &lt;/Stroke&gt;
+        /// &lt;/AreaSymbolization2D&gt;
+        ///&lt;/AreaRule&gt;
+        ///.
+        /// </summary>
+        internal static string AreaRuleTemplate {
+            get {
+                return ResourceManager.GetString("AreaRuleTemplate", resourceCulture);
+            }
+        }
+        
         internal static System.Drawing.Bitmap buffer {
             get {
                 object obj = ResourceManager.GetObject("buffer", resourceCulture);
@@ -758,6 +784,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Theme.
+        /// </summary>
+        internal static string TitleTheme {
+            get {
+                return ResourceManager.GetString("TitleTheme", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Viewer Options.
         /// </summary>
         internal static string TitleViewerOptions {

Modified: trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer/Properties/Resources.resx	2012-05-13 04:07:19 UTC (rev 6646)
@@ -427,4 +427,10 @@
   <data name="TextScale" xml:space="preserve">
     <value>Scale</value>
   </data>
+  <data name="TitleTheme" xml:space="preserve">
+    <value>Theme</value>
+  </data>
+  <data name="AreaRuleTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\AreaRuleTemplate.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
 </root>
\ No newline at end of file

Copied: trunk/MgDev/Desktop/MapViewer/Resources/AreaRuleTemplate.txt (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/Resources/AreaRuleTemplate.txt)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Resources/AreaRuleTemplate.txt	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/Resources/AreaRuleTemplate.txt	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,17 @@
+<AreaRule>
+ <LegendLabel>{0}</LegendLabel>
+ <Filter>{1}</Filter>
+ <AreaSymbolization2D>
+  <Fill>
+   <FillPattern>Solid</FillPattern>
+   <ForegroundColor>{2}</ForegroundColor>
+   <BackgroundColor>FF000000</BackgroundColor>
+  </Fill>
+  <Stroke>
+   <LineStyle>Solid</LineStyle>
+   <Thickness>0</Thickness>
+   <Color>{3}</Color>
+   <Unit>Inches</Unit>
+  </Stroke>
+ </AreaSymbolization2D>
+</AreaRule>

Copied: trunk/MgDev/Desktop/MapViewer/Util.cs (from rev 6645, branches/2.4/MgDev/Desktop/MapViewer/Util.cs)
===================================================================
--- trunk/MgDev/Desktop/MapViewer/Util.cs	                        (rev 0)
+++ trunk/MgDev/Desktop/MapViewer/Util.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+using System.Drawing;
+
+namespace OSGeo.MapGuide.Viewer
+{
+    internal static class Util
+    {
+        public static string ToHtmlColor(Color color)
+        {
+            return String.Format("{0:X2}{1:X2}{2:X2}", color.R, color.G, color.B);
+        }
+
+        public static MgLayerBase FindLayer(MgLayerCollection layers, String layerName)
+        {
+            MgLayerBase layer = null;
+            int i = 0;
+            for (i = 0; i < layers.GetCount(); i++)
+            {
+                MgLayerBase layer1 = layers.GetItem(i);
+
+                if (layer1.GetName() == layerName)
+                {
+                    layer = layer1;
+                    break;
+                }
+            }
+            return layer;
+        }
+
+        public static string GetMapSrs(MgMapBase map)
+        {
+            try
+            {
+                String srs = map.GetMapSRS();
+                if (srs != "")
+                    return srs;
+            }
+            catch (MgException e)
+            {
+            }
+
+            //No SRS, set to ArbitrayXY meters
+            //
+            return "LOCALCS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
+        }
+
+        public static void ClearDataSource(MgFeatureService featSvc, MgResourceIdentifier fsId, String featureName)
+        {
+            MgDeleteFeatures deleteCmd = new MgDeleteFeatures(featureName, "ID >= 0");
+            MgFeatureCommandCollection commands = new MgFeatureCommandCollection();
+            commands.Add(deleteCmd);
+            featSvc.UpdateFeatures(fsId, commands, false);
+        }
+
+        public static void ReleaseReader(MgPropertyCollection res, MgFeatureCommandCollection commands)
+        {
+            if (res == null)
+                return;
+
+            for (int i = 0; i < res.GetCount(); i++)
+            {
+                MgFeatureCommand cmd = commands.GetItem(i);
+                if (cmd is MgInsertFeatures)
+                {
+                    MgFeatureProperty resProp = res.GetItem(i) as MgFeatureProperty;
+                    if (resProp != null)
+                    {
+                        MgFeatureReader reader = resProp.GetValue() as MgFeatureReader;
+                        if (reader == null)
+                            return;
+                        reader.Close();
+                    }
+                }
+            }
+        }
+
+        public static void AddFeatureToCollection(MgBatchPropertyCollection propCollection, MgAgfReaderWriter agfRW, int featureId, MgGeometry featureGeom)
+        {
+            MgPropertyCollection bufferProps = new MgPropertyCollection();
+            MgInt32Property idProp = new MgInt32Property("ID", featureId);
+            bufferProps.Add(idProp);
+            MgByteReader geomReader = agfRW.Write(featureGeom);
+            MgGeometryProperty geomProp = new MgGeometryProperty("GEOM", geomReader);
+            bufferProps.Add(geomProp);
+            propCollection.Add(bufferProps);
+        }
+
+        public static String GetFeaturePropertyValue(MgReader featureReader, String propName)
+        {
+            String value = "";
+            int propertyType = featureReader.GetPropertyType(propName);
+            switch (propertyType)
+            {
+                case MgPropertyType.Boolean:
+                    value = featureReader.GetBoolean(propName).ToString();
+                    break;
+                case MgPropertyType.Byte:
+                    value = featureReader.GetByte(propName).ToString();
+                    break;
+                case MgPropertyType.Single:
+                    value = featureReader.GetSingle(propName).ToString();
+                    break;
+                case MgPropertyType.Double:
+                    value = featureReader.GetDouble(propName).ToString();
+                    break;
+                case MgPropertyType.Int16:
+                    value = featureReader.GetInt16(propName).ToString();
+                    break;
+                case MgPropertyType.Int32:
+                    value = featureReader.GetInt32(propName).ToString();
+                    break;
+                case MgPropertyType.Int64:
+                    value = featureReader.GetInt64(propName).ToString();
+                    break;
+                case MgPropertyType.String:
+                    value = featureReader.GetString(propName);
+                    break;
+                case MgPropertyType.DateTime:
+                case MgPropertyType.Null:
+                case MgPropertyType.Blob:
+                case MgPropertyType.Clob:
+                case MgPropertyType.Feature:
+                case MgPropertyType.Geometry:
+                case MgPropertyType.Raster:
+                    value = "[unsupported data type]";
+                    break;
+            }
+            return value;
+        }
+
+        public static String MakeUniqueLayerName(MgMapBase map, String layerName, String themeName)
+        {
+            String desiredName = "_" + layerName + themeName;
+            String uniqueName = desiredName;
+            int index = 1;
+
+            var layers = map.GetLayers();
+            while (layers.Contains(uniqueName))
+            {
+                uniqueName = desiredName + index.ToString();
+                index++;
+            }
+            return uniqueName;
+        }
+
+        public static String InterpolateColor(double portion, String startColor, String endColor, int percentTransparent)
+        {
+            int alpha = (int)(255 * (100.0 - percentTransparent) / 100.0);
+            String result = "";
+            if (startColor.Equals(endColor))
+            {
+                result = String.Format("{0:X2}{1}", alpha, startColor);
+            }
+            else
+            {
+                int red = CalculateRGB(portion, startColor.Substring(0, 2), endColor.Substring(0, 2));
+                int green = CalculateRGB(portion, startColor.Substring(2, 2), endColor.Substring(2, 2));
+                int blue = CalculateRGB(portion, startColor.Substring(4, 2), endColor.Substring(4, 2));
+                result = String.Format("{0:X2}{1:X2}{2:X2}{3:X2}", alpha, red, green, blue);
+            }
+            return result;
+        }
+
+        public static int CalculateRGB(double portion, String startRGB, String endRGB)
+        {
+            double result = Int32.Parse(startRGB, NumberStyles.HexNumber) + portion * (Int32.Parse(endRGB, NumberStyles.HexNumber) - Int32.Parse(startRGB, NumberStyles.HexNumber));
+            return (int)result;
+        }
+    }
+}

Modified: trunk/MgDev/Desktop/MapViewer.Desktop/MgDesktopMapViewerProvider.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer.Desktop/MgDesktopMapViewerProvider.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewer.Desktop/MgDesktopMapViewerProvider.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -11,16 +11,17 @@
         private MgdMap _implMap;
         private MgRenderingService _renderSvc;
         private MgServiceFactory _fact;
-        private MgResourceService _resSvc;
 
-        public MgDesktopMapViewerProvider(MgdMap map, MgdResourceService resSvc, MgRenderingService renderingService) : base(map, resSvc) 
+        public MgDesktopMapViewerProvider(MgdMap map) : base(map) 
         {
             _implMap = map;
+        }
+
+        protected override void SubInit()
+        {
             _fact = new MgServiceFactory();
-            _renderSvc = renderingService;
-            _resSvc = (MgResourceService)_fact.CreateService(MgServiceType.ResourceService);
+            _renderSvc = (MgRenderingService)_fact.CreateService(MgServiceType.RenderingService);
         }
-
         
         private MgRenderingOptions _lastRenderOpts;
 

Modified: trunk/MgDev/Desktop/MapViewerTest/CompactViewer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/CompactViewer.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewerTest/CompactViewer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -22,12 +22,7 @@
         public void LoadMap(MgResourceIdentifier resId)
         {
             var map = new MgdMap(resId);
-            var fact = new MgServiceFactory();
-            viewer.Init(
-                new MgDesktopMapViewerProvider(
-                    map,
-                    (MgdResourceService)fact.CreateService(MgServiceType.ResourceService),
-                    (MgRenderingService)fact.CreateService(MgServiceType.RenderingService)));
+            viewer.Init(new MgDesktopMapViewerProvider(map));
             //viewer.RefreshMap();
         }
     }

Modified: trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.Designer.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.Designer.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.Designer.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -32,15 +32,13 @@
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MgAppWindow));
             this.appMenu = new System.Windows.Forms.MenuStrip();
             this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
-            this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
             this.appContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
-            this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
             this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
             this.appContainer = new System.Windows.Forms.SplitContainer();
             this.toolStripContainer = new System.Windows.Forms.ToolStripContainer();
             this.infoPaneViewerContainer = new System.Windows.Forms.SplitContainer();
@@ -55,10 +53,12 @@
             this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
             this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
             this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripSplitButton1 = new System.Windows.Forms.ToolStripSplitButton();
+            this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripDropDownButton1 = new System.Windows.Forms.ToolStripDropDownButton();
+            this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
+            this.toolStripDropDownButton2 = new System.Windows.Forms.ToolStripDropDownButton();
             this.lblLoading = new System.Windows.Forms.ToolStripLabel();
-            this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
-            this.toolStripSplitButton2 = new System.Windows.Forms.ToolStripSplitButton();
             this.toolStrip1 = new System.Windows.Forms.ToolStrip();
             this.btnInitialTask = new System.Windows.Forms.ToolStripButton();
             this.taskMenu = new System.Windows.Forms.ToolStripSplitButton();
@@ -71,64 +71,74 @@
             this.legendCtrl = new OSGeo.MapGuide.Viewer.MgLegend();
             this.propertiesCtrl = new OSGeo.MapGuide.Viewer.MgPropertyPane();
             this.mapViewer = new OSGeo.MapGuide.Viewer.MgMapViewer();
-            this.mgInvokeComponentButton1 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
+            this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton5 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton6 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton7 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton8 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton9 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton10 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton11 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton12 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripButton13 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem25 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem26 = new System.Windows.Forms.ToolStripMenuItem();
+            this.taskPane = new OSGeo.MapGuide.Viewer.MgTaskPane();
+            this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem16 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem17 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem18 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem19 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem20 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem21 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem22 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem23 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem24 = new System.Windows.Forms.ToolStripMenuItem();
+            this.mgPrintComponent1 = new OSGeo.MapGuide.Viewer.MgPrintComponent();
             this.mgCopyMapComponent1 = new OSGeo.MapGuide.Viewer.MgCopyMapComponent();
-            this.mgInvokeComponentButton2 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgZoomInComponent1 = new OSGeo.MapGuide.Viewer.MgZoomInComponent();
-            this.mgInvokeComponentButton3 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgZoomOutComponent1 = new OSGeo.MapGuide.Viewer.MgZoomOutComponent();
-            this.mgInvokeComponentButton4 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgInitialViewComponent1 = new OSGeo.MapGuide.Viewer.MgInitialViewComponent();
-            this.mgInvokeComponentButton5 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgSelectComponent1 = new OSGeo.MapGuide.Viewer.MgSelectComponent();
-            this.mgInvokeComponentButton6 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgCircleSelectComponent1 = new OSGeo.MapGuide.Viewer.MgCircleSelectComponent();
-            this.mgInvokeComponentButton7 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgPolygonSelectComponent1 = new OSGeo.MapGuide.Viewer.MgPolygonSelectComponent();
-            this.mgInvokeComponentButton8 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgPanComponent1 = new OSGeo.MapGuide.Viewer.MgPanComponent();
-            this.mgInvokeComponentButton9 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgClearSelectionComponent1 = new OSGeo.MapGuide.Viewer.MgClearSelectionComponent();
-            this.mgInvokeComponentButton10 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgRefreshMapComponent1 = new OSGeo.MapGuide.Viewer.MgRefreshMapComponent();
-            this.mgInvokeComponentButton11 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgTooltipToggleComponent1 = new OSGeo.MapGuide.Viewer.MgTooltipToggleComponent();
-            this.mgInvokeComponentMenuItem20 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.mgBufferComponent1 = new OSGeo.MapGuide.Viewer.MgBufferComponent();
-            this.taskPane = new OSGeo.MapGuide.Viewer.MgTaskPane();
-            this.mgInvokeComponentMenuItem21 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.mgMeasureComponent1 = new OSGeo.MapGuide.Viewer.MgMeasureComponent();
-            this.mgInvokeComponentMenuItem22 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.mgQueryComponent1 = new OSGeo.MapGuide.Viewer.MgQueryComponent();
-            this.mgInvokeComponentButton15 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
             this.mgViewerOptionsComponent1 = new OSGeo.MapGuide.Viewer.MgViewerOptionsComponent();
-            this.mgInvokeComponentMenuItem23 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.plotToDwfComponent = new OSGeo.MapGuide.Viewer.MgGenericInvokeComponent();
-            this.mgInvokeComponentMenuItem1 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem2 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem3 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem14 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.mgLoadPackageComponent1 = new OSGeo.MapGuide.Viewer.MgLoadPackageComponent();
-            this.mgInvokeComponentMenuItem15 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem16 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem17 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem18 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem4 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem6 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem7 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem24 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
             this.mgZoomToSelectionComponent1 = new OSGeo.MapGuide.Viewer.MgZoomToSelectionComponent();
-            this.mgInvokeComponentMenuItem8 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem5 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem9 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem10 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem11 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem12 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem13 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgInvokeComponentMenuItem19 = new OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem();
-            this.mgPrintComponent1 = new OSGeo.MapGuide.Viewer.MgPrintComponent();
-            this.mgInvokeComponentButton12 = new OSGeo.MapGuide.Viewer.MgInvokeComponentButton();
-            this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
+            this.mgMenuItemComponentInvoker1 = new OSGeo.MapGuide.Viewer.MgMenuItemComponentInvoker();
+            this.loadCompactViewerComponent = new OSGeo.MapGuide.Viewer.MgGenericInvokeComponent();
+            this.profileComponent = new OSGeo.MapGuide.Viewer.MgGenericInvokeComponent();
+            this.mgToolButtonComponentInvoker1 = new OSGeo.MapGuide.Viewer.MgToolButtonComponentInvoker();
+            this.mgLayerSelectionHandler1 = new OSGeo.MapGuide.Viewer.MgLayerSelectionHandler();
+            this.mgThemeComponent1 = new OSGeo.MapGuide.Viewer.MgThemeComponent();
+            this.toolStripMenuItem27 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem28 = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem29 = new System.Windows.Forms.ToolStripMenuItem();
             this.appMenu.SuspendLayout();
             this.appContextMenu.SuspendLayout();
             this.appContainer.Panel1.SuspendLayout();
@@ -150,11 +160,12 @@
             this.appToolbar.SuspendLayout();
             this.toolStrip1.SuspendLayout();
             this.statusBar.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.mgPrintComponent1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgBufferComponent1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgMeasureComponent1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgQueryComponent1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgViewerOptionsComponent1)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.mgPrintComponent1)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.mgThemeComponent1)).BeginInit();
             this.SuspendLayout();
             // 
             // appMenu
@@ -171,83 +182,70 @@
             // fileToolStripMenuItem
             // 
             this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem14,
-            this.toolStripSeparator10,
-            this.quitToolStripMenuItem});
+            this.toolStripMenuItem1});
             this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
             this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
             this.fileToolStripMenuItem.Text = "File";
             // 
-            // toolStripSeparator10
-            // 
-            this.toolStripSeparator10.Name = "toolStripSeparator10";
-            this.toolStripSeparator10.Size = new System.Drawing.Size(144, 6);
-            // 
-            // quitToolStripMenuItem
-            // 
-            this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
-            this.quitToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
-            this.quitToolStripMenuItem.Text = "Quit";
-            this.quitToolStripMenuItem.Click += new System.EventHandler(this.quitToolStripMenuItem_Click);
-            // 
             // toolsToolStripMenuItem
             // 
             this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem15,
-            this.mgInvokeComponentMenuItem16,
-            this.mgInvokeComponentMenuItem17,
-            this.toolStripSeparator11,
-            this.mgInvokeComponentMenuItem18});
+            this.toolStripMenuItem2,
+            this.toolStripMenuItem3,
+            this.toolStripMenuItem4,
+            this.toolStripMenuItem28,
+            this.toolStripSeparator9,
+            this.toolStripMenuItem12});
             this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
             this.toolsToolStripMenuItem.Size = new System.Drawing.Size(48, 20);
             this.toolsToolStripMenuItem.Text = "Tools";
             // 
+            // toolStripSeparator9
+            // 
+            this.toolStripSeparator9.Name = "toolStripSeparator9";
+            this.toolStripSeparator9.Size = new System.Drawing.Size(151, 6);
+            // 
             // appContextMenu
             // 
             this.appContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem4,
-            this.toolStripSeparator6,
-            this.mgInvokeComponentMenuItem6,
-            this.mgInvokeComponentMenuItem7,
-            this.mgInvokeComponentMenuItem24,
-            this.mgInvokeComponentMenuItem8,
-            this.toolStripSeparator8,
-            this.mgInvokeComponentMenuItem5,
-            this.mgInvokeComponentMenuItem9,
-            this.mgInvokeComponentMenuItem10,
-            this.toolStripSeparator7,
-            this.mgInvokeComponentMenuItem11,
-            this.mgInvokeComponentMenuItem12,
-            this.mgInvokeComponentMenuItem13,
+            this.toolStripMenuItem13,
+            this.toolStripSeparator10,
+            this.toolStripMenuItem14,
+            this.toolStripMenuItem15,
+            this.toolStripMenuItem16,
+            this.toolStripMenuItem17,
+            this.toolStripSeparator11,
+            this.toolStripMenuItem18,
+            this.toolStripMenuItem19,
+            this.toolStripMenuItem20,
             this.toolStripSeparator12,
-            this.mgInvokeComponentMenuItem19});
+            this.toolStripMenuItem21,
+            this.toolStripMenuItem22,
+            this.toolStripMenuItem23,
+            this.toolStripSeparator13,
+            this.toolStripMenuItem24});
             this.appContextMenu.Name = "appContextMenu";
             this.appContextMenu.Size = new System.Drawing.Size(172, 292);
             // 
-            // toolStripSeparator6
+            // toolStripSeparator10
             // 
-            this.toolStripSeparator6.Name = "toolStripSeparator6";
-            this.toolStripSeparator6.Size = new System.Drawing.Size(168, 6);
+            this.toolStripSeparator10.Name = "toolStripSeparator10";
+            this.toolStripSeparator10.Size = new System.Drawing.Size(168, 6);
             // 
-            // toolStripSeparator8
+            // toolStripSeparator11
             // 
-            this.toolStripSeparator8.Name = "toolStripSeparator8";
-            this.toolStripSeparator8.Size = new System.Drawing.Size(168, 6);
+            this.toolStripSeparator11.Name = "toolStripSeparator11";
+            this.toolStripSeparator11.Size = new System.Drawing.Size(168, 6);
             // 
-            // toolStripSeparator7
-            // 
-            this.toolStripSeparator7.Name = "toolStripSeparator7";
-            this.toolStripSeparator7.Size = new System.Drawing.Size(168, 6);
-            // 
             // toolStripSeparator12
             // 
             this.toolStripSeparator12.Name = "toolStripSeparator12";
             this.toolStripSeparator12.Size = new System.Drawing.Size(168, 6);
             // 
-            // toolStripSeparator11
+            // toolStripSeparator13
             // 
-            this.toolStripSeparator11.Name = "toolStripSeparator11";
-            this.toolStripSeparator11.Size = new System.Drawing.Size(151, 6);
+            this.toolStripSeparator13.Name = "toolStripSeparator13";
+            this.toolStripSeparator13.Size = new System.Drawing.Size(168, 6);
             // 
             // appContainer
             // 
@@ -368,29 +366,30 @@
             // 
             this.appToolbar.Dock = System.Windows.Forms.DockStyle.None;
             this.appToolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentButton12,
-            this.toolStripSeparator13,
-            this.mgInvokeComponentButton1,
+            this.toolStripButton1,
             this.toolStripSeparator1,
-            this.mgInvokeComponentButton2,
-            this.mgInvokeComponentButton3,
-            this.mgInvokeComponentButton4,
+            this.toolStripButton2,
             this.toolStripSeparator2,
-            this.mgInvokeComponentButton5,
-            this.mgInvokeComponentButton6,
-            this.mgInvokeComponentButton7,
-            this.mgInvokeComponentButton8,
+            this.toolStripButton3,
+            this.toolStripButton4,
+            this.toolStripButton5,
             this.toolStripSeparator3,
-            this.mgInvokeComponentButton9,
-            this.mgInvokeComponentButton10,
+            this.toolStripButton6,
+            this.toolStripButton7,
+            this.toolStripButton8,
+            this.toolStripButton9,
             this.toolStripSeparator4,
-            this.mgInvokeComponentButton11,
+            this.toolStripButton10,
+            this.toolStripButton11,
             this.toolStripSeparator5,
-            this.toolStripSplitButton1,
-            this.lblLoading,
-            this.toolStripSeparator9,
-            this.mgInvokeComponentButton15,
-            this.toolStripSplitButton2});
+            this.toolStripButton12,
+            this.toolStripSeparator6,
+            this.toolStripDropDownButton1,
+            this.toolStripSeparator7,
+            this.toolStripButton13,
+            this.toolStripSeparator8,
+            this.toolStripDropDownButton2,
+            this.lblLoading});
             this.appToolbar.Location = new System.Drawing.Point(0, 0);
             this.appToolbar.Name = "appToolbar";
             this.appToolbar.Size = new System.Drawing.Size(748, 25);
@@ -422,18 +421,46 @@
             this.toolStripSeparator5.Name = "toolStripSeparator5";
             this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25);
             // 
-            // toolStripSplitButton1
+            // toolStripSeparator6
             // 
-            this.toolStripSplitButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem20,
-            this.mgInvokeComponentMenuItem21,
-            this.mgInvokeComponentMenuItem22});
-            this.toolStripSplitButton1.Image = global::MapViewerTest.Properties.Resources.icon_tasks;
-            this.toolStripSplitButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.toolStripSplitButton1.Name = "toolStripSplitButton1";
-            this.toolStripSplitButton1.Size = new System.Drawing.Size(68, 22);
-            this.toolStripSplitButton1.Text = "Tools";
+            this.toolStripSeparator6.Name = "toolStripSeparator6";
+            this.toolStripSeparator6.Size = new System.Drawing.Size(6, 25);
             // 
+            // toolStripDropDownButton1
+            // 
+            this.toolStripDropDownButton1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripMenuItem9,
+            this.toolStripMenuItem10,
+            this.toolStripMenuItem11,
+            this.toolStripMenuItem27});
+            this.toolStripDropDownButton1.Image = global::MapViewerTest.Properties.Resources.icon_tasks;
+            this.toolStripDropDownButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripDropDownButton1.Name = "toolStripDropDownButton1";
+            this.toolStripDropDownButton1.Size = new System.Drawing.Size(65, 22);
+            this.toolStripDropDownButton1.Text = "Tools";
+            // 
+            // toolStripSeparator7
+            // 
+            this.toolStripSeparator7.Name = "toolStripSeparator7";
+            this.toolStripSeparator7.Size = new System.Drawing.Size(6, 25);
+            // 
+            // toolStripSeparator8
+            // 
+            this.toolStripSeparator8.Name = "toolStripSeparator8";
+            this.toolStripSeparator8.Size = new System.Drawing.Size(6, 25);
+            // 
+            // toolStripDropDownButton2
+            // 
+            this.toolStripDropDownButton2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripMenuItem8,
+            this.toolStripMenuItem25,
+            this.toolStripMenuItem26});
+            this.toolStripDropDownButton2.Image = global::MapViewerTest.Properties.Resources.icon_tasks;
+            this.toolStripDropDownButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripDropDownButton2.Name = "toolStripDropDownButton2";
+            this.toolStripDropDownButton2.Size = new System.Drawing.Size(78, 22);
+            this.toolStripDropDownButton2.Text = "Custom";
+            // 
             // lblLoading
             // 
             this.lblLoading.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
@@ -443,21 +470,6 @@
             this.lblLoading.Size = new System.Drawing.Size(30, 22);
             this.lblLoading.Visible = false;
             // 
-            // toolStripSeparator9
-            // 
-            this.toolStripSeparator9.Name = "toolStripSeparator9";
-            this.toolStripSeparator9.Size = new System.Drawing.Size(6, 25);
-            // 
-            // toolStripSplitButton2
-            // 
-            this.toolStripSplitButton2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem23});
-            this.toolStripSplitButton2.Image = global::MapViewerTest.Properties.Resources.icon_tasks;
-            this.toolStripSplitButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.toolStripSplitButton2.Name = "toolStripSplitButton2";
-            this.toolStripSplitButton2.Size = new System.Drawing.Size(81, 22);
-            this.toolStripSplitButton2.Text = "Custom";
-            // 
             // toolStrip1
             // 
             this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -482,9 +494,10 @@
             // 
             this.taskMenu.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
             this.taskMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.mgInvokeComponentMenuItem1,
-            this.mgInvokeComponentMenuItem2,
-            this.mgInvokeComponentMenuItem3});
+            this.toolStripMenuItem5,
+            this.toolStripMenuItem6,
+            this.toolStripMenuItem7,
+            this.toolStripMenuItem29});
             this.taskMenu.Image = global::MapViewerTest.Properties.Resources.icon_tasks;
             this.taskMenu.ImageTransparentColor = System.Drawing.Color.Magenta;
             this.taskMenu.Name = "taskMenu";
@@ -569,17 +582,424 @@
             this.mapViewer.ZoomOutFactor = 2;
             this.mapViewer.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(this.OnViewerPropertyChanged);
             // 
-            // mgInvokeComponentButton1
+            // toolStripButton1
             // 
-            this.mgInvokeComponentButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton1.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton1.Image")));
-            this.mgInvokeComponentButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton1.Name = "mgInvokeComponentButton1";
-            this.mgInvokeComponentButton1.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton1.TargetComponent = this.mgCopyMapComponent1;
-            this.mgInvokeComponentButton1.Text = "Copy map to clipboard";
-            this.mgInvokeComponentButton1.ToolTipText = "Copy map to clipboard";
+            this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton1.Enabled = false;
+            this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
+            this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton1.Name = "toolStripButton1";
+            this.toolStripButton1.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton1, this.mgPrintComponent1);
+            this.toolStripButton1.Text = "Print";
+            this.toolStripButton1.ToolTipText = "Print";
             // 
+            // toolStripButton2
+            // 
+            this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton2.Enabled = false;
+            this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
+            this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton2.Name = "toolStripButton2";
+            this.toolStripButton2.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton2, this.mgCopyMapComponent1);
+            this.toolStripButton2.Text = "Copy map to clipboard";
+            this.toolStripButton2.ToolTipText = "Copy map to clipboard";
+            // 
+            // toolStripButton3
+            // 
+            this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton3.Enabled = false;
+            this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image")));
+            this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton3.Name = "toolStripButton3";
+            this.toolStripButton3.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton3, this.mgZoomInComponent1);
+            this.toolStripButton3.Text = "Zoom In";
+            this.toolStripButton3.ToolTipText = "Zoom In";
+            // 
+            // toolStripButton4
+            // 
+            this.toolStripButton4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton4.Enabled = false;
+            this.toolStripButton4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton4.Image")));
+            this.toolStripButton4.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton4.Name = "toolStripButton4";
+            this.toolStripButton4.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton4, this.mgZoomOutComponent1);
+            this.toolStripButton4.Text = "Zoom Out";
+            this.toolStripButton4.ToolTipText = "Zoom Out";
+            // 
+            // toolStripButton5
+            // 
+            this.toolStripButton5.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton5.Enabled = false;
+            this.toolStripButton5.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton5.Image")));
+            this.toolStripButton5.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton5.Name = "toolStripButton5";
+            this.toolStripButton5.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton5, this.mgInitialViewComponent1);
+            this.toolStripButton5.Text = "Zoom Extents";
+            this.toolStripButton5.ToolTipText = "Zoom Extents";
+            // 
+            // toolStripButton6
+            // 
+            this.toolStripButton6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton6.Enabled = false;
+            this.toolStripButton6.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton6.Image")));
+            this.toolStripButton6.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton6.Name = "toolStripButton6";
+            this.toolStripButton6.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton6, this.mgSelectComponent1);
+            this.toolStripButton6.Text = "Select";
+            this.toolStripButton6.ToolTipText = "Select";
+            // 
+            // toolStripButton7
+            // 
+            this.toolStripButton7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton7.Enabled = false;
+            this.toolStripButton7.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton7.Image")));
+            this.toolStripButton7.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton7.Name = "toolStripButton7";
+            this.toolStripButton7.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton7, this.mgCircleSelectComponent1);
+            this.toolStripButton7.Text = "Select Radius";
+            this.toolStripButton7.ToolTipText = "Select Radius";
+            // 
+            // toolStripButton8
+            // 
+            this.toolStripButton8.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton8.Enabled = false;
+            this.toolStripButton8.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton8.Image")));
+            this.toolStripButton8.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton8.Name = "toolStripButton8";
+            this.toolStripButton8.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton8, this.mgPolygonSelectComponent1);
+            this.toolStripButton8.Text = "Select Polygon";
+            this.toolStripButton8.ToolTipText = "Select Polygon";
+            // 
+            // toolStripButton9
+            // 
+            this.toolStripButton9.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton9.Enabled = false;
+            this.toolStripButton9.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton9.Image")));
+            this.toolStripButton9.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton9.Name = "toolStripButton9";
+            this.toolStripButton9.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton9, this.mgPanComponent1);
+            this.toolStripButton9.Text = "Pan";
+            this.toolStripButton9.ToolTipText = "Pan";
+            // 
+            // toolStripButton10
+            // 
+            this.toolStripButton10.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton10.Enabled = false;
+            this.toolStripButton10.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton10.Image")));
+            this.toolStripButton10.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton10.Name = "toolStripButton10";
+            this.toolStripButton10.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton10, this.mgClearSelectionComponent1);
+            this.toolStripButton10.Text = "Clear Selection";
+            this.toolStripButton10.ToolTipText = "Clear Selection";
+            // 
+            // toolStripButton11
+            // 
+            this.toolStripButton11.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+            this.toolStripButton11.Enabled = false;
+            this.toolStripButton11.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton11.Image")));
+            this.toolStripButton11.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton11.Name = "toolStripButton11";
+            this.toolStripButton11.Size = new System.Drawing.Size(23, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton11, this.mgRefreshMapComponent1);
+            this.toolStripButton11.Text = "Refresh Map";
+            this.toolStripButton11.ToolTipText = "Refresh Map";
+            // 
+            // toolStripButton12
+            // 
+            this.toolStripButton12.Enabled = false;
+            this.toolStripButton12.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton12.Image")));
+            this.toolStripButton12.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton12.Name = "toolStripButton12";
+            this.toolStripButton12.Size = new System.Drawing.Size(108, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton12, this.mgTooltipToggleComponent1);
+            this.toolStripButton12.Text = "Enable Tooltips";
+            this.toolStripButton12.ToolTipText = "Enable Tooltips";
+            // 
+            // toolStripMenuItem9
+            // 
+            this.toolStripMenuItem9.Enabled = false;
+            this.toolStripMenuItem9.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem9.Image")));
+            this.toolStripMenuItem9.Name = "toolStripMenuItem9";
+            this.toolStripMenuItem9.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem9, this.mgBufferComponent1);
+            this.toolStripMenuItem9.Text = "Buffer";
+            // 
+            // toolStripMenuItem10
+            // 
+            this.toolStripMenuItem10.Enabled = false;
+            this.toolStripMenuItem10.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem10.Image")));
+            this.toolStripMenuItem10.Name = "toolStripMenuItem10";
+            this.toolStripMenuItem10.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem10, this.mgMeasureComponent1);
+            this.toolStripMenuItem10.Text = "Measure";
+            // 
+            // toolStripMenuItem11
+            // 
+            this.toolStripMenuItem11.Enabled = false;
+            this.toolStripMenuItem11.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem11.Image")));
+            this.toolStripMenuItem11.Name = "toolStripMenuItem11";
+            this.toolStripMenuItem11.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem11, this.mgQueryComponent1);
+            this.toolStripMenuItem11.Text = "Query";
+            // 
+            // toolStripButton13
+            // 
+            this.toolStripButton13.Enabled = false;
+            this.toolStripButton13.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton13.Image")));
+            this.toolStripButton13.ImageTransparentColor = System.Drawing.Color.Magenta;
+            this.toolStripButton13.Name = "toolStripButton13";
+            this.toolStripButton13.Size = new System.Drawing.Size(107, 22);
+            this.mgToolButtonComponentInvoker1.SetTargetComponent(this.toolStripButton13, this.mgViewerOptionsComponent1);
+            this.toolStripButton13.Text = "Viewer Options";
+            this.toolStripButton13.ToolTipText = "Viewer Options";
+            // 
+            // toolStripMenuItem8
+            // 
+            this.toolStripMenuItem8.Enabled = false;
+            this.toolStripMenuItem8.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem8.Image")));
+            this.toolStripMenuItem8.Name = "toolStripMenuItem8";
+            this.toolStripMenuItem8.Size = new System.Drawing.Size(190, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem8, this.plotToDwfComponent);
+            this.toolStripMenuItem8.Text = "Plot to DWF";
+            this.toolStripMenuItem8.ToolTipText = "Plot to DWF";
+            // 
+            // toolStripMenuItem25
+            // 
+            this.toolStripMenuItem25.Enabled = false;
+            this.toolStripMenuItem25.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem25.Image")));
+            this.toolStripMenuItem25.Name = "toolStripMenuItem25";
+            this.toolStripMenuItem25.Size = new System.Drawing.Size(190, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem25, this.loadCompactViewerComponent);
+            this.toolStripMenuItem25.Text = "Load Compact Viewer";
+            this.toolStripMenuItem25.ToolTipText = "Load Compact Viewer";
+            // 
+            // toolStripMenuItem26
+            // 
+            this.toolStripMenuItem26.Enabled = false;
+            this.toolStripMenuItem26.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem26.Image")));
+            this.toolStripMenuItem26.Name = "toolStripMenuItem26";
+            this.toolStripMenuItem26.Size = new System.Drawing.Size(190, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem26, this.profileComponent);
+            this.toolStripMenuItem26.Text = "Profile";
+            this.toolStripMenuItem26.ToolTipText = "Profile this Map";
+            // 
+            // taskPane
+            // 
+            this.taskPane.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.taskPane.Location = new System.Drawing.Point(0, 25);
+            this.taskPane.Name = "taskPane";
+            this.taskPane.Size = new System.Drawing.Size(256, 658);
+            this.taskPane.TabIndex = 0;
+            // 
+            // toolStripMenuItem5
+            // 
+            this.toolStripMenuItem5.Enabled = false;
+            this.toolStripMenuItem5.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem5.Image")));
+            this.toolStripMenuItem5.Name = "toolStripMenuItem5";
+            this.toolStripMenuItem5.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem5, this.mgBufferComponent1);
+            this.toolStripMenuItem5.Text = "Buffer";
+            // 
+            // toolStripMenuItem6
+            // 
+            this.toolStripMenuItem6.Enabled = false;
+            this.toolStripMenuItem6.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem6.Image")));
+            this.toolStripMenuItem6.Name = "toolStripMenuItem6";
+            this.toolStripMenuItem6.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem6, this.mgMeasureComponent1);
+            this.toolStripMenuItem6.Text = "Measure";
+            // 
+            // toolStripMenuItem7
+            // 
+            this.toolStripMenuItem7.Enabled = false;
+            this.toolStripMenuItem7.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem7.Image")));
+            this.toolStripMenuItem7.Name = "toolStripMenuItem7";
+            this.toolStripMenuItem7.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem7, this.mgQueryComponent1);
+            this.toolStripMenuItem7.Text = "Query";
+            // 
+            // toolStripMenuItem1
+            // 
+            this.toolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem1.Image")));
+            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+            this.toolStripMenuItem1.Size = new System.Drawing.Size(147, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem1, this.mgLoadPackageComponent1);
+            this.toolStripMenuItem1.Text = "Load Package";
+            this.toolStripMenuItem1.ToolTipText = "Load Package";
+            // 
+            // toolStripMenuItem2
+            // 
+            this.toolStripMenuItem2.Enabled = false;
+            this.toolStripMenuItem2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem2.Image")));
+            this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+            this.toolStripMenuItem2.Size = new System.Drawing.Size(154, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem2, this.mgBufferComponent1);
+            this.toolStripMenuItem2.Text = "Buffer";
+            // 
+            // toolStripMenuItem3
+            // 
+            this.toolStripMenuItem3.Enabled = false;
+            this.toolStripMenuItem3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem3.Image")));
+            this.toolStripMenuItem3.Name = "toolStripMenuItem3";
+            this.toolStripMenuItem3.Size = new System.Drawing.Size(154, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem3, this.mgMeasureComponent1);
+            this.toolStripMenuItem3.Text = "Measure";
+            // 
+            // toolStripMenuItem4
+            // 
+            this.toolStripMenuItem4.Enabled = false;
+            this.toolStripMenuItem4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem4.Image")));
+            this.toolStripMenuItem4.Name = "toolStripMenuItem4";
+            this.toolStripMenuItem4.Size = new System.Drawing.Size(154, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem4, this.mgQueryComponent1);
+            this.toolStripMenuItem4.Text = "Query";
+            // 
+            // toolStripMenuItem12
+            // 
+            this.toolStripMenuItem12.Enabled = false;
+            this.toolStripMenuItem12.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem12.Image")));
+            this.toolStripMenuItem12.Name = "toolStripMenuItem12";
+            this.toolStripMenuItem12.Size = new System.Drawing.Size(154, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem12, this.mgViewerOptionsComponent1);
+            this.toolStripMenuItem12.Text = "Viewer Options";
+            this.toolStripMenuItem12.ToolTipText = "Viewer Options";
+            // 
+            // toolStripMenuItem13
+            // 
+            this.toolStripMenuItem13.Enabled = false;
+            this.toolStripMenuItem13.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem13.Image")));
+            this.toolStripMenuItem13.Name = "toolStripMenuItem13";
+            this.toolStripMenuItem13.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem13, this.mgRefreshMapComponent1);
+            this.toolStripMenuItem13.Text = "Refresh Map";
+            this.toolStripMenuItem13.ToolTipText = "Refresh Map";
+            // 
+            // toolStripMenuItem14
+            // 
+            this.toolStripMenuItem14.Enabled = false;
+            this.toolStripMenuItem14.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem14.Image")));
+            this.toolStripMenuItem14.Name = "toolStripMenuItem14";
+            this.toolStripMenuItem14.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem14, this.mgZoomInComponent1);
+            this.toolStripMenuItem14.Text = "Zoom In";
+            this.toolStripMenuItem14.ToolTipText = "Zoom In";
+            // 
+            // toolStripMenuItem15
+            // 
+            this.toolStripMenuItem15.Enabled = false;
+            this.toolStripMenuItem15.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem15.Image")));
+            this.toolStripMenuItem15.Name = "toolStripMenuItem15";
+            this.toolStripMenuItem15.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem15, this.mgZoomOutComponent1);
+            this.toolStripMenuItem15.Text = "Zoom Out";
+            this.toolStripMenuItem15.ToolTipText = "Zoom Out";
+            // 
+            // toolStripMenuItem16
+            // 
+            this.toolStripMenuItem16.Enabled = false;
+            this.toolStripMenuItem16.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem16.Image")));
+            this.toolStripMenuItem16.Name = "toolStripMenuItem16";
+            this.toolStripMenuItem16.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem16, this.mgZoomToSelectionComponent1);
+            this.toolStripMenuItem16.Text = "Zoom to Selection";
+            this.toolStripMenuItem16.ToolTipText = "Zoom to Selection";
+            // 
+            // toolStripMenuItem17
+            // 
+            this.toolStripMenuItem17.Enabled = false;
+            this.toolStripMenuItem17.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem17.Image")));
+            this.toolStripMenuItem17.Name = "toolStripMenuItem17";
+            this.toolStripMenuItem17.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem17, this.mgInitialViewComponent1);
+            this.toolStripMenuItem17.Text = "Zoom Extents";
+            this.toolStripMenuItem17.ToolTipText = "Zoom Extents";
+            // 
+            // toolStripMenuItem18
+            // 
+            this.toolStripMenuItem18.Enabled = false;
+            this.toolStripMenuItem18.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem18.Image")));
+            this.toolStripMenuItem18.Name = "toolStripMenuItem18";
+            this.toolStripMenuItem18.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem18, this.mgPanComponent1);
+            this.toolStripMenuItem18.Text = "Pan";
+            this.toolStripMenuItem18.ToolTipText = "Pan";
+            // 
+            // toolStripMenuItem19
+            // 
+            this.toolStripMenuItem19.Enabled = false;
+            this.toolStripMenuItem19.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem19.Image")));
+            this.toolStripMenuItem19.Name = "toolStripMenuItem19";
+            this.toolStripMenuItem19.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem19, this.mgSelectComponent1);
+            this.toolStripMenuItem19.Text = "Select";
+            this.toolStripMenuItem19.ToolTipText = "Select";
+            // 
+            // toolStripMenuItem20
+            // 
+            this.toolStripMenuItem20.Enabled = false;
+            this.toolStripMenuItem20.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem20.Image")));
+            this.toolStripMenuItem20.Name = "toolStripMenuItem20";
+            this.toolStripMenuItem20.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem20, this.mgClearSelectionComponent1);
+            this.toolStripMenuItem20.Text = "Clear Selection";
+            this.toolStripMenuItem20.ToolTipText = "Clear Selection";
+            // 
+            // toolStripMenuItem21
+            // 
+            this.toolStripMenuItem21.Enabled = false;
+            this.toolStripMenuItem21.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem21.Image")));
+            this.toolStripMenuItem21.Name = "toolStripMenuItem21";
+            this.toolStripMenuItem21.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem21, this.mgBufferComponent1);
+            this.toolStripMenuItem21.Text = "Buffer";
+            // 
+            // toolStripMenuItem22
+            // 
+            this.toolStripMenuItem22.Enabled = false;
+            this.toolStripMenuItem22.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem22.Image")));
+            this.toolStripMenuItem22.Name = "toolStripMenuItem22";
+            this.toolStripMenuItem22.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem22, this.mgMeasureComponent1);
+            this.toolStripMenuItem22.Text = "Measure";
+            // 
+            // toolStripMenuItem23
+            // 
+            this.toolStripMenuItem23.Enabled = false;
+            this.toolStripMenuItem23.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem23.Image")));
+            this.toolStripMenuItem23.Name = "toolStripMenuItem23";
+            this.toolStripMenuItem23.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem23, this.mgQueryComponent1);
+            this.toolStripMenuItem23.Text = "Query";
+            // 
+            // toolStripMenuItem24
+            // 
+            this.toolStripMenuItem24.Enabled = false;
+            this.toolStripMenuItem24.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem24.Image")));
+            this.toolStripMenuItem24.Name = "toolStripMenuItem24";
+            this.toolStripMenuItem24.Size = new System.Drawing.Size(171, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem24, this.mgViewerOptionsComponent1);
+            this.toolStripMenuItem24.Text = "Viewer Options";
+            this.toolStripMenuItem24.ToolTipText = "Viewer Options";
+            // 
+            // mgPrintComponent1
+            // 
+            this.mgPrintComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgPrintComponent1.Icon")));
+            this.mgPrintComponent1.Label = "Print";
+            this.mgPrintComponent1.Target = OSGeo.MapGuide.Viewer.MgViewerTarget.TaskPane;
+            this.mgPrintComponent1.TaskPane = this.taskPane;
+            this.mgPrintComponent1.ToolTipText = "Print";
+            this.mgPrintComponent1.Viewer = this.mapViewer;
+            // 
             // mgCopyMapComponent1
             // 
             this.mgCopyMapComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgCopyMapComponent1.Icon")));
@@ -587,17 +1007,6 @@
             this.mgCopyMapComponent1.ToolTipText = "Copy map to clipboard";
             this.mgCopyMapComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton2
-            // 
-            this.mgInvokeComponentButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton2.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton2.Image")));
-            this.mgInvokeComponentButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton2.Name = "mgInvokeComponentButton2";
-            this.mgInvokeComponentButton2.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton2.TargetComponent = this.mgZoomInComponent1;
-            this.mgInvokeComponentButton2.Text = "Zoom In";
-            this.mgInvokeComponentButton2.ToolTipText = "Zoom In";
-            // 
             // mgZoomInComponent1
             // 
             this.mgZoomInComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgZoomInComponent1.Icon")));
@@ -605,17 +1014,6 @@
             this.mgZoomInComponent1.ToolTipText = "Zoom In";
             this.mgZoomInComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton3
-            // 
-            this.mgInvokeComponentButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton3.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton3.Image")));
-            this.mgInvokeComponentButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton3.Name = "mgInvokeComponentButton3";
-            this.mgInvokeComponentButton3.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton3.TargetComponent = this.mgZoomOutComponent1;
-            this.mgInvokeComponentButton3.Text = "Zoom Out";
-            this.mgInvokeComponentButton3.ToolTipText = "Zoom Out";
-            // 
             // mgZoomOutComponent1
             // 
             this.mgZoomOutComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgZoomOutComponent1.Icon")));
@@ -624,17 +1022,6 @@
             this.mgZoomOutComponent1.Viewer = this.mapViewer;
             this.mgZoomOutComponent1.ZoomOutMode = OSGeo.MapGuide.Viewer.ZoomOutMode.ClickToZoom;
             // 
-            // mgInvokeComponentButton4
-            // 
-            this.mgInvokeComponentButton4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton4.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton4.Image")));
-            this.mgInvokeComponentButton4.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton4.Name = "mgInvokeComponentButton4";
-            this.mgInvokeComponentButton4.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton4.TargetComponent = this.mgInitialViewComponent1;
-            this.mgInvokeComponentButton4.Text = "Zoom Extents";
-            this.mgInvokeComponentButton4.ToolTipText = "Zoom Extents";
-            // 
             // mgInitialViewComponent1
             // 
             this.mgInitialViewComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgInitialViewComponent1.Icon")));
@@ -642,17 +1029,6 @@
             this.mgInitialViewComponent1.ToolTipText = "Zoom Extents";
             this.mgInitialViewComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton5
-            // 
-            this.mgInvokeComponentButton5.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton5.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton5.Image")));
-            this.mgInvokeComponentButton5.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton5.Name = "mgInvokeComponentButton5";
-            this.mgInvokeComponentButton5.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton5.TargetComponent = this.mgSelectComponent1;
-            this.mgInvokeComponentButton5.Text = "Select";
-            this.mgInvokeComponentButton5.ToolTipText = "Select";
-            // 
             // mgSelectComponent1
             // 
             this.mgSelectComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgSelectComponent1.Icon")));
@@ -660,17 +1036,6 @@
             this.mgSelectComponent1.ToolTipText = "Select";
             this.mgSelectComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton6
-            // 
-            this.mgInvokeComponentButton6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton6.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton6.Image")));
-            this.mgInvokeComponentButton6.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton6.Name = "mgInvokeComponentButton6";
-            this.mgInvokeComponentButton6.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton6.TargetComponent = this.mgCircleSelectComponent1;
-            this.mgInvokeComponentButton6.Text = "Select Radius";
-            this.mgInvokeComponentButton6.ToolTipText = "Select Radius";
-            // 
             // mgCircleSelectComponent1
             // 
             this.mgCircleSelectComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgCircleSelectComponent1.Icon")));
@@ -678,17 +1043,6 @@
             this.mgCircleSelectComponent1.ToolTipText = "Select Radius";
             this.mgCircleSelectComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton7
-            // 
-            this.mgInvokeComponentButton7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton7.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton7.Image")));
-            this.mgInvokeComponentButton7.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton7.Name = "mgInvokeComponentButton7";
-            this.mgInvokeComponentButton7.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton7.TargetComponent = this.mgPolygonSelectComponent1;
-            this.mgInvokeComponentButton7.Text = "Select Polygon";
-            this.mgInvokeComponentButton7.ToolTipText = "Select Polygon";
-            // 
             // mgPolygonSelectComponent1
             // 
             this.mgPolygonSelectComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgPolygonSelectComponent1.Icon")));
@@ -696,17 +1050,6 @@
             this.mgPolygonSelectComponent1.ToolTipText = "Select Polygon";
             this.mgPolygonSelectComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton8
-            // 
-            this.mgInvokeComponentButton8.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton8.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton8.Image")));
-            this.mgInvokeComponentButton8.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton8.Name = "mgInvokeComponentButton8";
-            this.mgInvokeComponentButton8.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton8.TargetComponent = this.mgPanComponent1;
-            this.mgInvokeComponentButton8.Text = "Pan";
-            this.mgInvokeComponentButton8.ToolTipText = "Pan";
-            // 
             // mgPanComponent1
             // 
             this.mgPanComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgPanComponent1.Icon")));
@@ -714,17 +1057,6 @@
             this.mgPanComponent1.ToolTipText = "Pan";
             this.mgPanComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton9
-            // 
-            this.mgInvokeComponentButton9.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton9.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton9.Image")));
-            this.mgInvokeComponentButton9.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton9.Name = "mgInvokeComponentButton9";
-            this.mgInvokeComponentButton9.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton9.TargetComponent = this.mgClearSelectionComponent1;
-            this.mgInvokeComponentButton9.Text = "Clear Selection";
-            this.mgInvokeComponentButton9.ToolTipText = "Clear Selection";
-            // 
             // mgClearSelectionComponent1
             // 
             this.mgClearSelectionComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgClearSelectionComponent1.Icon")));
@@ -732,17 +1064,6 @@
             this.mgClearSelectionComponent1.ToolTipText = "Clear Selection";
             this.mgClearSelectionComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton10
-            // 
-            this.mgInvokeComponentButton10.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton10.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton10.Image")));
-            this.mgInvokeComponentButton10.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton10.Name = "mgInvokeComponentButton10";
-            this.mgInvokeComponentButton10.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton10.TargetComponent = this.mgRefreshMapComponent1;
-            this.mgInvokeComponentButton10.Text = "Refresh Map";
-            this.mgInvokeComponentButton10.ToolTipText = "Refresh Map";
-            // 
             // mgRefreshMapComponent1
             // 
             this.mgRefreshMapComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgRefreshMapComponent1.Icon")));
@@ -750,16 +1071,6 @@
             this.mgRefreshMapComponent1.ToolTipText = "Refresh Map";
             this.mgRefreshMapComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton11
-            // 
-            this.mgInvokeComponentButton11.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton11.Image")));
-            this.mgInvokeComponentButton11.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton11.Name = "mgInvokeComponentButton11";
-            this.mgInvokeComponentButton11.Size = new System.Drawing.Size(108, 22);
-            this.mgInvokeComponentButton11.TargetComponent = this.mgTooltipToggleComponent1;
-            this.mgInvokeComponentButton11.Text = "Enable Tooltips";
-            this.mgInvokeComponentButton11.ToolTipText = "Enable Tooltips";
-            // 
             // mgTooltipToggleComponent1
             // 
             this.mgTooltipToggleComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgTooltipToggleComponent1.Icon")));
@@ -767,14 +1078,6 @@
             this.mgTooltipToggleComponent1.ToolTipText = "Enable Tooltips";
             this.mgTooltipToggleComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem20
-            // 
-            this.mgInvokeComponentMenuItem20.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem20.Image")));
-            this.mgInvokeComponentMenuItem20.Name = "mgInvokeComponentMenuItem20";
-            this.mgInvokeComponentMenuItem20.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem20.TargetComponent = this.mgBufferComponent1;
-            this.mgInvokeComponentMenuItem20.Text = "Buffer";
-            // 
             // mgBufferComponent1
             // 
             this.mgBufferComponent1.DefaultBufferUnits = OSGeo.MapGuide.Viewer.MeasurementUnit.Meters;
@@ -786,22 +1089,6 @@
             this.mgBufferComponent1.ToolTipText = null;
             this.mgBufferComponent1.Viewer = this.mapViewer;
             // 
-            // taskPane
-            // 
-            this.taskPane.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.taskPane.Location = new System.Drawing.Point(0, 25);
-            this.taskPane.Name = "taskPane";
-            this.taskPane.Size = new System.Drawing.Size(256, 658);
-            this.taskPane.TabIndex = 0;
-            // 
-            // mgInvokeComponentMenuItem21
-            // 
-            this.mgInvokeComponentMenuItem21.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem21.Image")));
-            this.mgInvokeComponentMenuItem21.Name = "mgInvokeComponentMenuItem21";
-            this.mgInvokeComponentMenuItem21.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem21.TargetComponent = this.mgMeasureComponent1;
-            this.mgInvokeComponentMenuItem21.Text = "Measure";
-            // 
             // mgMeasureComponent1
             // 
             this.mgMeasureComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgMeasureComponent1.Icon")));
@@ -811,14 +1098,6 @@
             this.mgMeasureComponent1.ToolTipText = null;
             this.mgMeasureComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem22
-            // 
-            this.mgInvokeComponentMenuItem22.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem22.Image")));
-            this.mgInvokeComponentMenuItem22.Name = "mgInvokeComponentMenuItem22";
-            this.mgInvokeComponentMenuItem22.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem22.TargetComponent = this.mgQueryComponent1;
-            this.mgInvokeComponentMenuItem22.Text = "Query";
-            // 
             // mgQueryComponent1
             // 
             this.mgQueryComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgQueryComponent1.Icon")));
@@ -828,16 +1107,6 @@
             this.mgQueryComponent1.ToolTipText = null;
             this.mgQueryComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentButton15
-            // 
-            this.mgInvokeComponentButton15.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton15.Image")));
-            this.mgInvokeComponentButton15.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton15.Name = "mgInvokeComponentButton15";
-            this.mgInvokeComponentButton15.Size = new System.Drawing.Size(107, 22);
-            this.mgInvokeComponentButton15.TargetComponent = this.mgViewerOptionsComponent1;
-            this.mgInvokeComponentButton15.Text = "Viewer Options";
-            this.mgInvokeComponentButton15.ToolTipText = "Viewer Options";
-            // 
             // mgViewerOptionsComponent1
             // 
             this.mgViewerOptionsComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgViewerOptionsComponent1.Icon")));
@@ -848,132 +1117,22 @@
             this.mgViewerOptionsComponent1.ToolTipText = "Viewer Options";
             this.mgViewerOptionsComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem23
-            // 
-            this.mgInvokeComponentMenuItem23.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem23.Image")));
-            this.mgInvokeComponentMenuItem23.Name = "mgInvokeComponentMenuItem23";
-            this.mgInvokeComponentMenuItem23.Size = new System.Drawing.Size(137, 22);
-            this.mgInvokeComponentMenuItem23.TargetComponent = this.plotToDwfComponent;
-            this.mgInvokeComponentMenuItem23.Text = "Plot to DWF";
-            this.mgInvokeComponentMenuItem23.ToolTipText = "Plot to DWF";
-            // 
             // plotToDwfComponent
             // 
+            this.plotToDwfComponent.CanInvokeWithoutLoadedMap = false;
             this.plotToDwfComponent.Icon = ((System.Drawing.Image)(resources.GetObject("plotToDwfComponent.Icon")));
             this.plotToDwfComponent.Label = "Plot to DWF";
             this.plotToDwfComponent.ToolTipText = "Plot to DWF";
             this.plotToDwfComponent.Viewer = this.mapViewer;
             this.plotToDwfComponent.Invoked += new System.EventHandler(this.plotToDwfComponent_Invoked);
             // 
-            // mgInvokeComponentMenuItem1
-            // 
-            this.mgInvokeComponentMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem1.Image")));
-            this.mgInvokeComponentMenuItem1.Name = "mgInvokeComponentMenuItem1";
-            this.mgInvokeComponentMenuItem1.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem1.TargetComponent = this.mgBufferComponent1;
-            this.mgInvokeComponentMenuItem1.Text = "Buffer";
-            // 
-            // mgInvokeComponentMenuItem2
-            // 
-            this.mgInvokeComponentMenuItem2.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem2.Image")));
-            this.mgInvokeComponentMenuItem2.Name = "mgInvokeComponentMenuItem2";
-            this.mgInvokeComponentMenuItem2.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem2.TargetComponent = this.mgMeasureComponent1;
-            this.mgInvokeComponentMenuItem2.Text = "Measure";
-            // 
-            // mgInvokeComponentMenuItem3
-            // 
-            this.mgInvokeComponentMenuItem3.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem3.Image")));
-            this.mgInvokeComponentMenuItem3.Name = "mgInvokeComponentMenuItem3";
-            this.mgInvokeComponentMenuItem3.Size = new System.Drawing.Size(119, 22);
-            this.mgInvokeComponentMenuItem3.TargetComponent = this.mgQueryComponent1;
-            this.mgInvokeComponentMenuItem3.Text = "Query";
-            // 
-            // mgInvokeComponentMenuItem14
-            // 
-            this.mgInvokeComponentMenuItem14.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem14.Image")));
-            this.mgInvokeComponentMenuItem14.Name = "mgInvokeComponentMenuItem14";
-            this.mgInvokeComponentMenuItem14.Size = new System.Drawing.Size(147, 22);
-            this.mgInvokeComponentMenuItem14.TargetComponent = this.mgLoadPackageComponent1;
-            this.mgInvokeComponentMenuItem14.Text = "Load Package";
-            this.mgInvokeComponentMenuItem14.ToolTipText = "Load Package";
-            // 
             // mgLoadPackageComponent1
             // 
             this.mgLoadPackageComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgLoadPackageComponent1.Icon")));
             this.mgLoadPackageComponent1.Label = "Load Package";
             this.mgLoadPackageComponent1.ToolTipText = "Load Package";
-            this.mgLoadPackageComponent1.Viewer = null;
+            this.mgLoadPackageComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem15
-            // 
-            this.mgInvokeComponentMenuItem15.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem15.Image")));
-            this.mgInvokeComponentMenuItem15.Name = "mgInvokeComponentMenuItem15";
-            this.mgInvokeComponentMenuItem15.Size = new System.Drawing.Size(154, 22);
-            this.mgInvokeComponentMenuItem15.TargetComponent = this.mgBufferComponent1;
-            this.mgInvokeComponentMenuItem15.Text = "Buffer";
-            // 
-            // mgInvokeComponentMenuItem16
-            // 
-            this.mgInvokeComponentMenuItem16.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem16.Image")));
-            this.mgInvokeComponentMenuItem16.Name = "mgInvokeComponentMenuItem16";
-            this.mgInvokeComponentMenuItem16.Size = new System.Drawing.Size(154, 22);
-            this.mgInvokeComponentMenuItem16.TargetComponent = this.mgMeasureComponent1;
-            this.mgInvokeComponentMenuItem16.Text = "Measure";
-            // 
-            // mgInvokeComponentMenuItem17
-            // 
-            this.mgInvokeComponentMenuItem17.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem17.Image")));
-            this.mgInvokeComponentMenuItem17.Name = "mgInvokeComponentMenuItem17";
-            this.mgInvokeComponentMenuItem17.Size = new System.Drawing.Size(154, 22);
-            this.mgInvokeComponentMenuItem17.TargetComponent = this.mgQueryComponent1;
-            this.mgInvokeComponentMenuItem17.Text = "Query";
-            // 
-            // mgInvokeComponentMenuItem18
-            // 
-            this.mgInvokeComponentMenuItem18.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem18.Image")));
-            this.mgInvokeComponentMenuItem18.Name = "mgInvokeComponentMenuItem18";
-            this.mgInvokeComponentMenuItem18.Size = new System.Drawing.Size(154, 22);
-            this.mgInvokeComponentMenuItem18.TargetComponent = this.mgViewerOptionsComponent1;
-            this.mgInvokeComponentMenuItem18.Text = "Viewer Options";
-            this.mgInvokeComponentMenuItem18.ToolTipText = "Viewer Options";
-            // 
-            // mgInvokeComponentMenuItem4
-            // 
-            this.mgInvokeComponentMenuItem4.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem4.Image")));
-            this.mgInvokeComponentMenuItem4.Name = "mgInvokeComponentMenuItem4";
-            this.mgInvokeComponentMenuItem4.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem4.TargetComponent = this.mgRefreshMapComponent1;
-            this.mgInvokeComponentMenuItem4.Text = "Refresh Map";
-            this.mgInvokeComponentMenuItem4.ToolTipText = "Refresh Map";
-            // 
-            // mgInvokeComponentMenuItem6
-            // 
-            this.mgInvokeComponentMenuItem6.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem6.Image")));
-            this.mgInvokeComponentMenuItem6.Name = "mgInvokeComponentMenuItem6";
-            this.mgInvokeComponentMenuItem6.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem6.TargetComponent = this.mgZoomInComponent1;
-            this.mgInvokeComponentMenuItem6.Text = "Zoom In";
-            this.mgInvokeComponentMenuItem6.ToolTipText = "Zoom In";
-            // 
-            // mgInvokeComponentMenuItem7
-            // 
-            this.mgInvokeComponentMenuItem7.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem7.Image")));
-            this.mgInvokeComponentMenuItem7.Name = "mgInvokeComponentMenuItem7";
-            this.mgInvokeComponentMenuItem7.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem7.TargetComponent = this.mgZoomOutComponent1;
-            this.mgInvokeComponentMenuItem7.Text = "Zoom Out";
-            this.mgInvokeComponentMenuItem7.ToolTipText = "Zoom Out";
-            // 
-            // mgInvokeComponentMenuItem24
-            // 
-            this.mgInvokeComponentMenuItem24.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem24.Image")));
-            this.mgInvokeComponentMenuItem24.Name = "mgInvokeComponentMenuItem24";
-            this.mgInvokeComponentMenuItem24.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem24.TargetComponent = this.mgZoomToSelectionComponent1;
-            this.mgInvokeComponentMenuItem24.Text = "Zoom to Selection";
-            this.mgInvokeComponentMenuItem24.ToolTipText = "Zoom to Selection";
-            // 
             // mgZoomToSelectionComponent1
             // 
             this.mgZoomToSelectionComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgZoomToSelectionComponent1.Icon")));
@@ -981,100 +1140,70 @@
             this.mgZoomToSelectionComponent1.ToolTipText = "Zoom to Selection";
             this.mgZoomToSelectionComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem8
+            // loadCompactViewerComponent
             // 
-            this.mgInvokeComponentMenuItem8.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem8.Image")));
-            this.mgInvokeComponentMenuItem8.Name = "mgInvokeComponentMenuItem8";
-            this.mgInvokeComponentMenuItem8.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem8.TargetComponent = this.mgInitialViewComponent1;
-            this.mgInvokeComponentMenuItem8.Text = "Zoom Extents";
-            this.mgInvokeComponentMenuItem8.ToolTipText = "Zoom Extents";
+            this.loadCompactViewerComponent.CanInvokeWithoutLoadedMap = false;
+            this.loadCompactViewerComponent.Icon = ((System.Drawing.Image)(resources.GetObject("loadCompactViewerComponent.Icon")));
+            this.loadCompactViewerComponent.Label = "Load Compact Viewer";
+            this.loadCompactViewerComponent.ToolTipText = "Load Compact Viewer";
+            this.loadCompactViewerComponent.Viewer = this.mapViewer;
+            this.loadCompactViewerComponent.Invoked += new System.EventHandler(this.loadCompactViewerComponent_Invoked);
             // 
-            // mgInvokeComponentMenuItem5
+            // profileComponent
             // 
-            this.mgInvokeComponentMenuItem5.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem5.Image")));
-            this.mgInvokeComponentMenuItem5.Name = "mgInvokeComponentMenuItem5";
-            this.mgInvokeComponentMenuItem5.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem5.TargetComponent = this.mgPanComponent1;
-            this.mgInvokeComponentMenuItem5.Text = "Pan";
-            this.mgInvokeComponentMenuItem5.ToolTipText = "Pan";
+            this.profileComponent.CanInvokeWithoutLoadedMap = false;
+            this.profileComponent.Icon = ((System.Drawing.Image)(resources.GetObject("profileComponent.Icon")));
+            this.profileComponent.Label = "Profile";
+            this.profileComponent.ToolTipText = "Profile this Map";
+            this.profileComponent.Viewer = this.mapViewer;
+            this.profileComponent.Invoked += new System.EventHandler(this.profileComponent_Invoked);
             // 
-            // mgInvokeComponentMenuItem9
+            // mgLayerSelectionHandler1
             // 
-            this.mgInvokeComponentMenuItem9.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem9.Image")));
-            this.mgInvokeComponentMenuItem9.Name = "mgInvokeComponentMenuItem9";
-            this.mgInvokeComponentMenuItem9.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem9.TargetComponent = this.mgSelectComponent1;
-            this.mgInvokeComponentMenuItem9.Text = "Select";
-            this.mgInvokeComponentMenuItem9.ToolTipText = "Select";
+            this.mgLayerSelectionHandler1.Layers = new string[] {
+        "Parcels"};
+            this.mgLayerSelectionHandler1.Viewer = this.mapViewer;
+            this.mgLayerSelectionHandler1.SelectionMade += new OSGeo.MapGuide.Viewer.MgLayerSelectionEventHandler(this.mgLayerSelectionHandler1_SelectionMade);
             // 
-            // mgInvokeComponentMenuItem10
+            // mgThemeComponent1
             // 
-            this.mgInvokeComponentMenuItem10.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem10.Image")));
-            this.mgInvokeComponentMenuItem10.Name = "mgInvokeComponentMenuItem10";
-            this.mgInvokeComponentMenuItem10.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem10.TargetComponent = this.mgClearSelectionComponent1;
-            this.mgInvokeComponentMenuItem10.Text = "Clear Selection";
-            this.mgInvokeComponentMenuItem10.ToolTipText = "Clear Selection";
+            this.mgThemeComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgThemeComponent1.Icon")));
+            this.mgThemeComponent1.Label = "Theme";
+            this.mgThemeComponent1.Target = OSGeo.MapGuide.Viewer.MgViewerTarget.TaskPane;
+            this.mgThemeComponent1.TaskPane = this.taskPane;
+            this.mgThemeComponent1.ToolTipText = "Theme";
+            this.mgThemeComponent1.Viewer = this.mapViewer;
             // 
-            // mgInvokeComponentMenuItem11
+            // toolStripMenuItem27
             // 
-            this.mgInvokeComponentMenuItem11.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem11.Image")));
-            this.mgInvokeComponentMenuItem11.Name = "mgInvokeComponentMenuItem11";
-            this.mgInvokeComponentMenuItem11.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem11.TargetComponent = this.mgBufferComponent1;
-            this.mgInvokeComponentMenuItem11.Text = "Buffer";
+            this.toolStripMenuItem27.Enabled = false;
+            this.toolStripMenuItem27.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem27.Image")));
+            this.toolStripMenuItem27.Name = "toolStripMenuItem27";
+            this.toolStripMenuItem27.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem27, this.mgThemeComponent1);
+            this.toolStripMenuItem27.Text = "Theme";
+            this.toolStripMenuItem27.ToolTipText = "Theme";
             // 
-            // mgInvokeComponentMenuItem12
+            // toolStripMenuItem28
             // 
-            this.mgInvokeComponentMenuItem12.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem12.Image")));
-            this.mgInvokeComponentMenuItem12.Name = "mgInvokeComponentMenuItem12";
-            this.mgInvokeComponentMenuItem12.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem12.TargetComponent = this.mgMeasureComponent1;
-            this.mgInvokeComponentMenuItem12.Text = "Measure";
+            this.toolStripMenuItem28.Enabled = false;
+            this.toolStripMenuItem28.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem28.Image")));
+            this.toolStripMenuItem28.Name = "toolStripMenuItem28";
+            this.toolStripMenuItem28.Size = new System.Drawing.Size(154, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem28, this.mgThemeComponent1);
+            this.toolStripMenuItem28.Text = "Theme";
+            this.toolStripMenuItem28.ToolTipText = "Theme";
             // 
-            // mgInvokeComponentMenuItem13
+            // toolStripMenuItem29
             // 
-            this.mgInvokeComponentMenuItem13.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem13.Image")));
-            this.mgInvokeComponentMenuItem13.Name = "mgInvokeComponentMenuItem13";
-            this.mgInvokeComponentMenuItem13.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem13.TargetComponent = this.mgQueryComponent1;
-            this.mgInvokeComponentMenuItem13.Text = "Query";
+            this.toolStripMenuItem29.Enabled = false;
+            this.toolStripMenuItem29.Image = ((System.Drawing.Image)(resources.GetObject("toolStripMenuItem29.Image")));
+            this.toolStripMenuItem29.Name = "toolStripMenuItem29";
+            this.toolStripMenuItem29.Size = new System.Drawing.Size(152, 22);
+            this.mgMenuItemComponentInvoker1.SetTargetComponent(this.toolStripMenuItem29, this.mgThemeComponent1);
+            this.toolStripMenuItem29.Text = "Theme";
+            this.toolStripMenuItem29.ToolTipText = "Theme";
             // 
-            // mgInvokeComponentMenuItem19
-            // 
-            this.mgInvokeComponentMenuItem19.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentMenuItem19.Image")));
-            this.mgInvokeComponentMenuItem19.Name = "mgInvokeComponentMenuItem19";
-            this.mgInvokeComponentMenuItem19.Size = new System.Drawing.Size(171, 22);
-            this.mgInvokeComponentMenuItem19.TargetComponent = this.mgViewerOptionsComponent1;
-            this.mgInvokeComponentMenuItem19.Text = "Viewer Options";
-            this.mgInvokeComponentMenuItem19.ToolTipText = "Viewer Options";
-            // 
-            // mgPrintComponent1
-            // 
-            this.mgPrintComponent1.Icon = ((System.Drawing.Image)(resources.GetObject("mgPrintComponent1.Icon")));
-            this.mgPrintComponent1.Label = "Print";
-            this.mgPrintComponent1.Target = OSGeo.MapGuide.Viewer.MgViewerTarget.TaskPane;
-            this.mgPrintComponent1.TaskPane = this.taskPane;
-            this.mgPrintComponent1.ToolTipText = "Print";
-            this.mgPrintComponent1.Viewer = this.mapViewer;
-            // 
-            // mgInvokeComponentButton12
-            // 
-            this.mgInvokeComponentButton12.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
-            this.mgInvokeComponentButton12.Image = ((System.Drawing.Image)(resources.GetObject("mgInvokeComponentButton12.Image")));
-            this.mgInvokeComponentButton12.ImageTransparentColor = System.Drawing.Color.Magenta;
-            this.mgInvokeComponentButton12.Name = "mgInvokeComponentButton12";
-            this.mgInvokeComponentButton12.Size = new System.Drawing.Size(23, 22);
-            this.mgInvokeComponentButton12.TargetComponent = this.mgPrintComponent1;
-            this.mgInvokeComponentButton12.Text = "Print";
-            this.mgInvokeComponentButton12.ToolTipText = "Print";
-            // 
-            // toolStripSeparator13
-            // 
-            this.toolStripSeparator13.Name = "toolStripSeparator13";
-            this.toolStripSeparator13.Size = new System.Drawing.Size(6, 25);
-            // 
             // MgAppWindow
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1114,11 +1243,12 @@
             this.toolStrip1.PerformLayout();
             this.statusBar.ResumeLayout(false);
             this.statusBar.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.mgPrintComponent1)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgBufferComponent1)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgMeasureComponent1)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgQueryComponent1)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.mgViewerOptionsComponent1)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.mgPrintComponent1)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.mgThemeComponent1)).EndInit();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -1138,22 +1268,6 @@
         private System.Windows.Forms.ToolStripStatusLabel lblSelected;
         private System.Windows.Forms.ToolStripStatusLabel lblScale;
         private System.Windows.Forms.ToolStripStatusLabel lblSize;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton1;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton2;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton3;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton4;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton5;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton6;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton7;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton8;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton9;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton10;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton11;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
         private OSGeo.MapGuide.Viewer.MgCircleSelectComponent mgCircleSelectComponent1;
         private OSGeo.MapGuide.Viewer.MgClearSelectionComponent mgClearSelectionComponent1;
         private OSGeo.MapGuide.Viewer.MgCopyMapComponent mgCopyMapComponent1;
@@ -1180,51 +1294,77 @@
         private System.Windows.Forms.ToolStrip toolStrip1;
         private System.Windows.Forms.ToolStripButton btnInitialTask;
         private System.Windows.Forms.ToolStripSplitButton taskMenu;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem1;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem2;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem3;
-        private System.Windows.Forms.ToolStripLabel lblLoading;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem4;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem5;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem6;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem7;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem8;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem9;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem10;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem11;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem12;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem13;
         private OSGeo.MapGuide.Viewer.MgViewerOptionsComponent mgViewerOptionsComponent1;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton15;
         private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem14;
         private OSGeo.MapGuide.Viewer.MgLoadPackageComponent mgLoadPackageComponent1;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
         private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem15;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem16;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem17;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem18;
-        private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem19;
         private OSGeo.MapGuide.Viewer.MgGenericInvokeComponent plotToDwfComponent;
-        private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton1;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem20;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem21;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem22;
-        private System.Windows.Forms.ToolStripSplitButton toolStripSplitButton2;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem23;
         private OSGeo.MapGuide.Viewer.MgZoomToSelectionComponent mgZoomToSelectionComponent1;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentMenuItem mgInvokeComponentMenuItem24;
         private OSGeo.MapGuide.Viewer.MgPrintComponent mgPrintComponent1;
-        private OSGeo.MapGuide.Viewer.MgInvokeComponentButton mgInvokeComponentButton12;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
+        private OSGeo.MapGuide.Viewer.MgMenuItemComponentInvoker mgMenuItemComponentInvoker1;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4;
+        private System.Windows.Forms.ToolStripButton toolStripButton1;
+        private OSGeo.MapGuide.Viewer.MgToolButtonComponentInvoker mgToolButtonComponentInvoker1;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+        private System.Windows.Forms.ToolStripButton toolStripButton2;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+        private System.Windows.Forms.ToolStripButton toolStripButton3;
+        private System.Windows.Forms.ToolStripButton toolStripButton4;
+        private System.Windows.Forms.ToolStripButton toolStripButton5;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+        private System.Windows.Forms.ToolStripButton toolStripButton6;
+        private System.Windows.Forms.ToolStripButton toolStripButton7;
+        private System.Windows.Forms.ToolStripButton toolStripButton8;
+        private System.Windows.Forms.ToolStripButton toolStripButton9;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
+        private System.Windows.Forms.ToolStripButton toolStripButton10;
+        private System.Windows.Forms.ToolStripButton toolStripButton11;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
+        private System.Windows.Forms.ToolStripButton toolStripButton12;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
+        private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton1;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
+        private System.Windows.Forms.ToolStripButton toolStripButton13;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
+        private System.Windows.Forms.ToolStripDropDownButton toolStripDropDownButton2;
+        private System.Windows.Forms.ToolStripLabel lblLoading;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem5;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem6;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem7;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem12;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem9;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem10;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem11;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem8;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem13;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem14;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem16;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem17;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem18;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem19;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem20;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem21;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem22;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem23;
         private System.Windows.Forms.ToolStripSeparator toolStripSeparator13;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem24;
+        private OSGeo.MapGuide.Viewer.MgLayerSelectionHandler mgLayerSelectionHandler1;
+        private OSGeo.MapGuide.Viewer.MgGenericInvokeComponent loadCompactViewerComponent;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem25;
+        private OSGeo.MapGuide.Viewer.MgGenericInvokeComponent profileComponent;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem26;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem28;
+        private OSGeo.MapGuide.Viewer.MgThemeComponent mgThemeComponent1;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem27;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem29;
 
     }
 }
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -16,6 +16,10 @@
         {
             InitializeComponent();
             taskMenu.DropDownDirection = ToolStripDropDownDirection.BelowLeft;
+            if (!this.DesignMode)
+            {
+                new MapViewerController(mapViewer, legendCtrl, this, propertiesCtrl);
+            }
         }
 
         public string MapDefinition
@@ -31,10 +35,6 @@
 
         protected override void OnLoad(EventArgs e)
         {
-            if (!this.DesignMode)
-            {
-                new MapViewerController(mapViewer, legendCtrl, this, propertiesCtrl);
-            }
             base.OnLoad(e);
         }
 
@@ -103,5 +103,34 @@
                 }
             }
         }
+
+        private void mgLayerSelectionHandler1_SelectionMade(string layerName, MgFeatureReader selectedFeatures)
+        {
+            int count = 0;
+            while (selectedFeatures.ReadNext())
+            {
+                count++;
+            }
+            selectedFeatures.Close();
+            MessageBox.Show(count + " parcels selected");
+        }
+
+        private void loadCompactViewerComponent_Invoked(object sender, EventArgs e)
+        {
+            var map = mapViewer.GetMap();
+            var viewer = new CompactViewer();
+            viewer.LoadMap(map.MapDefinition);
+            viewer.Show();
+        }
+
+        private void profileComponent_Invoked(object sender, EventArgs e)
+        {
+            var provider = mapViewer.GetProvider();
+            var map = mapViewer.GetMap();
+            var prof = (MgProfilingService)provider.CreateService(MgServiceType.ProfilingService);
+            var opts = new MgRenderingOptions("PNG", 2, new MgColor(mapViewer.SelectionColor));
+            var result = prof.ProfileRenderDynamicOverlay((MgdMap)map, (MgdSelection)mapViewer.GetSelection(), opts); 
+ 	        new XmlResponseDialog(result).ShowDialog(); 
+        }
     }
 }

Modified: trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.resx
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.resx	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewerTest/MgAppWindow.resx	2012-05-13 04:07:19 UTC (rev 6646)
@@ -120,37 +120,162 @@
   <metadata name="appMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="toolStripMenuItem2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
+</value>
+  </data>
+  <metadata name="mgMenuItemComponentInvoker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>802, 95</value>
+  </metadata>
+  <metadata name="mgBufferComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>446, 173</value>
+  </metadata>
+  <data name="mgBufferComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
+</value>
+  </data>
   <metadata name="appContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>338, 17</value>
   </metadata>
+  <data name="toolStripMenuItem3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
+</value>
+  </data>
+  <metadata name="mgMeasureComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 212</value>
+  </metadata>
+  <data name="mgMeasureComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="toolStripMenuItem4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <metadata name="mgQueryComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>840, 173</value>
+  </metadata>
+  <data name="mgQueryComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <data name="toolStripMenuItem28.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        R0lGODlhEAAQAIMAAAAAAP///6e6zXG39mCc0bzd+87trIC4QpfYTv/eStm9P//vqmdnZywsLP///wAA
+        ACH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAOACwAAAAAEAAQAAAIeQAdCBxIsKADBggTIjQokIGBhxAb
+        MDxoAIFFBAckMnRoUaFCghwRMFhAsqTGhhVFLkjAMoGCkxQPHBjJ0qPCBjhpJmBQoKfPBgKCCtDJc4DR
+        AQRgjlSgoOjRpCBxNnBqFOpAoUMLHEUKE2QBAmDBdh3IQKrZiVixBgQAOw==
+</value>
+  </data>
+  <metadata name="mgThemeComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>508, 212</value>
+  </metadata>
+  <data name="mgThemeComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        R0lGODlhEAAQAIMAAAAAAP///6e6zXG39mCc0bzd+87trIC4QpfYTv/eStm9P//vqmdnZywsLP///wAA
+        ACH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAOACwAAAAAEAAQAAAIeQAdCBxIsKADBggTIjQokIGBhxAb
+        MDxoAIFFBAckMnRoUaFCghwRMFhAsqTGhhVFLkjAMoGCkxQPHBjJ0qPCBjhpJmBQoKfPBgKCCtDJc4DR
+        AQRgjlSgoOjRpCBxNnBqFOpAoUMLHEUKE2QBAmDBdh3IQKrZiVixBgQAOw==
+</value>
+  </data>
+  <data name="toolStripMenuItem12.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
+        QtRiKBaLSqyrkQnkgovCkBg4zFyYOYRAlIo9raSTtpMuhcC7ihfPuQGD2Yak8K4TxOAEoQc3OGQnkrI/
+        avJAkOmcepMV4CwBAn0x1J+u6fmyrvrMfRM8A0F+LX5enrMECExRUggQ3MqKhvMt4CwBgnv1oNFiR3X9
+        cdVn7pvgGQj48cbLFHCWAIG1bwrhP4LY3/gFpD/IGPp59QYAAAAASUVORK5CYII=
+</value>
+  </data>
+  <metadata name="mgViewerOptionsComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>619, 173</value>
+  </metadata>
+  <data name="mgViewerOptionsComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
+        QtRiKBaLSqyrkQnkgovCkBg4zFyYOYRAlIo9raSTtpMuhcC7ihfPuQGD2Yak8K4TxOAEoQc3OGQnkrI/
+        avJAkOmcepMV4CwBAn0x1J+u6fmyrvrMfRM8A0F+LX5enrMECExRUggQ3MqKhvMt4CwBgnv1oNFiR3X9
+        cdVn7pvgGQj48cbLFHCWAIG1bwrhP4LY3/gFpD/IGPp59QYAAAAASUVORK5CYII=
+</value>
+  </data>
   <metadata name="appToolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>121, 17</value>
   </metadata>
-  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
-  <data name="mgInvokeComponentButton12.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD3SURBVDhPlZNLCoMwEIa9V6TdeBYXhdKKlB6rCy/QE3Tt
-        VnQhPlBEEXww5R8wxJqIHfhAksw3k8RYlhJCiMC2bTLh+z6p6zffSNwLCHYlEERRZATJCKMEgjiOtSRJ
-        wolLaCVhGNIwDFrqumbBL/IcxMkJ7LNDOm7eg6Vpmq5Ax1KARFNgbhxHyrKM8jyXSIHrulx5T4A1kLRt
-        S2VZMixQW98ToIDnP2maJqqqimEBJrquY0xnoM5D0DQNIwVFUdARUGCeZ94GkAJc3xEWQd/3BKTA1Lpu
-        HB0YBTjE1/uzAmOqaCP45xYu1ztvdXmteL2H/kQUMT3jL5h/eJuHqhoLAAAAAElFTkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD3SURBVDhPlZNLCoMwEIY9V5B241lcFEorUnqsLrxAT9C1
+        W9GF+EARRfDBlH/AEGsiduADSTLfTBJjWUoIIQLbtsmE7/ukrt98I3EvINiVQBBFkREkI4wSCOI41pIk
+        CScuoZWEYUjDMGip65oFv8hzECcnsM8O6bh5D5amaboCHUsBEk2BuXEcKcsyyvNcIgWu63LlPQHWQNK2
+        LZVlybBAbX1PgAKe/6RpmqiqKoYFmOi6jjGdgToPQdM0jBQURUFHQIF5nnkbQApwfUdYBH3fE5ACU+u6
+        cXRgFOAQX+/PCoypoo3gn1u4XO+81eW14vUe+hNRxPSMv4YPeJAk7UvrAAAAAElFTkSuQmCC
 </value>
   </data>
+  <metadata name="mgToolButtonComponentInvoker1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>409, 95</value>
+  </metadata>
   <metadata name="mgPrintComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 95</value>
+    <value>243, 95</value>
   </metadata>
   <data name="mgPrintComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD3SURBVDhPlZNLCoMwEIa9V6TdeBYXhdKKlB6rCy/QE3Tt
-        VnQhPlBEEXww5R8wxJqIHfhAksw3k8RYlhJCiMC2bTLh+z6p6zffSNwLCHYlEERRZATJCKMEgjiOtSRJ
-        wolLaCVhGNIwDFrqumbBL/IcxMkJ7LNDOm7eg6Vpmq5Ax1KARFNgbhxHyrKM8jyXSIHrulx5T4A1kLRt
-        S2VZMixQW98ToIDnP2maJqqqimEBJrquY0xnoM5D0DQNIwVFUdARUGCeZ94GkAJc3xEWQd/3BKTA1Lpu
-        HB0YBTjE1/uzAmOqaCP45xYu1ztvdXmteL2H/kQUMT3jL5h/eJuHqhoLAAAAAElFTkSuQmCC
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD3SURBVDhPlZNLCoMwEIY9V5B241lcFEorUnqsLrxAT9C1
+        W9GF+EARRfDBlH/AEGsiduADSTLfTBJjWUoIIQLbtsmE7/ukrt98I3EvINiVQBBFkREkI4wSCOI41pIk
+        CScuoZWEYUjDMGip65oFv8hzECcnsM8O6bh5D5amaboCHUsBEk2BuXEcKcsyyvNcIgWu63LlPQHWQNK2
+        LZVlybBAbX1PgAKe/6RpmqiqKoYFmOi6jjGdgToPQdM0jBQURUFHQIF5nnkbQApwfUdYBH3fE5ACU+u6
+        cXRgFOAQX+/PCoypoo3gn1u4XO+81eW14vUe+hNRxPSMv4YPeJAk7UvrAAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADgSURBVDhPhZPNCoJAFIV9spZtepfeoGWP2CaCKKQwNf9K
@@ -173,7 +298,7 @@
         SCNfOwFLv7h99gUnGcVV+atLwAAAAABJRU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIESURBVDhPnZPNSxtRFMX9T2ppN7axH2SjqaGpsU0TjJJi
@@ -189,7 +314,7 @@
 </value>
   </data>
   <metadata name="mgZoomInComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>407, 134</value>
+    <value>825, 134</value>
   </metadata>
   <data name="mgZoomInComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
@@ -206,7 +331,7 @@
         JC4A2evLqnFhjAkAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAH5SURBVDhPnZPLSxtRFMb9T2qpm7ZRW7KpqaHBaNMEU0kx
@@ -239,7 +364,7 @@
         AAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentButton4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFqSURBVDhPpZPbTsJAEIZ5NaPxAXgI5UK50Qt9LmPSeBYQ
@@ -266,7 +391,7 @@
         AeYbqBNEyxii5RKJIWRF4qTG/VjWf3l5wX+/8w9/3Qe1qQ/dtwAAAABJRU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentButton5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACcSURBVDhPY2BMZZzJmMb4nywM1MsA0rjxRDMcv//y7D8I
@@ -276,7 +401,7 @@
 </value>
   </data>
   <metadata name="mgSelectComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 134</value>
+    <value>435, 134</value>
   </metadata>
   <data name="mgSelectComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
@@ -287,7 +412,7 @@
         2RkA39ChmP3112gAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentButton6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton7.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEMSURBVDhPY2BABmkMJoypjA2MaYwHgPgtFB8AiTEA5VDU
@@ -312,7 +437,7 @@
         eRxJAAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentButton7.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADCSURBVDhPY2DABlIYjBnTGM+AMAOQjVUNAY3/+7ZkgjHQ
@@ -335,7 +460,7 @@
         gg==
 </value>
   </data>
-  <data name="mgInvokeComponentButton8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton9.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGTSURBVDhPlVNNSwJRFPV/tQpaiW1qFrmKICIqKMmICjIw
@@ -364,7 +489,7 @@
         cDSCJAV+xk7WP7yJ9EN8DX7nAAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentButton9.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton10.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEOSURBVDhPY2CgANjY2PwnWztI8+aOgP8Mbs5B/0EYZBIx
@@ -389,21 +514,21 @@
         0srGPRUAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentButton10.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPY2AAAifP4P+4MEieKAAy4Oev3ygYJAbSHJOc
         /K2itnX/lClz5PEaBtLw6MlLOIYZYGnvATY4Pq3gT0Nr72yshoAkcktq/99/+AyrARu37jkPksvMr/yP
         YQjIaSDTQQqAhqyHuQTmAnt/fwEnr5A1IG/ce/AM7BIU79Q0dh3fsmP//zUbdhx28gpeihywyM519Aye
-        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0jL6
+        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0tL6
         A1IL0gNXB9JIkQEwL4Cch+wFWFjAbHJzCxECefPeg6eoXiiva9+3def+/xu27r7g6BW8AtkLsBQKMSx0
         1frNu44AA/I/KODh6nqmzpMFRQ0ocEChC/TSQpBtMBeAEhHIIFAUw6IRpAclrBrb+mZlFVT9BynYuG3P
-        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4AEiVnFFMI
-        h08AAAAASUVORK5CYII=
+        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4A8r5nBCK/
+        IMoAAAAASUVORK5CYII=
 </value>
   </data>
   <metadata name="mgRefreshMapComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>183, 95</value>
+    <value>17, 134</value>
   </metadata>
   <data name="mgRefreshMapComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
@@ -411,14 +536,14 @@
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPY2AAAifP4P+4MEieKAAy4Oev3ygYJAbSHJOc
         /K2itnX/lClz5PEaBtLw6MlLOIYZYGnvATY4Pq3gT0Nr72yshoAkcktq/99/+AyrARu37jkPksvMr/yP
         YQjIaSDTQQqAhqyHuQTmAnt/fwEnr5A1IG/ce/AM7BIU79Q0dh3fsmP//zUbdhx28gpeihywyM519Aye
-        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0jL6
+        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0tL6
         A1IL0gNXB9JIkQEwL4Cch+wFWFjAbHJzCxECefPeg6eoXiiva9+3def+/xu27r7g6BW8AtkLsBQKMSx0
         1frNu44AA/I/KODh6nqmzpMFRQ0ocEChC/TSQpBtMBeAEhHIIFAUw6IRpAclrBrb+mZlFVT9BynYuG3P
-        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4AEiVnFFMI
-        h08AAAAASUVORK5CYII=
+        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4A8r5nBCK/
+        IMoAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentButton11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripButton12.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADLSURBVDhPY2AYBZSHwOmNjI2nNzCuIQsD9TIcX8e47v+X
@@ -429,7 +554,7 @@
 </value>
   </data>
   <metadata name="mgTooltipToggleComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>190, 134</value>
+    <value>608, 134</value>
   </metadata>
   <data name="mgTooltipToggleComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
@@ -441,21 +566,52 @@
         AABJRU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentButton15.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem9.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
-        QtRiKBaLSqyrkQnkgovCkBg4zFyYOYRAlIo9raSTtpMuhcC7ihfPuQGD2Yak8K4TxOAEoQc3OGQnkrI/
-        avJAkOmcepMV4CwBAn0x1J+u6fmyrvrMfRM8A0F+LX5enrMECExRUggQ3MqKhvMt4CwBgnv1oNFiR3X9
-        cdVn7pvgGQj48cbLFHCWAIG1bwrhP4LY3/gFpD/IGPp59QYAAAAASUVORK5CYII=
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
+        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
+        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
+        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
+        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
+        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
-  <metadata name="mgViewerOptionsComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 212</value>
-  </metadata>
-  <data name="mgViewerOptionsComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem10.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
+        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
+</value>
+  </data>
+  <data name="toolStripMenuItem11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
+        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
+        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
+        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
+        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
+        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
+        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
+        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
+        RK5CYII=
+</value>
+  </data>
+  <data name="toolStripMenuItem27.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        R0lGODlhEAAQAIMAAAAAAP///6e6zXG39mCc0bzd+87trIC4QpfYTv/eStm9P//vqmdnZywsLP///wAA
+        ACH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAOACwAAAAAEAAQAAAIeQAdCBxIsKADBggTIjQokIGBhxAb
+        MDxoAIFFBAckMnRoUaFCghwRMFhAsqTGhhVFLkjAMoGCkxQPHBjJ0qPCBjhpJmBQoKfPBgKCCtDJc4DR
+        AQRgjlSgoOjRpCBxNnBqFOpAoUMLHEUKE2QBAmDBdh3IQKrZiVixBgQAOw==
+</value>
+  </data>
+  <data name="toolStripButton13.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
         QtRiKBaLSqyrkQnkgovCkBg4zFyYOYRAlIo9raSTtpMuhcC7ihfPuQGD2Yak8K4TxOAEoQc3OGQnkrI/
         avJAkOmcepMV4CwBAn0x1J+u6fmyrvrMfRM8A0F+LX5enrMECExRUggQ3MqKhvMt4CwBgnv1oNFiR3X9
@@ -463,15 +619,12 @@
 </value>
   </data>
   <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>600, 212</value>
+    <value>205, 212</value>
   </metadata>
-  <metadata name="statusBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>237, 17</value>
-  </metadata>
-  <data name="mgInvokeComponentMenuItem20.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
         tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
         jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
         T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
@@ -480,44 +633,18 @@
         m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
-  <metadata name="mgBufferComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>446, 173</value>
-  </metadata>
-  <data name="mgBufferComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
-        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
-        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
-        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
-        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
-        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
-        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem21.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
         XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
         4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
 </value>
   </data>
-  <metadata name="mgMeasureComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>412, 212</value>
-  </metadata>
-  <data name="mgMeasureComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem7.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
-        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
-        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem22.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
         YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
         me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
         ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
@@ -529,28 +656,21 @@
         RK5CYII=
 </value>
   </data>
-  <metadata name="mgQueryComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>238, 212</value>
-  </metadata>
-  <data name="mgQueryComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem29.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
-        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
-        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
-        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
-        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
-        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
-        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
-        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
-        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
-        RK5CYII=
+        R0lGODlhEAAQAIMAAAAAAP///6e6zXG39mCc0bzd+87trIC4QpfYTv/eStm9P//vqmdnZywsLP///wAA
+        ACH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAOACwAAAAAEAAQAAAIeQAdCBxIsKADBggTIjQokIGBhxAb
+        MDxoAIFFBAckMnRoUaFCghwRMFhAsqTGhhVFLkjAMoGCkxQPHBjJ0qPCBjhpJmBQoKfPBgKCCtDJc4DR
+        AQRgjlSgoOjRpCBxNnBqFOpAoUMLHEUKE2QBAmDBdh3IQKrZiVixBgQAOw==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem23.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <metadata name="statusBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>237, 17</value>
+  </metadata>
+  <data name="toolStripMenuItem8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAACw0AAAsNAe0HwCwAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
+        YQUAAAAJcEhZcwAACwwAAAsMAT9AIsgAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
         CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
         LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
         SKIE53HEr5LIZHPQX15hiAZb1m23EEtoiCZuBRo4v09ncZWJwbvRBGXAAVcnwd1HhjJHR+oKVbPIt2PU
@@ -567,6 +687,20 @@
   <data name="plotToDwfComponent.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAACwwAAAsMAT9AIsgAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
+        CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
+        LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
+        SKIE53HEr5LIZHPQX15hiAZb1m23EEtoiCZuBRo4v09ncZWJwbvRBGXAAVcnwd1HhjJHR+oKVbPIt2PU
+        kmloyRS0uzRSDzlcP1yg1l+BxjWC/54w9SRiitCwKoS8VFADVPVNIJN9FHYluv6Kwc1mNIjJEzmCw0Po
+        3Jc5w+PCySHfwI/b95wv4DmvmxSLRSj9Dvg0wnhWCjDuGVkP3Yi8lwxTgG+fFa2byN1ytRPGhGXGEuBY
+        My3HXB1kvgHbs88XdCh9DnhjhJHkp4AnIGtvVDjokQ5sH9H21i4G15tRv0wYvpQCbVsyZ+qWRA8mRQ9+
+        nuvXWl0gp9hngX/uDxF8cRm55nF1nir/FGAxdYYqlVE6dHeTwXvmyLU6S07+/g45KJQpvzUZmQAAAABJ
+        RU5ErkJggg==
+</value>
+  </data>
+  <data name="toolStripMenuItem25.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAACw0AAAsNAe0HwCwAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
         CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
         LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
@@ -578,42 +712,55 @@
         RU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <metadata name="loadCompactViewerComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 95</value>
+  </metadata>
+  <data name="loadCompactViewerComponent.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
-        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
-        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
-        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
-        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
-        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
-        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
+        YQUAAAAJcEhZcwAACw0AAAsNAe0HwCwAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
+        CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
+        LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
+        SKIE53HEr5LIZHPQX15hiAZb1m23EEtoiCZuBRo4v09ncZWJwbvRBGXAAVcnwd1HhjJHR+oKVbPIt2PU
+        kmloyRS0uzRSDzlcP1yg1l+BxjWC/54w9SRiitCwKoS8VFADVPVNIJN9FHYluv6Kwc1mNIjJEzmCw0Po
+        3Jc5w+PCySHfwI/b95wv4DmvmxSLRSj9Dvg0wnhWCjDuGVkP3Yi8lwxTgG+fFa2byN1ytRPGhGXGEuBY
+        My3HXB1kvgHbs88XdCh9DnhjhJHkp4AnIGtvVDjokQ5sH9H21i4G15tRv0wYvpQCbVsyZ+qWRA8mRQ9+
+        nuvXWl0gp9hngX/uDxF8cRm55nF1nir/FGAxdYYqlVE6dHeTwXvmyLU6S07+/g45KJQpvzUZmQAAAABJ
+        RU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem26.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
-        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
-        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
+        YQUAAAAJcEhZcwAACw4AAAsOAUC+4UEAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
+        CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
+        LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
+        SKIE53HEr5LIZHPQX15hiAZb1m23EEtoiCZuBRo4v09ncZWJwbvRBGXAAVcnwd1HhjJHR+oKVbPIt2PU
+        kmloyRS0uzRSDzlcP1yg1l+BxjWC/54w9SRiitCwKoS8VFADVPVNIJN9FHYluv6Kwc1mNIjJEzmCw0Po
+        3Jc5w+PCySHfwI/b95wv4DmvmxSLRSj9Dvg0wnhWCjDuGVkP3Yi8lwxTgG+fFa2byN1ytRPGhGXGEuBY
+        My3HXB1kvgHbs88XdCh9DnhjhJHkp4AnIGtvVDjokQ5sH9H21i4G15tRv0wYvpQCbVsyZ+qWRA8mRQ9+
+        nuvXWl0gp9hngX/uDxF8cRm55nF1nir/FGAxdYYqlVE6dHeTwXvmyLU6S07+/g45KJQpvzUZmQAAAABJ
+        RU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <metadata name="profileComponent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>651, 95</value>
+  </metadata>
+  <data name="profileComponent.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
-        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
-        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
-        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
-        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
-        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
-        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
-        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
-        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
-        RK5CYII=
+        YQUAAAAJcEhZcwAACw4AAAsOAUC+4UEAAAG4SURBVDhPjZNNLwNRFIbPohv/oVhVk8kkNl0RQiQkWEkk
+        CKmoIj42BLFjI5FGxI7/QCIsrLC20IU2Umm1PkZFW02FdjBpXvfM7fjKUIsn55w7c9/73nPvJQDEtLZ0
+        LQrwTxateebkkgB29g7wZhhl4UV+FfinA3uB4+CZ6eI3vq5s64AF/qKswMnpOZhgSGDlXJfysgLhSBzh
+        SKIE53HEr5LIZHPQX15hiAZb1m23EEtoiCZuBRo4v09ncZWJwbvRBGXAAVcnwd1HhjJHR+oKVbPIt2PU
+        kmloyRS0uzRSDzlcP1yg1l+BxjWC/54w9SRiitCwKoS8VFADVPVNIJN9FHYluv6Kwc1mNIjJEzmCw0Po
+        3Jc5w+PCySHfwI/b95wv4DmvmxSLRSj9Dvg0wnhWCjDuGVkP3Yi8lwxTgG+fFa2byN1ytRPGhGXGEuBY
+        My3HXB1kvgHbs88XdCh9DnhjhJHkp4AnIGtvVDjokQ5sH9H21i4G15tRv0wYvpQCbVsyZ+qWRA8mRQ9+
+        nuvXWl0gp9hngX/uDxF8cRm55nF1nir/FGAxdYYqlVE6dHeTwXvmyLU6S07+/g45KJQpvzUZmQAAAABJ
+        RU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem14.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         R0lGODlhEAAQAIMAAAAAAP///ydYF5fYTmBfDJlmAGYzALWEU8yZZtSmeP/jyP///wAAAAAAAAAAAAAA
         ACH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAALACwAAAAAEAAQAAAIcwAXCBxIcIGAgwUTGhQQAKHAAhAj
@@ -622,7 +769,7 @@
 </value>
   </data>
   <metadata name="mgLoadPackageComponent1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>389, 95</value>
+    <value>223, 134</value>
   </metadata>
   <data name="mgLoadPackageComponent1.Icon" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
@@ -632,64 +779,20 @@
         nSWTmjy4k2hPoE6bOoVKVCpRqj6tFo0604DXr2DBKhwrMCAAOw==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem15.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem13.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
-        tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
-        jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
-        T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
-        m+XGNsUKQli5ZJIMJC+xX3WUSWRl1tjD3qYvxcLhg+OZDKTP3OCKD275vCwePX55JhMwHkqFAA+vlnH8
-        /K2AGTPfUjm4xKhoOn1RwYyZbzs2b3Nq+wYl21WUGY+s/QEOPqTsVU0Bn7+6iK2HAAcEuesalrYKHsnF
-        m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem16.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
-        XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
-        4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem17.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
-        YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
-        me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
-        ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
-        aDsYQqupDZSvgXRz/cLK6hqOzuOIiSIKioLrTAZC/AKH7OViLXu/oJt7UIWu4aVyEI0hnEwhm8tBYYAT
-        8QrBxCUCD7QXieI5M1hTwZPqpwhfJnF6da1eTkqyCoimxBKFLhKg7mgAOkaMsIPEjaRepkg+lFOQ+UL5
-        GgD3jhfWv/kgypm/yvt1FZSvAUxPz3qaDUbI2Sxk5n45kTepdBpNhlZQfkkr+/oG/J7JKci3t8gVCiWS
-        WFdGx8bBDzhhbn+t9eCexvO88Ir12efbgsS8yOfzLErY2NiEocWI3t5+2O12uN3uypDZ+XkPgepZa6k7
-        FGlN+/SyXq+H1WqFy+WqDHnsp7mHWCwWOJ2PfM6/QMxm8/9VQXCqhDQzM4ffTfzkLal2r4sAAAAASUVO
-        RK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem18.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
-        QtRiKBaLSqyrkQnkgovCkBg4zFyYOYRAlIo9raSTtpMuhcC7ihfPuQGD2Yak8K4TxOAEoQc3OGQnkrI/
-        avJAkOmcepMV4CwBAn0x1J+u6fmyrvrMfRM8A0F+LX5enrMECExRUggQ3MqKhvMt4CwBgnv1oNFiR3X9
-        cdVn7pvgGQj48cbLFHCWAIG1bwrhP4LY3/gFpD/IGPp59QYAAAAASUVORK5CYII=
-</value>
-  </data>
-  <data name="mgInvokeComponentMenuItem4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPY2AAAifP4P+4MEieKAAy4Oev3ygYJAbSHJOc
         /K2itnX/lClz5PEaBtLw6MlLOIYZYGnvATY4Pq3gT0Nr72yshoAkcktq/99/+AyrARu37jkPksvMr/yP
         YQjIaSDTQQqAhqyHuQTmAnt/fwEnr5A1IG/ce/AM7BIU79Q0dh3fsmP//zUbdhx28gpeihywyM519Aye
-        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0jL6
+        D3LJlu37/oMMg8uBAglkclB48iUXl1B+mATMBTC+jXeUoH9owjmQWpAeuAHO3mFgfzt5hYJDHR/Q0tL6
         A1IL0gNXB9JIkQEwL4Cch+wFWFjAbHJzCxECefPeg6eoXiiva9+3def+/xu27r7g6BW8AtkLsBQKMSx0
         1frNu44AA/I/KODh6nqmzpMFRQ0ocEChC/TSQpBtMBeAEhHIIFAUw6IRpAclrBrb+mZlFVT9BynYuG3P
-        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4AEiVnFFMI
-        h08AAAAASUVORK5CYII=
+        eVDqgxkAS50gp2fkV/wHqcWZGkEuAWnAZgA4oKH5A2dMgZwG8gYsntHzB1GGYAtEbNkdpA4A8r5nBCK/
+        IMoAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem14.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIESURBVDhPnZPNSxtRFMX9T2ppN7axH2SjqaGpsU0TjJJi
@@ -704,7 +807,7 @@
         JC4A2evLqnFhjAkAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem7.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem15.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAH5SURBVDhPnZPLSxtRFMb9T2qpm7ZRW7KpqaHBaNMEU0kx
@@ -719,7 +822,7 @@
         AAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem24.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem16.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         R0lGODlhEAAQAIZvAISChAEBAXBJJai7zsfb8Nrn9M/a5Nnm81tgZNDh8sXa77jH16jR4+fu9dDh8brT
         7erv89jm8uzw9ODq9Ku0vNHh8mRrcvT3+aStttri6oOGiJqbncrc7oaKjZ+fn9Di6JSVl67C1a6yt5u2
@@ -752,7 +855,7 @@
         CBAjECxFAwuMLDDwZoAAAQpDI/RcsHToAaJTvwkIADs=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem17.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFqSURBVDhPpZPbTsJAEIZ5NaPxAXgI5UK50Qt9LmPSeBYQ
@@ -764,7 +867,7 @@
         AeYbqBNEyxii5RKJIWRF4qTG/VjWf3l5wX+/8w9/3Qe1qQ/dtwAAAABJRU5ErkJggg==
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem18.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGTSURBVDhPlVNNSwJRFPV/tQpaiW1qFrmKICIqKMmICjIw
@@ -777,7 +880,7 @@
         cDSCJAV+xk7WP7yJ9EN8DX7nAAAAAElFTkSuQmCC
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem9.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem19.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACcSURBVDhPY2BMZZzJmMb4nywM1MsA0rjxRDMcv//y7D8I
@@ -786,7 +889,7 @@
         2RkA39ChmP3112gAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem10.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem20.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEOSURBVDhPY2CgANjY2PwnWztI8+aOgP8Mbs5B/0EYZBIx
@@ -797,10 +900,10 @@
         0srGPRUAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem21.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAFoSURBVDhPpVNdKwRRGN47jZ/g57hQJGSzmxSTUv4DF26F
         tRa12JLaXVtKMimJ3ZKLsUyWbEImdsUwF37C4zwzTZ2z7a4pp956v57ned9zZiIRcbTJgy5NNzIduvGj
         jRtVbcKYY461UIeAWNpC2qxj/swG/U7dgAz2REhMgUYRJhaKNmZSOfR0R5GtfKA3YSokJIwLYvbR6HNq
         T4QEiyJJcGD520/0LfskNPrMsT6byiNTfgdX9gnEaKMbFgp3fkNgjGWTa4mSDQr7BGI/qvQnTezdqySM
@@ -809,18 +912,18 @@
         m4t4WHDwJU7vVHDy5GDXqoN+250b3/A/v/MvkqOAAMpRUaEAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem12.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem22.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAABjSURBVDhPY2AY+sDGxuY/Ob6A64MxiDUIQz1IgFwMdjlV
         XEBRGJCjGUXPxCC2VfVBbP/QMVD8PzZxmBhIH9ggkMD/Fyn/F5ea/SeFBumDG/D9FNt/UjDIIrgBFHuB
         4kAccAMAwje0sEjeZewAAAAASUVORK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem13.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem23.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAJcEhZcwAADsAAAA7AAWrWiQkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
+        YQUAAAAJcEhZcwAADrwAAA68AZW8ckkAAAHySURBVDhPnZPLSxtRFMb9T6rUTW3Ulmw0GhqMNk0wSqCO
         YhnNIkZUjCKUgvj4C7rSlUtXQksKRUHQxk0XhYpF8IETkpiHjxiT0TgTI0nm6z0DloxJbOmFj3Mf5/7u
         me8wVVVFY2hyasLmcPjr6l8o1TW1eKZrVGhN+8V5ZeedbznB1PEGS5+82No/xHd/QI1Ln71oNppgc3D+
         ipCuHk74uLCIH4EQdiIx/GLaDkfx8zii6ujsHIPDI6C8EsjY+w8TbRYbdo7D2D89Qzx9A+nuTp3vxk7+
@@ -832,7 +935,7 @@
         RK5CYII=
 </value>
   </data>
-  <data name="mgInvokeComponentMenuItem19.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+  <data name="toolStripMenuItem24.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
         YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC0SURBVDhPrZPLCsIwEEXzXeKyS/0bQUFxISiKK8EH/TXF
@@ -841,6 +944,9 @@
         cdVn7pvgGQj48cbLFHCWAIG1bwrhP4LY3/gFpD/IGPp59QYAAAAASUVORK5CYII=
 </value>
   </data>
+  <metadata name="mgLayerSelectionHandler1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>310, 212</value>
+  </metadata>
   <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>111</value>
   </metadata>

Modified: trunk/MgDev/Desktop/MapViewerTest/Program.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewerTest/Program.cs	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MapViewerTest/Program.cs	2012-05-13 04:07:19 UTC (rev 6646)
@@ -19,6 +19,8 @@
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
+            
+            //Must call MgPlatform.Initialize() before we can work with anything from the MapGuide API
             try
             {
                 var sw = new Stopwatch();
@@ -32,80 +34,36 @@
                 MessageBox.Show(ex.ToString(), "Error");
                 return;
             }
-            var fact = new MgServiceFactory();
-            var resSvc = (MgResourceService)fact.CreateService(MgServiceType.ResourceService);
+            
+            //MgAppWindow is our Main Window class full of drag-and-drop component goodness. Go ahead and
+            //take a look at MgAppWindow.cs source, not much code there except for the 3 generic invoke components and the
+            //single custom selection handler. Everything else is encapsulated by designer-friendly drag and drop components
+            //Most of the work is dragging and dropping components into the designer surface, and setting lots of properties
             var frm = new MgAppWindow();
+            
+            //We can initialize without specifying a map (allowing for components that do not 
+            //require a loaded map to still be used). You just have to call LoadMap() on the MgMapViewer
+            //instance when ready (not demonstrated here). So if you do load a package here, you will
+            //have to restart the application
+            MgResourceIdentifier resId = null;
             if (args.Length == 1)
             {
-                try
-                {
-                    var resId = new MgResourceIdentifier(args[0]);
-                    resId.Validate();                    
-                    if (!resSvc.ResourceExists(resId))
-                    {
-                        using (var open = new OpenFileDialog())
-                        {
-                            open.Filter = "*.mgp|*.mgp";
-                            if (open.ShowDialog() == DialogResult.OK)
-                            {
-                                var source = new MgByteSource(open.FileName);
-                                var br = source.GetReader();
-                                resSvc.ApplyResourcePackage(br);
-                            }
-                        }
-                    }
-
-                    if (resSvc.ResourceExists(resId))
-                    {
-                        frm.Load += (s, e) =>
-                        {
-                            LoadMap(frm, resId);
-                        };
-                    }
-                    else
-                    {
-                        MessageBox.Show("The specified Map Definition (" + resId.ToString() + ") does not exist");
-                        return;
-                    }
-                }
-                catch (MgException ex)
-                {
-                    ex.Dispose();
-                }
+                resId = new MgResourceIdentifier(args[0]);
+                resId.Validate();
             }
-            else
-            {
-                var diag = new ResourceIdDialog();
-                if (diag.ShowDialog() == DialogResult.OK)
-                {
-                    var resId = diag.ResourceID;
-                    if (resSvc.ResourceExists(resId))
-                    {
-                        frm.Load += (s, e) =>
-                        {
-                            LoadMap(frm, resId);
-                        };
-                    }
-                    else
-                    {
-                        MessageBox.Show("The specified Map Definition (" + resId.ToString() + ") does not exist");
-                        return;
-                    }
-                }
-            }
-            Application.ApplicationExit += new EventHandler(OnAppExit);
-            Application.Run(frm);
-        }
 
-        private static void LoadMap(MgAppWindow frm, MgResourceIdentifier mapId)
-        {
-            var map = new MgdMap(mapId);
             var fact = new MgServiceFactory();
+            var resSvc = (MgdResourceService)fact.CreateService(MgServiceType.ResourceService);
+            MgdMap map = null;
 
-            frm.LoadMap(
-                new MgDesktopMapViewerProvider(map,
-                    (MgdResourceService)fact.CreateService(MgServiceType.ResourceService),
-                    (MgRenderingService)fact.CreateService(MgServiceType.RenderingService)));
+            if (resId != null && resSvc.ResourceExists(resId))
+                map = new MgdMap(resId);
+
+            //This is just a pass-through call to MgMapViewer.Init()
+            frm.LoadMap(new MgDesktopMapViewerProvider(map));
+
+            Application.ApplicationExit += new EventHandler(OnAppExit);
+            Application.Run(frm);
         }
 
         static void OnAppExit(object sender, EventArgs e)

Modified: trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-05-13 04:07:19 UTC (rev 6646)
@@ -1156,6 +1156,78 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureDistribution.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\FeatureGeometricFunctions.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\Rendering\FeatureInfoRenderer.cpp"
 				>
 				<FileConfiguration
@@ -1192,6 +1264,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureNumericFunctions.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\FeatureReader.cpp"
 				>
 				<FileConfiguration
@@ -1408,6 +1516,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureStringFunctions.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\FeatureUtil.cpp"
 				>
 				<FileConfiguration
@@ -2384,6 +2528,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\ProxyDataReader.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\RasterHelper.cpp"
 				>
 				<FileConfiguration
@@ -3510,6 +3690,14 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\BooleanDataReaderCreator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\ByteDataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Resource\ByteSourceDwfInputStreamImpl.h"
 				>
 			</File>
@@ -3546,6 +3734,18 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\DataReaderCreator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\DateTimeDataReaderCreator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\DoubleDataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Drawing\DrawingDefs.h"
 				>
 			</File>
@@ -3606,10 +3806,22 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureDistribution.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\FeatureGeometricFunctions.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Rendering\FeatureInfoRenderer.h"
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureNumericFunctions.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\FeatureReader.h"
 				>
 			</File>
@@ -3634,10 +3846,22 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeatureStringFunctions.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\FeatureUtil.h"
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\FeautreNumericFunctions.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\GeometryDataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\GwsConnectionPool.h"
 				>
 			</File>
@@ -3654,6 +3878,18 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Int16DataReaderCreator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\Int32DataReaderCreator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Services\Feature\Int64DataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Exception\InvalidDwfPackageException.h"
 				>
 			</File>
@@ -3718,6 +3954,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\Matrix.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\MgCSTrans.h"
 				>
 			</File>
@@ -3762,6 +4002,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\ProxyDataReader.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\RasterHelper.h"
 				>
 			</File>
@@ -3834,6 +4078,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\SingleDataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Feature\SpatialContextCacheItem.h"
 				>
 			</File>
@@ -3842,6 +4090,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\StringDataReaderCreator.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Exception\StylizeLayerFailedException.h"
 				>
 			</File>
@@ -3870,6 +4122,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Feature\UniqueFunction.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Rendering\UnitType.h"
 				>
 			</File>

Modified: trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj	2012-05-13 04:07:19 UTC (rev 6646)
@@ -227,6 +227,36 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureDistribution.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureGeometricFunctions.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureNumericFunctions.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureStringFunctions.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\ProxyDataReader.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="Services\ProfilingService.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -747,6 +777,25 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Exception\AliasNotFoundException.h" />
+    <ClInclude Include="Services\Feature\BooleanDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\ByteDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\DataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\DateTimeDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\DoubleDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\FeatureDistribution.h" />
+    <ClInclude Include="Services\Feature\FeatureGeometricFunctions.h" />
+    <ClInclude Include="Services\Feature\FeatureNumericFunctions.h" />
+    <ClInclude Include="Services\Feature\FeatureStringFunctions.h" />
+    <ClInclude Include="Services\Feature\FeautreNumericFunctions.h" />
+    <ClInclude Include="Services\Feature\GeometryDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\Int16DataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\Int32DataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\Int64DataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\Matrix.h" />
+    <ClInclude Include="Services\Feature\ProxyDataReader.h" />
+    <ClInclude Include="Services\Feature\SingleDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\StringDataReaderCreator.h" />
+    <ClInclude Include="Services\Feature\UniqueFunction.h" />
     <ClInclude Include="Services\ProfilingService.h" />
     <ClInclude Include="Services\Resource\ByteSourceDwfInputStreamImpl.h" />
     <ClInclude Include="Services\ByteSourceRasterStreamImpl.h" />

Modified: trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters	2012-05-13 04:07:19 UTC (rev 6646)
@@ -279,6 +279,21 @@
     <ClCompile Include="System\TimerUtil.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureDistribution.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureGeometricFunctions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureNumericFunctions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\FeatureStringFunctions.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Services\Feature\ProxyDataReader.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Exception\AliasNotFoundException.h">
@@ -569,6 +584,63 @@
     <ClInclude Include="System\TimerUtil.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Services\Feature\BooleanDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\ByteDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\DataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\DateTimeDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\DoubleDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\FeatureDistribution.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\FeatureGeometricFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\FeatureNumericFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\FeatureStringFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\FeautreNumericFunctions.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\GeometryDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\Int16DataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\Int32DataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\Int64DataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\UniqueFunction.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\StringDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\SingleDataReaderCreator.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\ProxyDataReader.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Services\Feature\Matrix.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\braindump.txt" />

Modified: trunk/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -44,16 +44,21 @@
 #include "Services/Feature/FdoForcedOneToOneFeatureReader.cpp"
 #include "Services/Feature/FeatureClassCacheItem.cpp"
 #include "Services/Feature/FeatureConnection.cpp"
+#include "Services/Feature/FeatureDistribution.cpp"
+#include "Services/Feature/FeatureGeometricFunctions.cpp"
+#include "Services/Feature/FeatureNumericFunctions.cpp"
 #include "Services/Feature/FeatureSchemaCacheItem.cpp"
 #include "Services/Feature/FeatureServiceCacheEntry.cpp"
 #include "Services/Feature/FeatureServiceCache.cpp"
 #include "Services/Feature/FeatureSourceCacheItem.cpp"
+#include "Services/Feature/FeatureStringFunctions.cpp"
 #include "Services/Feature/FeatureUtil.cpp"
 #include "Services/Feature/GwsConnectionPool.cpp"
 #include "Services/Feature/GwsFeatureReader.cpp"
 #include "Services/Feature/JoinFeatureReader.cpp"
 #include "Services/Feature/MgCSTrans.cpp"
 #include "Services/Feature/ProjectedFeatureReader.cpp"
+#include "Services/Feature/ProxyDataReader.cpp"
 #include "Services/Feature/RasterHelper.cpp"
 #include "Services/Feature/RdbmsFeatureSourceParams.cpp"
 #include "Services/Feature/SpatialContextCacheItem.cpp"

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/BooleanDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/BooleanDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/BooleanDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/BooleanDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_BOOLEAN_DATA_READER_CREATOR_H
+#define MG_BOOLEAN_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgBooleanDataReaderCreator : public MgDataReaderCreator<INT16>
+{
+    DECLARE_CLASSNAME(MgBooleanDataReaderCreator)
+
+public:
+    MgBooleanDataReaderCreator()
+    {
+    }
+
+    MgBooleanDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Boolean;
+    }
+
+    ~MgBooleanDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(INT16 val)
+    {
+        return new MgBooleanProperty(m_propertyAlias, (bool)val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/ByteDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/ByteDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/ByteDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/ByteDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_BYTE_DATA_READER_CREATOR_H
+#define MG_BYTE_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgByteDataReaderCreator : public MgDataReaderCreator<INT8>
+{
+    DECLARE_CLASSNAME(MgByteDataReaderCreator)
+
+public:
+    MgByteDataReaderCreator()
+    {
+    }
+
+    MgByteDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Byte;
+    }
+
+    ~MgByteDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(INT8 val)
+    {
+        return new MgByteProperty(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/DataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/DataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/DataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/DataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,170 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_DATA_READER_CREATOR_H
+#define MG_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+#include "MgDesktop.h"
+#include "ProxyDataReader.h"
+
+template <typename T>
+class MgDataReaderCreator : public MgDisposable
+{
+public:
+
+    MgDataReader* Execute(const std::vector<double>& in)
+    {
+        // We convert to appropriate types here
+        std::vector<T> values;
+        ConvertVector(in, values);
+
+        // Use the converted vector
+        Ptr<MgPropertyDefinitionCollection> propDefCol = this->GetPropertyDefinitions();
+        Ptr<MgBatchPropertyCollection> bpCol = this->GetBatchCollection(values);
+        return new MgProxyDataReader(bpCol, propDefCol);
+    }
+
+    MgDataReader* Execute(const std::vector<INT64>& in)
+    {
+        // We convert to appropriate types here
+        std::vector<T> values;
+        ConvertVector(in, values);
+
+        // Use the converted vector
+        Ptr<MgPropertyDefinitionCollection> propDefCol = this->GetPropertyDefinitions();
+        Ptr<MgBatchPropertyCollection> bpCol = this->GetBatchCollection(values);
+        return new MgProxyDataReader(bpCol, propDefCol);
+    }
+
+    MgDataReader* Execute(const std::vector<STRING>& in)
+    {
+        Ptr<MgPropertyDefinitionCollection> propDefCol = this->GetPropertyDefinitions();
+        Ptr<MgBatchPropertyCollection> bpCol = this->GetBatchCollection(in);
+        return new MgProxyDataReader(bpCol, propDefCol);
+    }
+
+    MgDataReader* Execute(MgGeometryCollection* in)
+    {
+        Ptr<MgPropertyDefinitionCollection> propDefCol = this->GetPropertyDefinitions();
+        Ptr<MgBatchPropertyCollection> bpCol = this->GetBatchCollection(in);
+        return new MgProxyDataReader(bpCol, propDefCol);
+    }
+
+    MgPropertyDefinitionCollection* GetPropertyDefinitions()
+    {
+        // Create property definition for the type specified
+        Ptr<MgPropertyDefinition> propDef = new MgPropertyDefinition(m_propertyAlias, m_propType);
+
+        // Add to property definition collection
+        Ptr<MgPropertyDefinitionCollection> propDefCol = new MgPropertyDefinitionCollection();
+        propDefCol->Add(propDef);
+
+        return propDefCol.Detach();
+    }
+
+    MgBatchPropertyCollection* GetBatchCollection(MgGeometryCollection* in)
+    {
+        // Create collection of properties
+        Ptr<MgBatchPropertyCollection> bpCol = new MgBatchPropertyCollection();
+
+        if (in != NULL)
+        {
+            INT32 cnt = in->GetCount();
+            for (INT32 i=0; i < cnt; i++)
+            {
+                // Add one value as one Feature (PropertyCollection)
+                Ptr<MgGeometry> geom = in->GetItem(i);
+                Ptr<MgProperty> prop = this->GetProperty(geom);
+                Ptr<MgPropertyCollection> propCol = new MgPropertyCollection();
+                propCol->Add(prop);     // Feature defined
+                bpCol->Add(propCol);    //  Add to set of Batch Collection
+            }
+        }
+
+        return bpCol.Detach();
+    }
+
+    MgBatchPropertyCollection* GetBatchCollection(const std::vector<T>& in)
+    {
+        int cnt = (int)in.size();
+
+        // Create collection of properties
+        Ptr<MgBatchPropertyCollection> bpCol = new MgBatchPropertyCollection();
+        for (int i=0; i < cnt; i++)
+        {
+            // Add one value as one Feature (PropertyCollection)
+            Ptr<MgProperty> prop = this->GetProperty((T)in[i]);
+            Ptr<MgPropertyCollection> propCol = new MgPropertyCollection();
+            propCol->Add(prop);     // Feature defined
+            bpCol->Add(propCol);    //  Add to set of Batch Collection
+        }
+
+        return bpCol.Detach();
+    }
+
+    void ConvertVector(const std::vector<double>& in, std::vector<T>& values)
+    {
+        // There will always be only few values and therefore copy should be fine.
+        int cnt = (int)in.size();
+        for(int i = 0; i < cnt; i++)
+        {
+            values.push_back((T)in[i]);
+        }
+    }
+
+    void ConvertVector(const std::vector<INT64>& in, std::vector<T>& values)
+    {
+        // There will always be only few values and therefore copy should be fine.
+        int cnt = (int)in.size();
+        for(int i = 0; i < cnt; i++)
+        {
+            values.push_back((T)in[i]);
+        }
+    }
+
+    // The following GetProperty methods must be overridden by derived class
+    virtual MgProperty* GetProperty(double val)     {return NULL;}
+    virtual MgProperty* GetProperty(float val)      {return NULL;}
+    virtual MgProperty* GetProperty(INT8 val)      {return NULL;}
+    virtual MgProperty* GetProperty(INT16 val)      {return NULL;}
+    virtual MgProperty* GetProperty(INT32 val)      {return NULL;}
+    virtual MgProperty* GetProperty(INT64 val)      {return NULL;}
+    virtual MgProperty* GetProperty(CREFSTRING val) {return NULL;}
+    virtual MgProperty* GetProperty(MgGeometry* val) {return NULL;}
+
+protected:
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    MgDataReaderCreator()
+    {
+        m_propType = MgPropertyType::Null;
+    }
+    ~MgDataReaderCreator()
+    {
+    }
+
+    STRING m_propertyAlias;
+    int m_propType;
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/DateTimeDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/DateTimeDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/DateTimeDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/DateTimeDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,58 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_DATETIME_DATA_READER_CREATOR_H
+#define MG_DATETIME_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgDateTimeDataReaderCreator : public MgDataReaderCreator<double>
+{
+    DECLARE_CLASSNAME(MgDateTimeDataReaderCreator)
+
+public:
+    MgDateTimeDataReaderCreator()
+    {
+    }
+
+    MgDateTimeDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::DateTime;
+    }
+
+    ~MgDateTimeDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(double val)
+    {
+        Ptr<MgDateTime> dateTime = new MgDateTime(val);
+        return new MgDateTimeProperty(m_propertyAlias, dateTime);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/DoubleDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/DoubleDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/DoubleDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/DoubleDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_DOUBLE_DATA_READER_CREATOR_H
+#define MG_DOUBLE_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgDoubleDataReaderCreator : public MgDataReaderCreator<double>
+{
+    DECLARE_CLASSNAME(MgDoubleDataReaderCreator)
+
+public:
+    MgDoubleDataReaderCreator()
+    {
+    }
+
+    MgDoubleDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Double;
+    }
+
+    ~MgDoubleDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(double val)
+    {
+        return new MgDoubleProperty(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.cpp	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -215,3 +215,40 @@
         FDO_SAFE_ADDREF(m_fdoConn);
     m_bCloseConnection = false;
 }
+
+bool MgFeatureConnection::IsSupportedFunction(FdoFunction* fdoFunc)
+{
+	CHECKNULL(m_fdoConn, L"MgFeatureConnection.SupportsFunction");
+
+    FdoPtr<FdoIExpressionCapabilities> fec = m_fdoConn->GetExpressionCapabilities();
+    CHECKNULL((FdoIExpressionCapabilities*)fec, L"MgFeatureConnection.SupportsFunction");
+
+    bool supports = false;
+
+    FdoPtr<FdoFunctionDefinitionCollection> ffdc = fec->GetFunctions();
+    if (NULL != (FdoFunctionDefinitionCollection*)ffdc)
+    {
+        FdoInt32 funcCnt = ffdc->GetCount();
+        for (FdoInt32 i=0; i < funcCnt; i++)
+        {
+            FdoPtr<FdoFunctionDefinition> ffd = ffdc->GetItem(i);
+            CHECKNULL((FdoFunctionDefinition*)ffd, L"MgFeatureConnection.SupportsFunction");
+
+            // TODO: Just comparing name is enough?
+            // TODO: I think, NOT, because there can be overloaded functions like one function
+            // with multiple arguments, differnet datatypes etc.
+            //
+            // Comparing argument count is not sufficient because, there can be optional arguments
+            // as well. Therefore, we should just restrict to name comparision only
+            FdoString* funcNameAllowed = ffd->GetName();
+            FdoString* funcNameSupplied = fdoFunc->GetName();
+            size_t cmp = _wcsicmp(funcNameAllowed, funcNameSupplied);
+            if (cmp == 0)
+            {
+                supports = true;
+                break;
+            }
+        }
+    }
+    return supports;
+}
\ No newline at end of file

Modified: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.h	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureConnection.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -37,6 +37,7 @@
     bool SupportsSelectOrdering();
     FdoJoinType GetJoinTypes() const;
 
+	bool IsSupportedFunction(FdoFunction* function);
     void OwnReader();
 
 private:

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.cpp (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.cpp)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.cpp	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,103 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "FeatureDefs.h"
+#include "FeatureDistribution.h"
+#include "FeatureUtil.h"
+#include "math.h"
+#include "float.h"
+#include <algorithm>
+#include "Matrix.h"
+#include "UniqueFunction.h"
+//#include "DataReaderCreator.h"
+//#include "DoubleDataReaderCreator.h"
+//#include "StringDataReaderCreator.h"
+#include "FeatureNumericFunctions.h"
+#include "FeatureGeometricFunctions.h"
+#include "FeatureStringFunctions.h"
+
+MgFeatureDistribution::MgFeatureDistribution()
+{
+}
+
+MgFeatureDistribution::~MgFeatureDistribution()
+{
+}
+
+MgFeatureDistribution* MgFeatureDistribution::CreateDistributionFunction(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    STRING propName;
+    Ptr<MgFeatureDistribution> featDist;
+
+    INT32 propType;
+    if(1 == reader->GetPropertyCount())
+    {
+        propType = MgFeatureUtil::GetPropertyDefinition(reader, propName);
+    }
+    else
+    {
+        // Only get the property needed
+        FdoPtr<FdoExpressionCollection> exprCol = customFunction->GetArguments();
+        FdoInt32 cnt = exprCol->GetCount();
+        FdoPtr<FdoExpression> expr;
+        if(cnt == 1)
+        {
+            expr = exprCol->GetItem(0);
+            FdoIdentifier* propIdentifier = dynamic_cast<FdoIdentifier*>(expr.p);
+            CHECKNULL(propIdentifier, L"MgFeatureDistribution.CreateDistributionFunction");
+            propName = propIdentifier->GetName();
+            propType = reader->GetPropertyType(propName);
+        }
+        else
+        {
+            // Throw original exception
+            propType = MgFeatureUtil::GetPropertyDefinition(reader, propName);
+        }
+    }
+
+    switch(propType)
+    {
+        case MgPropertyType::DateTime:
+        case MgPropertyType::Double:
+        case MgPropertyType::Byte:
+        case MgPropertyType::Int16:
+        case MgPropertyType::Int32:
+        case MgPropertyType::Int64:
+        case MgPropertyType::Single:
+        case MgPropertyType::Boolean:
+        {
+            featDist = new MgFeatureNumericFunctions(reader, customFunction, propertyAlias);
+            break;
+        }
+        case MgPropertyType::String:
+        {
+            featDist = new MgFeatureStringFunctions(reader, customFunction, propertyAlias);
+            break;
+        }
+        case MgPropertyType::Geometry:
+        {
+            featDist = new MgFeatureGeometricFunctions(reader, customFunction, propertyAlias);
+            break;
+        }
+        default:
+        {
+            throw new MgInvalidPropertyTypeException(
+                L"MgFeatureDistribution.CreateDistributionFunction", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+    }
+    return featDist.Detach();
+}

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureDistribution.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,42 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _MGFEATUREDISTRIBUTION_H
+#define _MGFEATUREDISTRIBUTION_H
+
+class MgDisposable;
+class FdoFunction;
+class MgReader;
+
+class MgFeatureDistribution : public MgDisposable
+{
+public:
+
+    static MgFeatureDistribution* CreateDistributionFunction(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+    virtual MgReader* Execute() = 0;
+
+protected:
+
+    MgFeatureDistribution();
+    virtual ~MgFeatureDistribution();
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.cpp (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.cpp)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.cpp	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,300 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "FeatureDefs.h"
+#include "FeatureUtil.h"
+#include "FeatureDistribution.h"
+#include "FeatureGeometricFunctions.h"
+#include "DataReaderCreator.h"
+//#include "StringDataReaderCreator.h"
+#include "GeometryDataReaderCreator.h"
+#include <algorithm>
+#include "UniqueFunction.h"
+
+MgFeatureGeometricFunctions::MgFeatureGeometricFunctions()
+{
+    m_type = MgPropertyType::Null;
+    m_reader = NULL;
+    m_customFunction = NULL;
+    m_propertyAlias = L"";
+    m_extentsInitialized = false;
+}
+
+MgFeatureGeometricFunctions::MgFeatureGeometricFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    Initialize(reader, customFunction, propertyAlias); // Initialize the instance
+}
+
+void MgFeatureGeometricFunctions::Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    CHECKNULL((MgReader*)reader, L"MgFeatureGeometricFunctions.Initialize");
+    CHECKNULL((FdoFunction*)customFunction, L"MgFeatureGeometricFunctions.Initialize");
+
+    if(1 == reader->GetPropertyCount())
+    {
+        m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+    }
+    else
+    {
+        // Only get the property needed
+        FdoPtr<FdoExpressionCollection> exprCol = customFunction->GetArguments();
+        FdoInt32 cnt = exprCol->GetCount();
+        FdoPtr<FdoExpression> expr;
+        if(cnt == 1)
+        {
+            expr = exprCol->GetItem(0);
+            FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
+            CHECKNULL(propName, L"MgFeatureGeometricFunctions.Initialize");
+            m_propertyName = propName->GetName();
+            m_type = reader->GetPropertyType(m_propertyName);
+        }
+        else
+        {
+            // Throw original exception
+            m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+        }
+    }
+
+    // TODO: Should we really check this, may be we can ignore ??
+    // because we can only come to here if property type is numeric
+    if (!this->CheckSupportedPropertyType())
+	{
+		throw new MgInvalidPropertyTypeException(
+			L"MgFeatureGeometricFunctions.Initialize", __LINE__, __WFILE__, NULL, L"", NULL);
+	}
+
+    // We must have an property alias
+    // Though we can name a property with same name as function expression
+    // But Fdo forces to have an alias. Therefore we implement this restriction.
+    if (propertyAlias.empty())
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgMissingPropertyAlias");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgFeatureGeometricFunctions.Initialize", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    m_reader = SAFE_ADDREF(reader);
+    m_customFunction = FDO_SAFE_ADDREF(customFunction);
+    m_propertyAlias = propertyAlias;
+    m_extentsInitialized = false;
+}
+
+
+MgFeatureGeometricFunctions::~MgFeatureGeometricFunctions()
+{
+}
+
+// Execute the function
+MgReader* MgFeatureGeometricFunctions::Execute()
+{
+    CHECKNULL((MgReader*)m_reader, L"MgFeatureGeometricFunctions.Execute");
+    CHECKNULL(m_customFunction, L"MgFeatureGeometricFunctions.Execute");
+
+    Ptr<MgGeometryCollection> geomCol = new MgGeometryCollection();
+
+    MG_LOG_TRACE_ENTRY(L"MgFeatureGeometricFunctions::Execute");
+    while(m_reader->ReadNext())
+    {
+        // Get the geometry
+        Ptr<MgGeometry> val = GetValue();
+
+        // Get the envelope
+        Ptr<MgEnvelope> envl = val->Envelope();
+        Ptr<MgCoordinate> lcoord;
+        Ptr<MgCoordinate> rcoord;
+        if (envl != NULL)
+        {
+            lcoord = envl->GetLowerLeftCoordinate();
+            rcoord = envl->GetUpperRightCoordinate();
+        }
+
+        // Compare with min/max coordinates
+        ComputeExtents(lcoord, rcoord);
+    }
+
+    // Execute the operation on the collected extents
+    Ptr<MgGeometryCollection> finalResult = ExecuteOperation();
+
+    // Create FeatureReader from geometric values
+    return GetReader(finalResult);
+}
+
+void MgFeatureGeometricFunctions::ComputeExtents(MgCoordinate* lowerLeft,
+                                                    MgCoordinate* upperRight)
+{
+    CHECKNULL((MgCoordinate*)lowerLeft, L"MgFeatureGeometricFunctions.ComputeExtents");
+    CHECKNULL((MgCoordinate*)upperRight, L"MgFeatureGeometricFunctions.ComputeExtents");
+
+    if (!m_extentsInitialized)
+    {
+        m_minX = lowerLeft->GetX();
+        m_minY = lowerLeft->GetY();
+        m_minZ = lowerLeft->GetZ();
+        m_minM = lowerLeft->GetM();
+
+        m_maxX = upperRight->GetX();
+        m_maxY = upperRight->GetY();
+        m_maxZ = upperRight->GetZ();
+        m_maxM = upperRight->GetM();
+
+        m_extentsInitialized = true;
+    }
+    else
+    {
+        if (lowerLeft->GetX() < m_minX)
+            m_minX = lowerLeft->GetX();
+        if (lowerLeft->GetY() < m_minY)
+            m_minY = lowerLeft->GetY();
+        if (lowerLeft->GetZ() < m_minZ)
+            m_minZ = lowerLeft->GetZ();
+        if (lowerLeft->GetM() < m_minM)
+            m_minM = lowerLeft->GetM();
+
+        if (upperRight->GetX() > m_maxX)
+            m_maxX = upperRight->GetX();
+        if (upperRight->GetY() > m_maxY)
+            m_maxY = upperRight->GetY();
+        if (upperRight->GetZ() > m_maxZ)
+            m_maxZ = upperRight->GetZ();
+        if (upperRight->GetM() > m_maxM)
+            m_maxM = upperRight->GetM();
+    }
+}
+
+MgGeometryCollection* MgFeatureGeometricFunctions::ExecuteOperation()
+{
+    INT32 funcCode = -1;
+
+    Ptr<MgGeometryCollection> result;
+
+    // Get the arguments from the FdoFunction
+    STRING propertyName;
+    bool supported = MgFeatureUtil::FindCustomFunction(m_customFunction, funcCode);
+
+    if (supported)
+    {
+        switch(funcCode)
+        {
+            case EXTENT:
+            {
+                // Create the geometry collection for the extents
+                MgGeometryFactory factory;
+
+                // TODO: Assuming we are two dimensional for now.
+
+                //Ptr<MgCoordinate> coord1 = factory.CreateCoordinateXYZM(minX, minY, minZ, minM);
+                //Ptr<MgCoordinate> coord2 = factory.CreateCoordinateXYZM(maxX, maxY, maxZ, maxM);
+
+                Ptr<MgCoordinate> coord1 = factory.CreateCoordinateXY(m_minX, m_minY);
+                Ptr<MgCoordinate> coord2 = factory.CreateCoordinateXY(m_maxX, m_minY);
+                Ptr<MgCoordinate> coord3 = factory.CreateCoordinateXY(m_maxX, m_maxY);
+                Ptr<MgCoordinate> coord4 = factory.CreateCoordinateXY(m_minX, m_maxY);
+
+                Ptr<MgCoordinateCollection> coordCol = new MgCoordinateCollection();
+                coordCol->Add(coord1);
+                coordCol->Add(coord2);
+                coordCol->Add(coord3);
+                coordCol->Add(coord4);
+
+                Ptr<MgLinearRing> outerRing = factory.CreateLinearRing(coordCol);
+                Ptr<MgGeometry> geom = factory.CreatePolygon(outerRing, NULL);
+
+                result = new MgGeometryCollection();
+                result->Add(geom);
+
+                break;
+            }
+            default:
+            {
+                STRING message = MgFeatureUtil::GetMessage(L"MgCustomFunctionNotSupported");
+
+                MgStringCollection arguments;
+                arguments.Add(message);
+                throw new MgFeatureServiceException(
+                    L"MgFeatureGeometricFunctions.ExecuteOperation",
+                    __LINE__, __WFILE__, &arguments, L"", NULL);
+            }
+        }
+    }
+
+    return result.Detach();
+}
+
+// Check whether property type is a supported type
+bool MgFeatureGeometricFunctions::CheckSupportedPropertyType()
+{
+	return MgPropertyType::Geometry == m_type;
+}
+
+
+// Get the value of property
+MgGeometry* MgFeatureGeometricFunctions::GetValue()
+{
+    Ptr<MgGeometry> geom;
+
+    if (!m_reader->IsNull(m_propertyName))
+    {
+        switch(m_type)
+        {
+            case MgPropertyType::Geometry:
+            {
+                Ptr<MgByteReader> reader = m_reader->GetGeometry(m_propertyName);
+                if (reader != NULL)
+                {
+                    MgAgfReaderWriter agfReader;
+                    geom = agfReader.Read(reader);
+                }
+                break;
+            }
+            default:
+            {
+                throw new MgInvalidPropertyTypeException(
+                    L"MgFeatureGeometricFunctions.GetValue",
+                    __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+    }
+
+    return geom.Detach();
+}
+
+
+
+
+// Create the reader for string properties
+MgReader* MgFeatureGeometricFunctions::GetReader(MgGeometryCollection* geomCol)
+{
+    Ptr<MgDataReader> dataReader;
+
+    switch(m_type)
+    {
+        case MgPropertyType::Geometry:
+        {
+            Ptr<MgGeometryDataReaderCreator> drCreator = new MgGeometryDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(geomCol);
+            break;
+        }
+        default:
+        {
+            throw new MgInvalidPropertyTypeException(
+                L"MgFeatureGeometricFunctions.GetReader", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+    }
+    return dataReader.Detach();
+}

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureGeometricFunctions.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,91 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_FEATURE_GEOMETRIC_FUNCTIONS_H_
+#define MG_FEATURE_GEOMETRIC_FUNCTIONS_H_
+
+class MgDisposable;
+class FdoFunction;
+class MgReader;
+class MgFeatureDistribution;
+class MgGeometry;
+class MgGeometryCollection;
+
+class MgFeatureGeometricFunctions : public MgFeatureDistribution
+{
+    DECLARE_CLASSNAME(MgFeatureGeometricFunctions)
+
+public:
+
+    MgFeatureGeometricFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+    virtual MgReader* Execute();
+
+protected:
+
+    MgFeatureGeometricFunctions();
+    virtual ~MgFeatureGeometricFunctions();
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+private:
+
+    struct CoordinateCollection
+    {
+        std::vector<double> x_coords;
+        std::vector<double> y_coords;
+        std::vector<double> z_coords;
+        std::vector<double> m_coords;
+    };
+
+    MgGeometry* GetValue();
+
+    void Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+
+    void ComputeExtents(MgCoordinate* lowerLeft, MgCoordinate* upperRight);
+    MgGeometryCollection* ExecuteOperation();
+
+    MgReader* GetReader(MgGeometryCollection* returnGeom);
+
+	//WTF: The original method was void and threw MgInvalidPropertyTypeException if not supported
+	//MSVC 2008 blows up on the linker phase with a combination of C1001 at this method and LNK1000
+	//
+	//Changing this method to return bool (supported = true) and throwing MgInvalidPropertyTypeException in
+	//the method that calls this (Initialize()) makes the problem go away. Real WTF there!
+    bool CheckSupportedPropertyType();
+
+private:
+
+    STRING m_propertyName;
+    INT16 m_type;
+    Ptr<MgReader> m_reader;
+    FdoPtr<FdoFunction> m_customFunction;
+    STRING m_propertyAlias;
+
+    bool m_extentsInitialized;
+    double m_minX;
+    double m_minY;
+    double m_minZ;
+    double m_minM;
+    double m_maxX;
+    double m_maxY;
+    double m_maxZ;
+    double m_maxM;
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.cpp (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.cpp)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.cpp	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,1039 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "FeatureDefs.h"
+#include "FeatureUtil.h"
+#include "FeatureDistribution.h"
+#include "FeatureNumericFunctions.h"
+#include "math.h"
+#include "float.h"
+#include <algorithm>
+#include "Matrix.h"
+#include "UniqueFunction.h"
+#include "DataReaderCreator.h"
+#include "DoubleDataReaderCreator.h"
+#include "ByteDataReaderCreator.h"
+#include "Int16DataReaderCreator.h"
+#include "Int32DataReaderCreator.h"
+#include "Int64DataReaderCreator.h"
+#include "SingleDataReaderCreator.h"
+#include "StringDataReaderCreator.h"
+#include "DateTimeDataReaderCreator.h"
+#include "BooleanDataReaderCreator.h"
+
+MgFeatureNumericFunctions::MgFeatureNumericFunctions()
+{
+    m_type = MgPropertyType::Null;
+    m_reader = NULL;
+    m_customFunction = NULL;
+    m_propertyAlias = L"";
+}
+
+MgFeatureNumericFunctions::MgFeatureNumericFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    Initialize(reader, customFunction, propertyAlias); // Initialize the instance
+}
+
+void MgFeatureNumericFunctions::Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    CHECKNULL((MgReader*)reader, L"MgFeatureNumericFunctions.Initialize");
+    CHECKNULL((FdoFunction*)customFunction, L"MgFeatureNumericFunctions.Initialize");
+
+    if(1 == reader->GetPropertyCount())
+    {
+        m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+    }
+    else
+    {
+        // Only get the property needed
+        FdoPtr<FdoExpressionCollection> exprCol = customFunction->GetArguments();
+        FdoInt32 cnt = exprCol->GetCount();
+        FdoPtr<FdoExpression> expr;
+        if(cnt == 1)
+        {
+            expr = exprCol->GetItem(0);
+            FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
+            CHECKNULL(propName, L"MgFeatureNumericFunctions.Initialize");
+            m_propertyName = propName->GetName();
+            m_type = reader->GetPropertyType(m_propertyName);
+        }
+        else
+        {
+            // Throw original exception
+            m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+        }
+    }
+
+    // TODO: Should we really check this, may be we can ignore ??
+    // because we can only come to here if property type is numeric
+    this->CheckSupportedPropertyType();
+
+    // We must have an property alias
+    // Though we can name a property with same name as function expression
+    // But Fdo forces to have an alias. Therefore we implement this restriction.
+    if (propertyAlias.empty())
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgMissingPropertyAlias");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgFeatureDistribution.Initialize", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    m_reader = SAFE_ADDREF(reader);
+    m_customFunction = FDO_SAFE_ADDREF(customFunction);
+    m_propertyAlias = propertyAlias;
+}
+
+MgFeatureNumericFunctions::~MgFeatureNumericFunctions()
+{
+}
+
+MgReader* MgFeatureNumericFunctions::Execute()
+{
+    CHECKNULL((MgReader*)m_reader, L"MgFeatureNumericFunctions.Execute");
+    CHECKNULL(m_customFunction, L"MgFeatureNumericFunctions.Execute");
+
+    Ptr<MgReader> reader;
+    MG_LOG_TRACE_ENTRY(L"MgFeatureNumericFunctions::Execute");
+    // TODO: Can this be optimized to process them as they are read?
+    // TODO: Should we put a limit on double buffer
+    INT32 funcCode = -1;
+    bool supported = MgFeatureUtil::FindCustomFunction(m_customFunction, funcCode);
+    if (supported)
+    {
+        // In case we have int64 but is a custom function use double to evaluate it.
+        // Since we don't have a type which can make operations with big numbers we will fix only Unique/Min/Max functions
+        // Even if we treat int64 different from double we don't solve the issue with truncation error.
+        // If we emulate SUM adding two big numbers we will get overflow even we use int64, e.g.:
+        // Int64 val1 = 9223372036854775806;
+        // Int64 val2 = 9223372036854775807;
+        // Int64 sum = val1 + val2; // the sum value will be -3 so is overflow error
+        // In the future we will need to implement a type which can handle int64 numbers without getting overflow a sum/avg is calculated.
+        // Since all other functions calculate a sum we will use double, at least to be able to get the right result for small numbers.
+        if (!(m_type == MgPropertyType::Int64 && (funcCode == MINIMUM || funcCode == MAXIMUM || funcCode == UNIQUE)))
+        {
+            VECTOR values, distValues;
+            while(m_reader->ReadNext())
+            {
+                // TODO: Add support for Geometry extents
+                double val = GetValue();
+                values.push_back(val);
+            }
+            // Calulate the distribution on the collected values
+            CalculateDistribution(values, distValues);
+
+            // Create FeatureReader from distribution values
+            reader = GetReader(distValues);
+        }
+        else
+        {
+            VECTOR_INT64 values, distValues;
+            while(m_reader->ReadNext())
+            {
+                INT64 int64Val = 0;
+                if (!m_reader->IsNull(m_propertyName))
+                    int64Val = m_reader->GetInt64(m_propertyName);
+                values.push_back(int64Val);
+            }
+
+            // Calulate the distribution on the collected values
+            CalculateDistribution(values, distValues);
+
+            // Create FeatureReader from distribution values
+            Ptr<MgInt64DataReaderCreator> drCreator = new MgInt64DataReaderCreator(m_propertyAlias);
+            reader = drCreator->Execute(distValues);
+        }
+    }
+    else
+    {
+        // just return an emty reader
+        VECTOR distValues;
+        reader = GetReader(distValues);
+    }
+
+    return reader.Detach();
+}
+
+// Check whether property type is a supported type
+void MgFeatureNumericFunctions::CheckSupportedPropertyType()
+{
+    bool supported = false;
+    switch(m_type)
+    {
+        case MgPropertyType::DateTime:
+        case MgPropertyType::Double:
+        case MgPropertyType::Byte:
+        case MgPropertyType::Int16:
+        case MgPropertyType::Int32:
+        case MgPropertyType::Int64:
+        case MgPropertyType::Single:
+        case MgPropertyType::Boolean:
+        {
+            supported = true;
+            break;
+        }
+        default:
+        {
+            throw new MgInvalidPropertyTypeException(L"MgFeatureNumericFunctions.CheckSupportedPropertyType",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+    }
+    return;
+}
+
+// Get the value of property
+double MgFeatureNumericFunctions::GetValue()
+{
+    double val = 0;
+
+    if (!m_reader->IsNull(m_propertyName))
+    {
+        switch(m_type)
+        {
+            case MgPropertyType::Double:
+            {
+                val = (double)m_reader->GetDouble(m_propertyName);
+                break;
+            }
+            case MgPropertyType::Byte:
+            {
+                val = (double)m_reader->GetByte(m_propertyName);
+                break;
+            }
+            case MgPropertyType::Int16:
+            {
+                val = (double)m_reader->GetInt16(m_propertyName);
+                break;
+            }
+            case MgPropertyType::Int32:
+            {
+                val = (double)m_reader->GetInt32(m_propertyName);
+                break;
+            }
+            case MgPropertyType::Int64:
+            {
+                val = (double)m_reader->GetInt64(m_propertyName);
+                break;
+            }
+            case MgPropertyType::Single:
+            {
+                val = (double)m_reader->GetSingle(m_propertyName);
+                break;
+            }
+            case MgPropertyType::DateTime:
+            {
+                Ptr<MgDateTime> dateTime = m_reader->GetDateTime(m_propertyName);
+                val = dateTime->ToNumber();
+                break;
+            }
+            case MgPropertyType::Boolean:
+            {
+                val = (double)m_reader->GetBoolean(m_propertyName);
+                break;
+            }
+            default:
+            {
+                throw new MgInvalidPropertyTypeException(L"MgFeatureNumericFunctions.CheckSupportedPropertyType",
+                    __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+    }
+    return val;
+}
+
+// Calculate equal categories
+void MgFeatureNumericFunctions::GetEqualCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues)
+{
+    // Expected categories should be more than zero
+    if (numCats <= 0)
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgInvalidComputedProperty");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgServerSelectFeatures.GetEqualCategories", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    // find the range of the data values
+    double min = DoubleMaxValue;
+    double max = -DoubleMaxValue;
+
+    int cnt = (int)values.size();
+    if (cnt <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+    for (int i=0; i < cnt; i++)
+    {
+        double val = values[i];
+
+        if (val > max)
+            max = val;
+        if (val < min)
+            min = val;
+    }
+
+    // expand the range a little to account for numerical instability
+    double delta = 0.0001 * (max - min);
+    min -= delta;
+    max += delta;
+    // but don't let the values extend beyond the data min/max
+    if (min < dataMin)
+        min = dataMin;
+    if (max > dataMax)
+        max = dataMax;
+
+    // This method ignores dataMin and dataMax.  A different "Equal" distribution
+    // might ignore the actual data values and create categories based on dataMin
+    // and dataMax when those values are not +/- infinity.
+
+    // fill in the categories
+    distValues.push_back(min);
+    delta = (max - min) / (double)numCats;
+    for (int i=1; i<numCats; i++)
+    {
+        double nextval = distValues[i-1] + delta;
+        distValues.push_back(nextval);
+    }
+    distValues.push_back(max);
+}
+
+
+void MgFeatureNumericFunctions::GetMinimum(VECTOR &values, VECTOR &distValues)
+{
+    // TODO: Change this algorithm to take reader directly instead of vector
+
+    // find the range of the data values
+    distValues.push_back(MgFeatureUtil::Minimum(values));
+}
+
+
+void MgFeatureNumericFunctions::GetMinimum(VECTOR_INT64 &values, VECTOR_INT64 &distValues)
+{
+    // TODO: Change this algorithm to take reader directly instead of vector
+
+    // find the range of the data values
+    distValues.push_back(MgFeatureUtil::Minimum(values));
+}
+
+
+void MgFeatureNumericFunctions::GetMaximum(VECTOR &values, VECTOR &distValues)
+{
+    // TODO: Change this algorithm to take reader directly instead of vector
+
+    // find the range of the data values
+    distValues.push_back(MgFeatureUtil::Maximum(values));
+}
+
+
+void MgFeatureNumericFunctions::GetMaximum(VECTOR_INT64 &values, VECTOR_INT64 &distValues)
+{
+    // TODO: Change this algorithm to take reader directly instead of vector
+
+    // find the range of the data values
+    distValues.push_back(MgFeatureUtil::Maximum(values));
+}
+
+
+void MgFeatureNumericFunctions::CalculateDistribution(VECTOR& values, VECTOR& distValues)
+{
+    STRING funcName;
+    int numCats;
+    double dataMin, dataMax;
+    INT32 funcCode = -1;
+
+    // Get the arguments from the FdoFunction
+    STRING propertyName;
+    bool supported = MgFeatureUtil::FindCustomFunction(m_customFunction, funcCode);
+
+    if (supported)
+    {
+        switch(funcCode)
+        {
+            case EQUAL_CATEGORY: // Equal Category
+            {
+                MgFeatureUtil::GetArguments(m_customFunction, propertyName, numCats, dataMin, dataMax, m_type);
+                GetEqualCategories(values, numCats, dataMin, dataMax, distValues);
+                break;
+            }
+            case STDEV_CATEGORY: // StdDev Category
+            {
+                MgFeatureUtil::GetArguments(m_customFunction, propertyName, numCats, dataMin, dataMax, m_type);
+                GetStandardDeviationCategories(values, numCats, dataMin, dataMax, distValues);
+                break;
+            }
+            case QUANTILE_CATEGORY: // Quantile Category
+            {
+                MgFeatureUtil::GetArguments(m_customFunction, propertyName, numCats, dataMin, dataMax, m_type);
+                GetQuantileCategories(values, numCats, dataMin, dataMax, distValues);
+                break;
+            }
+            case JENK_CATEGORY: // Jenk Category
+            {
+                MgFeatureUtil::GetArguments(m_customFunction, propertyName, numCats, dataMin, dataMax, m_type);
+                GetJenksCategories(values, numCats, dataMin, dataMax, distValues);
+                break;
+            }
+            case MINIMUM:
+            {
+                GetMinimum(values,distValues);
+                break;
+            }
+            case MAXIMUM:
+            {
+                GetMaximum(values,distValues);
+                break;
+            }
+            case MEAN:
+            {
+                GetMeanValue(values,distValues);
+                break;
+            }
+            case STANDARD_DEV:
+            {
+                GetStandardDeviation(values,distValues);
+                break;
+            }
+            case UNIQUE:
+            {
+                MgUniqueFunction<double>::Execute(values, distValues);
+                break;
+            }
+        }
+    }
+}
+
+void MgFeatureNumericFunctions::CalculateDistribution(VECTOR_INT64& values, VECTOR_INT64& distValues)
+{
+    INT32 funcCode = -1;
+    // Get the arguments from the FdoFunction
+    bool supported = MgFeatureUtil::FindCustomFunction(m_customFunction, funcCode);
+
+    if (supported)
+    {
+        switch(funcCode)
+        {
+            case MINIMUM:
+            {
+                GetMinimum(values, distValues);
+                break;
+            }
+            case MAXIMUM:
+            {
+                GetMaximum(values, distValues);
+                break;
+            }
+            case UNIQUE:
+            {
+                MgUniqueFunction<INT64>::Execute(values, distValues);
+                break;
+            }
+        }
+    }
+}
+
+MgReader* MgFeatureNumericFunctions::GetReader(VECTOR& distValues)
+{
+    Ptr<MgDataReader> dataReader;
+
+    switch(m_type)
+    {
+        case MgPropertyType::Double:
+        {
+            Ptr<MgDoubleDataReaderCreator> drCreator = new MgDoubleDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Byte:
+        {
+            Ptr<MgByteDataReaderCreator> drCreator = new MgByteDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Int16:
+        {
+            Ptr<MgInt16DataReaderCreator> drCreator = new MgInt16DataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Int32:
+        {
+            Ptr<MgInt32DataReaderCreator> drCreator = new MgInt32DataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Int64:
+        {
+            Ptr<MgInt64DataReaderCreator> drCreator = new MgInt64DataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Single:
+        {
+            Ptr<MgSingleDataReaderCreator> drCreator = new MgSingleDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::DateTime:
+        {
+            Ptr<MgDateTimeDataReaderCreator> drCreator = new MgDateTimeDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        case MgPropertyType::Boolean:
+        {
+            Ptr<MgBooleanDataReaderCreator> drCreator = new MgBooleanDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        default:
+        {
+            throw new MgInvalidPropertyTypeException(L"MgFeatureNumericFunctions.CheckSupportedPropertyType",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+    }
+    return dataReader.Detach();
+}
+
+//MgDataReader* MgFeatureNumericFunctions::GetStringReader(std::vector<STRING>& distValues)
+//{
+//    MgDoubleDataReaderCreator* drCreator = new MgDoubleDataReaderCreator(m_propertyAlias);
+//    Ptr<MgDataReader> dataReader = drCreator->Execute(distValues);
+//    delete drCreator;
+//
+//    return dataReader.Detach();
+//}
+
+// Calculate Standard Deviation for the values
+void MgFeatureNumericFunctions::GetStandardDeviationCategories( VECTOR &values, int numCats,
+                                                                double dataMin, double dataMax,
+                                                                VECTOR &distValues)
+{
+    // Expected categories should be more than zero
+    if (numCats <= 0)
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgInvalidComputedProperty");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgServerSelectFeatures.GetEqualCategories", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    // collect information about the data values
+    double min = DoubleMaxValue;
+    double max = -DoubleMaxValue;
+    double mean = 0;
+
+    int cnt = (int)values.size();
+    if (cnt <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+    for (int i=0; i < cnt; i++)
+    {
+        double val = values[i];
+
+        if (val > max)
+            max = val;
+        if (val < min)
+            min = val;
+        mean += val;
+    }
+
+    // expand min and max a little to account for numerical instability
+    double delta = 0.0001 * (max - min);
+    min -= delta;
+    max += delta;
+
+    // compute the mean, variance and standard deviation
+    double count = (double)cnt;  // (guaranteed to be > 0)
+    mean /= count;
+    double variance = 0;
+
+    for (int i=0; i < cnt; i++)
+    {
+        double val = values[i];
+        variance += (val - mean) * (val - mean);
+    }
+
+    double deviation = sqrt(variance / count);
+
+    // fill in the middle category/categories
+    double* cats = new double[numCats+1];
+    int midCat, highMidCat;
+    if (numCats % 2 == 0)
+    {
+        midCat = numCats / 2;
+        highMidCat = midCat;
+        cats[midCat] = mean;
+    }
+    else
+    {
+        midCat = (numCats - 1) / 2;
+        highMidCat = midCat + 1;
+        cats[midCat] = mean - 0.5 * deviation;
+        cats[highMidCat] = mean + 0.5 * deviation;
+    }
+
+    // fill in the other categories
+    for (int i=midCat-1; i>=0; i--)
+        cats[i] = cats[i+1] - deviation;
+
+    for (int i=highMidCat; i<=numCats; i++)
+        cats[i] = cats[i-1] + deviation;
+
+    // if the data method specifies strict a strict min and/or max, use them
+    if (!IsInf(dataMin) && !IsNan(dataMin) && (dataMin != -DoubleMaxValue))
+        min = dataMin;
+    if (!IsInf(dataMax) && !IsNan(dataMax) && (dataMax != DoubleMaxValue))
+        max = dataMax;
+
+    // flatten/clip any categories that extend beyond the min/max range
+    for (int i=0; i<=numCats; i++)
+    {
+        if (cats[i] < min)
+            cats[i] = min;
+        else if (cats[i] > max)
+            cats[i] = max;
+    }
+
+    for (int kk = 0; kk < numCats+1; kk++)
+    {
+        distValues.push_back(cats[kk]);
+    }
+
+    delete[] cats; // Delete the memory allocated before
+}
+
+
+// Calculate Quantile Distribution for the values
+void MgFeatureNumericFunctions::GetQuantileCategories(  VECTOR &values, int numCats,
+                                                    double dataMin, double dataMax,
+                                                    VECTOR &distValues )
+{
+    // Expected categories should be more than zero
+    if (numCats <= 0)
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgInvalidComputedProperty");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgServerSelectFeatures.GetEqualCategories", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    int count = (int)values.size();
+    if (count <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+    // Sort the data values in ascending order
+    std::sort(values.begin(), values.end());
+
+    // How many go into each full bucket?
+
+    int perBucket = ROUND((double)count/(double)numCats);
+    if (perBucket * numCats > count)
+        perBucket--;
+
+    // How many buckets are full, and how many are missing one?
+    int nearlyFullBuckets = numCats - (count - perBucket * numCats);
+    int fullBuckets = numCats - nearlyFullBuckets;
+
+    // expand min and max a little to account for numerical instability
+    double delta = 0.0001 * (values[count-1] - values[0]);
+    double* categories = new double[numCats+1];
+
+    // the first and last categories are limited by the data method limits
+    categories[0] = values[0] - delta;
+    if (categories[0] < dataMin)
+        categories[0] = dataMin;
+
+    categories[numCats] = values[count-1] + delta;
+    if (categories[numCats] > dataMax)
+        categories[numCats] = dataMax;
+
+    // Mix full and nearly-full buckets to fill in the categories between the ends.
+    int indexOfLast = -1;
+    for ( int i = 1; i<numCats; i++)
+    {
+        bool doingSmallBucket = (nearlyFullBuckets > fullBuckets);
+        // find the index of the last element we want in this bucket
+        indexOfLast += (doingSmallBucket ? perBucket : perBucket + 1);
+        // make category value be halfway between that element and the next
+        categories[i] = 0.5 * (values[indexOfLast] + values[indexOfLast+1]);
+
+        // Decrement count of correct bucket type.
+        if (doingSmallBucket)
+            nearlyFullBuckets--;
+        else
+            fullBuckets--;
+    }
+
+    for (int kk = 0; kk < numCats+1; kk++)
+    {
+        distValues.push_back(categories[kk]);
+    }
+
+    delete[] categories; // Delete the memory allocated before
+}
+
+
+bool MgFeatureNumericFunctions::IsInf(double x)
+{
+    bool isInfinity = false;
+#ifdef _WIN32
+    int code = _fpclass(x);
+    if ((code == _FPCLASS_NINF) || (code == _FPCLASS_PINF))
+    {
+        isInfinity = true;
+    }
+#else
+    isInfinity = isinf(x);
+#endif
+
+    return isInfinity;
+}
+
+bool MgFeatureNumericFunctions::IsNan(double x)
+{
+    bool isNan = false;
+#ifdef _WIN32
+    isNan = _isnan(x);
+#else
+    isNan = isnan(x);
+#endif
+    return isNan;
+}
+
+// Calculate Standard Deviation for the values
+void MgFeatureNumericFunctions::GetStandardDeviation(VECTOR &values, VECTOR &distValues)
+{
+    double mean = 0;
+
+    int cnt = (int)values.size();
+    if (cnt <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+    double min = DoubleMaxValue;
+    double max = -DoubleMaxValue;
+
+    for (int i=0; i < cnt; i++)
+    {
+        double val = values[i];
+
+        if (val > max)
+            max = val;
+
+        if (val < min)
+            min = val;
+
+        mean += val;
+    }
+
+    // expand min and max a little to account for numerical instability
+    double delta = 0.0001 * (max - min);
+    min -= delta;
+    max += delta;
+
+    // compute the mean, variance and standard deviation
+    double count = (double)cnt;  // (guaranteed to be > 0)
+    mean /= count;
+    double variance = 0;
+
+    for (int i=0; i < cnt; i++)
+    {
+        variance += (values[i] - mean) * (values[i] - mean);
+    }
+
+    double deviation = sqrt((double)(variance / count));
+
+    // Set the base date as min date
+    if (m_type == MgPropertyType::DateTime)
+    {
+        deviation += min;
+    }
+
+    distValues.push_back(deviation);
+
+    return;
+}
+
+// Calculate average
+void MgFeatureNumericFunctions::GetMeanValue(VECTOR &values, VECTOR &distValues)
+{
+    double mean = 0;
+
+    int cnt = (int)values.size();
+    if (cnt <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+    for (int i=0; i < cnt; i++)
+    {
+        double val = values[i];
+        mean += val;
+    }
+
+    // compute the mean, variance and standard deviation
+    double count = (double)cnt;  // (guaranteed to be > 0)
+    mean /= count;
+
+    distValues.push_back(mean);
+
+    return;
+}
+
+// Calculate average
+void MgFeatureNumericFunctions::GetUniqueValue(VECTOR &values, VECTOR &distValues)
+{
+    MgUniqueFunction<double>::Execute(values, distValues);
+}
+
+void MgFeatureNumericFunctions::GetUniqueValue(VECTOR_INT64 &values, VECTOR_INT64 &distValues)
+{
+    MgUniqueFunction<INT64>::Execute(values, distValues);
+}
+
+//-------------------------------------------------------------------------
+// Jenks' Optimization Method
+//
+//-------------------------------------------------------------------------
+void MgFeatureNumericFunctions::GetJenksCategories(  VECTOR &inputData, int numPartsRequested,
+                                                 double dataMin, double dataMax,
+                                                 VECTOR &distValues )
+{
+    // numPartsRequested // 2 - 10; 5 is good
+    int i = 0;  // index for numObservations (may be very large)
+    int j = 0;  // index for numPartsRequested (about 4-8)
+    int k = 0;
+
+    // Sort the data values in ascending order
+    std::sort(inputData.begin(), inputData.end());
+
+    int numObservations = (int)inputData.size();  // may be very large
+    // Possible improvement: Rework the code to use normal 0 based arrays.
+    // Actually it doesn't matter much since we have to create two
+    // matrices that themselves use more memory than the local copy
+    // of inputData.
+    //
+    // In order to ease the use of original FORTRAN and the later BASIC
+    // code, I will use 1 origin arrays and copy the inputData into
+    // a local array;
+    // I'll dimension the arrays one larger than necessary and use the
+    // index values from the original code.
+    //
+    // The algorithm must calculate with floating point values.
+    // If more optimization is attempted in the future, be aware of
+    // problems with calculations using mixed numeric types.
+
+    std::vector<double> data;
+    data.push_back(0);  // dummy value at index 0
+    std::copy(inputData.begin(), inputData.end(), std::back_inserter(data));
+    // copy from parameter inputData so that data index starts from 1
+
+    // Note that the Matrix constructors initialize all values to 0.
+    // mat1 contains integer values used for indices into data
+    // mat2 contains floating point values of data and bigNum
+    MgMatrix<int>     mat1(numObservations + 1, numPartsRequested + 1);
+    MgMatrix<double>  mat2(numObservations + 1, numPartsRequested + 1);
+
+//  const double bigNum = 1e+14; // from original BASIC code;
+//  const double bigNum = std::numeric_limits<double>::max();
+    const double bigNum = DBL_MAX;   // compiler's float.h
+
+    for (i = 1; i <= numPartsRequested; ++i)
+    {
+        mat1.Set(1, i, 1);
+        for (j = 2; j <= numObservations; ++j)
+        {
+            mat2.Set(j, i, bigNum);
+        }
+    }
+
+    std::vector<int> classBounds;
+    classBounds.push_back(-2);  // dummy value
+    for (i = 1; i <= numPartsRequested; ++i)
+    {
+        classBounds.push_back(-1);
+    }
+
+    for (int L = 2; L <= numObservations; ++L)
+    {
+        double s1 = 0;
+        double s2 = 0;
+        double v = 0;
+        int w = 0;
+
+        for (int m = 1; m <= L; ++m)
+        {
+            int i3 = L - m + 1;
+            double val = data[i3];
+            s2 += (double(val) * double(val));
+            // if datatype of val is ever allowed to be same as template
+            // parameter T, make sure multiplication is done in double.
+            s1 += val;
+            ++w;
+            v = s2 - ((s1 * s1) / w);
+            int i4 = i3 - 1;
+
+            if (i4 > 0)
+            {
+                for (j = 2; j <= numPartsRequested; ++j)
+                {
+                    double tempnum = v + mat2.Get(i4, j - 1);
+                    if (double(mat2.Get(L, j)) >= tempnum)
+                    {
+                        mat1.Set(L, j, i3);
+                        mat2.Set(L, j, tempnum);
+                    }
+                }
+            }
+        }
+
+        mat1.Set(L, 1, 1);
+        mat2.Set(L, 1, v);
+    }
+
+    k = numObservations;
+    for (j = numPartsRequested; j >= 1; --j)
+    {
+        if (k >= 0 && k <= numObservations)
+        {
+            classBounds[j] = mat1.Get(k, j);
+            k = mat1.Get(k, j) - 1;
+        }
+    }
+
+    std::vector<int> indices;
+
+    indices.push_back(0);
+    for (i = 2; i <= numPartsRequested; ++i)
+    {
+        int index = classBounds[i] - 1;
+        if (index > indices.back())
+        {
+            indices.push_back(index);
+        }
+    }
+
+    FixGroups(inputData, indices);
+
+    double val = 0.0;
+    int index = 0;
+    int totIndex = (int)indices.size();
+
+    for (int i = 1; i < totIndex; ++i)
+    {
+        index = indices[i] - 1;
+
+        val = inputData[index];
+        distValues.push_back(val);
+    }
+
+    index = numObservations - 1;
+    val = inputData[index];
+    distValues.push_back(val);
+
+    int retCnt = (int)distValues.size();
+    int inCnt = (int)inputData.size();
+
+    if (retCnt > 0 && inCnt > 0)
+    {
+        if (!doubles_equal(distValues[0],inputData[0]))
+        {
+            distValues.insert(distValues.begin(), inputData[0]);
+        }
+    }
+
+    return;
+}
+
+//-----------------------------------------------------------------------------
+// FixGroups
+// If the algorithm generated empty groups, then adjust the number of groups
+// and the indices.
+// Return true if adjustments we made;
+// Return false if no changes were made.
+bool MgFeatureNumericFunctions::FixGroups(const std::vector<double>& data, std::vector<int>& indices)
+{
+    bool changed1 = FixDuplicateIndices(indices);
+    bool changed2 = FixIndicesByValue(data, indices);
+
+    return changed1 || changed2;
+}
+
+
+//-----------------------------------------------------------------------------
+bool MgFeatureNumericFunctions::FixDuplicateIndices(std::vector<int>& indices)
+{
+    if (indices.size() <= 1)
+    {
+        return false;
+    }
+
+    // We will create a new vector of indices that is possibly adjusted,
+    // then replace the original vector with the new.  Since these vectors
+    // have typically less than 10 entries, we won't deal with making the
+    // adjustments in place.
+    std::vector<int> newIndices;
+
+    newIndices.push_back(indices[0]);
+
+    for (unsigned int i = 1; i < indices.size(); ++i)
+    {
+        if (indices[i] != indices[i - 1])
+            newIndices.push_back(indices[i]);
+    }
+
+    bool changed = (newIndices.size() != indices.size());
+    indices.clear();
+    indices = newIndices;
+
+    return changed;
+}
+
+
+//-----------------------------------------------------------------------------
+// Examine the values specified by the indices.  If any of the values
+// are identical, then toss out the higher index.
+bool MgFeatureNumericFunctions::FixIndicesByValue(const std::vector<double>& data, std::vector<int>& indices)
+{
+    if (indices.size() <= 1)
+    {
+        return false;
+    }
+
+    // We will create a new vector of indices that is possibly adjusted,
+    // then replace the original vector with the new.  Since these vectors
+    // have typically less than 10 entries, we won't deal with making the
+    // adjustments in place.
+    std::vector<int> newIndices;
+
+    newIndices.push_back(indices[0]);
+
+    for (unsigned int i = 1; i < indices.size(); ++i)
+    {
+        if ( ! doubles_equal(data[indices[i]], data[indices[i - 1]]) )
+            newIndices.push_back(indices[i]);
+    }
+
+    bool changed = (newIndices.size() != indices.size());
+    indices.clear();
+    indices = newIndices;
+
+    return changed;
+}
+
+bool MgFeatureNumericFunctions::doubles_equal(double d1, double d2)
+{
+    // We are doing our comparisons with a specific precision.
+    const double epsilon = 1.0e-12;  // very small
+    double d = fabs(d2 - d1);
+    return (d < epsilon);  // absolute value of difference less than tolerance
+}

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureNumericFunctions.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,92 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_FEATURE_NUMERIC_FUNCTIONS_H_
+#define MG_FEATURE_NUMERIC_FUNCTIONS_H_
+
+class MgDisposable;
+class FdoFunction;
+class MgReader;
+class MgFeatureDistribution;
+
+class MgFeatureNumericFunctions : public MgFeatureDistribution
+{
+    DECLARE_CLASSNAME(MgFeatureNumericFunctions)
+
+public:
+
+    MgFeatureNumericFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+    virtual ~MgFeatureNumericFunctions();
+    virtual MgReader* Execute();
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+protected:
+
+    MgFeatureNumericFunctions();
+
+private:
+
+    void Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+
+    void CalculateDistribution(VECTOR& values, VECTOR& distValues);
+    // do not call this method for other functions than MINIMUM, MAXIMUM, UNIQUE
+    void CalculateDistribution(VECTOR_INT64& values, VECTOR_INT64& distValues);
+    MgReader* GetReader(VECTOR& distValues);
+
+
+    // Distribution methods
+    void GetEqualCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
+    void GetStandardDeviationCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
+    void GetQuantileCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues );
+
+    // Jenk methods
+    void GetJenksCategories(VECTOR &inputData, int numPartsRequested, double dataMin, double dataMax, VECTOR &distValues);
+    bool FixGroups(const std::vector<double>& data, std::vector<int>& indices);
+    bool FixDuplicateIndices(std::vector<int>& indices);
+    bool FixIndicesByValue(const std::vector<double>& data, std::vector<int>& indices);
+    bool doubles_equal(double d1, double d2);
+
+    // Single row methods
+    void GetMeanValue(VECTOR &values, VECTOR &distValues);
+    void GetStandardDeviation(VECTOR &values, VECTOR &distValues);
+    void GetUniqueValue(VECTOR &values, VECTOR &distValues);
+    void GetUniqueValue(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+    void GetMinimum(VECTOR &values, VECTOR &distValues);
+    void GetMinimum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+    void GetMaximum(VECTOR &values, VECTOR &distValues);
+    void GetMaximum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+
+    // Utility methods
+    bool IsInf(double x);
+    bool IsNan(double x);
+
+    void CheckSupportedPropertyType();
+    double GetValue();
+
+private:
+
+    STRING m_propertyName;
+    INT16 m_type;
+    Ptr<MgReader> m_reader;
+    FdoPtr<FdoFunction> m_customFunction;
+    STRING m_propertyAlias;
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.cpp (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.cpp)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.cpp	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,216 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "MgDesktop.h"
+#include "FeatureDefs.h"
+#include "FeatureUtil.h"
+#include "FeatureDistribution.h"
+#include "FeatureStringFunctions.h"
+#include "DataReaderCreator.h"
+#include "StringDataReaderCreator.h"
+#include <algorithm>
+#include "UniqueFunction.h"
+
+MgFeatureStringFunctions::MgFeatureStringFunctions()
+{
+    m_type = MgPropertyType::Null;
+    m_reader = NULL;
+    m_customFunction = NULL;
+    m_propertyAlias = L"";
+}
+
+MgFeatureStringFunctions::MgFeatureStringFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    Initialize(reader, customFunction, propertyAlias); // Initialize the instance
+}
+
+void MgFeatureStringFunctions::Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias)
+{
+    CHECKNULL((MgReader*)reader, L"MgFeatureStringFunctions.Initialize");
+    CHECKNULL((FdoFunction*)customFunction, L"MgFeatureStringFunctions.Initialize");
+
+    if(1 == reader->GetPropertyCount())
+    {
+        m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+    }
+    else
+    {
+        // Only get the property needed
+        FdoPtr<FdoExpressionCollection> exprCol = customFunction->GetArguments();
+        FdoInt32 cnt = exprCol->GetCount();
+        FdoPtr<FdoExpression> expr;
+        if(cnt == 1)
+        {
+            expr = exprCol->GetItem(0);
+            FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
+            CHECKNULL(propName, L"MgFeatureStringFunctions.Initialize");
+            m_propertyName = propName->GetName();
+            m_type = reader->GetPropertyType(m_propertyName);
+        }
+        else
+        {
+            // Throw original exception
+            m_type = MgFeatureUtil::GetPropertyDefinition(reader, m_propertyName);
+        }
+    }
+
+    // TODO: Should we really check this, may be we can ignore ??
+    // because we can only come to here if property type is numeric
+	if (!this->CheckSupportedPropertyType()) 
+	{
+		throw new MgInvalidPropertyTypeException(
+            L"MgFeatureStringFunctions.Initialize", __LINE__, __WFILE__, NULL, L"", NULL);
+	}
+    // We must have an property alias
+    // Though we can name a property with same name as function expression
+    // But Fdo forces to have an alias. Therefore we implement this restriction.
+    if (propertyAlias.empty())
+    {
+        STRING message = MgFeatureUtil::GetMessage(L"MgMissingPropertyAlias");
+
+        MgStringCollection arguments;
+        arguments.Add(message);
+        throw new MgFeatureServiceException(L"MgFeatureStringFunctions.Initialize", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    m_reader = SAFE_ADDREF(reader);
+    m_customFunction = FDO_SAFE_ADDREF(customFunction);
+    m_propertyAlias = propertyAlias;
+}
+
+
+MgFeatureStringFunctions::~MgFeatureStringFunctions()
+{
+}
+
+// Execute the function
+MgReader* MgFeatureStringFunctions::Execute()
+{
+    CHECKNULL((MgReader*)m_reader, L"MgFeatureStringFunctions.Execute");
+    CHECKNULL(m_customFunction, L"MgFeatureStringFunctions.Execute");
+
+    std::vector<STRING> v2;
+
+    MG_LOG_TRACE_ENTRY(L"MgFeatureStringFunctions::Execute");
+    // TODO: Should we put a limit on double buffer
+
+    std::map<STRING, char> mMap;
+    typedef std::pair<STRING, char> String_Pair;
+
+    while(m_reader->ReadNext())
+    {
+        STRING val = L"";
+
+        // Get the value
+        GetValue(val);
+
+        // Insert the value into the std::map
+        mMap.insert( String_Pair(val, '7') );  // 7 is just arbitrary placeholder
+    }
+
+    // Execute the operation on the collected values
+    ExecuteOperation(mMap, v2);
+
+    // Create FeatureReader from distribution values
+    return GetReader(v2);
+}
+
+
+// Check whether property type is a supported type
+bool MgFeatureStringFunctions::CheckSupportedPropertyType()
+{
+    return (MgPropertyType::String == m_type);
+}
+
+
+// Get the value of property
+void MgFeatureStringFunctions::GetValue(REFSTRING val)
+{
+    if (!m_reader->IsNull(m_propertyName))
+    {
+        switch(m_type)
+        {
+            case MgPropertyType::String:
+            {
+                val = m_reader->GetString(m_propertyName);
+                break;
+            }
+            default:
+            {
+                throw new MgInvalidPropertyTypeException(
+                    L"MgFeatureStringFunctions.GetValue", __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+    }
+}
+
+
+// Execute the function
+void MgFeatureStringFunctions::ExecuteOperation(std::map<STRING, char>& values, std::vector<STRING>& distValues)
+{
+   INT32 funcCode = -1;
+
+    // Get the arguments from the FdoFunction
+    STRING propertyName;
+    bool supported = MgFeatureUtil::FindCustomFunction(m_customFunction, funcCode);
+
+    if (supported)
+    {
+        switch(funcCode)
+        {
+            case UNIQUE:
+            {
+                distValues.reserve(values.size());
+                std::map<STRING, char>::iterator iter2;
+                for (iter2 = values.begin(); iter2 != values.end(); iter2++)
+                    distValues.push_back(iter2->first);
+                break;
+            }
+            default:
+            {
+                STRING message = MgFeatureUtil::GetMessage(L"MgCustomFunctionNotSupported");
+
+                MgStringCollection arguments;
+                arguments.Add(message);
+                throw new MgFeatureServiceException(
+                    L"MgServerSelectFeatures.ExecuteOperation", __LINE__, __WFILE__, &arguments, L"", NULL);
+            }
+        }
+    }
+}
+
+// Create the reader for string properties
+MgReader* MgFeatureStringFunctions::GetReader(std::vector<STRING>& distValues)
+{
+    Ptr<MgDataReader> dataReader;
+
+    switch(m_type)
+    {
+        case MgPropertyType::String:
+        {
+            Ptr<MgStringDataReaderCreator> drCreator = new MgStringDataReaderCreator(m_propertyAlias);
+            dataReader = drCreator->Execute(distValues);
+            break;
+        }
+        default:
+        {
+            throw new MgInvalidPropertyTypeException(
+                L"MgFeatureStringFunctions.GetReader", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+    }
+    return dataReader.Detach();
+}

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeatureStringFunctions.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,68 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_FEATURE_STRING_FUNCTIONS_H_
+#define MG_FEATURE_STRING_FUNCTIONS_H_
+
+class MgDisposable;
+class FdoFunction;
+class MgReader;
+class MgFeatureDistribution;
+
+class MgFeatureStringFunctions : public MgFeatureDistribution
+{
+    DECLARE_CLASSNAME(MgFeatureStringFunctions)
+
+public:
+
+    MgFeatureStringFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+    virtual MgReader* Execute();
+
+protected:
+
+    MgFeatureStringFunctions();
+    virtual ~MgFeatureStringFunctions();
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+private:
+
+    void GetValue(REFSTRING val);
+    void Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+
+    void ExecuteOperation(std::map<STRING, char>& values, std::vector<STRING>& distValues);
+    MgReader* GetReader(std::vector<STRING>& distValues);
+
+	//WTF: The original method was void and threw MgInvalidPropertyTypeException if not supported
+	//MSVC 2008 blows up on the linker phase with a combination of C1001 at this method and LNK1000
+	//
+	//Changing this method to return bool (supported = true) and throwing MgInvalidPropertyTypeException in
+	//the method that calls this (Initialize()) makes the problem go away. Real WTF there!
+    bool CheckSupportedPropertyType();
+
+private:
+
+    STRING m_propertyName;
+    INT16 m_type;
+    Ptr<MgReader> m_reader;
+    FdoPtr<FdoFunction> m_customFunction;
+    STRING m_propertyAlias;
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/FeautreNumericFunctions.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,92 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_FEATURE_NUMERIC_FUNCTIONS_H_
+#define MG_FEATURE_NUMERIC_FUNCTIONS_H_
+
+class MgDisposable;
+class FdoFunction;
+class MgReader;
+class MgFeatureDistribution;
+
+class MgFeatureNumericFunctions : public MgFeatureDistribution
+{
+    DECLARE_CLASSNAME(MgFeatureNumericFunctions)
+
+public:
+
+    MgFeatureNumericFunctions(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+    virtual ~MgFeatureNumericFunctions();
+    virtual MgReader* Execute();
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+protected:
+
+    MgFeatureNumericFunctions();
+
+private:
+
+    void Initialize(MgReader* reader, FdoFunction* customFunction, CREFSTRING propertyAlias);
+
+    void CalculateDistribution(VECTOR& values, VECTOR& distValues);
+    // do not call this method for other functions than MINIMUM, MAXIMUM, UNIQUE
+    void CalculateDistribution(VECTOR_INT64& values, VECTOR_INT64& distValues);
+    MgReader* GetReader(VECTOR& distValues);
+
+
+    // Distribution methods
+    void GetEqualCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
+    void GetStandardDeviationCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues);
+    void GetQuantileCategories(VECTOR &values, int numCats, double dataMin, double dataMax, VECTOR &distValues );
+
+    // Jenk methods
+    void GetJenksCategories(VECTOR &inputData, int numPartsRequested, double dataMin, double dataMax, VECTOR &distValues);
+    bool FixGroups(const std::vector<double>& data, std::vector<int>& indices);
+    bool FixDuplicateIndices(std::vector<int>& indices);
+    bool FixIndicesByValue(const std::vector<double>& data, std::vector<int>& indices);
+    bool doubles_equal(double d1, double d2);
+
+    // Single row methods
+    void GetMeanValue(VECTOR &values, VECTOR &distValues);
+    void GetStandardDeviation(VECTOR &values, VECTOR &distValues);
+    void GetUniqueValue(VECTOR &values, VECTOR &distValues);
+    void GetUniqueValue(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+    void GetMinimum(VECTOR &values, VECTOR &distValues);
+    void GetMinimum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+    void GetMaximum(VECTOR &values, VECTOR &distValues);
+    void GetMaximum(VECTOR_INT64 &values, VECTOR_INT64 &distValues);
+
+    // Utility methods
+    bool IsInf(double x);
+    bool IsNan(double x);
+
+    void CheckSupportedPropertyType();
+    double GetValue();
+
+private:
+
+    STRING m_propertyName;
+    INT16 m_type;
+    Ptr<MgReader> m_reader;
+    FdoPtr<FdoFunction> m_customFunction;
+    STRING m_propertyAlias;
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/GeometryDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/GeometryDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/GeometryDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/GeometryDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,61 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_GEOMETRY_DATA_READER_CREATOR_H
+#define MG_GEOMETRY_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgGeometryDataReaderCreator : public MgDataReaderCreator<MgGeometry*>
+{
+    DECLARE_CLASSNAME(MgGeometryDataReaderCreator)
+
+public:
+    MgGeometryDataReaderCreator()
+    {
+    }
+
+    MgGeometryDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Geometry;
+    }
+
+    ~MgGeometryDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(MgGeometry* val)
+    {
+        // Convert Geometry to AGF
+        MgAgfReaderWriter agfWriter;
+        Ptr<MgByteReader> reader = agfWriter.Write(val);
+
+        // Create Geometry property
+        return new MgGeometryProperty(m_propertyAlias, reader);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int16DataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Int16DataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int16DataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int16DataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_INT16_DATA_READER_CREATOR_H
+#define MG_INT16_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgInt16DataReaderCreator : public MgDataReaderCreator<INT16>
+{
+    DECLARE_CLASSNAME(MgInt16DataReaderCreator)
+
+public:
+    MgInt16DataReaderCreator()
+    {
+    }
+
+    MgInt16DataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Int16;
+    }
+
+    ~MgInt16DataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(INT16 val)
+    {
+        return new MgInt16Property(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int32DataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Int32DataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int32DataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int32DataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_INT32_DATA_READER_CREATOR_H
+#define MG_INT32_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgInt32DataReaderCreator : public MgDataReaderCreator<INT32>
+{
+    DECLARE_CLASSNAME(MgInt32DataReaderCreator)
+
+public:
+    MgInt32DataReaderCreator()
+    {
+    }
+
+    MgInt32DataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Int32;
+    }
+
+    ~MgInt32DataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(INT32 val)
+    {
+        return new MgInt32Property(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int64DataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Int64DataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int64DataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Int64DataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_INT64_DATA_READER_CREATOR_H
+#define MG_INT64_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgInt64DataReaderCreator : public MgDataReaderCreator<INT64>
+{
+    DECLARE_CLASSNAME(MgInt64DataReaderCreator)
+
+public:
+    MgInt64DataReaderCreator()
+    {
+    }
+
+    MgInt64DataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Int64;
+    }
+
+    ~MgInt64DataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(INT64 val)
+    {
+        return new MgInt64Property(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/Matrix.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/Matrix.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/Matrix.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/Matrix.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,104 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_MATRIX_H
+#define MG_MATRIX_H
+
+#include <assert.h>
+#include <iostream>
+
+//=============================================================================
+//  This matrix template is designed to be used with built-in arithmetic types.
+//  It is of fixed size; it is constructed with one memory allocation.
+template <typename T>
+class MgMatrix
+{
+    public:
+        MgMatrix(int dim1, int dim2)
+        {
+            assert(dim1 > 0);
+            assert(dim2 > 0);
+            m_dim1 = dim1;
+            m_dim2 = dim2;
+            m_pData = new T [ dim1 * dim2 ];
+            assert(m_pData);
+            Clear();
+        }
+
+        ~MgMatrix()
+        {
+            delete [] m_pData;
+        }
+
+        void Set(int i, int j, T val)
+        {
+            *Ptr(i, j) = val;
+        }
+
+        T Get(int i, int j)
+        {
+            return *Ptr(i, j);
+        }
+
+        void Clear()
+        {
+            int bytes = sizeof(T) * m_dim1 * m_dim2;
+            memset(m_pData, 0, bytes);
+        }
+
+        void Fill(T val)
+        {
+            for (T* p = &m_pData[0]; p < (m_pData + (m_dim1 * m_dim2)); ++p)
+            {
+                *p = val;
+            }
+        }
+
+        void Dump(std::ostream& o)
+        {
+            for (int i = 0; i < m_dim1; ++i)
+            {
+                for (int j = 0; j < m_dim2; ++j)
+                {
+                    T d = Get(i, j);
+                    o << /*NOXLATE*/"matrix(" << i <<
+                      /*NOXLATE*/", " << j <<
+                      /*NOXLATE*/") = " << d <<
+                      /*NOXLATE*/"\n";
+                }
+            }
+        }
+
+    private:
+        T* Ptr(int i , int j)
+        {
+            // I've had some strange experiences with complex asserts inside
+            // template classes, so I'm doing each test individually.
+            assert(i >= 0);
+            assert(i < m_dim1);
+            assert(j >= 0);
+            assert(j < m_dim2);
+            return &m_pData[(i * m_dim2) + j];
+        }
+
+    private:
+        T*  m_pData;
+        int m_dim1;
+        int m_dim2;
+};
+
+#endif  // DM_MATRIX_H

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.cpp (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.cpp)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.cpp	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,885 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "ProxyDataReader.h"
+
+MG_IMPL_DYNCREATE(MgProxyDataReader);
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Construct an uninitialized MgProxyDataReader object
+///</summary>
+///
+MgProxyDataReader::MgProxyDataReader()
+{
+    m_currRecord = 0;
+    m_serverDataReader = L"";
+    m_service = NULL;
+    m_set = NULL;
+    m_propDefCol = NULL;
+}
+
+MgProxyDataReader::MgProxyDataReader(MgBatchPropertyCollection* batchCol, MgPropertyDefinitionCollection* propDefCol)
+{
+    m_currRecord = 0;
+    m_serverDataReader = L"";
+    m_service = NULL;
+    m_set = SAFE_ADDREF(batchCol);
+    m_propDefCol = SAFE_ADDREF(propDefCol);
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Destruct a MgProxyDataReader object
+///</summary>
+///
+MgProxyDataReader::~MgProxyDataReader()
+{
+    Close();
+    SAFE_RELEASE(m_service);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Advances the reader to the next item and returns true if there is
+/// another object to read or false if reading is complete. The default
+/// position of the reader is prior to the first item. Thus you must
+/// call ReadNext to begin accessing any data.
+/// </summary>
+/// <returns>
+/// Returns true if there is a next item.
+/// </returns>
+bool MgProxyDataReader::ReadNext()
+{
+    CHECKNULL(m_set, L"MgProxyDataReader.ReadNext");
+
+    bool foundNextFeature = false;
+
+    INT32 cnt = m_set->GetCount();
+
+    if ( m_currRecord < cnt )
+    {
+        m_currRecord++;
+        foundNextFeature = true;
+    }
+    else
+    {
+        // Fetch next set of records from server
+        try
+        {
+            m_currRecord = 0;
+            if (m_serverDataReader != L"")
+            {
+                Ptr<MgBatchPropertyCollection> bpCol = m_service->GetDataRows(m_serverDataReader);
+
+                if ((((MgBatchPropertyCollection*)bpCol) != NULL) && (bpCol->GetCount() > 0))
+                {
+                    UpdateCurrentSet(bpCol);
+                    foundNextFeature = true;
+                    m_currRecord++;
+                }
+            }
+        }
+        catch (MgException* me)
+        {
+            SAFE_RELEASE(me);
+        }
+    }
+
+    return foundNextFeature;
+}
+
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the number of properties in the result set.
+/// </summary>
+/// <returns>Returns the number of properties.</returns>
+INT32 MgProxyDataReader::GetPropertyCount()
+{
+    CHECKNULL(m_propDefCol, L"MgProxyDataReader.GetPropertyCount");
+
+    return m_propDefCol->GetCount();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the name of the property at the given ordinal position.
+/// </summary>
+/// <param name="index">Input the position of the property.</param>
+/// <returns>Returns the property name</returns>
+STRING MgProxyDataReader::GetPropertyName(INT32 index)
+{
+    CHECKNULL(m_propDefCol, L"MgProxyDataReader.GetPropertyName");
+
+    Ptr<MgPropertyDefinition> propDef = m_propDefCol->GetItem(index);
+    return propDef->GetName();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the index of the property with the specified name.
+/// </summary>
+/// <param name="propertyName">Input the name of the property.</param>
+/// <returns>Returns the property index</returns>
+INT32 MgProxyDataReader::GetPropertyIndex(CREFSTRING propertyName)
+{
+    CHECKNULL(m_propDefCol, L"MgProxyDataReader.GetPropertyIndex");
+
+    return m_propDefCol->IndexOf(propertyName);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the data type of the property with the specified name.
+/// </summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the type of the property.</returns>
+INT32 MgProxyDataReader::GetPropertyType(CREFSTRING propertyName)
+{
+    CHECKNULL(m_propDefCol, L"MgProxyDataReader.GetPropertyType");
+
+    Ptr<MgPropertyDefinition> propDef = m_propDefCol->GetItem(propertyName);
+    CHECKNULL((MgPropertyDefinition*)propDef, L"MgProxyDataReader.GetPropertyType");
+
+    return propDef->GetPropertyType();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the data type of the property at the specified index.
+/// </summary>
+/// <param name="index">Input the property index.</param>
+/// <returns>Returns the type of the property.</returns>
+INT32 MgProxyDataReader::GetPropertyType(INT32 index)
+{
+    CHECKNULL(m_propDefCol, L"MgProxyDataReader.GetPropertyType");
+
+    Ptr<MgPropertyDefinition> propDef = m_propDefCol->GetItem(index);
+    CHECKNULL((MgPropertyDefinition*)propDef, L"MgProxyDataReader.GetPropertyType");
+
+    return propDef->GetPropertyType();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+///  Returns true if the value of the specified property is null.
+/// </summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns true if the value is null.</returns>
+bool MgProxyDataReader::IsNull(CREFSTRING propertyName)
+{
+    bool isNull = false;
+
+    Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)GetProperty(propertyName);
+
+    if (ptrProp != NULL)
+    {
+        isNull = ptrProp->IsNull();
+    }
+
+    return isNull;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+///  Returns true if the value of the specified property is null.
+/// </summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns true if the value is null.</returns>
+bool MgProxyDataReader::IsNull(INT32 index)
+{
+    bool isNull = false;
+
+    Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)GetProperty(index);
+
+    if (ptrProp != NULL)
+    {
+        isNull = ptrProp->IsNull();
+    }
+
+    return isNull;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Boolean value of the specified property. No conversion is
+/// performed, thus the property must be a of boolean type the result
+/// is undertermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the Boolean value.</returns>
+bool MgProxyDataReader::GetBoolean(CREFSTRING propertyName)
+{
+    bool retVal = false;
+
+    Ptr<MgBooleanProperty> ptrProp = (MgBooleanProperty*)GetProperty(propertyName, MgPropertyType::Boolean);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Boolean value of the specified property. No conversion is
+/// performed, thus the property must be a of boolean type the result
+/// is undertermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the Boolean value.</returns>
+bool MgProxyDataReader::GetBoolean(INT32 index)
+{
+    bool retVal = false;
+
+    Ptr<MgBooleanProperty> ptrProp = (MgBooleanProperty*)GetProperty(index, MgPropertyType::Boolean);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Byte value of the specified property. No conversion is
+/// performed, thus the property must be a of byte type or the result
+/// is undertermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the Byte value.</returns>
+BYTE MgProxyDataReader::GetByte(CREFSTRING propertyName)
+{
+    BYTE retVal = 0;
+
+    Ptr<MgByteProperty> ptrProp = (MgByteProperty*)GetProperty(propertyName, MgPropertyType::Byte);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Byte value of the specified property. No conversion is
+/// performed, thus the property must be a of byte type or the result
+/// is undertermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the Byte value.</returns>
+BYTE MgProxyDataReader::GetByte(INT32 index)
+{
+    BYTE retVal = 0;
+
+    Ptr<MgByteProperty> ptrProp = (MgByteProperty*)GetProperty(index, MgPropertyType::Byte);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the DTime value of the specified property. No conversion is
+/// performed, thus the property must be a of date type or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the DTime value.</returns>
+MgDateTime* MgProxyDataReader::GetDateTime(CREFSTRING propertyName)
+{
+    Ptr<MgDateTimeProperty> ptrProp = (MgDateTimeProperty*)GetProperty(propertyName, MgPropertyType::DateTime);
+    Ptr<MgDateTime> retVal = ptrProp->GetValue();
+
+    return SAFE_ADDREF((MgDateTime*)retVal);
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the DTime value of the specified property. No conversion is
+/// performed, thus the property must be a of date type or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the DTime value.</returns>
+MgDateTime* MgProxyDataReader::GetDateTime(INT32 index)
+{
+    Ptr<MgDateTimeProperty> ptrProp = (MgDateTimeProperty*)GetProperty(index, MgPropertyType::DateTime);
+    Ptr<MgDateTime> retVal = ptrProp->GetValue();
+
+    return SAFE_ADDREF((MgDateTime*)retVal);
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Single value of the specified property. No conversion is
+/// performed, thus the property must be a of type single or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the single value.</returns>
+float MgProxyDataReader::GetSingle(CREFSTRING propertyName)
+{
+    float retVal = 0;
+
+    Ptr<MgSingleProperty> ptrProp = (MgSingleProperty*)GetProperty(propertyName, MgPropertyType::Single);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Single value of the specified property. No conversion is
+/// performed, thus the property must be a of type single or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the single value.</returns>
+float MgProxyDataReader::GetSingle(INT32 index)
+{
+    float retVal = 0;
+
+    Ptr<MgSingleProperty> ptrProp = (MgSingleProperty*)GetProperty(index, MgPropertyType::Single);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Double value of the specified property. No conversion is
+/// performed, thus the property must be a of type double or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the double value.</returns>
+double MgProxyDataReader::GetDouble(CREFSTRING propertyName)
+{
+    double retVal = 0;
+
+    Ptr<MgDoubleProperty> ptrProp = (MgDoubleProperty*)GetProperty(propertyName, MgPropertyType::Double);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Double value of the specified property. No conversion is
+/// performed, thus the property must be a of type double or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the double value.</returns>
+double MgProxyDataReader::GetDouble(INT32 index)
+{
+    double retVal = 0;
+
+    Ptr<MgDoubleProperty> ptrProp = (MgDoubleProperty*)GetProperty(index, MgPropertyType::Double);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 16 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 16 bits or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 16 bits value.</returns>
+INT16 MgProxyDataReader::GetInt16(CREFSTRING propertyName)
+{
+    INT16 retVal = 0;
+
+    Ptr<MgInt16Property> ptrProp = (MgInt16Property*)GetProperty(propertyName, MgPropertyType::Int16);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 16 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 16 bits or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 16 bits value.</returns>
+INT16 MgProxyDataReader::GetInt16(INT32 index)
+{
+    INT16 retVal = 0;
+
+    Ptr<MgInt16Property> ptrProp = (MgInt16Property*)GetProperty(index, MgPropertyType::Int16);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 32 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 32 bits or the result
+/// is undetermined</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 32 bits value.</returns>
+INT32 MgProxyDataReader::GetInt32(CREFSTRING propertyName)
+{
+    INT32 retVal = 0;
+
+    Ptr<MgInt32Property> ptrProp = (MgInt32Property*)GetProperty(propertyName, MgPropertyType::Int32);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 32 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 32 bits or the result
+/// is undetermined</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 32 bits value.</returns>
+INT32 MgProxyDataReader::GetInt32(INT32 index)
+{
+    INT32 retVal = 0;
+
+    Ptr<MgInt32Property> ptrProp = (MgInt32Property*)GetProperty(index, MgPropertyType::Int32);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 64 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 64 bits or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the integer 64 bits value.
+/// Note: INT64 is actually a pointer to an Integer64 object
+///</returns>
+INT64 MgProxyDataReader::GetInt64(CREFSTRING propertyName)
+{
+    INT64 retVal = 0;
+
+    Ptr<MgInt64Property> ptrProp = (MgInt64Property*)GetProperty(propertyName, MgPropertyType::Int64);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the integer 64 bits value of the specified property. No conversion is
+/// performed, thus the property must be a of type integer 64 bits or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the integer 64 bits value.
+/// Note: INT64 is actually a pointer to an Integer64 object
+///</returns>
+INT64 MgProxyDataReader::GetInt64(INT32 index)
+{
+    INT64 retVal = 0;
+
+    Ptr<MgInt64Property> ptrProp = (MgInt64Property*)GetProperty(index, MgPropertyType::Int64);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the string value.</returns>
+STRING MgProxyDataReader::GetString(CREFSTRING propertyName)
+{
+    STRING retVal = L"";
+
+    Ptr<MgStringProperty> ptrProp = (MgStringProperty*)GetProperty(propertyName, MgPropertyType::String);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the string value.</returns>
+STRING MgProxyDataReader::GetString(INT32 index)
+{
+    STRING retVal = L"";
+
+    Ptr<MgStringProperty> ptrProp = (MgStringProperty*)GetProperty(index, MgPropertyType::String);
+    retVal = ptrProp->GetValue();
+
+    return retVal;
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the BLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type BLOBs or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the BLOB value.</returns>
+MgByteReader* MgProxyDataReader::GetBLOB(CREFSTRING propertyName)
+{
+    Ptr<MgBlobProperty> ptrProp = (MgBlobProperty*)GetProperty(propertyName, MgPropertyType::Blob);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the BLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type BLOBs or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the BLOB value.</returns>
+MgByteReader* MgProxyDataReader::GetBLOB(INT32 index)
+{
+    Ptr<MgBlobProperty> ptrProp = (MgBlobProperty*)GetProperty(index, MgPropertyType::Blob);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the CLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type CLOB or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the CLOB value.</returns>
+MgByteReader* MgProxyDataReader::GetCLOB(CREFSTRING propertyName)
+{
+    Ptr<MgClobProperty> ptrProp = (MgClobProperty*)GetProperty(propertyName, MgPropertyType::Clob);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the CLOB value of the specified property. No conversion is
+/// performed, thus the property must be a of type CLOB or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the CLOB value.</returns>
+MgByteReader* MgProxyDataReader::GetCLOB(INT32 index)
+{
+    Ptr<MgClobProperty> ptrProp = (MgClobProperty*)GetProperty(index, MgPropertyType::Clob);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Geometry for the specified property. No conversion is
+/// performed, thus the property must be a of type Geometry or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns a ByteReader object</returns>
+MgByteReader* MgProxyDataReader::GetGeometry(CREFSTRING propertyName)
+{
+    Ptr<MgGeometryProperty> ptrProp = (MgGeometryProperty*)GetProperty(propertyName, MgPropertyType::Geometry);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the Geometry for the specified property. No conversion is
+/// performed, thus the property must be a of type Geometry or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns a ByteReader object</returns>
+MgByteReader* MgProxyDataReader::GetGeometry(INT32 index)
+{
+    Ptr<MgGeometryProperty> ptrProp = (MgGeometryProperty*)GetProperty(index, MgPropertyType::Geometry);
+    return ptrProp->GetValue();
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Serialize data to TCP/IP stream
+///</summary>
+///<param name="stream">
+/// Stream
+///</param>
+
+void MgProxyDataReader::Serialize(MgStream* stream)
+{
+    bool operationCompleted = true;
+    stream->WriteBoolean(operationCompleted);
+
+    if (operationCompleted)
+    {
+        stream->WriteString(m_serverDataReader);                        // Write the reader ID so we can retrieve it for later use
+        stream->WriteString(m_providerName);
+        stream->WriteObject(m_propDefCol);                              // Write the property definition
+        stream->WriteObject(m_set);                                     // Write the property data
+    }
+}
+
+//////////////////////////////////////////////////////////////////
+///<summary>
+/// Deserialize data from TCP/IP stream
+///</summary>
+///<param name="stream">
+/// Stream
+///</param>
+
+void MgProxyDataReader::Deserialize(MgStream* stream)
+{
+    bool operationCompleted = false;
+
+    stream->GetBoolean(operationCompleted);
+
+    if (operationCompleted)
+    {
+        stream->GetString(m_serverDataReader);                                  // Get the reader ID so we can retrieve it for later use
+        stream->GetString(m_providerName);
+        m_propDefCol = (MgPropertyDefinitionCollection*)stream->GetObject();    // Get the property definition
+        m_set = (MgBatchPropertyCollection*)stream->GetObject();                // Get the property data
+    }
+    else
+    {
+        MgException* exp = (MgException*)stream->GetObject();
+        exp->Raise();
+    }
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Serializes all features into an XML.
+/// XML is serialized from the current position of feature reader in the order
+/// data are retrieved.
+/// <returns>MgByteReader holding XML.</returns>
+MgByteReader* MgProxyDataReader::ToXml()
+{
+    string xmlStr;
+    this->ToXml(xmlStr);
+
+    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)xmlStr.c_str(), (INT32)xmlStr.length());
+    byteSource->SetMimeType(MgMimeType::Xml);
+
+    return byteSource->GetReader();
+}
+
+void MgProxyDataReader::ToXml(string &str)
+{
+    CHECKNULL((MgBatchPropertyCollection*)m_set, L"MgProxyDataReader.ToXml");
+    CHECKNULL((MgPropertyDefinitionCollection*)m_propDefCol, L"MgProxyDataReader.ToXml");
+
+    // this XML follows the SelectAggregate-1.0.0.xsd schema
+    str += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+    str += "<PropertySet>";
+    m_propDefCol->ToXml(str);
+    str += "<Properties>";
+    while ( this->ReadNext() )
+    {
+        Ptr<MgPropertyCollection> propCol = m_set->GetItem(m_currRecord-1);
+        INT32 cnt = propCol->GetCount();
+        if (propCol != NULL && cnt > 0)
+        {
+            str += "<PropertyCollection>";
+            propCol->ToXml(str,false);
+            str += "</PropertyCollection>";
+        }
+    }
+    str += "</Properties>";
+    str += "</PropertySet>";
+}
+
+void MgProxyDataReader::SetService(MgFeatureService* service)
+{
+    CHECKNULL(service, L"MgProxyDataReader.SetService");
+
+    if (m_service == NULL)
+    {
+        m_service = SAFE_ADDREF(service);
+    }
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Releases all the resources of feature reader.
+/// This must be called when user is done with Feature Reader
+/// <returns>Nothing</returns>
+void MgProxyDataReader::Close()
+{
+    if (m_serverDataReader != L"")
+    {
+        MG_TRY()
+
+        m_service->CloseDataReader(m_serverDataReader);
+        m_serverDataReader = L"";
+
+        MG_CATCH(L"MgProxyDataReader.Close")
+
+        // We do not rethrow the exception while destructing the object. Even if we had problem
+        // disposing this feature reader, it will automatically get collected after time out.
+    }
+}
+
+
+// Get the property for the specified name
+MgProperty* MgProxyDataReader::GetProperty(CREFSTRING propertyName, INT16 expectedType)
+{
+    Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)this->GetProperty(propertyName);
+    CHECKNULL(ptrProp, L"MgProxyDataReader.GetProperty");
+
+    if (ptrProp->IsNull())
+    {
+        MgStringCollection arguments;
+        arguments.Add(propertyName);
+
+        throw new MgNullPropertyValueException(L"MgProxyDataReader.GetProperty",
+            __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    INT16 propType = ptrProp->GetPropertyType();
+    MG_CHECK_PROPERTY_TYPE(propType, expectedType, L"MgProxyDataReader.GetProperty");
+
+    return SAFE_ADDREF((MgProperty*)ptrProp);
+}
+
+// Get the property for the specified name
+MgProperty* MgProxyDataReader::GetProperty(CREFSTRING propertyName)
+{
+    CHECKNULL(m_set, L"MgProxyDataReader.GetProperty");
+    MG_CHECK_FEATURE_SET_COUNT(m_set, L"MgProxyDataReader.GetProperty");
+
+    Ptr<MgPropertyCollection> ptrCol = m_set->GetItem(m_currRecord-1);
+    CHECKNULL(ptrCol, L"MgProxyDataReader.GetProperty");
+
+    Ptr<MgProperty> ptrProp = ptrCol->GetItem(propertyName);
+    CHECKNULL(ptrProp, L"MgProxyDataReader.GetProperty");
+
+    return SAFE_ADDREF((MgProperty*)ptrProp);
+}
+
+// Get the property for the specified name
+MgProperty* MgProxyDataReader::GetProperty(INT32 index, INT16 expectedType)
+{
+    Ptr<MgNullableProperty> ptrProp = (MgNullableProperty*)this->GetProperty(index);
+    CHECKNULL(ptrProp, L"MgProxyDataReader.GetProperty");
+
+    if (ptrProp->IsNull())
+    {
+        STRING buffer;
+        MgUtil::Int32ToString(index, buffer);
+
+        MgStringCollection arguments;
+        arguments.Add(buffer);
+
+        throw new MgNullPropertyValueException(L"MgProxyDataReader.GetProperty",
+            __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    INT16 propType = ptrProp->GetPropertyType();
+    MG_CHECK_PROPERTY_TYPE(propType, expectedType, L"MgProxyDataReader.GetProperty");
+
+    return SAFE_ADDREF((MgProperty*)ptrProp);
+}
+
+// Get the property for the specified index
+MgProperty* MgProxyDataReader::GetProperty(INT32 index)
+{
+    CHECKNULL(m_set, L"MgProxyDataReader.GetProperty");
+    MG_CHECK_FEATURE_SET_COUNT(m_set, L"MgProxyDataReader.GetProperty");
+
+    Ptr<MgPropertyCollection> ptrCol = m_set->GetItem(m_currRecord-1);
+    CHECKNULL(ptrCol, L"MgProxyDataReader.GetProperty");
+
+    Ptr<MgProperty> ptrProp = ptrCol->GetItem(index);
+    CHECKNULL(ptrProp, L"MgProxyDataReader.GetProperty");
+
+    return SAFE_ADDREF((MgProperty*)ptrProp);
+}
+
+void MgProxyDataReader::UpdateCurrentSet(MgBatchPropertyCollection* bpCol)
+{
+    CHECKNULL((MgBatchPropertyCollection*)m_set, L"MgProxyDataReader.UpdateCurrentSet");
+    CHECKNULL((MgBatchPropertyCollection*)bpCol, L"MgProxyDataReader.UpdateCurrentSet");
+
+    m_set->Clear();
+
+    // It is only reference copy
+    INT32 cnt = bpCol->GetCount();
+    for (INT32 i=0; i < cnt; i++)
+    {
+        Ptr<MgPropertyCollection> propCol = bpCol->GetItem(i);
+        m_set->Add(propCol);
+    }
+}
+
+/// <summary>Gets the raster object of the specified property.
+/// the property must be of Raster type; otherwise, an exception is thrown.
+/// </summary>
+/// <param name="propertyName">Input the property name.</param>
+/// <returns>Returns the raster object.</returns>
+MgRaster* MgProxyDataReader::GetRaster(CREFSTRING propertyName)
+{
+    Ptr<MgRasterProperty> ptrProp = (MgRasterProperty*)GetProperty(propertyName, MgPropertyType::Raster);
+    Ptr<MgRaster> retVal = ptrProp->GetValue();
+    retVal->SetMgService(m_service);
+    retVal->SetHandle(m_serverDataReader);
+
+    return SAFE_ADDREF((MgRaster*)retVal);
+}
+
+/// <summary>Gets the raster object of the specified property.
+/// the property must be of Raster type; otherwise, an exception is thrown.
+/// </summary>
+/// <param name="index">Input the property index.</param>
+/// <returns>Returns the raster object.</returns>
+MgRaster* MgProxyDataReader::GetRaster(INT32 index)
+{
+    Ptr<MgRasterProperty> ptrProp = (MgRasterProperty*)GetProperty(index, MgPropertyType::Raster);
+    Ptr<MgRaster> retVal = ptrProp->GetValue();
+    retVal->SetMgService(m_service);
+    retVal->SetHandle(m_serverDataReader);
+
+    return SAFE_ADDREF((MgRaster*)retVal);
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="propertyName">Property name.</param>
+/// <returns>Returns the string value.</returns>
+const wchar_t* MgProxyDataReader::GetString(CREFSTRING propertyName, INT32& length)
+{
+    STRING str = this->GetString(propertyName);
+    length = (INT32)str.size();
+
+    return str.c_str();
+}
+
+//////////////////////////////////////////////////////////////////
+/// <summary>
+/// Gets the string value of the specified property. No conversion is
+/// performed, thus the property must be a of type string or the result
+/// is NULL</summary>
+/// <param name="index">Property index.</param>
+/// <returns>Returns the string value.</returns>
+const wchar_t* MgProxyDataReader::GetString(INT32 index, INT32& length)
+{
+    STRING str = this->GetString(index);
+    length = (INT32)str.size();
+
+    return str.c_str();
+}

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/ProxyDataReader.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,610 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _MG_PROXY_DATA_READER_H
+#define _MG_PROXY_DATA_READER_H
+
+#include "MgDesktop.h"
+
+class MgDataReader;
+
+class MgProxyDataReader;
+template class MG_DESKTOP_API Ptr<MgProxyDataReader>;
+
+/// \cond INTERNAL
+/////////////////////////////////////////////////////////////////
+/// \brief
+/// The SqlReader interface provides a forward-only, read-only
+/// iterator for reading relational table data.
+///
+/// \remarks
+/// The initial position of the SqlReader interface is prior to the first item.
+/// Thus, you must call ReadNext to begin accessing any data.
+class MG_DESKTOP_API  MgProxyDataReader : public MgDataReader
+{
+    MG_DECL_DYNCREATE();
+    DECLARE_CLASSNAME(MgProxyDataReader)
+
+EXTERNAL_API:
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Advances the reader to the next item and returns true if there is
+    /// another object to read or false if reading is complete. The default
+    /// position of the reader is prior to the first item. Thus you must
+    /// call ReadNext to begin accessing any data.
+    ///
+    /// \return
+    /// Returns true if there is a next item.
+    ///
+    bool ReadNext();
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the number of properties in the result set.
+    ///
+    /// \return
+    /// Returns the number of properties.
+    ///
+    INT32 GetPropertyCount();
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the name of the property at the given ordinal position.
+    ///
+    /// \param index
+    /// Input the position of the property.
+    ///
+    /// \return
+    /// Returns the property name
+    ///
+    STRING GetPropertyName(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the index of the property with the specified name.
+    ///
+    /// \param propertyName
+    /// Input the name of the property.
+    ///
+    /// \return
+    /// Returns the property index
+    ///
+    INT32 GetPropertyIndex(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the data type of the property with the specified name.
+    ///
+    /// \param propertyName
+    /// Input the property name.
+    ///
+    /// \return
+    /// Returns the type of the property.
+    ///
+    INT32 GetPropertyType(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the data type of the property at the specified index.
+    ///
+    /// \param index
+    /// Input the property index.
+    ///
+    /// \return
+    /// Returns the type of the property.
+    ///
+    INT32 GetPropertyType(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    ///  Returns true if the value of the specified property is null.
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns true if the value is null.
+    ///
+    bool IsNull(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Boolean value of the specified property. No conversion is
+    /// performed, thus the property must be a of boolean type the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the Boolean value.
+    ///
+    bool GetBoolean(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Byte value of the specified property. No conversion is
+    /// performed, thus the property must be a of byte type or the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the Byte value.
+    ///
+    BYTE GetByte(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the DTime value of the specified property. No conversion is
+    /// performed, thus the property must be a of date type or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the DTime value.
+    ///
+    MgDateTime* GetDateTime(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Single value of the specified property. No conversion is
+    /// performed, thus the property must be a of type single or the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the single value.
+    ///
+    float GetSingle(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Double value of the specified property. No conversion is
+    /// performed, thus the property must be a of type double or the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the double value.
+    ///
+    double GetDouble(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 16 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 16 bits or the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the integer 16 bits value.
+    ///
+    INT16 GetInt16(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 32 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 32 bits or the result
+    /// is undetermined
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the integer 32 bits value.
+    ///
+    INT32 GetInt32(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 64 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 64 bits or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the integer 64 bits value.
+    /// Note: INT64 is actually a pointer to an Integer64 object
+    ///
+    INT64 GetInt64(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the string value of the specified property. No conversion is
+    /// performed, thus the property must be a of type string or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the string value.
+    ///
+    STRING GetString(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the BLOB value of the specified property. No conversion is
+    /// performed, thus the property must be a of type BLOBs or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the BLOB value.
+    ///
+    MgByteReader* GetBLOB(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the CLOB value of the specified property. No conversion is
+    /// performed, thus the property must be a of type CLOB or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the CLOB value.
+    ///
+    MgByteReader* GetCLOB(CREFSTRING propertyName);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Geometry for the specified property. No conversion is
+    /// performed, thus the property must be a of type Geometry or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns a ByteReader object
+    ///
+    MgByteReader* GetGeometry(CREFSTRING propertyName);
+
+    /// \brief
+    /// Gets the raster object of the specified property.
+    /// the property must be of Raster type; otherwise, an exception is thrown.
+    ///
+    /// \param propertyName
+    /// Input the property name.
+    ///
+    /// \return
+    /// Returns the raster object.
+    ///
+    MgRaster* GetRaster(CREFSTRING propertyName);
+
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    ///  Returns true if the value of the specified property is null.
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns true if the value is null.
+    ///
+    bool IsNull(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Boolean value of the specified property. No conversion is
+    /// performed, thus the property must be a of boolean type the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the Boolean value.
+    ///
+    bool GetBoolean(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Byte value of the specified property. No conversion is
+    /// performed, thus the property must be a of byte type or the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the Byte value.
+    ///
+    BYTE GetByte(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the DTime value of the specified property. No conversion is
+    /// performed, thus the property must be a of date type or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the DTime value.
+    ///
+    MgDateTime* GetDateTime(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Single value of the specified property. No conversion is
+    /// performed, thus the property must be a of type single or the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the single value.
+    ///
+    float GetSingle(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Double value of the specified property. No conversion is
+    /// performed, thus the property must be a of type double or the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the double value.
+    ///
+    double GetDouble(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 16 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 16 bits or the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the integer 16 bits value.
+    ///
+    INT16 GetInt16(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 32 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 32 bits or the result
+    /// is undetermined
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the integer 32 bits value.
+    ///
+    INT32 GetInt32(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the integer 64 bits value of the specified property. No conversion is
+    /// performed, thus the property must be a of type integer 64 bits or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the integer 64 bits value.
+    /// Note: INT64 is actually a pointer to an Integer64 object
+    ///
+    INT64 GetInt64(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the string value of the specified property. No conversion is
+    /// performed, thus the property must be a of type string or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the string value.
+    ///
+    STRING GetString(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the BLOB value of the specified property. No conversion is
+    /// performed, thus the property must be a of type BLOBs or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the BLOB value.
+    ///
+    MgByteReader* GetBLOB(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the CLOB value of the specified property. No conversion is
+    /// performed, thus the property must be a of type CLOB or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the CLOB value.
+    ///
+    MgByteReader* GetCLOB(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the Geometry for the specified property. No conversion is
+    /// performed, thus the property must be a of type Geometry or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns a ByteReader object
+    ///
+    MgByteReader* GetGeometry(INT32 index);
+
+    /// \brief
+    /// Gets the raster object of the specified property.
+    /// the property must be of Raster type; otherwise, an exception is thrown.
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the raster object.
+    ///
+    MgRaster* GetRaster(INT32 index);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Closes the FeatureReader object, freeing any resources it may be holding.
+    ///
+    void Close();
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Serializes all features into an XML.
+    /// XML is serialized from the current position of feature reader in the order
+    /// data are retrieved.
+    ///
+    /// \return
+    /// MgByteReader holding XML.
+    ///
+    MgByteReader* ToXml();
+
+INTERNAL_API:
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the string value of the specified property. No conversion is
+    /// performed, thus the property must be a of type string or the result
+    /// is NULL
+    ///
+    /// \param propertyName
+    /// Property name.
+    ///
+    /// \return
+    /// Returns the string value.
+    ///
+    const wchar_t* GetString(CREFSTRING propertyName, INT32& length);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Gets the string value of the specified property. No conversion is
+    /// performed, thus the property must be a of type string or the result
+    /// is NULL
+    ///
+    /// \param index
+    /// Property index.
+    ///
+    /// \return
+    /// Returns the string value.
+    ///
+    const wchar_t* GetString(INT32 index, INT32& length);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Serialize data to TCP/IP stream
+    ///
+    /// \param stream
+    /// Stream
+    ///
+    virtual void Serialize(MgStream* stream);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Deserialize data from TCP/IP stream
+    ///
+    /// \param stream
+    /// Stream
+    ///
+    virtual void Deserialize(MgStream* stream);
+
+    void ToXml(string &str);
+
+    void SetService(MgFeatureService* service);
+
+    virtual INT32 GetClassId()
+    {
+        return m_cls_id;
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    MgProxyDataReader(MgBatchPropertyCollection* batchCol, MgPropertyDefinitionCollection* propDefCol);
+
+    MgProxyDataReader();
+    ~MgProxyDataReader();
+
+private:
+
+    MgProperty* GetProperty(CREFSTRING propertyName, INT16 expectedType);
+    /// Get the property for the specified name
+    MgProperty* GetProperty(CREFSTRING propertyName);
+
+    MgProperty* GetProperty(INT32 index, INT16 expectedType);
+    /// Get the property for the specified index.
+    MgProperty* GetProperty(INT32 index);
+
+    void UpdateCurrentSet(MgBatchPropertyCollection* bpCol);
+
+    Ptr<MgBatchPropertyCollection> m_set;
+    Ptr<MgPropertyDefinitionCollection> m_propDefCol;
+
+    STRING m_providerName;
+    INT32 m_currRecord;
+    STRING m_serverDataReader;
+    MgFeatureService* m_service; // Do not want to implement a default constructor
+
+CLASS_ID:
+    static const INT32 m_cls_id = PlatformBase_FeatureService_DataReader;
+
+};
+/// \endcond
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/SingleDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/SingleDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/SingleDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/SingleDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_SINGLE_DATA_READER_CREATOR_H
+#define MG_SINGLE_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgSingleDataReaderCreator : public MgDataReaderCreator<float>
+{
+    DECLARE_CLASSNAME(MgSingleDataReaderCreator)
+
+public:
+    MgSingleDataReaderCreator()
+    {
+    }
+
+    MgSingleDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::Single;
+    }
+
+    ~MgSingleDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(float val)
+    {
+        return new MgSingleProperty(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/StringDataReaderCreator.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/StringDataReaderCreator.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/StringDataReaderCreator.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/StringDataReaderCreator.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_STRING_DATA_READER_CREATOR_H
+#define MG_STRING_DATA_READER_CREATOR_H
+
+using namespace std;
+
+#include <vector>
+
+class MgStringDataReaderCreator : public MgDataReaderCreator<STRING>
+{
+    DECLARE_CLASSNAME(MgStringDataReaderCreator)
+
+public:
+    MgStringDataReaderCreator()
+    {
+    }
+
+    MgStringDataReaderCreator(CREFSTRING propertyAlias)
+    {
+        m_propertyAlias = propertyAlias;
+        m_propType = MgPropertyType::String;
+    }
+
+    ~MgStringDataReaderCreator()
+    {
+    }
+
+    //
+    MgProperty* GetProperty(CREFSTRING val)
+    {
+        return new MgStringProperty(m_propertyAlias, val);
+    }
+
+    virtual void Dispose()
+    {
+        delete this;
+    }
+};
+
+#endif

Copied: trunk/MgDev/Desktop/MgDesktop/Services/Feature/UniqueFunction.h (from rev 6645, branches/2.4/MgDev/Desktop/MgDesktop/Services/Feature/UniqueFunction.h)
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/Feature/UniqueFunction.h	                        (rev 0)
+++ trunk/MgDev/Desktop/MgDesktop/Services/Feature/UniqueFunction.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -0,0 +1,50 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_UNIQUE_FUNCTION_H
+#define MG_UNIQUE_FUNCTION_H
+
+#include <vector>
+#include <map>
+using namespace std;
+
+//=============================================================================
+//  This matrix template is designed to be used with built-in arithmetic types.
+//  It is of fixed size; it is constructed with one memory allocation.
+template <typename T>
+class MgUniqueFunction
+{
+    public:
+        MgUniqueFunction() {}
+        ~MgUniqueFunction() {}
+
+        static void Execute(const std::vector<T>& in, std::vector<T>& out)
+        {
+            int cnt = (int)in.size();
+            if (cnt <= 0) { return; } // Nothing to do, we just send back Property Definition to clients from reader
+
+            std::map<T, char> mMap;
+            for (int i=0; i<cnt; i++) mMap[in[i]] = '7'; //7 is just arbitrary placeholder
+
+            out.reserve(mMap.size());
+            typename std::map<T, char>::iterator iter2;
+            for (iter2 = mMap.begin(); iter2 != mMap.end(); iter2++)
+                out.push_back(iter2->first);
+        }
+};
+
+#endif  // DM_MATRIX_H

Modified: trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.cpp	2012-05-13 04:07:19 UTC (rev 6646)
@@ -18,6 +18,7 @@
 #include "DataReader.h"
 #include "SqlReader.h"
 
+#include "Services/Feature/FeatureDistribution.h"
 #include "Services/Feature/ProjectedFeatureReader.h"
 #include "Services/Feature/GwsFeatureReader.h"
 #include "Services/Feature/GwsConnectionPool.h"
@@ -3294,6 +3295,10 @@
 
         INT32 propCount = props->GetCount();
         INT32 compCount = computed->GetCount();
+		
+		bool bCustomPropertyFound = false;
+		FdoFunction* customFunc = NULL;
+		STRING customPropName;
 
         FdoPtr<FdoIdentifierCollection> fdoProps = select->GetPropertyNames();
         if (propCount > 0)
@@ -3309,10 +3314,60 @@
 	        for (INT32 i = 0; i < compCount; i++)
 	        {
 		        Ptr<MgStringProperty> comp = computed->GetItem(i);
+				STRING aliasName = comp->GetName();
 		        FdoPtr<FdoExpression> expr = FdoExpression::Parse(comp->GetValue().c_str());
-		        FdoPtr<FdoComputedIdentifier> name= FdoComputedIdentifier::Create(comp->GetName().c_str(), expr);
+		        
+				if (ContainsUdf(connWrap, expr))
+				{
+					// If property is already found, two custom properties are not supported and therefore throw exception
+					if (bCustomPropertyFound)
+					{
+						STRING message = MgFeatureUtil::GetMessage(L"MgOnlyOnePropertyAllowed");
 
-		        fdoProps->Add(name);
+						MgStringCollection arguments;
+						arguments.Add(message);
+						throw new MgFeatureServiceException(L"MgdFeatureService::SelectAggregate", __LINE__, __WFILE__, &arguments, L"", NULL);
+					}
+
+					// Downcast to FdoFunction
+					FdoFunction* function = dynamic_cast<FdoFunction*>(expr.p);
+
+					if (function != NULL)
+					{
+						FdoString* expName = aliasName.c_str();
+						if (expName != NULL)
+						{
+							FdoPtr<FdoExpressionCollection> exprCol = function->GetArguments();
+							FdoInt32 cnt = exprCol->GetCount();
+							FdoPtr<FdoExpression> expr;
+							if (cnt > 0)
+							{
+								expr = exprCol->GetItem(0);   // Property Name
+							}
+
+							// Just pass in the property name
+							// FdoPtr<FdoComputedIdentifier> fdoIden = FdoComputedIdentifier::Create(expName, expr);
+
+							// NOTE: Each provider has its own rule for supporting computed properties, select and select aggregate
+							// functionality. Therefore we just work with simple select command, fetch the property and do the needed
+							// calculations. Therefore, we are not adding them as computed properties.
+
+							FdoIdentifier* propName = dynamic_cast<FdoIdentifier*>(expr.p);
+
+							if (propName != NULL)
+								fdoProps->Add(propName);
+
+							customPropName = aliasName;
+							bCustomPropertyFound = true;
+							customFunc = FDO_SAFE_ADDREF(function);
+						}
+					}
+				}
+				else
+				{
+					FdoPtr<FdoComputedIdentifier> name = FdoComputedIdentifier::Create(comp->GetName().c_str(), expr);
+					fdoProps->Add(name);
+				}
 	        }
         }
 
@@ -3339,7 +3394,17 @@
         }
 
         FdoPtr<FdoIDataReader> fdoReader = select->Execute();
-        reader = new MgdDataReader(connWrap, fdoReader);
+		if (bCustomPropertyFound) 
+		{
+			Ptr<MgReader> origReader = new MgdDataReader(connWrap, fdoReader);
+			Ptr<MgDataReader> customReader = dynamic_cast<MgDataReader*>(this->GetCustomReader(origReader, customFunc, customPropName));
+			origReader->Close();
+			reader = customReader;
+		}
+		else
+		{
+			reader = new MgdDataReader(connWrap, fdoReader);
+		}
     }
 
     MG_FEATURE_SERVICE_CHECK_CONNECTION_CATCH_AND_THROW(resource, L"MgdFeatureService::SelectAggregate")
@@ -3347,6 +3412,60 @@
 	return reader.Detach();
 }
 
+// Convert reader into a custom MgDataReader
+MgReader* MgdFeatureService::GetCustomReader(MgReader* reader, FdoFunction* customFunc, CREFSTRING propertyName)
+{
+    Ptr<MgReader> distReader;
+    Ptr<MgFeatureDistribution> featureDist =
+        MgFeatureDistribution::CreateDistributionFunction(reader, customFunc, propertyName);
+
+    distReader = featureDist->Execute();
+    return distReader.Detach();
+}
+
+bool MgdFeatureService::ContainsUdf(MgFeatureConnection* conn, FdoExpression* expression)
+{
+    bool isUdf = false;
+    bool fdoSupported = false;
+
+    // Downcast to FdoFunction
+    FdoFunction* function = dynamic_cast<FdoFunction*>(expression);
+
+    // If we are unable to downcast, it means it is not a function, it is just
+    // an expression. We do not do anything with this. We just pass it to FDO
+    if (function != NULL)
+    {
+        if (conn != NULL)
+        {
+            // Check if FDO supports this function, if so, let FDO handle it
+            fdoSupported = conn->IsSupportedFunction(function);
+        }
+
+        if (!fdoSupported)
+        {
+            // If function is not supported, then check if it is a custom function.
+            isUdf = IsCustomFunction(function);
+        }
+    }
+
+    return isUdf;
+}
+
+
+bool MgdFeatureService::IsCustomFunction(FdoFunction* fdoFunc)
+{
+    bool customFunc = false;
+
+    FdoString* funcNameAllowed = fdoFunc->GetName();
+    if (funcNameAllowed != NULL)
+    {
+        INT32 funcIndex = -1;
+        customFunc = MgFeatureUtil::FindCustomFunction(STRING(funcNameAllowed),funcIndex);
+    }
+
+    return customFunc;
+}
+
 MgPropertyCollection* MgdFeatureService::UpdateFeatures(MgResourceIdentifier* resource,
                                                         MgFeatureCommandCollection* commands,
                                                         bool useTransaction) 

Modified: trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.h
===================================================================
--- trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.h	2012-05-13 03:02:46 UTC (rev 6645)
+++ trunk/MgDev/Desktop/MgDesktop/Services/FeatureService.h	2012-05-13 04:07:19 UTC (rev 6646)
@@ -273,6 +273,10 @@
 											bool withLock,
                                             bool asScrollable);
 	
+	bool ContainsUdf(MgFeatureConnection* conn, FdoExpression* expression);
+	bool IsCustomFunction(FdoFunction* fdoFunc);
+	MgReader* GetCustomReader(MgReader* reader, FdoFunction* customFunc, CREFSTRING propertyName);
+
     static MgSpatialContextData* GetSpatialContextData(FdoISpatialContextReader* spatialReader, MgSpatialContextInfo* spatialContextInfo);
 
     // Methods for describe schema



More information about the mapguide-commits mailing list