[mapguide-commits] r6603 - in branches/2.4/MgDev/Desktop: DesktopUnmanagedApi/DotNet MapViewerTest MgDesktop MgDesktop/Services MgDesktop/Services/Rendering MgDesktop/System UnitTest

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sun Apr 29 18:11:03 EDT 2012


Author: jng
Date: 2012-04-29 15:11:03 -0700 (Sun, 29 Apr 2012)
New Revision: 6603

Added:
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.h
   branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.h
   branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.cpp
   branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.h
Modified:
   branches/2.4/MgDev/Desktop/DesktopUnmanagedApi/DotNet/MapGuideDesktopApiGen.xml
   branches/2.4/MgDev/Desktop/MapViewerTest/Form1.Designer.cs
   branches/2.4/MgDev/Desktop/MapViewerTest/Form1.cs
   branches/2.4/MgDev/Desktop/MapViewerTest/Form1.resx
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.h
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.h
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ServiceFactory.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/System/ClassId.h
   branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj
   branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj.filters
   branches/2.4/MgDev/Desktop/UnitTest/main.cpp
Log:
Add Profiling Service support to mg-desktop

Modified: branches/2.4/MgDev/Desktop/DesktopUnmanagedApi/DotNet/MapGuideDesktopApiGen.xml
===================================================================
--- branches/2.4/MgDev/Desktop/DesktopUnmanagedApi/DotNet/MapGuideDesktopApiGen.xml	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/DesktopUnmanagedApi/DotNet/MapGuideDesktopApiGen.xml	2012-04-29 22:11:03 UTC (rev 6603)
@@ -101,6 +101,7 @@
     <Header path="../../MgDesktop/Services/DrawingService.h" />
     <Header path="../../MgDesktop/Services/FeatureReader.h" />
     <Header path="../../MgDesktop/Services/FeatureService.h" />
+    <Header path="../../MgDesktop/Services/ProfilingService.h" />
     <Header path="../../MgDesktop/Services/RenderingService.h" />
     <Header path="../../MgDesktop/Services/ResourceService.h" />
     <Header path="../../MgDesktop/Services/ScrollableFeatureReader.h" />

Modified: branches/2.4/MgDev/Desktop/MapViewerTest/Form1.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewerTest/Form1.Designer.cs	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MapViewerTest/Form1.Designer.cs	2012-04-29 22:11:03 UTC (rev 6603)
@@ -57,21 +57,23 @@
             this.btnPlotToDwf = new System.Windows.Forms.ToolStripButton();
             this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
             this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
             this.splitContainer1 = new System.Windows.Forms.SplitContainer();
             this.splitContainer2 = new System.Windows.Forms.SplitContainer();
-            this.legend = new OSGeo.MapGuide.Viewer.MgLegend();
             this.ctxGroup = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.thisIsAGroupContextMenuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.ctxLayer = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.thisIsALayerContextMenuToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.propertyPane = new OSGeo.MapGuide.Viewer.MgPropertyPane();
-            this.viewer = new OSGeo.MapGuide.Viewer.MgMapViewer();
             this.ctxViewer = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.refreshMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.initialViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
+            this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
+            this.legend = new OSGeo.MapGuide.Viewer.MgLegend();
+            this.propertyPane = new OSGeo.MapGuide.Viewer.MgPropertyPane();
+            this.viewer = new OSGeo.MapGuide.Viewer.MgMapViewer();
             this.toolbar = new OSGeo.MapGuide.Viewer.MgDefaultToolbar();
-            this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
+            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
             this.statusStrip1.SuspendLayout();
             this.menuStrip1.SuspendLayout();
             this.toolStrip1.SuspendLayout();
@@ -227,9 +229,11 @@
             this.btnDigitizePolygon,
             this.toolStripSeparator1,
             this.btnPlotToDwf,
+            this.toolStripSeparator2,
             this.toolStripButton1,
             this.toolStripButton2,
-            this.toolStripButton3});
+            this.toolStripButton3,
+            this.toolStripButton4});
             this.toolStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
             this.toolStrip1.Location = new System.Drawing.Point(0, 25);
             this.toolStrip1.Name = "toolStrip1";
@@ -331,6 +335,15 @@
             this.toolStripButton2.Text = "Buffer";
             this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
             // 
+            // toolStripButton3
+            // 
+            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(59, 22);
+            this.toolStripButton3.Text = "Query";
+            this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click);
+            // 
             // splitContainer1
             // 
             this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -368,17 +381,6 @@
             this.splitContainer2.SplitterDistance = 236;
             this.splitContainer2.TabIndex = 0;
             // 
-            // legend
-            // 
-            this.legend.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.legend.GroupContextMenu = this.ctxGroup;
-            this.legend.LayerContextMenu = this.ctxLayer;
-            this.legend.Location = new System.Drawing.Point(0, 0);
-            this.legend.Name = "legend";
-            this.legend.Size = new System.Drawing.Size(208, 236);
-            this.legend.TabIndex = 0;
-            this.legend.ThemeCompressionLimit = 25;
-            // 
             // ctxGroup
             // 
             this.ctxGroup.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -407,28 +409,6 @@
             this.thisIsALayerContextMenuToolStripMenuItem.Text = "This is a layer context menu";
             this.thisIsALayerContextMenuToolStripMenuItem.Click += new System.EventHandler(this.thisIsALayerContextMenuToolStripMenuItem_Click);
             // 
-            // propertyPane
-            // 
-            this.propertyPane.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.propertyPane.Location = new System.Drawing.Point(0, 0);
-            this.propertyPane.Name = "propertyPane";
-            this.propertyPane.Size = new System.Drawing.Size(208, 225);
-            this.propertyPane.TabIndex = 0;
-            // 
-            // viewer
-            // 
-            this.viewer.ContextMenuStrip = this.ctxViewer;
-            this.viewer.ConvertTiledGroupsToNonTiled = true;
-            this.viewer.Cursor = System.Windows.Forms.Cursors.Default;
-            this.viewer.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.viewer.Location = new System.Drawing.Point(0, 0);
-            this.viewer.Name = "viewer";
-            this.viewer.SelectionColor = System.Drawing.Color.OrangeRed;
-            this.viewer.Size = new System.Drawing.Size(572, 465);
-            this.viewer.TabIndex = 1;
-            this.viewer.ZoomInFactor = 0.75D;
-            this.viewer.ZoomOutFactor = 1.35D;
-            // 
             // ctxViewer
             // 
             this.ctxViewer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -470,6 +450,49 @@
             this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolbar);
             this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1);
             // 
+            // toolStripButton4
+            // 
+            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(61, 22);
+            this.toolStripButton4.Text = "Profile";
+            this.toolStripButton4.ToolTipText = "Profile current map view";
+            this.toolStripButton4.Click += new System.EventHandler(this.toolStripButton4_Click);
+            // 
+            // legend
+            // 
+            this.legend.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.legend.GroupContextMenu = this.ctxGroup;
+            this.legend.LayerContextMenu = this.ctxLayer;
+            this.legend.Location = new System.Drawing.Point(0, 0);
+            this.legend.Name = "legend";
+            this.legend.Size = new System.Drawing.Size(208, 236);
+            this.legend.TabIndex = 0;
+            this.legend.ThemeCompressionLimit = 25;
+            // 
+            // propertyPane
+            // 
+            this.propertyPane.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.propertyPane.Location = new System.Drawing.Point(0, 0);
+            this.propertyPane.Name = "propertyPane";
+            this.propertyPane.Size = new System.Drawing.Size(208, 225);
+            this.propertyPane.TabIndex = 0;
+            // 
+            // viewer
+            // 
+            this.viewer.ContextMenuStrip = this.ctxViewer;
+            this.viewer.ConvertTiledGroupsToNonTiled = true;
+            this.viewer.Cursor = System.Windows.Forms.Cursors.Default;
+            this.viewer.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.viewer.Location = new System.Drawing.Point(0, 0);
+            this.viewer.Name = "viewer";
+            this.viewer.SelectionColor = System.Drawing.Color.OrangeRed;
+            this.viewer.Size = new System.Drawing.Size(572, 465);
+            this.viewer.TabIndex = 1;
+            this.viewer.ZoomInFactor = 0.75D;
+            this.viewer.ZoomOutFactor = 1.35D;
+            // 
             // toolbar
             // 
             this.toolbar.Dock = System.Windows.Forms.DockStyle.None;
@@ -483,14 +506,10 @@
             this.toolbar.Viewer = null;
             this.toolbar.ZoomOutMode = OSGeo.MapGuide.Viewer.ZoomOutMode.AutoZoom;
             // 
-            // toolStripButton3
+            // toolStripSeparator2
             // 
-            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(59, 22);
-            this.toolStripButton3.Text = "Query";
-            this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click);
+            this.toolStripSeparator2.Name = "toolStripSeparator2";
+            this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
             // 
             // Form1
             // 
@@ -574,6 +593,8 @@
         private System.Windows.Forms.ToolStripButton toolStripButton1;
         private System.Windows.Forms.ToolStripButton toolStripButton2;
         private System.Windows.Forms.ToolStripButton toolStripButton3;
+        private System.Windows.Forms.ToolStripButton toolStripButton4;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
     }
 }
 

Modified: branches/2.4/MgDev/Desktop/MapViewerTest/Form1.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewerTest/Form1.cs	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MapViewerTest/Form1.cs	2012-04-29 22:11:03 UTC (rev 6603)
@@ -475,5 +475,13 @@
             frm.Controls.Add(ctrl);
             frm.Show();
         }
+
+        private void toolStripButton4_Click(object sender, EventArgs e)
+        {
+            var prof = (MgProfilingService)fact.CreateService(MgServiceType.ProfilingService);
+            var opts = new MgRenderingOptions("PNG", 2, new MgColor(viewer.SelectionColor));
+            var result = prof.ProfileRenderDynamicOverlay(_map, (MgdSelection)viewer.GetSelection(), opts);
+            new XmlResponseDialog(result).ShowDialog();
+        }
     }
 }

Modified: branches/2.4/MgDev/Desktop/MapViewerTest/Form1.resx
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewerTest/Form1.resx	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MapViewerTest/Form1.resx	2012-04-29 22:11:03 UTC (rev 6603)
@@ -172,6 +172,21 @@
         KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
 </value>
   </data>
+  <data name="toolStripButton4.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+        YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
+        ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
+        HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
+        rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
+        TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
+        oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
+        7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
+        xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
+        LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
+        KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
+</value>
+  </data>
   <metadata name="ctxGroup.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>444, 17</value>
   </metadata>

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.h	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -48,6 +48,7 @@
 #include "Services/ScrollableFeatureReader.h"
 #include "Services/FeatureService.h"
 #include "Services/ImageFormats.h"
+#include "Services/ProfilingService.h"
 #include "Services/RenderingService.h"
 #include "Services/ResourceService.h"
 #include "Services/ServiceFactory.h"

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj	2012-04-29 22:11:03 UTC (rev 6603)
@@ -227,6 +227,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">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>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="Services\Resource\ByteSourceDwfInputStreamImpl.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -732,9 +738,16 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="System\TimerUtil.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>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Exception\AliasNotFoundException.h" />
+    <ClInclude Include="Services\ProfilingService.h" />
     <ClInclude Include="Services\Resource\ByteSourceDwfInputStreamImpl.h" />
     <ClInclude Include="Services\ByteSourceRasterStreamImpl.h" />
     <ClInclude Include="System\ClassId.h" />
@@ -828,6 +841,7 @@
     <ClInclude Include="Services\Resource\UnmanagedDataType.h" />
     <ClInclude Include="Services\Resource\ZipFileHandler.h" />
     <ClInclude Include="Services\Resource\ZipFileReader.h" />
+    <ClInclude Include="System\TimerUtil.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="..\braindump.txt" />

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcxproj.filters	2012-04-29 22:11:03 UTC (rev 6603)
@@ -273,6 +273,12 @@
     <ClCompile Include="Services\Resource\ZipFileReader.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Services\ProfilingService.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="System\TimerUtil.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Exception\AliasNotFoundException.h">
@@ -557,6 +563,12 @@
     <ClInclude Include="Services\Resource\ZipFileReader.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Services\ProfilingService.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="System\TimerUtil.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\braindump.txt" />

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -1,5 +1,6 @@
 #include "System/ConfigProperties.cpp"
 #include "System/PlatformInit.cpp"
+#include "System/TimerUtil.cpp"
 
 #include "Exception/AliasNotFoundException.cpp"
 #include "Exception/ConnectionFailedException.cpp"
@@ -26,6 +27,7 @@
 #include "Services/FeatureReader.cpp"
 #include "Services/FeatureService.cpp"
 #include "Services/ImageFormats.cpp"
+#include "Services/ProfilingService.cpp"
 #include "Services/RenderingService.cpp"
 #include "Services/ResourceService.cpp"
 #include "Services/ScrollableFeatureReader.cpp"

Copied: branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.cpp (from rev 6602, trunk/MgDev/Desktop/MgDesktop/Services/ProfilingService.cpp)
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,92 @@
+#include "ProfilingService.h"
+#include "ProfileResult.h"
+#include "ProfileRenderMapResult.h"
+#include "SAX2Parser.h" 
+
+MgProfilingService::MgProfilingService()
+{
+	Ptr<MgServiceFactory> fact = new MgServiceFactory();
+	m_svcRendering = static_cast<MgRenderingService*>(fact->CreateService(MgServiceType::RenderingService));
+}
+
+MgProfilingService::~MgProfilingService()
+{
+	SAFE_RELEASE(m_svcRendering);
+}
+
+MgByteReader* MgProfilingService::ProfileRenderDynamicOverlay(
+        MgdMap* map,
+        MgdSelection* selection,
+        MgRenderingOptions* options)
+{
+	Ptr<MgByteReader> ret;
+    
+    MG_TRY()
+
+    if (NULL == map)
+        throw new MgNullArgumentException(L"MgServerProfilingService.ProfileRenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    auto_ptr<ProfileRenderMapResult> pPRMResult; // a pointer points to Profile Render Map Result
+    pPRMResult.reset(new ProfileRenderMapResult());
+
+    // Start to profile the ProfileRenderDynamicOverlay process
+    double renderMapStart = MgTimerUtil::GetTime(); 
+    m_svcRendering->RenderDynamicOverlay(map, selection, options, pPRMResult.get());
+    double renderMapEnd = MgTimerUtil::GetTime();
+
+    pPRMResult->SetRenderTime(renderMapEnd - renderMapStart);
+    pPRMResult->SetProfileResultType(ProfileResult::ProfileRenderDynamicOverlay);
+
+    // Serialize the ProfileRenderMapResult to xml
+    MdfParser::SAX2Parser parser;
+    auto_ptr<Version> version;
+    version.reset(new Version(2,4,0));
+    string content = parser.SerializeToXML(pPRMResult.get(),version.get());
+    ret = new MgByteReader(MgUtil::MultiByteToWideChar(content), MgMimeType::Xml);
+
+    MG_CATCH_AND_THROW(L"MgServerProfilingService.ProfileRenderDynamicOverlay")
+
+    return ret.Detach();
+}
+
+
+MgByteReader* MgProfilingService::ProfileRenderMap(
+        MgdMap* map,
+        MgdSelection* selection,
+        MgCoordinate* center,
+        double scale,
+        INT32 width,
+        INT32 height,
+        MgColor* backgroundColor,
+        CREFSTRING format,
+        bool bKeepSelection)
+{
+	 Ptr<MgByteReader> ret;
+    
+    MG_TRY()
+
+    if (NULL == map)
+        throw new MgNullArgumentException(L"MgServerProfilingService.ProfileRenderMap", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    auto_ptr<ProfileRenderMapResult> pPRMResult; // a pointer points to Profile Render Map Result
+    pPRMResult.reset(new ProfileRenderMapResult());
+
+    // Start to profile the ProfileRenderMap process
+    double renderMapStart = MgTimerUtil::GetTime(); 
+    m_svcRendering->RenderMap(map, selection, center, scale, width, height, backgroundColor, format, bKeepSelection, pPRMResult.get());
+    double renderMapEnd = MgTimerUtil::GetTime();
+
+    pPRMResult->SetRenderTime(renderMapEnd - renderMapStart);
+    pPRMResult->SetProfileResultType(ProfileResult::ProfileRenderMap);
+
+    // Serialize the ProfileRenderMapResult to xml
+    MdfParser::SAX2Parser parser;
+    auto_ptr<Version> version;
+    version.reset(new Version(2,4,0));
+    string content = parser.SerializeToXML(pPRMResult.get(),version.get());
+    ret = new MgByteReader(MgUtil::MultiByteToWideChar(content), MgMimeType::Xml);
+
+    MG_CATCH_AND_THROW(L"MgServerProfilingService.ProfileRenderMap")
+
+    return ret.Detach();
+}
\ No newline at end of file

Copied: branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.h (from rev 6602, trunk/MgDev/Desktop/MgDesktop/Services/ProfilingService.h)
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ProfilingService.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,128 @@
+#ifndef DESKTOP_PROFILING_SERVICE_H
+#define DESKTOP_PROFILING_SERVICE_H
+
+#include "MgDesktop.h"
+
+class MgRenderingOptions;
+class MgRenderingService;
+
+/// \defgroup MgProfilingService MgProfilingService
+/// \ingroup Profiling_Service_Module
+/// \{
+
+/// \brief
+/// This class provides services to profile exsiting MapGuide APIs 
+class MG_DESKTOP_API MgProfilingService : public MgService
+{
+PUBLISHED_API:
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Profile the process of rendering all dynamic layers in the specified 
+    /// MgMap to a dynamic overlay image with a transparent background.
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param selection
+    /// Input
+    /// map feature selection. Specifies the selected features on the map
+    /// \param options
+    /// Input
+    /// rendering options
+    ///
+    /// \return
+    /// A byte reader containing the profile result
+    ///
+    virtual MgByteReader* ProfileRenderDynamicOverlay(
+        MgdMap* map,
+        MgdSelection* selection,
+        MgRenderingOptions* options);
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Profile the process of rendering a MgMap to the requested image 
+    /// format with specified center point and scale.
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param selection
+    /// Input
+    /// map feature selection. Specifies the selected features on the map
+    /// \param center
+    /// Input
+    /// map center point. Specifies the center point for the map
+    /// \param scale
+    /// Input
+    /// map scale. Specifies the scale for the map
+    /// \param width
+    /// Input
+    /// image width. Specifies the image width in pixels
+    /// \param height
+    /// Input
+    /// image height. Specifies the image height in pixels
+    /// \param backgroundColor
+    /// Input
+    /// background color. Specifies the map background color
+    /// \param format
+    /// Input
+    /// image format. Defines the format of the resulting image
+    /// \param bKeepSelection
+    /// Input
+    /// true if you want to keep the selection
+    ///
+    /// \return
+    /// A byte reader containing the profile result
+    ///
+    virtual MgByteReader* ProfileRenderMap(
+        MgdMap* map,
+        MgdSelection* selection,
+        MgCoordinate* center,
+        double scale,
+        INT32 width,
+        INT32 height,
+        MgColor* backgroundColor,
+        CREFSTRING format,
+        bool bKeepSelection);
+
+INTERNAL_API:
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct an MgProfileService object.
+    ///
+    MgProfilingService();
+
+EXTERNAL_API:
+	virtual ~MgProfilingService();
+
+protected:
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Get the class Id
+    ///
+    /// \return
+    /// The integer value
+    ///
+	virtual INT32 GetClassId() { return m_cls_id; }
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Dispose this object
+    ///
+    /// \return
+    /// Nothing
+    ///
+	virtual void Dispose() { delete this; }
+
+private:
+	MgRenderingService* m_svcRendering;
+
+CLASS_ID:
+    static const INT32 m_cls_id = MapGuide_Desktop_ProfilingService_ProfilingService;
+};
+/// \}
+
+#endif
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.cpp	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -351,7 +351,8 @@
                                   double scale,
                                   bool selection,
                                   bool extractColors,
-                                  CancelStylization cancel)
+                                  ProfileRenderLayersResultBase* pPRLsResult,
+								  CancelStylization cancel)
 {
     #ifdef _DEBUG
     long dwStart = GetTickCount();
@@ -362,10 +363,12 @@
     // stylization operation.
     TransformCacheMap transformCache;
 
-    Ptr<MgStringCollection> layerIds = new MgStringCollection();
     // Get the layers' resource content in a single request by adding them to a collection
     for (int i = layers->GetCount()-1; i >= 0; i--)
     {
+        auto_ptr<MdfModel::LayerDefinition> ldf;
+        RSMgFeatureReader* rsReader = NULL;
+
         Ptr<MgLayerBase> mapLayer = layers->GetItem(i);
 
         //don't send data if layer is not currently visible
@@ -386,60 +389,43 @@
                 continue;
         }
 
-        Ptr<MgResourceIdentifier> mapLayerId = mapLayer->GetLayerDefinition();
-        layerIds->Add(mapLayerId->ToString());
-    }
 
-    // request the collection from resource service and add ResourceContent to the individual layers
-    if(layerIds->GetCount() != 0)
-    {
-        Ptr<MgStringCollection> layerContents = svcResource->GetResourceContents(layerIds, NULL);
-        for(int i = 0; i < layerIds->GetCount(); i ++)
-        {
-            for(int j = 0; j < layers->GetCount(); j ++)
-            {
-                Ptr<MgLayerBase> mapLayer = layers->GetItem(j);
-                Ptr<MgResourceIdentifier> mapLayerId = mapLayer->GetLayerDefinition();
-                if(mapLayerId->ToString() == layerIds->GetItem(i))
-                {
-                    mapLayer->SetLayerResourceContent(layerContents->GetItem(i));
-                    break;
-                }
-            }
-        }
-    }
-
-    // cycle over the layers and do stylization
-    for (int i = layers->GetCount()-1; i >= 0; i--)
-    {
-        auto_ptr<MdfModel::LayerDefinition> ldf;
-        RSMgFeatureReader* rsReader = NULL;
-
-        Ptr<MgLayerBase> mapLayer = layers->GetItem(i);
-
         #ifdef _DEBUG
         long dwLayerStart = GetTickCount();
         ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYERSTART** Name:%W  VAS:%W\n", i, (mapLayer->GetName()).c_str(), mapLayer->IsVisibleAtScale(scale)? L"True" : L"False"));
         #endif
 
-        if(mapLayer->GetLayerResourceContent() == L"")
-            continue;
 
+
         MG_SERVER_MAPPING_SERVICE_TRY()
 
-            // get layer definition using SAX XML Parser
-            ldf.reset(MgLayerBase::GetLayerDefinition(mapLayer->GetLayerResourceContent()));
+            // Just profile visible layers?
+            TransformCache* TCForProfile = NULL;
+            double minScale_Profile = 0.0;
+            double maxScale_Profile = MdfModel::VectorScaleRange::MAX_MAP_SCALE;
+            if(NULL != pPRLsResult)
+            {
+                ProfileRenderLayerResult* pPRLResult = new ProfileRenderLayerResult(); // points points to Profile Render Layers Result
+               
+                // Set the start time of stylizing layer
+                pPRLResult->SetRenderTime(MgTimerUtil::GetTime());
 
+                ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+                pPRLResultColl->Adopt(pPRLResult);
+            }
+
+            //get layer definition
+            Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+            ldf.reset(MgLayerBase::GetLayerDefinition(svcResource, layerid));
+
             Ptr<MgLayerGroup> group = mapLayer->GetGroup();
-
-            /*
+			/*
             MgLogDetail logDetail(MgServiceType::MappingService, MgLogDetail::InternalTrace, L"MgMappingUtil.StylizeLayers", mgStackParams);
             logDetail.AddString(L"Map",map->GetName());
-            Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+
             logDetail.AddResourceIdentifier(L"LayerId",layerid);
             logDetail.Create();
-            */
-
+			*/
             //base map layers are not editable
             bool bEditable = true;
             if (mapLayer->GetLayerType() == MgLayerType::BaseMap)
@@ -486,6 +472,9 @@
 
                 if (scaleRange)
                 {
+                    minScale_Profile = scaleRange->GetMinScale();
+                    maxScale_Profile = scaleRange->GetMaxScale();
+
                     #ifdef _DEBUG
                     ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W\n", i, (mapLayer->GetName()).c_str()));
                     #endif
@@ -514,6 +503,7 @@
 
                     //get a transform from layer coord sys to map coord sys
                     TransformCache* item = TransformCache::GetLayerToMapTransform(transformCache, vl->GetFeatureName(), featResId, dstCs, csFactory, svcFeature);
+                    TCForProfile = item;
                     Ptr<MgCoordinateSystem> layerCs = item? item->GetCoordSys() : NULL;
                     MgCSTrans* xformer = item? item->GetTransform() : NULL;
 
@@ -597,6 +587,9 @@
 
                 if (scaleRange)
                 {
+                    minScale_Profile = scaleRange->GetMinScale();
+                    maxScale_Profile = scaleRange->GetMaxScale();
+
                     //get feature source id
                     STRING sfeatResId = gl->GetResourceID();
                     Ptr<MgResourceIdentifier> featResId = new MgResourceIdentifier(sfeatResId);
@@ -621,6 +614,7 @@
                         ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sg_fdoRfpMutex));
                         item = TransformCache::GetLayerToMapTransform(transformCache, gl->GetFeatureName(), featResId, dstCs, csFactory, svcFeature);
                     }
+                    TCForProfile = item;
 
                     Ptr<MgCoordinateSystem> layerCs = item? item->GetCoordSys() : NULL;
                     MgCSTrans* xformer = item? item->GetTransform() : NULL;
@@ -649,7 +643,7 @@
                     // On error, ignore the exception and use the original extent.
                     MG_TRY()
                     Ptr<MgSpatialContextReader> contextReader = svcFeature->GetSpatialContexts(featResId, false);
-                    STRING layerWkt = layerCs->ToString();
+                    STRING layerWkt = (NULL == layerCs.p) ? L"" : layerCs->ToString();
                     while (contextReader.p != NULL && contextReader->ReadNext())
                     {
                         // Try to find wkt for feature's coordinate system
@@ -731,6 +725,9 @@
             }
             else if (dl) //############################################################################ drawing layer
             {
+                minScale_Profile = dl->GetMinScale();
+                maxScale_Profile = dl->GetMaxScale();
+
                 // make sure we have a valid scale range
                 if (scale >= dl->GetMinScale() && scale < dl->GetMaxScale())
                 {
@@ -773,6 +770,7 @@
                             }
                         }
                     }
+                    TCForProfile = cached;
 
                     //get DWF from drawing service
                     Ptr<MgByteReader> reader = svcDrawing->GetSection(resId, dl->GetSheet());
@@ -789,6 +787,60 @@
                 #endif
             } // end layer switch
 
+            if(NULL != pPRLsResult)
+            {
+                ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+                
+                // Get current ProfileRenderLayerResult
+                ProfileRenderLayerResult* pPRLResult = pPRLResultColl->GetAt(pPRLResultColl->GetCount()-1); //TODO: check index
+                
+                // Calculate the time spent on stylizing layer
+                double stylizeLayerTime = MgTimerUtil::GetTime() - pPRLResult->GetRenderTime();
+                pPRLResult->SetRenderTime(stylizeLayerTime);
+
+                pPRLResult->SetResourceId(layerid->ToString());
+                pPRLResult->SetLayerName(mapLayer->GetName());
+
+                if(vl)
+                {
+                    pPRLResult->SetLayerType(L"Vector Layer"); //NOXLATE?
+                }
+                else if(dl)
+                {
+                    pPRLResult->SetLayerType(L"Drawing Layer"); //NOXLATE?
+                }
+                else if(gl)
+                {
+                    pPRLResult->SetLayerType(L"Grid Layer"); //NOXLATE?
+                }
+                else
+                {
+                    pPRLResult->SetLayerType(L"Unknown Type"); //NOXLATE?
+                }
+                
+                pPRLResult->SetFeatureClassName(mapLayer->GetFeatureClassName());
+
+                STRING layerCsCode = L"";
+                if(NULL != TCForProfile)
+                {
+                    Ptr<MgCoordinateSystem> layerCS = TCForProfile->GetCoordSys();
+                    layerCsCode = layerCS->GetCsCode();
+                }
+                pPRLResult->SetCoordinateSystem(layerCsCode);
+
+                ScaleRange* pScaleRange = new ScaleRange();
+                pScaleRange->SetMinScale(minScale_Profile);
+                pScaleRange->SetMaxScale(maxScale_Profile);
+                pPRLResult->AdoptScaleRange(pScaleRange);
+
+                STRING filter = L""; // NOXLATE
+                if (overrideFilters)
+                {
+                    filter = overrideFilters->GetItem(i);
+                }
+                pPRLResult->SetFilter(filter.empty()? mapLayer->GetFilter() : filter);
+            }
+
         MG_SERVER_MAPPING_SERVICE_CATCH(L"MgMappingUtil.StylizeLayers");
 
         delete rsReader;
@@ -799,7 +851,7 @@
             //       layer failed in addition to logging the error.
             //MgServerManager* serverManager = MgServerManager::GetInstance();
             //STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
-            STRING locale = MgResources::DefaultMessageLocale;
+			STRING locale = MgResources::DefaultMessageLocale;
 
             // Get the layer that failed
             MgStringCollection arguments;
@@ -828,10 +880,30 @@
             ACE_DEBUG( (LM_DEBUG, err.c_str()) );
 #endif
             // TODO could throw here depending on a serverconfig setting (RFC64)
-            //throw exception;
+//          throw exception;
+
+
+            if(NULL != pPRLsResult)
+            {
+                ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+                
+                // Get current ProfileRenderLayerResult
+                ProfileRenderLayerResult* pPRLResult = pPRLResultColl->GetAt(pPRLResultColl->GetCount()-1); //TODO: check index
+                
+                // Calculate the time spent on stylizing layer
+                double stylizeLayerTime = MgTimerUtil::GetTime() - pPRLResult->GetRenderTime();
+                pPRLResult->SetRenderTime(stylizeLayerTime);
+
+                Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+                pPRLResult->SetResourceId(layerid->ToString());
+                pPRLResult->SetLayerName(mapLayer->GetName());
+
+                pPRLResult->SetError(message);
+            }
         } // if exception
     } // for all layers
 
+
     #ifdef _DEBUG
     ACE_DEBUG((LM_INFO, L"(%t)StylizeLayers() **MAPDONE** Layers:%d  Total Time:%6.4f (s)\n\n", layers->GetCount(), (GetTickCount()-dwStart)/1000.0));
     #endif

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.h	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Rendering/MappingUtil.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -5,6 +5,7 @@
 #include "MapLayer/Layer.h"
 #include "MapLayer/Map.h"
 #include "RendererStyles.h"
+#include "ProfileRenderLayersResult.h"
 
 typedef bool (*CancelStylization)(void* userData);
 
@@ -57,6 +58,7 @@
                               double scale,
                               bool selection = false,
                               bool extractColors = false,
+							  ProfileRenderLayersResultBase* = NULL,
                               CancelStylization cancel = NULL);
 
     static RSMgFeatureReader* ExecuteFeatureQuery(MgFeatureService* svcFeature,

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -149,7 +149,8 @@
                           m_maxRasterImageHeight,
                           MgConfigProperties::DefaultRenderingServicePropertyMaxRasterImageHeight);
 
-    pConf->GetIntValue(MgConfigProperties::RenderingServicePropertiesSection,
+	// Set Mapping Service related properties
+	pConf->GetIntValue(MgConfigProperties::RenderingServicePropertiesSection,
                           MgConfigProperties::RenderingServicePropertyRasterGridSizeForPlot,
                           m_rasterGridSizeForPlot,
                           MgConfigProperties::DefaultRenderingServicePropertyRasterGridSizeForPlot);
@@ -343,10 +344,511 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+void MgRenderingService::SetConnectionProperties(MgConnectionProperties*)
+{
+    // Do nothing.  No connection properties are required for server-side service objects.
+}
+
+MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
+                                               MgPlotSpecification* plotSpec,
+                                               MgLayout* layout,
+                                               MgDwfVersion* dwfVersion)
+{
+    Ptr<MgByteReader> byteReader;
+
+    MG_SERVER_MAPPING_SERVICE_TRY()
+
+    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
+
+    if (NULL == map  || NULL == dwfVersion || NULL == plotSpec )
+    {
+        throw new MgNullArgumentException(
+            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Create a MgMapPlot which will be passed to GenerateMultiPlot
+    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, plotSpec, layout);
+
+    // Add it to a MgMapPlotCollecion
+    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
+    mapPlots->Add(mapPlot);
+
+    // Create the plot
+    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
+
+    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
+
+    return byteReader.Detach();
+}
+
+MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
+                                               MgCoordinate* center,
+                                               double scale,
+                                               MgPlotSpecification* plotSpec,
+                                               MgLayout* layout,
+                                               MgDwfVersion* dwfVersion)
+{
+    Ptr<MgByteReader> byteReader;
+
+    MG_SERVER_MAPPING_SERVICE_TRY()
+
+    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
+
+    if (NULL == map  || NULL == center || NULL == dwfVersion || NULL == plotSpec )
+    {
+        throw new MgNullArgumentException(
+            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Create a MgMapPlot which will be passed to GenerateMultiPlot
+    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, center, scale, plotSpec, layout);
+
+    // Add it to a MgMapPlotCollecion
+    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
+    mapPlots->Add(mapPlot);
+
+    // Create the plot
+    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
+
+    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
+
+    return byteReader.Detach();
+}
+
+MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
+                                               MgEnvelope* extents,
+                                               bool expandToFit,
+                                               MgPlotSpecification* plotSpec,
+                                               MgLayout* layout,
+                                               MgDwfVersion* dwfVersion)
+{
+    Ptr<MgByteReader> byteReader;
+
+    MG_SERVER_MAPPING_SERVICE_TRY()
+
+    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
+
+    if (NULL == map  || NULL == extents || NULL == plotSpec || NULL == dwfVersion )
+    {
+        throw new MgNullArgumentException(
+            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Make a copy of the extents
+    Ptr<MgCoordinate> oldll = extents->GetLowerLeftCoordinate();
+    Ptr<MgCoordinate> oldur = extents->GetUpperRightCoordinate();
+    Ptr<MgCoordinate> ll = new MgCoordinateXY(oldll->GetX(), oldll->GetY());
+    Ptr<MgCoordinate> ur = new MgCoordinateXY(oldur->GetX(), oldur->GetY());
+    if (ll == NULL || ur == NULL)
+    {
+        throw new MgNullArgumentException(L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+    Ptr<MgEnvelope> env = new MgEnvelope(ll, ur);
+
+    // Create a MgMapPlot which will be passed to GenerateMultiPlot
+    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, env, expandToFit, plotSpec, layout);
+
+    // Add it to a MgMapPlotCollecion
+    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
+    if (mapPlot == NULL || mapPlots == NULL)
+    {
+        throw new MgNullArgumentException(L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+    mapPlots->Add(mapPlot);
+
+    // Create the plot
+    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
+
+    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
+
+    return byteReader.Detach();
+}
+
+MgByteReader* MgRenderingService::GenerateMultiPlot(MgMapPlotCollection* mapPlots,
+                                                    MgDwfVersion* dwfVersion)
+{
+    Ptr<MgByteReader> byteReader;
+
+    MG_SERVER_MAPPING_SERVICE_TRY()
+
+    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GenerateMultiPlot()");
+
+    if (0 == mapPlots || 0 == dwfVersion)
+    {
+        throw new MgNullArgumentException(
+            L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // get a temporary file to write out EPlot DWF to
+    // TODO: clean the temp file name prefix
+    STRING dwfName = MgFileUtil::GenerateTempFileName(false, L"default_prefix");
+
+    EPlotRenderer dr(dwfName.c_str(), 0, 0, L"inches");  // NOXLATE
+
+    dr.SetRasterGridSize(m_rasterGridSizeForPlot);
+    dr.SetMinRasterGridSize(m_minRasterGridSizeForPlot);
+    dr.SetRasterGridSizeOverrideRatio(m_rasterGridSizeOverrideRatioForPlot);
+    dr.SetMaxRasterImageWidth(m_maxRasterImageWidth);
+    dr.SetMaxRasterImageHeight(m_maxRasterImageHeight);
+
+    RSMgSymbolManager mgr(m_svcResource);
+    dr.SetSymbolManager(&mgr);
+
+    // process the MapPlot collection
+    for (int nMapPlotIndex = 0; nMapPlotIndex < mapPlots->GetCount(); nMapPlotIndex++)
+    {
+        Ptr<MgMapPlot> mapPlot = mapPlots->GetItem(nMapPlotIndex);
+        if (NULL == mapPlot)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgdMap> map = mapPlot->GetMap();
+        if (NULL == map)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgPlotSpecification> plotSpec = mapPlot->GetPlotSpecification();
+        if (NULL == plotSpec)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgLayout> layout = mapPlot->GetLayout();
+
+        double width = plotSpec->GetPaperWidth();
+        double height = plotSpec->GetPaperHeight();
+        STRING pageUnits = plotSpec->GetPageSizeUnits();
+
+        dr.SetPageWidth(width);
+        dr.SetPageHeight(height);
+        dr.SetPageSizeUnits(pageUnits);
+        dr.SetMapWidth(width);
+        dr.SetMapHeight(height);
+        dr.mapBoundsHeight() = height;
+
+        // temporary place for the resId of the Map
+        Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+
+        // request extenst
+        Ptr<MgEnvelope> env = map->GetDataExtent();
+        if (env == NULL)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgCoordinate> ll = env->GetLowerLeftCoordinate();
+        Ptr<MgCoordinate> ur = env->GetUpperRightCoordinate();
+        if (ll == NULL || ur == NULL)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        RS_Bounds b(ll->GetX(), ll->GetY(), ur->GetX(), ur->GetY());
+
+        //if requested data extent is not valid, use map definition extent
+        // this may be removed eventually, but is a good sanity check nonetheless
+        if (!b.IsValid())
+        {
+            Ptr<MgEnvelope> env2 = map->GetMapExtent();
+            if (env2 == NULL)
+            {
+                throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+
+            Ptr<MgCoordinate> ll2 = env2->GetLowerLeftCoordinate();
+            Ptr<MgCoordinate> ur2 = env2->GetUpperRightCoordinate();
+            if (ll2 == NULL || ur2 == NULL)
+            {
+                throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+
+            b.minx = ll2->GetX();
+            b.miny = ll2->GetY();
+            b.maxx = ur2->GetX();
+            b.maxy = ur2->GetY();
+        }
+
+        // Create a simple print layout containing only the map
+        Ptr<MgPrintLayout> printLayout = new MgPrintLayout();
+        if (printLayout == NULL)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        if (NULL != layout)
+        {
+            Ptr<MgResourceIdentifier> resID = layout->GetLayout();
+            printLayout->Create(m_svcResource, resID);
+            printLayout->SetPlotSize(plotSpec);
+            printLayout->SetScaleBarUnits(layout->GetUnitType());
+            printLayout->SetPlotTitle(layout->GetTitle());
+
+            Ptr<MgPlotSpecification> spec = printLayout->GetPlotSize();
+
+            width = spec->GetPaperWidth();
+            height = spec->GetPaperHeight();
+            pageUnits = spec->GetPageSizeUnits();
+        }
+        else
+        {
+            printLayout->SetPlotSize(plotSpec);
+        }
+
+        printLayout->PageWidth() = width;
+        printLayout->PageHeight() = height;
+        printLayout->Units() = pageUnits;
+
+        dr.EnableLayoutPlot();
+
+        //get the map coordinate system
+        MdfModel::MdfString srs = map->GetMapSRS();
+        Ptr<MgCoordinateSystem> dstCs;
+        if (!srs.empty())
+        {
+            //let's not fail here if coord sys conversion fails for the
+            //map's coordinate system. Instead we will fail per layer at a later stage
+            try
+            {
+                dstCs = m_pCSFactory->Create(srs);
+            }
+            catch (MgInvalidCoordinateSystemException* e)
+            {
+                e->Release();
+            }
+        }
+
+        double metersPerUnit = (dstCs.p) ? dstCs->ConvertCoordinateSystemUnitsToMeters(1.0) : 1.0;
+        RS_String units = (dstCs.p) ? dstCs->GetUnits() : L"";
+
+        double dMapScale = 0.0;
+        Ptr<MgCoordinate> center = new MgCoordinateXY(0, 0);
+        Ptr<MgEnvelope> extents = map->GetMapExtent();
+        if (center == NULL || extents == NULL)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        switch (mapPlot->GetMapPlotInstruction())
+        {
+        case MgMapPlotInstruction::UseMapCenterAndScale:
+            {
+                dMapScale = map->GetViewScale();
+                if (dMapScale <= 0)
+                {
+                    Ptr<MgEnvelope> extents = map->GetDataExtent();
+                    if (extents == NULL)
+                    {
+                        throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                    }
+                    printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight());
+                    double mapWidth = dr.mapWidth();
+                    double mapHeight = dr.mapHeight();
+                    if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0) // NOXLATE
+                    {
+                        mapWidth *= MM_TO_IN;
+                        mapHeight *= MM_TO_IN;
+                    }
+
+                    double scaleToFitX = (extents->GetWidth() * metersPerUnit * M_TO_IN) / mapWidth;
+                    double scaleToFitY = (extents->GetHeight() * metersPerUnit * M_TO_IN) / mapHeight;
+                    dMapScale = rs_max(scaleToFitX, scaleToFitY);
+                }
+
+                Ptr<MgPoint> pt = map->GetViewCenter();
+                center = pt->GetCoordinate();
+                break;
+            }
+        case MgMapPlotInstruction::UseOverriddenCenterAndScale:
+            {
+                dMapScale = mapPlot->GetScale();
+                center = mapPlot->GetCenter();
+                break;
+            }
+        case MgMapPlotInstruction::UseOverriddenExtent:
+            {
+                // Compute the plotCenter and plotScale from the extents
+                extents = mapPlot->GetExtent();
+                //...plotCenter
+                Ptr<MgCoordinate> plotll = extents->GetLowerLeftCoordinate();
+                Ptr<MgCoordinate> plotur = extents->GetUpperRightCoordinate();
+                if (plotll == NULL || plotur == NULL)
+                {
+                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                }
+                double minX = plotll->GetX();
+                double minY = plotll->GetY();
+                double maxX = plotur->GetX();
+                double maxY = plotur->GetY();
+                double centerX = minX + (maxX - minX) * 0.5;
+                double centerY = minY + (maxY - minY) * 0.5;
+                //
+                //...plotScale
+                printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight());
+                double mapWidth = dr.mapWidth();
+                double mapHeight = dr.mapHeight();
+                if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0)  // NOXLATE
+                {
+                    mapWidth *= MM_TO_IN;
+                    mapHeight *= MM_TO_IN;
+                }
+
+                double scaleToFitX = (extents->GetWidth() * metersPerUnit * M_TO_IN) / mapWidth;
+                double scaleToFitY = (extents->GetHeight() * metersPerUnit * M_TO_IN) / mapHeight;
+                dMapScale = rs_max(scaleToFitX, scaleToFitY);
+
+                map->SetViewScale(dMapScale);
+                center = new MgCoordinateXY(centerX, centerY);
+                if (center == NULL)
+                {
+                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                }
+                Ptr<MgPoint> centerpt = new MgPoint(center);
+                if (centerpt == NULL)
+                {
+                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                }
+                map->SetViewCenter(centerpt);
+                break;
+            }
+        default:
+            {
+                MgStringCollection arguments;
+                arguments.Add(L"1");
+                arguments.Add(L"MgMapPlotCollection");
+
+                throw new MgInvalidArgumentException(L"MgRenderingService::GenerateMultiPlot",
+                    __LINE__, __WFILE__, &arguments, L"MgInvalidMapPlotCollectionMapPlotInstruction", NULL);
+            }
+            break;
+        }
+
+        printLayout->SetPlotCenter(center);
+        printLayout->SetPlotScale(dMapScale);
+
+        // Get the map background color
+        RS_Color bgcolor;
+        StylizationUtil::ParseColor( map->GetBackgroundColor(), bgcolor);
+
+        // Get the layout background color
+        RS_Color layoutColor;
+        Ptr<MgColor> bgColor = printLayout->GetBackgroundColor();
+        layoutColor.red() = bgColor->GetRed();
+        layoutColor.green() = bgColor->GetGreen();
+        layoutColor.blue() = bgColor->GetBlue();
+
+        // Get the session ID
+        STRING sessionId;
+        /*Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
+        if (userInfo != NULL)
+            sessionId = userInfo->GetMgSessionId();*/
+
+        RS_MapUIInfo mapInfo(sessionId, map->GetName(), L"", srs, units, layoutColor);
+
+        // Dynamically adjust the width and height of the map
+        printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight(), mapPlot->GetExpandToFit());
+
+        Ptr<MgCoordinate> newll;
+        Ptr<MgCoordinate> newur;
+        if (mapPlot->GetMapPlotInstruction() != MgMapPlotInstruction::UseOverriddenExtent || mapPlot->GetExpandToFit())
+        {
+            double mapWidth = dr.mapWidth();
+            double mapHeight = dr.mapHeight();
+            if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0)  // NOXLATE
+            {
+                mapWidth *= MM_TO_IN;
+                mapHeight *= MM_TO_IN;
+            }
+
+            env = printLayout->DetermineLayoutMapExtents(map, metersPerUnit, mapWidth, mapHeight);
+
+            newll = env->GetLowerLeftCoordinate();
+            newur = env->GetUpperRightCoordinate();
+        }
+        else if (mapPlot->GetMapPlotInstruction() == MgMapPlotInstruction::UseOverriddenExtent && !mapPlot->GetExpandToFit())
+        {
+            newll = extents->GetLowerLeftCoordinate();
+            newur = extents->GetUpperRightCoordinate();
+        }
+
+        b.minx = newll->GetX();
+        b.miny = newll->GetY();
+        b.maxx = newur->GetX();
+        b.maxy = newur->GetY();
+
+        SEMgSymbolManager semgr(m_svcResource);
+        DefaultStylizer ds(&semgr);
+
+        double dpi = map->GetDisplayDpi();
+        dr.StartMap(&mapInfo, b, dMapScale, dpi, metersPerUnit);
+
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        if (layers == NULL)
+        {
+            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        // Define a polygon to represent the map extents and fill it with the map background color
+        dr.StartLayer(NULL, NULL);
+        LineBuffer lb(5);
+        lb.MoveTo(b.minx, b.miny);
+        lb.LineTo(b.maxx, b.miny);
+        lb.LineTo(b.maxx, b.maxy);
+        lb.LineTo(b.minx, b.maxy);
+        lb.Close();
+
+        RS_LineStroke lineStroke;
+        RS_FillStyle fillStyle(lineStroke, bgcolor, layoutColor, L"Solid");  // NOXLATE
+        dr.ProcessPolygon(&lb, fillStyle);
+        dr.EndLayer();
+
+        //transfer layers to a temporary collection
+        //here it doesn't matter but in the rendering service it does
+        Ptr<MgReadOnlyLayerCollection> rolc = new MgReadOnlyLayerCollection();
+
+        for (int u=0; u<layers->GetCount(); u++)
+        {
+            Ptr<MgLayerBase> lr = layers->GetItem(u);
+            rolc->Add(lr);
+        }
+
+        //stylize all the map layers
+        MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
+                                     rolc, NULL, &ds, &dr, dstCs, false, false, dMapScale);
+
+        // Finish adding the map to the page
+        // Calculate the the height of the map bounds on the page (in page units)
+        dr.mapBoundsHeight() = b.height() * dr.mapWidth()/b.width();
+
+        //construct one every time -- not really a bottleneck
+        MgLegendPlotUtil lu(m_svcResource);
+
+        // Now add the rest of the layout element to the page
+        lu.AddLayoutElements(printLayout, (STRING)mapInfo.name(), mapResId->ToString(), map, layers, b, dMapScale, metersPerUnit, dr);
+
+        dr.EndMap();
+    }
+
+    dr.Done();
+
+    // write out the file
+    Ptr<MgByteSource> bs = new MgByteSource(dwfName, true);
+
+    bs->SetMimeType(MgMimeType::Dwf);
+    byteReader = bs->GetReader();
+
+    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GenerateMultiPlot")
+
+    return byteReader.Detach();
+}
+
+// ---------------------------------- BEGIN Rendering Service APIs ----------------------------------------------- //
+
+///////////////////////////////////////////////////////////////////////////////
 MgByteReader* MgRenderingService::RenderTile(MgdMap* map,
-                                             CREFSTRING baseMapLayerGroupName,
-                                             INT32 tileColumn,
-                                             INT32 tileRow)
+                                                   CREFSTRING baseMapLayerGroupName,
+                                                   INT32 tileColumn,
+                                                   INT32 tileRow)
 {
     Ptr<MgByteReader> ret;
 
@@ -373,7 +875,7 @@
         arguments.Add(baseMapLayerGroupName);
 
         throw new MgInvalidArgumentException(L"MgRenderingService.RenderTile",
-            __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
+            __LINE__, __WFILE__, &arguments, L"MgdMapLayerGroupNameNotFound", NULL);
     }
 
     // get the scale at which to render the tile
@@ -418,16 +920,16 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// render a map using all layers from the baseGroup
 MgByteReader* MgRenderingService::RenderTile(MgdMap* map,
-                                             MgLayerGroup* baseGroup,
-                                             INT32 scaleIndex,
-                                             INT32 width,
-                                             INT32 height,
-                                             double scale,
-                                             double mcsMinX,
-                                             double mcsMaxX,
-                                             double mcsMinY,
-                                             double mcsMaxY,
-                                             CREFSTRING format)
+                                                   MgLayerGroup* baseGroup,
+                                                   INT32 scaleIndex,
+                                                   INT32 width,
+                                                   INT32 height,
+                                                   double scale,
+                                                   double mcsMinX,
+                                                   double mcsMaxX,
+                                                   double mcsMinY,
+                                                   double mcsMaxY,
+                                                   CREFSTRING format)
 {
     Ptr<MgByteReader> ret;
 
@@ -488,8 +990,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bKeepSelection = true
 MgByteReader* MgRenderingService::RenderDynamicOverlay(MgdMap* map,
-                                                       MgdSelection* selection,
-                                                       CREFSTRING format)
+                                                             MgdSelection* selection,
+                                                             CREFSTRING format)
 {
     // Call updated RenderDynamicOverlay API
     return RenderDynamicOverlay(map, selection, format, true);
@@ -499,9 +1001,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bKeepSelection = true
 MgByteReader* MgRenderingService::RenderDynamicOverlay(MgdMap* map,
-                                                       MgdSelection* selection,
-                                                       CREFSTRING format,
-                                                       bool bKeepSelection)
+                                                             MgdSelection* selection,
+                                                             CREFSTRING format,
+                                                             bool bKeepSelection)
 {
     // Call updated RenderDynamicOverlay API
     MgRenderingOptions options(format, MgRenderingOptions::RenderSelection |
@@ -512,10 +1014,24 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 // called from API (first call of AjaxPgPViewerSampleApplication)
+// default arg pPRMResult = NULL
 MgByteReader* MgRenderingService::RenderDynamicOverlay(MgdMap* map,
-                                                       MgdSelection* selection,
-                                                       MgRenderingOptions* options)
+                                                             MgdSelection* selection,
+                                                             MgRenderingOptions* options)
 {
+    // Call updated RenderDynamicOverlay API 
+    return RenderDynamicOverlay(map, selection, options, NULL);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Non-published RenderDynamicOverlay API with profile result parameter
+// pPRMResult - a pointer points to Profile Render Map Result.
+MgByteReader* MgRenderingService::RenderDynamicOverlay(MgdMap* map,
+                                                             MgdSelection* selection,
+                                                             MgRenderingOptions* options,
+                                                             ProfileRenderMapResult* pPRMResult)
+{
     Ptr<MgByteReader> ret;
 
     MG_TRY()
@@ -531,19 +1047,19 @@
     double metersPerUnit = map->GetMetersPerUnit();
 
     if (width <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgdMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
 
     if (height <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgdMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
 
     if (dpi <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgdMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
 
     if (scale <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgMapViewScaleCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgdMapViewScaleCannotBeLessThanOrEqualToZero", NULL);
 
     if (metersPerUnit <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderDynamicOverlay", __LINE__, __WFILE__, NULL, L"MgdMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
 
     // sanity check - number of image pixels cannot exceed MAX_PIXELS
     if (width * height > MAX_PIXELS)
@@ -575,38 +1091,50 @@
     for (int i=0; i<layers->GetCount(); i++)
     {
         Ptr<MgLayerBase> layer = layers->GetItem(i);
-        Ptr<MgLayerGroup> layerGroup = layer->GetGroup();
-        //DESKTOP-IMPL: Server doesn't need to do this because
-        //state changes are saved and invisible layers are cleared
-        //on each open
-        if (!layer->IsVisible())
-            continue;
-
-        //DESKTOP-IMPL: Server doesn't need to do this because
-        //state changes are saved and invisible layers are cleared
-        //on each open
-        if (NULL != (MgLayerGroup*)layerGroup && !layerGroup->IsVisible())
-            continue;
-
         INT32 layerType = layer->GetLayerType();
         if (layerType == MgLayerType::Dynamic)
             roLayers->Add(layer);
     }
 
+    if(NULL != pPRMResult)
+    {
+        Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+        pPRMResult->SetResourceId(mapResId ? mapResId->ToString() : L"");
+        pPRMResult->SetScale(scale);
+        pPRMResult->SetExtents(Box2D(extent.minx, extent.miny, extent.maxx, extent.maxy));
+        pPRMResult->SetLayerCount(layers->GetCount());
+    }
+
     // call the internal helper API to do all the stylization overhead work
-    ret = RenderMapInternal(map, selection, roLayers, dr.get(), width, height, width, height, scale, extent, false, options, true);
+    ret = RenderMapInternal(map, selection, roLayers, dr.get(), width, height, width, height, scale, extent, false, options, true, pPRMResult);
 
-    MG_CATCH_AND_THROW(L"MgRenderingService.RenderDynamicOverlay")
+    MG_CATCH(L"MgRenderingService.RenderDynamicOverlay")
+    if (mgException.p)
+    {
+        if(NULL != pPRMResult)
+        {
+            //MgServerManager* serverManager = MgServerManager::GetInstance();
+            //STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
+			STRING locale = MgResources::DefaultMessageLocale;
 
+            Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+            pPRMResult->SetResourceId(mapResId ? mapResId->ToString() : L"");
+
+            STRING message = mgException->GetExceptionMessage(locale);
+            pPRMResult->SetError(message);
+        }
+
+        MG_THROW()
+    }
+
     return ret.Detach();
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bKeepSelection = true
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            CREFSTRING format)
+                                                  MgdSelection* selection,
+                                                  CREFSTRING format)
 {
     // Call updated RenderMap API
     return RenderMap(map, selection, format, true);
@@ -616,9 +1144,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bClip = false
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            CREFSTRING format,
-                                            bool bKeepSelection)
+                                                  MgdSelection* selection,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection)
 {
     return RenderMap(map, selection, format, bKeepSelection, false);
 }
@@ -629,10 +1157,10 @@
 // color and display sizes as default arguments to call the real rendermap method
 // default arg (bKeepSelection = true, bClip = false)
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            CREFSTRING format,
-                                            bool bKeepSelection,
-                                            bool bClip)
+                                                  MgdSelection* selection,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection,
+                                                  bool bClip)
 {
     Ptr<MgByteReader> ret;
 
@@ -662,12 +1190,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // default arg bKeepSelection = true
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            MgEnvelope* extents,
-                                            INT32 width,
-                                            INT32 height,
-                                            MgColor* backgroundColor,
-                                            CREFSTRING format)
+                                                  MgdSelection* selection,
+                                                  MgEnvelope* extents,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format)
 {
     // Call updated RenderMap API
     return RenderMap(map, selection, extents, width, height, backgroundColor, format, true);
@@ -678,13 +1206,13 @@
 // render the provided extent of the map and align aspect ratios to the provided window
 // default arg bKeepSelection = true
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            MgEnvelope* extents,
-                                            INT32 width,
-                                            INT32 height,
-                                            MgColor* backgroundColor,
-                                            CREFSTRING format,
-                                            bool bKeepSelection)
+                                                  MgdSelection* selection,
+                                                  MgEnvelope* extents,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection)
 {
     Ptr<MgByteReader> ret;
 
@@ -698,16 +1226,16 @@
     double metersPerUnit = map->GetMetersPerUnit();
 
     if (width <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
 
     if (height <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
 
     if (dpi <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
 
     if (metersPerUnit <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
 
     // compute a view center and scale from the given extents
     // and pass on to the RenderMap that uses center and scale
@@ -784,13 +1312,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 // default argument bKeepSelection = true
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            MgCoordinate* center,
-                                            double scale,
-                                            INT32 width,
-                                            INT32 height,
-                                            MgColor* backgroundColor,
-                                            CREFSTRING format)
+                                                  MgdSelection* selection,
+                                                  MgCoordinate* center,
+                                                  double scale,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format)
 {
     // Call updated RenderMap API
     return RenderMap(map, selection, center, scale, width, height, backgroundColor, format, true);
@@ -798,35 +1326,51 @@
 
 
 ///////////////////////////////////////////////////////////////////////////////
-// default arguments bClip = false
+// default arguments bClip = false  pProfileRenderMapResult = NULL
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            MgCoordinate* center,
-                                            double scale,
-                                            INT32 width,
-                                            INT32 height,
-                                            MgColor* backgroundColor,
-                                            CREFSTRING format,
-                                            bool bKeepSelection)
+                                                  MgdSelection* selection,
+                                                  MgCoordinate* center,
+                                                  double scale,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection)
 {
     return RenderMap(map, selection, center, scale, width, height, backgroundColor, format, bKeepSelection, false);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// default arguments bClip = false
+MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
+                                                  MgdSelection* selection,
+                                                  MgCoordinate* center,
+                                                  double scale,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection,
+                                                  ProfileRenderMapResult* pPRMResult)
+{
+    return RenderMap(map, selection, center, scale, width, height, backgroundColor, format, bKeepSelection, false, pPRMResult);
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 // render map around center point in given scale
 // default args bKeepSelection = true, bClip = false, backgroundColor = map->backgroundColor,
 // width = map->getDisplayWidth, height = map->getDisplayHeight
 MgByteReader* MgRenderingService::RenderMap(MgdMap* map,
-                                            MgdSelection* selection,
-                                            MgCoordinate* center,
-                                            double scale,
-                                            INT32 width,
-                                            INT32 height,
-                                            MgColor* backgroundColor,
-                                            CREFSTRING format,
-                                            bool bKeepSelection,
-                                            bool bClip)
+                                                  MgdSelection* selection,
+                                                  MgCoordinate* center,
+                                                  double scale,
+                                                  INT32 width,
+                                                  INT32 height,
+                                                  MgColor* backgroundColor,
+                                                  CREFSTRING format,
+                                                  bool bKeepSelection,
+                                                  bool bClip,
+                                                  ProfileRenderMapResult* pPRMResult)
 {
     Ptr<MgByteReader> ret;
 
@@ -840,19 +1384,19 @@
     double metersPerUnit = map->GetMetersPerUnit();
 
     if (width <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
 
     if (height <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
 
     if (dpi <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
 
     if (scale <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapViewScaleCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapViewScaleCannotBeLessThanOrEqualToZero", NULL);
 
     if (metersPerUnit <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgdMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
 
     // sanity check - number of image pixels cannot exceed MAX_PIXELS
     if (width * height > MAX_PIXELS)
@@ -877,11 +1421,37 @@
     // initialize the appropriate map renderer
     auto_ptr<SE_Renderer> dr(CreateRenderer(width, height, bgcolor, bClip));
 
+    if(NULL != pPRMResult)
+    {
+        Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+        pPRMResult->SetResourceId(mapResId ? mapResId->ToString() : L"");
+        pPRMResult->SetScale(scale);
+        pPRMResult->SetExtents(Box2D(b.minx, b.miny, b.maxx, b.maxy));
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        pPRMResult->SetLayerCount(layers->GetCount());
+    }
+
     // call the internal helper API to do all the stylization overhead work
-    ret = RenderMapInternal(map, selection, NULL, dr.get(), width, height, width, height, format, scale, b, false, bKeepSelection, true);
+    ret = RenderMapInternal(map, selection, NULL, dr.get(), width, height, width, height, format, scale, b, false, bKeepSelection, true, pPRMResult);
 
-    MG_CATCH_AND_THROW(L"MgRenderingService.RenderMap")
+    MG_CATCH(L"MgRenderingService.RenderMap")
+    if (mgException.p)
+    {
+        if(NULL != pPRMResult)
+        {
+            //MgServerManager* serverManager = MgServerManager::GetInstance();
+            //STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
+			STRING locale = MgResources::DefaultMessageLocale;
 
+            Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+            pPRMResult->SetResourceId(mapResId ? mapResId->ToString() : L"");
+
+            STRING message = mgException->GetExceptionMessage(locale);
+            pPRMResult->SetError(message);
+        }
+
+        MG_THROW()
+    }
     return ret.Detach();
 }
 
@@ -889,23 +1459,24 @@
 // pack options into object and forward call (select Selection AND Layers)
 // maybe keepSelection called by RenderTile
 MgByteReader* MgRenderingService::RenderMapInternal(MgdMap* map,
-                                                    MgdSelection* selection,
-                                                    MgReadOnlyLayerCollection* roLayers,
-                                                    SE_Renderer* dr,
-                                                    INT32 drawWidth,
-                                                    INT32 drawHeight,
-                                                    INT32 saveWidth,
-                                                    INT32 saveHeight,
-                                                    CREFSTRING format,
-                                                    double scale,
-                                                    RS_Bounds& b,
-                                                    bool expandExtents,
-                                                    bool bKeepSelection,
-                                                    bool renderWatermark)
+                                                          MgdSelection* selection,
+                                                          MgReadOnlyLayerCollection* roLayers,
+                                                          SE_Renderer* dr,
+                                                          INT32 drawWidth,
+                                                          INT32 drawHeight,
+                                                          INT32 saveWidth,
+                                                          INT32 saveHeight,
+                                                          CREFSTRING format,
+                                                          double scale,
+                                                          RS_Bounds& b,
+                                                          bool expandExtents,
+                                                          bool bKeepSelection,
+                                                          bool renderWatermark,
+                                                          ProfileRenderMapResult* pPRMResult)
 {
     MgRenderingOptions options(format, MgRenderingOptions::RenderSelection |
         MgRenderingOptions::RenderLayers | (bKeepSelection? MgRenderingOptions::KeepSelection : 0), NULL);
-    return RenderMapInternal(map, selection, roLayers, dr, drawWidth, drawHeight, saveWidth, saveHeight, scale, b, expandExtents, &options, renderWatermark);
+    return RenderMapInternal(map, selection, roLayers, dr, drawWidth, drawHeight, saveWidth, saveHeight, scale, b, expandExtents, &options, renderWatermark, pPRMResult);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -917,18 +1488,19 @@
 // render map using provided options object from before
 // this is called for tiles and for dynamic overlays
 MgByteReader* MgRenderingService::RenderMapInternal(MgdMap* map,
-                                                    MgdSelection* selection,
-                                                    MgReadOnlyLayerCollection* roLayers,
-                                                    SE_Renderer* dr,
-                                                    INT32 drawWidth,
-                                                    INT32 drawHeight,
-                                                    INT32 saveWidth,
-                                                    INT32 saveHeight,
-                                                    double scale,
-                                                    RS_Bounds& b,
-                                                    bool expandExtents,
-                                                    MgRenderingOptions* options,
-                                                    bool renderWatermark)
+                                                          MgdSelection* selection,
+                                                          MgReadOnlyLayerCollection* roLayers,
+                                                          SE_Renderer* dr,
+                                                          INT32 drawWidth,
+                                                          INT32 drawHeight,
+                                                          INT32 saveWidth,
+                                                          INT32 saveHeight,
+                                                          double scale,
+                                                          RS_Bounds& b,
+                                                          bool expandExtents,
+                                                          MgRenderingOptions* options,
+                                                          bool renderWatermark,
+                                                          ProfileRenderMapResult* pPRMResult)
 {
     // set the map scale to the requested scale
     map->SetViewScale(scale);
@@ -954,11 +1526,9 @@
 
     // get the session ID
     STRING sessionId = map->GetSessionId();
-    /*
-    Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
-    if (userInfo != NULL)
-        sessionId = userInfo->GetMgSessionId();
-    */
+    //Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
+    //if (userInfo != NULL)
+    //    sessionId = userInfo->GetMgSessionId();
 
     // initialize the stylizer
     RSMgSymbolManager mgr(m_svcResource);
@@ -987,353 +1557,70 @@
             for (INT32 i=0; i<layers->GetCount(); i++)
             {
                 Ptr<MgLayerBase> layer = layers->GetItem(i);
-                Ptr<MgLayerGroup> layerGroup = layer->GetGroup();
-                //DESKTOP-IMPL: Server doesn't need to do this because
-                //state changes are saved and invisible layers are cleared
-                //on each open
-                if (!layer->IsVisible())
-                    continue;
-
-                //DESKTOP-IMPL: Server doesn't need to do this because
-                //state changes are saved and invisible layers are cleared
-                //on each open
-                if (NULL != (MgLayerGroup*)layerGroup && !layerGroup->IsVisible())
-                    continue;
-
                 tempLayers->Add(layer);
             }
         }
 
         INT32 behavior = options->GetBehavior();
+
         if (behavior & MgRenderingOptions::RenderLayers)    // this is for tiles so observer colormaps
         {
-            MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
-                                         tempLayers, NULL, &ds, dr, dstCs, expandExtents, false, scale,
-                                         false, hasColorMap(format));
+            RenderLayers(map, tempLayers, &ds, dr, dstCs, expandExtents, scale, format, pPRMResult);
         }
 
         // now we need to stylize the selection on top (this is not for tiles!)
         if (selection && (behavior & MgRenderingOptions::RenderSelection))
         {
-            Ptr<MgReadOnlyLayerCollection> selLayers = selection->GetLayers();
-
-            #ifdef _DEBUG
-            printf("MgRenderingService::RenderMapInternal() - Layers:%d  Selection Layers:%d\n", tempLayers.p? tempLayers->GetCount() : 0, selLayers.p? selLayers->GetCount() : 0);
-            #endif
-
-            if (selLayers.p && selLayers->GetCount() > 0)
-            {
-                // tell the renderer to override draw styles with the ones
-                // we use for selection
-                MgColor *selectionColor = options->GetSelectionColor();
-                if (selectionColor == NULL)
-                {
-                    dr->SetRenderSelectionMode(true);
-                }
-                else
-                {
-                    dr->SetRenderSelectionMode(true,
-                        selectionColor->GetRed() << 24 |
-                        selectionColor->GetGreen() << 16 |
-                        selectionColor->GetBlue() << 8 |
-                        selectionColor->GetAlpha());
-                }
-                SAFE_RELEASE(selectionColor);
-
-                // prepare a collection of temporary MgLayers which have the right
-                // FDO filters that will fetch only the selected features from FDO
-                Ptr<MgReadOnlyLayerCollection> modLayers = new MgReadOnlyLayerCollection();
-                Ptr<MgStringCollection> overrideFilters = new MgStringCollection();
-
-                for (int s=0; s<selLayers->GetCount(); s++)
-                {
-                    Ptr<MgLayerBase> selLayer = selLayers->GetItem(s);
-
-                    // generate a filter for the selected features
-                    Ptr<MgStringCollection> filters = selection->GenerateFilters(
-                    selLayer, selLayer->GetFeatureClassName(), m_renderSelectionBatchSize);
-                    INT32 numFilter = (NULL == filters)? 0 : filters->GetCount();
-
-                    for (INT32 i = 0; i < numFilter; ++i)
-                    {
-                        overrideFilters->Add(filters->GetItem(i));
-                        modLayers->Add(selLayer);
-                    }
-                }
-
-                MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
-                    modLayers, overrideFilters, &ds, dr, dstCs, false, false, scale, (behavior & MgRenderingOptions::KeepSelection) != 0);
-
-                // Set selection mode to false to avoid affecting following code
-                dr->SetRenderSelectionMode(false);
-            }
+            RenderSelection(map, selection, tempLayers, options, &ds, dr, dstCs, scale, behavior, pPRMResult);
         }
 
         if (renderWatermark && (behavior & MgRenderingOptions::RenderLayers) && map->GetWatermarkUsage() != 0)
         {
-            // Rendering watermark only when:
-            //      1. rendering layers
-            //      2. not set renderWatermark to false (not render tile)
-            //      3. Map's watermark usage is not 0, which means watermark usage is WMS and / or Viewer.
-            WatermarkInstanceCollection watermarkInstances;   //Watermark list to render
-            WatermarkInstanceCollection tempWatermarkInstances;    //Used to reverse list
-            auto_ptr<WatermarkInstance> tempInstance;
-
-            // Get watermark instance in map
-            Ptr<MgResourceIdentifier> mapId = map->GetMapDefinition();
-            if (mapId.p)
-            {
-                auto_ptr<MapDefinition> mdef(MgMapBase::GetMapDefinition(m_svcResource, mapId));
-                WatermarkInstanceCollection* mapWatermarks = mdef->GetWatermarks();
-                for (int i=mapWatermarks->GetCount()-1; i>=0; i--)
-                    tempWatermarkInstances.Adopt(mapWatermarks->OrphanAt(i));
-                for (int i=tempWatermarkInstances.GetCount()-1; i>=0; i--)
-                {
-                    tempInstance.reset(tempWatermarkInstances.OrphanAt(i));
-                    if (!tempInstance.get())
-                        continue;
-                    if (((map->GetWatermarkUsage() & MgdMap::Viewer) != 0
-                        && (tempInstance->GetUsage() & WatermarkInstance::Viewer) == 0)
-                        || ((map->GetWatermarkUsage() & MgdMap::WMS) != 0
-                        && (tempInstance->GetUsage() & WatermarkInstance::WMS) == 0))
-                        continue;
-                    bool alreadyInList = false;
-                    for (int j=watermarkInstances.GetCount()-1; j >=0; j--)
-                    {
-                        if (tempInstance->Equals(watermarkInstances.GetAt(j)))
-                        {
-                            alreadyInList = true;
-                            break;
-                        }
-                    }
-
-                    if (!alreadyInList)
-                    {
-                        watermarkInstances.Adopt(tempInstance.release());
-                    }
-                }
-            }
-
-            // Get watermark instance in layer
-            const int layerCount = tempLayers->GetCount();
-            auto_ptr<LayerDefinition> ldf;
-            for (int i=0; i<layerCount; ++i)
-            {
-                Ptr<MgLayerBase> mapLayer(tempLayers->GetItem(i));
-
-                // the layer resource content should be set during stylization if visible
-                if (mapLayer->GetLayerResourceContent() == L"")
-                    continue;
-
-                ldf.reset(MgLayerBase::GetLayerDefinition(mapLayer->GetLayerResourceContent()));
-
-                WatermarkInstanceCollection* layerWatermarks = ldf->GetWatermarks();
-                for (int j=layerWatermarks->GetCount()-1; j>=0; j--)
-                    tempWatermarkInstances.Adopt(layerWatermarks->OrphanAt(j));
-                for (int j=tempWatermarkInstances.GetCount()-1; j>=0; j--)
-                {
-                    tempInstance.reset(tempWatermarkInstances.OrphanAt(j));
-                    if (!tempInstance.get())
-                        continue;
-                    if (((map->GetWatermarkUsage() & MgdMap::Viewer) != 0
-                        && (tempInstance->GetUsage() & WatermarkInstance::Viewer) == 0)
-                        || ((map->GetWatermarkUsage() & MgdMap::WMS) != 0
-                        && (tempInstance->GetUsage() & WatermarkInstance::WMS) == 0))
-                        continue;
-
-                    bool alreadyInList = false;
-                    for (int k=watermarkInstances.GetCount()-1; k>=0; k--)
-                    {
-                        if (tempInstance->Equals(watermarkInstances.GetAt(k)))
-                        {
-                            alreadyInList = true;
-                            break;
-                        }
-                    }
-
-                    if (!alreadyInList)
-                    {
-                        watermarkInstances.Adopt(tempInstance.release());
-                    }
-                }
-            }
-            assert(tempWatermarkInstances.GetCount() == 0);
-
-            MgStringCollection watermarkIds;            // ID list of loaded watermark definition
-            MgStringCollection watermarkDefinitions;    // Loaded watermark definition
-            MgStringCollection failLoadedIds;           // ID list of failed in loading resource
-
-            for (int i=watermarkInstances.GetCount()-1; i>=0; i--)
-            {
-                WatermarkInstance* instance = watermarkInstances.GetAt(i);
-                STRING resourceId = instance->GetResourceId();
-                WatermarkDefinition* wdef = NULL;
-                MG_TRY()
-                    for(int j = 0; j < watermarkIds.GetCount(); j++)
-                    {
-                        if(resourceId == watermarkIds.GetItem(j))
-                        {
-                            wdef = MgWatermark::GetWatermarkDefinition(watermarkDefinitions.GetItem(j));
-                            break;
-                        }
-                    }
-                    if(wdef == NULL)
-                    {
-                        Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(resourceId);
-                        Ptr<MgByteReader> reader = m_svcResource->GetResourceContent(resId);
-                        STRING content = reader->ToString();
-                        watermarkIds.Add(resourceId);
-                        watermarkDefinitions.Add(content);
-                        wdef = MgWatermark::GetWatermarkDefinition(content);
-                    }
-                    assert(wdef != NULL);
-                    if (instance->GetPositionOverride())
-                    {
-                        wdef->AdoptPosition(instance->OrphanPositionOverride());
-                    }
-                    if (instance->GetAppearanceOverride())
-                    {
-                        wdef->AdoptAppearance(instance->OrphanAppearanceOverride());
-                    }
-                    ds.StylizeWatermark(dr, wdef, drawWidth, drawHeight, saveWidth, saveHeight);
-                
-                MG_CATCH(L"MgRenderingService.RenderMapInternal")
-                if(mgException.p)
-                {
-                    // Do not do anything if fail in resource loading and has logged error.
-                    bool isExceptionLogged = false;
-                    if(wdef == NULL) // Fail in resource loading
-                    { 
-                        for(int i = 0; i < failLoadedIds.GetCount(); i++)
-                        {
-                            if(resourceId == failLoadedIds.GetItem(i))
-                            {
-                                isExceptionLogged = true;
-                                break;
-                            }
-                        }
-                    }
-                    if(!isExceptionLogged)
-                    {
-                        // TODO: Eventually this should be used to indicate visually to the client what
-                        //       layer failed in addition to logging the error.
-                        //MgServerManager* serverManager = MgServerManager::GetInstance();
-                        //STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
-                        //MG_LOG_EXCEPTION_ENTRY(mgException->GetExceptionMessage(locale).c_str(), mgException->GetStackTrace(locale).c_str());
-
-#if defined(_DEBUG) || defined(_DEBUG_PNG8)
-                        STRING details = mgException->GetDetails(MgResources::DefaultMessageLocale);
-
-                        wstring err = L"\n %t Error during stylization of watermark:";
-                        err += instance->GetName();
-                        err += L"\n";
-                        err += L"Details: ";
-                        err += details;
-                        err += L"\n";
-                        ACE_DEBUG( (LM_DEBUG, err.c_str()) );
-#endif
-                        if(wdef == NULL)            // Failed in resource loading
-                        {
-                            failLoadedIds.Add(resourceId);
-                        }
-                    }
-                }
-            }
+            RenderWatermarks(map,tempLayers,&ds, dr,drawWidth, drawHeight, saveWidth, saveHeight, pPRMResult);
         }
 
     MG_CATCH(L"MgRenderingService.RenderMapInternal")
 
-    dr->EndMap();
-
-    MG_THROW()  // to skip a faulty tile we need to rethrow the exception which could be thrown in StylizeLayers
-/*
-    //-------------------------------------------------------
-    // draw a border around the tile - used for debugging
-    RS_LineStroke ls;
-    ls.color() = RS_Color(128, 128, 128, 64);
-
-    LineBuffer lb(5);
-    double mcsMinX = b.minx;
-    double mcsMaxX = b.maxx;
-    double mcsMinY = b.miny;
-    double mcsMaxY = b.maxy;
-    double incX = (mcsMaxX - mcsMinX) / saveWidth  / 10.0;
-    double incY = (mcsMaxY - mcsMinY) / saveHeight / 10.0;
-    lb.MoveTo(mcsMinX + incX, mcsMinY + incY);
-    lb.LineTo(mcsMaxX - incX, mcsMinY + incY);
-    lb.LineTo(mcsMaxX - incX, mcsMaxY - incY);
-    lb.LineTo(mcsMinX + incX, mcsMaxY - incY);
-    lb.LineTo(mcsMinX + incX, mcsMinY + incY);
-    dr->ProcessPolyline(&lb, ls);
-    //-------------------------------------------------------
-*/
-    Ptr<MgByteReader> ret;
-
-    // get a byte representation of the image
-    auto_ptr<RS_ByteData> data;
-
-    try
+    if(NULL != pPRMResult)
     {
-        // call the image renderer to create the image
-        if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
+        if(NULL != dstCs)
         {
-            //-------------------------------------------------------
-            /// RFC60 code to correct colormaps by UV
-            //-------------------------------------------------------
-            // We examine the expressions collected from xml definitions of all layers.
-            // The map object has a list from all color entries found in the most recent
-            // layer stylization.
-            // * TODO - currently they are interpreted as ffffffff 32-bit RGBA string values
-            // * adding expresssions and other interpretations should be done in ParseColorStrings
-            // * the color Palette for the renderer is a vector<RS_Color>
-            if (hasColorMap(format))
-            {
-                RS_ColorVector tileColorPalette;
-                MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
-//              printf("<<<<<<<<<<<<<<<<<<<<< MgRenderingService::ColorPalette->size(): %d\n", tileColorPalette.size());
-                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, &tileColorPalette));
-            }
-            else
-                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, NULL));
+            pPRMResult->SetCoordinateSystem(dstCs->GetCsCode());
         }
-        else
-            data.reset(((GDRenderer*)dr)->Save(format, saveWidth, saveHeight));
+
+        ProfileRenderLabelsResult* pPRLablesResult = new ProfileRenderLabelsResult(); // pointer points to Render Labels Result
+        
+        // Set the start time of stylizing labels
+        pPRLablesResult->SetRenderTime(MgTimerUtil::GetTime());
+
+        pPRMResult->AdoptProfileRenderLabelsResult(pPRLablesResult);
     }
-    catch (exception e)
-    {
-        ACE_DEBUG((LM_DEBUG, L"(%t) %w caught in RenderingService ColorPaletteGeneration\n", e.what()));
-        throw e;
-    }
 
-    if (NULL != data.get())
+    dr->EndMap();
+
+    if(NULL != pPRMResult)
     {
-        // put this into a byte source
-        Ptr<MgByteSource> bs = new MgByteSource(data->GetBytes(), data->GetNumBytes());
+        ProfileRenderLabelsResult* pPRLablesResult = pPRMResult->GetProfileRenderLabelsResult();
 
-        if (format == MgImageFormats::Gif)
-            bs->SetMimeType(MgMimeType::Gif);
-        else if (format == MgImageFormats::Jpeg)
-            bs->SetMimeType(MgMimeType::Jpeg);
-        else if (format == MgImageFormats::Png || format == MgImageFormats::Png8)
-            bs->SetMimeType(MgMimeType::Png);
-        else if (format == MgImageFormats::Tiff)
-            bs->SetMimeType(MgMimeType::Tiff);
-
-        ret = bs->GetReader();
+        // Calculate the time spent on stylizing labels
+        double stylizeLabelsTime = MgTimerUtil::GetTime() - pPRLablesResult->GetRenderTime();
+        pPRLablesResult->SetRenderTime(stylizeLabelsTime);
     }
-    else
-        throw new MgNullReferenceException(L"MgRenderingService.RenderMapInternal", __LINE__, __WFILE__, NULL, L"MgNoDataFromRenderer", NULL);
 
+    MG_THROW()  // to skip a faulty tile we need to rethrow the exception which could be thrown in StylizeLayers
+
+    Ptr<MgByteReader> ret = CreateImage(map, dr, saveWidth, saveHeight, format, pPRMResult);
+
     return ret.Detach();
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 MgByteReader* MgRenderingService::RenderMapLegend(MgdMap* map,
-                                                  INT32 width,
-                                                  INT32 height,
-                                                  MgColor* backgroundColor,
-                                                  CREFSTRING format)
+                                                        INT32 width,
+                                                        INT32 height,
+                                                        MgColor* backgroundColor,
+                                                        CREFSTRING format)
 {
     Ptr<MgByteReader> ret;
 
@@ -1344,10 +1631,10 @@
 
     // validate map view parameters
     if (width <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMapLegend", __LINE__, __WFILE__, NULL, L"MgMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMapLegend", __LINE__, __WFILE__, NULL, L"MgdMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
 
     if (height <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMapLegend", __LINE__, __WFILE__, NULL, L"MgMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
+        throw new MgInvalidArgumentException(L"MgRenderingService.RenderMapLegend", __LINE__, __WFILE__, NULL, L"MgdMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
 
     // sanity check - number of image pixels cannot exceed MAX_PIXELS
     if (width * height > MAX_PIXELS)
@@ -1416,396 +1703,13 @@
     return ret.Detach();
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
-// A helper function that does most of the work for QueryFeatures
-// and QueryFeatureProperties.  Basically runs a rendering loop with
-// a custom renderer supplied by the caller that accumulates selection
-// related things like property values and feature IDs.
-void MgRenderingService::RenderForSelection(MgdMap* map,
-                                            MgStringCollection* layerNames,
-                                            MgGeometry* geometry,
-                                            INT32 selectionVariant,
-                                            CREFSTRING featureFilter,
-                                            INT32 maxFeatures,
-                                            INT32 layerAttributeFilter,
-                                            FeatureInfoRenderer* selRenderer)
-{
-    // Cache coordinate system transforms for the life of the
-    // stylization operation.
-    TransformCacheMap transformCache;
-
-    MG_TRY()
-
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): ** START **\n")));
-    if (NULL == map || (NULL == geometry && featureFilter.empty()))
-        throw new MgNullArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"", NULL);
-
-    if (maxFeatures < 0)
-    {
-        STRING buffer;
-        MgUtil::Int32ToString(maxFeatures, buffer);
-
-        MgStringCollection arguments;
-        arguments.Add(L"5");
-        arguments.Add(buffer);
-
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection",
-            __LINE__, __WFILE__, &arguments, L"MgValueCannotBeLessThanZero", NULL);
-    }
-
-    // get the session ID
-    STRING sessionId = map->GetSessionId();
-    //Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
-    //if (userInfo != NULL)
-    //    sessionId = userInfo->GetMgSessionId();
-
-    // validate map view parameters
-    int width            = map->GetDisplayWidth();
-    int height           = map->GetDisplayHeight();
-    int dpi              = map->GetDisplayDpi();
-    double scale         = map->GetViewScale();
-    double metersPerUnit = map->GetMetersPerUnit();
-
-    if (width <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"MgMapDisplayWidthCannotBeLessThanOrEqualToZero", NULL);
-
-    if (height <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"MgMapDisplayHeightCannotBeLessThanOrEqualToZero", NULL);
-
-    if (dpi <= 0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"MgMapDisplayDpiCannotBeLessThanOrEqualToZero", NULL);
-
-    if (scale <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"MgMapViewScaleCannotBeLessThanOrEqualToZero", NULL);
-
-    if (metersPerUnit <= 0.0)
-        throw new MgInvalidArgumentException(L"MgRenderingService.RenderForSelection", __LINE__, __WFILE__, NULL, L"MgMapMetersPerUnitCannotBeLessThanOrEqualToZero", NULL);
-
-    // compute map extent that corresponds to pixel extent
-    Ptr<MgPoint> pt          = map->GetViewCenter();
-    Ptr<MgCoordinate> center = pt->GetCoordinate();
-    double unitsPerPixel     = METERS_PER_INCH / (double)dpi / metersPerUnit;
-    double mapWidth2         = 0.5 * (double)width  * unitsPerPixel * scale;
-    double mapHeight2        = 0.5 * (double)height * unitsPerPixel * scale;
-
-    RS_Bounds extent(center->GetX() - mapWidth2,
-                     center->GetY() - mapHeight2,
-                     center->GetX() + mapWidth2,
-                     center->GetY() + mapHeight2);
-
-    // begin map stylization
-    RS_Color bgcolor(0, 0, 0, 255); // not used
-    STRING srs = map->GetMapSRS();
-    RS_MapUIInfo mapInfo(sessionId, map->GetName(), map->GetObjectId(), srs, L"", bgcolor);
-
-    // initialize the stylizer
-    SEMgSymbolManager semgr(m_svcResource);
-    DefaultStylizer ds(&semgr);
-
-    selRenderer->StartMap(&mapInfo, extent, scale, dpi, metersPerUnit, NULL);
-
-    //initial simple selection scheme
-    //Run a geometric FDO query on the given selection geometry
-    //and return the features we get from FDO
-
-    Ptr<MgLayerCollection> layers = map->GetLayers();
-
-    bool bOnlySelectableLayers = !((layerAttributeFilter & FILTER_SELECTABLE) == 0);
-    bool bOnlyVisibleLayers = !((layerAttributeFilter & FILTER_VISIBLE) == 0);
-    bool bOnlyTooltipLayers = !((layerAttributeFilter & FILTER_HASTOOLTIPS) == 0);
-
-    //iterate over all map layers, but only do selection
-    //if the layer is in the passed in collection
-    for (int p=0; p<layers->GetCount(); p++)
-    {
-        //find the layer we need to select features from
-        Ptr<MgLayerBase> layer = layers->GetItem(p);
-
-        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): Layer: %W  Selectable:%W  Visible: %W\n"), layer->GetName().c_str(), layer->GetSelectable()? L"True" : L"False", layer->IsVisibleAtScale(scale)? L"True" : L"False"));
-
-        //do this first - this check is fast
-        if (bOnlySelectableLayers && !layer->GetSelectable())
-            continue;
-
-        //do we want to select on this layer -- if caller
-        //gave us a layer name collection, check if the layer
-        //is in there
-        if (layerNames && layerNames->GetCount() > 0 && layerNames->IndexOf(layer->GetName()) == -1)
-            continue;
-
-        //check the visibility at scale if we're not ignoring scale ranges
-        if (bOnlyVisibleLayers && !layer->IsVisibleAtScale(scale))
-            continue;
-
-        //if we only want layers with tooltips, check that this layer has tooltips
-        if (bOnlyTooltipLayers)
-        {
-//          layer->GetLayerInfoFromDefinition(m_svcResource);
-            if (!layer->HasTooltips())
-                continue;
-        }
-
-        //have we processed enough features already?
-        if (maxFeatures <= 0)
-            break;
-
-        //get the MDF layer definition
-        Ptr<MgResourceIdentifier> layerResId = layer->GetLayerDefinition();
-        auto_ptr<MdfModel::LayerDefinition> ldf(MgLayerBase::GetLayerDefinition(m_svcResource, layerResId));
-        MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(ldf.get());
-
-        //we can only do geometric query selection for vector layers
-        if (vl)
-        {
-            ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): Layer: %W  Vector Layer\n"), layer->GetName().c_str()));
-
-            //check to see if we want even layers that aren't visible at the current scale
-            if (!bOnlyVisibleLayers)
-            {
-                // Modify the layer scale range only for layers that are passed in
-                MdfModel::VectorScaleRangeCollection* scaleRanges = vl->GetScaleRanges();
-                if (scaleRanges)
-                {
-                    MdfModel::VectorScaleRange* scaleRange = scaleRanges->GetAt(0);
-                    if (scaleRange)
-                    {
-                        scaleRange->SetMinScale(0.0);
-                        scaleRange->SetMaxScale(MdfModel::VectorScaleRange::MAX_MAP_SCALE);
-                    }
-                }
-            }
-
-            Ptr<MgResourceIdentifier> featResId = new MgResourceIdentifier(layer->GetFeatureSourceId());
-
-            //get a transform from layer coord sys to map coord sys
-            Ptr<MgCoordinateSystem> mapCs = srs.empty()? NULL : m_pCSFactory->Create(srs);
-            TransformCache* item = TransformCache::GetLayerToMapTransform(transformCache, vl->GetFeatureName(), featResId, mapCs, m_pCSFactory, m_svcFeature);
-            Ptr<MgCoordinateSystemTransform> trans = item? item->GetMgTransform() : NULL;
-
-            Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
-            Ptr<MgGeometricEntity> queryGeom;
-            if (geometry != NULL)
-            {
-                //if we have a valid transform, get the request geom in layer's space
-                queryGeom = SAFE_ADDREF(geometry);
-
-                if (trans)
-                {
-                    //get selection geometry in layer space
-                    queryGeom = geometry->Transform(trans);
-                }
-
-                #ifdef _DEBUG
-                // Output the selection geometry
-                STRING geomText = queryGeom->ToAwkt(true);
-                ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) SELECTION FILTER:\n%W\n\n"), geomText.c_str()));
-                #endif
-
-                //set the spatial filter for the selection
-                options->SetSpatialFilter(layer->GetFeatureGeometryName(), (MgGeometry*)(queryGeom.p), /*MgFeatureSpatialOperations*/selectionVariant);
-            }
-
-            // Initialize the reader
-            auto_ptr<RSMgFeatureReader> rsrdr;
-
-            try
-            {
-                if (!featureFilter.empty())
-                {
-                    //set the feature filter, if any
-                    MgdSelection selectionFilter(map, featureFilter);
-                    Ptr<MgReadOnlyLayerCollection> layers = selectionFilter.GetLayers();
-                    if (layers != NULL)
-                    {
-                        for (int i = 0; i < layers->GetCount(); i++)
-                        {
-                            Ptr<MgLayerBase> layer = layers->GetItem(i);
-                            STRING className = layer->GetFeatureClassName();
-                            STRING filter = selectionFilter.GenerateFilter(layer, className);
-                            options->SetFilter(filter);
-                        }
-                    }
-                }
-                else if (!vl->GetFilter().empty())
-                {
-                    //set layer feature filter if any
-                    options->SetFilter(vl->GetFilter());
-                }
-
-                // TODO: can FeatureName be an extension name rather than a FeatureClass?
-                // The reader below needs to be closed and released before the intersectPolygon SelectFeatures below happens
-                // or we end up with a reference count issue that causes a new FDO connection to be cached instead of
-                // reusing the already existing one.
-                Ptr<MgFeatureReader> rdr = m_svcFeature->SelectFeatures(featResId, vl->GetFeatureName(), options);
-                rsrdr.reset(new RSMgFeatureReader(rdr, m_svcFeature, featResId, options, vl->GetGeometry()));
-
-                // Note that the FdoIFeatureReader smart pointer below is created
-                // inside the following IF statement to ensure it gets destroyed
-                // BEFORE the RSMgFeatureReader object above goes out of scope,
-                // even when an exception gets thrown.
-                if (FdoPtr<FdoIFeatureReader>(rsrdr->GetInternalReader()))
-                {
-                    //run a stylization loop with the FeatureInfoRenderer.
-                    //This will build up the selection set and also
-                    //evaluate the tooltip, hyperlink and feature properties
-                    //for the first feature hit
-
-                    RS_UIGraphic uig(NULL, 0, L"");
-                    RS_LayerUIInfo layerinfo(layer->GetName(),
-                                             layer->GetObjectId(), // object ID
-                                             true,   // selectable
-                                             true,   // visible
-                                             true,   // editable
-                                             L"",    // group name
-                                             L"",    // group ID
-                                             true,   // showInLegend
-                                             true,   // expandInLegend
-                                             0.0,    // zOrder
-                                             uig);   // uiGraphic
-
-                    //extract hyperlink and tooltip info
-                    if (!vl->GetToolTip().empty()) layerinfo.hastooltips() = true;
-                    if (vl->GetUrlData() && !vl->GetUrlData()->GetUrlContent().empty())
-                    {
-                        layerinfo.hashyperlinks() = true;
-                    }
-
-                    //set up the property name mapping -- it tells us what
-                    //string the viewer should be displaying as the name of each
-                    //feature property
-                    // TODO: can FeatureName be an extension name rather than a FeatureClass?
-                    RS_FeatureClassInfo fcinfo(vl->GetFeatureName());
-
-                    MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings();
-                    for (int i=0; i<pmappings->GetCount(); i++)
-                    {
-                        MdfModel::NameStringPair* m = pmappings->GetAt(i);
-                        fcinfo.add_mapping(m->GetName(), m->GetValue());
-                    }
-
-                    selRenderer->StartLayer(&layerinfo, &fcinfo);
-                    ds.StylizeVectorLayer(vl, selRenderer, rsrdr.get(), NULL, scale, StylizeThatMany, selRenderer);
-
-                    // Clear the readers in case they are reused below
-                    rdr = NULL;
-                    rsrdr.reset();
-
-                    int numFeaturesProcessed = selRenderer->GetNumFeaturesProcessed();
-                    if (!numFeaturesProcessed && selRenderer->NeedPointTest())
-                    {
-                        // Construct a square selection area 400x larger than then previous area
-                        // centered around the centroid of the original selection area
-                        // Example:  a 4x4 pixel selection area becomes an 80x80 pixel selection area
-                        Ptr<MgPoint> centroid = queryGeom->GetCentroid();
-                        Ptr<MgCoordinate> ctr = centroid->GetCoordinate();
-                        double area = queryGeom->GetArea();
-                        double delta = sqrt(area) * 10.0;
-
-                        // Only process selection if we have a valid area.  The input geometry may not have a
-                        // centroid if it is outside the bounds of the coordinate system.  GetArea() will
-                        // return zero in these cases.
-                        if (delta > 0.0)
-                        {
-                            Ptr<MgCoordinateCollection> coordinates = new MgCoordinateCollection();
-                            Ptr<MgCoordinateXY> coord1 = new MgCoordinateXY(ctr->GetX() - delta, ctr->GetY() - delta);
-                            coordinates->Add(coord1);
-                            Ptr<MgCoordinateXY> coord2 = new MgCoordinateXY(ctr->GetX() - delta, ctr->GetY() + delta);
-                            coordinates->Add(coord2);
-                            Ptr<MgCoordinateXY> coord3 = new MgCoordinateXY(ctr->GetX() + delta, ctr->GetY() + delta);
-                            coordinates->Add(coord3);
-                            Ptr<MgCoordinateXY> coord4 = new MgCoordinateXY(ctr->GetX() + delta, ctr->GetY() - delta);
-                            coordinates->Add(coord4);
-                            coordinates->Add(coord1);
-                            Ptr<MgLinearRing> outerRing = new MgLinearRing(coordinates);
-                            Ptr<MgPolygon> polygon = new MgPolygon(outerRing, NULL);
-
-                            // The selection area may extent past the map extents so clip the selection area to the map extent
-                            Ptr<MgEnvelope> extent = map->GetMapExtent();
-                            Ptr<MgCoordinate> llCoord = extent->GetLowerLeftCoordinate();
-                            Ptr<MgCoordinate> urCoord = extent->GetUpperRightCoordinate();
-                            Ptr<MgCoordinateCollection> extentCoords = new MgCoordinateCollection();
-                            Ptr<MgCoordinateXY> c1 = new MgCoordinateXY(llCoord->GetX(), llCoord->GetY());
-                            extentCoords->Add(c1);
-                            Ptr<MgCoordinateXY> c2 = new MgCoordinateXY(llCoord->GetX(), urCoord->GetY());
-                            extentCoords->Add(c2);
-                            Ptr<MgCoordinateXY> c3 = new MgCoordinateXY(urCoord->GetX(), urCoord->GetY());
-                            extentCoords->Add(c3);
-                            Ptr<MgCoordinateXY> c4 = new MgCoordinateXY(urCoord->GetX(), llCoord->GetY());
-                            extentCoords->Add(c4);
-                            extentCoords->Add(c1);
-                            Ptr<MgLinearRing> extentRing = new MgLinearRing(extentCoords);
-                            Ptr<MgPolygon> extentPolygon = new MgPolygon(extentRing, NULL);
-                            Ptr<MgGeometry> intersectPolygon = polygon->Intersection(extentPolygon);
-
-                            if (intersectPolygon != NULL)
-                            {
-                                options->SetSpatialFilter(layer->GetFeatureGeometryName(), intersectPolygon, /*MgFeatureSpatialOperations*/selectionVariant);
-
-                                rdr = m_svcFeature->SelectFeatures(featResId, vl->GetFeatureName(), options);
-                                rsrdr.reset(new RSMgFeatureReader(rdr, m_svcFeature, featResId, options, vl->GetGeometry()));
-                                selRenderer->PointTest(true);
-                                ds.StylizeVectorLayer(vl, selRenderer, rsrdr.get(), NULL, scale, StylizeThatMany, selRenderer);
-
-                                // Clear the readers
-                                rdr = NULL;
-                                rsrdr.reset();
-
-                                selRenderer->PointTest(false);
-                                numFeaturesProcessed = selRenderer->GetNumFeaturesProcessed();
-                            }
-                        }
-                    }
-                    selRenderer->EndLayer();
-
-                    //update maxFeatures to number of features that
-                    //we can select from subsequent layers
-                    maxFeatures -= numFeaturesProcessed;
-                }
-            }
-            catch (MgFdoException* e)
-            {
-                //TODO: what should we really be doing in this case?
-                //This can happen if the underlying FDO provider does not
-                //support a particular spatial operation. One way around this
-                //is to select all features which appear on the screen and then
-                //do our own geometry math.
-                #ifdef _DEBUG
-                STRING error = e->GetExceptionMessage();
-                ACE_DEBUG((LM_INFO, ACE_TEXT("(%t) RenderForSelection() - Error: %S\n"), error.c_str()));
-                #endif
-
-                // Let's throw the exception here, so that it can be recorded in the error log.
-                throw e;
-            }
-        }
-    }
-
-    selRenderer->EndMap();
-    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RenderForSelection(): ** END **\n")));
-
-    MG_CATCH(L"MgRenderingService.RenderForSelection")
-
-    TransformCache::Clear(transformCache);
-
-    MG_THROW()
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-void MgRenderingService::SetConnectionProperties(MgConnectionProperties*)
-{
-    // Do nothing.  No connection properties are required for server-side service objects.
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
 SE_Renderer* MgRenderingService::CreateRenderer(int width,
-                                                int height,
-                                                RS_Color& bgColor,
-                                                bool requiresClipping,
-                                                bool localOverposting,
-                                                double tileExtentOffset)
+                                                      int height,
+                                                      RS_Color& bgColor,
+                                                      bool requiresClipping,
+                                                      bool localOverposting,
+                                                      double tileExtentOffset)
 {
     SE_Renderer* renderer = NULL;
     if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
@@ -1825,495 +1729,477 @@
     return renderer;
 }
 
-MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
-                                               MgPlotSpecification* plotSpec,
-                                               MgLayout* layout,
-                                               MgDwfVersion* dwfVersion)
+///////////////////////////////////////////////////////////////////////////////
+inline void MgRenderingService::RenderLayers(MgdMap* map,
+                                                   MgReadOnlyLayerCollection* layers,
+                                                   Stylizer* ds,
+                                                   Renderer* dr,
+                                                   MgCoordinateSystem* dstCs,
+                                                   bool expandExtents,
+                                                   double scale,
+                                                   CREFSTRING format,
+                                                   ProfileRenderMapResult* pPRMResult)
 {
-    Ptr<MgByteReader> byteReader;
+    ProfileRenderLayersResult* pPRLsResult = NULL; // pointer points to Profile Render Layers Result
 
-    MG_SERVER_MAPPING_SERVICE_TRY()
-
-    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
-
-    if (NULL == map  || NULL == dwfVersion || NULL == plotSpec )
+    if(NULL != pPRMResult)
     {
-        throw new MgNullArgumentException(
-            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        pPRLsResult = new ProfileRenderLayersResult();
+        pPRMResult->AdoptProfileRenderLayersResult(pPRLsResult);
+                
+        // Set the start time of stylizing layers
+        pPRLsResult->SetRenderTime(MgTimerUtil::GetTime());
     }
 
-    // Create a MgMapPlot which will be passed to GenerateMultiPlot
-    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, plotSpec, layout);
+    MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
+                                    layers, NULL, ds, dr, dstCs, expandExtents, false, scale,
+                                    false, hasColorMap(format), pPRLsResult);
 
-    // Add it to a MgMapPlotCollecion
-    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
-    mapPlots->Add(mapPlot);
-
-    // Create the plot
-    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
-
-    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
-
-    return byteReader.Detach();
-}
-
-MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
-                                               MgCoordinate* center,
-                                               double scale,
-                                               MgPlotSpecification* plotSpec,
-                                               MgLayout* layout,
-                                               MgDwfVersion* dwfVersion)
-{
-    Ptr<MgByteReader> byteReader;
-
-    MG_SERVER_MAPPING_SERVICE_TRY()
-
-    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
-
-    if (NULL == map  || NULL == center || NULL == dwfVersion || NULL == plotSpec )
+    if(NULL != pPRMResult)
     {
-        throw new MgNullArgumentException(
-            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        pPRLsResult = pPRMResult->GetProfileRenderLayersResult();
 
-    // Create a MgMapPlot which will be passed to GenerateMultiPlot
-    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, center, scale, plotSpec, layout);
-
-    // Add it to a MgMapPlotCollecion
-    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
-    mapPlots->Add(mapPlot);
-
-    // Create the plot
-    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
-
-    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
-
-    return byteReader.Detach();
-}
-
-MgByteReader* MgRenderingService::GeneratePlot(MgdMap* map,
-                                               MgEnvelope* extents,
-                                               bool expandToFit,
-                                               MgPlotSpecification* plotSpec,
-                                               MgLayout* layout,
-                                               MgDwfVersion* dwfVersion)
-{
-    Ptr<MgByteReader> byteReader;
-
-    MG_SERVER_MAPPING_SERVICE_TRY()
-
-    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GeneratePlot()");
-
-    if (NULL == map  || NULL == extents || NULL == plotSpec || NULL == dwfVersion )
-    {
-        throw new MgNullArgumentException(
-            L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        // Calculate the time spent on stylizing layers
+        double stylizeLayersTime = MgTimerUtil::GetTime() - pPRLsResult->GetRenderTime();
+        pPRLsResult->SetRenderTime(stylizeLayersTime);
     }
-
-    // Make a copy of the extents
-    Ptr<MgCoordinate> oldll = extents->GetLowerLeftCoordinate();
-    Ptr<MgCoordinate> oldur = extents->GetUpperRightCoordinate();
-    Ptr<MgCoordinate> ll = new MgCoordinateXY(oldll->GetX(), oldll->GetY());
-    Ptr<MgCoordinate> ur = new MgCoordinateXY(oldur->GetX(), oldur->GetY());
-    if (ll == NULL || ur == NULL)
-    {
-        throw new MgNullArgumentException(L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    Ptr<MgEnvelope> env = new MgEnvelope(ll, ur);
-
-    // Create a MgMapPlot which will be passed to GenerateMultiPlot
-    Ptr<MgMapPlot> mapPlot = new MgMapPlot(map, env, expandToFit, plotSpec, layout);
-
-    // Add it to a MgMapPlotCollecion
-    Ptr<MgMapPlotCollection> mapPlots = new MgMapPlotCollection();
-    if (mapPlot == NULL || mapPlots == NULL)
-    {
-        throw new MgNullArgumentException(L"MgRenderingService::GeneratePlot", __LINE__, __WFILE__, NULL, L"", NULL);
-    }
-    mapPlots->Add(mapPlot);
-
-    // Create the plot
-    byteReader = GenerateMultiPlot(mapPlots, dwfVersion);
-
-    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GeneratePlot")
-
-    return byteReader.Detach();
 }
 
-MgByteReader* MgRenderingService::GenerateMultiPlot(MgMapPlotCollection* mapPlots,
-                                                    MgDwfVersion* dwfVersion)
+///////////////////////////////////////////////////////////////////////////////
+inline void MgRenderingService::RenderSelection(MgdMap* map,
+                                                      MgdSelection* selection,
+                                                      MgReadOnlyLayerCollection* layers,
+                                                      MgRenderingOptions* options,
+                                                      Stylizer* ds,
+                                                      Renderer* dr,
+                                                      MgCoordinateSystem* dstCs,
+                                                      double scale,
+                                                      INT32 behavior,
+                                                      ProfileRenderMapResult* pPRMResult)
 {
-    Ptr<MgByteReader> byteReader;
+    SE_Renderer* renderer = dynamic_cast<SE_Renderer*>(dr);
 
-    MG_SERVER_MAPPING_SERVICE_TRY()
+    ProfileRenderSelectionResult* pPRSResult = NULL; // pointer points to Profile Render Selection Result
 
-    MG_LOG_TRACE_ENTRY(L"MgServerMappingService::GenerateMultiPlot()");
-
-    if (0 == mapPlots || 0 == dwfVersion)
+    if(NULL != pPRMResult)
     {
-        throw new MgNullArgumentException(
-            L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+        pPRSResult = new ProfileRenderSelectionResult();
+        pPRMResult->AdoptProfileRenderSelectionResult(pPRSResult);
+                
+        // Set the start time of stylizing selected layers
+        pPRSResult->SetRenderTime(MgTimerUtil::GetTime());
     }
 
-    // get a temporary file to write out EPlot DWF to
-    // TODO: clean the temp file name prefix
-    STRING dwfName = MgFileUtil::GenerateTempFileName(false, L"default_prefix");
+    Ptr<MgReadOnlyLayerCollection> selLayers = selection->GetLayers();
 
-    EPlotRenderer dr(dwfName.c_str(), 0, 0, L"inches");  // NOXLATE
+    #ifdef _DEBUG
+    printf("MgRenderingService::RenderSelection() - Layers:%d  Selection Layers:%d\n", layers? layers->GetCount() : 0, selLayers.p? selLayers->GetCount() : 0);
+    #endif
 
-    dr.SetRasterGridSize(m_rasterGridSizeForPlot);
-    dr.SetMinRasterGridSize(m_minRasterGridSizeForPlot);
-    dr.SetRasterGridSizeOverrideRatio(m_rasterGridSizeOverrideRatioForPlot);
-    dr.SetMaxRasterImageWidth(m_maxRasterImageWidth);
-    dr.SetMaxRasterImageHeight(m_maxRasterImageHeight);
-
-    RSMgSymbolManager mgr(m_svcResource);
-    dr.SetSymbolManager(&mgr);
-
-    // process the MapPlot collection
-    for (int nMapPlotIndex = 0; nMapPlotIndex < mapPlots->GetCount(); nMapPlotIndex++)
+    if (selLayers.p && selLayers->GetCount() > 0)
     {
-        Ptr<MgMapPlot> mapPlot = mapPlots->GetItem(nMapPlotIndex);
-        if (NULL == mapPlot)
+        // tell the renderer to override draw styles with the ones
+        // we use for selection
+        MgColor *selectionColor = options->GetSelectionColor();
+        if (selectionColor == NULL)
         {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            renderer->SetRenderSelectionMode(true);
         }
-
-        Ptr<MgdMap> map = mapPlot->GetMap();
-        if (NULL == map)
+        else
         {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            renderer->SetRenderSelectionMode(true,
+                selectionColor->GetRed() << 24 |
+                selectionColor->GetGreen() << 16 |
+                selectionColor->GetBlue() << 8 |
+                selectionColor->GetAlpha());
         }
+        SAFE_RELEASE(selectionColor);
 
-        Ptr<MgPlotSpecification> plotSpec = mapPlot->GetPlotSpecification();
-        if (NULL == plotSpec)
+        // prepare a collection of temporary MgLayers which have the right
+        // FDO filters that will fetch only the selected features from FDO
+        Ptr<MgReadOnlyLayerCollection> modLayers = new MgReadOnlyLayerCollection();
+        Ptr<MgStringCollection> overrideFilters = new MgStringCollection();
+
+        for (int s=0; s<selLayers->GetCount(); s++)
         {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
+            Ptr<MgLayerBase> selLayer = selLayers->GetItem(s);
 
-        Ptr<MgLayout> layout = mapPlot->GetLayout();
+            // generate a filter for the selected features
+            Ptr<MgStringCollection> filters = selection->GenerateFilters(
+            selLayer, selLayer->GetFeatureClassName(), m_renderSelectionBatchSize);
+            INT32 numFilter = (NULL == filters)? 0 : filters->GetCount();
 
-        double width = plotSpec->GetPaperWidth();
-        double height = plotSpec->GetPaperHeight();
-        STRING pageUnits = plotSpec->GetPageSizeUnits();
+            for (INT32 i = 0; i < numFilter; ++i)
+            {
+                overrideFilters->Add(filters->GetItem(i));
+                modLayers->Add(selLayer);
+            }
+        }
 
-        dr.SetPageWidth(width);
-        dr.SetPageHeight(height);
-        dr.SetPageSizeUnits(pageUnits);
-        dr.SetMapWidth(width);
-        dr.SetMapHeight(height);
-        dr.mapBoundsHeight() = height;
+        MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
+            modLayers, overrideFilters, ds, renderer, dstCs, false, false, scale, (behavior & MgRenderingOptions::KeepSelection) != 0,false,pPRSResult);
 
-        // temporary place for the resId of the Map
-        Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
+        // Set selection mode to false to avoid affecting following code
+        renderer->SetRenderSelectionMode(false);
+    }
 
-        // request extenst
-        Ptr<MgEnvelope> env = map->GetDataExtent();
-        if (env == NULL)
-        {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
+    if(NULL != pPRMResult)
+    {
+        pPRSResult = pPRMResult->GetProfileRenderSelectionResult();
 
-        Ptr<MgCoordinate> ll = env->GetLowerLeftCoordinate();
-        Ptr<MgCoordinate> ur = env->GetUpperRightCoordinate();
-        if (ll == NULL || ur == NULL)
-        {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
-        RS_Bounds b(ll->GetX(), ll->GetY(), ur->GetX(), ur->GetY());
+        // Calculate the time spent on stylizing selected layers
+        double stylizeSelectionTime = MgTimerUtil::GetTime() - pPRSResult->GetRenderTime();
+        pPRSResult->SetRenderTime(stylizeSelectionTime);
+    }
+}
+///////////////////////////////////////////////////////////////////////////////
+inline void MgRenderingService::RenderWatermarks(MgdMap* map,
+                                                       MgReadOnlyLayerCollection* layers,
+                                                       Stylizer* ds,
+                                                       Renderer* dr,
+                                                       int drawWidth,
+                                                       int drawHeight,
+                                                       INT32 saveWidth,
+                                                       INT32 saveHeight,
+                                                       ProfileRenderMapResult* pPRMResult)
+{
+    // Rendering watermark only when:
+    // 1. rendering layers
+    // 2. not set renderWatermark to false (not render tile)
+    // 3. Map's watermark usage is not 0, which means watermark usage is WMS and / or Viewer.
+    WatermarkInstanceCollection watermarkInstances;   //Watermark list to render
+    WatermarkInstanceCollection tempWatermarkInstances;    //Used to reverse list
+    auto_ptr<WatermarkInstance> tempInstance;
 
-        //if requested data extent is not valid, use map definition extent
-        // this may be removed eventually, but is a good sanity check nonetheless
-        if (!b.IsValid())
+    // Get watermark instance in map
+    Ptr<MgResourceIdentifier> mapId = map->GetMapDefinition();
+    if (mapId.p)
+    {
+        auto_ptr<MapDefinition> mdef(MgMapBase::GetMapDefinition(m_svcResource, mapId));
+        WatermarkInstanceCollection* mapWatermarks = mdef->GetWatermarks();
+        for (int i=mapWatermarks->GetCount()-1; i>=0; i--)
+            tempWatermarkInstances.Adopt(mapWatermarks->OrphanAt(i));
+        for (int i=tempWatermarkInstances.GetCount()-1; i>=0; i--)
         {
-            Ptr<MgEnvelope> env2 = map->GetMapExtent();
-            if (env2 == NULL)
+            tempInstance.reset(tempWatermarkInstances.OrphanAt(i));
+            if (!tempInstance.get())
+                continue;
+            if (((map->GetWatermarkUsage() & MgdMap::Viewer) != 0
+                && (tempInstance->GetUsage() & WatermarkInstance::Viewer) == 0)
+                || ((map->GetWatermarkUsage() & MgdMap::WMS) != 0
+                && (tempInstance->GetUsage() & WatermarkInstance::WMS) == 0))
+                continue;
+            bool alreadyInList = false;
+            for (int j=watermarkInstances.GetCount()-1; j >=0; j--)
             {
-                throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                if (tempInstance->Equals(watermarkInstances.GetAt(j)))
+                {
+                    alreadyInList = true;
+                    break;
+                }
             }
 
-            Ptr<MgCoordinate> ll2 = env2->GetLowerLeftCoordinate();
-            Ptr<MgCoordinate> ur2 = env2->GetUpperRightCoordinate();
-            if (ll2 == NULL || ur2 == NULL)
+            if (!alreadyInList)
             {
-                throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                watermarkInstances.Adopt(tempInstance.release());
             }
-
-            b.minx = ll2->GetX();
-            b.miny = ll2->GetY();
-            b.maxx = ur2->GetX();
-            b.maxy = ur2->GetY();
         }
+    }
 
-        // Create a simple print layout containing only the map
-        Ptr<MgPrintLayout> printLayout = new MgPrintLayout();
-        if (printLayout == NULL)
-        {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
-        }
+    // Get watermark instance in layer
+    const int layerCount = layers->GetCount();
+    auto_ptr<LayerDefinition> ldf;
+    for (int i=0; i<layerCount; ++i)
+    {
+        Ptr<MgLayerBase> mapLayer(layers->GetItem(i));
 
-        if (NULL != layout)
-        {
-            Ptr<MgResourceIdentifier> resID = layout->GetLayout();
-            printLayout->Create(m_svcResource, resID);
-            printLayout->SetPlotSize(plotSpec);
-            printLayout->SetScaleBarUnits(layout->GetUnitType());
-            printLayout->SetPlotTitle(layout->GetTitle());
+        Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+        ldf.reset(MgLayerBase::GetLayerDefinition(m_svcResource, layerid));
 
-            Ptr<MgPlotSpecification> spec = printLayout->GetPlotSize();
-
-            width = spec->GetPaperWidth();
-            height = spec->GetPaperHeight();
-            pageUnits = spec->GetPageSizeUnits();
-        }
-        else
+        WatermarkInstanceCollection* layerWatermarks = ldf->GetWatermarks();
+        for (int j=layerWatermarks->GetCount()-1; j>=0; j--)
+            tempWatermarkInstances.Adopt(layerWatermarks->OrphanAt(j));
+        for (int j=tempWatermarkInstances.GetCount()-1; j>=0; j--)
         {
-            printLayout->SetPlotSize(plotSpec);
-        }
+            tempInstance.reset(tempWatermarkInstances.OrphanAt(j));
+            if (!tempInstance.get())
+                continue;
+            if (((map->GetWatermarkUsage() & MgdMap::Viewer) != 0
+                && (tempInstance->GetUsage() & WatermarkInstance::Viewer) == 0)
+                || ((map->GetWatermarkUsage() & MgdMap::WMS) != 0
+                && (tempInstance->GetUsage() & WatermarkInstance::WMS) == 0))
+                continue;
 
-        printLayout->PageWidth() = width;
-        printLayout->PageHeight() = height;
-        printLayout->Units() = pageUnits;
-
-        dr.EnableLayoutPlot();
-
-        //get the map coordinate system
-        MdfModel::MdfString srs = map->GetMapSRS();
-        Ptr<MgCoordinateSystem> dstCs;
-        if (!srs.empty())
-        {
-            //let's not fail here if coord sys conversion fails for the
-            //map's coordinate system. Instead we will fail per layer at a later stage
-            try
+            bool alreadyInList = false;
+            for (int k=watermarkInstances.GetCount()-1; k>=0; k--)
             {
-                dstCs = m_pCSFactory->Create(srs);
+                if (tempInstance->Equals(watermarkInstances.GetAt(k)))
+                {
+                    alreadyInList = true;
+                    break;
+                }
             }
-            catch (MgInvalidCoordinateSystemException* e)
+
+            if (!alreadyInList)
             {
-                e->Release();
+                watermarkInstances.Adopt(tempInstance.release());
             }
         }
+    }
+    assert(tempWatermarkInstances.GetCount() == 0);
 
-        double metersPerUnit = (dstCs.p) ? dstCs->ConvertCoordinateSystemUnitsToMeters(1.0) : 1.0;
-        RS_String units = (dstCs.p) ? dstCs->GetUnits() : L"";
+    MgStringCollection watermarkIds;            // ID list of loaded watermark definition
+    MgStringCollection watermarkDefinitions;    // Loaded watermark definition
+    MgStringCollection failLoadedIds;           // ID list of failed in loading resource
 
-        double dMapScale = 0.0;
-        Ptr<MgCoordinate> center = new MgCoordinateXY(0, 0);
-        Ptr<MgEnvelope> extents = map->GetMapExtent();
-        if (center == NULL || extents == NULL)
+    if(0 != watermarkInstances.GetCount())
+    {
+        ProfileRenderWatermarksResult* pPRWsResult = NULL; // pointer points to Profile Render Watermarks Result
+
+        if(NULL != pPRMResult)
         {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            pPRWsResult = new ProfileRenderWatermarksResult();
+            pPRMResult->AdoptProfileRenderWatermarksResult(pPRWsResult);
+                
+            // Set the start time of stylizing watermarks
+            pPRWsResult->SetRenderTime(MgTimerUtil::GetTime());
         }
 
-        switch (mapPlot->GetMapPlotInstruction())
+        for (int i=watermarkInstances.GetCount()-1; i>=0; i--)
         {
-        case MgMapPlotInstruction::UseMapCenterAndScale:
-            {
-                dMapScale = map->GetViewScale();
-                if (dMapScale <= 0)
+            WatermarkInstance* instance = watermarkInstances.GetAt(i);
+            STRING resourceId = instance->GetResourceId();
+            WatermarkDefinition* wdef = NULL;
+            MG_TRY()
+                for(int j = 0; j < watermarkIds.GetCount(); j++)
                 {
-                    Ptr<MgEnvelope> extents = map->GetDataExtent();
-                    if (extents == NULL)
+                    if(resourceId == watermarkIds.GetItem(j))
                     {
-                        throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                        wdef = MgWatermark::GetWatermarkDefinition(watermarkDefinitions.GetItem(j));
+                        break;
                     }
-                    printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight());
-                    double mapWidth = dr.mapWidth();
-                    double mapHeight = dr.mapHeight();
-                    if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0) // NOXLATE
-                    {
-                        mapWidth *= MM_TO_IN;
-                        mapHeight *= MM_TO_IN;
-                    }
-
-                    double scaleToFitX = (extents->GetWidth() * metersPerUnit * M_TO_IN) / mapWidth;
-                    double scaleToFitY = (extents->GetHeight() * metersPerUnit * M_TO_IN) / mapHeight;
-                    dMapScale = rs_max(scaleToFitX, scaleToFitY);
                 }
 
-                Ptr<MgPoint> pt = map->GetViewCenter();
-                center = pt->GetCoordinate();
-                break;
-            }
-        case MgMapPlotInstruction::UseOverriddenCenterAndScale:
-            {
-                dMapScale = mapPlot->GetScale();
-                center = mapPlot->GetCenter();
-                break;
-            }
-        case MgMapPlotInstruction::UseOverriddenExtent:
-            {
-                // Compute the plotCenter and plotScale from the extents
-                extents = mapPlot->GetExtent();
-                //...plotCenter
-                Ptr<MgCoordinate> plotll = extents->GetLowerLeftCoordinate();
-                Ptr<MgCoordinate> plotur = extents->GetUpperRightCoordinate();
-                if (plotll == NULL || plotur == NULL)
+                if(NULL != pPRWsResult)
                 {
-                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                    ProfileRenderWatermarkResult* pPRWResult = new ProfileRenderWatermarkResult(); // pointer points to Render Watermark Result
+                        
+                    // Set the start time of stylizing watermark
+                    pPRWResult->SetRenderTime(MgTimerUtil::GetTime());
+
+                    ProfileRenderWatermarkResultCollection* pPRWResultColl = pPRWsResult->GetProfileRenderWatermarkResults();
+                    pPRWResultColl->Adopt(pPRWResult);
                 }
-                double minX = plotll->GetX();
-                double minY = plotll->GetY();
-                double maxX = plotur->GetX();
-                double maxY = plotur->GetY();
-                double centerX = minX + (maxX - minX) * 0.5;
-                double centerY = minY + (maxY - minY) * 0.5;
-                //
-                //...plotScale
-                printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight());
-                double mapWidth = dr.mapWidth();
-                double mapHeight = dr.mapHeight();
-                if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0)  // NOXLATE
+
+                if(wdef == NULL)
                 {
-                    mapWidth *= MM_TO_IN;
-                    mapHeight *= MM_TO_IN;
+                    Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(resourceId);
+                    Ptr<MgByteReader> reader = m_svcResource->GetResourceContent(resId);
+                    STRING content = reader->ToString();
+                    watermarkIds.Add(resourceId);
+                    watermarkDefinitions.Add(content);
+                    wdef = MgWatermark::GetWatermarkDefinition(content);
                 }
-
-                double scaleToFitX = (extents->GetWidth() * metersPerUnit * M_TO_IN) / mapWidth;
-                double scaleToFitY = (extents->GetHeight() * metersPerUnit * M_TO_IN) / mapHeight;
-                dMapScale = rs_max(scaleToFitX, scaleToFitY);
-
-                map->SetViewScale(dMapScale);
-                center = new MgCoordinateXY(centerX, centerY);
-                if (center == NULL)
+                assert(wdef != NULL);
+                if (instance->GetPositionOverride())
                 {
-                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                    wdef->AdoptPosition(instance->OrphanPositionOverride());
                 }
-                Ptr<MgPoint> centerpt = new MgPoint(center);
-                if (centerpt == NULL)
+                if (instance->GetAppearanceOverride())
                 {
-                    throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+                    wdef->AdoptAppearance(instance->OrphanAppearanceOverride());
                 }
-                map->SetViewCenter(centerpt);
-                break;
-            }
-        default:
-            {
-                MgStringCollection arguments;
-                arguments.Add(L"1");
-                arguments.Add(L"MgMapPlotCollection");
+                ds->StylizeWatermark(dr, wdef, drawWidth, drawHeight, saveWidth, saveHeight);
+                
+                if(NULL != pPRWsResult)
+                {
+                    ProfileRenderWatermarkResultCollection* pPRWResultColl = pPRWsResult->GetProfileRenderWatermarkResults();
+                    ProfileRenderWatermarkResult* pPRWResult = pPRWResultColl->GetAt(pPRWResultColl->GetCount()-1); // TODO: check index
 
-                throw new MgInvalidArgumentException(L"MgRenderingService::GenerateMultiPlot",
-                    __LINE__, __WFILE__, &arguments, L"MgInvalidMapPlotCollectionMapPlotInstruction", NULL);
-            }
-            break;
-        }
+                    // Calculate the time spent on stylizing watermark
+                    double stylizeWatermarkTime = MgTimerUtil::GetTime() - pPRWResult->GetRenderTime();
+                    pPRWResult->SetRenderTime(stylizeWatermarkTime);
 
-        printLayout->SetPlotCenter(center);
-        printLayout->SetPlotScale(dMapScale);
+                    pPRWResult->SetResourceId(resourceId);
 
-        // Get the map background color
-        RS_Color bgcolor;
-        StylizationUtil::ParseColor( map->GetBackgroundColor(), bgcolor);
+                    WatermarkPosition* position = wdef->GetPosition();
+                    if(NULL != dynamic_cast<XYWatermarkPosition*>(position))
+                    {
+                        pPRWResult->SetPositionType(L"XY");
+                    }
+                    else // No other position types
+                    {
+                        pPRWResult->SetPositionType(L"Tile");
+                    }
+                }
 
-        // Get the layout background color
-        RS_Color layoutColor;
-        Ptr<MgColor> bgColor = printLayout->GetBackgroundColor();
-        layoutColor.red() = bgColor->GetRed();
-        layoutColor.green() = bgColor->GetGreen();
-        layoutColor.blue() = bgColor->GetBlue();
+            MG_CATCH(L"MgRenderingService.RenderWatermarks")
+            if(mgException.p)
+            {
+                // Do not do anything if fail in resource loading and has logged error.
+                bool isExceptionLogged = false;
+                if(wdef == NULL) // Fail in resource loading
+                { 
+                    for(int i = 0; i < failLoadedIds.GetCount(); i++)
+                    {
+                        if(resourceId == failLoadedIds.GetItem(i))
+                        {
+                            isExceptionLogged = true;
+                            break;
+                        }
+                    }
+                }
+                if(!isExceptionLogged)
+                {
+                    // TODO: Eventually this should be used to indicate visually to the client what
+                    //       layer failed in addition to logging the error.
+                    //MgServerManager* serverManager = MgServerManager::GetInstance();
+                    //STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
+					STRING locale = MgResources::DefaultMessageLocale;
+                    //MG_LOG_EXCEPTION_ENTRY(mgException->GetExceptionMessage(locale).c_str(), mgException->GetStackTrace(locale).c_str());
 
-        // Get the session ID
-        STRING sessionId;
-        /*Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
-        if (userInfo != NULL)
-            sessionId = userInfo->GetMgSessionId();*/
+#if defined(_DEBUG) || defined(_DEBUG_PNG8)
+                    STRING details = mgException->GetDetails(locale);
 
-        RS_MapUIInfo mapInfo(sessionId, map->GetName(), L"", srs, units, layoutColor);
+                    wstring err = L"\n %t Error during stylization of watermark:";
+                    err += instance->GetName();
+                    err += L"\n";
+                    err += L"Details: ";
+                    err += details;
+                    err += L"\n";
+                    ACE_DEBUG( (LM_DEBUG, err.c_str()) );
+#endif
+                    if(wdef == NULL)            // Failed in resource loading
+                    {
+                        failLoadedIds.Add(resourceId);
+                    }
 
-        // Dynamically adjust the width and height of the map
-        printLayout->ComputeMapOffsetAndSize(dMapScale, extents, metersPerUnit, dr.mapOffsetX(), dr.mapOffsetY(), dr.mapWidth(), dr.mapHeight(), mapPlot->GetExpandToFit());
+                    if(NULL != pPRWsResult)
+                    {
+                        ProfileRenderWatermarkResultCollection* pPRWResultColl = pPRWsResult->GetProfileRenderWatermarkResults();
+                        ProfileRenderWatermarkResult* pPRWResult = pPRWResultColl->GetAt(pPRWResultColl->GetCount()-1); // TODO: check index
 
-        Ptr<MgCoordinate> newll;
-        Ptr<MgCoordinate> newur;
-        if (mapPlot->GetMapPlotInstruction() != MgMapPlotInstruction::UseOverriddenExtent || mapPlot->GetExpandToFit())
-        {
-            double mapWidth = dr.mapWidth();
-            double mapHeight = dr.mapHeight();
-            if (_wcsicmp(pageUnits.c_str(), L"mm") == 0 || _wcsicmp(pageUnits.c_str(), L"millimeters") == 0)  // NOXLATE
-            {
-                mapWidth *= MM_TO_IN;
-                mapHeight *= MM_TO_IN;
-            }
+                        // Calculate the time spent on stylizing watermark
+                        double stylizeWatermarkTime = MgTimerUtil::GetTime() - pPRWResult->GetRenderTime();
+                        pPRWResult->SetRenderTime(stylizeWatermarkTime);
 
-            env = printLayout->DetermineLayoutMapExtents(map, metersPerUnit, mapWidth, mapHeight);
+                        pPRWResult->SetResourceId(resourceId);
 
-            newll = env->GetLowerLeftCoordinate();
-            newur = env->GetUpperRightCoordinate();
+                        STRING message = mgException->GetExceptionMessage(locale);
+                        pPRWResult->SetError(message);
+                    }
+                }
+            }
         }
-        else if (mapPlot->GetMapPlotInstruction() == MgMapPlotInstruction::UseOverriddenExtent && !mapPlot->GetExpandToFit())
-        {
-            newll = extents->GetLowerLeftCoordinate();
-            newur = extents->GetUpperRightCoordinate();
-        }
 
-        b.minx = newll->GetX();
-        b.miny = newll->GetY();
-        b.maxx = newur->GetX();
-        b.maxy = newur->GetY();
-
-        SEMgSymbolManager semgr(m_svcResource);
-        DefaultStylizer ds(&semgr);
-
-        double dpi = map->GetDisplayDpi();
-        dr.StartMap(&mapInfo, b, dMapScale, dpi, metersPerUnit);
-
-        Ptr<MgLayerCollection> layers = map->GetLayers();
-        if (layers == NULL)
+        if(NULL != pPRWsResult)
         {
-            throw new MgNullReferenceException(L"MgRenderingService::GenerateMultiPlot", __LINE__, __WFILE__, NULL, L"", NULL);
+            // Calculate the time spent on stylizing watermarks
+            double stylizeRenderWatermarksTime = MgTimerUtil::GetTime() - pPRWsResult->GetRenderTime();
+            pPRWsResult->SetRenderTime(stylizeRenderWatermarksTime);
         }
+    }
+}
 
-        // Define a polygon to represent the map extents and fill it with the map background color
-        dr.StartLayer(NULL, NULL);
-        LineBuffer lb(5);
-        lb.MoveTo(b.minx, b.miny);
-        lb.LineTo(b.maxx, b.miny);
-        lb.LineTo(b.maxx, b.maxy);
-        lb.LineTo(b.minx, b.maxy);
-        lb.Close();
+////////////////////////////////////////////////////////////////////////////////
+inline MgByteReader* MgRenderingService::CreateImage(MgdMap* map,
+                                                           Renderer* dr,
+                                                           INT32 saveWidth,
+                                                           INT32 saveHeight,
+                                                           CREFSTRING format,
+                                                           ProfileRenderMapResult* pPRMResult)
+{
+    if(NULL != pPRMResult)
+    {
+        // Set the start time of creating map image
+        pPRMResult->SetCreateImageTime(MgTimerUtil::GetTime());
+    }
 
-        RS_LineStroke lineStroke;
-        RS_FillStyle fillStyle(lineStroke, bgcolor, layoutColor, L"Solid");  // NOXLATE
-        dr.ProcessPolygon(&lb, fillStyle);
-        dr.EndLayer();
+/*
+    //-------------------------------------------------------
+    // draw a border around the tile - used for debugging
+    RS_LineStroke ls;
+    ls.color() = RS_Color(128, 128, 128, 64);
 
-        //transfer layers to a temporary collection
-        //here it doesn't matter but in the rendering service it does
-        Ptr<MgReadOnlyLayerCollection> rolc = new MgReadOnlyLayerCollection();
+    LineBuffer lb(5);
+    double mcsMinX = b.minx;
+    double mcsMaxX = b.maxx;
+    double mcsMinY = b.miny;
+    double mcsMaxY = b.maxy;
+    double incX = (mcsMaxX - mcsMinX) / saveWidth  / 10.0;
+    double incY = (mcsMaxY - mcsMinY) / saveHeight / 10.0;
+    lb.MoveTo(mcsMinX + incX, mcsMinY + incY);
+    lb.LineTo(mcsMaxX - incX, mcsMinY + incY);
+    lb.LineTo(mcsMaxX - incX, mcsMaxY - incY);
+    lb.LineTo(mcsMinX + incX, mcsMaxY - incY);
+    lb.LineTo(mcsMinX + incX, mcsMinY + incY);
+    dr->ProcessPolyline(&lb, ls);
+    //-------------------------------------------------------
+*/
 
-        for (int u=0; u<layers->GetCount(); u++)
+    // get a byte representation of the image
+    auto_ptr<RS_ByteData> data;
+    Ptr<MgByteSource> bs;
+
+    try
+    {
+        // call the image renderer to create the image
+        if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
         {
-            Ptr<MgLayerBase> lr = layers->GetItem(u);
-            rolc->Add(lr);
+            //-------------------------------------------------------
+            /// RFC60 code to correct colormaps by UV
+            //-------------------------------------------------------
+            // We examine the expressions collected from xml definitions of all layers.
+            // The map object has a list from all color entries found in the most recent
+            // layer stylization.
+            // * TODO - currently they are interpreted as ffffffff 32-bit RGBA string values
+            // * adding expresssions and other interpretations should be done in ParseColorStrings
+            // * the color Palette for the renderer is a vector<RS_Color>
+            if (hasColorMap(format))
+            {
+                RS_ColorVector tileColorPalette;
+                MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
+//              printf("<<<<<<<<<<<<<<<<<<<<< MgRenderingService::ColorPalette->size(): %d\n", tileColorPalette.size());
+                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, &tileColorPalette));
+            }
+            else
+                data.reset(((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight, NULL));
         }
+        else
+            data.reset(((GDRenderer*)dr)->Save(format, saveWidth, saveHeight));
+    }
+    catch (exception e)
+    {
+        ACE_DEBUG((LM_DEBUG, L"(%t) %w caught in RenderingService ColorPaletteGeneration\n", e.what()));
+        throw e;
+    }
 
-        //stylize all the map layers
-        MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
-                                     rolc, NULL, &ds, &dr, dstCs, false, false, dMapScale);
+    if (NULL != data.get())
+    {
+        // put this into a byte source
+        bs = new MgByteSource(data->GetBytes(), data->GetNumBytes());
 
-        // Finish adding the map to the page
-        // Calculate the the height of the map bounds on the page (in page units)
-        dr.mapBoundsHeight() = b.height() * dr.mapWidth()/b.width();
+        if (format == MgImageFormats::Gif)
+            bs->SetMimeType(MgMimeType::Gif);
+        else if (format == MgImageFormats::Jpeg)
+            bs->SetMimeType(MgMimeType::Jpeg);
+        else if (format == MgImageFormats::Png || format == MgImageFormats::Png8)
+            bs->SetMimeType(MgMimeType::Png);
+        else if (format == MgImageFormats::Tiff)
+            bs->SetMimeType(MgMimeType::Tiff);
+    }
+    else
+        throw new MgNullReferenceException(L"MgRenderingService.CreateImage", __LINE__, __WFILE__, NULL, L"MgNoDataFromRenderer", NULL);
+    
+    if(NULL != pPRMResult)
+    {
+        // Calculate the time spent on stylizing labels
+        double createImageTime = MgTimerUtil::GetTime() - pPRMResult->GetCreateImageTime();
+        pPRMResult->SetCreateImageTime(createImageTime);
 
-        //construct one every time -- not really a bottleneck
-        MgLegendPlotUtil lu(m_svcResource);
-
-        // Now add the rest of the layout element to the page
-        lu.AddLayoutElements(printLayout, (STRING)mapInfo.name(), mapResId->ToString(), map, layers, b, dMapScale, metersPerUnit, dr);
-
-        dr.EndMap();
+        pPRMResult->SetImageFormat(format);
+        pPRMResult->SetRendererType(m_rendererName);
     }
 
-    dr.Done();
-
-    // write out the file
-    Ptr<MgByteSource> bs = new MgByteSource(dwfName, true);
-
-    bs->SetMimeType(MgMimeType::Dwf);
-    byteReader = bs->GetReader();
-
-    MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgRenderingService::GenerateMultiPlot")
-
-    return byteReader.Detach();
+    return bs->GetReader();
 }
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.h	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/RenderingService.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -12,10 +12,13 @@
 class MgDrawingService;
 struct RS_Bounds;
 class RS_Color;
+class Stylizer;
+class Renderer;
 
 namespace MdfModel
 {
     class FeatureTypeStyle;
+	class ProfileRenderMapResult;
 }
 
 template class Ptr<MgDrawingService>;
@@ -55,6 +58,11 @@
                                                MgdSelection* selection,
                                                MgRenderingOptions* options);
 
+    virtual MgByteReader* RenderDynamicOverlay(MgdMap* map,
+                                               MgdSelection* selection,
+                                               MgRenderingOptions* options,
+                                               ProfileRenderMapResult* pPRMResult);
+
     virtual MgByteReader* RenderMap(MgdMap* map,
                                     MgdSelection* selection,
                                     CREFSTRING format);
@@ -76,7 +84,8 @@
                                           MgColor* backgroundColor,
                                           CREFSTRING format);
 
-    virtual MgByteReader* GenerateLegendImage(MgResourceIdentifier* resource,
+    // --------------- BEGIN: DWF Rendering and miscellaneous APIs from MgMappingService -----------------------//
+	 virtual MgByteReader* GenerateLegendImage(MgResourceIdentifier* resource,
                                               double scale,
                                               INT32 width,
                                               INT32 height,
@@ -84,8 +93,6 @@
                                               INT32 geomType,
                                               INT32 themeCategory);
 
-    // --------------- DWF Rendering APIs from MgMappingService -----------------------//
-
     virtual MgByteReader* GeneratePlot(
         MgdMap* map,
         MgPlotSpecification* plotSpec,
@@ -112,10 +119,12 @@
         MgMapPlotCollection* mapPlots,
         MgDwfVersion* dwfVersion);
 
+private:
+	bool FeatureTypeStyleSupportsGeomType(MdfModel::FeatureTypeStyle* fts, INT32 geomType);
+	// --------------- END: DWF Rendering and miscellaneous APIs from MgMappingService -----------------------//
+
 INTERNAL_API:
-    //These APIs are most likely relics from having to deal with a stateless
-    //medium like HTTP. We won't remove them for now, but we won't make them
-    //visible either
+
     virtual MgByteReader* RenderMap(MgdMap* map,
                                     MgdSelection* selection,
                                     MgEnvelope* extents,
@@ -161,11 +170,21 @@
                                     MgColor* backgroundColor,
                                     CREFSTRING format,
                                     bool bKeepSelection,
-                                    bool bClip);
+                                    ProfileRenderMapResult* pPRMResult);
 
+    virtual MgByteReader* RenderMap(MgdMap* map,
+                                    MgdSelection* selection,
+                                    MgCoordinate* center,
+                                    double scale,
+                                    INT32 width,
+                                    INT32 height,
+                                    MgColor* backgroundColor,
+                                    CREFSTRING format,
+                                    bool bKeepSelection,
+                                    bool bClip,
+                                    ProfileRenderMapResult* pPRMResult = NULL);
+
 private:
-    bool FeatureTypeStyleSupportsGeomType(MdfModel::FeatureTypeStyle* fts, INT32 geomType);
-
     // used for tile generation
     MgByteReader* RenderTile(MgdMap* map,
                              MgLayerGroup* baseGroup,
@@ -193,8 +212,9 @@
                                     RS_Bounds& b,
                                     bool expandExtents,
                                     bool bKeepSelection,
-                                    bool renderWatermark);
-
+                                    bool renderWatermark,
+                                    ProfileRenderMapResult* pPRMResult = NULL);
+	
     MgByteReader* RenderMapInternal(MgdMap* map,
                                     MgdSelection* selection,
                                     MgReadOnlyLayerCollection* roLayers,
@@ -207,9 +227,10 @@
                                     RS_Bounds& b,
                                     bool expandExtents,
                                     MgRenderingOptions* options,
-                                    bool renderWatermark);
+                                    bool renderWatermark,
+                                    ProfileRenderMapResult* pPRMResult = NULL);
 
-    void RenderForSelection(MgdMap* map,
+    void RenderForSelection(MgMap* map,
                          MgStringCollection* layerNames,
                          MgGeometry* geometry,
                          INT32 selectionVariant,
@@ -225,6 +246,44 @@
                                 bool localOverposting = false,
                                 double tileExtentOffset = 0.0);
 
+    void RenderLayers(MgdMap* map,
+                      MgReadOnlyLayerCollection* layers,
+                      Stylizer* ds,
+                      Renderer* dr,
+                      MgCoordinateSystem* dstCs,
+                      bool expandExtents,
+                      double scale,
+                      CREFSTRING format,
+                      ProfileRenderMapResult* pPRMResult);
+
+    void RenderSelection(MgdMap* map,
+                         MgdSelection* selection,
+                         MgReadOnlyLayerCollection* layers,
+                         MgRenderingOptions* options,
+                         Stylizer* ds,
+                         Renderer* dr,
+                         MgCoordinateSystem* dstCs,
+                         double scale,
+                         INT32 behavior,
+                         ProfileRenderMapResult* pPRMResult);
+
+    void RenderWatermarks(MgdMap* map,
+                          MgReadOnlyLayerCollection* layers,
+                          Stylizer* ds,
+                          Renderer* dr,
+                          int drawWidth,
+                          int drawHeight,
+                          INT32 saveWidth,
+                          INT32 saveHeight,
+                          ProfileRenderMapResult* pPRMResult);
+
+    MgByteReader* CreateImage(MgdMap* map,
+                              Renderer* dr,
+                              INT32 saveWidth,
+                              INT32 saveHeight,
+                              CREFSTRING format,
+                              ProfileRenderMapResult* pPRMResult);
+
     // member data
     Ptr<MgFeatureService> m_svcFeature;
     Ptr<MgResourceService> m_svcResource;
@@ -241,6 +300,7 @@
     INT32 m_maxRasterImageWidth;
     INT32 m_maxRasterImageHeight;
 
+	// Mapping Service configuration properties
     INT32 m_rasterGridSizeForPlot;
     INT32 m_minRasterGridSizeForPlot;
     double m_rasterGridSizeOverrideRatioForPlot;

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ServiceFactory.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ServiceFactory.cpp	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ServiceFactory.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -1,6 +1,7 @@
 #include "ServiceFactory.h"
 #include "ResourceService.h"
 #include "FeatureService.h"
+#include "ProfilingService.h"
 #include "RenderingService.h"
 #include "DrawingService.h"
 #include "Exception/ServiceNotSupportedException.h"
@@ -59,6 +60,8 @@
         return new MgDrawingService();
     case MgServiceType::FeatureService:
         return new MgdFeatureService();
+	case MgServiceType::ProfilingService:
+		return new MgProfilingService();
     case MgServiceType::RenderingService:
         return new MgRenderingService();
     case MgServiceType::ResourceService:

Modified: branches/2.4/MgDev/Desktop/MgDesktop/System/ClassId.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/System/ClassId.h	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/MgDesktop/System/ClassId.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -12,6 +12,7 @@
 #define MAPGUIDE_DESKTOP_RESOURCESERVICE_ID     41100
 #define MAPGUIDE_DESKTOP_TILESERVICE_ID         41200
 #define MAPGUIDE_DESKTOP_KMLSERVICE_ID          41300
+#define MAPGUIDE_DESKTOP_PROFILING_SERVICE_ID   41400
 
 // MapLayer API
 #define MapGuide_Desktop_MapLayer_Map           MAPGUIDE_DESKTOP_MAPLAYER_ID+0
@@ -120,8 +121,10 @@
 // Tile Service
 #define MapGuide_Desktop_TileService_TileService                            MAPGUIDE_DESKTOP_TILESERVICE_ID+0
 
-// Tile Service
+// KML Service
 #define MapGuide_Desktop_KmlService_KmlService                              MAPGUIDE_DESKTOP_KMLSERVICE_ID+0
 
+// Profiling
+#define MapGuide_Desktop_ProfilingService_ProfilingService					MAPGUIDE_DESKTOP_PROFILING_SERVICE_ID+0
 
 #endif
\ No newline at end of file

Copied: branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.cpp (from rev 6602, trunk/MgDev/Desktop/MgDesktop/System/TimerUtil.cpp)
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,65 @@
+#include "MgDesktop.h"
+#include "TimerUtil.h"
+
+#ifdef WIN32
+LARGE_INTEGER MgTimerUtil::frequency = {0};
+LARGE_INTEGER MgTimerUtil::count = {0};
+#else
+timeval MgTimerUtil::count = {0};
+#endif
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Constructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+
+MgTimerUtil::MgTimerUtil()
+{
+}
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Destructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+
+MgTimerUtil::~MgTimerUtil()
+{
+}
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Retrieves the current time in milliseconds.
+/// </summary>
+///----------------------------------------------------------------------------
+
+double MgTimerUtil::GetTime()
+{
+#ifdef WIN32
+    if(0 == frequency.QuadPart)
+    {
+        GetFrequency(&frequency);
+    }
+    QueryPerformanceCounter(&count);
+
+    return count.QuadPart* (1000.0 / frequency.QuadPart);
+#else
+    gettimeofday(&count, NULL);
+    return (count.tv_sec * 1000.0) + (count.tv_usec / 1000.0);
+#endif
+}
+
+#ifdef WIN32
+///----------------------------------------------------------------------------
+/// <summary>
+/// Invoke the QueryPerformanceFrequency to initialize class member frequency.
+/// </summary>
+///----------------------------------------------------------------------------
+
+void MgTimerUtil::GetFrequency(LARGE_INTEGER* pFrequency)
+{
+    if(!QueryPerformanceFrequency(pFrequency))
+        throw new MgUnclassifiedException(L"MgTimerUtil.GetFrequency", __LINE__, __WFILE__, NULL, L"", NULL);
+}
+#endif

Copied: branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.h (from rev 6602, trunk/MgDev/Desktop/MgDesktop/System/TimerUtil.h)
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/System/TimerUtil.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,75 @@
+#ifndef DESKTOP_TIMER_UTIL_H
+#define DESKTOP_TIMER_UTIL_H
+
+#ifdef WIN32   
+#include <windows.h>
+#else          
+#include <sys/time.h>
+#endif
+
+/// \cond INTERNAL
+class MG_DESKTOP_API MgTimerUtil
+{
+    DECLARE_CLASSNAME(MgTimerUtil)
+
+INTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Constructs the object.
+    ///
+    ///
+
+    MgTimerUtil();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destructs the object.
+    ///
+    ///
+
+    virtual ~MgTimerUtil();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Retrieves the current time in milliseconds
+    ///
+    /// \return
+    /// current time in milliseconds
+    ///
+    ///
+
+    static double GetTime();
+
+private:
+
+    /// Unimplemented Methods
+
+    MgTimerUtil(const MgTimerUtil& util);
+    MgTimerUtil& operator=(const MgTimerUtil& util);
+
+    /// Helper Methods
+
+#ifdef WIN32
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Invoke the QueryPerformanceFrequency to initialize frequency.
+    /// \param pFrequency
+    /// Pointer which idicates the frequncy.
+    ///
+
+    static void GetFrequency(LARGE_INTEGER* pFrequency);
+#endif
+
+private:
+
+#ifdef WIN32
+    static LARGE_INTEGER frequency;
+    static LARGE_INTEGER count;
+#else
+    static timeval count;
+#endif
+};
+/// \endcond
+
+#endif
\ No newline at end of file

Copied: branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.cpp (from rev 6602, trunk/MgDev/Desktop/UnitTest/TestProfilingService.cpp)
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,568 @@
+//
+//  Copyright (C) 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 "TestProfilingService.h"
+#include "StylizationDefs.h"
+const STRING TEST_LOCALE = L"en";
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestProfilingService, "TestProfilingService");
+
+
+TestProfilingService::TestProfilingService()
+{
+    // Initialize service objects.
+    Ptr<MgServiceFactory> factory = new MgServiceFactory();
+
+    m_svcResource = dynamic_cast<MgResourceService*>(
+        factory->CreateService(MgServiceType::ResourceService));
+    assert(m_svcResource != NULL);
+
+    m_svcProfiling = dynamic_cast<MgProfilingService*>(
+        factory->CreateService(MgServiceType::ProfilingService));
+    assert(m_svcProfiling != NULL);
+}
+
+
+TestProfilingService::~TestProfilingService()
+{
+}
+
+
+void TestProfilingService::setUp()
+{
+}
+
+
+void TestProfilingService::tearDown()
+{
+}
+
+
+void TestProfilingService::TestStart()
+{
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\nRunning Profiling Service tests.\n")));
+
+    try
+    {
+        // publish the map definition
+        Ptr<MgResourceIdentifier> mapres1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        Ptr<MgByteSource> mdfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_Sheboygan.mdf", false);
+        Ptr<MgByteReader> mdfrdr1 = mdfsrc1->GetReader();
+        m_svcResource->SetResource(mapres1, mdfrdr1, NULL);
+
+        // publish the layer definitions
+        Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.ldf", false);
+        Ptr<MgByteReader> ldfrdr1 = ldfsrc1->GetReader();
+        m_svcResource->SetResource(ldfres1, ldfrdr1, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_Rail.ldf", false);
+        Ptr<MgByteReader> ldfrdr2 = ldfsrc2->GetReader();
+        m_svcResource->SetResource(ldfres2, ldfrdr2, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc3 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.ldf", false);
+        Ptr<MgByteReader> ldfrdr3 = ldfsrc3->GetReader();
+        m_svcResource->SetResource(ldfres3, ldfrdr3, NULL);
+
+        // publish the feature sources
+        Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
+        Ptr<MgByteSource> fssrc1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.fs", false);
+        Ptr<MgByteReader> fsrdr1 = fssrc1->GetReader();
+        m_svcResource->SetResource(fsres1, fsrdr1, NULL);
+
+        Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
+        Ptr<MgByteSource> fssrc2 = new MgByteSource(L"../UnitTestFiles/UT_Rail.fs", false);
+        Ptr<MgByteReader> fsrdr2 = fssrc2->GetReader();
+        m_svcResource->SetResource(fsres2, fsrdr2, NULL);
+
+        Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
+        Ptr<MgByteSource> fssrc3 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.fs", false);
+        Ptr<MgByteReader> fsrdr3 = fssrc3->GetReader();
+        m_svcResource->SetResource(fsres3, fsrdr3, NULL);
+
+        // publish the resource data
+        Ptr<MgByteSource> dataSource1 = new MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.sdf", false);
+        Ptr<MgByteReader> dataReader1 = dataSource1->GetReader();
+        m_svcResource->SetResourceData(fsres1, L"UT_HydrographicPolygons.sdf", L"File", dataReader1);
+
+        Ptr<MgByteSource> dataSource2 = new MgByteSource(L"../UnitTestFiles/UT_Rail.sdf", false);
+        Ptr<MgByteReader> dataReader2 = dataSource2->GetReader();
+        m_svcResource->SetResourceData(fsres2, L"UT_Rail.sdf", L"File", dataReader2);
+
+        Ptr<MgByteSource> dataSource3 = new MgByteSource(L"../UnitTestFiles/UT_Parcels.sdf", false);
+        Ptr<MgByteReader> dataReader3 = dataSource3->GetReader();
+        m_svcResource->SetResourceData(fsres3, L"UT_Parcels.sdf", L"File", dataReader3);
+
+        // publish the print layouts
+        Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
+        Ptr<MgByteSource> plsrc1 = new MgByteSource(L"../UnitTestFiles/UT_AllElements.pl", false);
+        Ptr<MgByteReader> plrdr1 = plsrc1->GetReader();
+        m_svcResource->SetResource(plres1, plrdr1, NULL);
+
+        Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
+        Ptr<MgByteSource> plsrc2 = new MgByteSource(L"../UnitTestFiles/UT_NoLegend.pl", false);
+        Ptr<MgByteReader> plrdr2 = plsrc2->GetReader();
+        m_svcResource->SetResource(plres2, plrdr2, NULL);
+
+        // publish the symbol library
+        Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
+        Ptr<MgByteSource> slsrc1 = new MgByteSource(L"../UnitTestFiles/UT_SymbolMart.sl", false);
+        Ptr<MgByteReader> slrdr1 = slsrc1->GetReader();
+        m_svcResource->SetResource(slres1, slrdr1, NULL);
+        Ptr<MgByteSource> datasrc = new MgByteSource(L"../UnitTestFiles/UT_Symbols.dwf", false);
+        Ptr<MgByteReader> datardr = datasrc->GetReader();
+        m_svcResource->SetResourceData(slres1, L"symbols.dwf", L"File", datardr);
+
+        //
+        // publish symbology stuff
+        //
+
+        // the point feature source
+        Ptr<MgResourceIdentifier> fsres4 = new MgResourceIdentifier(L"Library://UnitTests/Data/Capitals.FeatureSource");
+        Ptr<MgByteSource> fssrc4 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPoints.fs", false);
+        Ptr<MgByteReader> fsrdr4 = fssrc4->GetReader();
+        m_svcResource->SetResource(fsres4, fsrdr4, NULL);
+
+        // point sdf file
+        Ptr<MgByteSource> dataSource4 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPoints.sdf", false);
+        Ptr<MgByteReader> dataReader4 = dataSource4->GetReader();
+        m_svcResource->SetResourceData(fsres4, L"UT_SymbologyPoints.sdf", L"File", dataReader4);
+
+        // point symbols
+        Ptr<MgResourceIdentifier> sdres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/PointSymbol.SymbolDefinition");
+        Ptr<MgByteSource> sdsrc1 = new MgByteSource(L"../UnitTestFiles/symbol.sd", false);
+        Ptr<MgByteReader> sdrdr1 = sdsrc1->GetReader();
+        m_svcResource->SetResource(sdres1, sdrdr1, NULL);
+
+        Ptr<MgResourceIdentifier> sdres2 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/PointSymbolParam.SymbolDefinition");
+        Ptr<MgByteSource> sdsrc2 = new MgByteSource(L"../UnitTestFiles/symbolp.sd", false);
+        Ptr<MgByteReader> sdrdr2 = sdsrc2->GetReader();
+        m_svcResource->SetResource(sdres2, sdrdr2, NULL);
+
+        // point ldf
+        Ptr<MgResourceIdentifier> ldfres4 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Capitals.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc4 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPoints.ldf", false);
+        Ptr<MgByteReader> ldfrdr4 = ldfsrc4->GetReader();
+        m_svcResource->SetResource(ldfres4, ldfrdr4, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/CapitalsParam.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc5 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPointsParam.ldf", false);
+        Ptr<MgByteReader> ldfrdr5 = ldfsrc5->GetReader();
+        m_svcResource->SetResource(ldfres5, ldfrdr5, NULL);
+
+        // point mdf
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Capitals.MapDefinition");
+        Ptr<MgByteSource> mdfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPoints.mdf", false);
+        Ptr<MgByteReader> mdfrdr2 = mdfsrc2->GetReader();
+        m_svcResource->SetResource(mapres2, mdfrdr2, NULL);
+
+        Ptr<MgResourceIdentifier> mapres3 = new MgResourceIdentifier(L"Library://UnitTests/Maps/CapitalsParam.MapDefinition");
+        Ptr<MgByteSource> mdfsrc3 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPointsParam.mdf", false);
+        Ptr<MgByteReader> mdfrdr3 = mdfsrc3->GetReader();
+        m_svcResource->SetResource(mapres3, mdfrdr3, NULL);
+
+        // the line feature source
+        Ptr<MgResourceIdentifier> fsres5 = new MgResourceIdentifier(L"Library://UnitTests/Data/Lines.FeatureSource");
+        Ptr<MgByteSource> fssrc5 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLines.fs", false);
+        Ptr<MgByteReader> fsrdr5 = fssrc5->GetReader();
+        m_svcResource->SetResource(fsres5, fsrdr5, NULL);
+
+        // line sdf file
+        Ptr<MgByteSource> dataSource5 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLines.sdf", false);
+        Ptr<MgByteReader> dataReader5 = dataSource5->GetReader();
+        m_svcResource->SetResourceData(fsres5, L"UT_SymbologyLines.sdf", L"File", dataReader5);
+
+        // line symbols
+        Ptr<MgResourceIdentifier> sdres3 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/LineSymbol.SymbolDefinition");
+        Ptr<MgByteSource> sdsrc3 = new MgByteSource(L"../UnitTestFiles/linesymbol.sd", false);
+        Ptr<MgByteReader> sdrdr3 = sdsrc3->GetReader();
+        m_svcResource->SetResource(sdres3, sdrdr3, NULL);
+
+        Ptr<MgResourceIdentifier> sdres4 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/MTYP1500a.SymbolDefinition");
+        Ptr<MgByteSource> sdsrc4 = new MgByteSource(L"../UnitTestFiles/MTYP1500a.sd", false);
+        Ptr<MgByteReader> sdrdr4 = sdsrc4->GetReader();
+        m_svcResource->SetResource(sdres4, sdrdr4, NULL);
+
+        // line ldf
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Lines.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc6 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLines.ldf", false);
+        Ptr<MgByteReader> ldfrdr6 = ldfsrc6->GetReader();
+        m_svcResource->SetResource(ldfres6, ldfrdr6, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres7 = new MgResourceIdentifier(L"Library://UnitTests/Layers/LinesCrossTick.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc7 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLinesCrossTick.ldf", false);
+        Ptr<MgByteReader> ldfrdr7 = ldfsrc7->GetReader();
+        m_svcResource->SetResource(ldfres7, ldfrdr7, NULL);
+
+        // line mdf
+        Ptr<MgResourceIdentifier> mapres4 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Lines.MapDefinition");
+        Ptr<MgByteSource> mdfsrc4 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLines.mdf", false);
+        Ptr<MgByteReader> mdfrdr4 = mdfsrc4->GetReader();
+        m_svcResource->SetResource(mapres4, mdfrdr4, NULL);
+
+        Ptr<MgResourceIdentifier> mapres5 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinesCrossTick.MapDefinition");
+        Ptr<MgByteSource> mdfsrc5 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyLinesCrossTick.mdf", false);
+        Ptr<MgByteReader> mdfrdr5 = mdfsrc5->GetReader();
+        m_svcResource->SetResource(mapres5, mdfrdr5, NULL);
+
+        // annotation ldf - this shares the point sdf
+        Ptr<MgResourceIdentifier> ldfres8 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation1.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc8 = new MgByteSource(L"../UnitTestFiles/UT_Annotation1.ldf", false);
+        Ptr<MgByteReader> ldfrdr8 = ldfsrc8->GetReader();
+        m_svcResource->SetResource(ldfres8, ldfrdr8, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres9 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation2.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc9 = new MgByteSource(L"../UnitTestFiles/UT_Annotation2.ldf", false);
+        Ptr<MgByteReader> ldfrdr9 = ldfsrc9->GetReader();
+        m_svcResource->SetResource(ldfres9, ldfrdr9, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres10 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation3.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc10 = new MgByteSource(L"../UnitTestFiles/UT_Annotation3.ldf", false);
+        Ptr<MgByteReader> ldfrdr10 = ldfsrc10->GetReader();
+        m_svcResource->SetResource(ldfres10, ldfrdr10, NULL);
+
+        // annotation mdf
+        Ptr<MgResourceIdentifier> mapres8 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation1.MapDefinition");
+        Ptr<MgByteSource> mdfsrc8 = new MgByteSource(L"../UnitTestFiles/UT_Annotation1.mdf", false);
+        Ptr<MgByteReader> mdfrdr8 = mdfsrc8->GetReader();
+        m_svcResource->SetResource(mapres8, mdfrdr8, NULL);
+
+        Ptr<MgResourceIdentifier> mapres9 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation2.MapDefinition");
+        Ptr<MgByteSource> mdfsrc9 = new MgByteSource(L"../UnitTestFiles/UT_Annotation2.mdf", false);
+        Ptr<MgByteReader> mdfrdr9 = mdfsrc9->GetReader();
+        m_svcResource->SetResource(mapres9, mdfrdr9, NULL);
+
+        Ptr<MgResourceIdentifier> mapres10 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation3.MapDefinition");
+        Ptr<MgByteSource> mdfsrc10 = new MgByteSource(L"../UnitTestFiles/UT_Annotation3.mdf", false);
+        Ptr<MgByteReader> mdfrdr10 = mdfsrc10->GetReader();
+        m_svcResource->SetResource(mapres10, mdfrdr10, NULL);
+
+        //symbology - polygons
+        Ptr<MgResourceIdentifier> mapres11 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_SymbologyPolygons.MapDefinition");
+        Ptr<MgByteSource> mdfsrc11 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyPolygons.mdf", false);
+        Ptr<MgByteReader> mdfrdr11 = mdfsrc11->GetReader();
+        m_svcResource->SetResource(mapres11, mdfrdr11, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres11 = new MgResourceIdentifier(L"Library://UnitTests/Layers/SymbologyParcels.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc11 = new MgByteSource(L"../UnitTestFiles/UT_SymbologyParcels.ldf", false);
+        Ptr<MgByteReader> ldfrdr11 = ldfsrc11->GetReader();
+        m_svcResource->SetResource(ldfres11, ldfrdr11, NULL);
+
+        Ptr<MgResourceIdentifier> sdres5 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/AreaSymbol.SymbolDefinition");
+        Ptr<MgByteSource> sdsrc5 = new MgByteSource(L"../UnitTestFiles/areasymbol.sd", false);
+        Ptr<MgByteReader> sdrdr5 = sdsrc5->GetReader();
+        m_svcResource->SetResource(sdres5, sdrdr5, NULL);
+
+        // For watermark test
+        // publish the map definition
+        Ptr<MgResourceIdentifier> mapres12 = new MgResourceIdentifier(L"Library://UnitTests/Maps/SheboyganWithWatermark.MapDefinition");
+        Ptr<MgByteSource> mdfsrc12 = new MgByteSource(L"../UnitTestFiles/UT_SheboyganWithWatermark.mdf", false);
+        Ptr<MgByteReader> mdfrdr12 = mdfsrc12->GetReader();
+        m_svcResource->SetResource(mapres12, mdfrdr12, NULL);
+
+        // publish the watermark definition
+        Ptr<MgResourceIdentifier> wdfres1 = new MgResourceIdentifier(L"Library://UnitTests/Watermarks/PoweredByMapGuide.WatermarkDefinition");
+        Ptr<MgByteSource> wdfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_PoweredByMapGuide.wdf", false);
+        Ptr<MgByteReader> wdfrdr1 = wdfsrc1->GetReader();
+        m_svcResource->SetResource(wdfres1, wdfrdr1, NULL);
+
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+
+void TestProfilingService::TestEnd()
+{
+    try
+    {
+        // delete the map definition
+        Ptr<MgResourceIdentifier> mapres1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+        m_svcResource->DeleteResource(mapres1);
+
+        // delete the layer definitions
+        Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/HydrographicPolygons.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres1);
+
+        Ptr<MgResourceIdentifier> ldfres2 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Rail.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres2);
+
+        Ptr<MgResourceIdentifier> ldfres3 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Parcels.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres3);
+
+        // delete the feature sources
+        Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
+        m_svcResource->DeleteResource(fsres1);
+
+        Ptr<MgResourceIdentifier> fsres2 = new MgResourceIdentifier(L"Library://UnitTests/Data/Rail.FeatureSource");
+        m_svcResource->DeleteResource(fsres2);
+
+        Ptr<MgResourceIdentifier> fsres3 = new MgResourceIdentifier(L"Library://UnitTests/Data/Parcels.FeatureSource");
+        m_svcResource->DeleteResource(fsres3);
+
+        // delete the print layouts
+        Ptr<MgResourceIdentifier> plres1 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/AllElements.PrintLayout");
+        m_svcResource->DeleteResource(plres1);
+
+        Ptr<MgResourceIdentifier> plres2 = new MgResourceIdentifier(L"Library://UnitTests/PrintLayouts/NoLegend.PrintLayout");
+        m_svcResource->DeleteResource(plres2);
+
+        // delete the symbol library
+        Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
+        m_svcResource->DeleteResource(slres1);
+
+        // delete symbology stuff
+        Ptr<MgResourceIdentifier> fsres4 = new MgResourceIdentifier(L"Library://UnitTests/Data/Capitals.FeatureSource");
+        m_svcResource->DeleteResource(fsres4);
+        Ptr<MgResourceIdentifier> sdres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/PointSymbol.SymbolDefinition");
+        m_svcResource->DeleteResource(sdres1);
+        Ptr<MgResourceIdentifier> sdres2 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/PointSymbolParam.SymbolDefinition");
+        m_svcResource->DeleteResource(sdres2);
+        Ptr<MgResourceIdentifier> ldfres4 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Capitals.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres4);
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/CapitalsParam.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres5);
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Capitals.MapDefinition");
+        m_svcResource->DeleteResource(mapres2);
+        Ptr<MgResourceIdentifier> mapres3 = new MgResourceIdentifier(L"Library://UnitTests/Maps/CapitalsParam.MapDefinition");
+        m_svcResource->DeleteResource(mapres3);
+
+        Ptr<MgResourceIdentifier> fsres5 = new MgResourceIdentifier(L"Library://UnitTests/Data/Lines.FeatureSource");
+        m_svcResource->DeleteResource(fsres5);
+        Ptr<MgResourceIdentifier> sdres3 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/LineSymbol.SymbolDefinition");
+        m_svcResource->DeleteResource(sdres3);
+        Ptr<MgResourceIdentifier> sdres4 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/MTYP1500a.SymbolDefinition");
+        m_svcResource->DeleteResource(sdres4);
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/Lines.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres6);
+        Ptr<MgResourceIdentifier> ldfres7 = new MgResourceIdentifier(L"Library://UnitTests/Layers/LinesCrossTick.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres7);
+        Ptr<MgResourceIdentifier> mapres4 = new MgResourceIdentifier(L"Library://UnitTests/Maps/Lines.MapDefinition");
+        m_svcResource->DeleteResource(mapres4);
+        Ptr<MgResourceIdentifier> mapres5 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinesCrossTick.MapDefinition");
+        m_svcResource->DeleteResource(mapres5);
+
+        Ptr<MgResourceIdentifier> ldfres8 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation1.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres8);
+        Ptr<MgResourceIdentifier> ldfres9 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation2.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres9);
+        Ptr<MgResourceIdentifier> ldfres10 = new MgResourceIdentifier(L"Library://UnitTests/Layers/UT_Annotation3.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres10);
+        Ptr<MgResourceIdentifier> mapres8 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation1.MapDefinition");
+        m_svcResource->DeleteResource(mapres8);
+        Ptr<MgResourceIdentifier> mapres9 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation2.MapDefinition");
+        m_svcResource->DeleteResource(mapres9);
+        Ptr<MgResourceIdentifier> mapres10 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_Annotation3.MapDefinition");
+        m_svcResource->DeleteResource(mapres10);
+
+        Ptr<MgResourceIdentifier> mapres11 = new MgResourceIdentifier(L"Library://UnitTests/Maps/UT_SymbologyPolygons.MapDefinition");
+        m_svcResource->DeleteResource(mapres11);
+        Ptr<MgResourceIdentifier> ldfres11 = new MgResourceIdentifier(L"Library://UnitTests/Layers/SymbologyParcels.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres11);
+        Ptr<MgResourceIdentifier> sdres5 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/AreaSymbol.SymbolDefinition");
+        m_svcResource->DeleteResource(sdres5);
+        
+        Ptr<MgResourceIdentifier> mapres12 = new MgResourceIdentifier(L"Library://UnitTests/Maps/SheboyganWithWatermark.MapDefinition");
+        m_svcResource->DeleteResource(mapres12);
+        Ptr<MgResourceIdentifier> wdfres1 = new MgResourceIdentifier(L"Library://UnitTests/Watermarks/PoweredByMapGuide.WatermarkDefinition");
+        m_svcResource->DeleteResource(wdfres1);
+
+       #ifdef _DEBUG
+        MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
+        if(pFdoConnectionManager)
+        {
+            pFdoConnectionManager->ShowCache();
+        }
+        #endif
+    }
+    catch(MgFileIoException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\nMgFileIoException - Possible file permission error.\nError: %W\n"), message.c_str()));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        message += e->GetStackTrace(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+
+    ACE_DEBUG((LM_INFO, ACE_TEXT("\nProfiling Service tests completed.\n\n")));
+}
+
+
+void TestProfilingService::TestCase_ProfileRenderDynamicOverlay()
+{
+    try
+    {
+        // make a runtime normal map
+        Ptr<MgdMap> map = CreateTestMap();
+        Ptr<MgdSelection> selectionOnMap = CreateSelection(map);
+
+        // make a runtime map with watermark
+        Ptr<MgdMap> mapWithWatermark = CreateTestMapWithWatermark();
+        Ptr<MgdSelection> selectionOnMapWithWatermark = CreateSelection(mapWithWatermark);
+
+        // make a rendering option
+        Ptr<MgRenderingOptions> options = new MgRenderingOptions(L"PNG",MgRenderingOptions::RenderSelection| MgRenderingOptions::RenderLayers| MgRenderingOptions::KeepSelection,NULL);
+        
+        // profile rendering normal map
+        Ptr<MgByteReader> rdr1 = m_svcProfiling->ProfileRenderDynamicOverlay(map, NULL, options);
+        rdr1->ToFile(L"../UnitTestFiles/ProfileRenderDynamicOverlay_Normal.xml");
+
+        // profile rendering normal map with selection
+        Ptr<MgByteReader> rdr2 = m_svcProfiling->ProfileRenderDynamicOverlay(map, selectionOnMap, options);
+        rdr2->ToFile(L"../UnitTestFiles/ProfileRenderDynamicOverlay_Selection.xml");
+
+        // profile rendering map with watermark
+        Ptr<MgByteReader> rdr3 = m_svcProfiling->ProfileRenderDynamicOverlay(mapWithWatermark, NULL, options);
+        rdr3->ToFile(L"../UnitTestFiles/ProfileRenderDynamicOverlay_Watermark.xml");
+
+        // profile rendering map with both watermark and selection
+        Ptr<MgByteReader> rdr4 = m_svcProfiling->ProfileRenderDynamicOverlay(mapWithWatermark, selectionOnMapWithWatermark, options);
+        rdr4->ToFile(L"../UnitTestFiles/ProfileRenderDynamicOverlay_Watermark_Selection.xml");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+
+void TestProfilingService::TestCase_ProfileRenderMap()
+{
+    try
+    {
+        // make a runtime normal map
+        Ptr<MgdMap> map = CreateTestMap();
+        Ptr<MgdSelection> selectionOnMap = CreateSelection(map);
+
+        // make a runtime map with watermark
+        Ptr<MgdMap> mapWithWatermark = CreateTestMapWithWatermark();
+        Ptr<MgdSelection> selectionOnMapWithWatermark = CreateSelection(mapWithWatermark);
+
+        // make a rendering option
+        Ptr<MgRenderingOptions> options = new MgRenderingOptions(L"PNG",MgRenderingOptions::RenderSelection| MgRenderingOptions::RenderLayers| MgRenderingOptions::KeepSelection,NULL);
+
+        Ptr<MgCoordinate> coordNewCenter = new MgCoordinateXY(-87.733253, 43.746199);
+        Ptr<MgColor> bgc = new MgColor(255, 255, 255, 255);
+
+        // profile rendering normal map
+        Ptr<MgByteReader> rdr1 = m_svcProfiling->ProfileRenderMap(map, NULL, coordNewCenter, 75000, 1024, 1024, bgc, L"PNG", false);
+        rdr1->ToFile(L"../UnitTestFiles/ProfileRenderMap_Normal.xml");
+
+        // profile rendering normal map with selection
+        Ptr<MgByteReader> rdr2 = m_svcProfiling->ProfileRenderMap(map, selectionOnMap, coordNewCenter, 75000, 1024, 1024, bgc, L"PNG", false);
+        rdr2->ToFile(L"../UnitTestFiles/ProfileRenderMap_Selection.xml");
+
+        // profile rendering normal map with watermark
+        Ptr<MgByteReader> rdr3 = m_svcProfiling->ProfileRenderMap(mapWithWatermark, NULL, coordNewCenter, 75000, 1024, 1024, bgc, L"PNG", false);
+        rdr3->ToFile(L"../UnitTestFiles/ProfileRenderMap_Watermark.xml");
+
+        // profile rendering normal map with watermark
+        Ptr<MgByteReader> rdr4 = m_svcProfiling->ProfileRenderMap(mapWithWatermark, selectionOnMapWithWatermark, coordNewCenter, 75000, 1024, 1024, bgc, L"PNG", false);
+        rdr4->ToFile(L"../UnitTestFiles/ProfileRenderMap_Watermark_Selection.xml");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+MgdMap* TestProfilingService::CreateTestMap()
+{
+    Ptr<MgResourceIdentifier> mdfres = new MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition");
+    MgdMap* map = new MgdMap(mdfres, L"UnitTestSheboygan");
+
+    Ptr<MgCoordinate> coordNewCenter = new MgCoordinateXY(-87.733253, 43.746199);
+    Ptr<MgPoint> ptNewCenter = new MgPoint(coordNewCenter);
+    map->SetViewCenter(ptNewCenter);
+    map->SetViewScale(75000.0);
+    map->SetDisplayDpi(96);
+    map->SetDisplayWidth(1024);
+    map->SetDisplayHeight(1024);
+
+    return map;
+}
+
+MgdMap* TestProfilingService::CreateTestMapWithWatermark()
+{
+    Ptr<MgResourceIdentifier> mdfres = new MgResourceIdentifier(L"Library://UnitTests/Maps/SheboyganWithWatermark.MapDefinition");
+    MgdMap* map = new MgdMap(mdfres, L"UnitTestSheboyganWithWatermark");
+
+    Ptr<MgCoordinate> coordNewCenter = new MgCoordinateXY(-87.733253, 43.746199);
+    Ptr<MgPoint> ptNewCenter = new MgPoint(coordNewCenter);
+    map->SetViewCenter(ptNewCenter);
+    map->SetViewScale(75000.0);
+    map->SetDisplayDpi(96);
+    map->SetDisplayWidth(1024);
+    map->SetDisplayHeight(1024);
+
+    return map;
+}
+
+MgdSelection* TestProfilingService::CreateSelection(MgdMap* map)
+{
+    // make a selection in normal map
+    STRING layerId;
+    Ptr<MgLayerCollection> layers = map->GetLayers();
+
+    for (int i=0; i<layers->GetCount(); i++)
+    {
+        Ptr<MgLayerBase> layer = layers->GetItem(i);
+        if(L"HydrographicPolygons" ==layer->GetName())
+        {
+            layerId = layer->GetObjectId();
+        }
+    }
+    STRING selectionStr = L"<?xml version=\"1.0\" encoding=\"UTF-8\"?><FeatureSet><Layer id=\"";
+    selectionStr.append(layerId);
+    selectionStr.append(L"\"><Class id=\"SHP_Schema:HydrographicPolygons\"><ID>HQAAAA==</ID></Class></Layer></FeatureSet>");
+
+    MgdSelection* selection = new MgdSelection(map, selectionStr);
+    return selection;
+}
+

Copied: branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.h (from rev 6602, trunk/MgDev/Desktop/UnitTest/TestProfilingService.h)
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/UnitTest/TestProfilingService.h	2012-04-29 22:11:03 UTC (rev 6603)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 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 _TESTPROFILINGSERVICE_H
+#define _TESTPROFILINGSERVICE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class TestProfilingService : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE(TestProfilingService);
+    CPPUNIT_TEST(TestStart); // This must be the very first unit test
+
+    CPPUNIT_TEST(TestCase_ProfileRenderDynamicOverlay);
+    CPPUNIT_TEST(TestCase_ProfileRenderMap);
+
+    CPPUNIT_TEST(TestEnd); // This must be the very last unit test
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+    TestProfilingService();
+    ~TestProfilingService();
+
+    void setUp();
+    void tearDown();
+    void TestStart();
+    void TestEnd();
+
+    void TestCase_ProfileRenderDynamicOverlay();
+    void TestCase_ProfileRenderMap();
+
+private:
+    MgdMap* CreateTestMap();
+    MgdMap* CreateTestMapWithWatermark();
+    MgdSelection* CreateSelection(MgdMap* map);
+
+private:
+    Ptr<MgResourceService> m_svcResource;
+    Ptr<MgProfilingService> m_svcProfiling;
+};
+
+#endif // _TESTPROFILINGSERVICE_H

Modified: branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj	2012-04-29 22:11:03 UTC (rev 6603)
@@ -283,6 +283,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="TestProfilingService.cpp" />
     <ClCompile Include="TestRenderingService.cpp" />
     <ClCompile Include="TestResourceService.cpp" />
     <ClCompile Include="TestTileService.cpp" />
@@ -293,6 +294,7 @@
     <ClInclude Include="TestKmlService.h" />
     <ClInclude Include="TestMappingService.h" />
     <ClInclude Include="TestPerformance.h" />
+    <ClInclude Include="TestProfilingService.h" />
     <ClInclude Include="TestRenderingService.h" />
     <ClInclude Include="TestResourceService.h" />
     <ClInclude Include="TestTileService.h" />

Modified: branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj.filters
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj.filters	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/UnitTest/UnitTest.vcxproj.filters	2012-04-29 22:11:03 UTC (rev 6603)
@@ -39,6 +39,9 @@
     <ClCompile Include="TestTileService.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="TestProfilingService.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="CppUnitExtensions.h">
@@ -68,5 +71,8 @@
     <ClInclude Include="UnitTesting.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="TestProfilingService.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/UnitTest/main.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-04-29 21:45:57 UTC (rev 6602)
+++ branches/2.4/MgDev/Desktop/UnitTest/main.cpp	2012-04-29 22:11:03 UTC (rev 6603)
@@ -66,6 +66,7 @@
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestResourceService").makeTest());
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestRenderingService").makeTest());
     runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestFeatureService").makeTest());
+	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry("TestProfilingService").makeTest());
     
     //This causes access violations in Visual Leak Detector when run in debug mode. Only uncommment
     //to verify functionality, but don't use VLD for memory leak detection. Seek an alternate tool/library



More information about the mapguide-commits mailing list