[mapguide-commits] r8330 - in trunk/MgDev: . Common/MapGuideCommon Common/MapGuideCommon/Exception Common/MapGuideCommon/MapLayer Common/MapGuideCommon/Resources Common/MapGuideCommon/Services Common/MapGuideCommon/System Common/MdfModel Common/MdfParser Common/PlatformBase/MapLayer Common/PlatformBase/Services Common/Schema Doc/samples Doc/samples/ol2samples Doc/samples/ol2samples/tiled Doc/samples/ol2samples/xyz Server/src/Common/Manager Server/src/Core Server/src/PostBuild Server/src/Services/Mapping Server/src/Services/Rendering Server/src/Services/Resource Server/src/Services/Tile Server/src/UnitTesting UnitTest/TestData/Samples/Sheboygan UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers_Advanced UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/MapsTiled UnitTest/TestData/TileService UnitTest/WebTier/MapAgent/MapAgentFor ms Web/src/HttpHandler Web/src/mapviewerjava Web/src/mapviewernet Web/src/mapviewerphp

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Aug 12 04:11:22 PDT 2014


Author: jng
Date: 2014-08-12 04:11:22 -0700 (Tue, 12 Aug 2014)
New Revision: 8330

Added:
   trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.cpp
   trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.h
   trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp
   trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h
   trunk/MgDev/Common/MdfModel/TileSetDefinition.cpp
   trunk/MgDev/Common/MdfModel/TileSetDefinition.h
   trunk/MgDev/Common/MdfModel/TileSetSource.cpp
   trunk/MgDev/Common/MdfModel/TileSetSource.h
   trunk/MgDev/Common/MdfModel/TileStoreParameters.cpp
   trunk/MgDev/Common/MdfModel/TileStoreParameters.h
   trunk/MgDev/Common/MdfParser/IOTileSetDefinition.cpp
   trunk/MgDev/Common/MdfParser/IOTileSetDefinition.h
   trunk/MgDev/Common/MdfParser/IOTileSetSource.cpp
   trunk/MgDev/Common/MdfParser/IOTileSetSource.h
   trunk/MgDev/Common/MdfParser/IOTileStoreParameters.cpp
   trunk/MgDev/Common/MdfParser/IOTileStoreParameters.h
   trunk/MgDev/Common/Schema/MapDefinition-3.0.0.xsd
   trunk/MgDev/Common/Schema/RuntimeMap-3.0.0.xsd
   trunk/MgDev/Common/Schema/TileProviderList-3.0.0.xsd
   trunk/MgDev/Common/Schema/TileSetDefinition-3.0.0.xsd
   trunk/MgDev/Doc/samples/ol2samples/xyz/
   trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.cpp
   trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.h
   trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.cpp
   trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.h
   trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.cpp
   trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.h
   trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.h
   trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.h
   trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.h
   trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/TileSets/
   trunk/MgDev/UnitTest/TestData/TileService/UT_BaseMap.tsd
   trunk/MgDev/UnitTest/TestData/TileService/UT_LinkedTileSet.mdf
   trunk/MgDev/UnitTest/TestData/TileService/UT_XYZ.tsd
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileprovidersform.html
   trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.h
Modified:
   trunk/MgDev/
   trunk/MgDev/Common/MapGuideCommon/Makefile.am
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
   trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp
   trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.cpp
   trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.h
   trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res
   trunk/MgDev/Common/MapGuideCommon/Services/MappingDefs.h
   trunk/MgDev/Common/MapGuideCommon/Services/MappingService.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h
   trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h
   trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h
   trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.h
   trunk/MgDev/Common/MapGuideCommon/Services/TileService.h
   trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h
   trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
   trunk/MgDev/Common/MdfModel/Makefile.am
   trunk/MgDev/Common/MdfModel/MapDefinition.cpp
   trunk/MgDev/Common/MdfModel/MapDefinition.h
   trunk/MgDev/Common/MdfModel/MdfModel.vcxproj
   trunk/MgDev/Common/MdfModel/MdfModel.vcxproj.filters
   trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.cpp
   trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.h
   trunk/MgDev/Common/MdfParser/IOExtra.cpp
   trunk/MgDev/Common/MdfParser/IOExtra.h
   trunk/MgDev/Common/MdfParser/IOMapDefinition.cpp
   trunk/MgDev/Common/MdfParser/IOMapDefinition.h
   trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.cpp
   trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.h
   trunk/MgDev/Common/MdfParser/IONameStringPair.cpp
   trunk/MgDev/Common/MdfParser/IONameStringPair.h
   trunk/MgDev/Common/MdfParser/Makefile.am
   trunk/MgDev/Common/MdfParser/MdfParser.vcxproj
   trunk/MgDev/Common/MdfParser/MdfParser.vcxproj.filters
   trunk/MgDev/Common/MdfParser/SAX2Parser.cpp
   trunk/MgDev/Common/MdfParser/SAX2Parser.h
   trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.cpp
   trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.h
   trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroupType.h
   trunk/MgDev/Common/PlatformBase/MapLayer/MapBase.h
   trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.cpp
   trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.h
   trunk/MgDev/Common/PlatformBase/Services/ResourceService.h
   trunk/MgDev/Doc/samples/ol2samples/tiled/index.html
   trunk/MgDev/Doc/samples/ol2samples/xyz/index.html
   trunk/MgDev/Doc/samples/samples.php
   trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp
   trunk/MgDev/Server/src/Core/Makefile.am
   trunk/MgDev/Server/src/PostBuild/PostBuild.mak
   trunk/MgDev/Server/src/Services/Mapping/MappingOperationFactory.cpp
   trunk/MgDev/Server/src/Services/Mapping/OpCreateRuntimeMap.cpp
   trunk/MgDev/Server/src/Services/Mapping/OpDescribeRuntimeMap.cpp
   trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.cpp
   trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.h
   trunk/MgDev/Server/src/Services/Rendering/Makefile.am
   trunk/MgDev/Server/src/Services/Rendering/OpRenderTile.cpp
   trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp
   trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp
   trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h
   trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj
   trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters
   trunk/MgDev/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp
   trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.cpp
   trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.h
   trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.cpp
   trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.h
   trunk/MgDev/Server/src/Services/Resource/Makefile.am
   trunk/MgDev/Server/src/Services/Resource/ResourceOperationFactory.cpp
   trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp
   trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h
   trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj
   trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj.filters
   trunk/MgDev/Server/src/Services/Resource/ServerResourceServiceBuild.cpp
   trunk/MgDev/Server/src/Services/Tile/Makefile.am
   trunk/MgDev/Server/src/Services/Tile/OpClearCache.cpp
   trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeX.cpp
   trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeY.cpp
   trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
   trunk/MgDev/Server/src/Services/Tile/ServerTileService.h
   trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj
   trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj.filters
   trunk/MgDev/Server/src/Services/Tile/ServerTileServiceBuild.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCache.h
   trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp
   trunk/MgDev/Server/src/UnitTesting/TestMappingService.cpp
   trunk/MgDev/Server/src/UnitTesting/TestMappingService.h
   trunk/MgDev/Server/src/UnitTesting/TestMdfModel.cpp
   trunk/MgDev/Server/src/UnitTesting/TestMdfModel.h
   trunk/MgDev/Server/src/UnitTesting/TestRenderingService.cpp
   trunk/MgDev/Server/src/UnitTesting/TestRenderingService.h
   trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp
   trunk/MgDev/Server/src/UnitTesting/TestTileService.h
   trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml
   trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_CONTENT.xml
   trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml
   trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/MgResourcePackageManifest.xml
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cleartilecacheform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizexform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizeyform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html
   trunk/MgDev/Web/src/HttpHandler/HttpClearTileCache.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpDescribeRuntimeMap.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.h
   trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.h
   trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
   trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
   trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
   trunk/MgDev/Web/src/HttpHandler/Makefile.am
   trunk/MgDev/Web/src/mapviewerjava/legend.jsp
   trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp
   trunk/MgDev/Web/src/mapviewernet/legend.aspx
   trunk/MgDev/Web/src/mapviewernet/mapframe.aspx
   trunk/MgDev/Web/src/mapviewerphp/legend.php
   trunk/MgDev/Web/src/mapviewerphp/mapframe.php
   trunk/MgDev/run_tests.bat
Log:
Implement RFC 140. This consists of the following changes:

Merged revision(s) 8174-8208 from sandbox/jng/tiling:
Add new APIs to MgRenderingService:
 - RenderTile overload that accepts tile width, tile height, tile dpi and tile image format.
 - RenderTileXYZ, allows rendering of tiled maps as XYZ tiles similar to Google Maps, OSM and similar maps.

New unit tests added to exercise these APIs.
........
Apply scaling logic (same logic used in RenderMap overloads that take MgEnvelope) for XYZ-rendered tiles.
........
Add new resource type: TileSetDefinition

A Tile Set Definition is essentially the BaseMapDefinition component of the Map Definition document, separated out to a separate resource, with ability to also specify:
 * Tile Image Format
 * Tile Width
 * Tile Height

The Tile Set Definition schema also supports a FDO-style provider model where a provider can be specified via a provider name and set of name/value parameters.

MgMap is updated to handle TileSetDefinition resources if referenced.

Nothing uses this new resource type yet. That will come in future submissions
........
This submission performs open-heart surgery on the server tile service.

MgTileCache has been re-defined as an abstract class providing a similar interface to MgTileService which currently has one subclass: MgTileCacheDefault.

The new role of MgServerTileService is simply to instantiate the correct MgTileCache subclass instance and forward the calls to it.

MgTileCacheDefault is the amalgamation of the old implementations of MgServerTileService and MgTileCache, and provides the existing tile management logic for existing tiled Map Definitions.

This is done to allow for a TileSetDefinition-driven MgTileCache subclass in the near future, which the refactored MgServerTileService is ready to forward requests to when implemented.
........
MdfModel/MdfParser/Schema updates
 - Fix TileSetDefinition not being read by SAX2Parser
 - Fix BaseMapLayerGroup instances not being attached to TileSetDefinition
 - Fix NameStringPair instances not being attached to TileStoreParameters
 - Rename ImageFormat to Format in TileSetDefinition-3.0.0.xsd
 - Fix incorrect version in MapDefinition-3.0.0.xsd
........
Add MG_TILE_CACHE_PATH to list of special tags
........
Add first cut of shareable tile sets:
 - Add a new implementation of MgTileCache (MgTileCacheDefaultProvider) that inherits from MgTileCacheDefaults and overrides several key methods, to return values that are plugged in by the TileSetDefinition resource.
 - Modify MgMap to allow creation from
   - A Map Definition
   - A Map Definition that links to a Tile Set Definition
   - A Tile Set Definition
   This is to allow the tile rendering off of Tile Set Definitions to work as they require a MgMap be passed to the RenderTile() method.
 - Add new unit tests
   - MdfModel test to ensure a TileSetDefinition is properly deserialized
   - Tile Service tests to exercise multi-threaded GetTile() calls to a tile set definition and clearing the cache of a tile set definition
   - MgMap tests to exercise creation from the new input resource permutations
........
Implement GetTileProviders
........
Add missing files from previous submissions
........
This submission includes the following changes:
 - Hook up existing tile cache invalidation to also flush out caches for Tile Set Definitions. This required a new internal EnumerateParentTileSetDefinitions() added to MgResourceService, which serves the same purpose as EnumerateParentMapDefinitions() only for tile sets.
 - Implement handlers for proxy method calls on new tile service methods.
 - Add new mapagent test forms.
........
Fix assorted invalid stream header errors as a result of misunderstanding how data goes across the wire from the web tier to the server tier and some bad copypasta.
........
Add support for XYZ tile provider in the Tile Set Definition. In the process of adding XYZ tile provider support it has been discovered that some of the schema elements in the current TileSetDefinition schema do not make any sense in an XYZ context.

As a result, such elements have been repurposed as provider-specific parameters. However this has resulted in a little bit of ugliness:

 * MgMap's coordinate system and finite scale extraction logic is now hardcoded against these 2 tile providers as the CoordinateSystem and FiniteDisplayScale elements no longer exist. MdfModel test has been updated to match the new TileSetDefinition structure.
 * MgMap::Create() now has a strict parameter which is true when invoked through the published API and false otherwise. When strict is true, an MgUnsupportedTileProviderException is thrown when attempting to create a MgMap from a tile set or a map definition that links to a tile set that uses a non-default tile provider. For tile rendering, it will invoke MgMap::Create() with strict = false

We can live with a bit of hardcoding for now. If we do want to formally have an externally pluggable tile provider system in the vein of FDO in the future, that's when we'll need to probably introduce some new Tile Service APIs to return this Coordinate System and finite scale information and delegate this logic to the specific tile provider instead of hard-coding this logic into MgMap which we currently do.

Finally, a new OpenLayers XYZ sample is included that demonstrates the XYZ layer support through this new tile provider.
........
Add missing XYZ tile provider source from previous submission and use a cleaner directory structure for XYZ tiles, which is <basepath>/<group>/<z>/<x>/<y>.<format>
........
Move our string constants up to the MapGuideCommon level so it can be referenced in both MgMap and server tile service.
........
Add unit tests to cover recent changes.
........
- Add test for exercising multithreaded XYZ GetTile
- Fix tabs in PostBuild.mak 
........
Update AJAX viewer files to support Map Definitions linked to Tile Sets.
........
Makefile.am updates
........
Fix incorrect display names and description for XYZ tile provider.
........
Comment out debugging
........
Fix background color not being set when creating a MgMap from a Map Definition linked to a tile set.
........
Clean up documentation of the new APIs.
........
Add XML schema for TileProviderList.
........
Add example tilesets to Sheboygan sample data set
........
This submission includes the following changes:
 - Remove redundant set of operation codes for the Mapping Service. We now use MgMappingServiceOpId instead of the inline enum in MgMappingService
 - Move GetTileSetDefinition from MgLayerGroup to MgMap. The map will at most only ever link to one tile set, so it should make more sense to have this method in the MgMap.
 - Update tile service unit tests to verify checked values are the same after saving the MgMap and re-opening the MgMap.
 - Update CreateRuntimeMap/DescribeRuntimeMap:
    - Add new v3.0 RuntimeMap schema
    - Add new overload that takes a schema version, allowing v2.6 and v3.0 responses to be generated.
    - For the v3.0 response, if the MgMap was created from a Tile Set Definition or from a Map Definition linked to a tile set, the tile set definition id and tile size is included in the response.
........
Ensure that groups of type MgLayerGroupType::BaseMapFromTileSet are not omitted from a CREATERUNTIMEMAP/DESCRIBERUNTIMEMAP response.
........
Fix sample data. The sample tile set had some bad extents and coordinate systems. Also the tile sets weren't included in the package manifest so they weren't loaded.
........
Update AJAX viewers in light of the moving of GetTileSetDefinition() from MgLayerGroup to MgMap
........
Update OL2 samples
........




Property changes on: trunk/MgDev
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318
/sandbox/jng/convenience_apis:8263
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163
   + /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318
/sandbox/jng/convenience_apis:8263
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/tiling:8174-8208
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163

Copied: trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.cpp (from rev 8208, sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnknownTileProviderException.cpp)
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,40 @@
+//
+//  Copyright (C) 2004-2014 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 "MapGuideCommon.h"
+
+IMPLEMENT_EXCEPTION_DEFAULTS(MgUnknownTileProviderException, MgApplicationException)
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Construct a MgUnknownTileProviderException object.
+///
+MgUnknownTileProviderException::MgUnknownTileProviderException(CREFSTRING methodName,
+    INT32 lineNumber, CREFSTRING fileName, MgStringCollection* whatArguments,
+    CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw() :
+    MgApplicationException(methodName, lineNumber, fileName,
+        whatArguments, whyMessageId, whyArguments)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Destruct the object.
+///
+MgUnknownTileProviderException::~MgUnknownTileProviderException() throw()
+{
+}

Copied: trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.h (from rev 8208, sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnknownTileProviderException.h)
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.h	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnknownTileProviderException.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,69 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_UNKNOWN_TILE_PROVIDER_EXCEPTION_H_
+#define MG_UNKNOWN_TILE_PROVIDER_EXCEPTION_H_
+
+/// \ingroup Exceptions_Module
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Thrown when a tile set definition contains an unknown tile provider
+///
+class MG_MAPGUIDE_API MgUnknownTileProviderException : public MgApplicationException
+{
+    DECLARE_CLASSNAME(MgUnknownTileProviderException)
+
+EXTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct a MgUnknownTileProviderException object.
+    ///
+    /// \param methodName
+    /// Name of the method where the exception occurred.
+    /// \param lineNumber
+    /// Line number where the exception occurred.
+    /// \param fileName
+    /// File name where the exception occurred.
+    /// \param whatArguments
+    /// Collection of arguments used to format the message that describes what the exception is.
+    /// \param whyMessageId
+    /// ID of the message that describes why the exception occurs.
+    /// \param whyArguments
+    /// Collection of arguments used to format the message that describes why the exception occurs.
+    ///
+    MgUnknownTileProviderException(CREFSTRING methodName, INT32 lineNumber,
+        CREFSTRING fileName, MgStringCollection* whatArguments,
+        CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destructor for a MgUnknownTileProviderException object.
+    ///
+    virtual ~MgUnknownTileProviderException() throw();
+
+INTERNAL_API:
+
+    DECLARE_EXCEPTION_DEFAULTS(MgUnknownTileProviderException)
+
+CLASS_ID:
+
+    static const INT32 m_cls_id = MapGuide_Exception_MgUnknownTileProviderException;
+};
+
+#endif

Copied: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp (from rev 8208, sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp)
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,40 @@
+//
+//  Copyright (C) 2004-2014 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 "MapGuideCommon.h"
+
+IMPLEMENT_EXCEPTION_DEFAULTS(MgUnsupportedTileProviderException, MgApplicationException)
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Construct a MgUnsupportedTileProviderException object.
+///
+MgUnsupportedTileProviderException::MgUnsupportedTileProviderException(CREFSTRING methodName,
+    INT32 lineNumber, CREFSTRING fileName, MgStringCollection* whatArguments,
+    CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw() :
+    MgApplicationException(methodName, lineNumber, fileName,
+        whatArguments, whyMessageId, whyArguments)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Destruct the object.
+///
+MgUnsupportedTileProviderException::~MgUnsupportedTileProviderException() throw()
+{
+}

Copied: trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h (from rev 8208, sandbox/jng/tiling/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h)
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h	                        (rev 0)
+++ trunk/MgDev/Common/MapGuideCommon/Exception/UnsupportedTileProviderException.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,70 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_UNSUPPORTED_TILE_PROVIDER_EXCEPTION_H_
+#define MG_UNSUPPORTED_TILE_PROVIDER_EXCEPTION_H_
+
+/// \ingroup Exceptions_Module
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Thrown when a new MgMap is created from a Map Definition that references a Tile Set Definition
+/// that uses an unsupported tile provider
+///
+class MG_MAPGUIDE_API MgUnsupportedTileProviderException : public MgApplicationException
+{
+    DECLARE_CLASSNAME(MgUnsupportedTileProviderException)
+
+EXTERNAL_API:
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Construct a MgUnsupportedTileProviderException object.
+    ///
+    /// \param methodName
+    /// Name of the method where the exception occurred.
+    /// \param lineNumber
+    /// Line number where the exception occurred.
+    /// \param fileName
+    /// File name where the exception occurred.
+    /// \param whatArguments
+    /// Collection of arguments used to format the message that describes what the exception is.
+    /// \param whyMessageId
+    /// ID of the message that describes why the exception occurs.
+    /// \param whyArguments
+    /// Collection of arguments used to format the message that describes why the exception occurs.
+    ///
+    MgUnsupportedTileProviderException(CREFSTRING methodName, INT32 lineNumber,
+        CREFSTRING fileName, MgStringCollection* whatArguments,
+        CREFSTRING whyMessageId, MgStringCollection* whyArguments) throw();
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Destructor for a MgUnsupportedTileProviderException object.
+    ///
+    virtual ~MgUnsupportedTileProviderException() throw();
+
+INTERNAL_API:
+
+    DECLARE_EXCEPTION_DEFAULTS(MgUnsupportedTileProviderException)
+
+CLASS_ID:
+
+    static const INT32 m_cls_id = MapGuide_Exception_MgUnsupportedTileProviderException;
+};
+
+#endif

Modified: trunk/MgDev/Common/MapGuideCommon/Makefile.am
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -65,7 +65,9 @@
   Exception/SessionNotFoundException.cpp \
   Exception/StylizeLayerFailedException.cpp \
   Exception/UnauthorizedAccessException.cpp \
+  Exception/UnknownTileProviderException.cpp \
   Exception/UnsupportedProviderThreadModelException.cpp \
+  Exception/UnsupportedTileProviderException.cpp \
   Exception/UriFormatException.cpp \
   MapLayer/Layer.cpp \
   MapLayer/Map.cpp \
@@ -191,6 +193,8 @@
   Exception/SessionNotFoundException.h \
   Exception/StylizeLayerFailedException.h \
   Exception/UnauthorizedAccessException.h \
+  Exception/UnknownTileProviderException.h \
+  Exception/UnsupportedTileProviderException.h \
   Exception/UnsupportedProviderThreadModelException.h \
   Exception/UriFormatException.h \
   MapLayer/Layer.h \

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -116,6 +116,8 @@
 #include "Exception/SessionNotFoundException.h"
 #include "Exception/StylizeLayerFailedException.h"
 #include "Exception/UnauthorizedAccessException.h"
+#include "Exception/UnknownTileProviderException.h"
+#include "Exception/UnsupportedTileProviderException.h"
 #include "Exception/UnsupportedProviderThreadModelException.h"
 #include "Exception/UriFormatException.h"
 

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -198,6 +198,18 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="Exception\UnknownTileProviderException.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="Exception\UnsupportedTileProviderException.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="MapLayer\Layer.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -939,6 +951,8 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="Exception\UnknownTileProviderException.h" />
+    <ClInclude Include="Exception\UnsupportedTileProviderException.h" />
     <ClInclude Include="MapLayer\Layer.h" />
     <ClInclude Include="MapLayer\Map.h" />
     <ClInclude Include="MapLayer\Selection.h" />

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommon.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -394,6 +394,10 @@
     <ClCompile Include="Util\TimerUtil.cpp">
       <Filter>Util</Filter>
     </ClCompile>
+    <ClCompile Include="Exception\UnknownTileProviderException.cpp">
+      <Filter>Exception</Filter>
+    </ClCompile>
+    <ClCompile Include="Exception\UnsupportedTileProviderException.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="MapLayer\Layer.h">
@@ -769,6 +773,10 @@
     <ClInclude Include="Util\TimerUtil.h">
       <Filter>Util</Filter>
     </ClInclude>
+    <ClInclude Include="Exception\UnknownTileProviderException.h">
+      <Filter>Exception</Filter>
+    </ClInclude>
+    <ClInclude Include="Exception\UnsupportedTileProviderException.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MapGuideCommon.rc" />

Modified: trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapGuideCommonBuild.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -72,6 +72,8 @@
 #include  "Exception/SessionNotFoundException.cpp"
 #include  "Exception/StylizeLayerFailedException.cpp"
 #include  "Exception/UnauthorizedAccessException.cpp"
+#include  "Exception/UnknownTileProviderException.cpp"
+#include  "Exception/UnsupportedTileProviderException.cpp"
 #include  "Exception/UnsupportedProviderThreadModelException.cpp"
 #include  "Exception/UriFormatException.cpp"
 #include  "MapLayer/Layer.cpp"

Modified: trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -36,7 +36,8 @@
     m_inSave(false),
     m_unpackedLayersGroups(false),
     m_colorPalette(NULL),        // lazy instantiation
-    m_watermarkUsage(Viewer)
+    m_watermarkUsage(Viewer),
+    m_tileSetId((MgResourceIdentifier*)NULL)
 {
 }
 
@@ -49,7 +50,8 @@
     m_inSave(false),
     m_unpackedLayersGroups(false),
     m_colorPalette(NULL),        // lazy instantiation
-    m_watermarkUsage(Viewer)
+    m_watermarkUsage(Viewer),
+    m_tileSetId((MgResourceIdentifier*)NULL)
 {
     if (NULL == siteConnection)
     {
@@ -111,10 +113,38 @@
 // Initializes a new Map object.
 // This method is used for Mg Viewers or for offline map production.
 //
-void MgMap::Create(MgResourceService* resourceService, MgResourceIdentifier* mapDefinition, CREFSTRING mapName)
+void MgMap::Create(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName)
 {
+    Create(resourceService, resource, mapName, true);
+}
+
+void MgMap::Create(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName, bool strict)
+{
     MG_TRY()
 
+    if (resource->GetResourceType() == MgResourceType::MapDefinition)
+        CreateFromMapDefinition(resourceService, resource, mapName);
+    else if (resource->GetResourceType() == MgResourceType::TileSetDefinition)
+        CreateFromTileSet(resourceService, resource, mapName, strict);
+    else
+        throw new MgInvalidResourceTypeException(L"MgMap.Create", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    MG_CATCH_AND_THROW(L"MgMap.Create")
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Initializes a new MgMap object given a map definition and a name for the map.
+/// This method is used for MapGuide Viewers or for offline map production.
+///
+void MgMap::Create(MgResourceIdentifier* mapDefinition, CREFSTRING mapName)
+{
+    Create(NULL, mapDefinition, mapName);
+}
+
+void MgMap::CreateFromMapDefinition(MgResourceService* resourceService, MgResourceIdentifier* mapDefinition, CREFSTRING mapName)
+{
+    MG_TRY()
+
     InitializeResourceService(resourceService);
     m_trackChangesDisabled = true;
 
@@ -146,23 +176,83 @@
     }
 
     // build the runtime map object from the parsed definition
+    std::auto_ptr<MdfModel::TileSetDefinition> tdef;
     std::auto_ptr<MdfModel::MapDefinition> mdef(parser.DetachMapDefinition());
     assert(mdef.get() != NULL);
 
     MgGeometryFactory gf;
+    Ptr<MgResourceIdentifier> tileSetDefId;
 
-    const Box2D& extent = mdef->GetExtents();
-    Ptr<MgCoordinate> lowerLeft = gf.CreateCoordinateXY(extent.GetMinX(), extent.GetMinY());
-    Ptr<MgCoordinate> upperRight = gf.CreateCoordinateXY(extent.GetMaxX(), extent.GetMaxY());
-    m_mapExtent = new MgEnvelope(lowerLeft, upperRight);
-    m_dataExtent = new MgEnvelope(lowerLeft, upperRight);
-    m_backColor = mdef->GetBackgroundColor();
+    //If this Map Definition links to a Tile Set Definition, its coordinate system takes precedence
+    if (mdef->GetTileSourceType() == MapDefinition::TileSetDefinition)
+    {
+        // get the tile set definition from the resource repository
+        tileSetDefId = new MgResourceIdentifier(mdef->GetTileSetSource()->GetResourceId());
+        Ptr<MgByteReader> tdContent = m_resourceService->GetResourceContent(tileSetDefId);
+        Ptr<MgByteSink> tdSink = new MgByteSink(tdContent);
+        Ptr<MgByte> tdBytes = tdSink->ToBuffer();
 
-    Ptr<MgCoordinate> coordCenter = gf.CreateCoordinateXY(extent.GetMinX() + (extent.GetMaxX() - extent.GetMinX()) / 2,
-                                                          extent.GetMinY() + (extent.GetMaxY() - extent.GetMinY()) / 2);
-    m_center = gf.CreatePoint(coordCenter);
-    m_srs = mdef->GetCoordinateSystem();
+        // parse the tile set definition
+        MdfParser::SAX2Parser parser;
+        parser.ParseString((const char*)tdBytes->Bytes(), tdBytes->GetLength());
 
+        if (!parser.GetSucceeded())
+        {
+            STRING errorMsg = parser.GetErrorMessage();
+            MgStringCollection arguments;
+            arguments.Add(errorMsg);
+            throw new MgInvalidMapDefinitionException(L"MgMap.Create", __LINE__, __WFILE__, &arguments, L"", NULL);
+        }
+
+        tdef.reset(parser.DetachTileSetDefinition());
+        assert(tdef.get() != NULL);
+
+        m_srs = GetCoordinateSystemFromTileSet(tdef.get(), true);
+
+        //If tile CS is not the same as map def CS, then the bounds of the map def need to be transformed
+        if (m_srs != mdef->GetCoordinateSystem())
+        {
+            Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
+            Ptr<MgCoordinateSystem> mapCs = csFactory->Create(mdef->GetCoordinateSystem());
+            Ptr<MgCoordinateSystem> tileCs = csFactory->Create(m_srs);
+            Ptr<MgCoordinateSystemTransform> trans = csFactory->GetTransform(mapCs, tileCs);
+
+            const Box2D& extent = mdef->GetExtents();
+            Ptr<MgCoordinate> lowerLeft = gf.CreateCoordinateXY(extent.GetMinX(), extent.GetMinY());
+            Ptr<MgCoordinate> upperRight = gf.CreateCoordinateXY(extent.GetMaxX(), extent.GetMaxY());
+            Ptr<MgEnvelope> mapExtent = new MgEnvelope(lowerLeft, upperRight);
+            Ptr<MgEnvelope> dataExtent = new MgEnvelope(lowerLeft, upperRight);
+
+            m_mapExtent = mapExtent->Transform(trans);
+            m_dataExtent = mapExtent->Transform(trans);
+
+            Ptr<MgCoordinate> ll = mapExtent->GetLowerLeftCoordinate();
+            Ptr<MgCoordinate> ur = mapExtent->GetUpperRightCoordinate();
+            
+            Ptr<MgCoordinate> coordCenter = gf.CreateCoordinateXY(ll->GetX() + (ur->GetX() - ll->GetX()) / 2,
+                                                                  ll->GetY() + (ur->GetY() - ll->GetY()) / 2);
+
+            m_center = gf.CreatePoint(coordCenter);
+        }
+        m_backColor = mdef->GetBackgroundColor();
+        m_tileSetId = SAFE_ADDREF((MgResourceIdentifier*)tileSetDefId);
+    }
+    else
+    {
+        m_srs = mdef->GetCoordinateSystem();
+
+        const Box2D& extent = mdef->GetExtents();
+        Ptr<MgCoordinate> lowerLeft = gf.CreateCoordinateXY(extent.GetMinX(), extent.GetMinY());
+        Ptr<MgCoordinate> upperRight = gf.CreateCoordinateXY(extent.GetMaxX(), extent.GetMaxY());
+        m_mapExtent = new MgEnvelope(lowerLeft, upperRight);
+        m_dataExtent = new MgEnvelope(lowerLeft, upperRight);
+        m_backColor = mdef->GetBackgroundColor();
+
+        Ptr<MgCoordinate> coordCenter = gf.CreateCoordinateXY(extent.GetMinX() + (extent.GetMaxX() - extent.GetMinX()) / 2,
+                                                              extent.GetMinY() + (extent.GetMaxY() - extent.GetMinY()) / 2);
+        m_center = gf.CreatePoint(coordCenter);
+    }
+
     //Calculate the meter per unit for the given coordinate system
     m_metersPerUnit = 1.0; // assume a default value
     if (m_srs.length() > 0)
@@ -187,8 +277,9 @@
 
     map<STRING, MgLayerGroup*>::const_iterator itKg;
 
+    //Process dynamic layer groups
     MapLayerGroupCollection* groups = mdef->GetLayerGroups();
-    if(groups)
+    if (groups)
     {
         for(int i = 0; i < groups->GetCount(); i++)
         {
@@ -227,7 +318,7 @@
     }
 
     //resolve group links if required
-    if(unresolvedGroupLinks.size() > 0)
+    if (unresolvedGroupLinks.size() > 0)
     {
         map<MgLayerGroup*, STRING>::const_iterator itUnres;
         for(itUnres = unresolvedGroupLinks.begin(); itUnres != unresolvedGroupLinks.end(); ++itUnres)
@@ -255,15 +346,19 @@
     //Get all the layers (normal layer or base layer) and get the contents of them in a single request.
     Ptr<MgStringCollection> layerIds = new MgStringCollection();
     MapLayerCollection* normalLayers = mdef->GetLayers();
-    if(normalLayers)
+    if (normalLayers)
     {
         for(int i = 0; i < normalLayers->GetCount(); i ++)
         {
             layerIds->Add(normalLayers->GetAt(i)->GetLayerResourceID());
         }
     }
-    BaseMapLayerGroupCollection* baseLayerGroups = mdef->GetBaseMapLayerGroups();
-    if(baseLayerGroups)
+    BaseMapLayerGroupCollection* baseLayerGroups = NULL;
+    if (NULL != tdef.get())
+        baseLayerGroups = tdef->GetBaseMapLayerGroups();
+    else
+        baseLayerGroups = mdef->GetBaseMapLayerGroups();
+    if (baseLayerGroups)
     {
         for(int i = 0; i < baseLayerGroups->GetCount(); i ++)
         {
@@ -279,7 +374,7 @@
         }
     }
     std::map<STRING, STRING> layerContentPair;
-    if(layerIds->GetCount() != 0)
+    if (layerIds->GetCount() != 0)
     {
         Ptr<MgStringCollection> layerContents = m_resourceService->GetResourceContents(layerIds, NULL);
         for(int i = 0; i < layerIds->GetCount(); i ++)
@@ -291,7 +386,7 @@
     //build the runtime layers and attach them to their groups
     SCALERANGES scaleRanges;
     MapLayerCollection* layers = mdef->GetLayers();
-    if(layers)
+    if (layers)
     {
         for(int i = 0; i < layers->GetCount(); i++, displayOrder += LAYER_ZORDER_INCR)
         {
@@ -313,7 +408,7 @@
             m_layers->Add(rtLayer);
 
             STRING groupName = layer->GetGroup();
-            if(groupName.length())
+            if (groupName.length())
             {
                 //attach the layer to its group
                 itKg = knownGroups.find(groupName);
@@ -329,8 +424,12 @@
     knownGroups.clear();
 
     // BaseMapLayerGroups and BaseMapLayers come at the end
-    BaseMapLayerGroupCollection* baseGroups = mdef->GetBaseMapLayerGroups();
-    if(baseGroups)
+    BaseMapLayerGroupCollection* baseGroups = NULL;
+    if (NULL != tdef.get())
+        baseGroups = tdef->GetBaseMapLayerGroups();
+    else
+        baseGroups = mdef->GetBaseMapLayerGroups();
+    if (baseGroups)
     {
         for(int i = 0; i < baseGroups->GetCount(); i++)
         {
@@ -339,8 +438,11 @@
             //create a runtime group from this group and add it to the group collection
             STRING groupName = baseGroup->GetName();
             Ptr<MgLayerGroup> rtGroup = new MgLayerGroup(groupName);
+            if (tdef.get() != NULL)
+                rtGroup->SetLayerGroupType(MgLayerGroupType::BaseMapFromTileSet);
+            else
+                rtGroup->SetLayerGroupType(MgLayerGroupType::BaseMap);
             rtGroup->SetVisible(baseGroup->IsVisible());
-            rtGroup->SetLayerGroupType(MgLayerGroupType::BaseMap);
             rtGroup->SetDisplayInLegend(baseGroup->IsShowInLegend());
             rtGroup->SetExpandInLegend(baseGroup->IsExpandInLegend());
             rtGroup->SetLegendLabel(baseGroup->GetLegendLabel());
@@ -402,13 +504,15 @@
 
     // build the sorted list of finite display scales
     SORTEDSCALES sortedScales;
-    DisplayScaleCollection* displayScales = mdef->GetFiniteDisplayScales();
-    if(displayScales)
+    MdfModel::DisplayScaleCollection* displayScales = NULL;
+    MdfModel::DisplayScaleCollection dispScalesFromTDef;
+    if (NULL != tdef.get())
     {
-        for(int i = 0; i < displayScales->GetCount(); i++)
+        FINITESCALES fScales;
+        GetFiniteDisplayScalesFromTileSet(tdef.get(), fScales, true);
+        for (FINITESCALES::iterator it = fScales.begin(); it != fScales.end(); it++)
         {
-            DisplayScale* displayScale = displayScales->GetAt(i);
-            double scale = displayScale->GetValue();
+            double scale = *it;
 
             // skip non-positive scales
             if (scale <= 0.0)
@@ -423,7 +527,31 @@
             sortedScales.insert(SORTEDSCALES::value_type(scale, scale));
         }
     }
+    else
+    {
+        displayScales = mdef->GetFiniteDisplayScales();
+        if (displayScales)
+        {
+            for(int i = 0; i < displayScales->GetCount(); i++)
+            {
+                DisplayScale* displayScale = displayScales->GetAt(i);
+                double scale = displayScale->GetValue();
 
+                // skip non-positive scales
+                if (scale <= 0.0)
+                    continue;
+
+                // skip duplicate scales
+                SORTEDSCALES::iterator iter = sortedScales.find(scale);
+                if (iter != sortedScales.end())
+                    continue;
+
+                // insert the scale (automatically sorted in ascending order)
+                sortedScales.insert(SORTEDSCALES::value_type(scale, scale));
+            }
+        }
+    }
+
     // load the sorted scales into the vector
     for (SORTEDSCALES::iterator sIter = sortedScales.begin(); sIter != sortedScales.end(); ++sIter)
         m_finiteDisplayScales.push_back(sIter->second);
@@ -433,18 +561,286 @@
     // there's nothing to unpack anymore in this case
     m_unpackedLayersGroups = true;
 
-    MG_CATCH_AND_THROW(L"MgMap.Create")
+    MG_CATCH_AND_THROW(L"MgMap.CreateFromMapDefinition")
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// Initializes a new MgMap object given a map definition and a name for the map.
-/// This method is used for MapGuide Viewers or for offline map production.
-///
-void MgMap::Create(MgResourceIdentifier* mapDefinition, CREFSTRING mapName)
+void MgMap::CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* tileSetDefId, CREFSTRING mapName, bool strict)
 {
-    Create(NULL, mapDefinition, mapName);
+    MG_TRY()
+
+    InitializeResourceService(resourceService);
+    m_trackChangesDisabled = true;
+
+    m_mapDefinitionId = NULL;
+    m_name = mapName;
+    m_tileSetId = SAFE_ADDREF(tileSetDefId);
+
+    // reset the colorlist from our layers (std::list dtor clears the list)
+    delete m_colorPalette;
+    m_colorPalette = NULL;  // initialize to empty (lazy as its only used for 8bit color)
+
+    // generate a unique id for this map
+    MgUtil::GenerateUuid(m_objectId);
+
+    // get the map definition from the resource repository
+    Ptr<MgByteReader> content = m_resourceService->GetResourceContent(tileSetDefId);
+    Ptr<MgByteSink> sink = new MgByteSink(content);
+    Ptr<MgByte> bytes = sink->ToBuffer();
+
+    // parse the map definition
+    MdfParser::SAX2Parser parser;
+    parser.ParseString((const char*)bytes->Bytes(), bytes->GetLength());
+
+    if (!parser.GetSucceeded())
+    {
+        STRING errorMsg = parser.GetErrorMessage();
+        MgStringCollection arguments;
+        arguments.Add(errorMsg);
+        throw new MgInvalidMapDefinitionException(L"MgMap.Create", __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+
+    // build the runtime map object from the parsed definition
+    std::auto_ptr<MdfModel::TileSetDefinition> tdef(parser.DetachTileSetDefinition());
+    assert(tdef.get() != NULL);
+
+    MgGeometryFactory gf;
+
+    const Box2D& extent = tdef->GetExtents();
+    Ptr<MgCoordinate> lowerLeft = gf.CreateCoordinateXY(extent.GetMinX(), extent.GetMinY());
+    Ptr<MgCoordinate> upperRight = gf.CreateCoordinateXY(extent.GetMaxX(), extent.GetMaxY());
+    m_mapExtent = new MgEnvelope(lowerLeft, upperRight);
+    m_dataExtent = new MgEnvelope(lowerLeft, upperRight);
+    m_backColor = L"FFFFFFFF";
+
+    Ptr<MgCoordinate> coordCenter = gf.CreateCoordinateXY(extent.GetMinX() + (extent.GetMaxX() - extent.GetMinX()) / 2,
+                                                          extent.GetMinY() + (extent.GetMaxY() - extent.GetMinY()) / 2);
+    m_center = gf.CreatePoint(coordCenter);
+    m_srs = GetCoordinateSystemFromTileSet(tdef.get(), strict);
+
+    //Calculate the meter per unit for the given coordinate system
+    m_metersPerUnit = 1.0; // assume a default value
+    if (m_srs.length() > 0)
+    {
+        Ptr<MgCoordinateSystemFactory> coordFactory = new MgCoordinateSystemFactory();
+        Ptr<MgCoordinateSystem> coordSys = coordFactory->Create(m_srs);
+        if (coordSys != NULL)
+        {
+            m_metersPerUnit = coordSys->ConvertCoordinateSystemUnitsToMeters(1.0);
+        }
+    }
+
+    // clear the collections
+    m_layers->Clear();
+    m_groups->Clear();
+    m_changeLists->Clear();
+    m_finiteDisplayScales.clear();
+
+    double displayOrder = LAYER_ZORDER_TOP;
+
+    //Get all the layersand get the contents of them in a single request.
+    Ptr<MgStringCollection> layerIds = new MgStringCollection();
+    BaseMapLayerGroupCollection* baseLayerGroups = tdef->GetBaseMapLayerGroups();
+    if (baseLayerGroups)
+    {
+        for(int i = 0; i < baseLayerGroups->GetCount(); i ++)
+        {
+            BaseMapLayerGroup* baseGroup = (BaseMapLayerGroup*)baseLayerGroups->GetAt(i);
+            BaseMapLayerCollection* baseLayers = baseGroup->GetLayers();
+            if(baseLayers)
+            {
+                for(int j = 0; j < baseLayers->GetCount(); j ++)
+                {
+                    layerIds->Add(baseLayers->GetAt(j)->GetLayerResourceID());
+                }
+            }
+        }
+    }
+    std::map<STRING, STRING> layerContentPair;
+    if (layerIds->GetCount() != 0)
+    {
+        Ptr<MgStringCollection> layerContents = m_resourceService->GetResourceContents(layerIds, NULL);
+        for(int i = 0; i < layerIds->GetCount(); i ++)
+        {
+            layerContentPair.insert(std::pair<STRING, STRING>(layerIds->GetItem(i), layerContents->GetItem(i)));
+        }
+    }
+
+    // BaseMapLayerGroups and BaseMapLayers come at the end
+    BaseMapLayerGroupCollection* baseGroups = tdef->GetBaseMapLayerGroups();
+    if (baseGroups)
+    {
+        for(int i = 0; i < baseGroups->GetCount(); i++)
+        {
+            BaseMapLayerGroup* baseGroup = (BaseMapLayerGroup*)baseGroups->GetAt(i);
+
+            //create a runtime group from this group and add it to the group collection
+            STRING groupName = baseGroup->GetName();
+            Ptr<MgLayerGroup> rtGroup;
+            rtGroup = new MgLayerGroup(groupName);
+            rtGroup->SetVisible(baseGroup->IsVisible());
+            rtGroup->SetLayerGroupType(MgLayerGroupType::BaseMapFromTileSet);
+            rtGroup->SetDisplayInLegend(baseGroup->IsShowInLegend());
+            rtGroup->SetExpandInLegend(baseGroup->IsExpandInLegend());
+            rtGroup->SetLegendLabel(baseGroup->GetLegendLabel());
+
+            // NOTE: base groups do not have a parent group
+
+            m_groups->Add(rtGroup);
+
+            // process the base map layers for this group
+            BaseMapLayerCollection* baseLayers = baseGroup->GetLayers();
+            if (baseLayers)
+            {
+                for(int j = 0; j < baseLayers->GetCount(); j++, displayOrder += LAYER_ZORDER_INCR)
+                {
+                    BaseMapLayer* baseLayer = (BaseMapLayer*)baseLayers->GetAt(j);
+
+                    // base layers should always be visible
+                    assert(baseLayer->IsVisible());
+                    if (baseLayer->IsVisible())
+                    {
+                        //create a runtime layer from this base layer and add it to the layer collection
+                        Ptr<MgResourceIdentifier> layerDefId = new MgResourceIdentifier(baseLayer->GetLayerResourceID());
+                        Ptr<MgLayerBase> rtLayer = new MgLayer(layerDefId, m_resourceService, true, false);
+                        rtLayer->SetLayerResourceContent(layerContentPair[layerDefId->ToString()]);
+                        rtLayer->SetName(baseLayer->GetName());
+                        rtLayer->SetVisible(true);
+                        rtLayer->SetLayerType(MgLayerType::BaseMap);
+                        rtLayer->SetDisplayInLegend(baseLayer->IsShowInLegend());
+                        rtLayer->SetExpandInLegend(baseLayer->IsExpandInLegend());
+                        rtLayer->SetLegendLabel(baseLayer->GetLegendLabel());
+                        rtLayer->SetSelectable(baseLayer->IsSelectable());
+                        rtLayer->SetDisplayOrder(displayOrder);
+
+                        m_layers->Add(rtLayer);
+
+                        // attach the layer to its group
+                        rtLayer->SetGroup(rtGroup);
+                    }
+                }
+            }
+        }
+    }
+
+    // Now that we've added all the layers (dynamic and base map) to the m_layers collection,
+    // bulk load the identity properties for all layers
+    Ptr<MgSiteConnection> siteConn;
+    if (m_siteConnection.p != NULL)
+    {
+        siteConn = SAFE_ADDREF((MgSiteConnection*)m_siteConnection);
+    }
+    else
+    {
+        Ptr<MgUserInformation> userInfo = m_resourceService->GetUserInfo();
+        siteConn = new MgSiteConnection();
+        siteConn->Open(userInfo);
+    }
+    Ptr<MgFeatureService> featureService = dynamic_cast<MgFeatureService*>(siteConn->CreateService(MgServiceType::FeatureService));
+    BulkLoadIdentityProperties(featureService);
+
+    // build the sorted list of finite display scales
+    SORTEDSCALES sortedScales;
+    FINITESCALES displayScales;
+    GetFiniteDisplayScalesFromTileSet(tdef.get(), displayScales, strict);
+    if (displayScales.size() > 0)
+    {
+        for (FINITESCALES::iterator it = displayScales.begin(); it != displayScales.end(); it++)
+        {
+            double scale = *it;
+
+            // skip non-positive scales
+            if (scale <= 0.0)
+                continue;
+
+            // skip duplicate scales
+            SORTEDSCALES::iterator iter = sortedScales.find(scale);
+            if (iter != sortedScales.end())
+                continue;
+
+            // insert the scale (automatically sorted in ascending order)
+            sortedScales.insert(SORTEDSCALES::value_type(scale, scale));
+        }
+    }
+
+    // load the sorted scales into the vector
+    for (SORTEDSCALES::iterator sIter = sortedScales.begin(); sIter != sortedScales.end(); ++sIter)
+        m_finiteDisplayScales.push_back(sIter->second);
+
+    m_trackChangesDisabled = false;
+
+    // there's nothing to unpack anymore in this case
+    m_unpackedLayersGroups = true;
+
+    MG_CATCH_AND_THROW(L"MgMap.CreateFromTileSet")
 }
 
+STRING MgMap::GetCoordinateSystemFromTileSet(MdfModel::TileSetDefinition* tileset, bool strict)
+{
+    //Yes, this is hard-coded against specific providers. Revisit if we do want
+    //to FDO-ize this tile provider concept.
+
+    MdfModel::TileStoreParameters* storeParams = tileset->GetTileStoreParameters();
+    if (storeParams->GetTileProvider() == MG_TILE_PROVIDER_DEFAULT)
+    {
+        MdfModel::NameStringPairCollection* parameters = storeParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* nsp = parameters->GetAt(i);
+            if (nsp->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_COORDINATESYSTEM)
+            {
+                return nsp->GetValue();
+            }
+        }
+    }
+    else if (storeParams->GetTileProvider() == MG_TILE_PROVIDER_XYZ)
+    {
+        //XYZ is always LL84
+        Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
+        return csFactory->ConvertCoordinateSystemCodeToWkt(L"LL84"); //NOXLATE
+    }
+    if (strict)
+    {
+        MgStringCollection args;
+        args.Add(storeParams->GetTileProvider());
+        throw new MgUnsupportedTileProviderException(L"MgMap.GetCoordinateSystemFromTileSet", __LINE__, __WFILE__, &args, L"", NULL);
+    }
+    else
+    {
+        return L"";
+    }
+}
+
+void MgMap::GetFiniteDisplayScalesFromTileSet(MdfModel::TileSetDefinition* tileset, FINITESCALES& scales, bool strict)
+{
+    //Yes, this is hard-coded against specific providers. Revisit if we do want
+    //to FDO-ize this tile provider concept.
+
+    MdfModel::TileStoreParameters* storeParams = tileset->GetTileStoreParameters();
+    if (storeParams->GetTileProvider() == MG_TILE_PROVIDER_DEFAULT) //NOXLATE
+    {
+        MdfModel::NameStringPairCollection* parameters = storeParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* nsp = parameters->GetAt(i);
+            if (nsp->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST) //NOXLATE
+            {
+                Ptr<MgStringCollection> values = MgStringCollection::ParseCollection(nsp->GetValue(), L","); //NOXLATE
+                for (INT32 i = 0; i < values->GetCount(); i++)
+                {
+                    double val = MgUtil::StringToDouble(values->GetItem(i));
+                    scales.push_back(val);
+                }
+            }
+        }
+    }
+    else if (strict)
+    {
+        MgStringCollection args;
+        args.Add(storeParams->GetTileProvider());
+        throw new MgUnsupportedTileProviderException(L"MgMap.GetFiniteDisplayScalesFromTileSet", __LINE__, __WFILE__, &args, L"", NULL);
+    }
+}
+
 //////////////////////////////////////////////////////////////
 // Call down to base class implementation.  Ptr<> seems to be
 // messing this up.  Weird
@@ -894,6 +1290,9 @@
     //watermark usage
     stream->WriteInt32(m_watermarkUsage);
 
+    //tile set definition
+    stream->WriteObject(m_tileSetId);
+
     // Serialize Layers and Groups as a blob.
     if (m_inSave)
     {
@@ -1015,6 +1414,9 @@
     //watermark usage
     streamReader->GetInt32(m_watermarkUsage);
 
+    //tile set definition
+    m_tileSetId = (MgResourceIdentifier*)stream->GetObject();
+
     //blob for layers and groups
     INT32 nBytes = 0;
     streamReader->GetInt32(nBytes);
@@ -1170,3 +1572,11 @@
 {
     m_watermarkUsage = watermarkUsage;
 }
+
+//////////////////////////////////////////////////////////////////
+// Returns the resource id of the Tile Set Definition that this group originates from.
+//
+MgResourceIdentifier* MgMap::GetTileSetDefinition()
+{
+    return SAFE_ADDREF((MgResourceIdentifier*)m_tileSetId);
+}
\ No newline at end of file

Modified: trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/MapLayer/Map.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -29,6 +29,11 @@
 class MgSiteConnection;
 template class MG_MAPGUIDE_API Ptr<MgMap>;
 
+namespace MdfModel
+{
+    class TileSetDefinition;
+}
+
 #ifdef _WIN32
 #undef CreateService
 #endif
@@ -276,10 +281,15 @@
 
     //////////////////////////////////////////////////////////////////
     /// \brief
-    /// Initializes a new MgMap object given a map definition
-    /// and a name for the map. This method is used for
+    /// Initializes a new MgMap object given a map definition or tile set
+    /// definition and a name for the map. This method is used for
     /// MapGuide Viewers or for offline map production.
     ///
+    /// \remarks
+    /// If creating a MgMap object from a tile set definition, only "Default" is the
+    /// acceptable tile provider. Any other provider will cause this method to
+    /// throw a MgUnsupportedTileProviderException
+    ///
     /// <!-- Syntax in .Net, Java, and PHP -->
     /// \htmlinclude DotNetSyntaxTop.html
     /// void Create(MgResourceIdentifier mapDefinition, string mapName);
@@ -291,7 +301,7 @@
     /// void Create(MgResourceIdentifier mapDefinition, string mapName);
     /// \htmlinclude SyntaxBottom.html
     ///
-    /// \param mapDefinition
+    /// \param resource
     /// An MgResourceIdentifier that specifies the
     /// location of the map definition in a resource
     /// repository.
@@ -311,7 +321,7 @@
     /// \endcode
     /// \htmlinclude ExampleBottom.html
     ///
-    virtual void Create(MgResourceIdentifier* mapDefinition, CREFSTRING mapName);
+    virtual void Create(MgResourceIdentifier* resource, CREFSTRING mapName);
 
     //////////////////////////////////////////////////////////////////
     /// \brief
@@ -412,6 +422,31 @@
     ///
     INT32 GetWatermarkUsage();
 
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the resource id of the Tile Set Definition that created 
+    /// this map, or the Tile Set Definition linked from the Map Definition 
+    /// used to created this map. If it was created from a Map Definition and 
+    /// that does not link to a Tile Set Definition, then NULL is returned.
+    ///
+    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// MgResourceIdentifier GetTileSetDefinition();
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// MgResourceIdentifier GetTileSetDefinition();
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// MgResourceIdentifier GetTileSetDefinition();
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \since 3.0
+    ///
+    /// \return
+    /// Returns the resource id of the Tile Set Definition. NULL if created from a Map Definition that does not link
+    /// to a Tile Set
+    MgResourceIdentifier* GetTileSetDefinition();
+
 INTERNAL_API:
 
     //////////////////////////////////////////////////////////////////
@@ -619,6 +654,8 @@
     ///
     virtual void SetWatermarkUsage(INT32 watermarkUsage);
 
+    virtual void Create(MgResourceService* resourceService, MgResourceIdentifier* mapDefinition, CREFSTRING mapName, bool strict);
+
 protected:
 
     //////////////////////////////////////////////////////////////////
@@ -661,7 +698,12 @@
     static const INT32 m_cls_id = MapGuide_MapLayer_Map;
 
 private:
+    void CreateFromMapDefinition(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName);
+    void CreateFromTileSet(MgResourceService* resourceService, MgResourceIdentifier* resource, CREFSTRING mapName, bool strict);
 
+    STRING GetCoordinateSystemFromTileSet(MdfModel::TileSetDefinition* tileset, bool strict);
+    void GetFiniteDisplayScalesFromTileSet(MdfModel::TileSetDefinition* tileset, FINITESCALES& scales, bool strict);
+
     // Version for serialization
     static const int m_serializeVersion = (4<<16) + 0;
     static STRING m_layerGroupTag;
@@ -669,6 +711,7 @@
     Ptr<MgSiteConnection> m_siteConnection;
     Ptr<MgMemoryStreamHelper> m_layerGroupHelper;
     Ptr<MgResourceService> m_resourceService;
+    Ptr<MgResourceIdentifier> m_tileSetId;
     bool m_inSave;
     bool m_unpackedLayersGroups;
     ColorStringList* m_colorPalette;

Modified: trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Resources/mapguide_en.res	2014-08-12 11:11:22 UTC (rev 8330)
@@ -426,6 +426,17 @@
 # T I L E  S E R V I C E
 # *****************************************************************************
 [TileService]
+MgTileProvider_Default_DisplayName                     = Default Tile Provider
+MgTileProvider_Default_Description                     = Default tile access provided by MapGuide. Supports MapGuide-managed tile path or user-defined path
+MgTileProvider_XYZ_DisplayName                         = XYZ Tile Provider
+MgTileProvider_XYZ_Description                         = XYZ tile access provided by MapGuide. Grid scheme is compatible with Google Maps and Open Street Map. Rendered tiles are 256x256. Layers must be convertible from lat/lon coordinates. Under this scheme, Row = X, Column = Y, Scale = Z for accessing tiles. Supports MapGuide-managed tile path or user-defined path
+MgTileProvider_Common_Property_TilePath_LocalizedName  = Tile Path
+MgTileProvider_Common_Property_TileWidth_LocalizedName = Tile Width
+MgTileProvider_Common_Property_TileHeight_LocalizedName = Tile Height
+MgTileProvider_Common_Property_TileFormat_LocalizedName = Tile Format
+MgTileProvider_Common_Property_RenderOnly_LocalizedName = Render Tiles Only (do not cache)
+MgTileProvider_Common_Property_CoordinateSystem_LocalizedName = Coordinate System
+MgTileProvider_Common_Property_FiniteScaleList_LocalizedName = Finite Display Scale List
 
 # *****************************************************************************
 # S T Y L I Z A T I O N

Modified: trunk/MgDev/Common/MapGuideCommon/Services/MappingDefs.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/MappingDefs.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/MappingDefs.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -107,6 +107,9 @@
     static const int CreateRuntimeMap2          = 0x1111EE0F;
     static const int DescribeRuntimeMap         = 0x1111EE10;
     static const int DescribeRuntimeMap2        = 0x1111EE11;
+    static const int CreateRuntimeMap3          = 0x1111EE12;
+    static const int DescribeRuntimeMap3        = 0x1111EE13;
+
 };
 /// \endcond
 

Modified: trunk/MgDev/Common/MapGuideCommon/Services/MappingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/MappingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/MappingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -540,6 +540,24 @@
     ///
     MgMappingService();
 
+    virtual MgByteReader* DescribeRuntimeMap(MgMap* map,
+                                             CREFSTRING iconFormat,
+                                             INT32 iconWidth,
+                                             INT32 iconHeight,
+                                             INT32 requestedFeatures,
+                                             INT32 iconsPerScaleRange,
+                                             INT32 schemaVersion) = 0;
+
+    virtual MgByteReader* CreateRuntimeMap(MgResourceIdentifier* mapDefinition,
+                                           CREFSTRING targetMapName,
+                                           CREFSTRING sessionId,
+                                           CREFSTRING iconFormat,
+                                           INT32 iconWidth,
+                                           INT32 iconHeight,
+                                           INT32 requestedFeatures,
+                                           INT32 iconsPerScaleRange,
+                                           INT32 schemaVersion) = 0;
+
     ///////////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Generates an \link ePlot ePlot \endlink containing a legend for the

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -424,6 +424,40 @@
     return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
 }
 
+MgByteReader* MgProxyMappingService::CreateRuntimeMap(MgResourceIdentifier* mapDefinition,
+                                                      CREFSTRING targetMapName,
+                                                      CREFSTRING sessionId,
+                                                      CREFSTRING iconFormat,
+                                                      INT32 iconWidth,
+                                                      INT32 iconHeight,
+                                                      INT32 requestedFeatures,
+                                                      INT32 iconsPerScaleRange,
+                                                      INT32 schemaVersion)
+{
+    MgCommand cmd;
+
+    cmd.ExecuteCommand(m_connProp,
+                       MgCommand::knObject,
+                       MgMappingServiceOpId::CreateRuntimeMap3,
+                       9,
+                       Mapping_Service,
+                       BUILD_VERSION(3,0,0),
+                       MgCommand::knObject,    mapDefinition,
+                       MgCommand::knString,    &targetMapName,
+                       MgCommand::knString,    &sessionId,
+                       MgCommand::knString,    &iconFormat,
+                       MgCommand::knInt32,     iconWidth,
+                       MgCommand::knInt32,     iconHeight,
+                       MgCommand::knInt32,     requestedFeatures,
+                       MgCommand::knInt32,     iconsPerScaleRange,
+                       MgCommand::knInt32,     schemaVersion,
+                       MgCommand::knNone);
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 /// \brief
 /// Returns an XML-based description of the runtime map
@@ -547,6 +581,36 @@
     return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
 }
 
+MgByteReader* MgProxyMappingService::DescribeRuntimeMap(MgMap* map,
+                                                        CREFSTRING iconFormat,
+                                                        INT32 iconWidth,
+                                                        INT32 iconHeight,
+                                                        INT32 requestedFeatures,
+                                                        INT32 iconsPerScaleRange,
+                                                        INT32 schemaVersion)
+{
+    MgCommand cmd;
+
+    cmd.ExecuteCommand(m_connProp,
+                       MgCommand::knObject,
+                       MgMappingServiceOpId::DescribeRuntimeMap3,
+                       7,
+                       Mapping_Service,
+                       BUILD_VERSION(3,0,0),
+                       MgCommand::knObject,    map,
+                       MgCommand::knString,    &iconFormat,
+                       MgCommand::knInt32,     iconWidth,
+                       MgCommand::knInt32,     iconHeight,
+                       MgCommand::knInt32,     requestedFeatures,
+                       MgCommand::knInt32,     iconsPerScaleRange,
+                       MgCommand::knInt32,     schemaVersion,
+                       MgCommand::knNone);
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
 //////////////////////////////////////////////////////////////////
 /// \brief
 /// Sets the connection properties for the Proxy Service.  This

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyMappingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -434,6 +434,24 @@
 
     DECLARE_CREATE_SERVICE()
 
+    virtual MgByteReader* DescribeRuntimeMap(MgMap* map,
+                                             CREFSTRING iconFormat,
+                                             INT32 iconWidth,
+                                             INT32 iconHeight,
+                                             INT32 requestedFeatures,
+                                             INT32 iconsPerScaleRange,
+                                             INT32 schemaVersion);
+
+    virtual MgByteReader* CreateRuntimeMap(MgResourceIdentifier* mapDefinition,
+                                           CREFSTRING targetMapName,
+                                           CREFSTRING sessionId,
+                                           CREFSTRING iconFormat,
+                                           INT32 iconWidth,
+                                           INT32 iconHeight,
+                                           INT32 requestedFeatures,
+                                           INT32 iconsPerScaleRange,
+                                           INT32 schemaVersion);
+
     //////////////////////////////////////////////////////////////////
     /// \brief
     /// Sets the connection properties for the Proxy Service.  This

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -106,7 +106,92 @@
     return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
 }
 
+MgByteReader* MgProxyRenderingService::RenderTile(
+    MgMap* map,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow,
+    INT32 tileWidth,
+    INT32 tileHeight,
+    INT32 tileDpi,
+    CREFSTRING tileImageFormat)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knObject,                            // Return type expected
+                        MgRenderingServiceOpId::RenderTile2,            // Command Code
+                        8,                                              // No of arguments
+                        Rendering_Service,                              // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, map,                       // Argument#1
+                        MgCommand::knString, &baseMapLayerGroupName,    // Argument#2
+                        MgCommand::knInt32, tileColumn,                 // Argument#3
+                        MgCommand::knInt32, tileRow,                    // Argument#4
+                        MgCommand::knInt32, tileWidth,                  // Argument#5
+                        MgCommand::knInt32, tileHeight,                 // Argument#6
+                        MgCommand::knInt32, tileDpi,                    // Argument#7
+                        MgCommand::knString, &tileImageFormat,          // Argument#8
+                        MgCommand::knNone);                             // End of arguments
 
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
+MgByteReader* MgProxyRenderingService::RenderTileXYZ(MgMap* map,
+                                                     CREFSTRING baseMapLayerGroupName,
+                                                     INT32 x,
+                                                     INT32 y,
+                                                     INT32 z)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knObject,                            // Return type expected
+                        MgRenderingServiceOpId::RenderTileXYZ,          // Command Code
+                        5,                                              // No of arguments
+                        Rendering_Service,                              // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, map,                       // Argument#1
+                        MgCommand::knString, &baseMapLayerGroupName,    // Argument#2
+                        MgCommand::knInt32, x,                          // Argument#3
+                        MgCommand::knInt32, y,                          // Argument#4
+                        MgCommand::knInt32, z,                          // Argument#5
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
+MgByteReader* MgProxyRenderingService::RenderTileXYZ(MgMap* map,
+                                                     CREFSTRING baseMapLayerGroupName,
+                                                     INT32 x,
+                                                     INT32 y,
+                                                     INT32 z,
+                                                     INT32 dpi,
+                                                     CREFSTRING tileImageFormat)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knObject,                            // Return type expected
+                        MgRenderingServiceOpId::RenderTileXYZ2,         // Command Code
+                        7,                                              // No of arguments
+                        Rendering_Service,                              // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, map,                       // Argument#1
+                        MgCommand::knString, &baseMapLayerGroupName,    // Argument#2
+                        MgCommand::knInt32, x,                          // Argument#3
+                        MgCommand::knInt32, y,                          // Argument#4
+                        MgCommand::knInt32, z,                          // Argument#5
+                        MgCommand::knInt32, dpi,                        // Argument#6
+                        MgCommand::knInt32, &tileImageFormat,           // Argument#7
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}
+
 /////////////////////////////////////////////////////////////////
 /// <summary>
 /// Renders all dynamic layers in the specified MgMap to a dynamic overlay image

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyRenderingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -58,6 +58,127 @@
 
     /////////////////////////////////////////////////////////////////
     /// \brief
+    /// Returns the specified base map tile for the given map.
+    ///
+    /// \remarks
+    /// This method only renders the given tile. No tile caching is performed
+    /// by this method. To render and cache the tile, use the 
+    /// \link MgTileService::GetTile GetTile \endlink method instead. However,
+    /// using that method will use default tile width/height/dpi/format specified
+    /// in your MapGuide Server configuration
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param tileColumn
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param tileRow
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param tileWidth
+    /// Input
+    /// Specifies the width of the tile to return.
+    /// \param tileHeight
+    /// Input
+    /// Specifies the height of the tile to return.
+    /// \param tileDpi
+    /// Input
+    /// Specifies the dpi the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile. See \link MgImageFormats \endlink
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgByteReader* RenderTile(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow,
+        INT32 tileWidth,
+        INT32 tileHeight,
+        INT32 tileDpi,
+        CREFSTRING tileImageFormat);
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified map tile for the given map. Tile structure is
+    /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+    /// others
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param x
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param y
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param z
+    /// Input
+    /// Specifies the zoom level of the tile to return.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgByteReader* RenderTileXYZ(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 x,
+        INT32 y,
+        INT32 z);
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified map tile for the given map. Tile structure is
+    /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+    /// others
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param x
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param y
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param z
+    /// Input
+    /// Specifies the zoom level of the tile to return.
+    /// \param dpi
+    /// Input
+    /// Specifies the dpi of the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile to return.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgByteReader* RenderTileXYZ(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 x,
+        INT32 y,
+        INT32 z,
+        INT32 dpi,
+        CREFSTRING tileImageFormat);
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
     /// Renders all dynamic layers in the specified MgMap to a dynamic overlay image
     /// with a transparent background. The center, scale, size, and layers to be
     /// rendered are defined by the specified map instance.  The format parameter

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1160,7 +1160,7 @@
         MgResourceService::opIdEnumerateParentMapDefinitions, // Command code
         1,                                                  // Number of arguments
         Resource_Service,                                   // Service ID
-        BUILD_VERSION(1,0,0),                               // Operation version
+        BUILD_VERSION(3,0,0),                               // Operation version
         MgCommand::knObject, resources,                     // Argument #1
         MgCommand::knNone);
 
@@ -1171,6 +1171,32 @@
     return (MgSerializableCollection*)cmd.GetReturnValue().val.m_obj;
 }
 
+MgSerializableCollection* MgProxyResourceService::EnumerateParentTileSetDefinitions(
+    MgSerializableCollection* resources)
+{
+    MgCommand cmd;
+
+    MG_TRY()
+
+    assert(m_connProp != NULL);
+
+    cmd.ExecuteCommand(
+        m_connProp,                                         // Connection
+        MgCommand::knObject,                                // Return type
+        MgResourceService::opIdEnumerateParentTileSetDefinitions, // Command code
+        1,                                                  // Number of arguments
+        Resource_Service,                                   // Service ID
+        BUILD_VERSION(1,0,0),                               // Operation version
+        MgCommand::knObject, resources,                     // Argument #1
+        MgCommand::knNone);
+
+    SetWarning(cmd.GetWarningObject());
+
+    MG_CATCH_AND_THROW(L"MgProxyResourceService.EnumerateParentTileSetDefinitions")
+
+    return (MgSerializableCollection*)cmd.GetReturnValue().val.m_obj;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief
 /// Enumerate the resource documents in the specified repository.

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyResourceService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -175,6 +175,25 @@
 
     ///////////////////////////////////////////////////////////////////////////
     /// \brief
+    /// Enumerate all the parent Tile Set Definition resources of the specified
+    /// resources.
+    ///
+    /// This method only works on "Library" and "Session" repositories.
+    //
+    /// \param resources
+    /// Child resources.
+    ///
+    /// \return
+    /// MgResourceIdentifier list of Map Definition resources.
+    ///
+    /// \exception MgInvalidRepositoryTypeException
+    /// \exception MgInvalidResourceTypeException
+    ///
+    virtual MgSerializableCollection* EnumerateParentTileSetDefinitions(
+        MgSerializableCollection* resources);
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
     /// Enumerate the resource documents in the specified repository.
     ///
     /// \remarks

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -260,3 +260,83 @@
 {
     m_connProp = SAFE_ADDREF(connProp);
 }
+
+//////////////////////////////////////////////////////////////////
+/// \brief
+/// Clears the entire tile cache for the given tile set.  Tiles for all base
+/// map layer groups and finite scales will be removed.
+///
+/// \param map
+/// Input
+/// Specifies the map whose tile cache will be cleared.
+///
+void MgProxyTileService::ClearCache(MgResourceIdentifier* tileSet)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knVoid,                              // Return type expected
+                        MgTileServiceOpId::ClearCache2,                 // Command Code
+                        1,                                              // No of arguments
+                        Tile_Service,                                   // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, tileSet,                   // Argument#1
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+}
+
+//////////////////////////////////////////////////////////////////
+/// \brief
+/// Returns the default width of a tile.
+INT32 MgProxyTileService::GetDefaultTileSizeX(MgResourceIdentifier* tileSet)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knInt32,                             // Return type expected
+                        MgTileServiceOpId::GetDefaultTileSizeX2,        // Command Code
+                        1,                                              // No of arguments
+                        Tile_Service,                                   // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, tileSet,                   // Argument#1
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return cmd.GetReturnValue().val.m_i32;
+}
+
+//////////////////////////////////////////////////////////////////
+/// \brief
+/// Returns the default height of a tile.
+INT32 MgProxyTileService::GetDefaultTileSizeY(MgResourceIdentifier* tileSet)
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knInt32,                             // Return type expected
+                        MgTileServiceOpId::GetDefaultTileSizeY2,        // Command Code
+                        1,                                              // No of arguments
+                        Tile_Service,                                   // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knObject, tileSet,                   // Argument#1
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return cmd.GetReturnValue().val.m_i32;
+}
+
+MgByteReader* MgProxyTileService::GetTileProviders()
+{
+    MgCommand cmd;
+    cmd.ExecuteCommand(m_connProp,                                      // Connection
+                        MgCommand::knObject,                            // Return type expected
+                        MgTileServiceOpId::GetTileProviders,            // Command Code
+                        0,                                              // No of arguments
+                        Tile_Service,                                   // Service Id
+                        BUILD_VERSION(3,0,0),                           // Operation version
+                        MgCommand::knNone);                             // End of arguments
+
+    SetWarning(cmd.GetWarningObject());
+
+    return (MgByteReader*)cmd.GetReturnValue().val.m_obj;
+}

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyTileService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -101,6 +101,18 @@
 
     //////////////////////////////////////////////////////////////////
     /// \brief
+    /// Clears the entire tile cache for the given tile set.  Tiles for all base
+    /// map layer groups and finite scales will be removed.
+    ///
+    /// \param map
+    /// Input
+    /// Specifies the map whose tile cache will be cleared.
+    ///
+    /// \since 3.0
+    virtual void ClearCache(MgResourceIdentifier* tileSet);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
     /// Returns the default width of a tile.
     ///
     /// \return
@@ -117,6 +129,41 @@
     ///
     virtual INT32 GetDefaultTileSizeY();
 
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the default width of a tile.
+    ///
+    /// \param tileSet
+    /// Input
+    /// Specifies the resource id of the tile set
+    ///
+    /// \return
+    /// Default width of a tile in pixels.
+    ///
+    /// \since 3.0
+    virtual INT32 GetDefaultTileSizeX(MgResourceIdentifier* tileSet);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the default height of a tile.
+    ///
+    /// \param tileSet
+    /// Input
+    /// Specifies the resource id of the tile set
+    ///
+    /// \return
+    /// Default height of a tile in pixels.
+    ///
+    /// \since 3.0
+    virtual INT32 GetDefaultTileSizeY(MgResourceIdentifier* tileSet);
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the list of available tile providers, along with supported connection parameters
+    ///
+    /// \since 3.0
+    virtual MgByteReader* GetTileProviders();
+
 INTERNAL_API:
 
     /////////////////////////////////////////////////////////////////

Modified: trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/RenderingDefs.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -40,6 +40,9 @@
     static const int RenderDynamicOverlay2      = 0x1111E90C;
     static const int RenderMap5                 = 0x1111E90D;
     static const int QueryFeatureProperties2    = 0x1111E90E;
+    static const int RenderTile2                = 0x1111E90F;
+    static const int RenderTileXYZ              = 0x1111E910;
+    static const int RenderTileXYZ2             = 0x1111E911;
 };
 /// \endcond
 

Modified: trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/RenderingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -46,6 +46,8 @@
     /// by this method. To render and cache the tile, use the 
     /// \link MgTileService::GetTile GetTile \endlink method instead
     ///
+    /// \deprecated This method is deprecated. Use the RenderTile that acceps width/height/dpi/format
+    ///
     /// \param map
     /// Input
     /// map object containing current state of map.
@@ -70,6 +72,128 @@
 
     /////////////////////////////////////////////////////////////////
     /// \brief
+    /// Returns the specified base map tile for the given map.
+    ///
+    /// \remarks
+    /// This method only renders the given tile. No tile caching is performed
+    /// by this method. To render and cache the tile, use the 
+    /// \link MgTileService::GetTile GetTile \endlink method instead. However,
+    /// using that method will use default tile width/height/dpi/format specified
+    /// in your MapGuide Server configuration
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param tileColumn
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param tileRow
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param tileWidth
+    /// Input
+    /// Specifies the width of the tile to return.
+    /// \param tileHeight
+    /// Input
+    /// Specifies the height of the tile to return.
+    /// \param tileDpi
+    /// Input
+    /// Specifies the dpi the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile. See \link MgImageFormats \endlink
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgByteReader* RenderTile(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow,
+        INT32 tileWidth,
+        INT32 tileHeight,
+        INT32 tileDpi,
+        CREFSTRING tileImageFormat) = 0;
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified map tile for the given map. Tile structure is
+    /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+    /// others
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param x
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param y
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param z
+    /// Input
+    /// Specifies the zoom level of the tile to return.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    /// \since 3.0
+    virtual MgByteReader* RenderTileXYZ(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 x,
+        INT32 y,
+        INT32 z) = 0;
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the specified map tile for the given map. Tile structure is
+    /// based on the XYZ tiling scheme used by Google Maps, OpenStreetMap, and
+    /// others
+    ///
+    /// \param map
+    /// Input
+    /// map object containing current state of map.
+    /// \param baseMapLayerGroupName
+    /// Input
+    /// Specifies the name of the baseMapLayerGroup for which to render the tile.
+    /// \param x
+    /// Input
+    /// Specifies the row index of the tile to return.
+    /// \param y
+    /// Input
+    /// Specifies the column index of the tile to return.
+    /// \param z
+    /// Input
+    /// Specifies the zoom level of the tile to return.
+    /// \param dpi
+    /// Input
+    /// Specifies the dpi of the tile to return.
+    /// \param tileImageFormat
+    /// Input
+    /// Specifies the image format of the tile to return.
+    ///
+    /// \return
+    /// A byte reader containing the rendered tile image.
+    ///
+    virtual MgByteReader* RenderTileXYZ(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 x,
+        INT32 y,
+        INT32 z,
+        INT32 dpi,
+        CREFSTRING tileImageFormat) = 0;
+
+    /////////////////////////////////////////////////////////////////
+    /// \brief
     /// Renders all dynamic layers in the specified MgMap to a dynamic overlay image
     /// with a transparent background. The center, scale, size, and layers to be
     /// rendered are defined by the specified map instance.  The format parameter

Modified: trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -29,3 +29,4 @@
 INT32  MgTileParameters::tileHeight = 300;                    // height for all tiles
 const INT32  MgTileParameters::tileDPI    =  96;              // assumed DPI for all tiles
 STRING MgTileParameters::tileFormat = MgImageFormats::Png;    // image format for all tiles
+STRING MgTileParameters::tileCachePath = L"";                 // tile cache root directory

Modified: trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/TileDefs.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -27,11 +27,15 @@
 class MG_MAPGUIDE_API MgTileServiceOpId
 {
 INTERNAL_API:
-    static const int GetTile    = 0x1111E801;
-    static const int SetTile    = 0x1111E802;
-    static const int ClearCache = 0x1111E803;
+    static const int GetTile              = 0x1111E801;
+    static const int SetTile              = 0x1111E802;
+    static const int ClearCache           = 0x1111E803;
     static const int GetDefaultTileSizeX  = 0x1111E804;
     static const int GetDefaultTileSizeY  = 0x1111E805;
+    static const int ClearCache2          = 0x1111E806;
+    static const int GetDefaultTileSizeX2 = 0x1111E807;
+    static const int GetDefaultTileSizeY2 = 0x1111E808;
+    static const int GetTileProviders     = 0x1111E809;
 };
 /// \endcond
 
@@ -39,7 +43,7 @@
 /// \cond INTERNAL
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief
-/// Tile parameters.
+/// Default tile parameters.
 /// INTERNAL do not document.
 ///
 class MG_MAPGUIDE_API MgTileParameters
@@ -47,9 +51,20 @@
 INTERNAL_API:
     static INT32 tileWidth;       // width for all tiles
     static INT32 tileHeight;      // height for all tiles
-    static const INT32 tileDPI;         // assumed DPI for all tiles
+    static const INT32 tileDPI;   // assumed DPI for all tiles
     static STRING tileFormat;     // image format for all tiles
+    static STRING tileCachePath;  // tile cache root path
 };
 /// \endcond
 
+#define MG_TILE_PROVIDER_DEFAULT L"Default"
+#define MG_TILE_PROVIDER_XYZ L"XYZ"
+#define MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH         L"TilePath"
+#define MG_TILE_PROVIDER_COMMON_PARAM_TILEWIDTH        L"TileWidth"
+#define MG_TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT       L"TileHeight"
+#define MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT       L"TileFormat"
+#define MG_TILE_PROVIDER_COMMON_PARAM_RENDERONLY       L"RenderOnly"
+#define MG_TILE_PROVIDER_COMMON_PARAM_COORDINATESYSTEM L"CoordinateSystem"
+#define MG_TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST  L"FiniteScaleList"
+
 #endif

Modified: trunk/MgDev/Common/MapGuideCommon/Services/TileService.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/TileService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/Services/TileService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -61,13 +61,18 @@
 
     /////////////////////////////////////////////////////////////////
     /// \brief
-    /// Returns the specified base map tile for the given map.  If a cached tile
-    /// image exists it will return it, otherwise the tile is rendered and added
-    /// to the cache.
+    /// Returns the specified base map tile for the given map or tile set.  
+    /// If a cached tile image exists it will return it, otherwise the tile 
+    /// is rendered and added to the cache. 
     ///
-    /// \param mapDefinition
+    /// \remarks
+    /// If retrieving a tile from a tile set, the row, column and scale index 
+    /// may take on different meaning depending on the tile provider specified
+    /// in the tile set
+    ///
+    /// \param resource
     /// Input
-    /// Resource identifier for the map definition
+    /// Resource identifier for the map definition or Tile Set Definition
     /// \param baseMapLayerGroupName
     /// Input
     /// Specifies the name of the baseMapLayerGroup for which to render the tile.
@@ -85,7 +90,7 @@
     /// A byte reader containing the rendered tile image.
     ///
     virtual MgByteReader* GetTile(
-        MgResourceIdentifier* mapDefinition,
+        MgResourceIdentifier* resource,
         CREFSTRING baseMapLayerGroupName,
         INT32 tileColumn,
         INT32 tileRow,
@@ -104,6 +109,18 @@
 
     //////////////////////////////////////////////////////////////////
     /// \brief
+    /// Clears the entire tile cache for the given tile set.  Tiles for all base
+    /// map layer groups and finite scales will be removed.
+    ///
+    /// \param map
+    /// Input
+    /// Specifies the map whose tile cache will be cleared.
+    ///
+    /// \since 3.0
+    virtual void ClearCache(MgResourceIdentifier* tileSet) = 0;
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
     /// Returns the default width of a tile.
     ///
     /// \return
@@ -122,6 +139,45 @@
     /// \since 1.2
     virtual INT32 GetDefaultTileSizeY() = 0;
 
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the default width of a tile.
+    ///
+    /// \param tileSet
+    /// Input
+    /// Specifies the resource id of the tile set
+    ///
+    /// \return
+    /// Default width of a tile in pixels.
+    ///
+    /// \since 3.0
+    virtual INT32 GetDefaultTileSizeX(MgResourceIdentifier* tileSet) = 0;
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the default height of a tile.
+    ///
+    /// \param tileSet
+    /// Input
+    /// Specifies the resource id of the tile set
+    ///
+    /// \return
+    /// Default height of a tile in pixels.
+    ///
+    /// \since 3.0
+    virtual INT32 GetDefaultTileSizeY(MgResourceIdentifier* tileSet) = 0;
+
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Returns the XML description of available tile providers, along with supported connection parameters. This provides
+    /// sufficient information for client applications to build rich editor user interfaces for editing Tile Set Definitions
+    ///
+    /// \return
+    /// The XML description of available tile providers
+    ///
+    /// \since 3.0
+    virtual MgByteReader* GetTileProviders() = 0;
+
 INTERNAL_API:
 
     /////////////////////////////////////////////////////////////////

Modified: trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonClassId.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -89,6 +89,8 @@
 #define MapGuide_Exception_MgUnsupportedProviderThreadModelException    MAPGUIDE_EXCEPTION_ID+53
 #define MapGuide_Exception_MgAllProviderConnectionsUsedException        MAPGUIDE_EXCEPTION_ID+54
 #define MapGuide_Exception_MgRasterTransformationNotSupportedException  MAPGUIDE_EXCEPTION_ID+55
+#define MapGuide_Exception_MgUnknownTileProviderException               MAPGUIDE_EXCEPTION_ID+56
+#define MapGuide_Exception_MgUnsupportedTileProviderException           MAPGUIDE_EXCEPTION_ID+57
 
 
 // MapLayer API

Modified: trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MapGuideCommon/System/MapGuideCommonFactory.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -88,6 +88,8 @@
     EXCEPTION_CLASS_CREATOR(MgSessionExpiredException)
     EXCEPTION_CLASS_CREATOR(MgSessionNotFoundException)
     EXCEPTION_CLASS_CREATOR(MgUnauthorizedAccessException)
+    EXCEPTION_CLASS_CREATOR(MgUnknownTileProviderException)
+    EXCEPTION_CLASS_CREATOR(MgUnsupportedTileProviderException)
     EXCEPTION_CLASS_CREATOR(MgUnsupportedProviderThreadModelException)
     EXCEPTION_CLASS_CREATOR(MgUriFormatException)
 

Modified: trunk/MgDev/Common/MdfModel/Makefile.am
===================================================================
--- trunk/MgDev/Common/MdfModel/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfModel/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -102,6 +102,9 @@
   TextFrame.cpp \
   TextSymbol.cpp \
   ThemeLabel.cpp \
+  TileSetDefinition.cpp \
+  TileSetSource.cpp \
+  TileStoreParameters.cpp \
   TileWatermarkPosition.cpp \
   UnicodeString.cpp \
   URLData.cpp \
@@ -223,6 +226,9 @@
   TextFrame.h \
   TextSymbol.h \
   ThemeLabel.h \
+  TileSetDefinition.h \
+  TileSetSource.h \
+  TileStoreParameters.h \
   TileWatermarkPosition.h \
   UnicodeString.h \
   URLData.h \

Modified: trunk/MgDev/Common/MdfModel/MapDefinition.cpp
===================================================================
--- trunk/MgDev/Common/MdfModel/MapDefinition.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfModel/MapDefinition.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -47,6 +47,7 @@
 : m_strName(strName)
 , m_strCoordSys(strCoordinateSystem)
 , m_boxExtents(0.0, 0.0)
+, m_tileSourceType(Inline)
 {
     // default values
     this->m_strBkGrnd = L"ffffffff"; // NOXLATE
@@ -219,6 +220,21 @@
     return &this->m_baseMapLayerGroups;
 }
 
+MapDefinition::TileSourceType MapDefinition::GetTileSourceType() const
+{
+    return this->m_tileSourceType;
+}
+
+void MapDefinition::SetTileSourceType(TileSourceType tileSourceType)
+{
+    this->m_tileSourceType = tileSourceType;
+}
+
+TileSetSource* MapDefinition::GetTileSetSource()
+{
+    return &this->m_tileSetSource;
+}
+
 #ifdef _WIN32
 #ifdef _DEBUG
 int MapDefinition::DumpMemoryLeaks()

Modified: trunk/MgDev/Common/MdfModel/MapDefinition.h
===================================================================
--- trunk/MgDev/Common/MdfModel/MapDefinition.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfModel/MapDefinition.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -25,6 +25,7 @@
 #include "MapLayerGroup.h"
 #include "BaseMapLayerGroup.h"
 #include "WatermarkInstance.h"
+#include "TileSetSource.h"
 #include "DisplayScale.h"
 
 BEGIN_NAMESPACE_MDFMODEL
@@ -37,6 +38,13 @@
     class MDFMODEL_API MapDefinition : public MdfRootObject
     {
     public:
+        // Describes the source of the tiled layers
+        enum TileSourceType
+        {
+            Inline,
+            TileSetDefinition
+        };
+
         // Construction, destruction, initialization.
         MapDefinition(const MdfString& strName, const MdfString& strCoordinateSystem);
         virtual ~MapDefinition();
@@ -87,6 +95,15 @@
         // The base map groups; used to define tiles for the HTML viewer.
         BaseMapLayerGroupCollection* GetBaseMapLayerGroups();
 
+        // Property : TileSetSource
+        // Gets the reference to the external TileSetDefinition
+        TileSetSource* GetTileSetSource();
+
+        // Property : TileSourceType
+        // Indicates the tile source type (inside the Map Definition or referencing a Tile Set Definition)
+        TileSourceType GetTileSourceType() const;
+        void SetTileSourceType(TileSourceType tileSourceType);
+
 //#ifdef _WIN32
 #if _DEBUG
         // for memory leak testing
@@ -111,6 +128,8 @@
         Box2D m_boxExtents;
         DisplayScaleCollection m_finiteDisplayScales;
         BaseMapLayerGroupCollection m_baseMapLayerGroups;
+        TileSetSource m_tileSetSource;
+        TileSourceType m_tileSourceType;
     };
 
 END_NAMESPACE_MDFMODEL

Modified: trunk/MgDev/Common/MdfModel/MdfModel.vcxproj
===================================================================
--- trunk/MgDev/Common/MdfModel/MdfModel.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfModel/MdfModel.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -232,6 +232,9 @@
     <ClCompile Include="HillShade.cpp" />
     <ClCompile Include="FeatureSource.cpp" />
     <ClCompile Include="SupplementalSpatialContextInfo.cpp" />
+    <ClCompile Include="TileSetDefinition.cpp" />
+    <ClCompile Include="TileSetSource.cpp" />
+    <ClCompile Include="TileStoreParameters.cpp" />
     <ClCompile Include="URLData.cpp" />
     <ClCompile Include="VectorLayerDefinition.cpp" />
     <ClCompile Include="VectorScaleRange.cpp" />
@@ -347,6 +350,9 @@
     <ClInclude Include="HillShade.h" />
     <ClInclude Include="FeatureSource.h" />
     <ClInclude Include="SupplementalSpatialContextInfo.h" />
+    <ClInclude Include="TileSetDefinition.h" />
+    <ClInclude Include="TileSetSource.h" />
+    <ClInclude Include="TileStoreParameters.h" />
     <ClInclude Include="URLData.h" />
     <ClInclude Include="VectorLayerDefinition.h" />
     <ClInclude Include="VectorScaleRange.h" />

Modified: trunk/MgDev/Common/MdfModel/MdfModel.vcxproj.filters
===================================================================
--- trunk/MgDev/Common/MdfModel/MdfModel.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfModel/MdfModel.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -40,6 +40,9 @@
     <Filter Include="ProfileResult">
       <UniqueIdentifier>{117f7c46-7bea-4de3-887b-c162c15359d5}</UniqueIdentifier>
     </Filter>
+    <Filter Include="TileSetDefinition">
+      <UniqueIdentifier>{e5dae237-fc68-4fca-b0ff-cf0377111684}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="AreaUsage.cpp">
@@ -355,6 +358,15 @@
     <ClCompile Include="NameStringPair.cpp" />
     <ClCompile Include="UnicodeString.cpp" />
     <ClCompile Include="Version.cpp" />
+    <ClCompile Include="TileSetSource.cpp">
+      <Filter>TileSetDefinition</Filter>
+    </ClCompile>
+    <ClCompile Include="TileSetDefinition.cpp">
+      <Filter>TileSetDefinition</Filter>
+    </ClCompile>
+    <ClCompile Include="TileStoreParameters.cpp">
+      <Filter>TileSetDefinition</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AreaUsage.h">
@@ -683,6 +695,15 @@
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="UnicodeString.h" />
     <ClInclude Include="Version.h" />
+    <ClInclude Include="TileSetDefinition.h">
+      <Filter>TileSetDefinition</Filter>
+    </ClInclude>
+    <ClInclude Include="TileSetSource.h">
+      <Filter>TileSetDefinition</Filter>
+    </ClInclude>
+    <ClInclude Include="TileStoreParameters.h">
+      <Filter>TileSetDefinition</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MdfModel.rc" />

Copied: trunk/MgDev/Common/MdfModel/TileSetDefinition.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.cpp)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileSetDefinition.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileSetDefinition.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,56 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "TileSetDefinition.h"
+
+// Construction, destruction, initialization.
+TileSetDefinition::TileSetDefinition()
+    : m_boxExtents(0.0, 0.0)
+{
+
+}
+
+TileSetDefinition::~TileSetDefinition()
+{
+
+}
+
+// Property: TileStoreParameters
+// Defines the parameters to access the tile cache
+TileStoreParameters* TileSetDefinition::GetTileStoreParameters()
+{
+    return &this->m_parameters;
+}
+
+// Property : Extents
+// The extents to be used by the MapDefinition
+const Box2D& TileSetDefinition::GetExtents() const
+{
+    return this->m_boxExtents;
+}
+
+void TileSetDefinition::SetExtents(const Box2D& boxExtents)
+{
+    this->m_boxExtents = boxExtents;
+}
+
+// Property : BaseMapLayerGroups
+// The base map groups; used to define tiles for the HTML viewer.
+BaseMapLayerGroupCollection* TileSetDefinition::GetBaseMapLayerGroups()
+{
+    return &this->m_baseMapLayerGroups;
+}
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfModel/TileSetDefinition.h (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileSetDefinition.h)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileSetDefinition.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileSetDefinition.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,63 @@
+//
+//  Copyright (C) 2004-2014 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 TILESETDEFINITION_H_
+#define TILESETDEFINITION_H_
+
+#include "MdfModel.h"
+#include "MdfRootObject.h"
+#include "Box2D.h"
+#include "DisplayScale.h"
+#include "BaseMapLayerGroup.h"
+#include "TileStoreParameters.h"
+
+BEGIN_NAMESPACE_MDFMODEL
+
+    class MDFMODEL_API TileSetDefinition : public MdfRootObject
+    {
+    public:
+        // Construction, destruction, initialization.
+        TileSetDefinition();
+        virtual ~TileSetDefinition();
+
+        // Property: TileStoreParameters
+        // Defines the parameters to access the tile cache
+        TileStoreParameters* GetTileStoreParameters();
+
+        // Property : Extents
+        // The extents to be used by the MapDefinition
+        const Box2D& GetExtents() const;
+        void SetExtents(const Box2D& boxExtents);
+
+        // Property : BaseMapLayerGroups
+        // The base map groups; used to define tiles for the HTML viewer.
+        BaseMapLayerGroupCollection* GetBaseMapLayerGroups();
+
+    private:
+        // Hidden MapDefinition copy constructor and assignment operator.
+        TileSetDefinition(const TileSetDefinition&);
+        TileSetDefinition& operator=(const TileSetDefinition&);
+
+        // Data members
+        // See corresponding properties for descriptions
+        TileStoreParameters m_parameters;
+        Box2D m_boxExtents;
+        BaseMapLayerGroupCollection m_baseMapLayerGroups;
+    };
+
+END_NAMESPACE_MDFMODEL
+
+#endif //TILESETDEFINITION_H_
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfModel/TileSetSource.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileSetSource.cpp)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileSetSource.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileSetSource.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,39 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "TileSetSource.h"
+
+TileSetSource::TileSetSource()
+{
+
+}
+
+TileSetSource::~TileSetSource()
+{
+
+}
+
+// Property : ResourceId
+const MdfString& TileSetSource::GetResourceId() const
+{
+    return this->m_resourceId;
+}
+
+void TileSetSource::SetResourceId(const MdfString&  strResourceId)
+{
+    this->m_resourceId = strResourceId;
+}
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfModel/TileSetSource.h (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileSetSource.h)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileSetSource.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileSetSource.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,45 @@
+//
+//  Copyright (C) 2004-2014 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 TILESETSOURCE_H_
+#define TILESETSOURCE_H_
+
+#include "MdfModel.h"
+#include "MdfRootObject.h"
+
+BEGIN_NAMESPACE_MDFMODEL
+
+    class MDFMODEL_API TileSetSource : public MdfRootObject
+    {
+    public:
+        TileSetSource();
+        virtual ~TileSetSource();
+
+        // Property : ResourceId
+        const MdfString& GetResourceId() const;
+        void SetResourceId(const MdfString&  strResourceId);
+
+    private:
+        // Hidden copy constructor and assignment operator.
+        TileSetSource(const TileSetSource&);
+        TileSetSource& operator=(const TileSetSource&);
+
+        MdfString m_resourceId;
+    };
+
+END_NAMESPACE_MDFMODEL
+
+#endif //TILESETSOURCE_H_
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfModel/TileStoreParameters.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.cpp)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileStoreParameters.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileStoreParameters.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,49 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "TileStoreParameters.h"
+
+TileStoreParameters::TileStoreParameters()
+    : m_format(L"PNG"),
+      m_width(300),
+      m_height(300)
+{
+    
+}
+
+TileStoreParameters::~TileStoreParameters()
+{
+
+}
+
+// Operations
+// Property : Parameters
+NameStringPairCollection* TileStoreParameters::GetParameters()
+{
+    return &this->m_parameters;
+}
+
+// Property : TileProvider
+const MdfString& TileStoreParameters::GetTileProvider() const
+{
+    return this->m_provider;
+}
+
+void TileStoreParameters::SetTileProvider(const MdfString &provider)
+{
+    this->m_provider = provider;
+}
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfModel/TileStoreParameters.h (from rev 8208, sandbox/jng/tiling/Common/MdfModel/TileStoreParameters.h)
===================================================================
--- trunk/MgDev/Common/MdfModel/TileStoreParameters.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfModel/TileStoreParameters.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,55 @@
+//
+//  Copyright (C) 2004-2014 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 TILESTOREPARAMETERS_H_
+#define TILESTOREPARAMETERS_H_
+
+#include "MdfModel.h"
+#include "NameStringPair.h"
+#include "MdfRootObject.h"
+
+BEGIN_NAMESPACE_MDFMODEL
+
+    class MDFMODEL_API TileStoreParameters : public MdfRootObject
+    {
+    public:
+        TileStoreParameters();
+        virtual ~TileStoreParameters();
+
+        // Operations
+        // Property : Parameters
+        NameStringPairCollection* GetParameters();
+
+        // Property : TileProvider
+        const MdfString& GetTileProvider() const;
+        void SetTileProvider(const MdfString &provider);
+
+    private:
+
+        // Hidden copy constructor and assignment operator.
+        TileStoreParameters(const TileStoreParameters&);
+        TileStoreParameters& operator=(const TileStoreParameters&);
+
+        int m_width;
+        int m_height;
+        MdfString m_provider;
+        MdfString m_format;
+        NameStringPairCollection m_parameters;
+    };
+
+END_NAMESPACE_MDFMODEL
+
+#endif //TILESTOREPARAMETERS_H_
\ No newline at end of file

Modified: trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -44,7 +44,11 @@
 {
 }
 
+IOBaseMapLayerGroup::IOBaseMapLayerGroup(TileSetDefinition* tileset, Version& version) : IOMapLayerGroupCommon(tileset, version)
+{
+}
 
+
 IOBaseMapLayerGroup::~IOBaseMapLayerGroup()
 {
 }
@@ -87,7 +91,14 @@
     if (this->m_startElemName == name)
     {
         this->m_layerGroup->SetUnknownXml(this->m_unknownXml);
-        this->m_map->GetBaseMapLayerGroups()->Adopt(static_cast<BaseMapLayerGroup*>(this->m_layerGroup));
+        if (NULL != this->m_map)
+        {
+            this->m_map->GetBaseMapLayerGroups()->Adopt(static_cast<BaseMapLayerGroup*>(this->m_layerGroup));
+        }
+        else if (NULL != this->m_tileset)
+        {
+            this->m_tileset->GetBaseMapLayerGroups()->Adopt(static_cast<BaseMapLayerGroup*>(this->m_layerGroup));
+        }
         this->m_map = NULL;
         this->m_layerGroup = NULL;
         this->m_startElemName = L"";

Modified: trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.h
===================================================================
--- trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOBaseMapLayerGroup.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -21,6 +21,7 @@
 #include "SAX2ElementHandler.h"
 #include "BaseMapLayerGroup.h"
 #include "MapDefinition.h"
+#include "TileSetDefinition.h"
 #include "IOMapLayerGroupCommon.h"
 #include "Version.h"
 
@@ -34,6 +35,7 @@
     public:
         IOBaseMapLayerGroup(Version& version);
         IOBaseMapLayerGroup(MapDefinition* map, Version& version);
+        IOBaseMapLayerGroup(TileSetDefinition* tileset, Version& version);
         virtual ~IOBaseMapLayerGroup();
 
         virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);

Modified: trunk/MgDev/Common/MdfParser/IOExtra.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/IOExtra.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOExtra.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -38,6 +38,7 @@
     this->m_minY = +DBL_MAX;
     this->m_maxY = -DBL_MAX;
     this->m_map  = NULL;
+    this->m_tileset = NULL;
 }
 
 
@@ -48,9 +49,20 @@
     this->m_minY = +DBL_MAX;
     this->m_maxY = -DBL_MAX;
     this->m_map  = map;
+    this->m_tileset = NULL;
 }
 
+IOExtra::IOExtra(TileSetDefinition* tileset, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_minX = +DBL_MAX;
+    this->m_maxX = -DBL_MAX;
+    this->m_minY = +DBL_MAX;
+    this->m_maxY = -DBL_MAX;
+    this->m_map  = NULL;
+    this->m_tileset = tileset;
+}
 
+
 IOExtra::~IOExtra()
 {
 }
@@ -97,8 +109,16 @@
 {
     if (this->m_startElemName == name)
     {
-        this->m_map->SetExtents(Box2D(this->m_minX, this->m_minY, this->m_maxX, this->m_maxY));
-        this->m_map = NULL;
+        if (NULL != this->m_map)
+        {
+            this->m_map->SetExtents(Box2D(this->m_minX, this->m_minY, this->m_maxX, this->m_maxY));
+            this->m_map = NULL;
+        }
+        else if (NULL != this->m_tileset)
+        {
+            this->m_tileset->SetExtents(Box2D(this->m_minX, this->m_minY, this->m_maxX, this->m_maxY));
+            this->m_tileset;
+        }
         this->m_startElemName = L"";
         handlerStack->pop();
         delete this;

Modified: trunk/MgDev/Common/MdfParser/IOExtra.h
===================================================================
--- trunk/MgDev/Common/MdfParser/IOExtra.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOExtra.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -21,6 +21,7 @@
 #include "SAX2ElementHandler.h"
 #include "Box2D.h"
 #include "MapDefinition.h"
+#include "TileSetDefinition.h"
 #include "Version.h"
 
 using namespace XERCES_CPP_NAMESPACE;
@@ -33,6 +34,7 @@
     public:
         IOExtra(Version& version);
         IOExtra(MapDefinition* map, Version& version);
+        IOExtra(TileSetDefinition* map, Version& version);
         virtual ~IOExtra();
 
         virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);
@@ -47,6 +49,7 @@
         double m_minY;
         double m_maxY;
         MapDefinition* m_map;
+        TileSetDefinition* m_tileset;
 };
 
 END_NAMESPACE_MDFPARSER

Modified: trunk/MgDev/Common/MdfParser/IOMapDefinition.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/IOMapDefinition.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOMapDefinition.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -23,6 +23,7 @@
 #include "IOMapLayerGroup.h"
 #include "IOWatermarkInstance.h"
 #include "IOBaseMapDefinition.h"
+#include "IOTileSetSource.h"
 #include "IOUnknown.h"
 
 using namespace XERCES_CPP_NAMESPACE;
@@ -39,17 +40,18 @@
 ELEM_MAP_ENTRY(7, MapLayer);
 ELEM_MAP_ENTRY(8, MapLayerGroup);
 ELEM_MAP_ENTRY(9, BaseMapDefinition);
-ELEM_MAP_ENTRY(10, Watermarks);
-ELEM_MAP_ENTRY(11, Watermark);
-ELEM_MAP_ENTRY(12, ExtendedData1);
+ELEM_MAP_ENTRY(10, TileSetSource);
+ELEM_MAP_ENTRY(11, Watermarks);
+ELEM_MAP_ENTRY(12, Watermark);
+ELEM_MAP_ENTRY(13, ExtendedData1);
 
-IOMapDefinition::IOMapDefinition(Version& version) : SAX2ElementHandler(version)
+IOMapDefinition::IOMapDefinition(Version& version) : SAX2ElementHandler(version), m_bReadBaseMapDef(false)
 {
     this->m_map = NULL;
 }
 
 
-IOMapDefinition::IOMapDefinition(MapDefinition* map, Version& version) : SAX2ElementHandler(version)
+IOMapDefinition::IOMapDefinition(MapDefinition* map, Version& version) : SAX2ElementHandler(version), m_bReadBaseMapDef(false)
 {
     this->m_map = map;
 }
@@ -100,9 +102,23 @@
             IOBaseMapDefinition* IO = new IOBaseMapDefinition(this->m_map, this->m_version);
             handlerStack->push(IO);
             IO->StartElement(name, handlerStack);
+            this->m_map->SetTileSourceType(MapDefinition::Inline);
+            m_bReadBaseMapDef = true;
         }
         break;
 
+    case eTileSetSource:
+        {
+            if (!m_bReadBaseMapDef) //Only read this element if no BaseMapDefinition element was read
+            {
+                IOTileSetSource* IO = new IOTileSetSource(this->m_map->GetTileSetSource(), this->m_version);
+                handlerStack->push(IO);
+                IO->StartElement(name, handlerStack);
+                this->m_map->SetTileSourceType(MapDefinition::TileSetDefinition);
+            }
+        }
+        break;
+
     case eWatermark:
         {
             Version wdVersion;
@@ -170,7 +186,7 @@
 
 // Determine which WatermarkDefinition schema version to use based
 // on the supplied MapDefinition version:
-// * MDF version == 2.4.0  =>  WD version 2.4.0
+// * MDF version >= 2.4.0  =>  WD version 2.4.0
 // * MDF version <= 2.3.0  =>  WD version 2.3.0
 bool IOMapDefinition::GetWatermarkDefinitionVersion(Version* mdfVersion, Version& wdVersion)
 {
@@ -189,7 +205,7 @@
     MdfString strVersion;
     if (version)
     {
-        if ((*version >= Version(1, 0, 0)) && (*version <= Version(2, 4, 0)))
+        if ((*version >= Version(1, 0, 0)) && (*version <= Version(3, 0, 0)))
         {
             // MDF in MapGuide 2006 - current
             strVersion = version->ToString();
@@ -205,7 +221,7 @@
     else
     {
         // use the current highest version
-        strVersion = L"2.4.0";
+        strVersion = L"3.0.0";
     }
 
     if (!version || (*version > Version(1, 0, 0)))
@@ -248,9 +264,17 @@
     for (int i=0; i<map->GetLayerGroups()->GetCount(); ++i)
         IOMapLayerGroup::Write(fd, map->GetLayerGroups()->GetAt(i), version, tab);
 
-    // Property: BaseMapDefinition
-    if (map->GetFiniteDisplayScales()->GetCount() > 0)
-        IOBaseMapDefinition::Write(fd, map, version, tab);
+    if (map->GetTileSourceType() == MapDefinition::Inline)
+    {
+        // Property: BaseMapDefinition
+        if (map->GetFiniteDisplayScales()->GetCount() > 0)
+            IOBaseMapDefinition::Write(fd, map, version, tab);
+    }
+    else
+    {
+        // Property: TileSetSource
+        IOTileSetSource::Write(fd, map->GetTileSetSource(), version, tab);
+    }
 
     // Property: Watermarks (optional)
     int watermarkCount = map->GetWatermarks()->GetCount();

Modified: trunk/MgDev/Common/MdfParser/IOMapDefinition.h
===================================================================
--- trunk/MgDev/Common/MdfParser/IOMapDefinition.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOMapDefinition.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -43,6 +43,7 @@
     private:
         static bool GetWatermarkDefinitionVersion(Version* mdfVersion, Version& wdVersion);
         MapDefinition* m_map;
+        bool m_bReadBaseMapDef;
 };
 
 END_NAMESPACE_MDFPARSER

Modified: trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -27,6 +27,7 @@
 {
     this->m_layerGroup = NULL;
     this->m_map = NULL;
+    this->m_tileset = NULL;
 }
 
 
@@ -34,9 +35,18 @@
 {
     this->m_layerGroup = NULL;
     this->m_map = map;
+    this->m_tileset = NULL;
 }
 
 
+IOMapLayerGroupCommon::IOMapLayerGroupCommon(TileSetDefinition* tileset, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_layerGroup = NULL;
+    this->m_map = NULL;
+    this->m_tileset = tileset;
+}
+
+
 IOMapLayerGroupCommon::~IOMapLayerGroupCommon()
 {
 }

Modified: trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.h
===================================================================
--- trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IOMapLayerGroupCommon.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -21,6 +21,7 @@
 #include "SAX2ElementHandler.h"
 #include "MapLayerGroupCommon.h"
 #include "MapDefinition.h"
+#include "TileSetDefinition.h"
 #include "Version.h"
 
 using namespace XERCES_CPP_NAMESPACE;
@@ -35,6 +36,7 @@
 
     public:
         IOMapLayerGroupCommon(MapDefinition* map, Version& version);
+        IOMapLayerGroupCommon(TileSetDefinition* tileset, Version& version);
         virtual ~IOMapLayerGroupCommon();
 
         virtual void ElementChars(const wchar_t* ch);
@@ -44,6 +46,7 @@
     protected:
         MapLayerGroupCommon* m_layerGroup;
         MapDefinition* m_map;
+        TileSetDefinition* m_tileset;
 };
 
 END_NAMESPACE_MDFPARSER

Modified: trunk/MgDev/Common/MdfParser/IONameStringPair.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/IONameStringPair.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IONameStringPair.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -35,6 +35,7 @@
     this->m_nameStringPair = NULL;
     this->m_layer = NULL;
     this->m_overrides = NULL;
+    this->m_tileStoreParams = NULL;
 }
 
 
@@ -44,6 +45,7 @@
     this->m_nameStringPair = NULL;
     this->m_layer = layer;
     this->m_overrides = NULL;
+    this->m_tileStoreParams = NULL;
 }
 
 
@@ -53,9 +55,19 @@
     this->m_nameStringPair = NULL;
     this->m_layer = NULL;
     this->m_overrides = NULL;
+    this->m_tileStoreParams = NULL;
 }
 
+IONameStringPair::IONameStringPair(TileStoreParameters* params, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_featureSource = NULL;
+    this->m_nameStringPair = NULL;
+    this->m_layer = NULL;
+    this->m_overrides = NULL;
+    this->m_tileStoreParams = params;
+}
 
+
 IONameStringPair::~IONameStringPair()
 {
 }
@@ -82,7 +94,7 @@
             ParseUnknownXml(name, handlerStack);
         }
     }
-    else if (this->m_featureSource)
+    else if (this->m_featureSource || this->m_tileStoreParams)
     {
         if (this->m_currElemName == L"Parameter") // NOXLATE
         {
@@ -126,10 +138,13 @@
             this->m_layer->GetPropertyMappings()->Adopt(this->m_nameStringPair);
         else if (this->m_featureSource)
             this->m_featureSource->GetParameters()->Adopt(this->m_nameStringPair);
+        else if (this->m_tileStoreParams)
+            this->m_tileStoreParams->GetParameters()->Adopt(this->m_nameStringPair);
 
         this->m_layer = NULL;
         this->m_featureSource = NULL;
         this->m_nameStringPair = NULL;
+        this->m_tileStoreParams = NULL;
         this->m_startElemName = L"";
         handlerStack->pop();
         delete this;

Modified: trunk/MgDev/Common/MdfParser/IONameStringPair.h
===================================================================
--- trunk/MgDev/Common/MdfParser/IONameStringPair.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/IONameStringPair.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -22,6 +22,7 @@
 #include "NameStringPair.h"
 #include "VectorLayerDefinition.h"
 #include "FeatureSource.h"
+#include "TileStoreParameters.h"
 #include "Version.h"
 
 using namespace XERCES_CPP_NAMESPACE;
@@ -35,6 +36,7 @@
         IONameStringPair(Version& version);
         IONameStringPair(VectorLayerDefinition* layer, Version& version);
         IONameStringPair(FeatureSource* featureSource, Version& version);
+        IONameStringPair(TileStoreParameters* params, Version& version);
         virtual ~IONameStringPair();
 
         virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);
@@ -47,6 +49,7 @@
         NameStringPair* m_nameStringPair;
         VectorLayerDefinition* m_layer;
         FeatureSource* m_featureSource;
+        TileStoreParameters* m_tileStoreParams;
         NameStringPairCollection* m_overrides;
 };
 

Copied: trunk/MgDev/Common/MdfParser/IOTileSetDefinition.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.cpp)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileSetDefinition.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileSetDefinition.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,159 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "IOTileSetDefinition.h"
+#include "IOExtra.h"
+#include "IOTileStoreParameters.h"
+#include "IOBaseMapLayerGroup.h"
+#include "IOUnknown.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+using namespace MDFPARSER_NAMESPACE;
+
+CREATE_ELEMENT_MAP;
+ELEM_MAP_ENTRY(1, TileSetDefinition);
+ELEM_MAP_ENTRY(2, TileStoreParameters);
+ELEM_MAP_ENTRY(3, CoordinateSystem);
+ELEM_MAP_ENTRY(4, Extents);
+ELEM_MAP_ENTRY(5, FiniteDisplayScale);
+ELEM_MAP_ENTRY(6, BaseMapLayerGroup);
+ELEM_MAP_ENTRY(7, ExtendedData1);
+
+IOTileSetDefinition::IOTileSetDefinition(Version& version) : SAX2ElementHandler(version)
+{
+    this->m_tileset = NULL;
+}
+
+
+IOTileSetDefinition::IOTileSetDefinition(TileSetDefinition* tileset, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_tileset = tileset;
+}
+
+
+IOTileSetDefinition::~IOTileSetDefinition()
+{
+}
+
+
+void IOTileSetDefinition::StartElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    this->m_currElemName = name;
+    this->m_currElemId = _ElementIdFromName(name);
+
+    switch (this->m_currElemId)
+    {
+    case eTileSetDefinition:
+        this->m_startElemName = name;
+        break;
+
+    case eTileStoreParameters:
+        {
+            IOTileStoreParameters* IO = new IOTileStoreParameters(this->m_tileset->GetTileStoreParameters(), this->m_version);
+            handlerStack->push(IO);
+            IO->StartElement(name, handlerStack);
+        }
+        break;
+
+    case eExtents:
+        {
+            IOExtra* IO = new IOExtra(this->m_tileset, this->m_version);
+            handlerStack->push(IO);
+            IO->StartElement(name, handlerStack);
+        }
+        break;
+
+    case eBaseMapLayerGroup:
+        {
+            IOBaseMapLayerGroup* IO = new IOBaseMapLayerGroup(this->m_tileset, this->m_version);
+            handlerStack->push(IO);
+            IO->StartElement(name, handlerStack);
+        }
+        break;
+
+    case eExtendedData1:
+        this->m_procExtData = true;
+        break;
+
+    case eUnknown:
+        ParseUnknownXml(name, handlerStack);
+        break;
+    }
+}
+
+
+void IOTileSetDefinition::ElementChars(const wchar_t* ch)
+{
+
+}
+
+
+void IOTileSetDefinition::EndElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    if (this->m_startElemName == name)
+    {
+        this->m_tileset = NULL;
+        this->m_startElemName = L"";
+        handlerStack->pop();
+        delete this;
+    }
+}
+
+
+void IOTileSetDefinition::Write(MdfStream& fd, TileSetDefinition* tileset, Version* version, MgTab& tab)
+{
+    // verify the MDF version
+    MdfString strVersion;
+    if (version)
+    {
+        if (*version == Version(3, 0, 0))
+        {
+            strVersion = version->ToString();
+        }
+        else
+        {
+            // unsupported MDF version
+            // TODO - need a way to return error information
+            _ASSERT(false);
+            return;
+        }
+    }
+    else
+    {
+        // use the current highest version
+        strVersion = L"3.0.0";
+    }
+
+    fd << tab.tab() << "<TileSetDefinition xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"TileSetDefinition-" << EncodeString(strVersion) << ".xsd\" version=\"" << EncodeString(strVersion) << "\">" << std::endl; // NOXLATE
+    tab.inctab();
+
+    // Property: TileStoreParameters
+    IOTileStoreParameters::Write(fd, tileset->GetTileStoreParameters(), version, tab);
+
+    // Property: Extents
+    IOExtra::WriteBox2D(fd, tileset->GetExtents(), false, version, tab);
+
+    // Property: BaseMapLayerGroups
+    BaseMapLayerGroupCollection* baseMapGroups = tileset->GetBaseMapLayerGroups();
+    for (int i=0; i<baseMapGroups->GetCount(); ++i)
+        IOBaseMapLayerGroup::Write(fd, static_cast<BaseMapLayerGroup*>(baseMapGroups->GetAt(i)), version, tab);
+
+    tab.dectab();
+    fd << tab.tab() << "</TileSetDefinition>" << std::endl; // NOXLATE
+}

Copied: trunk/MgDev/Common/MdfParser/IOTileSetDefinition.h (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileSetDefinition.h)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileSetDefinition.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileSetDefinition.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,51 @@
+//
+//  Copyright (C) 2004-2014 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 _IOTILESETDEFINITION_H
+#define _IOTILESETDEFINITION_H
+
+#include "SAX2ElementHandler.h"
+#include "Version.h"
+#include "TileSetDefinition.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+
+BEGIN_NAMESPACE_MDFPARSER
+
+    class IOTileSetDefinition : public SAX2ElementHandler
+    {
+    private:
+        IOTileSetDefinition(Version& version);
+
+    public:
+        IOTileSetDefinition(TileSetDefinition* tileset, Version& version);
+        virtual ~IOTileSetDefinition();
+
+        virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);
+        virtual void ElementChars(const wchar_t* ch);
+        virtual void EndElement(const wchar_t* name, HandlerStack* handlerStack);
+
+        static void Write(MdfStream& fd, TileSetDefinition* tileset, Version* version, MgTab& tab);
+
+    private:
+        TileSetDefinition* m_tileset;
+    };
+
+END_NAMESPACE_MDFPARSER
+
+#endif //_IOTILESETDEFINITION_H
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfParser/IOTileSetSource.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileSetSource.cpp)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileSetSource.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileSetSource.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,79 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "IOTileSetSource.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+using namespace MDFPARSER_NAMESPACE;
+
+IOTileSetSource::IOTileSetSource(Version& version) : SAX2ElementHandler(version)
+{
+    this->m_source = NULL;
+}
+
+IOTileSetSource::IOTileSetSource(TileSetSource* source, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_source = source;
+}
+
+IOTileSetSource::~IOTileSetSource()
+{
+
+}
+
+void IOTileSetSource::StartElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    this->m_currElemName = name;
+    if (this->m_currElemName == L"TileSetSource") // NOXLATE
+    {
+        this->m_startElemName = name;
+    }
+}
+
+void IOTileSetSource::ElementChars(const wchar_t* ch)
+{
+    if (this->m_currElemName == L"ResourceId") // NOXLATE
+    {
+        this->m_source->SetResourceId(ch);
+    }
+}
+
+void IOTileSetSource::EndElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    if (this->m_startElemName == name)
+    {
+        this->m_source = NULL;
+        this->m_startElemName = L"";
+        handlerStack->pop();
+        delete this;
+    }
+}
+
+void IOTileSetSource::Write(MdfStream& fd, TileSetSource* source, Version* version, MgTab& tab)
+{
+    fd << tab.tab() << "<TileSetSource>" << std::endl; // NOXLATE
+    tab.inctab();
+
+    fd << tab.tab() << startStr("ResourceId"); //NOXLATE
+    fd << EncodeString(source->GetResourceId());
+    fd << endStr("ResourceId") << std::endl; //NOXLATE
+
+    tab.dectab();
+    fd << tab.tab() << "</TileSetSource>" << std::endl; // NOXLATE
+}
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfParser/IOTileSetSource.h (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileSetSource.h)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileSetSource.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileSetSource.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,51 @@
+//
+//  Copyright (C) 2004-2014 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 _IOTILESETSOURCE_H
+#define _IOTILESETSOURCE_H
+
+#include "SAX2ElementHandler.h"
+#include "Version.h"
+#include "TileSetSource.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+
+BEGIN_NAMESPACE_MDFPARSER
+
+    class IOTileSetSource : public SAX2ElementHandler
+    {
+    private:
+        IOTileSetSource(Version& version);
+
+    public:
+        IOTileSetSource(TileSetSource* source, Version& version);
+        virtual ~IOTileSetSource();
+
+        virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);
+        virtual void ElementChars(const wchar_t* ch);
+        virtual void EndElement(const wchar_t* name, HandlerStack* handlerStack);
+
+        static void Write(MdfStream& fd, TileSetSource* source, Version* version, MgTab& tab);
+
+    private:
+        TileSetSource* m_source;
+    };
+
+END_NAMESPACE_MDFPARSER
+
+#endif //_IOTILESETSOURCE_H
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfParser/IOTileStoreParameters.cpp (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.cpp)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileStoreParameters.cpp	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileStoreParameters.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,94 @@
+//
+//  Copyright (C) 2004-2014 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 "stdafx.h"
+#include "IOTileStoreParameters.h"
+#include "IONameStringPair.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+using namespace MDFPARSER_NAMESPACE;
+
+IOTileStoreParameters::IOTileStoreParameters(Version& version) : SAX2ElementHandler(version)
+{
+    this->m_params = NULL;
+}
+
+IOTileStoreParameters::IOTileStoreParameters(TileStoreParameters* params, Version& version) : SAX2ElementHandler(version)
+{
+    this->m_params = params;
+}
+
+IOTileStoreParameters::~IOTileStoreParameters()
+{
+
+}
+
+void IOTileStoreParameters::StartElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    this->m_currElemName = name;
+    if (this->m_currElemName == L"TileStoreParameters") // NOXLATE
+    {
+        this->m_startElemName = name;
+    }
+    else
+    {
+        if (this->m_currElemName == L"Parameter")
+        {
+            IONameStringPair* IO = new IONameStringPair(this->m_params, this->m_version);
+            handlerStack->push(IO);
+            IO->StartElement(name, handlerStack);
+        }
+    }
+}
+
+void IOTileStoreParameters::ElementChars(const wchar_t* ch)
+{
+    if (this->m_currElemName == L"TileProvider") // NOXLATE
+    {
+        this->m_params->SetTileProvider(ch);
+    }
+}
+
+void IOTileStoreParameters::EndElement(const wchar_t* name, HandlerStack* handlerStack)
+{
+    if (this->m_startElemName == name)
+    {
+        this->m_params = NULL;
+        this->m_startElemName = L"";
+        handlerStack->pop();
+        delete this;
+    }
+}
+
+void IOTileStoreParameters::Write(MdfStream& fd, TileStoreParameters* params, Version* version, MgTab& tab)
+{
+    fd << tab.tab() << "<TileStoreParameters>" << std::endl; // NOXLATE
+    tab.inctab();
+
+    // Property: TileProvider
+    fd << tab.tab() << startStr("TileProvider"); //NOXLATE
+    fd << EncodeString(params->GetTileProvider());
+    fd << endStr("TileProvider") << std::endl; //NOXLATE
+
+    // Property: Parameters
+    for (int i=0; i<params->GetParameters()->GetCount(); ++i)
+        IONameStringPair::Write(fd, "Parameter", params->GetParameters()->GetAt(i), version, tab); //NOXLATE
+
+    tab.dectab();
+    fd << tab.tab() << "</TileStoreParameters>" << std::endl; // NOXLATE
+}
\ No newline at end of file

Copied: trunk/MgDev/Common/MdfParser/IOTileStoreParameters.h (from rev 8208, sandbox/jng/tiling/Common/MdfParser/IOTileStoreParameters.h)
===================================================================
--- trunk/MgDev/Common/MdfParser/IOTileStoreParameters.h	                        (rev 0)
+++ trunk/MgDev/Common/MdfParser/IOTileStoreParameters.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,51 @@
+//
+//  Copyright (C) 2004-2014 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 _IOTILESTOREPARAMETERS_H
+#define _IOTILESTOREPARAMETERS_H
+
+#include "SAX2ElementHandler.h"
+#include "Version.h"
+#include "TileStoreParameters.h"
+
+using namespace XERCES_CPP_NAMESPACE;
+using namespace MDFMODEL_NAMESPACE;
+
+BEGIN_NAMESPACE_MDFPARSER
+
+    class IOTileStoreParameters : public SAX2ElementHandler
+    {
+    private:
+        IOTileStoreParameters(Version& version);
+
+    public:
+        IOTileStoreParameters(TileStoreParameters* params, Version& version);
+        virtual ~IOTileStoreParameters();
+
+        virtual void StartElement(const wchar_t* name, HandlerStack* handlerStack);
+        virtual void ElementChars(const wchar_t* ch);
+        virtual void EndElement(const wchar_t* name, HandlerStack* handlerStack);
+
+        static void Write(MdfStream& fd, TileStoreParameters* params, Version* version, MgTab& tab);
+
+    private:
+        TileStoreParameters* m_params;
+    };
+
+END_NAMESPACE_MDFPARSER
+
+#endif //_IOTILESTOREPARAMETERS_H
\ No newline at end of file

Modified: trunk/MgDev/Common/MdfParser/Makefile.am
===================================================================
--- trunk/MgDev/Common/MdfParser/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -102,6 +102,9 @@
   IOText.cpp \
   IOTextFrame.cpp \
   IOThemeLabel.cpp \
+  IOTileSetDefinition.cpp \
+  IOTileSetSource.cpp \
+  IOTileStoreParameters.cpp \
   IOTileWatermarkPosition.cpp \
   IOUnknown.cpp \
   IOURLData.cpp \
@@ -213,6 +216,9 @@
   IOText.h \
   IOTextFrame.h \
   IOThemeLabel.h \
+  IOTileSetDefinition.h \
+  IOTileSetSource.h \
+  IOTileStoreParameters.h \
   IOTileWatermarkPosition.h \
   IOUnknown.h \
   IOURLData.h \

Modified: trunk/MgDev/Common/MdfParser/MdfParser.vcxproj
===================================================================
--- trunk/MgDev/Common/MdfParser/MdfParser.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/MdfParser.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -201,6 +201,9 @@
     <ClCompile Include="Common\IOSize2D.cpp" />
     <ClCompile Include="Common\IOStringObjectCollection.cpp" />
     <ClCompile Include="Common\IOVector3D.cpp" />
+    <ClCompile Include="IOTileSetDefinition.cpp" />
+    <ClCompile Include="IOTileSetSource.cpp" />
+    <ClCompile Include="IOTileStoreParameters.cpp" />
     <ClCompile Include="IOURLData.cpp" />
     <ClCompile Include="IOProfileRenderLabelsResult.cpp" />
     <ClCompile Include="IOProfileRenderLayerResult.cpp" />
@@ -313,6 +316,9 @@
     <ClInclude Include="Common\IOSize2D.h" />
     <ClInclude Include="Common\IOStringObjectCollection.h" />
     <ClInclude Include="Common\IOVector3D.h" />
+    <ClInclude Include="IOTileSetDefinition.h" />
+    <ClInclude Include="IOTileSetSource.h" />
+    <ClInclude Include="IOTileStoreParameters.h" />
     <ClInclude Include="IOURLData.h" />
     <ClInclude Include="IOProfileRenderLabelsResult.h" />
     <ClInclude Include="IOProfileRenderLayerResult.h" />

Modified: trunk/MgDev/Common/MdfParser/MdfParser.vcxproj.filters
===================================================================
--- trunk/MgDev/Common/MdfParser/MdfParser.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/MdfParser.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -172,6 +172,9 @@
     <ClCompile Include="MdfParser.cpp" />
     <ClCompile Include="SAX2ElementHandler.cpp" />
     <ClCompile Include="SAX2Parser.cpp" />
+    <ClCompile Include="IOTileSetDefinition.cpp" />
+    <ClCompile Include="IOTileSetSource.cpp" />
+    <ClCompile Include="IOTileStoreParameters.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Common\IOColor.h">
@@ -334,6 +337,9 @@
     <ClInclude Include="SAX2ElementHandler.h" />
     <ClInclude Include="SAX2Parser.h" />
     <ClInclude Include="stdafx.h" />
+    <ClInclude Include="IOTileSetDefinition.h" />
+    <ClInclude Include="IOTileSetSource.h" />
+    <ClInclude Include="IOTileStoreParameters.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="MdfParser.rc" />

Modified: trunk/MgDev/Common/MdfParser/SAX2Parser.cpp
===================================================================
--- trunk/MgDev/Common/MdfParser/SAX2Parser.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/SAX2Parser.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -23,6 +23,7 @@
 #include "IOGridLayerDefinition.h"
 #include "IOSimpleSymbolDefinition.h"
 #include "IOCompoundSymbolDefinition.h"
+#include "IOTileSetDefinition.h"
 #include "UnicodeString.h"
 #include "PrintLayout/IOPrintLayoutDefinition.h"
 #include "PrintLayout/IOPrintLayoutElementDefinition.h"
@@ -266,7 +267,14 @@
     return ret;
 }
 
+TileSetDefinition* SAX2Parser::DetachTileSetDefinition()
+{
+    TileSetDefinition* ret = m_tileset;
+    m_tileset = NULL;
+    return ret;
+}
 
+
 bool SAX2Parser::GetSucceeded() const
 {
     return m_succeeded;
@@ -547,7 +555,17 @@
     return fd.str();
 }
 
+std::string SAX2Parser::SerializeToXML(TileSetDefinition* tileset, MdfModel::Version* version)
+{
+    MdfStringStream fd;
+    MgTab tab;
 
+    if (NULL != tileset)
+        IOTileSetDefinition::Write(fd, tileset, version, tab);
+
+    return fd.str();
+}
+
 void SAX2Parser::startElement(const XMLCh* const uri,
                               const XMLCh* const localname,
                               const XMLCh* const qname,
@@ -662,6 +680,17 @@
             m_handlerStack->push(IO);
             IO->StartElement(str.c_str(), m_handlerStack);
         }
+        else if (str == L"TileSetDefinition") // NOXLATE
+        {
+            // set the version
+            SetTileSetDefinitionVersion(attributes);
+
+            _ASSERT(m_map == NULL); // otherwise we leak
+            m_tileset = new TileSetDefinition();
+            IOTileSetDefinition* IO = new IOTileSetDefinition(m_tileset, m_version);
+            m_handlerStack->push(IO);
+            IO->StartElement(str.c_str(), m_handlerStack);
+        }
     }
     // Otherwise, if the stack has items on it, just pass the event through.
     else
@@ -889,7 +918,32 @@
     }
 }
 
+void SAX2Parser::SetTileSetDefinitionVersion(const Attributes& attributes)
+{
+    // Although right now we only have 3.0.0 here, this function is still
+    // needed for future expansion.
 
+    // check for a version attribute
+    int index = attributes.getIndex(W2X(L"version"));
+    const XMLCh* verValue = (index >= 0)? attributes.getValue(index) : NULL;
+
+    // according to the schema profile result elements require a version
+    // attribute, but users may generate XML which is missing this attribute
+    if (verValue)
+    {
+        std::wstring version = X2W(verValue);
+
+        if (_wcsicmp(version.c_str(), L"3.0.0") == 0)
+            m_version = MdfModel::Version(3, 0, 0);
+    }
+    else
+    {
+        // assume the latest version if the attribute is missing
+        m_version = MdfModel::Version(3, 0, 0);
+    }
+}
+
+
 MapDefinition* SAX2Parser::CreateClone(MapDefinition* map)
 {
     _ASSERT(NULL != map);
@@ -993,3 +1047,18 @@
 
     return parser.DetachProfileResult();
 }
+
+
+TileSetDefinition* SAX2Parser::CreateClone(TileSetDefinition* tileset)
+{
+    _ASSERT(NULL != tileset);
+    if (NULL == tileset)
+        return NULL;
+
+    SAX2Parser parser;
+    std::string xmlOfTD("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");   // NOXLATE
+    xmlOfTD.append(parser.SerializeToXML(tileset, NULL));
+    parser.ParseString(xmlOfTD.c_str(), xmlOfTD.size());
+
+    return parser.DetachTileSetDefinition();
+}

Modified: trunk/MgDev/Common/MdfParser/SAX2Parser.h
===================================================================
--- trunk/MgDev/Common/MdfParser/SAX2Parser.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/MdfParser/SAX2Parser.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -19,6 +19,7 @@
 #define _SAX2PARSER_H
 
 #include "MapDefinition.h"
+#include "TileSetDefinition.h"
 #include "VectorLayerDefinition.h"
 #include "DrawingLayerDefinition.h"
 #include "GridLayerDefinition.h"
@@ -95,6 +96,7 @@
         std::string SerializeToXML(PrintLayoutElementDefinition* printLayoutElem, MdfModel::Version* version);
         std::string SerializeToXML(WatermarkDefinition* watermark, MdfModel::Version* version);
         std::string SerializeToXML(ProfileResult* profileResult, MdfModel::Version* version);
+        std::string SerializeToXML(TileSetDefinition* tileset, MdfModel::Version* version);
 
         // Detaches the most recently parsed object from the parser.
         // The calling method is then responsible for disposing the object,
@@ -112,6 +114,7 @@
         MapViewportDefinition* DetachMapViewportDefinition();
         WatermarkDefinition* DetachWatermarkDefinition();
         ProfileResult* DetachProfileResult();
+        TileSetDefinition* DetachTileSetDefinition();
 
         // Creates a clone of the given map/layer/symbol/print layout/print layout element definition.
         // The object is serialized and parsed into a new object, which is returned.
@@ -122,6 +125,7 @@
         static PrintLayoutElementDefinition* CreateClone(PrintLayoutElementDefinition* printLayoutElem);
         static WatermarkDefinition* CreateClone(WatermarkDefinition* watermark);
         static ProfileResult* CreateClone(ProfileResult* profileResult);
+        static TileSetDefinition* CreateClone(TileSetDefinition* tileset);
 
         // Success State
         bool GetSucceeded() const;
@@ -162,6 +166,7 @@
         void SetPrintLayoutElementDefinitionVersion(const Attributes& attributes);
         void SetWatermarkDefinitionVersion(const Attributes& attributes);
         void SetProfileResultVersion(const Attributes& attributes);
+        void SetTileSetDefinitionVersion(const Attributes& attributes);
 
     protected:
         // The objects to be generated by the parser.
@@ -174,6 +179,7 @@
         PrintLayoutDefinition* m_printLayout;
         MapViewportDefinition* m_mapViewport;
         WatermarkDefinition* m_watermark;
+        TileSetDefinition* m_tileset;
         ProfileResult* m_profileResult;
 
         // Succeeded is true if the parse has succeeded. As of now,

Modified: trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.cpp
===================================================================
--- trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -26,6 +26,7 @@
     : m_type(MgLayerGroupType::Normal),
       m_name(L""),
       m_group((MgLayerGroup*)NULL),
+      m_tileSetId((MgResourceIdentifier*)NULL),
       m_visible(true),
       m_displayInLegend(false),
       m_expandInLegend(false),
@@ -52,7 +53,6 @@
     MgUtil::GenerateUuid(m_objectId);
 }
 
-
 //////////////////////////////////////////////////////////////
 // Returns the group name
 //
@@ -281,4 +281,4 @@
 void MgLayerGroup::SetContainer(MgLayerGroupCollection* cont)
 {
     m_groups = cont;
-}
+}
\ No newline at end of file

Modified: trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroup.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -522,6 +522,7 @@
     STRING              m_objectId;
     INT32               m_type;
     Ptr<MgLayerGroup>   m_group;
+    Ptr<MgResourceIdentifier> m_tileSetId;
     bool                m_visible;
     bool                m_displayInLegend;
     bool                m_expandInLegend;

Modified: trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroupType.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroupType.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/MapLayer/LayerGroupType.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -40,6 +40,16 @@
     /// it contains base map layers).
     ///
     static const INT32 BaseMap = 2;
+    /////////////////////////////////////////////////
+    /// \brief
+    /// Specifies that the layer is a base map layer from a TileSetDefinition resource.
+    ///
+    /// \remarks
+    /// From a client application perspective, a layer group with of this type should be treated
+    /// the same as layer group of type \link MgLayerGroupType::BaseMap BaseMap \endlink
+    ///
+    /// \since 3.0
+    static const INT32 BaseMapFromTileSet = 3;
 };
 /// \}
 

Modified: trunk/MgDev/Common/PlatformBase/MapLayer/MapBase.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/MapLayer/MapBase.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/MapLayer/MapBase.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -158,7 +158,9 @@
     /// Returns the resource identifier that specifies the location
     /// of the map definition that was used to create this map.
     ///
-    /// \note1
+    /// \remarks
+    /// If this map was created from a Tile Set Definition, this method
+    /// will return NULL
     ///
     /// <!-- Syntax in .Net, Java, and PHP -->
     /// \htmlinclude DotNetSyntaxTop.html
@@ -173,7 +175,8 @@
     ///
     /// \return
     /// Returns an MgResourceIdentifier that specifies the location
-    /// of the map definition.
+    /// of the map definition. NULL is returned if this map was created
+    /// from a Tile Set Definition
     ///
     virtual MgResourceIdentifier* GetMapDefinition();  /// __get
 

Modified: trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.cpp
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -54,6 +54,7 @@
 const STRING MgResourceType::PrintLayoutDefinition  = L"PrintLayoutDefinition";
 const STRING MgResourceType::PrintLayoutElementDefinition   = L"PrintLayoutElementDefinition";
 const STRING MgResourceType::WatermarkDefinition    = L"WatermarkDefinition";
+const STRING MgResourceType::TileSetDefinition      = L"TileSetDefinition";
 
 
 const STRING MgResourceType::User                   = L"User";
@@ -69,6 +70,7 @@
 const STRING MgResourceTag::Username                = L"%MG_USERNAME%";
 const STRING MgResourceTag::Password                = L"%MG_PASSWORD%";
 const STRING MgResourceTag::DataFilePath            = L"%MG_DATA_FILE_PATH%";
+const STRING MgResourceTag::TileCachePath           = L"%MG_TILE_CACHE_PATH%";
 const STRING MgResourceTag::DataPathAliasBegin      = L"%MG_DATA_PATH_ALIAS[";
 const STRING MgResourceTag::DataPathAliasEnd        = L"]%";
 

Modified: trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/Services/ResourceDefs.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -277,6 +277,17 @@
     ///
     static const STRING WatermarkDefinition;    ///\if INTERNAL value("WatermarkDefinition") \endif
 
+    ////////////////////////////////////////////////////////////////
+    /// \brief
+    /// This resource is a tile set definition.
+    ///
+    /// \remarks
+    /// It represents a tile cache that can be referenced by a Map Definition.
+    ///
+    /// \see \ref TileSetDefinition_schema "TileSetDefinition schema"
+    ///
+    static const STRING TileSetDefinition;      ///\if INTERNAL value("TileSetDefinition") \endif
+
 INTERNAL_API:
 
     ///////////////////////////////////////////////////////////////////////////
@@ -365,6 +376,13 @@
 
     ////////////////////////////////////////////////////////////////
     /// \brief
+    /// Replaced with the location of tile cache associated with the
+    /// given resource. The trailing "/" is included.
+    ///
+    static const STRING TileCachePath;  ///\if INTERNAL value("%MG_TILE_CACHE_PATH%") \endif
+
+    ////////////////////////////////////////////////////////////////
+    /// \brief
     /// Denotes beginning of data path alias.
     ///
     static const STRING DataPathAliasBegin;   ///\if INTERNAL value("%MG_DATA_PATH_ALIAS[") \endif

Modified: trunk/MgDev/Common/PlatformBase/Services/ResourceService.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/ResourceService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Common/PlatformBase/Services/ResourceService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1893,6 +1893,25 @@
     virtual MgSerializableCollection* EnumerateParentMapDefinitions(
         MgSerializableCollection* resources) = 0;
 
+    ///////////////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Enumerate all the parent Tile Set Definition resources of the specified
+    /// resources.
+    ///
+    /// This method only works on "Library" and "Session" repositories.
+    //
+    /// \param resources
+    /// Child resources.
+    ///
+    /// \return
+    /// MgResourceIdentifier list of Map Definition resources.
+    ///
+    /// \exception MgInvalidRepositoryTypeException
+    /// \exception MgInvalidResourceTypeException
+    ///
+    virtual MgSerializableCollection* EnumerateParentTileSetDefinitions(
+        MgSerializableCollection* resources) = 0;
+
     //////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns if permission has been granted for a resource
@@ -2040,6 +2059,7 @@
         opIdResourceExists                  = 0x1111EF1B,
         opIdEnumerateResourceDocuments      = 0x1111EF1C,
         opIdGetResourceContents             = 0x1111EF1D,
+        opIdEnumerateParentTileSetDefinitions = 0x1111EF1E,
     };
 };
 

Copied: trunk/MgDev/Common/Schema/MapDefinition-3.0.0.xsd (from rev 8208, sandbox/jng/tiling/Common/Schema/MapDefinition-3.0.0.xsd)
===================================================================
--- trunk/MgDev/Common/Schema/MapDefinition-3.0.0.xsd	                        (rev 0)
+++ trunk/MgDev/Common/Schema/MapDefinition-3.0.0.xsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="3.0.0">
+  <xs:include schemaLocation="WatermarkDefinition-2.4.0.xsd"/>
+  <xs:complexType name="Box2DType">
+    <xs:annotation>
+      <xs:documentation>Box2D encapsulates the the coordinates of a box in 2-D space</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="MinX" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Minimum x-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MaxX" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Maximum x-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MinY" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Minimum y-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MaxY" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Maximum y-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="MapLayerCommonType">
+    <xs:annotation>
+      <xs:documentation>MapLayerCommonType is a common superclass of MapLayerType and BaseMapLayerType.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Name of the MapLayer</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ResourceId" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>ResourceId of the MapLayer</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Selectable" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer can be selected</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ShowInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer should be shown in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Label to be shown for the Layer in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer should be expanded in the legend.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="MapLayerType">
+    <xs:annotation>
+      <xs:documentation>MapLayerType encapsulates the properties of a map layer, including its group and options about how it should be displayed.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="MapLayerCommonType">
+        <xs:sequence>
+          <xs:element name="Visible" type="xs:boolean">
+            <xs:annotation>
+              <xs:documentation>Whether this layer's visiblity should be visible or not when it first comes into range</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+          <xs:element name="Group" type="xs:string">
+            <xs:annotation>
+              <xs:documentation>Group of which the MapLayer is a member of</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+          <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="BaseMapLayerType">
+    <xs:annotation>
+      <xs:documentation>BaseMapLayerType encapsulates the properties of a BaseMapLayer.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="MapLayerCommonType">
+        <xs:sequence>
+          <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="MapLayerGroupCommonType">
+    <xs:annotation>
+      <xs:documentation>MapLayerGroupCommonType is a common superclass of MapLayerGroupType and BaseMapLayerGroupType.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of this LayerGroup</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Visible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether this group's visiblity should be visible or not when it first comes into range</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ShowInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the LayerGroup should be shown in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the LayerGroup should be initially expanded in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Label to be shown for the LayerGroup in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="MapLayerGroupType">
+    <xs:annotation>
+      <xs:documentation>MapLayerGroupType encapsulates the properties of a MapLayerGroup.  Its extension to MapLayerGroupCommonType is that the MapLayerGroup itself can also be in a MapLayerGroup.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="MapLayerGroupCommonType">
+        <xs:sequence>
+          <xs:element name="Group" type="xs:string">
+            <xs:annotation>
+              <xs:documentation>The group that contains the MapLayerGroup</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+          <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="BaseMapLayerGroupType">
+    <xs:annotation>
+      <xs:documentation>BaseMapLayerGroupType encapsulates the properties of a BaseMapLayerGroup.  It extends MapLayerGroupCommonType by holding the layers in the group.  The base map layer groups defines what layers are used to render a tile set in the HTML viewer.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="MapLayerGroupCommonType">
+        <xs:sequence>
+          <xs:element name="BaseMapLayer" type="BaseMapLayerType" minOccurs="0" maxOccurs="unbounded">
+            <xs:annotation>
+              <xs:documentation>The layers that are part of this group. The order of the layers represents the draw order, layers first is the list are drawn over top of layers later in the list.</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+          <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="MapDefinitionType">
+    <xs:annotation>
+      <xs:documentation>MapDefinitionType encapsulates a MapDefinition, which houses a collection of MapLayers and their groups.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="CoordinateSystem" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The coordinate system as WKT used by the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Extents" type="Box2DType">
+        <xs:annotation>
+          <xs:documentation>A bounding box around the area of the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="BackgroundColor" type="xs:hexBinary">
+        <xs:annotation>
+          <xs:documentation>The background color to be used with the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Metadata" type="xs:string" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>Metadata regarding the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MapLayer" type="MapLayerType" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Zero or more MapLayers that make up the MapDefinition. The order of the layers represents the draw order, layers first is the list are drawn over top of layers later in the list.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MapLayerGroup" type="MapLayerGroupType" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Zero or more MapLayerGroups that make up the MapDefinition</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="BaseMapDefinition" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>The base map.</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="FiniteDisplayScale" type="xs:double" maxOccurs="unbounded">
+              <xs:annotation>
+                <xs:documentation>The display scales that the base map layers will have tiles available. Applies to the HTML viewer.</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+            <xs:element name="BaseMapLayerGroup" type="BaseMapLayerGroupType" minOccurs="0" maxOccurs="unbounded">
+              <xs:annotation>
+                <xs:documentation>A group of layers that is used to compose a tiled layer in the HTML viewer</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="TileSetSource" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>A reference to the tile set source to use</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="ResourceId" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>ResourceId of the TileSetDefinition</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="Watermarks" type="WatermarkInstanceCollectionType" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>The collection of watermarks used in the map.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:element name="MapDefinition">
+    <xs:annotation>
+      <xs:documentation>A MapDefinition defines the collection of layers, groupings of layers, and base map</xs:documentation>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:complexContent>
+        <xs:extension base="MapDefinitionType">
+          <xs:attribute name="version" type="xs:string" use="required" fixed="3.0.0"/>
+        </xs:extension>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>

Copied: trunk/MgDev/Common/Schema/RuntimeMap-3.0.0.xsd (from rev 8208, sandbox/jng/tiling/Common/Schema/RuntimeMap-3.0.0.xsd)
===================================================================
--- trunk/MgDev/Common/Schema/RuntimeMap-3.0.0.xsd	                        (rev 0)
+++ trunk/MgDev/Common/Schema/RuntimeMap-3.0.0.xsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="RuntimeMap">
+    <xs:annotation>
+      <xs:documentation>Describes information about a Runtime Map, so that client applications can interact with it</xs:documentation>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="SiteVersion" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The MapGuide Site Version</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="Name" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The name of the runtime map. This is the value required for any mapagent operation that require a MAPNAME parameter</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="MapDefinition" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The resource id of the Map Definition from which this runtime map was created from</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="TileSetDefinition" type="xs:string" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>The resource id of the Tile Set Definition that this Map Definition is linked from. If this Map Definition does not link to a tile set, this element is omitted</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="TileWidth" type="xs:string" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>The tile width as defined by the settings in the Tile Set Definition. If this Map Definition does not link to a tile set, this element is omitted</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="TileHeight" type="xs:string" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>The tile height as defined by the settings in the Tile Set Definition. If this Map Definition does not link to a tile set, this element is omitted</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="BackgroundColor" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The map's background color in ARGB hex string format</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="DisplayDpi" type="xs:integer">
+          <xs:annotation>
+            <xs:documentation>The number of dots per inch of the map display</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="IconMimeType" type="xs:string" minOccurs="0">
+          <xs:annotation>
+            <xs:documentation>The mime type of all inline icons</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="CoordinateSystem" type="CoordinateSystemType" />
+        <xs:element name="Extents" type="Envelope" />
+        <xs:element name="Group" type="RuntimeMapGroup" minOccurs="0" maxOccurs="unbounded" />
+        <xs:element name="Layer" type="RuntimeMapLayer" minOccurs="0" maxOccurs="unbounded" />
+        <xs:element name="FiniteDisplayScale" type="xs:double" minOccurs="0" maxOccurs="unbounded" />
+        <xs:attribute name="version" type="xs:string" use="required" fixed="3.0.0"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:complexType name="CoordinateSystemType">
+    <xs:annotation>
+      <xs:documentation>Describes the coordinate system of the runtime map</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Wkt" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The WKT string of the coordinate system</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MentorCode" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The CS-Map code of the coordinate system</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="EpsgCode" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The EPSG code of the coordinate system</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MetersPerUnit" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>The meters-per-unit value of the coordinate system</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="RuntimeMapGroup">
+    <xs:annotation>
+      <xs:documentation>Describes a group of Runtime Map Layers</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of the group</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Type" type="xs:integer">
+        <xs:annotation>
+          <xs:documentation>The type of this group. Can be tiled or dynamic. Uses the value of MgLayerGroupType</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The group's legend label</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ObjectId" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The group's unique id. Use this value for turning on/off this group in a GETDYNAMICMAPOVERLAYIMAGE request</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ParentId" type="xs:string" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>The group's parent group id. Use this value for determining parent-child relationships when building a layer/group hierarchy</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="DisplayInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this group should be displayed in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this group should be initially expanded in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Visible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this group is potentially visible. Note that this may be true even though the group is not visible. This will occur if one of the groups this group is organized within is not visible.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ActuallyVisible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates the actual visibility of the group. The visibility depends on the visible property of the group, and the visible property of each group this group is organized within.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="RuntimeMapLayer">
+    <xs:annotation>
+      <xs:documentation>Describes a runtime instance of a Layer Definition</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of the layer</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Type" type="xs:integer">
+        <xs:annotation>
+          <xs:documentation>The type of this layer. Can be tiled or dynamic. Uses the value of MgLayerType</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The layer's legend label</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ObjectId" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The layer's unique id. Use this value for turning on/off this layer in a GETDYNAMICMAPOVERLAYIMAGE request</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ParentId" type="xs:string" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>The layer's parent group id. Use this value for determining parent-child relationships when building a layer/group hierarchy</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="DisplayInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this layer should be displayed in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this layer should be initially expanded (if layer is themed) in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Visible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates whether this layer is potentially visible. Note that this may be true even though the layer is not visible. This will occur if the visible flag of one of the groups this layer is organized within is not visible or when the current viewScale property of the map is outside the scale ranges defined for this layer.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ActuallyVisible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Indicates the actual visibility of the layer. The visibility depends on the visible property of the group, and the visible property of each group this group is organized within.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LayerDefinition" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The Layer Definition from which this runtime layer was created from</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="FeatureSource" type="FeatureSourceInfo" minOccurs="0" />
+      <xs:element name="ScaleRange" type="ScaleRangeInfo" minOccurs="0" maxOccurs="unbounded" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="FeatureSourceInfo">
+    <xs:annotation>
+      <xs:documentation>Describe the Feature Source information for a runtime layer</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="ResourceId" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The Feature Source resource id</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ClassName" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The qualified FDO class name</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Geometry" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of the default Geometry property</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="ScaleRangeInfo">
+    <xs:annotation>
+      <xs:documentation>Describes a scale range of the runtime layer</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="MinScale" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>The minimum scale of this scale range</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MaxScale" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>The maximum scale of this scale range</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="FeatureStyle" type="FeatureStyleInfo" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>The feature style for a given geometry type.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="FeatureStyleInfo">
+    <xs:annotation>
+      <xs:documentation>Defines the style rules for a given geometry type</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Type" type="xs:integer">
+        <xs:annotation>
+          <xs:documentation>The geometry type that this rule is applicable to (1=point, 2=line, 3=area, 4=composite)</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Rule" type="RuleInfo" minOccurs="0" maxOccurs="unbounded" />
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="RuleInfo">
+    <xs:annotation>
+      <xs:documentation>Describes a stylization rule in a layer's scale range</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The legend label for this rule</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Filter" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The FDO filter that features must match in order for them to be stylized using this particular rule</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Icon" type="xs:string" minOccurs="0">
+        <xs:annotation>
+          <xs:documentation>Defines the icon for this rule. The icon's image content is in base64 format</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="Envelope">
+    <xs:annotation>
+      <xs:documentation>Specifies an envelope (a rectangle) using two corner points.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="LowerLeftCoordinate">
+        <xs:annotation>
+          <xs:documentation>Specifies the lower left corner of the envelope.</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="X" type="xs:string"/>
+            <xs:element name="Y" type="xs:string"/>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="UpperRightCoordinate">
+        <xs:annotation>
+          <xs:documentation>Specifies the upper right corner of the envelope.</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="X" type="xs:string"/>
+            <xs:element name="Y" type="xs:string"/>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>
\ No newline at end of file

Copied: trunk/MgDev/Common/Schema/TileProviderList-3.0.0.xsd (from rev 8208, sandbox/jng/tiling/Common/Schema/TileProviderList-3.0.0.xsd)
===================================================================
--- trunk/MgDev/Common/Schema/TileProviderList-3.0.0.xsd	                        (rev 0)
+++ trunk/MgDev/Common/Schema/TileProviderList-3.0.0.xsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="TileProviderList" type="TileProviderList">
+    <xs:annotation>
+      <xs:documentation>Root element that contains a collection of TileProvider elements.</xs:documentation>
+    </xs:annotation>
+  </xs:element>
+  <xs:complexType name="TileProviderList">
+    <xs:sequence>
+      <xs:element name="TileProvider" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Describes an installed tile provider.</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="Name" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>Unique name of the feature provider. This name should be of the form <Company>.<Provider>.lt;Version>.</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+            <xs:element name="DisplayName" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A user friendly display name of the feature provider.</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+            <xs:element name="Description" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A brief description of the feature provider.</xs:documentation>
+              </xs:annotation>
+            </xs:element>
+            <xs:element name="ConnectionProperties">
+              <xs:annotation>
+                <xs:documentation>Connection properties for each provider with default values will be listed here.</xs:documentation>
+              </xs:annotation>
+              <xs:complexType>
+                <xs:sequence minOccurs="0" maxOccurs="unbounded">
+                  <xs:element name="ConnectionProperty" minOccurs="0" maxOccurs="unbounded">
+                    <xs:complexType>
+                      <xs:sequence>
+                        <xs:element name="Name" type="xs:string">
+                          <xs:annotation>
+                            <xs:documentation>Name of the property retrieved from Fdo Provider</xs:documentation>
+                          </xs:annotation>
+                        </xs:element>
+                        <xs:element name="LocalizedName" type="xs:string" minOccurs="0">
+                          <xs:annotation>
+                            <xs:documentation>Properties can have localized names for displaying them in UI. Provider will inform us what that string should be.</xs:documentation>
+                          </xs:annotation>
+                        </xs:element>
+                        <xs:element name="DefaultValue" type="xs:string" minOccurs="0">
+                          <xs:annotation>
+                            <xs:documentation>This is a default value. This will be one of the values listed in  Value element</xs:documentation>
+                          </xs:annotation>
+                        </xs:element>
+                        <xs:element name="Value" type="xs:string" minOccurs="0" maxOccurs="unbounded">
+                          <xs:annotation>
+                            <xs:documentation>A property can have more than one alternative values to choose from. All possible values will be listed here.</xs:documentation>
+                          </xs:annotation>
+                        </xs:element>
+                      </xs:sequence>
+                      <xs:attribute name="Required" type="xs:boolean" use="required"/>
+                      <xs:attribute name="Protected" type="xs:boolean" use="required"/>
+                      <xs:attribute name="Enumerable" type="xs:boolean" use="required"/>
+                    </xs:complexType>
+                  </xs:element>
+                </xs:sequence>
+              </xs:complexType>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>

Copied: trunk/MgDev/Common/Schema/TileSetDefinition-3.0.0.xsd (from rev 8208, sandbox/jng/tiling/Common/Schema/TileSetDefinition-3.0.0.xsd)
===================================================================
--- trunk/MgDev/Common/Schema/TileSetDefinition-3.0.0.xsd	                        (rev 0)
+++ trunk/MgDev/Common/Schema/TileSetDefinition-3.0.0.xsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:include schemaLocation="PlatformCommon-1.0.0.xsd"/>
+  <xs:element name="TileSetDefinition">
+    <xs:annotation>
+      <xs:documentation>Defines a tile cache</xs:documentation>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="TileStoreParameters" type="TileStoreParametersType">
+           <xs:annotation>
+            <xs:documentation>Defines the parameters to access and describe the tile cache</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="Extents" type="Box2DType">
+          <xs:annotation>
+            <xs:documentation>A bounding box around the area of the tile cache</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element name="BaseMapLayerGroup" type="BaseMapLayerGroupCommonType" minOccurs="1" maxOccurs="unbounded">
+          <xs:annotation>
+            <xs:documentation>A group of layers that is used to compose a tiled layer in the HTML viewer</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:complexType name="TileStoreParametersType">
+    <xs:annotation>
+      <xs:documentation>TileStoreParameters defines the parameters of this tile cache.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="TileProvider" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The tile image provider</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Parameter" type="NameValuePairType" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Collection of name value pairs for connecting to the tile image provider</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="NameValuePairType">
+    <xs:annotation>
+      <xs:documentation>A type describing name and value pairs</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Text for the name of parameter</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Value" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Text for value of parameter</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExtendedData1" type="ExtendedDataType" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="Box2DType">
+    <xs:annotation>
+      <xs:documentation>Box2D encapsulates the the coordinates of a box in 2-D space</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="MinX" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Minimum x-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MaxX" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Maximum x-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MinY" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Minimum y-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="MaxY" type="xs:double">
+        <xs:annotation>
+          <xs:documentation>Maximum y-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="BaseMapLayerType">
+    <xs:annotation>
+      <xs:documentation>BaseMapLayerType encapsulates the properties of a BaseMapLayer.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Name of the MapLayer</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ResourceId" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>ResourceId of the MapLayer</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Selectable" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer can be selected</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ShowInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer should be shown in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Label to be shown for the Layer in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the Layer should be expanded in the legend.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="MapLayerGroupCommonType">
+    <xs:annotation>
+      <xs:documentation>MapLayerGroupCommonType is a common subclass of MapLayerGroupCommonType and BaseMapLayerGroupCommonType</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="Name" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The name of this LayerGroup</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Visible" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether this group's visiblity should be visible or not when it first comes into range</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ShowInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the LayerGroup should be shown in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="ExpandInLegend" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>Whether or not the LayerGroup should be initially expanded in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="LegendLabel" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Label to be shown for the LayerGroup in the legend</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="BaseMapLayerGroupCommonType">
+    <xs:annotation>
+      <xs:documentation>BaseMapLayerGroupCommonType encapsulates the properties of a BaseMapLayerGroup. It extends MapLayerGroupCommonType by holding the layers in the group.  The base map layer groups defines what layers are used to render a tile set in the HTML viewer.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="MapLayerGroupCommonType">
+        <xs:sequence>
+          <xs:element name="BaseMapLayer" type="BaseMapLayerType" minOccurs="0" maxOccurs="unbounded">
+            <xs:annotation>
+              <xs:documentation>The layers that are part of this group. The order of the layers represents the draw order, layers first is the list are drawn over top of layers later in the list.</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+        </xs:sequence>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+</xs:schema>
\ No newline at end of file

Modified: trunk/MgDev/Doc/samples/ol2samples/tiled/index.html
===================================================================
--- trunk/MgDev/Doc/samples/ol2samples/tiled/index.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Doc/samples/ol2samples/tiled/index.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -44,7 +44,7 @@
         function createMap(reqFeatures) {
             $.getJSON(mapAgentUrl, {
                 "OPERATION": "CREATERUNTIMEMAP",
-                "VERSION": "2.6.0",
+                "VERSION": "3.0.0",
                 "MAPDEFINITION": "Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition",
                 "USERNAME": "Anonymous", //Or you can use "SESSION": "<my session id>"
                 "REQUESTEDFEATURES": reqFeatures,
@@ -152,6 +152,18 @@
                     });
                     map.addLayer(layer);
                     tiledLayers[group.Name[0]] = layer;
+                } else if (group.Type[0] == "3") { //MgLayerGroupType.BaseMapFromTileSet
+                    var layer = new OpenLayers.Layer.MapGuide("MapGuide base layer group via CREATERUNTIMEMAP: " + group.Name[0], mapAgentUrl + "?USERNAME=Anonymous", {
+                        mapdefinition: rtMapInfo.RuntimeMap.TileSetDefinition[0],
+                        basemaplayergroupname: group.Name[0]
+                    }, {
+                        singleTile: false,
+                        defaultSize: new OpenLayers.Size(
+                            parseInt(rtMapInfo.RuntimeMap.TileWidth[0]),
+                            parseInt(rtMapInfo.RuntimeMap.TileHeight[0]))
+                    });
+                    map.addLayer(layer);
+                    tiledLayers[group.Name[0]] = layer;
                 }
             }
             map.zoomToMaxExtent();

Modified: trunk/MgDev/Doc/samples/ol2samples/xyz/index.html
===================================================================
--- sandbox/jng/tiling/Doc/samples/ol2samples/xyz/index.html	2014-06-14 15:40:30 UTC (rev 8208)
+++ trunk/MgDev/Doc/samples/ol2samples/xyz/index.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -29,7 +29,7 @@
                 ]
             });
             var layer = new OpenLayers.Layer.XYZ( "XYZ Layer From MapGuide",
-                    "../../mapagent/mapagent.fcgi?OPERATION=GETTILEIMAGE&VERSION=1.2.0&CLIENTAGENT=OpenLayers&MAPDEFINITION=Library://Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition&BASEMAPLAYERGROUPNAME=Base+Layer+Group&TILECOL=${y}&TILEROW=${x}&SCALEINDEX=${z}",
+                    "../../mapagent/mapagent.fcgi?OPERATION=GETTILEIMAGE&VERSION=1.2.0&CLIENTAGENT=OpenLayers&USERNAME=Anonymous&MAPDEFINITION=Library://Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition&BASEMAPLAYERGROUPNAME=Base+Layer+Group&TILECOL=${y}&TILEROW=${x}&SCALEINDEX=${z}",
                     {sphericalMercator: true} );
             map.addLayer(layer);
             map.zoomToExtent(map.restrictedExtent);

Modified: trunk/MgDev/Doc/samples/samples.php
===================================================================
--- trunk/MgDev/Doc/samples/samples.php	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Doc/samples/samples.php	2014-08-12 11:11:22 UTC (rev 8330)
@@ -119,9 +119,10 @@
                     <li><a href="ol2samples/selection/index.html">Basic Sheboygan un-tiled map example with selection</a></li>
                     <li><a href="ol2samples/mixed/index.html">Basic Sheboygan mixed map (tiled and untiled) example</a></li>
                     <li><a href="ol2samples/commercial/index.html">Sheboygan map with Google/OSM layers</a></li>
+                    <li><a href="ol2samples/xyz/index.html">Sheboygan map as XYZ layer</a></li>
                 </ul>
                 <? } ?>
             <? } ?>
         </div>
     </body>
-</html>
\ No newline at end of file
+</html>

Modified: trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -502,6 +502,8 @@
             {
                 affectedResources = resourceService->EnumerateParentMapDefinitions(changedResources);
                 tileService->NotifyResourcesChanged(affectedResources, false);
+                affectedResources = resourceService->EnumerateParentTileSetDefinitions(changedResources);
+                tileService->NotifyResourcesChanged(affectedResources, false);
             }
 
             // Dispatch resource change notifications to support servers.

Modified: trunk/MgDev/Server/src/Core/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Core/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Core/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -267,6 +267,9 @@
 	@cp -f ../../../UnitTest/TestData/Symbology/UT_Annotation3.ldf ../UnitTestFiles
 	@cp -f ../../../UnitTest/TestData/Symbology/UT_Annotation3.mdf ../UnitTestFiles
 	@cp -f ../../../UnitTest/TestData/TileService/UT_BaseMap.mdf ../UnitTestFiles
+	@cp -f ../../../UnitTest/TestData/TileService/UT_BaseMap.tsd ../UnitTestFiles
+	@cp -f ../../../UnitTest/TestData/TileService/UT_XYZ.tsd ../UnitTestFiles
+	@cp -f ../../../UnitTest/TestData/TileService/UT_LinkedTileSet.mdf ../UnitTestFiles
 	@cp -f ../../../UnitTest/TestData/TileService/UT_StylizationFuncs.mdf ../UnitTestFiles
 	@cp -f ../../../UnitTest/TestData/TileService/UT_Parcels.fs ../UnitTestFiles
 	@cp -f ../../../UnitTest/TestData/TileService/UT_Parcels.ldf ../UnitTestFiles

Modified: trunk/MgDev/Server/src/PostBuild/PostBuild.mak
===================================================================
--- trunk/MgDev/Server/src/PostBuild/PostBuild.mak	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/PostBuild/PostBuild.mak	2014-08-12 11:11:22 UTC (rev 8330)
@@ -164,6 +164,9 @@
         ..\..\bin\UnitTestFiles\TEST.FeatureSource \
         ..\..\bin\UnitTestFiles\TEST.sdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+        ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
         ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -433,6 +436,9 @@
         ..\..\bin\UnitTestFiles\TEST.FeatureSource \
         ..\..\bin\UnitTestFiles\TEST.sdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+        ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
         ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -702,6 +708,9 @@
           ..\..\bin\UnitTestFiles\TEST.FeatureSource \
           ..\..\bin\UnitTestFiles\TEST.sdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+          ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
           ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -971,6 +980,9 @@
           ..\..\bin\UnitTestFiles\TEST.FeatureSource \
           ..\..\bin\UnitTestFiles\TEST.sdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+          ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
           ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -1113,6 +1125,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -1205,7 +1220,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource        del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
     del /F   ..\..\bin\debug\*.ilk
@@ -1250,6 +1265,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -1342,7 +1360,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource       del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
     del /F   ..\..\bin\debug64\*.ilk
@@ -1387,6 +1405,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -1522,6 +1543,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                     del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -1614,7 +1638,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource       del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
 
@@ -1784,6 +1808,9 @@
         ..\..\bin\UnitTestFiles\TEST.FeatureSource \
         ..\..\bin\UnitTestFiles\TEST.sdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+        ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
         ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -2046,6 +2073,9 @@
         ..\..\bin\UnitTestFiles\TEST.FeatureSource \
         ..\..\bin\UnitTestFiles\TEST.sdf \
         ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+        ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+        ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+        ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
         ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
         ..\..\bin\UnitTestFiles\UT_Parcels.fs \
         ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -2308,6 +2338,9 @@
           ..\..\bin\UnitTestFiles\TEST.FeatureSource \
           ..\..\bin\UnitTestFiles\TEST.sdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+          ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
           ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -2570,6 +2603,9 @@
           ..\..\bin\UnitTestFiles\TEST.FeatureSource \
           ..\..\bin\UnitTestFiles\TEST.sdf \
           ..\..\bin\UnitTestFiles\UT_BaseMap.mdf \
+          ..\..\bin\UnitTestFiles\UT_BaseMap.tsd \
+          ..\..\bin\UnitTestFiles\UT_XYZ.tsd \
+          ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf \
           ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf \
           ..\..\bin\UnitTestFiles\UT_Parcels.fs \
           ..\..\bin\UnitTestFiles\UT_Parcels.ldf \
@@ -2705,6 +2741,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -2790,7 +2829,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource        del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
     del /F   ..\..\bin\debug(v100)\*.ilk
@@ -2835,6 +2874,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -2920,7 +2962,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource        del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
     del /F   ..\..\bin\debug(v100)64\*.ilk
@@ -2965,6 +3007,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -3093,6 +3138,9 @@
     if EXIST ..\..\bin\UnitTestFiles\TEST.FeatureSource             del /F ..\..\bin\UnitTestFiles\TEST.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\TEST.sdf                       del /F ..\..\bin\UnitTestFiles\TEST.sdf
     if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.mdf                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.mdf
+    if EXIST ..\..\bin\UnitTestFiles\UT_BaseMap.tsd                 del /F ..\..\bin\UnitTestFiles\UT_BaseMap.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_XYZ.tsd                        del /F ..\..\bin\UnitTestFiles\UT_XYZ.tsd
+    if EXIST ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf           del /F ..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf        del /F ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.fs                  del /F ..\..\bin\UnitTestFiles\UT_Parcels.fs
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels.ldf                 del /F ..\..\bin\UnitTestFiles\UT_Parcels.ldf
@@ -3178,7 +3226,7 @@
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.sqlite           del /F ..\..\bin\UnitTestFiles\SavePointTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource    del /F ..\..\bin\UnitTestFiles\SavePointTest.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource    del /F ..\..\bin\UnitTestFiles\UT_Parcels_SQLite_Join.FeatureSource
-    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource		del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
+    if EXIST ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource        del /F ..\..\bin\UnitTestFiles\UT_FdoJoin.FeatureSource
     if EXIST ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite         del /F ..\..\bin\UnitTestFiles\ParcelsJoinTest.sqlite
     if EXIST ..\..\bin\UnitTestFiles\JoinTest.sqlite                del /F ..\..\bin\UnitTestFiles\JoinTest.FeatureSource
 
@@ -3228,6 +3276,9 @@
 "..\..\..\UnitTestFiles\UT_SingleFTSMultiCTS.ldf" :
 "..\..\..\UnitTest\TestData\MappingService\UT_RotatedPointStyles.ldf" :
 "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.mdf" :
+"..\..\..\UnitTest\TestData\TileService\UT_BaseMap.tsd" :
+"..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" :
+"..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" :
 "..\..\..\UnitTest\TestData\TileService\UT_StylizationFuncs.mdf" :
 "..\..\..\UnitTest\TestData\TileService\UT_Parcels.fs" :
 "..\..\..\UnitTest\TestData\TileService\UT_Parcels.ldf" :
@@ -3467,6 +3518,18 @@
     if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
     if EXIST "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.mdf" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.mdf" ..\..\bin\UnitTestFiles\
 
+..\..\bin\UnitTestFiles\UT_BaseMap.tsd : "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.tsd"
+    if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
+    if EXIST "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.tsd" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_BaseMap.tsd" ..\..\bin\UnitTestFiles\
+
+..\..\bin\UnitTestFiles\UT_XYZ.tsd : "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd"
+    if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
+    if EXIST "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_XYZ.tsd" ..\..\bin\UnitTestFiles\
+
+..\..\bin\UnitTestFiles\UT_LinkedTileSet.mdf : "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf"
+    if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
+    if EXIST "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_LinkedTileSet.mdf" ..\..\bin\UnitTestFiles\
+
 ..\..\bin\UnitTestFiles\UT_StylizationFuncs.mdf : "..\..\..\UnitTest\TestData\TileService\UT_StylizationFuncs.mdf"
     if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
     if EXIST "..\..\..\UnitTest\TestData\TileService\UT_StylizationFuncs.mdf" xcopy /r /d /y "..\..\..\UnitTest\TestData\TileService\UT_StylizationFuncs.mdf" ..\..\bin\UnitTestFiles\
@@ -3689,4 +3752,4 @@
 
 ..\..\bin\UnitTestFiles\JoinTest.sqlite : "..\..\..\UnitTest\TestData\FeatureService\SQLite\JoinTest.sqlite"
     if NOT EXIST ..\..\bin\UnitTestFiles\nul mkdir ..\..\bin\UnitTestFiles
-    if EXIST "..\..\..\UnitTest\TestData\FeatureService\SQLite\JoinTest.sqlite" xcopy /r /d /y "..\..\..\UnitTest\TestData\FeatureService\SQLite\JoinTest.sqlite" ..\..\bin\UnitTestFiles\
\ No newline at end of file
+    if EXIST "..\..\..\UnitTest\TestData\FeatureService\SQLite\JoinTest.sqlite" xcopy /r /d /y "..\..\..\UnitTest\TestData\FeatureService\SQLite\JoinTest.sqlite" ..\..\bin\UnitTestFiles\

Modified: trunk/MgDev/Server/src/Services/Mapping/MappingOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/MappingOperationFactory.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Mapping/MappingOperationFactory.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -75,7 +75,7 @@
     MG_TRY()
     switch (operationId)
     {
-    case MgMappingService::opIdGeneratePlot:
+    case MgMappingServiceOpId::GeneratePlot:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -87,7 +87,7 @@
         }
         break;
 
-    case MgMappingService::opIdGeneratePlot2:
+    case MgMappingServiceOpId::GeneratePlot2:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -99,7 +99,7 @@
         }
         break;
 
-    case MgMappingService::opIdGeneratePlot3:
+    case MgMappingServiceOpId::GeneratePlot3:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -111,7 +111,7 @@
         }
         break;
 
-    case MgMappingService::opIdGenerateMultiPlot:
+    case MgMappingServiceOpId::GenerateMultiPlot:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -123,7 +123,7 @@
         }
         break;
 
-    case MgMappingService::opIdGenerateLegendPlot:
+    case MgMappingServiceOpId::GenerateLegendPlot:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -135,7 +135,7 @@
         }
         break;
 
-    case MgMappingService::opIdGenerateLegendImage:
+    case MgMappingServiceOpId::GenerateLegendImage:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -147,7 +147,7 @@
         }
         break;
 
-    case MgMappingService::opIdQueryFeatures:
+    case MgMappingServiceOpId::QueryFeatures:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -159,7 +159,7 @@
         }
         break;
 
-    case MgMappingService::opIdQueryFeaturesWms:
+    case MgMappingServiceOpId::QueryFeatures2:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(1,0):
@@ -171,7 +171,7 @@
         }
         break;
 
-    case MgMappingService::opIdCreateRuntimeMap:
+    case MgMappingServiceOpId::CreateRuntimeMap:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(2,6):
@@ -183,7 +183,7 @@
         }
         break;
 
-    case MgMappingService::opIdCreateRuntimeMap2:
+    case MgMappingServiceOpId::CreateRuntimeMap2:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(2,6):
@@ -195,9 +195,21 @@
         }
         break;
 
-    case MgMappingService::opIdDescribeRuntimeMap:
+    case MgMappingServiceOpId::CreateRuntimeMap3:
         switch (VERSION_NO_PHASE(operationVersion))
         {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpCreateRuntimeMap());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgDrawingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
+    case MgMappingServiceOpId::DescribeRuntimeMap:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
         case VERSION_SUPPORTED(2,6):
             handler.reset(new MgOpDescribeRuntimeMap());
             break;
@@ -207,7 +219,7 @@
         }
         break;
 
-    case MgMappingService::opIdDescribeRuntimeMap2:
+    case MgMappingServiceOpId::DescribeRuntimeMap2:
         switch (VERSION_NO_PHASE(operationVersion))
         {
         case VERSION_SUPPORTED(2,6):
@@ -219,6 +231,18 @@
         }
         break;
 
+    case MgMappingServiceOpId::DescribeRuntimeMap3:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpDescribeRuntimeMap());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgDrawingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
     default:
         throw new MgInvalidOperationException(
             L"MgMappingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/Services/Mapping/OpCreateRuntimeMap.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/OpCreateRuntimeMap.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Mapping/OpCreateRuntimeMap.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -103,6 +103,53 @@
 
         EndExecution(byteReader);
     }
+    else if (9 == m_packet.m_NumArguments)
+    {
+        STRING targetMapName;
+        STRING sessionId;
+        STRING iconFormat;
+        INT32 iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange;
+        INT32 schemaVersion;
+
+        Ptr<MgResourceIdentifier> mapDefinition = (MgResourceIdentifier*)m_stream->GetObject();
+        m_stream->GetString(targetMapName);
+        m_stream->GetString(sessionId);
+        m_stream->GetString(iconFormat);
+        m_stream->GetInt32(iconWidth);
+        m_stream->GetInt32(iconHeight);
+        m_stream->GetInt32(requestedFeatures);
+        m_stream->GetInt32(iconsPerScaleRange);
+        m_stream->GetInt32(schemaVersion);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == mapDefinition) ? L"MgResourceIdentifier" : mapDefinition->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(targetMapName);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(sessionId);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(iconFormat);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconWidth);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconHeight);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(requestedFeatures);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconsPerScaleRange);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(schemaVersion);
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader =
+            m_service->CreateRuntimeMap(mapDefinition, targetMapName, sessionId, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange, schemaVersion);
+
+        EndExecution(byteReader);
+    }
     else if (4 == m_packet.m_NumArguments)
     {
         STRING sessionId;

Modified: trunk/MgDev/Server/src/Services/Mapping/OpDescribeRuntimeMap.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/OpDescribeRuntimeMap.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Mapping/OpDescribeRuntimeMap.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -100,6 +100,50 @@
 
         EndExecution(byteReader);
     }
+    else if (7 == m_packet.m_NumArguments)
+    {
+        STRING targetMapName;
+        STRING sessionId;
+        STRING iconFormat;
+        INT32 iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange;
+        INT32 schemaVersion;
+
+        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
+        map->SetDelayedLoadResourceService(m_resourceService);
+        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+
+        m_stream->GetString(iconFormat);
+        m_stream->GetInt32(iconWidth);
+        m_stream->GetInt32(iconHeight);
+        m_stream->GetInt32(requestedFeatures);
+        m_stream->GetInt32(iconsPerScaleRange);
+        m_stream->GetInt32(schemaVersion);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(iconFormat);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconWidth);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconHeight);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(requestedFeatures);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(iconsPerScaleRange);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(schemaVersion);
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader =
+            m_service->DescribeRuntimeMap(map, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange, schemaVersion);
+
+        EndExecution(byteReader);
+    }
     else if (3 == m_packet.m_NumArguments)
     {
         STRING sessionId;

Modified: trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1145,7 +1145,17 @@
     assert(m_svcDrawing != NULL);
 }
 
+//gets an instance of the tile service using the service manager
+void MgServerMappingService::InitializeTileService()
+{
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
 
+    m_svcTile = dynamic_cast<MgTileService*>(
+        serviceMan->RequestService(MgServiceType::TileService));
+    assert(m_svcTile != NULL);
+} 
+
 // Returns true if the supplied feature type style is compatible with the
 // supplied geometry type: 1=Point, 2=Line, 3=Area, 4=Composite
 bool MgServerMappingService::FeatureTypeStyleSupportsGeomType(MdfModel::FeatureTypeStyle* fts, INT32 geomType)
@@ -1261,6 +1271,17 @@
                                                          INT32 requestedFeatures,
                                                          INT32 iconsPerScaleRange)
 {
+    return DescribeRuntimeMap(map, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange, MG_API_VERSION(3, 0, 0) /* Latest and greatest */);
+}
+
+MgByteReader* MgServerMappingService::DescribeRuntimeMap(MgMap* map,
+                                                         CREFSTRING iconFormat,
+                                                         INT32 iconWidth,
+                                                         INT32 iconHeight,
+                                                         INT32 requestedFeatures,
+                                                         INT32 iconsPerScaleRange,
+                                                         INT32 schemaVersion)
+{
     LayerDefinitionMap layerDefinitionMap;
     if (MgImageFormats::Png != iconFormat &&
         MgImageFormats::Gif != iconFormat &&
@@ -1281,10 +1302,14 @@
     STRING sessionId = map->GetSessionId();
     STRING targetMapName = map->GetName();
     Ptr<MgResourceIdentifier> mapDefinition = map->GetMapDefinition();
+    Ptr<MgResourceIdentifier> tileSetDefinition = map->GetTileSetDefinition();
 
     //TODO: Possible future caching opportunity?
     std::string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";  // NOXLATE
-    xml.append("<RuntimeMap xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"RuntimeMap-2.6.0.xsd\">\n");
+    if (schemaVersion == MG_API_VERSION(2, 6, 0))
+        xml.append("<RuntimeMap xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"RuntimeMap-2.6.0.xsd\">\n");
+    else
+        xml.append("<RuntimeMap xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"RuntimeMap-3.0.0.xsd\" version=\"3.0.0\">\n");
     // ------------------------------ Site Version ----------------------------------//
     xml.append("<SiteVersion>");
     MgServerManager* serverMgr = MgServerManager::GetInstance();
@@ -1302,6 +1327,30 @@
     xml.append("<MapDefinition>");
     xml.append(MgUtil::WideCharToMultiByte(mapDefinition->ToString()));
     xml.append("</MapDefinition>\n");
+    //Write tile set definition if requesting a v3.0.0 response
+    if (NULL != (MgResourceIdentifier*)tileSetDefinition && schemaVersion == MG_API_VERSION(3, 0, 0))
+    {
+        if (m_svcTile == NULL)
+            InitializeTileService();
+
+        std::string sWidth;
+        std::string sHeight;
+        MgUtil::Int32ToString(m_svcTile->GetDefaultTileSizeX(tileSetDefinition), sWidth);
+        MgUtil::Int32ToString(m_svcTile->GetDefaultTileSizeY(tileSetDefinition), sHeight);
+
+        // ------------------------------ Tile Set Definition ID --------------------------------- //
+        xml.append("<TileSetDefinition>");
+        xml.append(MgUtil::WideCharToMultiByte(tileSetDefinition->ToString()));
+        xml.append("</TileSetDefinition>\n");
+        // ------------------------------ Tile Width ---------------------------------- //
+        xml.append("<TileWidth>");
+        xml.append(sWidth);
+        xml.append("</TileWidth>\n");
+        // ------------------------------ Tile Height --------------------------------- //
+        xml.append("<TileHeight>");
+        xml.append(sHeight);
+        xml.append("</TileHeight>\n");
+    }
     // ------------------------------ Background Color ---------------------------------- //
     xml.append("<BackgroundColor>");
     xml.append(MgUtil::WideCharToMultiByte(map->GetBackgroundColor()));
@@ -1420,7 +1469,7 @@
         for (INT32 i = 0; i < groups->GetCount(); i++)
         {
             Ptr<MgLayerGroup> group = groups->GetItem(i);
-            if (group->GetLayerGroupType() != MgLayerGroupType::BaseMap)
+            if (group->GetLayerGroupType() != MgLayerGroupType::BaseMap && group->GetLayerGroupType() != MgLayerGroupType::BaseMapFromTileSet)
                 continue;
 
             Ptr<MgLayerGroup> parent = group->GetGroup();
@@ -1481,6 +1530,19 @@
                                                        INT32 requestedFeatures,
                                                        INT32 iconsPerScaleRange)
 {
+    return CreateRuntimeMap(mapDefinition, targetMapName, sessionId, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange, MG_API_VERSION(3, 0, 0) /* Latest and greatest */);
+}
+
+MgByteReader* MgServerMappingService::CreateRuntimeMap(MgResourceIdentifier* mapDefinition,
+                                                       CREFSTRING targetMapName,
+                                                       CREFSTRING sessionId,
+                                                       CREFSTRING iconFormat,
+                                                       INT32 iconWidth,
+                                                       INT32 iconHeight,
+                                                       INT32 requestedFeatures,
+                                                       INT32 iconsPerScaleRange,
+                                                       INT32 schemaVersion)
+{
     CHECKARGUMENTNULL(mapDefinition, L"MgServerMappingService.CreateRuntimeMap");
     LayerDefinitionMap layerDefinitionMap;
     if (MgImageFormats::Png != iconFormat &&
@@ -1519,7 +1581,7 @@
     sel->Save(m_svcResource, sessionId, targetMapName);
     map->Save(m_svcResource, mapStateId);
 
-    byteReader = DescribeRuntimeMap(map, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange);
+    byteReader = DescribeRuntimeMap(map, iconFormat, iconWidth, iconHeight, requestedFeatures, iconsPerScaleRange, schemaVersion);
 
     MG_SERVER_MAPPING_SERVICE_CATCH_AND_THROW(L"MgServerMappingService.CreateRuntimeMap")
 

Modified: trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -125,6 +125,16 @@
                                                INT32 requestedFeatures,
                                                INT32 iconsPerScaleRange);
 
+        virtual MgByteReader* CreateRuntimeMap(MgResourceIdentifier* mapDefinition,
+                                               CREFSTRING targetMapName,
+                                               CREFSTRING sessionId,
+                                               CREFSTRING iconFormat,
+                                               INT32 iconWidth,
+                                               INT32 iconHeight,
+                                               INT32 requestedFeatures,
+                                               INT32 iconsPerScaleRange,
+                                               INT32 schemaVersion);
+
         virtual MgByteReader* DescribeRuntimeMap(MgMap* map,
                                                  INT32 requestedFeatures,
                                                  INT32 iconsPerScaleRange);
@@ -136,6 +146,14 @@
                                                  INT32 requestedFeatures,
                                                  INT32 iconsPerScaleRange);
 
+        virtual MgByteReader* DescribeRuntimeMap(MgMap* map,
+                                                 CREFSTRING iconFormat,
+                                                 INT32 iconWidth,
+                                                 INT32 iconHeight,
+                                                 INT32 requestedFeatures,
+                                                 INT32 iconsPerScaleRange,
+                                                 INT32 schemaVersion);
+
         void SetConnectionProperties(MgConnectionProperties* connProp);
 
 // Data Members
@@ -149,10 +167,12 @@
         void InitializeFeatureService();
         void InitializeResourceService();
         void InitializeDrawingService();
+        void InitializeTileService();
 
         Ptr<MgFeatureService> m_svcFeature;
         Ptr<MgResourceService> m_svcResource;
         Ptr<MgDrawingService> m_svcDrawing;
+        Ptr<MgTileService> m_svcTile;
         Ptr<MgCoordinateSystemFactory> m_pCSFactory;
 
         INT32 m_rasterGridSize;

Modified: trunk/MgDev/Server/src/Services/Rendering/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -35,6 +35,7 @@
   OpRenderDynamicOverlay.cpp \
   OpRenderMap.cpp \
   OpRenderTile.cpp \
+  OpRenderTileXYZ.cpp \
   OpQueryFeatures.cpp \
   OpQueryFeatureProperties.cpp \
   FeatureInfoRenderer.cpp \
@@ -50,6 +51,7 @@
   OpRenderDynamicOverlay.h \
   OpRenderMap.h \
   OpRenderTile.h \
+  OpRenderTileXYZ.h \
   OpQueryFeatures.h \
   OpQueryFeatureProperties.h \
   FeatureInfoRenderer.h \

Modified: trunk/MgDev/Server/src/Services/Rendering/OpRenderTile.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/OpRenderTile.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/OpRenderTile.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -94,6 +94,60 @@
 
         EndExecution(byteReader);
     }
+    else if (8 == m_packet.m_NumArguments)
+    {
+        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
+        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+        map->SetDelayedLoadResourceService(m_resourceService);
+
+        STRING baseMapLayerGroupName;
+        m_stream->GetString(baseMapLayerGroupName);
+
+        INT32 tileCol = 0;
+        m_stream->GetInt32(tileCol);
+
+        INT32 tileRow = 0;
+        m_stream->GetInt32(tileRow);
+
+        INT32 tileWidth = 0;
+        m_stream->GetInt32(tileWidth);
+
+        INT32 tileHeight = 0;
+        m_stream->GetInt32(tileHeight);
+
+        INT32 tileDpi = 0;
+        m_stream->GetInt32(tileDpi);
+
+        STRING tileImageFormat;
+        m_stream->GetString(tileImageFormat);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(baseMapLayerGroupName.c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileCol);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileRow);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileWidth);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileHeight);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileDpi);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(tileImageFormat.c_str());
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader =
+            m_service->RenderTile(map, baseMapLayerGroupName, tileCol, tileRow, tileWidth, tileHeight, tileDpi, tileImageFormat);
+
+        EndExecution(byteReader);
+    }
     else
     {
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();

Copied: trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Rendering/OpRenderTileXYZ.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,176 @@
+//
+//  Copyright (C) 2004-2014 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 "OpRenderTileXYZ.h"
+#include "LogManager.h"
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Constructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpRenderTileXYZ::MgOpRenderTileXYZ()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Destructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpRenderTileXYZ::~MgOpRenderTileXYZ()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Executes the operation.
+/// </summary>
+///
+/// <exceptions>
+/// MgException
+/// </exceptions>
+///----------------------------------------------------------------------------
+void MgOpRenderTileXYZ::Execute()
+{
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  (%t) MgOpRenderTileXYZ::Execute()\n")));
+
+    MG_LOG_OPERATION_MESSAGE(L"RenderTileXYZ");
+
+    MG_TRY()
+
+    MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+    ACE_ASSERT(m_stream != NULL);
+
+    if (5 == m_packet.m_NumArguments)
+    {
+        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
+        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+        map->SetDelayedLoadResourceService(m_resourceService);
+
+        STRING baseMapLayerGroupName;
+        m_stream->GetString(baseMapLayerGroupName);
+
+        INT32 x = 0;
+        m_stream->GetInt32(x);
+
+        INT32 y = 0;
+        m_stream->GetInt32(y);
+
+        INT32 z = 0;
+        m_stream->GetInt32(z);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(baseMapLayerGroupName.c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(x);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(y);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(z);
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader = m_service->RenderTileXYZ(map, baseMapLayerGroupName, x, y, z);
+
+        EndExecution(byteReader);
+    }
+    else if (7 == m_packet.m_NumArguments)
+    {
+        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
+        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+        map->SetDelayedLoadResourceService(m_resourceService);
+
+        STRING baseMapLayerGroupName;
+        m_stream->GetString(baseMapLayerGroupName);
+
+        INT32 x = 0;
+        m_stream->GetInt32(x);
+
+        INT32 y = 0;
+        m_stream->GetInt32(y);
+
+        INT32 z = 0;
+        m_stream->GetInt32(z);
+
+        INT32 tileDpi = 0;
+        m_stream->GetInt32(tileDpi);
+
+        STRING tileImageFormat;
+        m_stream->GetString(tileImageFormat);
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(baseMapLayerGroupName.c_str());
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(x);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(y);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(z);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_INT32(tileDpi);
+        MG_LOG_OPERATION_MESSAGE_ADD_SEPARATOR();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(tileImageFormat.c_str());
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader = m_service->RenderTileXYZ(map, baseMapLayerGroupName, x, y, z, tileDpi, tileImageFormat);
+
+        EndExecution(byteReader);
+    }
+    else
+    {
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+    }
+
+    if (!m_argsRead)
+    {
+        throw new MgOperationProcessingException(L"MgOpRenderTileXYZ.Execute",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Successful operation
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+    MG_CATCH(L"MgOpRenderTileXYZ.Execute")
+
+    if (mgException != NULL)
+    {
+        // Failed operation
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+    }
+
+    // Add access log entry for operation
+    MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+    MG_THROW()
+}

Copied: trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Rendering/OpRenderTileXYZ.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Rendering/OpRenderTileXYZ.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,33 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_OP_RENDER_TILE_XYZ_H
+#define MG_OP_RENDER_TILE_XYZ_H
+
+#include "RenderingOperation.h"
+
+class MgOpRenderTileXYZ : public MgRenderingOperation
+{
+    public:
+        MgOpRenderTileXYZ();
+        virtual ~MgOpRenderTileXYZ();
+
+    public:
+        virtual void Execute();
+};
+
+#endif

Modified: trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/RenderingOperationFactory.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -73,6 +73,42 @@
         }
         break;
 
+    case MgRenderingServiceOpId::RenderTile2:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpRenderTile());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
+    case MgRenderingServiceOpId::RenderTileXYZ:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpRenderTileXYZ());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
+    case MgRenderingServiceOpId::RenderTileXYZ2:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpRenderTileXYZ());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
     case MgRenderingServiceOpId::RenderDynamicOverlay:
         switch (VERSION_NO_PHASE(operationVersion))
         {
@@ -85,6 +121,7 @@
                 L"MgRenderingOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
         }
         break;
+
     case MgRenderingServiceOpId::RenderDynamicOverlay2:
         switch (VERSION_NO_PHASE(operationVersion))
         {

Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -29,12 +29,14 @@
 #include "LegendPlotUtil.h"
 #include "TransformCache.h"
 #include "Box2D.h"
+#include <cmath>
 
 // Profile
 #include "ProfileRenderMapResult.h"
 
+#define XYZ_TILE_WIDTH 256
+#define XYZ_TILE_HEIGHT 256
 
-
 // the maximum number of allowed pixels for rendered images
 static const INT32 MAX_PIXELS = 16384*16384;
 static const INT32 FILTER_VISIBLE = 1;
@@ -150,6 +152,33 @@
 
     MG_TRY()
 
+    ret = RenderTile(map, 
+                     baseMapLayerGroupName,
+                     tileColumn,
+                     tileRow,
+                     MgTileParameters::tileWidth,
+                     MgTileParameters::tileHeight,
+                     MgTileParameters::tileDPI,
+                     MgTileParameters::tileFormat);
+
+    MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTile")
+
+    return ret.Detach();
+}
+
+MgByteReader* MgServerRenderingService::RenderTile(MgMap* map,
+                                                   CREFSTRING baseMapLayerGroupName,
+                                                   INT32 tileColumn,
+                                                   INT32 tileRow,
+                                                   INT32 tileWidth,
+                                                   INT32 tileHeight,
+                                                   INT32 tileDpi,
+                                                   CREFSTRING tileImageFormat)
+{
+    Ptr<MgByteReader> ret;
+
+    MG_TRY()
+
     if (NULL == map || baseMapLayerGroupName.empty())
         throw new MgNullArgumentException(L"MgServerRenderingService.RenderTile", __LINE__, __WFILE__, NULL, L"", NULL);
 
@@ -178,7 +207,7 @@
     scale = map->GetFiniteDisplayScaleAt(scaleIndex);
 
     // ensure the tile DPI is set on the map
-    map->SetDisplayDpi(MgTileParameters::tileDPI);
+    map->SetDisplayDpi(tileDpi);
 
     // ------------------------------------------------------
     // the upper left corner of tile (0,0) corresponds to the
@@ -194,9 +223,9 @@
     double mapMaxY = rs_max(pt00->GetY(), pt11->GetY());
 
     double metersPerUnit  = map->GetMetersPerUnit();
-    double metersPerPixel = METERS_PER_INCH / MgTileParameters::tileDPI;
-    double tileWidthMCS   = (double)MgTileParameters::tileWidth  * metersPerPixel * scale / metersPerUnit;
-    double tileHeightMCS  = (double)MgTileParameters::tileHeight * metersPerPixel * scale / metersPerUnit;
+    double metersPerPixel = METERS_PER_INCH / tileDpi;
+    double tileWidthMCS   = (double)tileWidth  * metersPerPixel * scale / metersPerUnit;
+    double tileHeightMCS  = (double)tileHeight * metersPerPixel * scale / metersPerUnit;
 
     double tileMinX = mapMinX + (double)(tileColumn  ) * tileWidthMCS;  // left edge
     double tileMaxX = mapMinX + (double)(tileColumn+1) * tileWidthMCS;  // right edge
@@ -204,15 +233,197 @@
     double tileMaxY = mapMaxY - (double)(tileRow     ) * tileHeightMCS; // top edge
 
     // make the call to render the tile
-    ret = RenderTile(map, baseGroup, scaleIndex, MgTileParameters::tileWidth, MgTileParameters::tileHeight, scale,
-                     tileMinX, tileMaxX, tileMinY, tileMaxY, MgTileParameters::tileFormat);
+    ret = RenderTile(map, baseGroup, scaleIndex, tileWidth, tileHeight, scale,
+                     tileMinX, tileMaxX, tileMinY, tileMaxY, tileImageFormat);
 
     MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTile")
 
     return ret.Detach();
 }
 
+MgByteReader* MgServerRenderingService::RenderTileXYZ(MgMap* map,
+                                                      CREFSTRING baseMapLayerGroupName,
+                                                      INT32 x,
+                                                      INT32 y,
+                                                      INT32 z)
+{
+    Ptr<MgByteReader> ret;
 
+    MG_TRY()
+
+    ret = RenderTileXYZ(map, baseMapLayerGroupName, x, y, z, MgTileParameters::tileDPI, MgTileParameters::tileFormat);
+
+    MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTileXYZ")
+
+    return ret.Detach();
+}
+
+MgByteReader* MgServerRenderingService::RenderTileXYZ(MgMap* map,
+                                                      CREFSTRING baseMapLayerGroupName,
+                                                      INT32 x,
+                                                      INT32 y,
+                                                      INT32 z,
+                                                      INT32 dpi,
+                                                      CREFSTRING tileImageFormat)
+{
+    Ptr<MgByteReader> ret;
+
+    MG_TRY()
+
+    if (NULL == map || baseMapLayerGroupName.empty())
+        throw new MgNullArgumentException(L"MgServerRenderingService.RenderTileXYZ", __LINE__, __WFILE__, NULL, L"", NULL);
+
+    // get the layer group associated with the name
+    Ptr<MgLayerGroupCollection> layerGroups = map->GetLayerGroups();
+    Ptr<MgLayerGroup> baseGroup = layerGroups->GetItem(baseMapLayerGroupName);
+    if (baseGroup == NULL)
+    {
+        MgStringCollection arguments;
+        arguments.Add(L"2");
+        arguments.Add(baseMapLayerGroupName);
+
+        throw new MgInvalidArgumentException(L"MgServerRenderingService.RenderTileXYZ",
+            __LINE__, __WFILE__, &arguments, L"MgMapLayerGroupNameNotFound", NULL);
+    }
+
+    //Set the dpi
+    map->SetDisplayDpi(dpi);
+
+    int width = XYZ_TILE_WIDTH;
+    int height = XYZ_TILE_HEIGHT;
+
+    //XYZ to lat/lon math. From this we can convert to the bounds in the map's CS
+    //
+    //Source: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
+    double nMin = M_PI - 2.0 * M_PI * y / pow(2.0, z);
+    double nMax = M_PI - 2.0 * M_PI * (y + 1) / pow(2.0, z);
+    double lonMin = x / pow(2.0, z) * 360.0 - 180;
+	double latMin = 180.0 / M_PI * atan(0.5 * (exp(nMin) - exp(-nMin)));
+    double lonMax = (x + 1) / pow(2.0, z) * 360.0 - 180;
+	double latMax = 180.0 / M_PI * atan(0.5 * (exp(nMax) - exp(-nMax)));
+
+    double mcsMinX = std::min(lonMin, lonMax);
+    double mcsMinY = std::min(latMin, latMax);
+    double mcsMaxX = std::max(lonMin, lonMax);
+    double mcsMaxY = std::max(latMin, latMax);
+
+    STRING mapCsWkt = map->GetMapSRS();
+    Ptr<MgCoordinateSystemFactory> csFactory = new MgCoordinateSystemFactory();
+    Ptr<MgCoordinateSystem> mapCs = csFactory->Create(mapCsWkt);
+    if (mapCs->GetCsCode() != L"LL84")
+    {
+        //Set up LL to map transform and transform the bounds into map space
+        Ptr<MgCoordinateSystem> llCs = csFactory->CreateFromCode(L"LL84");
+        Ptr<MgCoordinateSystemTransform> trans = csFactory->GetTransform(llCs, mapCs);
+
+        Ptr<MgCoordinate> ul = trans->Transform(lonMin, latMin);
+        Ptr<MgCoordinate> lr = trans->Transform(lonMax, latMax);
+
+        mcsMinX = std::min(lr->GetX(), ul->GetX());
+        mcsMinY = std::min(lr->GetY(), ul->GetY());
+        mcsMaxX = std::max(lr->GetX(), ul->GetX());
+        mcsMaxY = std::max(lr->GetY(), ul->GetY());
+    }
+
+    // Inlining same logic from RenderTile() overload below as we want the same logic, but we want to pass scale
+    // instead of scale index
+
+    // get map extent that corresponds to tile extent
+    RS_Bounds extent(mcsMinX, mcsMinY, mcsMaxX, mcsMaxY);
+
+    // use the map's background color, but always make it fully transparent
+    RS_Color bgColor;
+    StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
+    bgColor.alpha() = 0;
+
+    // the label renderer needs to know the tile extent offset parameter
+    double tileExtentOffset = 0.0;
+    MgConfiguration* pConf = MgConfiguration::GetInstance();
+    pConf->GetDoubleValue(MgConfigProperties::RenderingServicePropertiesSection,
+                          MgConfigProperties::RenderingServicePropertyTileExtentOffset,
+                          tileExtentOffset,
+                          MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset);
+    if (tileExtentOffset < 0.0)
+        tileExtentOffset = MgConfigProperties::DefaultRenderingServicePropertyTileExtentOffset;
+    
+    // Image scaling logic ripped verbatim from RenderMap() overload that takes MgEnvelope
+    //
+    // If we need to scale the image (because of request for non-square
+    // pixels) we will need to draw at one image size and then save at
+    // another scaled size.  Here we will compute the correct map scale
+    // and render size for a requested extent and image size.
+    double screenAR = (double)width / (double)height;
+    double mapAR = extent.width() / extent.height();
+
+    int drawWidth = width;
+    int drawHeight = height;
+    double scale = 0.0;
+
+    if (mapAR >= screenAR)
+    {
+        scale = extent.width() * map->GetMetersPerUnit() / METERS_PER_INCH * (double)dpi / (double)width;
+
+        // we based map scale on the image width, so adjust rendering
+        // height to match the map aspect ratio
+        drawHeight = (int)(width / mapAR);
+
+        // ignore small perturbations in order to avoid rescaling the
+        // end image in cases where the rescaling of width is less than
+        // a pixel or so
+        if (abs(drawHeight - height) <= 1)
+            drawHeight = height;
+    }
+    else
+    {
+        scale = extent.height() * map->GetMetersPerUnit() / METERS_PER_INCH * (double)dpi / (double)height;
+
+        // we based map scale on the image height, so adjust rendering
+        // height to match the map aspect ratio
+        drawWidth = (int)(height * mapAR);
+
+        // ignore small perturbations, in order to avoid rescaling the
+        // end image in cases where the rescaling of width is less than
+        // a pixel or so
+        if (abs(drawWidth - width) <= 1)
+            drawWidth = width;
+    }
+
+    //printf("XYZ(%d, %d, %d) -> [%f, %f] [%f, %f] at %f -- (w: %d, h: %d, mpu: %f)\n", x, y, z, mcsMinX, mcsMinY, mcsMaxX, mcsMaxY, scale, width, height, map->GetMetersPerUnit());
+
+    // sanity check - number of image pixels cannot exceed MAX_PIXELS
+    if (drawWidth * drawHeight > MAX_PIXELS)
+        throw new MgOutOfRangeException(L"MgServerRenderingService.RenderMap", __LINE__, __WFILE__, NULL, L"MgInvalidImageSizeTooBig", NULL);
+
+    // initialize the renderer (set clipping to false so that we label
+    // the unclipped geometry)
+    auto_ptr<SE_Renderer> dr(CreateRenderer(drawWidth, drawHeight, bgColor, false, true, tileExtentOffset));
+
+    // create a temporary collection containing all the layers for the base group
+    Ptr<MgLayerCollection> layers = map->GetLayers();
+    Ptr<MgReadOnlyLayerCollection> roLayers = new MgReadOnlyLayerCollection();
+    for (int i=0; i<layers->GetCount(); i++)
+    {
+        Ptr<MgLayerBase> layer = layers->GetItem(i);
+        Ptr<MgLayerGroup> parentGroup = layer->GetGroup();
+        if (parentGroup == baseGroup)
+            roLayers->Add(layer);
+    }
+
+    // of course the group has to also be visible
+    bool groupVisible = baseGroup->GetVisible();
+    baseGroup->SetVisible(true);
+
+    // call the internal helper API to do all the stylization overhead work
+    ret = RenderMapInternal(map, NULL, roLayers, dr.get(), drawWidth, drawHeight, width, height, tileImageFormat, scale, extent, true, true, false);
+
+    // restore the base group's visibility
+    baseGroup->SetVisible(groupVisible);
+
+    MG_CATCH_AND_THROW(L"MgServerRenderingService.RenderTileXYZ")
+
+    return ret.Detach();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// render a map using all layers from the baseGroup
 MgByteReader* MgServerRenderingService::RenderTile(MgMap* map,

Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -47,6 +47,29 @@
                                      INT32 tileColumn,
                                      INT32 tileRow);
 
+    virtual MgByteReader* RenderTile(MgMap* map,
+                                     CREFSTRING baseMapLayerGroupName,
+                                     INT32 tileColumn,
+                                     INT32 tileRow,
+                                     INT32 tileWidth,
+                                     INT32 tileHeight,
+                                     INT32 tileDpi,
+                                     CREFSTRING tileImageFormat);
+
+    virtual MgByteReader* RenderTileXYZ(MgMap* map,
+                                        CREFSTRING baseMapLayerGroupName,
+                                        INT32 x,
+                                        INT32 y,
+                                        INT32 z);
+
+    virtual MgByteReader* RenderTileXYZ(MgMap* map,
+                                        CREFSTRING baseMapLayerGroupName,
+                                        INT32 x,
+                                        INT32 y,
+                                        INT32 z,
+                                        INT32 dpi,
+                                        CREFSTRING tileImageFormat);
+
     virtual MgByteReader* RenderDynamicOverlay(MgMap* map,
                                                MgSelection* selection,
                                                CREFSTRING format);

Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -234,6 +234,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="OpRenderTileXYZ.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="RenderingOperation.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -285,6 +291,7 @@
     <ClInclude Include="OpRenderMap.h" />
     <ClInclude Include="OpRenderMapLegend.h" />
     <ClInclude Include="OpRenderTile.h" />
+    <ClInclude Include="OpRenderTileXYZ.h" />
     <ClInclude Include="RenderingOperation.h" />
     <ClInclude Include="RenderingOperationFactory.h" />
     <ClInclude Include="FeatureInfoRenderer.h" />

Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -36,6 +36,9 @@
     <ClCompile Include="RenderingServiceHandler.cpp" />
     <ClCompile Include="ServerRenderingService.cpp" />
     <ClCompile Include="ServerRenderingServiceBuild.cpp" />
+    <ClCompile Include="OpRenderTileXYZ.cpp">
+      <Filter>Ops</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="OpQueryFeatureProperties.h">
@@ -68,6 +71,9 @@
     <ClInclude Include="ServerRenderingDllExport.h" />
     <ClInclude Include="ServerRenderingService.h" />
     <ClInclude Include="..\..\Common\stdafx.h" />
+    <ClInclude Include="OpRenderTileXYZ.h">
+      <Filter>Ops</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ServerRenderingService.rc" />

Modified: trunk/MgDev/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Rendering/ServerRenderingServiceBuild.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -24,6 +24,7 @@
 #include "OpRenderMap.cpp"
 #include "OpRenderMapLegend.cpp"
 #include "OpRenderTile.cpp"
+#include "OpRenderTileXYZ.cpp"
 #include "OpQueryFeatures.cpp"
 #include "OpQueryFeatureProperties.cpp"
 #include "RenderingOperation.cpp"

Modified: trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -747,6 +747,61 @@
     MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgApplicationRepositoryManager.EnumerateParentMapDefinitions")
 }
 
+///////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Enumerate all the parent Map Definition resources of the specified
+/// resources.
+///
+/// Note that child list will also be updated with additional members during
+/// the search.
+///
+void MgApplicationRepositoryManager::EnumerateParentTileSetDefinitions(
+    set<string>& childResources, set<STRING>& parentResources)
+{
+    MG_RESOURCE_SERVICE_TRY()
+
+    // If the child list contains some Map Definition resources, then
+    // insert them into the parent list.
+
+    for (set<string>::const_iterator i = childResources.begin();
+        i != childResources.end( ); ++i)
+    {
+        string mbResourcePathname = *i;
+        STRING wcResourcePathname;
+        MgUtil::MultiByteToWideChar(mbResourcePathname, wcResourcePathname);
+        MgResourceIdentifier resource(wcResourcePathname);
+
+        if (resource.IsResourceTypeOf(MgResourceType::TileSetDefinition))
+        {
+            parentResources.insert(wcResourcePathname);
+        }
+    }
+
+    MgApplicationResourceContentManager* resourceContentMan =
+        GetApplicationResourceContentManager();
+
+    // Scan through the repository tree to search for all the parent Map
+    // Definition resources that reference the specified child resources.
+
+    set<string> *prevSearchResources, *currSearchResources, *nextSearchResources;
+    set<string> inputResources, outputResources;
+
+    inputResources = childResources;
+    currSearchResources = &inputResources;
+    nextSearchResources = &outputResources;
+
+    while (!currSearchResources->empty())
+    {
+        resourceContentMan->EnumerateParentTileSetDefinitions(*currSearchResources,
+            *nextSearchResources, childResources, parentResources);
+        prevSearchResources = currSearchResources;
+        currSearchResources = nextSearchResources;
+        nextSearchResources = prevSearchResources;
+    }
+
+    MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgApplicationRepositoryManager.EnumerateParentTileSetDefinitions")
+}
+
 ///----------------------------------------------------------------------------
 /// <summary>
 /// Enumerates tagged data for the specified resource.

Modified: trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ApplicationRepositoryManager.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -71,6 +71,8 @@
     MgByteReader* EnumerateReferences(MgResourceIdentifier* resource);
     void EnumerateParentMapDefinitions(
         set<string>& childResources, set<STRING>& parentResources);
+    void EnumerateParentTileSetDefinitions(
+        set<string>& childResources, set<STRING>& parentResources);
 
     // Resource Data Management APIs
 

Modified: trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -275,6 +275,96 @@
     MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgApplicationResourceContentManager.EnumerateParentMapDefinitions")
 }
 
+///////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Enumerate all the parent Tile Set Definition resources of the specified
+/// resources.
+///
+/// Note that checking permissions is not required for this operation.
+///
+void MgApplicationResourceContentManager::EnumerateParentTileSetDefinitions(
+    const set<string>& currSearchResources, set<string>& nextSearchResources,
+    set<string>& childResources, set<STRING>& parentResources)
+{
+    MG_RESOURCE_SERVICE_TRY()
+
+    // Reset the next search list.
+
+    nextSearchResources.clear();
+
+    // Do nothing if the current search list is empty.
+
+    if (currSearchResources.empty())
+    {
+        return;
+    }
+
+    // Set up an XQuery.
+
+    string query = "collection('";
+    query += m_container.getName();
+    query += "')";
+    query += "//*/ResourceId[";
+
+    for (set<string>::const_iterator i = currSearchResources.begin();
+        i != currSearchResources.end( ); ++i)
+    {
+        if (i != currSearchResources.begin())
+        {
+            query += " or ";
+        }
+
+        query += ".=\"";
+        query += *i;
+        query += "\"";
+    }
+
+    query += "]";
+
+    // Execute the XQuery.
+
+    XmlManager& xmlMan = m_container.getManager();
+    XmlQueryContext queryContext = xmlMan.createQueryContext();
+    XmlResults results = IsTransacted() ?
+        xmlMan.query(GetXmlTxn(), query, queryContext, 0) :
+        xmlMan.query(query, queryContext, 0);
+    XmlDocument xmlDoc;
+
+    while (results.next(xmlDoc))
+    {
+        string mbResourcePathname = xmlDoc.getName();
+        STRING wcResourcePathname;
+        MgUtil::MultiByteToWideChar(mbResourcePathname, wcResourcePathname);
+        MgResourceIdentifier resource(wcResourcePathname);
+
+        if (!resource.IsFolder())
+        {
+            // Insert the resource into the parent list if it is a Tile Set Definition.
+            // Otherwise, insert it into the child list.
+
+            if (resource.IsResourceTypeOf(MgResourceType::TileSetDefinition))
+            {
+                parentResources.insert(wcResourcePathname);
+            }
+            else
+            {
+                std::pair<set<string>::iterator, bool> i =
+                    childResources.insert(mbResourcePathname);
+
+                // Insert the resource into the next search list if it is not in
+                // the child list.
+
+                if (i.second)
+                {
+                    nextSearchResources.insert(mbResourcePathname);
+                }
+            }
+        }
+    }
+
+    MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgApplicationResourceContentManager.EnumerateParentTileSetDefinitions")
+}
+
 ///----------------------------------------------------------------------------
 /// <summary>
 /// Enumerates tagged data for the specified resource.

Modified: trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ApplicationResourceContentManager.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -53,6 +53,9 @@
     void EnumerateParentMapDefinitions(
         const set<string>& currSearchResources, set<string>& nextSearchResources,
         set<string>& childResources, set<STRING>& parentResources);
+    void EnumerateParentTileSetDefinitions(
+        const set<string>& currSearchResources, set<string>& nextSearchResources,
+        set<string>& childResources, set<STRING>& parentResources);
 
     // Resource Data Management APIs
 

Modified: trunk/MgDev/Server/src/Services/Resource/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -55,6 +55,7 @@
   OpDeleteResource.cpp \
   OpDeleteResourceData.cpp \
   OpEnumerateParentMapDefinitions.cpp \
+  OpEnumerateParentTileSetDefinitions.cpp \
   OpEnumerateRepositories.cpp \
   OpEnumerateResourceData.cpp \
   OpEnumerateResourceDocuments.cpp \
@@ -135,6 +136,7 @@
   OpDeleteResource.h \
   OpDeleteResourceData.h \
   OpEnumerateParentMapDefinitions.h \
+  OpEnumerateParentTileSetDefinitions.h \
   OpEnumerateRepositories.h \
   OpEnumerateResourceData.h \
   OpEnumerateResourceDocuments.h \

Copied: trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,110 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "ResourceServiceDefs.h"
+#include "OpEnumerateParentTileSetDefinitions.h"
+#include "ServerResourceService.h"
+#include "LogManager.h"
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Constructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpEnumerateParentTileSetDefinitions::MgOpEnumerateParentTileSetDefinitions()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Destructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpEnumerateParentTileSetDefinitions::~MgOpEnumerateParentTileSetDefinitions()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Executes the operation.
+/// </summary>
+///
+/// <exceptions>
+/// MgException
+/// </exceptions>
+///----------------------------------------------------------------------------
+void MgOpEnumerateParentTileSetDefinitions::Execute()
+{
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  (%t) MgOpEnumerateParentTileSetDefinitions::Execute()\n")));
+
+    MG_LOG_OPERATION_MESSAGE(L"EnumerateParentTileSetDefinitions");
+
+    MG_RESOURCE_SERVICE_TRY()
+
+    MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+    ACE_ASSERT(m_stream != NULL);
+
+    if (1 == m_packet.m_NumArguments)
+    {
+        Ptr<MgSerializableCollection> resources =
+            (MgSerializableCollection*)m_stream->GetObject();
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(L"MgSerializableCollection");
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgSerializableCollection> mapDefinitions =
+            m_service->EnumerateParentTileSetDefinitions(resources);
+
+        EndExecution(mapDefinitions);
+    }
+    else
+    {
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+    }
+
+    if (!m_argsRead)
+    {
+        throw new MgOperationProcessingException(L"MgOpEnumerateParentTileSetDefinitions.Execute",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Successful operation
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+    MG_RESOURCE_SERVICE_CATCH(L"MgOpEnumerateParentTileSetDefinitions.Execute")
+
+    if (mgException != NULL)
+    {
+        // Failed operation
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+    }
+
+    // Add access log entry for operation
+    MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+    MG_RESOURCE_SERVICE_THROW()
+}

Copied: trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Resource/OpEnumerateParentTileSetDefinitions.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,33 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MGOPENUMERATEPARENTTILESETDEFINITIONS_H
+#define MGOPENUMERATEPARENTTILESETDEFINITIONS_H
+
+#include "ResourceOperation.h"
+
+class MgOpEnumerateParentTileSetDefinitions : public MgResourceOperation
+{
+    public:
+        MgOpEnumerateParentTileSetDefinitions();
+        virtual ~MgOpEnumerateParentTileSetDefinitions();
+
+    public:
+        virtual void Execute();
+};
+
+#endif

Modified: trunk/MgDev/Server/src/Services/Resource/ResourceOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ResourceOperationFactory.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ResourceOperationFactory.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -39,6 +39,7 @@
 #include "OpGetResourceModifiedDate.h"
 #include "OpEnumerateResourceReferences.h"
 #include "OpEnumerateParentMapDefinitions.h"
+#include "OpEnumerateParentTileSetDefinitions.h"
 #include "OpChangeResourceOwner.h"
 #include "OpInheritPermissionsFrom.h"
 // Resource Data Management APIs
@@ -340,6 +341,18 @@
         }
         break;
 
+    case MgResourceService::opIdEnumerateParentTileSetDefinitions:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpEnumerateParentTileSetDefinitions());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgResourceOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
     case MgResourceService::opIdChangeResourceOwner:
         switch (VERSION_NO_PHASE(operationVersion))
         {

Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1541,6 +1541,135 @@
     return mapDefinitions.Detach();
 }
 
+///////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Enumerate all the parent Tile Set Definition resources of the specified
+/// resources.
+///
+MgSerializableCollection* MgServerResourceService::EnumerateParentTileSetDefinitions(MgSerializableCollection* resources)
+{
+    Ptr<MgSerializableCollection> tileSetDefinitions;
+
+    MG_RESOURCE_SERVICE_TRY()
+
+    MG_LOG_TRACE_ENTRY(L"MgServerResourceService::EnumerateParentTileSetDefinitions()");
+
+    if (NULL == resources)
+    {
+        throw new MgNullArgumentException(
+            L"MgServerResourceService.EnumerateParentTileSetDefinitions",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Check if the resources come from the Library or Session repository.
+
+    set<string> childResources;
+    INT32 libraryResources = 0;
+    INT32 numResources = resources->GetCount();
+
+    for (INT32 i = 0; i < numResources; ++i)
+    {
+        Ptr<MgSerializable> serializableObj = resources->GetItem(i);
+        MgResourceIdentifier* resource = dynamic_cast<MgResourceIdentifier*>(
+            serializableObj.p);
+
+        if (NULL == resource)
+        {
+            throw new MgInvalidCastException(
+                L"MgServerResourceService.EnumerateParentTileSetDefinitions",
+                __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        if (!resource->IsFolder())
+        {
+            if (resource->IsRepositoryTypeOf(MgRepositoryType::Library))
+            {
+                childResources.insert(MgUtil::WideCharToMultiByte(
+                    resource->ToString()));
+                ++libraryResources;
+            }
+            else if (resource->IsRepositoryTypeOf(MgRepositoryType::Session))
+            {
+                childResources.insert(MgUtil::WideCharToMultiByte(
+                    resource->ToString()));
+            }
+            else
+            {
+                throw new MgInvalidRepositoryTypeException(
+                    L"MgServerResourceService.EnumerateParentTileSetDefinitions",
+                    __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+        }
+    }
+
+    // Note that a Session resource may reference a Library resource but not
+    // the other way around, therefore:
+    //
+    // 1. If the resource comes from the Session repository, then we need to
+    //    perform this operation on only the Session repository.
+    // 2. If the resource comes from the Library repository, then we need to
+    //    perform this operation on both the Library and Session repositories.
+
+    set<STRING> parentResources;
+    numResources = static_cast<INT32>(childResources.size());
+
+    if (numResources > 0)
+    {
+        if (libraryResources > 0)
+        {
+            MgLibraryRepositoryManager libraryRepositoryMan(*sm_libraryRepository);
+
+            libraryRepositoryMan.Initialize(true);
+            libraryRepositoryMan.EnumerateParentTileSetDefinitions(childResources,
+                parentResources);
+            libraryRepositoryMan.Terminate();
+        }
+
+        if(sm_bSingleSessionRepository)
+        {
+            MgSessionRepositoryManager sessionRepositoryMan(*sm_sessionRepository);
+
+            sessionRepositoryMan.Initialize(true);
+            sessionRepositoryMan.EnumerateParentTileSetDefinitions(childResources,
+                parentResources);
+            sessionRepositoryMan.Terminate();
+        }
+        else
+        {
+            for (std::map<STRING, MgSessionRepository* >::iterator i = sm_sessionRepositories.begin();i != sm_sessionRepositories.end(); ++i)
+            {
+                MgSessionRepository* sessionRepository = i->second;
+                if(NULL != sessionRepository)
+                {
+                    MgSessionRepositoryManager sessionRepositoryMan(*sessionRepository);
+
+                    sessionRepositoryMan.Initialize(true);
+                    sessionRepositoryMan.EnumerateParentTileSetDefinitions(childResources,
+                        parentResources);
+                    sessionRepositoryMan.Terminate();
+                }
+            }
+        }
+    }
+
+    if (!parentResources.empty())
+    {
+        tileSetDefinitions = new MgSerializableCollection();
+
+        for (set<STRING>::const_iterator i = parentResources.begin();
+            i != parentResources.end( ); ++i)
+        {
+            Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(*i);
+
+            tileSetDefinitions->Add(resource.p);
+        }
+    }
+
+    MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgServerResourceService.EnumerateParentTileSetDefinitions")
+
+    return tileSetDefinitions.Detach();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief
 /// Enumerate the resource documents in the specified repository.

Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -97,6 +97,8 @@
         MgResourceIdentifier* resource);
     virtual MgSerializableCollection* EnumerateParentMapDefinitions(
         MgSerializableCollection* resources);
+    virtual MgSerializableCollection* EnumerateParentTileSetDefinitions(
+        MgSerializableCollection* resources);
     virtual STRING EnumerateResourceDocuments(MgStringCollection* resources,
         CREFSTRING type, INT32 properties);
     virtual void ChangeResourceOwner(MgResourceIdentifier* resource,

Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -254,6 +254,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="OpEnumerateParentTileSetDefinitions.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="OpEnumerateRepositories.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -691,6 +697,7 @@
     <ClInclude Include="OpDeleteResource.h" />
     <ClInclude Include="OpDeleteResourceData.h" />
     <ClInclude Include="OpEnumerateParentMapDefinitions.h" />
+    <ClInclude Include="OpEnumerateParentTileSetDefinitions.h" />
     <ClInclude Include="OpEnumerateRepositories.h" />
     <ClInclude Include="OpEnumerateResourceData.h" />
     <ClInclude Include="OpEnumerateResourceDocuments.h" />

Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj.filters
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceService.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -150,6 +150,9 @@
     <ClCompile Include="ZipFileHandler.cpp" />
     <ClCompile Include="ZipFileReader.cpp" />
     <ClCompile Include="ZipFileWriter.cpp" />
+    <ClCompile Include="OpEnumerateParentTileSetDefinitions.cpp">
+      <Filter>Ops</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="OpApplyResourcePackage.h">
@@ -297,6 +300,9 @@
     <ClInclude Include="ZipFileHandler.h" />
     <ClInclude Include="ZipFileReader.h" />
     <ClInclude Include="ZipFileWriter.h" />
+    <ClInclude Include="OpEnumerateParentTileSetDefinitions.h">
+      <Filter>Ops</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ServerResourceService.rc" />

Modified: trunk/MgDev/Server/src/Services/Resource/ServerResourceServiceBuild.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Resource/ServerResourceServiceBuild.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Resource/ServerResourceServiceBuild.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -39,6 +39,7 @@
 #include "OpDeleteResource.cpp"
 #include "OpDeleteResourceData.cpp"
 #include "OpEnumerateParentMapDefinitions.cpp"
+#include "OpEnumerateParentTileSetDefinitions.cpp"
 #include "OpEnumerateRepositories.cpp"
 #include "OpEnumerateResourceData.cpp"
 #include "OpEnumerateResourceDocuments.cpp"

Modified: trunk/MgDev/Server/src/Services/Tile/Makefile.am
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -6,6 +6,7 @@
 
 INCLUDES = \
   -I../../../../Oem/ACE/ACE_wrappers \
+  -I../../../../Oem/dbxml/xerces-c-src/src \
   -I../../../../Common/Foundation \
   -I../../../../Common/Geometry \
   -I../../../../Common/PlatformBase \
@@ -13,7 +14,8 @@
   -I../../Common \
   -I../../Common/Base \
   -I../../Common/Manager \
-  -I../../../../Common/MdfModel
+  -I../../../../Common/MdfModel \
+  -I../../../../Common/MdfParser
 
 lib_LTLIBRARIES = libMgServerTileService.la
 
@@ -23,11 +25,15 @@
 include_SOURCES = \
   OpClearCache.cpp \
   OpGetTile.cpp \
+  OpGetTileProviders.cpp \
   OpGetDefaultTileSizeX.cpp \
   OpGetDefaultTileSizeY.cpp \
   OpSetTile.cpp \
   ServerTileService.cpp \
   TileCache.cpp \
+  TileCacheDefault.cpp \
+  TileCacheDefaultProvider.cpp \
+  TileCacheXYZProvider.cpp \
   TileOperation.cpp \
   TileOperationFactory.cpp \
   TileServiceHandler.cpp
@@ -35,12 +41,16 @@
 noinst_HEADERS = $(include_SOURCES) \
   OpClearCache.h \
   OpGetTile.h \
+  OpGetTileProviders.h \
   OpGetDefaultTileSizeX.h \
   OpGetDefaultTileSizeY.h \
   OpSetTile.h \
   ServerTileDllExport.h \
   ServerTileService.h \
   TileCache.h \
+  TileCacheDefault.h \
+  TileCacheDefaultProvider.h \
+  TileCacheXYZProvider.h \
   TileOperation.h \
   TileOperationFactory.h \
   TileServiceHandler.h

Modified: trunk/MgDev/Server/src/Services/Tile/OpClearCache.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpClearCache.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/OpClearCache.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -62,21 +62,41 @@
 
     if (1 == m_packet.m_NumArguments)
     {
-        Ptr<MgMap> map = (MgMap*)m_stream->GetObject();
-        Ptr<MgResourceIdentifier> resource = map->GetResourceId();
-        map->SetDelayedLoadResourceService(m_resourceService);
+        Ptr<MgSerializable> obj = (MgSerializable*)m_stream->GetObject();
+        if (obj->IsOfClass(MapGuide_MapLayer_Map))
+        {
+            Ptr<MgMap> map = SAFE_ADDREF((MgMap*)obj.p);
+            Ptr<MgResourceIdentifier> resource = map->GetResourceId();
+            map->SetDelayedLoadResourceService(m_resourceService);
 
-        BeginExecution();
+            BeginExecution();
 
-        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
-        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
-        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+            MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+            MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+            MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
 
-        Validate();
+            Validate();
 
-        m_service->ClearCache(map);
+            m_service->ClearCache(map);
 
-        EndExecution();
+            EndExecution();
+        }
+        else if (obj->IsOfClass(PlatformBase_ResourceService_ResourceIdentifier))
+        {
+            Ptr<MgResourceIdentifier> resource = SAFE_ADDREF((MgResourceIdentifier*)obj.p);
+
+            BeginExecution();
+
+            MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+            MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+            MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+            Validate();
+
+            m_service->ClearCache(resource);
+
+            EndExecution();
+        }
     }
     else
     {

Modified: trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeX.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeX.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeX.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -73,6 +73,22 @@
 
         EndExecution(size);
     }
+    else if (1 == m_packet.m_NumArguments)
+    {
+        Ptr<MgResourceIdentifier> resource = (MgResourceIdentifier*)m_stream->GetObject();
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        INT32 size = m_service->GetDefaultTileSizeX(resource);
+
+        EndExecution(size);
+    }
     else
     {
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();

Modified: trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeY.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeY.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/OpGetDefaultTileSizeY.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -73,6 +73,22 @@
 
         EndExecution(size);
     }
+    else if (1 == m_packet.m_NumArguments)
+    {
+        Ptr<MgResourceIdentifier> resource = (MgResourceIdentifier*)m_stream->GetObject();
+
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING((NULL == resource) ? L"MgResourceIdentifier" : resource->ToString().c_str());
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        INT32 size = m_service->GetDefaultTileSizeX(resource);
+
+        EndExecution(size);
+    }
     else
     {
         MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();

Copied: trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/OpGetTileProviders.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,102 @@
+//
+//  Copyright (C) 2004-2014 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 "OpGetTileProviders.h"
+#include "LogManager.h"
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Constructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpGetTileProviders::MgOpGetTileProviders()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Destructs the object.
+/// </summary>
+///----------------------------------------------------------------------------
+MgOpGetTileProviders::~MgOpGetTileProviders()
+{
+}
+
+
+///----------------------------------------------------------------------------
+/// <summary>
+/// Executes the operation.
+/// </summary>
+///
+/// <exceptions>
+/// MgException
+/// </exceptions>
+///----------------------------------------------------------------------------
+void MgOpGetTileProviders::Execute()
+{
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  (%t) MgOpGetTileProviders::Execute()\n")));
+
+    MG_LOG_OPERATION_MESSAGE(L"GetTileProviders");
+
+    MG_TRY()
+
+    MG_LOG_OPERATION_MESSAGE_INIT(m_packet.m_OperationVersion, m_packet.m_NumArguments);
+
+    ACE_ASSERT(m_stream != NULL);
+
+    if (0 == m_packet.m_NumArguments)
+    {   
+        BeginExecution();
+
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+
+        Validate();
+
+        Ptr<MgByteReader> byteReader = m_service->GetTileProviders();
+
+        EndExecution(byteReader);
+    }
+    else
+    {
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_START();
+        MG_LOG_OPERATION_MESSAGE_PARAMETERS_END();
+    }
+
+    if (!m_argsRead)
+    {
+        throw new MgOperationProcessingException(L"MgOpGetTileProviders.Execute",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Successful operation
+    MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
+
+    MG_CATCH(L"MgOpGetTileProviders.Execute")
+
+    if (mgException != NULL)
+    {
+        // Failed operation
+        MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Failure.c_str());
+    }
+
+    // Add access log entry for operation
+    MG_LOG_OPERATION_MESSAGE_ACCESS_ENTRY();
+
+    MG_THROW()
+}

Copied: trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/OpGetTileProviders.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/OpGetTileProviders.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,33 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef MG_OP_GET_TILE_PROVIDERS_H
+#define MG_OP_GET_TILE_PROVIDERS_H
+
+#include "TileOperation.h"
+
+class MgOpGetTileProviders : public MgTileOperation
+{
+    public:
+        MgOpGetTileProviders();
+        virtual ~MgOpGetTileProviders();
+
+    public:
+        virtual void Execute();
+};
+
+#endif

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -17,524 +17,582 @@
 
 #include "MapGuideCommon.h"
 #include "ServerTileService.h"
+#include "TileSetDefinition.h"
+#include "UnmanagedDataManager.h"
+#include "SAX2Parser.h"
 
 IMPLEMENT_CREATE_SERVICE(MgServerTileService)
 
-ACE_Recursive_Thread_Mutex MgServerTileService::sm_mutex;
-bool MgServerTileService::sm_initialized = false;
-MgServerTileService::MapCache MgServerTileService::sm_mapCache;
-bool MgServerTileService::sm_renderOnly = false;
-INT32 MgServerTileService::sm_creationCutoffTime = 120;     // in seconds
-INT32 MgServerTileService::sm_pollingInterval = 1;          // in seconds
-INT32 MgServerTileService::sm_mapCacheSize = 10;
-
 MgServerTileService::MgServerTileService() : MgTileService()
 {
-    if (!sm_initialized)
-    {
-        // Perform Double-Checked Locking Optimization.
-        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
-
-        if (!sm_initialized)
-        {
-            MgConfiguration* configuration = MgConfiguration::GetInstance();
-
-            configuration->GetBoolValue(
-                MgConfigProperties::TileServicePropertiesSection,
-                MgConfigProperties::TileServicePropertyRenderOnly,
-                sm_renderOnly,
-                MgConfigProperties::DefaultTileServicePropertyRenderOnly);
-
-            configuration->GetIntValue(
-                MgConfigProperties::TileServicePropertiesSection,
-                MgConfigProperties::TileServicePropertyCreationCutoffTime,
-                sm_creationCutoffTime,
-                MgConfigProperties::DefaultTileServicePropertyCreationCutoffTime);
-
-            configuration->GetIntValue(
-                MgConfigProperties::TileServicePropertiesSection,
-                MgConfigProperties::TileServicePropertyPollingInterval,
-                sm_pollingInterval,
-                MgConfigProperties::DefaultTileServicePropertyPollingInterval);
-
-            configuration->GetIntValue(
-                MgConfigProperties::TileServicePropertiesSection,
-                MgConfigProperties::TileServicePropertyTiledMapCacheSize,
-                sm_mapCacheSize,
-                MgConfigProperties::DefaultTileServicePropertyTiledMapCacheSize);
-
-            MgTileCache::Initialize();
-            sm_initialized = true;
-        }
-    }
-
-    m_tileCache = new MgTileCache();
+    MgTileCacheDefault::Initialize();
 }
 
-
 MgServerTileService::~MgServerTileService()
 {
+
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// \brief
-/// Determine if the tile cache is empty.
-///
-bool MgServerTileService::IsTileCacheEmpty() const
+MgByteReader* MgServerTileService::GetTile(
+    MgMap* map,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow)
 {
-    ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, false));
+    Ptr<MgByteReader> ret;
 
-    return sm_mapCache.empty();
-}
+    MG_TRY()
 
-///////////////////////////////////////////////////////////////////////////////
-/// \brief
-/// Detect if the tile file has been locked by another thread or process.
-///
-bool MgServerTileService::DetectTileLockFile(CREFSTRING lockPathname)
-{
-    bool found = false;
-    struct _stat64 lockFileInfo;
+    if (NULL == map || baseMapLayerGroupName.empty())
+    {
+        throw new MgNullArgumentException(L"MgServerTileService.GetTile",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
 
-    // Check the lock file to see if another thread/process is writing the tile file.
-    while (MgFileUtil::GetFileStatus(lockPathname, lockFileInfo))
+    // find the finite display scale closest to the requested map scale
+    double scale = map->GetViewScale();
+    INT32 scaleIndex = map->FindNearestFiniteDisplayScaleIndex(scale);
+
+    // if we don't find a nearest scale then something is wrong with the map
+    if (scaleIndex < 0)
     {
-        time_t currTime;
-        ACE_OS::time(&currTime);
-        INT32 diffTime = (INT32)(currTime - lockFileInfo.st_mtime);
-
-        if (diffTime < sm_creationCutoffTime)
-        {
-            ACE_OS::sleep(sm_pollingInterval);
-        }
-        else
-        {
-            found = true;
-            break;
-        }
+        throw new MgInvalidMapDefinitionException(L"MgServerTileService.GetTile",
+            __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    return found;
+    Ptr<MgTileCacheDefault> cache = new MgTileCacheDefault(map);
+    ret = cache->GetTile(baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetTile")
+
+    return ret.Detach();
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-// Create tilename from mapDefinition, scaleIndex, row, and column.
-// Remove lockfile, look for the tile in the cache, if not in cache create
-// lockfile and look for map in mapcache.
-MgByteReader* MgServerTileService::GetTile(MgResourceIdentifier* mapDefinition,
-                                           CREFSTRING baseMapLayerGroupName,
-                                           INT32 tileColumn,
-                                           INT32 tileRow,
-                                           INT32 scaleIndex)
+MgByteReader* MgServerTileService::GetTile(
+    MgResourceIdentifier* resource,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow,
+    INT32 scaleIndex)
 {
     Ptr<MgByteReader> ret;
-    FILE* lockFile = NULL;
-    STRING tilePathname, lockPathname;
 
     MG_TRY()
 
-    if (NULL == mapDefinition || baseMapLayerGroupName.empty())
+    if (NULL == resource || baseMapLayerGroupName.empty())
     {
         throw new MgNullArgumentException(L"MgServerTileService.GetTile",
             __LINE__, __WFILE__, NULL, L"", NULL);
     }
+        
+    Ptr<MgTileCache> cache = GetTileCache(resource);
+    ret = cache->GetTile(baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
 
-    if (scaleIndex < 0)
-    {
-        STRING buffer;
-        MgUtil::Int32ToString(scaleIndex, buffer);
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetTile")
 
-        MgStringCollection arguments;
-        arguments.Add(L"5");
-        arguments.Add(buffer);
+    return ret.Detach();
+}
 
-        throw new MgInvalidArgumentException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, &arguments, L"MgInvalidScaleIndex", NULL);
-    }
+void MgServerTileService::ClearCache(MgMap* map)
+{
+    MG_TRY()
 
-    // get the service from our helper method
-    Ptr<MgResourceService> resourceService = GetResourceServiceForMapDef(mapDefinition,
-                                            L"MgServerTileService.GetTile");
-    // Generate tile and lock pathnames.
-    m_tileCache->GeneratePathnames(mapDefinition, scaleIndex, baseMapLayerGroupName,
-        tileColumn, tileRow, tilePathname, lockPathname, false);
+    CHECKARGUMENTNULL(map, L"MgServerTileService.ClearCache");
 
-    // If there is a dangling lock file, then attempt to remove it.
-    if (DetectTileLockFile(lockPathname))
-    {
-        // TODO: Handle the exception by displaying a tile with an error message?
-        MgFileUtil::DeleteFile(lockPathname, true);
-    }
+    Ptr<MgTileCacheDefault> cache = new MgTileCacheDefault(map);
+    cache->Clear();
 
-    // try getting the tile from the cache
-    ret = m_tileCache->Get(tilePathname);
+    MG_CATCH_AND_THROW(L"MgServerTileService.ClearCache")
+}
 
-    // if the reader is NULL then the tile wasn't in the cache and we
-    // need to generate it
-    while (NULL == ret)
-    {
-        // Attempt use a cached & serialized MgMap object
-        Ptr<MgMemoryStreamHelper> cachedMap;
-        STRING mapString = mapDefinition->ToString();
-        Ptr<MgMap> map;
+void MgServerTileService::ClearCache(MgResourceIdentifier* tileSet)
+{
+    MG_TRY()
 
-        // Protect the serialized MgMap cache with a mutex.  Stream reading is not
-        // thread safe so we need to deserialize the map within the mutex to ensure
-        // that a Rewind() is not called in the middle of a Deserialize().
-        // Lockfile test and creation is in same protected scope.
-        {
-            // Attempt to lock the tile file.
-            ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
+    CHECKARGUMENTNULL(tileSet, L"MgServerTileService.ClearCache");
 
-            // Bail out if the tile file has been locked for so long.
-            if (DetectTileLockFile(lockPathname))
-            {
-                MgStringCollection arguments;
-                arguments.Add(lockPathname);
+    Ptr<MgTileCache> cache = GetTileCache(tileSet);
+    cache->Clear();
 
-                throw new MgFileIoException(L"MgServerTileService.GetTile",
-                    __LINE__, __WFILE__, &arguments, L"MgUnableToLockTileFile", NULL);
-            }
+    MG_CATCH_AND_THROW(L"MgServerTileService.ClearCache")
+}
 
-            // try getting the tile from the cache
-            ret = m_tileCache->Get(tilePathname);
+INT32 MgServerTileService::GetDefaultTileSizeX()
+{
+    return MgTileParameters::tileWidth;
+}
 
-            if (NULL != ret)
-            {
-                break;  // tile was in tileCache .. done.
-            }
+INT32 MgServerTileService::GetDefaultTileSizeY()
+{
+    return MgTileParameters::tileHeight;
+}
 
-            // Create the lock file and close it right away.
-            m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
-            lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+INT32 MgServerTileService::GetDefaultTileSizeX(MgResourceIdentifier* tileSet)
+{
+    INT32 ret = 0;
 
-            if (NULL == lockFile)
-            {
-                MgStringCollection arguments;
-                arguments.Add(lockPathname);
+    MG_TRY()
 
-                throw new MgFileIoException(L"MgServerTileService.GetTile",
-                    __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
-            }
-            else
-            {
-                ACE_OS::fclose(lockFile);
-            }
+    Ptr<MgTileCache> cache = GetTileCache(tileSet);
+    ret = cache->GetDefaultTileSizeX();
 
-            MapCache::const_iterator iter = sm_mapCache.find(mapString);
-            if (sm_mapCache.end() != iter)
-            {
-                cachedMap = SAFE_ADDREF((*iter).second);
-                cachedMap->Rewind();
-                Ptr<MgStream> stream = new MgStream(cachedMap);
-                map = new MgMap();
-                map->Deserialize(stream);
-            }
-            else
-            {
-                Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
-                Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
-                siteConn->Open(userInfo);
-                map = new MgMap(siteConn);
-                map->Create(resourceService, mapDefinition, mapString);
-                cachedMap = new MgMemoryStreamHelper();
-                Ptr<MgStream> stream = new MgStream(cachedMap);
-                map->Serialize(stream);
-                if ((INT32)sm_mapCache.size() >= sm_mapCacheSize)
-                {
-                    ClearMapCache(L"");
-                }
-                sm_mapCache[mapString] = SAFE_ADDREF((MgMemoryStreamHelper*)cachedMap);
-            }
-        }   // end of mutex scope
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetDefaultTileSizeX")
+    
+    return ret;
+}
 
-        double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
-        map->SetViewScale(scale);
+INT32 MgServerTileService::GetDefaultTileSizeY(MgResourceIdentifier* tileSet)
+{
+    INT32 ret = 0;
 
-        // Render the tile and cache it.
-        ret = GetTile(tilePathname, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
-        break;
-    }
+    MG_TRY()
 
-    MG_CATCH(L"MgServerTileService.GetTile")
+    Ptr<MgTileCache> cache = GetTileCache(tileSet);
+    ret = cache->GetDefaultTileSizeX();
 
-    if (NULL != lockFile)
-    {
-        MgFileUtil::DeleteFile(lockPathname, false);
-    }
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetDefaultTileSizeY")
 
-    MG_THROW()
-
-    return ret.Detach();
+    return ret;
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-// look for the tile in the tilecache first
-MgByteReader* MgServerTileService::GetTile(MgMap* map,
-                                           CREFSTRING baseMapLayerGroupName,
-                                           INT32 tileColumn,
-                                           INT32 tileRow)
+MgByteReader* MgServerTileService::GetTileProviders()
 {
     Ptr<MgByteReader> ret;
-    FILE* lockFile = NULL;
-    STRING tilePathname, lockPathname;
 
     MG_TRY()
 
-    if (NULL == map || baseMapLayerGroupName.empty())
-    {
-        throw new MgNullArgumentException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+    //This response is obviously pre-canned right now. If we do want to FDO-ize tile provider support
+    //we obviously should revisit this.
 
-    // find the finite display scale closest to the requested map scale
-    double scale = map->GetViewScale();
-    INT32 scaleIndex = map->FindNearestFiniteDisplayScaleIndex(scale);
+    std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+    xml.append("<TileProviderList xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"TileProviderList-3.0.0.xsd\">\n");
 
-    // if we don't find a nearest scale then something is wrong with the map
-    if (scaleIndex < 0)
+    //Default Tile Provider
     {
-        throw new MgInvalidMapDefinitionException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, NULL, L"", NULL);
-    }
+        xml.append("<TileProvider>\n");
+        xml.append("<Name>");
+        std::string mbName;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_DEFAULT, mbName);
+        xml.append(mbName);
+        xml.append("</Name>\n");
+        xml.append("<DisplayName>");
+        std::string mbDisplayName;
+        STRING wDisplayName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_DisplayName");
+        MgUtil::WideCharToMultiByte(wDisplayName, mbDisplayName);
+        xml.append(mbDisplayName);
+        xml.append("</DisplayName>\n");
+        xml.append("<Description>");
+        std::string mbDescription;
+        STRING wDescription = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Default_Description");
+        MgUtil::WideCharToMultiByte(wDescription, mbDescription);
+        xml.append(mbDescription);
+        xml.append("</Description>\n");
+        xml.append("<ConnectionProperties>\n");
+    
+        //Property: TilePath
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTilePath;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH, mbTilePath);
+        xml.append(mbTilePath);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocName;
+        STRING wLocName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TilePath_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocName, mbLocName);
+        xml.append(mbLocName);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTag;
+        MgUtil::WideCharToMultiByte(MgResourceTag::TileCachePath, mbDefaultTag);
+        xml.append(mbDefaultTag);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
+    
+        //Property: TileWidth
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileWidth;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEWIDTH, mbTileWidth);
+        xml.append(mbTileWidth);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileWidth;
+        STRING wLocTileWidth = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileWidth_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileWidth, mbLocTileWidth);
+        xml.append(mbLocTileWidth);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTileWidth;
+        MgUtil::Int32ToString(MgConfigProperties::DefaultTileServicePropertyTileSizeX, mbDefaultTileWidth);
+        xml.append(mbDefaultTileWidth);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-    // Detect the lock file to see if another thread is creating the tile file.
-    m_tileCache->GeneratePathnames(map, scaleIndex, baseMapLayerGroupName,
-        tileColumn, tileRow, tilePathname, lockPathname, false);
+        //Property: TileHeight
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileHeight;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT, mbTileHeight);
+        xml.append(mbTileHeight);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileHeight;
+        STRING wLocTileHeight = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileHeight_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileHeight, mbLocTileHeight);
+        xml.append(mbLocTileHeight);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTileHeight;
+        MgUtil::Int32ToString(MgConfigProperties::DefaultTileServicePropertyTileSizeY, mbDefaultTileHeight);
+        xml.append(mbDefaultTileHeight);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-    // If there is a dangling lock file, then attempt to remove it.
-    if (DetectTileLockFile(lockPathname))
-    {
-        // TODO: Handle the exception by displaying a tile with an error message?
-        MgFileUtil::DeleteFile(lockPathname, true);
-    }
+        //Property: TileFormat
+        xml.append("<ConnectionProperty Enumerable=\"true\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileFormat;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT, mbTileFormat);
+        xml.append(mbTileFormat);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileFormat;
+        STRING wLocTileFormat = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileFormat_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileFormat, mbLocTileFormat);
+        xml.append(mbLocTileFormat);
+        xml.append("</LocalizedName>\n");
+        //Image formats supported by our tile service
+        xml.append("<DefaultValue>PNG</DefaultValue>\n");
+        xml.append("<Value>PNG</Value>");
+        xml.append("<Value>PNG8</Value>");
+        xml.append("<Value>JPG</Value>");
+        xml.append("<Value>GIF</Value>");
 
-    // try getting the tile from the cache
-    ret = m_tileCache->Get(tilePathname);
+        xml.append("</ConnectionProperty>\n");
 
-    // if the reader is NULL then the tile wasn't in the cache and we
-    // need to generate it
-    while (NULL == ret)
-    {
-        {
-            // Attemp to lock the tile file.
-            ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
+        //Property: RenderOnly
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"false\">\n");
+        xml.append("<Name>");
+        std::string mbRenderOnly;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_RENDERONLY, mbRenderOnly);
+        xml.append(mbRenderOnly);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocRenderOnly;
+        STRING wLocRenderOnly = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_RenderOnly_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocRenderOnly, mbLocRenderOnly);
+        xml.append(mbLocRenderOnly);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>false</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-            // Bail out if the tile file has been locked for so long.
-            if (DetectTileLockFile(lockPathname))
-            {
-                MgStringCollection arguments;
-                arguments.Add(lockPathname);
+        //Property: CoordinateSystem
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbCoordSys;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_COORDINATESYSTEM, mbCoordSys);
+        xml.append(mbCoordSys);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocCoordSys;
+        STRING wLocCoordSys = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_CoordinateSystem_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocCoordSys, mbLocCoordSys);
+        xml.append(mbLocCoordSys);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue></DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-                throw new MgFileIoException(L"MgServerTileService.GetTile",
-                    __LINE__, __WFILE__, &arguments, L"MgUnableToLockTileFile", NULL);
-            }
+        //Property: FiniteScaleList
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbFiniteScaleList;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST, mbFiniteScaleList);
+        xml.append(mbFiniteScaleList);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocFiniteScaleList;
+        STRING wLocFiniteScaleList = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_FiniteScaleList_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocFiniteScaleList, mbLocFiniteScaleList);
+        xml.append(mbLocFiniteScaleList);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue></DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-            // try getting the tile from the cache
-            ret = m_tileCache->Get(tilePathname);
+        xml.append("</ConnectionProperties>\n");
+        xml.append("</TileProvider>\n");
+    }
+    //XYZ Tile Provider
+    {
+        xml.append("<TileProvider>\n");
+        xml.append("<Name>");
+        std::string mbName;
+        STRING wName = MG_TILE_PROVIDER_XYZ;
+        MgUtil::WideCharToMultiByte(wName, mbName);
+        xml.append(mbName);
+        xml.append("</Name>\n");
+        xml.append("<DisplayName>");
+        std::string mbDisplayName;
+        STRING wDisplayName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_XYZ_DisplayName");
+        MgUtil::WideCharToMultiByte(wDisplayName, mbDisplayName);
+        xml.append(mbDisplayName);
+        xml.append("</DisplayName>\n");
+        xml.append("<Description>");
+        std::string mbDescription;
+        STRING wDescription = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_XYZ_Description");
+        MgUtil::WideCharToMultiByte(wDescription, mbDescription);
+        xml.append(mbDescription);
+        xml.append("</Description>\n");
+        xml.append("<ConnectionProperties>\n");
+    
+        //Property: TilePath
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTilePath;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH, mbTilePath);
+        xml.append(mbTilePath);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocName;
+        STRING wLocName = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TilePath_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocName, mbLocName);
+        xml.append(mbLocName);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>");
+        std::string mbDefaultTag;
+        MgUtil::WideCharToMultiByte(MgResourceTag::TileCachePath, mbDefaultTag);
+        xml.append(mbDefaultTag);
+        xml.append("</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-            if (NULL != ret)
-            {
-                break;
-            }
+        //Property: TileFormat
+        xml.append("<ConnectionProperty Enumerable=\"true\" Protected=\"false\" Required=\"true\">\n");
+        xml.append("<Name>");
+        std::string mbTileFormat;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT, mbTileFormat);
+        xml.append(mbTileFormat);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocTileFormat;
+        STRING wLocTileFormat = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_TileFormat_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocTileFormat, mbLocTileFormat);
+        xml.append(mbLocTileFormat);
+        xml.append("</LocalizedName>\n");
+        //Image formats supported by our tile service
+        xml.append("<DefaultValue>PNG</DefaultValue>\n");
+        xml.append("<Value>PNG</Value>");
+        xml.append("<Value>PNG8</Value>");
+        xml.append("<Value>JPG</Value>");
+        xml.append("<Value>GIF</Value>");
 
-            // Create the lock file and close it right away.
-            m_tileCache->CreateFullPath(map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
-            lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+        xml.append("</ConnectionProperty>\n");
 
-            if (NULL == lockFile)
-            {
-                MgStringCollection arguments;
-                arguments.Add(lockPathname);
+        //Property: RenderOnly
+        xml.append("<ConnectionProperty Enumerable=\"false\" Protected=\"false\" Required=\"false\">\n");
+        xml.append("<Name>");
+        std::string mbRenderOnly;
+        MgUtil::WideCharToMultiByte(MG_TILE_PROVIDER_COMMON_PARAM_RENDERONLY, mbRenderOnly);
+        xml.append(mbRenderOnly);
+        xml.append("</Name>\n");
+        xml.append("<LocalizedName>");
+        std::string mbLocRenderOnly;
+        STRING wLocRenderOnly = MgUtil::GetResourceMessage(MgResources::TileService, L"MgTileProvider_Common_Property_RenderOnly_LocalizedName");
+        MgUtil::WideCharToMultiByte(wLocRenderOnly, mbLocRenderOnly);
+        xml.append(mbLocRenderOnly);
+        xml.append("</LocalizedName>\n");
+        xml.append("<DefaultValue>false</DefaultValue>\n");
+        xml.append("</ConnectionProperty>\n");
 
-                throw new MgFileIoException(L"MgServerTileService.GetTile",
-                    __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
-            }
-            else
-            {
-                ACE_OS::fclose(lockFile);
-            }
-        }
-
-        // Render the tile and cache it.
-        ret = GetTile(tilePathname, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
-        break;
+        xml.append("</ConnectionProperties>\n");
+        xml.append("</TileProvider>\n");
     }
 
-    MG_CATCH(L"MgServerTileService.GetTile")
+    xml.append("</TileProviderList>");
 
-    if (NULL != lockFile)
-    {
-        MgFileUtil::DeleteFile(lockPathname, false);
-    }
+    Ptr<MgByteSource> source = new MgByteSource((BYTE_ARRAY_IN)xml.c_str(), (INT32)xml.length());
+    source->SetMimeType(MgMimeType::Xml);
+    ret = source->GetReader();
 
-    MG_THROW()
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetTileProviders")
 
     return ret.Detach();
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-// render a tile and store it in the cache
-MgByteReader* MgServerTileService::GetTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
-    CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)
+void MgServerTileService::SetTile(
+    MgByteReader* img,
+    MgMap* map,
+    INT32 scaleIndex,
+    CREFSTRING baseMapLayerGroupName,
+    INT32 tileColumn,
+    INT32 tileRow)
 {
-    Ptr<MgByteReader> img;
+    MG_TRY()
 
-    // get a rendering service instance
-    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
-    Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
-        serviceMan->RequestService(MgServiceType::RenderingService));
-    assert(NULL != svcRendering);
+    Ptr<MgTileCacheDefault> cache = new MgTileCacheDefault(map);
+    cache->SetTile(baseMapLayerGroupName, tileColumn, tileRow, scaleIndex, img);
 
-    if (svcRendering != NULL)
-    {
-        // generate the tile
-        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow);
-
-        // cache the tile
-        if (!sm_renderOnly)
-        {
-            m_tileCache->Set(img, tilePathname);
-
-            // rewind the reader since setting the tile advances it to the end
-            if (img)
-            {
-                img->Rewind();
-            }
-        }
-    }
-
-    return img.Detach();
+    MG_CATCH_AND_THROW(L"MgServerTileService.SetTile")
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-// take a tile image and store it in the tilecache using lockfiles
-void MgServerTileService::SetTile(MgByteReader* img,
-                                  MgMap* map,
-                                  INT32 scaleIndex,
-                                  CREFSTRING baseMapLayerGroupName,
-                                  INT32 tileColumn,
-                                  INT32 tileRow)
+MgTileCache* MgServerTileService::GetTileCache(MgResourceIdentifier* resource)
 {
-    FILE* lockFile = NULL;
-    STRING tilePathname, lockPathname;
+    Ptr<MgTileCache> cache;
 
     MG_TRY()
 
-    if (NULL == img || NULL == map || baseMapLayerGroupName.empty())
+    if (resource->GetResourceType() == MgResourceType::MapDefinition)
     {
-        throw new MgNullArgumentException(L"MgServerTileService.SetTile",
-            __LINE__, __WFILE__, NULL, L"", NULL);
+        cache = new MgTileCacheDefault(resource);
     }
-
-    if (scaleIndex < 0)
+    else if (resource->GetResourceType() == MgResourceType::TileSetDefinition)
     {
-        STRING buffer;
-        MgUtil::Int32ToString(scaleIndex, buffer);
+        // get service manager
+        MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+        assert(NULL != serviceMan);
 
-        MgStringCollection arguments;
-        arguments.Add(L"3");
-        arguments.Add(buffer);
+        // Get the service from service manager
+        Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
+            serviceMan->RequestService(MgServiceType::ResourceService));
+        assert(NULL != resourceService);
 
-        throw new MgInvalidArgumentException(L"MgServerTileService.GetTile",
-            __LINE__, __WFILE__, &arguments, L"MgInvalidScaleIndex", NULL);
-    }
+        if (!resourceService->HasPermission(resource, MgResourcePermission::ReadOnly))
+        {
+            MG_LOG_AUTHENTICATION_ENTRY(MgResources::PermissionDenied.c_str());
 
-    // Generate tile and lock pathnames.
-    m_tileCache->GeneratePathnames(map, scaleIndex, baseMapLayerGroupName,
-        tileColumn, tileRow, tilePathname, lockPathname, true);
+            MgStringCollection arguments;
+            arguments.Add(resource->ToString());
 
-    {
-        // Attemp to lock the tile file.
-        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
-
-        if (DetectTileLockFile(lockPathname))
-        {
-            // Attemp to remove a dangling lock file.
-            MgFileUtil::DeleteFile(lockPathname, true);
+            throw new MgPermissionDeniedException(L"MgServerTileService.GetTileCache", __LINE__, __WFILE__, &arguments, L"", NULL);
         }
 
-        // Create the lock file and close it right away.
-        lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+        Ptr<MgByteReader> content = resourceService->GetResourceContent(resource);
+        Ptr<MgByteSink> sink = new MgByteSink(content);
+        std::string xml;
+        sink->ToStringUtf8(xml);
 
-        if (NULL == lockFile)
+        // Before parsing, do any substitutions on the content
+        MgUnmanagedDataManager::SubstituteDataPathAliases(xml);
+
+        // parse the tile set definition
+        MdfParser::SAX2Parser parser;
+        parser.ParseString(xml.c_str(), xml.size());
+
+        if (!parser.GetSucceeded())
         {
+            STRING errorMsg = parser.GetErrorMessage();
             MgStringCollection arguments;
-            arguments.Add(lockPathname);
+            arguments.Add(errorMsg);
+            throw new MgXmlParserException(L"MgServerTileService.GetTileCache", __LINE__, __WFILE__, &arguments, L"", NULL);
+        }
 
-            throw new MgFileIoException(L"MgServerTileService.SetTile",
-                __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
-        }
-        else
-        {
-            ACE_OS::fclose(lockFile);
-        }
+        MdfModel::TileSetDefinition* tileset = parser.DetachTileSetDefinition();
+        assert(NULL != tileset);
+        
+        cache = GetTileCache(resource, tileset);
     }
 
-    // cache the tile
-    m_tileCache->Set(img, tilePathname);
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetTileCache")
 
-    MG_CATCH(L"MgServerTileService.SetTile")
-
-    if (NULL != lockFile)
-    {
-        MgFileUtil::DeleteFile(lockPathname, false);
-    }
-
-    MG_THROW()
+    return cache.Detach();
 }
 
-
-///////////////////////////////////////////////////////////////////////////////
-// accessor method for resource service
-MgResourceService* MgServerTileService::GetResourceServiceForMapDef(MgResourceIdentifier* mapDefinition,
-                                                                    CREFSTRING funcName)
+MgTileCache* MgServerTileService::GetTileCache(MgResourceIdentifier* tileSetId, MdfModel::TileSetDefinition* tileset)
 {
-    // get service manager
-    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
+    Ptr<MgTileCache> cache;
 
-    // Get the service from service manager
-    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
-        serviceMan->RequestService(MgServiceType::ResourceService));
-    assert(NULL != resourceService);
+    MG_TRY()
 
-    if (!resourceService->HasPermission(mapDefinition, MgResourcePermission::ReadOnly))
+    MdfModel::TileStoreParameters* tilesetParams = tileset->GetTileStoreParameters();
+    const MdfModel::MdfString& provider = tilesetParams->GetTileProvider();
+    if (provider == MG_TILE_PROVIDER_DEFAULT)
     {
-        MG_LOG_AUTHENTICATION_ENTRY(MgResources::PermissionDenied.c_str());
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        INT32 width = 300;
+        INT32 height = 300;
+        STRING format = L"PNG";
+        STRING path;
+        bool bRenderOnly = false;
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH)
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEWIDTH)
+            {
+                width = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT)
+            {
+                height = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_RENDERONLY)
+            {
+                bRenderOnly = MgUtil::StringToBoolean(pair->GetValue());
+            }
+        }
 
-        MgStringCollection arguments;
-        arguments.Add(mapDefinition->ToString());
+        //If we find the cache path substitution tag, replace it with the default path from the configuration
+        if (path == MgResourceTag::TileCachePath)
+        {
+            path = MgTileParameters::tileCachePath;
+        }
 
-        throw new MgPermissionDeniedException(
-            funcName, __LINE__, __WFILE__, &arguments, L"", NULL);
+        cache = new MgTileCacheDefaultProvider(tileSetId, path, width, height, format, bRenderOnly);
     }
-    return resourceService.Detach();
-}
+    else if (provider == MG_TILE_PROVIDER_XYZ)
+    {
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        STRING format = L"PNG";
+        STRING path;
+        bool bRenderOnly = false;
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH)
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_RENDERONLY)
+            {
+                bRenderOnly = MgUtil::StringToBoolean(pair->GetValue());
+            }
+        }
 
+        //If we find the cache path substitution tag, replace it with the default path from the configuration
+        if (path == MgResourceTag::TileCachePath)
+        {
+            path = MgTileParameters::tileCachePath;
+        }
 
-///////////////////////////////////////////////////////////////////////////////
-void MgServerTileService::ClearCache(MgMap* map)
-{
-    MG_TRY()
+        cache = new MgTileCacheXYZProvider(tileSetId, path, format, bRenderOnly);
+    }
+    else 
+    {
+        MgStringCollection arguments;
+        arguments.Add(provider);
+        throw new MgUnknownTileProviderException(L"MgServerTileService.GetTileCache", __LINE__, __WFILE__, &arguments, L"UnknownTileProvider", NULL);
+    }
 
-    if (NULL == map)
-        throw new MgNullArgumentException(L"MgServerTileService.ClearCache", __LINE__, __WFILE__, NULL, L"", NULL);
+    MG_CATCH_AND_THROW(L"MgServerTileService.GetTileCache")
 
-    Ptr<MgResourceIdentifier> resourceId = map->GetMapDefinition();
-    ClearMapCache(resourceId->ToString());
+    return cache.Detach();
+}
 
-    m_tileCache->Clear(map);
-
-    MG_CATCH_AND_THROW(L"MgServerTileService.ClearCache")
+bool MgServerTileService::IsTileCacheEmpty() const
+{
+    return MgTileCacheDefault::IsTileCacheEmpty();
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief
 /// Handle the Resource Change Notification event.
@@ -558,16 +616,25 @@
                     dynamic_cast<MgResourceIdentifier*>(serializableObj.p);
                 ACE_ASSERT(NULL != resource);
 
-                if (NULL != resource && resource->IsResourceTypeOf(MgResourceType::MapDefinition))
+                if (NULL != resource && (resource->IsResourceTypeOf(MgResourceType::MapDefinition) 
+                                     || resource->IsResourceTypeOf(MgResourceType::TileSetDefinition)))
                 {
                     MG_TRY()
 
-                    // clear any cached mgmap objects
-                    ClearMapCache(resource->ToString());
-
                     // clear any tile cache associated with this map
-                    m_tileCache->Clear(resource);
+                    Ptr<MgTileCache> cache = GetTileCache(resource);
+                    cache->Clear();
 
+                    //ACE_DEBUG ((LM_INFO, ACE_TEXT("(%t) Cleared tile cache for %W\n"), resource->ToString().c_str()));
+
+                    MgTileCacheDefault* cacheDefault = dynamic_cast<MgTileCacheDefault*>(cache.p);
+                    if (NULL != cacheDefault)
+                    {
+                        // clear any cached mgmap objects
+                        cacheDefault->ClearMapCache(resource->ToString());
+                        //ACE_DEBUG ((LM_INFO, ACE_TEXT("(%t) Cleared mem-cached MgMap instances for %W\n"), resource->ToString().c_str()));
+                    }
+
                     MG_CATCH(L"MgServerTileService.NotifyResourcesChanged")
 
                     if (NULL != mgException.p)
@@ -593,61 +660,8 @@
     return success;
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 void MgServerTileService::SetConnectionProperties(MgConnectionProperties*)
 {
     // Do nothing.  No connection properties are required for Server-side service objects.
 }
-
-
-///////////////////////////////////////////////////////////////////////////////
-void MgServerTileService::ClearMapCache(CREFSTRING mapDefinition)
-{
-    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
-    MapCache::iterator iter = sm_mapCache.end();
-    if (mapDefinition.empty())
-    {
-        for (iter = sm_mapCache.begin(); iter != sm_mapCache.end(); ++iter)
-        {
-            SAFE_RELEASE((*iter).second);
-            (*iter).second = NULL;
-        }
-        sm_mapCache.clear();
-
-        STRING message;
-        MgResources* resources = NULL;
-        MG_TRY()
-        resources = MgResources::GetInstance();
-        if (NULL != resources)
-        {
-            message = resources->GetResourceMessage(MgResources::ErrorDescription, L"MgMapCacheCleared", NULL);
-            MG_LOG_ERROR_ENTRY(message.c_str());
-        }
-        MG_CATCH_AND_RELEASE()
-    }
-    else
-    {
-        iter = sm_mapCache.find(mapDefinition);
-        if (sm_mapCache.end() != iter)
-        {
-            SAFE_RELEASE((*iter).second);
-            (*iter).second = NULL;
-            sm_mapCache.erase(iter);
-        }
-    }
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-INT32 MgServerTileService::GetDefaultTileSizeX()
-{
-    return MgTileParameters::tileWidth;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-INT32 MgServerTileService::GetDefaultTileSizeY()
-{
-    return MgTileParameters::tileHeight;
-}

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -21,68 +21,63 @@
 #include "ServerTileDllExport.h"
 #include "TileCache.h"
 
+namespace MdfModel
+{
+    class TileSetDefinition;
+}
+
 class MG_SERVER_TILE_API MgServerTileService : public MgTileService
 {
     DECLARE_CLASSNAME(MgServerTileService)
-
 public:
     MgServerTileService();
     ~MgServerTileService();
     DECLARE_CREATE_SERVICE()
 
-    virtual MgByteReader* GetTile(MgMap* map,
-                                  CREFSTRING baseMapLayerGroupName,
-                                  INT32 tileColumn,
-                                  INT32 tileRow);
+    virtual MgByteReader* GetTile(
+        MgMap* map,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow);
 
-    virtual MgByteReader* GetTile(MgResourceIdentifier* mapDefinition,
-                                  CREFSTRING baseMapLayerGroupName,
-                                  INT32 tileColumn,
-                                  INT32 tileRow,
-                                  INT32 scaleIndex);
+    virtual MgByteReader* GetTile(
+        MgResourceIdentifier* resource,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow,
+        INT32 scaleIndex);
 
-    virtual void SetTile(MgByteReader* img,
-                         MgMap* map,
-                         INT32 scaleIndex,
-                         CREFSTRING baseMapLayerGroupName,
-                         INT32 tileColumn,
-                         INT32 tileRow);
-
     virtual void ClearCache(MgMap* map);
 
+    virtual void ClearCache(MgResourceIdentifier* tileSet);
+
     virtual INT32 GetDefaultTileSizeX();
 
     virtual INT32 GetDefaultTileSizeY();
 
-    virtual bool IsTileCacheEmpty() const;
-    virtual bool NotifyResourcesChanged(MgSerializableCollection* resources,
-        bool strict = true);
+    virtual INT32 GetDefaultTileSizeX(MgResourceIdentifier* tileSet);
 
-    void SetConnectionProperties(MgConnectionProperties* connProp);
+    virtual INT32 GetDefaultTileSizeY(MgResourceIdentifier* tileSet);
 
-private:
+    virtual MgByteReader* GetTileProviders();
 
-    bool DetectTileLockFile(CREFSTRING lockPathname);
+    virtual void SetTile(
+        MgByteReader* img,
+        MgMap* map,
+        INT32 scaleIndex,
+        CREFSTRING baseMapLayerGroupName,
+        INT32 tileColumn,
+        INT32 tileRow);
 
-    MgByteReader* GetTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
-        CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+    virtual bool IsTileCacheEmpty() const;
 
-    void ClearMapCache(CREFSTRING mapName);
+    virtual bool NotifyResourcesChanged(MgSerializableCollection* resources, bool strict = true);
 
-    MgResourceService* GetResourceServiceForMapDef(MgResourceIdentifier* mapDefinition, CREFSTRING funcName);
+    void SetConnectionProperties(MgConnectionProperties* connProp);
 
-    // member data
-    Ptr<MgTileCache> m_tileCache;
-
-    typedef std::map<STRING, MgMemoryStreamHelper*> MapCache;
-
-    static ACE_Recursive_Thread_Mutex sm_mutex;
-    static bool sm_initialized;
-    static MapCache sm_mapCache;
-    static bool sm_renderOnly;
-    static INT32 sm_creationCutoffTime;
-    static INT32 sm_pollingInterval;
-    static INT32 sm_mapCacheSize;
+private:
+    MgTileCache* GetTileCache(MgResourceIdentifier* resource);
+    MgTileCache* GetTileCache(MgResourceIdentifier* tileSetId, MdfModel::TileSetDefinition* tileset);
 };
 
 #endif

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -94,7 +94,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -104,9 +104,9 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACEd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACEd.lib;MgMdfModeld.lib;MgMdfParserd.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerTileServiced.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);..\..\..\..\Common\lib\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerTileServiced.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -120,7 +120,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -130,9 +130,9 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACEd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACEd.lib;MgMdfModeld.lib;MgMdfParserd.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerTileServiced.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);..\..\..\..\Common\lib\Debug64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerTileServiced.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -146,7 +146,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -155,9 +155,9 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACE.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACE.lib;MgMdfModel.lib;MgMdfParser.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerTileService.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);..\..\..\..\Common\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerTileService.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -173,7 +173,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Mapping;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\dbxml\xerces-c-src\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_TILE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -182,9 +182,9 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACE.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACE.lib;MgMdfModel.lib;MgMdfParser.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerTileService.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);..\..\..\..\Common\lib\Release64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerTileService.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -222,12 +222,36 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="OpGetTileProviders.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="OpSetTile.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="TileCacheDefault.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="TileCacheDefaultProvider.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="TileCacheXYZProvider.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="TileOperation.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -271,7 +295,11 @@
     <ClInclude Include="OpGetDefaultTileSizeX.h" />
     <ClInclude Include="OpGetDefaultTileSizeY.h" />
     <ClInclude Include="OpGetTile.h" />
+    <ClInclude Include="OpGetTileProviders.h" />
     <ClInclude Include="OpSetTile.h" />
+    <ClInclude Include="TileCacheDefault.h" />
+    <ClInclude Include="TileCacheDefaultProvider.h" />
+    <ClInclude Include="TileCacheXYZProvider.h" />
     <ClInclude Include="TileOperation.h" />
     <ClInclude Include="TileOperationFactory.h" />
     <ClInclude Include="ServerTileDllExport.h" />

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj.filters
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -32,6 +32,12 @@
     <ClCompile Include="ServerTileServiceBuild.cpp" />
     <ClCompile Include="TileCache.cpp" />
     <ClCompile Include="TileServiceHandler.cpp" />
+    <ClCompile Include="TileCacheDefault.cpp" />
+    <ClCompile Include="TileCacheDefaultProvider.cpp" />
+    <ClCompile Include="OpGetTileProviders.cpp">
+      <Filter>Ops</Filter>
+    </ClCompile>
+    <ClCompile Include="TileCacheXYZProvider.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="OpClearCache.h">
@@ -60,6 +66,12 @@
     <ClInclude Include="..\..\Common\stdafx.h" />
     <ClInclude Include="TileCache.h" />
     <ClInclude Include="TileServiceHandler.h" />
+    <ClInclude Include="TileCacheDefault.h" />
+    <ClInclude Include="TileCacheDefaultProvider.h" />
+    <ClInclude Include="OpGetTileProviders.h">
+      <Filter>Ops</Filter>
+    </ClInclude>
+    <ClInclude Include="TileCacheXYZProvider.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ServerTileService.rc" />

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileServiceBuild.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileServiceBuild.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileServiceBuild.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -23,7 +23,11 @@
 #include "OpSetTile.cpp"
 #include "OpGetDefaultTileSizeX.cpp"
 #include "OpGetDefaultTileSizeY.cpp"
+#include "OpGetTileProviders.cpp"
 #include "TileCache.cpp"
+#include "TileCacheDefault.cpp"
+#include "TileCacheDefaultProvider.cpp"
+#include "TileCacheXYZProvider.cpp"
 #include "TileOperation.cpp"
 #include "TileOperationFactory.cpp"
 #include "TileServiceHandler.cpp"

Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -18,406 +18,12 @@
 #include "MapGuideCommon.h"
 #include "TileCache.h"
 
-const STRING SCALE_INDEX_PREFIX = L"S";
-const STRING ROW_PREFIX = L"R";
-const STRING COLUMN_PREFIX = L"C";
-
-STRING MgTileCache::sm_path = L"";
-INT32 MgTileCache::sm_tileColumnsPerFolder = 30;
-INT32 MgTileCache::sm_tileRowsPerFolder = 30;
-
-// default constructor
 MgTileCache::MgTileCache()
 {
-}
 
-///////////////////////////////////////////////////////////////////////////////
-/// \brief
-/// Initialize the tile cache configuration.
-///
-void MgTileCache::Initialize()
-{
-    if (sm_path.empty())
-    {
-        // initialize the tile cache path
-        MgConfiguration* configuration = MgConfiguration::GetInstance();
-
-        configuration->GetStringValue(
-            MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyTileCachePath,
-            sm_path,
-            MgConfigProperties::DefaultTileServicePropertyTileCachePath);
-
-        // generate directory location for tile cache
-        MgFileUtil::AppendSlashToEndOfPath(sm_path);
-
-        // create directory if it is not already there
-        MgFileUtil::CreateDirectory(sm_path, false, true);
-
-        configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyTileColumnsPerFolder,
-            sm_tileColumnsPerFolder,
-            MgConfigProperties::DefaultTileServicePropertyTileColumnsPerFolder);
-
-        configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyTileRowsPerFolder,
-            sm_tileRowsPerFolder,
-            MgConfigProperties::DefaultTileServicePropertyTileRowsPerFolder);
-
-        configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyTileSizeX,
-            MgTileParameters::tileWidth,
-            MgConfigProperties::DefaultTileServicePropertyTileSizeX);
-
-        configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyTileSizeY,
-            MgTileParameters::tileHeight,
-            MgConfigProperties::DefaultTileServicePropertyTileSizeY);
-
-        STRING format;
-        configuration->GetStringValue(MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyImageFormat,
-            format,
-            MgConfigProperties::DefaultTileServicePropertyImageFormat);
-
-        // Only allow GIF, PNG, PNG8 and JPG as tile formats
-        if (format == MgImageFormats::Png || format == MgImageFormats::Png8 || format == MgImageFormats::Jpeg || format == MgImageFormats::Gif)
-        {
-            MgTileParameters::tileFormat = format;
-        }
-        else
-        {
-            MgTileParameters::tileFormat = MgImageFormats::Png;
-        }
-    }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// \brief
-/// Generate tile and lock pathnames.
-///
-void MgTileCache::GeneratePathnames(MgResourceIdentifier* mapDef, int scaleIndex,
-    CREFSTRING group, int tileColumn, int tileRow,
-    STRING& tilePathname, STRING& lockPathname, bool createFullPath)
+MgTileCache::~MgTileCache()
 {
-    STRING fileName = L"/" + GetTileName(tileRow, tileColumn) + L".";
-    STRING basePath = GetBasePath(mapDef);
 
-    if (createFullPath)
-    {
-        tilePathname = CreateFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
-    }
-    else
-    {
-        tilePathname = GetFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
-    }
-
-    // Generate the tile and lock pathnames
-    //     <tilePathname> = <fullPath>/<row>_<column>.png/jpg
-    //     <lockPathname> = <fullPath>/<row>_<column>.lck
-    tilePathname += fileName;
-    lockPathname = tilePathname;
-    if (MgTileParameters::tileFormat == MgImageFormats::Jpeg)
-    {
-        tilePathname += L"jpg";
-    }
-    else if (MgTileParameters::tileFormat == MgImageFormats::Gif)
-    {
-        tilePathname += L"gif";
-    }
-    else
-    {
-        tilePathname += L"png";
-    }
-
-    lockPathname += L"lck";
 }
-
-void MgTileCache::GeneratePathnames(MgMap* map, int scaleIndex,
-    CREFSTRING group, int tileColumn, int tileRow,
-    STRING& tilePathname, STRING& lockPathname, bool createFullPath)
-{
-    assert(NULL != map);
-    Ptr<MgResourceIdentifier> mapDef = map->GetMapDefinition();
-
-    GeneratePathnames(mapDef, scaleIndex, group, tileColumn, tileRow,
-        tilePathname, lockPathname, createFullPath);
-}
-
-// returns any cached tile for the given pathname
-MgByteReader* MgTileCache::Get(CREFSTRING tilePathname)
-{
-    Ptr<MgByteReader> ret;
-
-    MG_TRY()
-
-    if (MgFileUtil::PathnameExists(tilePathname))
-    {
-        Ptr<MgByteSource> byteSource = new MgByteSource(tilePathname, false);
-
-        if (MgTileParameters::tileFormat == MgImageFormats::Jpeg)
-        {
-            byteSource->SetMimeType(MgMimeType::Jpeg);
-        }
-        else if (MgTileParameters::tileFormat == MgImageFormats::Gif)
-        {
-            byteSource->SetMimeType(MgMimeType::Gif);
-        }
-        else
-        {
-            byteSource->SetMimeType(MgMimeType::Png);
-        }
-
-        ret = byteSource->GetReader();
-    }
-
-    MG_CATCH_AND_RELEASE()
-
-    return ret.Detach();
-}
-
-// caches a tile for the given pathname
-void MgTileCache::Set(MgByteReader* img, CREFSTRING tilePathname)
-{
-    if (img != NULL)
-    {
-        Ptr<MgByteSink> byteSink = new MgByteSink(img);
-
-        byteSink->ToFile(tilePathname);
-    }
-}
-
-// clears the tile cache for the given map
-void MgTileCache::Clear(MgMap* map)
-{
-    if (map != NULL)
-    {
-        STRING basePath = GetBasePath(map);
-
-        // delete main map directory
-        if (!basePath.empty())
-            MgFileUtil::DeleteDirectory(basePath, true, false);
-    }
-}
-
-// clears the tile cache for the given map
-void MgTileCache::Clear(MgResourceIdentifier* mapDef)
-{
-    // the resource must be a map definition
-    if (mapDef != NULL && mapDef->GetResourceType() == MgResourceType::MapDefinition)
-    {
-        STRING basePath = GetBasePath(mapDef);
-
-        // delete main map directory
-        if (!basePath.empty())
-            MgFileUtil::DeleteDirectory(basePath, true, false);
-    }
-}
-
-// gets the base path to use with the tile cache for the given map definition resource
-STRING MgTileCache::GetBasePath(MgResourceIdentifier* mapDef)
-{
-    assert(mapDef != NULL);
-    assert(mapDef->GetResourceType() == MgResourceType::MapDefinition);
-    STRING mapPath;
-
-    if (mapDef->GetRepositoryType() == MgRepositoryType::Library)
-    {
-        // for maps in the library repository the path+name is unique
-        mapPath  = mapDef->GetPath();
-        mapPath += L"_";
-        mapPath += mapDef->GetName();
-    }
-    else if (mapDef->GetRepositoryType() == MgRepositoryType::Session)
-    {
-        // for maps in the session repository we use the session + path + map name
-        mapPath  = mapDef->GetRepositoryName();
-        mapPath += L"_";
-
-        STRING resourcePath  = mapDef->GetPath();
-
-        if (!resourcePath.empty())
-        {
-            mapPath += resourcePath;
-            mapPath += L"_";
-        }
-
-        mapPath += mapDef->GetName();
-    }
-    else
-    {
-        // shouldn't get here
-        assert(false);
-        return mapPath;
-    }
-
-    // for safety
-    mapPath = MgUtil::ReplaceString(mapPath, L"/", L"_");
-    mapPath = MgUtil::ReplaceString(mapPath, L":", L"_");
-
-    // Build the base path using format "%ls%ls":
-    //     <basePath> = <tileCachePath><mapPath>
-    STRING basePath = sm_path;
-    basePath += mapPath;
-
-    return basePath;
-}
-
-// gets the base path to use with the tile cache for the given map
-STRING MgTileCache::GetBasePath(MgMap* map)
-{
-    assert(NULL != map);
-    Ptr<MgResourceIdentifier> mapDef = map->GetMapDefinition();
-    return GetBasePath(mapDef);
-}
-
-// gets the full path to use with the tile cache for the given base path / scale index / group
-STRING MgTileCache::GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    // Build full path
-    //     <fullPath> = <basePath>/<scaleIndex>/<group>/<rowFolder>/<columnFolder>
-    assert(!basePath.empty());
-    STRING fullPath = basePath;
-
-    fullPath += L"/";
-    fullPath += GetScaleIndexFolder(scaleIndex);
-
-    fullPath += L"/";
-    fullPath += group;
-
-    fullPath += L"/";
-    fullPath += GetRowFolder(tileRow);
-
-    fullPath += L"/";
-    fullPath += GetColumnFolder(tileColumn);
-
-    return fullPath;
-}
-
-// gets the full path to use with the tile cache for the given map definition / scale index / group
-STRING MgTileCache::GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    return GetFullPath(GetBasePath(mapDef), scaleIndex, group, tileColumn, tileRow);
-}
-
-// gets the full path to use with the tile cache for the given map / scale index / group
-STRING MgTileCache::GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    assert(NULL != map);
-    Ptr<MgResourceIdentifier> mapDef = map->GetMapDefinition();
-    return GetFullPath(mapDef, scaleIndex, group, tileColumn, tileRow);
-}
-
-STRING MgTileCache::CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    assert(!basePath.empty());
-    STRING fullPath = basePath;
-
-    // Create base directory if it does not exist.
-    MgFileUtil::CreateDirectory(fullPath, false);
-
-    // Create scale directory if it does not exist.
-    fullPath += L"/";
-    fullPath += GetScaleIndexFolder(scaleIndex);
-    MgFileUtil::CreateDirectory(fullPath, false);
-
-    // Create group directory if it does not exist.
-    fullPath += L"/";
-    fullPath += group;
-    MgFileUtil::CreateDirectory(fullPath, false);
-
-    // Create row directory if it does not exist.
-    fullPath += L"/";
-    fullPath += GetRowFolder(tileRow);
-    MgFileUtil::CreateDirectory(fullPath, false);
-
-    // Create column directory if it does not exist.
-    fullPath += L"/";
-    fullPath += GetColumnFolder(tileColumn);
-    MgFileUtil::CreateDirectory(fullPath, false);
-
-    return fullPath;
-}
-
-STRING MgTileCache::CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    return CreateFullPath(GetBasePath(mapDef), scaleIndex, group, tileColumn, tileRow);
-}
-
-STRING MgTileCache::CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
-{
-    return CreateFullPath(GetBasePath(map), scaleIndex, group, tileColumn, tileRow);
-}
-
-// Get the folder name corresponding to the specified scale index
-STRING MgTileCache::GetScaleIndexFolder(int scaleIndex)
-{
-    STRING scaleIndexString;
-    MgUtil::Int32ToString(scaleIndex, scaleIndexString);
-    return SCALE_INDEX_PREFIX + scaleIndexString;
-}
-
-// Get the folder name corresponding to the specified tile row
-STRING MgTileCache::GetRowFolder(int tileRow)
-{
-    return GetFolder(ROW_PREFIX, tileRow, sm_tileRowsPerFolder);
-}
-
-// Get the folder name corresponding to the specified tile column
-STRING MgTileCache::GetColumnFolder(int tileColumn)
-{
-    return GetFolder(COLUMN_PREFIX, tileColumn, sm_tileColumnsPerFolder);
-}
-
-// Get the parent folder for a given row or column
-STRING MgTileCache::GetFolder(STRING prefix, int tileIndex, int tilesPerFolder)
-{
-    STRING folder;
-
-    // Determine which folder contains this tile
-    int folderIndex = tileIndex / tilesPerFolder;
-    int firstTileIndex = folderIndex * tilesPerFolder;
-    if(tileIndex < 0 && firstTileIndex == 0)
-    {
-        folder = L"-0";
-    }
-    else
-    {
-        MgUtil::Int32ToString(firstTileIndex, folder);
-    }
-    return prefix + folder;
-}
-
-// Get the filename corresponding to the specified row and column.
-// No file extension is added.
-STRING MgTileCache::GetTileName(int tileRow, int tileColumn)
-{
-    return GetTileIndexString(tileRow, sm_tileRowsPerFolder) + L"_" +
-        GetTileIndexString(tileColumn, sm_tileColumnsPerFolder);
-}
-
-// When a tile is stored in a folder, the index value of the parent folder
-// is subtracted from the overall tile index.
-// e.g. If we store 30 rows of tiles per folder, a tile with overall row
-// index 73 will be stored in the row folder "R60" with a row index of 13.
-// Note: Negative values are maintained even near the origin, so a tile with
-// an overall row index of -13 would be stored in row folder "R-0" with a
-// row index of -13.
-STRING MgTileCache::GetTileIndexString(int tileIndex, int tilesPerFolder)
-{
-    STRING name;
-
-    // Determine the offset of this tile within the folder
-    int tileNameIndex = tileIndex % tilesPerFolder;
-    if(tileIndex < 0 && tileNameIndex == 0)
-    {
-        name = L"-0";
-    }
-    else
-    {
-        MgUtil::Int32ToString(tileNameIndex, name);
-    }
-    return name;
-}
-
-

Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.h
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -20,61 +20,30 @@
 
 #include "ServerTileDllExport.h"
 
-// File-system-based cache for base map layer group tiles generated by the rendering service.
+//An abstract tile cache
 class MG_SERVER_TILE_API MgTileCache : public MgDisposable
 {
 public:
     MgTileCache();
+    virtual ~MgTileCache();
 
-    static void Initialize();
+    virtual MgByteReader* GetTile(CREFSTRING baseMapLayerGroupName,
+                                  INT32 tileColumn,
+                                  INT32 tileRow,
+                                  INT32 scaleIndex) = 0;
 
-    void GeneratePathnames(MgResourceIdentifier* mapDef, int scaleIndex,
-        CREFSTRING group, int tileColumn, int tileRow,
-        STRING& tilePathname, STRING& lockPathname, bool createFullPath);
-    void GeneratePathnames(MgMap* map, int scaleIndex,
-        CREFSTRING group, int tileColumn, int tileRow,
-        STRING& tilePathname, STRING& lockPathname, bool createFullPath);
+    
+    virtual void SetTile(CREFSTRING baseMapLayerGroupName,
+                         INT32 tileColumn,
+                         INT32 tileRow,
+                         INT32 scaleIndex,
+                         MgByteReader* img) = 0;
 
-    STRING CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-    STRING CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    virtual void Clear() = 0;
 
-    MgByteReader* Get(CREFSTRING tilePathname);
-    void Set(MgByteReader* img, CREFSTRING tilePathname);
+    virtual INT32 GetDefaultTileSizeX() = 0;
 
-    void Clear(MgMap* map);
-    void Clear(MgResourceIdentifier* mapDef);
-
-protected:
-    virtual void Dispose()
-    {
-        delete this;
-    }
-
-private:
-    // Unimplemented Constructors/Methods
-    MgTileCache(const MgTileCache&);
-    MgTileCache& operator=(const MgTileCache&);
-
-    STRING GetBasePath(MgResourceIdentifier* mapDef);
-    STRING GetBasePath(MgMap* map);
-
-    STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-    STRING GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-    STRING GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-
-    STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
-
-    STRING GetScaleIndexFolder(int scaleIndex);
-    STRING GetRowFolder(int tileRow);
-    STRING GetColumnFolder(int tileColumn);
-    STRING GetFolder(STRING prefix, int tileIndex, int tilesPerFolder);
-
-    STRING GetTileName(int tileRow, int tileColumn);
-    STRING GetTileIndexString(int tileIndex, int tilesPerFolder);
-
-    static STRING sm_path;
-    static INT32 sm_tileColumnsPerFolder;
-    static INT32 sm_tileRowsPerFolder;
+    virtual INT32 GetDefaultTileSizeY() = 0;
 };
 
 #endif

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,937 @@
+//
+//  Copyright (C) 2004-2011 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "MapGuideCommon.h"
+#include "TileCacheDefault.h"
+#include "ServiceManager.h"
+
+const STRING SCALE_INDEX_PREFIX = L"S";
+const STRING ROW_PREFIX = L"R";
+const STRING COLUMN_PREFIX = L"C";
+
+STRING MgTileCacheDefault::sm_path = L"";
+INT32 MgTileCacheDefault::sm_tileColumnsPerFolder = 30;
+INT32 MgTileCacheDefault::sm_tileRowsPerFolder = 30;
+
+ACE_Recursive_Thread_Mutex MgTileCacheDefault::sm_mutex;
+MgTileCacheDefault::MapCache MgTileCacheDefault::sm_mapCache;
+bool MgTileCacheDefault::sm_initialized = false;
+bool MgTileCacheDefault::sm_renderOnly = false;
+INT32 MgTileCacheDefault::sm_creationCutoffTime = 120;     // in seconds
+INT32 MgTileCacheDefault::sm_pollingInterval = 1;          // in seconds
+INT32 MgTileCacheDefault::sm_mapCacheSize = 10;
+
+MgTileCacheDefault::MgTileCacheDefault()
+{
+    m_map = NULL;
+    m_resourceId = NULL;
+}
+
+MgTileCacheDefault::MgTileCacheDefault(MgMap* map)
+{
+    m_map = SAFE_ADDREF(map);
+    m_resourceId = NULL;
+}
+
+MgTileCacheDefault::MgTileCacheDefault(MgResourceIdentifier* resource)
+{
+    m_map = NULL;
+    m_resourceId = SAFE_ADDREF(resource);
+}
+
+MgTileCacheDefault::~MgTileCacheDefault()
+{
+
+}
+
+void MgTileCacheDefault::Initialize()
+{
+    if (!sm_initialized)
+    {
+        // Perform Double-Checked Locking Optimization.
+        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
+
+        if (!sm_initialized)
+        {
+            MgConfiguration* configuration = MgConfiguration::GetInstance();
+
+            configuration->GetBoolValue(
+                MgConfigProperties::TileServicePropertiesSection,
+                MgConfigProperties::TileServicePropertyRenderOnly,
+                sm_renderOnly,
+                MgConfigProperties::DefaultTileServicePropertyRenderOnly);
+
+            configuration->GetIntValue(
+                MgConfigProperties::TileServicePropertiesSection,
+                MgConfigProperties::TileServicePropertyCreationCutoffTime,
+                sm_creationCutoffTime,
+                MgConfigProperties::DefaultTileServicePropertyCreationCutoffTime);
+
+            configuration->GetIntValue(
+                MgConfigProperties::TileServicePropertiesSection,
+                MgConfigProperties::TileServicePropertyPollingInterval,
+                sm_pollingInterval,
+                MgConfigProperties::DefaultTileServicePropertyPollingInterval);
+
+            configuration->GetIntValue(
+                MgConfigProperties::TileServicePropertiesSection,
+                MgConfigProperties::TileServicePropertyTiledMapCacheSize,
+                sm_mapCacheSize,
+                MgConfigProperties::DefaultTileServicePropertyTiledMapCacheSize);
+
+            if (sm_path.empty())
+            {
+                configuration->GetStringValue(
+                    MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyTileCachePath,
+                    sm_path,
+                    MgConfigProperties::DefaultTileServicePropertyTileCachePath);
+
+                // generate directory location for tile cache
+                MgFileUtil::AppendSlashToEndOfPath(sm_path);
+
+                // create directory if it is not already there
+                MgFileUtil::CreateDirectory(sm_path, false, true);
+
+                MgTileParameters::tileCachePath = sm_path;
+
+                configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyTileColumnsPerFolder,
+                    sm_tileColumnsPerFolder,
+                    MgConfigProperties::DefaultTileServicePropertyTileColumnsPerFolder);
+
+                configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyTileRowsPerFolder,
+                    sm_tileRowsPerFolder,
+                    MgConfigProperties::DefaultTileServicePropertyTileRowsPerFolder);
+
+                configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyTileSizeX,
+                    MgTileParameters::tileWidth,
+                    MgConfigProperties::DefaultTileServicePropertyTileSizeX);
+
+                configuration->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyTileSizeY,
+                    MgTileParameters::tileHeight,
+                    MgConfigProperties::DefaultTileServicePropertyTileSizeY);
+
+                STRING format;
+                configuration->GetStringValue(MgConfigProperties::TileServicePropertiesSection,
+                    MgConfigProperties::TileServicePropertyImageFormat,
+                    format,
+                    MgConfigProperties::DefaultTileServicePropertyImageFormat);
+
+                // Only allow GIF, PNG, PNG8 and JPG as tile formats
+                if (format == MgImageFormats::Png || format == MgImageFormats::Png8 || format == MgImageFormats::Jpeg || format == MgImageFormats::Gif)
+                {
+                    MgTileParameters::tileFormat = format;
+                }
+                else
+                {
+                    MgTileParameters::tileFormat = MgImageFormats::Png;
+                }
+            }
+            sm_initialized = true;
+        }
+    }
+}
+
+MgByteReader* MgTileCacheDefault::GetTile(CREFSTRING baseMapLayerGroupName,
+                                          INT32 tileColumn,
+                                          INT32 tileRow,
+                                          INT32 scaleIndex)
+{
+    Ptr<MgByteReader> ret;
+
+    MG_TRY()
+
+    if (m_map != NULL)
+        ret = GetTileForMap(baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+    else if (m_resourceId != NULL)
+        ret = GetTileForResource(m_resourceId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+
+    MG_CATCH_AND_THROW(L"MgTileCacheDefault.GetTile")
+
+    return ret.Detach();
+}
+
+MgByteReader* MgTileCacheDefault::GetTileForResource(MgResourceIdentifier* resource,
+                                                     CREFSTRING baseMapLayerGroupName,
+                                                     INT32 tileColumn,
+                                                     INT32 tileRow,
+                                                     INT32 scaleIndex)
+{
+    Ptr<MgByteReader> ret;
+    FILE* lockFile = NULL;
+    STRING tilePathname, lockPathname;
+
+    MG_TRY()
+
+    if (NULL == (MgResourceIdentifier*)resource || baseMapLayerGroupName.empty())
+    {
+        throw new MgNullArgumentException(L"MgTileCacheDefault.GetTileForResource",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    if (scaleIndex < 0)
+    {
+        STRING buffer;
+        MgUtil::Int32ToString(scaleIndex, buffer);
+
+        MgStringCollection arguments;
+        arguments.Add(L"5");
+        arguments.Add(buffer);
+
+        throw new MgInvalidArgumentException(L"MgTileCacheDefault.GetTileForResource",
+            __LINE__, __WFILE__, &arguments, L"MgInvalidScaleIndex", NULL);
+    }
+
+    // get the service from our helper method
+    Ptr<MgResourceService> resourceService = GetResourceServiceForMapDef(resource,
+                                            L"MgTileCacheDefault.GetTileForResource");
+    // Generate tile and lock pathnames.
+    GeneratePathNames(scaleIndex, baseMapLayerGroupName, tileColumn, tileRow, tilePathname, lockPathname, false);
+
+    // If there is a dangling lock file, then attempt to remove it.
+    if (DetectTileLockFile(lockPathname))
+    {
+        // TODO: Handle the exception by displaying a tile with an error message?
+        MgFileUtil::DeleteFile(lockPathname, true);
+    }
+
+    // try getting the tile from the cache
+    ret = Get(tilePathname);
+
+    // if the reader is NULL then the tile wasn't in the cache and we
+    // need to generate it
+    while (NULL == ret)
+    {
+        // Attempt use a cached & serialized MgMap object
+        Ptr<MgMemoryStreamHelper> cachedMap;
+        STRING mapString = resource->ToString();
+        Ptr<MgMap> map;
+
+        // Protect the serialized MgMap cache with a mutex.  Stream reading is not
+        // thread safe so we need to deserialize the map within the mutex to ensure
+        // that a Rewind() is not called in the middle of a Deserialize().
+        // Lockfile test and creation is in same protected scope.
+        {
+            // Attempt to lock the tile file.
+            ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
+
+            // Bail out if the tile file has been locked for so long.
+            if (DetectTileLockFile(lockPathname))
+            {
+                MgStringCollection arguments;
+                arguments.Add(lockPathname);
+
+                throw new MgFileIoException(L"MgTileCacheDefault.GetTileForResource",
+                    __LINE__, __WFILE__, &arguments, L"MgUnableToLockTileFile", NULL);
+            }
+
+            // try getting the tile from the cache
+            ret = Get(tilePathname);
+
+            if (NULL != ret)
+            {
+                break;  // tile was in tileCache .. done.
+            }
+
+            // Create the lock file and close it right away.
+            CreateFullPath(scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+            lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+
+            if (NULL == lockFile)
+            {
+                MgStringCollection arguments;
+                arguments.Add(lockPathname);
+
+                throw new MgFileIoException(L"MgTileCacheDefault.GetTileForResource",
+                    __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
+            }
+            else
+            {
+                ACE_OS::fclose(lockFile);
+            }
+
+            MapCache::const_iterator iter = sm_mapCache.find(mapString);
+            if (sm_mapCache.end() != iter)
+            {
+                cachedMap = SAFE_ADDREF((*iter).second);
+                cachedMap->Rewind();
+                Ptr<MgStream> stream = new MgStream(cachedMap);
+                map = new MgMap();
+                map->Deserialize(stream);
+            }
+            else
+            {
+                Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
+                Ptr<MgUserInformation> userInfo = MgUserInformation::GetCurrentUserInfo();
+                siteConn->Open(userInfo);
+                map = new MgMap(siteConn);
+                map->Create(resourceService, resource, mapString, false /* Allow MgMap to be created from any tile provider if resource is tile set */);
+                cachedMap = new MgMemoryStreamHelper();
+                Ptr<MgStream> stream = new MgStream(cachedMap);
+                map->Serialize(stream);
+                if ((INT32)sm_mapCache.size() >= sm_mapCacheSize)
+                {
+                    ClearMapCache(L"");
+                }
+                sm_mapCache[mapString] = SAFE_ADDREF((MgMemoryStreamHelper*)cachedMap);
+            }
+        }   // end of mutex scope
+
+        //Some tile providers (eg. XYZ) may not work with pre-defined scale lists, so the scale index doesn't
+        //resolve to some position in a finite scale list (that won't exist for XYZ), but rather it is part of 
+        //some formula used to determine the appropriate scale
+        if (map->GetFiniteDisplayScaleCount() > 0)
+        {
+            double scale = map->GetFiniteDisplayScaleAt(scaleIndex);
+            map->SetViewScale(scale);
+        }
+
+        // Render the tile and cache it.
+        ret = RenderAndCacheTile(tilePathname, map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+        break;
+    }
+
+    MG_CATCH(L"MgTileCacheDefault.GetTileForResource")
+
+    if (NULL != lockFile)
+    {
+        MgFileUtil::DeleteFile(lockPathname, false);
+    }
+
+    MG_THROW()
+
+    return ret.Detach();
+}
+
+MgByteReader* MgTileCacheDefault::GetTileForMap(CREFSTRING baseMapLayerGroupName,
+                                                INT32 tileColumn,
+                                                INT32 tileRow,
+                                                INT32 scaleIndex)
+{
+    Ptr<MgByteReader> ret;
+    FILE* lockFile = NULL;
+    STRING tilePathname, lockPathname;
+
+    MG_TRY()
+
+    if (NULL == m_map || baseMapLayerGroupName.empty())
+    {
+        throw new MgNullArgumentException(L"MgServerTileService.GetTile",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // find the finite display scale closest to the requested map scale
+    double scale = m_map->GetViewScale();
+    INT32 scaleIndex = m_map->FindNearestFiniteDisplayScaleIndex(scale);
+
+    // if we don't find a nearest scale then something is wrong with the map
+    if (scaleIndex < 0)
+    {
+        throw new MgInvalidMapDefinitionException(L"MgServerTileService.GetTile",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    // Detect the lock file to see if another thread is creating the tile file.
+    GeneratePathNames(scaleIndex, baseMapLayerGroupName,
+        tileColumn, tileRow, tilePathname, lockPathname, false);
+
+    // If there is a dangling lock file, then attempt to remove it.
+    if (DetectTileLockFile(lockPathname))
+    {
+        // TODO: Handle the exception by displaying a tile with an error message?
+        MgFileUtil::DeleteFile(lockPathname, true);
+    }
+
+    // try getting the tile from the cache
+    ret = Get(tilePathname);
+
+    // if the reader is NULL then the tile wasn't in the cache and we
+    // need to generate it
+    while (NULL == ret)
+    {
+        {
+            // Attemp to lock the tile file.
+            ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
+
+            // Bail out if the tile file has been locked for so long.
+            if (DetectTileLockFile(lockPathname))
+            {
+                MgStringCollection arguments;
+                arguments.Add(lockPathname);
+
+                throw new MgFileIoException(L"MgServerTileService.GetTile",
+                    __LINE__, __WFILE__, &arguments, L"MgUnableToLockTileFile", NULL);
+            }
+
+            // try getting the tile from the cache
+            ret = Get(tilePathname);
+
+            if (NULL != ret)
+            {
+                break;
+            }
+
+            // Create the lock file and close it right away.
+            CreateFullPath(scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+            lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+
+            if (NULL == lockFile)
+            {
+                MgStringCollection arguments;
+                arguments.Add(lockPathname);
+
+                throw new MgFileIoException(L"MgServerTileService.GetTile",
+                    __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
+            }
+            else
+            {
+                ACE_OS::fclose(lockFile);
+            }
+        }
+
+        // Render the tile and cache it.
+        ret = RenderAndCacheTile(tilePathname, m_map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
+        break;
+    }
+
+    MG_CATCH(L"MgServerTileService.GetTile")
+
+    if (NULL != lockFile)
+    {
+        MgFileUtil::DeleteFile(lockPathname, false);
+    }
+
+    MG_THROW()
+
+    return ret.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// render a tile and store it in the cache
+MgByteReader* MgTileCacheDefault::RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
+    CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)
+{
+    Ptr<MgByteReader> img;
+
+    // get a rendering service instance
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
+    Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
+        serviceMan->RequestService(MgServiceType::RenderingService));
+    assert(NULL != svcRendering);
+
+    if (svcRendering != NULL)
+    {
+        // generate the tile
+        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat());
+
+        // cache the tile
+        if (!sm_renderOnly)
+        {
+            Set(img, tilePathname);
+
+            // rewind the reader since setting the tile advances it to the end
+            if (img)
+            {
+                img->Rewind();
+            }
+        }
+    }
+
+    return img.Detach();
+}
+
+void MgTileCacheDefault::SetTile(CREFSTRING baseMapLayerGroupName,
+                                 INT32 tileColumn,
+                                 INT32 tileRow,
+                                 INT32 scaleIndex,
+                                 MgByteReader* img)
+{
+    FILE* lockFile = NULL;
+    STRING tilePathname, lockPathname;
+
+    MG_TRY()
+
+    if (NULL == img || NULL == (MgMap*)m_map || baseMapLayerGroupName.empty())
+    {
+        throw new MgNullArgumentException(L"MgTileCacheDefault.SetTile",
+            __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    if (scaleIndex < 0)
+    {
+        STRING buffer;
+        MgUtil::Int32ToString(scaleIndex, buffer);
+
+        MgStringCollection arguments;
+        arguments.Add(L"3");
+        arguments.Add(buffer);
+
+        throw new MgInvalidArgumentException(L"MgTileCacheDefault.GetTile",
+            __LINE__, __WFILE__, &arguments, L"MgInvalidScaleIndex", NULL);
+    }
+
+    // Generate tile and lock pathnames.
+    GeneratePathNames(scaleIndex, baseMapLayerGroupName,
+        tileColumn, tileRow, tilePathname, lockPathname, true);
+
+    {
+        // Attemp to lock the tile file.
+        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
+
+        if (DetectTileLockFile(lockPathname))
+        {
+            // Attemp to remove a dangling lock file.
+            MgFileUtil::DeleteFile(lockPathname, true);
+        }
+
+        // Create the lock file and close it right away.
+        lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
+
+        if (NULL == lockFile)
+        {
+            MgStringCollection arguments;
+            arguments.Add(lockPathname);
+
+            throw new MgFileIoException(L"MgTileCacheDefault.SetTile",
+                __LINE__, __WFILE__, &arguments, L"MgUnableToOpenLockFile", NULL);
+        }
+        else
+        {
+            ACE_OS::fclose(lockFile);
+        }
+    }
+
+    // cache the tile
+    Set(img, tilePathname);
+
+    MG_CATCH(L"MgTileCacheDefault.SetTile")
+
+    if (NULL != lockFile)
+    {
+        MgFileUtil::DeleteFile(lockPathname, false);
+    }
+
+    MG_THROW()
+}
+
+void MgTileCacheDefault::Clear()
+{
+    STRING basePath = GetBasePath();
+
+    // delete main map directory
+    if (!basePath.empty())
+        MgFileUtil::DeleteDirectory(basePath, true, false);
+}
+
+INT32 MgTileCacheDefault::GetDefaultTileSizeX()
+{
+    return MgTileParameters::tileWidth;
+}
+
+INT32 MgTileCacheDefault::GetDefaultTileSizeY()
+{
+    return MgTileParameters::tileHeight;
+}
+
+STRING MgTileCacheDefault::GetTileFormat()
+{
+    return MgTileParameters::tileFormat;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// accessor method for resource service
+MgResourceService* MgTileCacheDefault::GetResourceServiceForMapDef(MgResourceIdentifier* mapDefinition,
+                                                                   CREFSTRING funcName)
+{
+    // get service manager
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
+
+    // Get the service from service manager
+    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
+        serviceMan->RequestService(MgServiceType::ResourceService));
+    assert(NULL != resourceService);
+
+    if (!resourceService->HasPermission(mapDefinition, MgResourcePermission::ReadOnly))
+    {
+        MG_LOG_AUTHENTICATION_ENTRY(MgResources::PermissionDenied.c_str());
+
+        MgStringCollection arguments;
+        arguments.Add(mapDefinition->ToString());
+
+        throw new MgPermissionDeniedException(
+            funcName, __LINE__, __WFILE__, &arguments, L"", NULL);
+    }
+    return resourceService.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Detect if the tile file has been locked by another thread or process.
+///
+bool MgTileCacheDefault::DetectTileLockFile(CREFSTRING lockPathname)
+{
+    bool found = false;
+    struct _stat64 lockFileInfo;
+
+    // Check the lock file to see if another thread/process is writing the tile file.
+    while (MgFileUtil::GetFileStatus(lockPathname, lockFileInfo))
+    {
+        time_t currTime;
+        ACE_OS::time(&currTime);
+        INT32 diffTime = (INT32)(currTime - lockFileInfo.st_mtime);
+
+        if (diffTime < sm_creationCutoffTime)
+        {
+            ACE_OS::sleep(sm_pollingInterval);
+        }
+        else
+        {
+            found = true;
+            break;
+        }
+    }
+
+    return found;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+void MgTileCacheDefault::ClearMapCache(CREFSTRING mapDefinition)
+{
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
+    MapCache::iterator iter = sm_mapCache.end();
+    if (mapDefinition.empty())
+    {
+        for (iter = sm_mapCache.begin(); iter != sm_mapCache.end(); ++iter)
+        {
+            SAFE_RELEASE((*iter).second);
+            (*iter).second = NULL;
+        }
+        sm_mapCache.clear();
+
+        STRING message;
+        MgResources* resources = NULL;
+        MG_TRY()
+        resources = MgResources::GetInstance();
+        if (NULL != resources)
+        {
+            message = resources->GetResourceMessage(MgResources::ErrorDescription, L"MgMapCacheCleared", NULL);
+            MG_LOG_ERROR_ENTRY(message.c_str());
+        }
+        MG_CATCH_AND_RELEASE()
+    }
+    else
+    {
+        iter = sm_mapCache.find(mapDefinition);
+        if (sm_mapCache.end() != iter)
+        {
+            SAFE_RELEASE((*iter).second);
+            (*iter).second = NULL;
+            sm_mapCache.erase(iter);
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Generate tile and lock pathnames.
+///
+void MgTileCacheDefault::GeneratePathNames(int scaleIndex,
+    CREFSTRING group, int tileColumn, int tileRow,
+    STRING& tilePathname, STRING& lockPathname, bool createFullPath)
+{
+    STRING fileName = L"/" + GetTileName(tileRow, tileColumn) + L".";
+    STRING basePath = GetBasePath();
+
+    if (createFullPath)
+    {
+        tilePathname = CreateFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
+    }
+    else
+    {
+        tilePathname = GetFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
+    }
+
+    // Generate the tile and lock pathnames
+    //     <tilePathname> = <fullPath>/<row>_<column>.png/jpg
+    //     <lockPathname> = <fullPath>/<row>_<column>.lck
+    tilePathname += fileName;
+    lockPathname = tilePathname;
+    STRING fmt = GetTileFormat();
+    if (fmt == MgImageFormats::Jpeg)
+    {
+        tilePathname += L"jpg";
+    }
+    else if (fmt == MgImageFormats::Gif)
+    {
+        tilePathname += L"gif";
+    }
+    else
+    {
+        tilePathname += L"png";
+    }
+
+    lockPathname += L"lck";
+}
+
+// Get the filename corresponding to the specified row and column.
+// No file extension is added.
+STRING MgTileCacheDefault::GetTileName(int tileRow, int tileColumn)
+{
+    return GetTileIndexString(tileRow, sm_tileRowsPerFolder) + L"_" +
+           GetTileIndexString(tileColumn, sm_tileColumnsPerFolder);
+}
+
+// When a tile is stored in a folder, the index value of the parent folder
+// is subtracted from the overall tile index.
+// e.g. If we store 30 rows of tiles per folder, a tile with overall row
+// index 73 will be stored in the row folder "R60" with a row index of 13.
+// Note: Negative values are maintained even near the origin, so a tile with
+// an overall row index of -13 would be stored in row folder "R-0" with a
+// row index of -13.
+STRING MgTileCacheDefault::GetTileIndexString(int tileIndex, int tilesPerFolder)
+{
+    STRING name;
+
+    // Determine the offset of this tile within the folder
+    int tileNameIndex = tileIndex % tilesPerFolder;
+    if(tileIndex < 0 && tileNameIndex == 0)
+    {
+        name = L"-0";
+    }
+    else
+    {
+        MgUtil::Int32ToString(tileNameIndex, name);
+    }
+    return name;
+}
+
+// Get the folder name corresponding to the specified scale index
+STRING MgTileCacheDefault::GetScaleIndexFolder(int scaleIndex)
+{
+    STRING scaleIndexString;
+    MgUtil::Int32ToString(scaleIndex, scaleIndexString);
+    return SCALE_INDEX_PREFIX + scaleIndexString;
+}
+
+// Get the folder name corresponding to the specified tile row
+STRING MgTileCacheDefault::GetRowFolder(int tileRow)
+{
+    return GetFolder(ROW_PREFIX, tileRow, sm_tileRowsPerFolder);
+}
+
+STRING MgTileCacheDefault::CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    assert(!basePath.empty());
+    STRING fullPath = basePath;
+
+    // Create base directory if it does not exist.
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create scale directory if it does not exist.
+    fullPath += L"/";
+    fullPath += GetScaleIndexFolder(scaleIndex);
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create group directory if it does not exist.
+    fullPath += L"/";
+    fullPath += group;
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create row directory if it does not exist.
+    fullPath += L"/";
+    fullPath += GetRowFolder(tileRow);
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create column directory if it does not exist.
+    fullPath += L"/";
+    fullPath += GetColumnFolder(tileColumn);
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    return fullPath;
+}
+
+STRING MgTileCacheDefault::CreateFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    return CreateFullPath(GetBasePath(), scaleIndex, group, tileColumn, tileRow);
+}
+
+STRING MgTileCacheDefault::GetBasePath()
+{
+    Ptr<MgResourceIdentifier> resId;
+    if (NULL != (MgMap*)m_map)
+    {
+        resId = m_map->GetMapDefinition();
+    }
+    else if (NULL != m_resourceId && m_resourceId->GetResourceType() == MgResourceType::MapDefinition)
+    {
+        resId = SAFE_ADDREF((MgResourceIdentifier*)m_resourceId);
+    }
+    return GetBasePathFromResourceId(resId, sm_path);
+}
+
+STRING MgTileCacheDefault::GetBasePathFromResourceId(MgResourceIdentifier* resId, CREFSTRING rootPath)
+{
+    STRING mapPath;
+    if (resId->GetRepositoryType() == MgRepositoryType::Library)
+    {
+        // for maps in the library repository the path+name is unique
+        mapPath  = resId->GetPath();
+        mapPath += L"_";
+        mapPath += resId->GetName();
+    }
+    else if (resId->GetRepositoryType() == MgRepositoryType::Session)
+    {
+        // for maps in the session repository we use the session + path + map name
+        mapPath  = resId->GetRepositoryName();
+        mapPath += L"_";
+
+        STRING resourcePath  = resId->GetPath();
+
+        if (!resourcePath.empty())
+        {
+            mapPath += resourcePath;
+            mapPath += L"_";
+        }
+
+        mapPath += resId->GetName();
+    }
+    else
+    {
+        // shouldn't get here
+        assert(false);
+        return mapPath;
+    }
+
+    // for safety
+    mapPath = MgUtil::ReplaceString(mapPath, L"/", L"_");
+    mapPath = MgUtil::ReplaceString(mapPath, L":", L"_");
+
+    // Build the base path using format "%ls%ls":
+    //     <basePath> = <tileCachePath><mapPath>
+    STRING basePath = rootPath;
+    basePath += mapPath;
+
+    return basePath;
+}
+
+// gets the full path to use with the tile cache for the given base path / scale index / group
+STRING MgTileCacheDefault::GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    // Build full path
+    //     <fullPath> = <basePath>/<scaleIndex>/<group>/<rowFolder>/<columnFolder>
+    assert(!basePath.empty());
+    STRING fullPath = basePath;
+
+    fullPath += L"/";
+    fullPath += GetScaleIndexFolder(scaleIndex);
+
+    fullPath += L"/";
+    fullPath += group;
+
+    fullPath += L"/";
+    fullPath += GetRowFolder(tileRow);
+
+    fullPath += L"/";
+    fullPath += GetColumnFolder(tileColumn);
+
+    return fullPath;
+}
+
+// gets the full path to use with the tile cache for the given map definition / scale index / group
+STRING MgTileCacheDefault::GetFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    return GetFullPath(GetBasePath(), scaleIndex, group, tileColumn, tileRow);
+}
+
+// Get the folder name corresponding to the specified tile column
+STRING MgTileCacheDefault::GetColumnFolder(int tileColumn)
+{
+    return GetFolder(COLUMN_PREFIX, tileColumn, sm_tileColumnsPerFolder);
+}
+
+// Get the parent folder for a given row or column
+STRING MgTileCacheDefault::GetFolder(STRING prefix, int tileIndex, int tilesPerFolder)
+{
+    STRING folder;
+
+    // Determine which folder contains this tile
+    int folderIndex = tileIndex / tilesPerFolder;
+    int firstTileIndex = folderIndex * tilesPerFolder;
+    if(tileIndex < 0 && firstTileIndex == 0)
+    {
+        folder = L"-0";
+    }
+    else
+    {
+        MgUtil::Int32ToString(firstTileIndex, folder);
+    }
+    return prefix + folder;
+}
+
+MgByteReader* MgTileCacheDefault::Get(CREFSTRING path)
+{
+    Ptr<MgByteReader> ret;
+
+    MG_TRY()
+
+    if (MgFileUtil::PathnameExists(path))
+    {
+        Ptr<MgByteSource> byteSource = new MgByteSource(path, false);
+
+        if (MgTileParameters::tileFormat == MgImageFormats::Jpeg)
+        {
+            byteSource->SetMimeType(MgMimeType::Jpeg);
+        }
+        else if (MgTileParameters::tileFormat == MgImageFormats::Gif)
+        {
+            byteSource->SetMimeType(MgMimeType::Gif);
+        }
+        else
+        {
+            byteSource->SetMimeType(MgMimeType::Png);
+        }
+
+        ret = byteSource->GetReader();
+    }
+
+    MG_CATCH_AND_RELEASE()
+
+    return ret.Detach();
+}
+
+void MgTileCacheDefault::Set(MgByteReader* img, CREFSTRING path)
+{
+    if (img != NULL)
+    {
+        Ptr<MgByteSink> byteSink = new MgByteSink(img);
+
+        byteSink->ToFile(path);
+    }
+}
+
+bool MgTileCacheDefault::IsTileCacheEmpty()
+{
+    ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, false));
+
+    return sm_mapCache.empty();
+}

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefault.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheDefault.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,123 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+#ifndef _MG_TILE_CACHE_DEFAULT_H_
+#define _MG_TILE_CACHE_DEFAULT_H_
+
+#include "TileCache.h"
+
+//The default tile cache implementation with default settings based on server configuration
+class MG_SERVER_TILE_API MgTileCacheDefault : public MgTileCache
+{
+public:
+    MgTileCacheDefault();
+    MgTileCacheDefault(MgMap* map);
+    MgTileCacheDefault(MgResourceIdentifier* resource);
+    virtual ~MgTileCacheDefault();
+
+    static void Initialize();
+
+    virtual MgByteReader* GetTile(CREFSTRING baseMapLayerGroupName,
+                                  INT32 tileColumn,
+                                  INT32 tileRow,
+                                  INT32 scaleIndex);
+
+    virtual void SetTile(CREFSTRING baseMapLayerGroupName,
+                         INT32 tileColumn,
+                         INT32 tileRow,
+                         INT32 scaleIndex,
+                         MgByteReader* img);
+
+    virtual void Clear();
+
+    virtual INT32 GetDefaultTileSizeX();
+
+    virtual INT32 GetDefaultTileSizeY();
+
+    virtual STRING GetTileFormat();
+
+    void ClearMapCache(CREFSTRING mapName);
+
+    static bool IsTileCacheEmpty();
+
+protected:
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    virtual STRING GetBasePath();
+    virtual STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    virtual STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+
+    virtual MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+
+    virtual STRING GetTileName(int tileRow, int tileColumn);
+
+    MgByteReader* GetTileForResource(MgResourceIdentifier* resource,
+                                     CREFSTRING baseMapLayerGroupName,
+                                     INT32 tileColumn,
+                                     INT32 tileRow,
+                                     INT32 scaleIndex);
+
+    STRING GetBasePathFromResourceId(MgResourceIdentifier* resId, CREFSTRING rootPath);
+
+    void Set(MgByteReader* img, CREFSTRING path);
+    MgByteReader* Get(CREFSTRING path);
+
+private:
+    MgByteReader* GetTileForMap(CREFSTRING baseMapLayerGroupName,
+                                INT32 tileColumn,
+                                INT32 tileRow,
+                                INT32 scaleIndex);
+
+    void GeneratePathNames(int scaleIndex,
+        CREFSTRING group, int tileColumn, int tileRow,
+        STRING& tilePathname, STRING& lockPathname, bool createFullPath);
+
+    STRING GetFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    
+    STRING CreateFullPath(int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+
+    STRING GetScaleIndexFolder(int scaleIndex);
+    STRING GetRowFolder(int tileRow);
+    STRING GetColumnFolder(int tileColumn);
+    STRING GetFolder(STRING prefix, int tileIndex, int tilesPerFolder);
+
+    STRING GetTileIndexString(int tileIndex, int tilesPerFolder);
+
+    MgResourceService* GetResourceServiceForMapDef(MgResourceIdentifier* mapDefinition, CREFSTRING funcName);
+    bool DetectTileLockFile(CREFSTRING lockPathname);
+
+    Ptr<MgResourceIdentifier> m_resourceId;
+    Ptr<MgMap> m_map;
+
+    static STRING sm_path;
+    static INT32 sm_tileColumnsPerFolder;
+    static INT32 sm_tileRowsPerFolder;
+
+    typedef std::map<STRING, MgMemoryStreamHelper*> MapCache;
+
+    static ACE_Recursive_Thread_Mutex sm_mutex;
+    static MapCache sm_mapCache;
+    static bool sm_initialized;
+    static bool sm_renderOnly;
+    static INT32 sm_creationCutoffTime;
+    static INT32 sm_pollingInterval;
+    static INT32 sm_mapCacheSize;
+};
+
+#endif
\ No newline at end of file

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,103 @@
+//
+//  Copyright (C) 2004-2014 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 "MapGuideCommon.h"
+#include "TileCacheDefaultProvider.h"
+
+MgTileCacheDefaultProvider::MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format, bool bRenderOnly)
+{
+    m_tilesetId = SAFE_ADDREF(tileSetId);
+    m_path = path;
+    m_tileWidth = tileWidth;
+    m_tileHeight = tileHeight;
+    m_format = format;
+    m_renderOnly = bRenderOnly;
+}
+
+MgTileCacheDefaultProvider::~MgTileCacheDefaultProvider()
+{
+
+}
+
+MgByteReader* MgTileCacheDefaultProvider::GetTile(CREFSTRING baseMapLayerGroupName,
+                                                  INT32 tileColumn,
+                                                  INT32 tileRow,
+                                                  INT32 scaleIndex)
+{
+    Ptr<MgByteReader> ret;
+    MG_TRY()
+
+    ret = GetTileForResource(m_tilesetId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+
+    MG_CATCH_AND_THROW(L"MgTileCacheDefaultProvider.GetTile")
+    return ret.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// render a tile and store it in the cache
+MgByteReader* MgTileCacheDefaultProvider::RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
+    CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)
+{
+    Ptr<MgByteReader> img;
+
+    // get a rendering service instance
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
+    Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
+        serviceMan->RequestService(MgServiceType::RenderingService));
+    assert(NULL != svcRendering);
+
+    if (svcRendering != NULL)
+    {
+        // generate the tile
+        img = svcRendering->RenderTile(map, baseMapLayerGroupName, tileColumn, tileRow, GetDefaultTileSizeX(), GetDefaultTileSizeY(), map->GetDisplayDpi(), GetTileFormat());
+
+        // cache the tile
+        if (!m_renderOnly)
+        {
+            Set(img, tilePathname);
+
+            // rewind the reader since setting the tile advances it to the end
+            if (img)
+            {
+                img->Rewind();
+            }
+        }
+    }
+
+    return img.Detach();
+}
+
+INT32 MgTileCacheDefaultProvider::GetDefaultTileSizeX()
+{
+    return m_tileWidth;
+}
+
+INT32 MgTileCacheDefaultProvider::GetDefaultTileSizeY()
+{
+    return m_tileHeight;
+}
+
+STRING MgTileCacheDefaultProvider::GetTileFormat()
+{
+    return m_format;
+}
+
+STRING MgTileCacheDefaultProvider::GetBasePath()
+{
+    return GetBasePathFromResourceId(m_tilesetId, m_path);
+}
\ No newline at end of file

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheDefaultProvider.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheDefaultProvider.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,58 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+#ifndef _MG_TILE_CACHE_DEFAULT_PROVIDER_H_
+#define _MG_TILE_CACHE_DEFAULT_PROVIDER_H_
+
+#include "TileCacheDefault.h"
+
+class MG_SERVER_TILE_API MgTileCacheDefaultProvider : public MgTileCacheDefault
+{
+public:
+    MgTileCacheDefaultProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, INT32 tileWidth, INT32 tileHeight, CREFSTRING format, bool bRenderOnly);
+    virtual ~MgTileCacheDefaultProvider();
+
+    virtual MgByteReader* GetTile(CREFSTRING baseMapLayerGroupName,
+                                  INT32 tileColumn,
+                                  INT32 tileRow,
+                                  INT32 scaleIndex);
+
+    virtual MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+
+    virtual INT32 GetDefaultTileSizeX();
+
+    virtual INT32 GetDefaultTileSizeY();
+
+    virtual STRING GetTileFormat();
+
+protected:
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    virtual STRING GetBasePath();
+
+private:
+    Ptr<MgResourceIdentifier> m_tilesetId;
+    STRING m_path;
+    INT32 m_tileWidth;
+    INT32 m_tileHeight;
+    STRING m_format;
+    bool m_renderOnly;
+};
+
+#endif
\ No newline at end of file

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.cpp (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheXYZProvider.cpp)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.cpp	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,165 @@
+//
+//  Copyright (C) 2004-2014 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 "MapGuideCommon.h"
+#include "TileCacheXYZProvider.h"
+
+MgTileCacheXYZProvider::MgTileCacheXYZProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, CREFSTRING format, bool bRenderOnly)
+{
+    m_tilesetId = SAFE_ADDREF(tileSetId);
+    m_path = path;
+    m_format = format;
+    m_renderOnly = bRenderOnly;
+}
+
+MgTileCacheXYZProvider::~MgTileCacheXYZProvider()
+{
+
+}
+
+MgByteReader* MgTileCacheXYZProvider::GetTile(CREFSTRING baseMapLayerGroupName,
+                                                  INT32 tileColumn,
+                                                  INT32 tileRow,
+                                                  INT32 scaleIndex)
+{
+    Ptr<MgByteReader> ret;
+    MG_TRY()
+
+    ret = GetTileForResource(m_tilesetId, baseMapLayerGroupName, tileColumn, tileRow, scaleIndex);
+
+    MG_CATCH_AND_THROW(L"MgTileCacheXYZProvider.GetTile")
+    return ret.Detach();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// render a tile and store it in the cache
+MgByteReader* MgTileCacheXYZProvider::RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex,
+    CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow)
+{
+    Ptr<MgByteReader> img;
+
+    // get a rendering service instance
+    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+    assert(NULL != serviceMan);
+    Ptr<MgRenderingService> svcRendering = dynamic_cast<MgRenderingService*>(
+        serviceMan->RequestService(MgServiceType::RenderingService));
+    assert(NULL != svcRendering);
+
+    if (svcRendering != NULL)
+    {
+        // generate the tile
+        img = svcRendering->RenderTileXYZ(map, baseMapLayerGroupName, tileRow, tileColumn, scaleIndex, map->GetDisplayDpi(), m_format);
+
+        // cache the tile
+        if (!m_renderOnly)
+        {
+            Set(img, tilePathname);
+
+            // rewind the reader since setting the tile advances it to the end
+            if (img)
+            {
+                img->Rewind();
+            }
+        }
+    }
+
+    return img.Detach();
+}
+
+INT32 MgTileCacheXYZProvider::GetDefaultTileSizeX()
+{
+    return 256; //Always
+}
+
+INT32 MgTileCacheXYZProvider::GetDefaultTileSizeY()
+{
+    return 256; //Always
+}
+
+STRING MgTileCacheXYZProvider::GetTileFormat()
+{
+    return m_format;
+}
+
+STRING MgTileCacheXYZProvider::GetBasePath()
+{
+    return GetBasePathFromResourceId(m_tilesetId, m_path);
+}
+
+STRING MgTileCacheXYZProvider::CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    assert(!basePath.empty());
+    STRING fullPath = basePath;
+
+    // Create base directory if it does not exist.
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create group directory if it does not exist.
+    fullPath += L"/";
+    fullPath += group;
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create z directory if it does not exist.
+    fullPath += L"/";
+    STRING sZ;
+    MgUtil::Int32ToString(scaleIndex, sZ);
+    fullPath += sZ;
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    // Create x directory if it does not exist.
+    fullPath += L"/";
+    STRING sX;
+    MgUtil::Int32ToString(tileRow, sX);
+    fullPath += sX;
+    MgFileUtil::CreateDirectory(fullPath, false);
+
+    return fullPath;
+}
+
+// gets the full path to use with the tile cache for the given base path / scale index / group
+STRING MgTileCacheXYZProvider::GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
+{
+    // Build full path
+    //     <fullPath> = <basePath>/<group>/<z>/<x>/<y>.<format>
+    assert(!basePath.empty());
+    STRING fullPath = basePath;
+
+    fullPath += L"/";
+    fullPath += group;
+
+    fullPath += L"/";
+    STRING sZ;
+    MgUtil::Int32ToString(scaleIndex, sZ);
+    fullPath += sZ;
+
+    fullPath += L"/";
+    STRING sX;
+    MgUtil::Int32ToString(tileRow, sX);
+    fullPath += sX;
+
+    return fullPath;
+}
+
+// Get the filename corresponding to the specified row and column.
+// No file extension is added.
+STRING MgTileCacheXYZProvider::GetTileName(int tileRow, int tileColumn)
+{
+    //row (x) is already part of the parent directory, so column (y) is the tile name
+    STRING ret;
+    MgUtil::Int32ToString(tileColumn, ret);
+    return ret;
+}
\ No newline at end of file

Copied: trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.h (from rev 8208, sandbox/jng/tiling/Server/src/Services/Tile/TileCacheXYZProvider.h)
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.h	                        (rev 0)
+++ trunk/MgDev/Server/src/Services/Tile/TileCacheXYZProvider.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,61 @@
+//
+//  Copyright (C) 2004-2014 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+#ifndef _MG_TILE_CACHE_XYZ_PROVIDER_H_
+#define _MG_TILE_CACHE_XYZ_PROVIDER_H_
+
+#include "TileCacheDefault.h"
+
+class MG_SERVER_TILE_API MgTileCacheXYZProvider : public MgTileCacheDefault
+{
+public:
+    MgTileCacheXYZProvider(MgResourceIdentifier* tileSetId, CREFSTRING path, CREFSTRING format, bool bRenderOnly);
+    virtual ~MgTileCacheXYZProvider();
+
+    virtual MgByteReader* GetTile(CREFSTRING baseMapLayerGroupName,
+                                  INT32 tileColumn,
+                                  INT32 tileRow,
+                                  INT32 scaleIndex);
+
+    virtual MgByteReader* RenderAndCacheTile(CREFSTRING tilePathname, MgMap* map, INT32 scaleIndex, CREFSTRING baseMapLayerGroupName, INT32 tileColumn, INT32 tileRow);
+
+    virtual INT32 GetDefaultTileSizeX();
+
+    virtual INT32 GetDefaultTileSizeY();
+
+    virtual STRING GetTileFormat();
+
+    //Overriding these as we want to use a cleaner directory structure for XYZ tiles
+    virtual STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    virtual STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    virtual STRING GetTileName(int tileRow, int tileColumn);
+
+protected:
+    virtual void Dispose()
+    {
+        delete this;
+    }
+
+    virtual STRING GetBasePath();
+
+private:
+    Ptr<MgResourceIdentifier> m_tilesetId;
+    STRING m_path;
+    STRING m_format;
+    bool m_renderOnly;
+};
+
+#endif
\ No newline at end of file

Modified: trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/Services/Tile/TileOperationFactory.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -98,6 +98,18 @@
         }
         break;
 
+    case MgTileServiceOpId::ClearCache2:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpClearCache());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgTileOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
     case MgTileServiceOpId::GetDefaultTileSizeX:
         switch (VERSION_NO_PHASE(operationVersion))
         {
@@ -122,6 +134,42 @@
         }
         break;
 
+    case MgTileServiceOpId::GetDefaultTileSizeX2:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpGetDefaultTileSizeX());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgTileOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
+    case MgTileServiceOpId::GetDefaultTileSizeY2:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpGetDefaultTileSizeY());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgTileOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
+    case MgTileServiceOpId::GetTileProviders:
+        switch (VERSION_NO_PHASE(operationVersion))
+        {
+        case VERSION_SUPPORTED(3,0):
+            handler.reset(new MgOpGetTileProviders());
+            break;
+        default:
+            throw new MgInvalidOperationVersionException(
+                L"MgTileOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+        break;
+
     default:
         throw new MgInvalidOperationException(
             L"MgTileOperationFactory.GetOperation", __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/UnitTesting/TestMappingService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMappingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestMappingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -128,6 +128,16 @@
         Ptr<MgByteReader> ldfrdr4 = ldfsrc4->GetReader();
         m_svcResource->SetResource(ldfres4, ldfrdr4, NULL);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc5 = new MgByteSource(L"../UnitTestFiles/UT_RoadCenterLines.ldf", false);
+        Ptr<MgByteReader> ldfrdr5 = ldfsrc5->GetReader();
+        m_svcResource->SetResource(ldfres5, ldfrdr5, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/VotingDistricts.LayerDefinition");
+        Ptr<MgByteSource> ldfsrc6 = new MgByteSource(L"../UnitTestFiles/UT_VotingDistricts.ldf", false);
+        Ptr<MgByteReader> ldfrdr6 = ldfsrc6->GetReader();
+        m_svcResource->SetResource(ldfres6, ldfrdr6, 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);
@@ -176,6 +186,16 @@
         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);
+
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+        Ptr<MgByteSource> mdfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_LinkedTileSet.mdf", false);
+        Ptr<MgByteReader> mdfrdr2 = mdfsrc2->GetReader();
+        m_svcResource->SetResource(mapres2, mdfrdr2, NULL);
+
+        Ptr<MgResourceIdentifier> tilesetres1 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc1 = new MgByteSource(L"../UnitTestFiles/UT_BaseMap.tsd", false);
+        Ptr<MgByteReader> tsdrdr1 = tsdsrc1->GetReader();
+        m_svcResource->SetResource(tilesetres1, tsdrdr1, NULL);
     }
     catch (MgException* e)
     {
@@ -216,6 +236,12 @@
         Ptr<MgResourceIdentifier> ldfres4 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RotatedPointStyles.LayerDefinition");
         m_svcResource->DeleteResource(ldfres4);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres5);
+
+        Ptr<MgResourceIdentifier> ldfres6 = new MgResourceIdentifier(L"Library://UnitTests/Layers/VotingDistricts.LayerDefinition");
+        m_svcResource->DeleteResource(ldfres6);
+
         //delete the feature sources
         Ptr<MgResourceIdentifier> fsres1 = new MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
         m_svcResource->DeleteResource(fsres1);
@@ -237,6 +263,12 @@
         Ptr<MgResourceIdentifier> slres1 = new MgResourceIdentifier(L"Library://UnitTests/Symbols/SymbolMart.SymbolLibrary");
         m_svcResource->DeleteResource(slres1);
 
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+        m_svcResource->DeleteResource(mapres2);
+
+        Ptr<MgResourceIdentifier> tilesetres1 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        m_svcResource->DeleteResource(tilesetres1);
+
         #ifdef _DEBUG
         MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
         if(pFdoConnectionManager)
@@ -459,6 +491,33 @@
     }
 }
 
+void TestMappingService::TestCase_CreateAndDescribeLinkedRuntimeMap()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> mdfId = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+        STRING format = MgImageFormats::Png;
+        Ptr<MgByteReader> rtMap = m_svcMapping->CreateRuntimeMap(mdfId, L"TestCase_CreateAndDescribeLinkedRuntimeMap", m_session, format, 16, 16, 0, 25);
+        Ptr<MgByteSink> sink = new MgByteSink(rtMap);
+        sink->ToFile(L"../UnitTestFiles/TestCase_CreateLinkedRuntimeMap.xml");
+
+        Ptr<MgMap> map = new MgMap(m_siteConnection);
+        map->Open(L"TestCase_CreateAndDescribeLinkedRuntimeMap");
+        rtMap = m_svcMapping->DescribeRuntimeMap(map, format, 16, 16, 0, 25);
+        sink = new MgByteSink(rtMap);
+        sink->ToFile(L"../UnitTestFiles/TestCase_DescribeLinkedRuntimeMap.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 TestMappingService::TestCase_SaveMap()
 {
     try

Modified: trunk/MgDev/Server/src/UnitTesting/TestMappingService.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMappingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestMappingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -36,6 +36,7 @@
     CPPUNIT_TEST(TestCase_GetLegendImagePointStyleWithConstRotations);
     CPPUNIT_TEST(TestCase_CreateRuntimeMap);
     CPPUNIT_TEST(TestCase_DescribeRuntimeMap);
+    CPPUNIT_TEST(TestCase_CreateAndDescribeLinkedRuntimeMap);
     //CPPUNIT_TEST(TestCase_QueryFeaturesImageMap);
 
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
@@ -56,6 +57,7 @@
     void TestCase_SaveMap();
     void TestCase_GetPlot();
     void TestCase_GetMultiPlot();
+    void TestCase_CreateAndDescribeLinkedRuntimeMap();
     void TestCase_GetPlotUsingCurrentCenterAndScale();
     void TestCase_GetPlotUsingOverriddenCenterAndScale();
     void TestCase_GetPlotUsingExtents();

Modified: trunk/MgDev/Server/src/UnitTesting/TestMdfModel.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMdfModel.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestMdfModel.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -82,6 +82,16 @@
         Ptr<MgByteSource> mdfsrc4 = new MgByteSource(L"../UnitTestFiles/MdfTestMap.mdf", false);
         Ptr<MgByteReader> mdfrdr4 = mdfsrc4->GetReader();
         m_svcResource->SetResource(mdfres4, mdfrdr4, NULL);
+
+        Ptr<MgResourceIdentifier> tsdres5 = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/MdfTestTileSet.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc5 = new MgByteSource(L"../UnitTestFiles/UT_BaseMap.tsd", false);
+        Ptr<MgByteReader> tsdrdr5 = tsdsrc5->GetReader();
+        m_svcResource->SetResource(tsdres5, tsdrdr5, NULL);
+
+        Ptr<MgResourceIdentifier> tsdres6 = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/XYZTestTileSet.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc6 = new MgByteSource(L"../UnitTestFiles/UT_XYZ.tsd", false);
+        Ptr<MgByteReader> tsdrdr6 = tsdsrc6->GetReader();
+        m_svcResource->SetResource(tsdres6, tsdrdr6, NULL);
     }
     catch (MgException* e)
     {
@@ -114,6 +124,8 @@
         m_svcResource->DeleteResource(ldfres3);
         Ptr<MgResourceIdentifier> mdfres4 = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/MdfTestMap.MapDefinition");
         m_svcResource->DeleteResource(mdfres4);
+        Ptr<MgResourceIdentifier> mdfres5 = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/MdfTestTileSet.TileSetDefinition");
+        m_svcResource->DeleteResource(mdfres5);
     }
     catch(MgFileIoException* e)
     {
@@ -861,3 +873,193 @@
         CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
     }
 }
+
+void TestMdfModel::TestCase_TileSetDefinitionDefault()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/MdfTestTileSet.TileSetDefinition");
+        Ptr<MgByteReader> content = m_svcResource->GetResourceContent(tsId);
+        Ptr<MgByteSink> sink = new MgByteSink(content);
+        Ptr<MgByte> bytes = sink->ToBuffer();
+
+        MdfParser::SAX2Parser parser;
+        parser.ParseString((const char*)bytes->Bytes(), bytes->GetLength());
+
+        CPPUNIT_ASSERT(parser.GetSucceeded());
+        MdfModel::TileSetDefinition* tileset = parser.DetachTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != tileset);
+
+        MdfModel::TileStoreParameters* tilesetParams = tileset->GetTileStoreParameters();
+        CPPUNIT_ASSERT(NULL != tilesetParams);
+        CPPUNIT_ASSERT(MG_TILE_PROVIDER_DEFAULT == tilesetParams->GetTileProvider());
+
+        STRING path;
+        INT32 width;
+        INT32 height;
+        STRING format;
+        FINITESCALES scales;
+
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH)
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEWIDTH)
+            {
+                width = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEHEIGHT)
+            {
+                height = MgUtil::StringToInt32(pair->GetValue());
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_FINITESCALELIST)
+            {
+                Ptr<MgStringCollection> values = MgStringCollection::ParseCollection(pair->GetValue(), L","); //NOXLATE
+                for (INT32 i = 0; i < values->GetCount(); i++)
+                {
+                    double val = MgUtil::StringToDouble(values->GetItem(i));
+                    scales.push_back(val);
+                }
+            }
+        }
+
+        CPPUNIT_ASSERT(256 == width);
+        CPPUNIT_ASSERT(256 == height);
+        CPPUNIT_ASSERT(L"PNG" == format);
+        CPPUNIT_ASSERT(MgResourceTag::TileCachePath == path);
+
+        const MdfModel::Box2D& extents = tileset->GetExtents();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.79786601383196, extents.GetMinX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181,   extents.GetMinY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.66452777186925, extents.GetMaxX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.8037962206133,  extents.GetMaxY(), 0.0000000000001);
+
+        CPPUNIT_ASSERT(10 == scales.size());
+        CPPUNIT_ASSERT(200000 == scales.at(0));
+        CPPUNIT_ASSERT(100000 == scales.at(1));
+        CPPUNIT_ASSERT(50000 == scales.at(2));
+        CPPUNIT_ASSERT(25000 == scales.at(3));
+        CPPUNIT_ASSERT(12500 == scales.at(4));
+        CPPUNIT_ASSERT(6250 == scales.at(5));
+        CPPUNIT_ASSERT(3125 == scales.at(6));
+        CPPUNIT_ASSERT(1562.5 == scales.at(7));
+        CPPUNIT_ASSERT(781.25 == scales.at(8));
+        CPPUNIT_ASSERT(390.625 == scales.at(9));
+
+        MdfModel::BaseMapLayerGroupCollection* groups = tileset->GetBaseMapLayerGroups();
+        CPPUNIT_ASSERT(1 == groups->GetCount());
+        CPPUNIT_ASSERT(L"BaseLayers" == groups->GetAt(0)->GetName());
+        CPPUNIT_ASSERT(L"Base Layers" == groups->GetAt(0)->GetLegendLabel());
+        CPPUNIT_ASSERT(groups->GetAt(0)->IsShowInLegend());
+        CPPUNIT_ASSERT(groups->GetAt(0)->IsExpandInLegend());
+
+        MdfModel::BaseMapLayerCollection* layers = groups->GetAt(0)->GetLayers();
+        CPPUNIT_ASSERT(2 == layers->GetCount());
+
+        CPPUNIT_ASSERT(L"Parcels" == layers->GetAt(0)->GetName());
+        CPPUNIT_ASSERT(L"Parcels" == layers->GetAt(0)->GetLegendLabel());
+        CPPUNIT_ASSERT(L"Library://UnitTests/Layers/Parcels.LayerDefinition" == layers->GetAt(0)->GetLayerResourceID());
+        CPPUNIT_ASSERT(!layers->GetAt(0)->IsExpandInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(0)->IsShowInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(0)->IsSelectable());
+
+        CPPUNIT_ASSERT(L"VotingDistricts" == layers->GetAt(1)->GetName());
+        CPPUNIT_ASSERT(L"Voting Districts" == layers->GetAt(1)->GetLegendLabel());
+        CPPUNIT_ASSERT(L"Library://UnitTests/Layers/VotingDistricts.LayerDefinition" == layers->GetAt(1)->GetLayerResourceID());
+        CPPUNIT_ASSERT(!layers->GetAt(1)->IsExpandInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(1)->IsShowInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(1)->IsSelectable());
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
+
+void TestMdfModel::TestCase_TileSetDefinitionXYZ()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(L"Library://UnitTests/MdfModel/XYZTestTileSet.TileSetDefinition");
+        Ptr<MgByteReader> content = m_svcResource->GetResourceContent(tsId);
+        Ptr<MgByteSink> sink = new MgByteSink(content);
+        Ptr<MgByte> bytes = sink->ToBuffer();
+
+        MdfParser::SAX2Parser parser;
+        parser.ParseString((const char*)bytes->Bytes(), bytes->GetLength());
+
+        CPPUNIT_ASSERT(parser.GetSucceeded());
+        MdfModel::TileSetDefinition* tileset = parser.DetachTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != tileset);
+
+        MdfModel::TileStoreParameters* tilesetParams = tileset->GetTileStoreParameters();
+        CPPUNIT_ASSERT(NULL != tilesetParams);
+        CPPUNIT_ASSERT(MG_TILE_PROVIDER_XYZ == tilesetParams->GetTileProvider());
+
+        STRING path;
+        STRING format;
+
+        MdfModel::NameStringPairCollection* parameters = tilesetParams->GetParameters();
+        for (INT32 i = 0; i < parameters->GetCount(); i++)
+        {
+            MdfModel::NameStringPair* pair = parameters->GetAt(i);
+            if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEPATH)
+            {
+                path = pair->GetValue();
+            }
+            else if (pair->GetName() == MG_TILE_PROVIDER_COMMON_PARAM_TILEFORMAT)
+            {
+                format = pair->GetValue();
+            }
+        }
+
+        CPPUNIT_ASSERT(L"PNG" == format);
+        CPPUNIT_ASSERT(MgResourceTag::TileCachePath == path);
+
+        const MdfModel::Box2D& extents = tileset->GetExtents();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.79786601383196, extents.GetMinX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181,   extents.GetMinY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.66452777186925, extents.GetMaxX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.8037962206133,  extents.GetMaxY(), 0.0000000000001);
+
+        MdfModel::BaseMapLayerGroupCollection* groups = tileset->GetBaseMapLayerGroups();
+        CPPUNIT_ASSERT(1 == groups->GetCount());
+        CPPUNIT_ASSERT(L"BaseLayers" == groups->GetAt(0)->GetName());
+        CPPUNIT_ASSERT(L"Base Layers" == groups->GetAt(0)->GetLegendLabel());
+        CPPUNIT_ASSERT(groups->GetAt(0)->IsShowInLegend());
+        CPPUNIT_ASSERT(groups->GetAt(0)->IsExpandInLegend());
+
+        MdfModel::BaseMapLayerCollection* layers = groups->GetAt(0)->GetLayers();
+        CPPUNIT_ASSERT(2 == layers->GetCount());
+
+        CPPUNIT_ASSERT(L"Parcels" == layers->GetAt(0)->GetName());
+        CPPUNIT_ASSERT(L"Parcels" == layers->GetAt(0)->GetLegendLabel());
+        CPPUNIT_ASSERT(L"Library://UnitTests/Layers/Parcels.LayerDefinition" == layers->GetAt(0)->GetLayerResourceID());
+        CPPUNIT_ASSERT(!layers->GetAt(0)->IsExpandInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(0)->IsShowInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(0)->IsSelectable());
+
+        CPPUNIT_ASSERT(L"VotingDistricts" == layers->GetAt(1)->GetName());
+        CPPUNIT_ASSERT(L"Voting Districts" == layers->GetAt(1)->GetLegendLabel());
+        CPPUNIT_ASSERT(L"Library://UnitTests/Layers/VotingDistricts.LayerDefinition" == layers->GetAt(1)->GetLayerResourceID());
+        CPPUNIT_ASSERT(!layers->GetAt(1)->IsExpandInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(1)->IsShowInLegend());
+        CPPUNIT_ASSERT(layers->GetAt(1)->IsSelectable());
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
\ No newline at end of file

Modified: trunk/MgDev/Server/src/UnitTesting/TestMdfModel.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMdfModel.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestMdfModel.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -28,6 +28,9 @@
     CPPUNIT_TEST(TestCase_Serialization);
     CPPUNIT_TEST(TestCase_Versioning);
 
+    CPPUNIT_TEST(TestCase_TileSetDefinitionDefault);
+    CPPUNIT_TEST(TestCase_TileSetDefinitionXYZ);
+
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
     CPPUNIT_TEST_SUITE_END();
 
@@ -42,6 +45,8 @@
 
     void TestCase_Serialization();
     void TestCase_Versioning();
+    void TestCase_TileSetDefinitionDefault();
+    void TestCase_TileSetDefinitionXYZ();
 
 private:
     Ptr<MgResourceService> m_svcResource;

Modified: trunk/MgDev/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestRenderingService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestRenderingService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1597,6 +1597,87 @@
     }
 }
 
+void TestRenderingService::TestCase_RenderTileBaseline()
+{
+    try
+    {
+        Ptr<MgMap> map = CreateTestTiledMap();
+        map->SetViewScale(12500.0);
+        Ptr<MgByteReader> tile4_6 = m_svcRendering->RenderTile(map, L"BaseLayers", 4, 6);
+        Ptr<MgByteReader> tile4_7 = m_svcRendering->RenderTile(map, L"BaseLayers", 4, 7);
+        Ptr<MgByteReader> tile5_6 = m_svcRendering->RenderTile(map, L"BaseLayers", 5, 6);
+        Ptr<MgByteReader> tile5_7 = m_svcRendering->RenderTile(map, L"BaseLayers", 5, 7);
+
+        tile4_6->ToFile(L"../UnitTestFiles/RenderTile_4_6_Baseline.png");
+        tile4_7->ToFile(L"../UnitTestFiles/RenderTile_4_7_Baseline.png");
+        tile5_6->ToFile(L"../UnitTestFiles/RenderTile_5_6_Baseline.png");
+        tile5_7->ToFile(L"../UnitTestFiles/RenderTile_5_7_Baseline.png");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
+
+void TestRenderingService::TestCase_RenderTile(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        Ptr<MgMap> map = CreateTestTiledMap();
+        map->SetViewScale(12500.0);
+        Ptr<MgByteReader> tile4_6 = m_svcRendering->RenderTile(map, L"BaseLayers", 4, 6, 300, 300, 96, imageFormat);
+        Ptr<MgByteReader> tile4_7 = m_svcRendering->RenderTile(map, L"BaseLayers", 4, 7, 300, 300, 96, imageFormat);
+        Ptr<MgByteReader> tile5_6 = m_svcRendering->RenderTile(map, L"BaseLayers", 5, 6, 300, 300, 96, imageFormat);
+        Ptr<MgByteReader> tile5_7 = m_svcRendering->RenderTile(map, L"BaseLayers", 5, 7, 300, 300, 96, imageFormat);
+
+        tile4_6->ToFile(GetPath(L"../UnitTestFiles/RenderTile_4_6_300x300 at 96", imageFormat, extension));
+        tile4_7->ToFile(GetPath(L"../UnitTestFiles/RenderTile_4_7_300x300 at 96", imageFormat, extension));
+        tile5_6->ToFile(GetPath(L"../UnitTestFiles/RenderTile_5_6_300x300 at 96", imageFormat, extension));
+        tile5_7->ToFile(GetPath(L"../UnitTestFiles/RenderTile_5_7_300x300 at 96", imageFormat, extension));
+
+        Ptr<MgByteReader> tile11_11 = m_svcRendering->RenderTile(map, L"BaseLayers", 11, 11, 256, 256, 96, imageFormat);
+        Ptr<MgByteReader> tile11_12 = m_svcRendering->RenderTile(map, L"BaseLayers", 11, 12, 256, 256, 96, imageFormat);
+        Ptr<MgByteReader> tile12_11 = m_svcRendering->RenderTile(map, L"BaseLayers", 12, 11, 256, 256, 96, imageFormat);
+        Ptr<MgByteReader> tile12_12 = m_svcRendering->RenderTile(map, L"BaseLayers", 12, 12, 256, 256, 96, imageFormat);
+
+        tile11_11->ToFile(GetPath(L"../UnitTestFiles/RenderTile_11_11_256x256 at 96", imageFormat, extension));
+        tile11_12->ToFile(GetPath(L"../UnitTestFiles/RenderTile_11_12_256x256 at 96", imageFormat, extension));
+        tile12_11->ToFile(GetPath(L"../UnitTestFiles/RenderTile_12_11_256x256 at 96", imageFormat, extension));
+        tile12_12->ToFile(GetPath(L"../UnitTestFiles/RenderTile_12_12_256x256 at 96", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
+
+void TestRenderingService::TestCase_RenderTileXYZ(CREFSTRING imageFormat, CREFSTRING extension)
+{
+    try
+    {
+        Ptr<MgMap> map = CreateTestTiledMap();
+        Ptr<MgByteReader> tileTL = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 2099, 2985, 13, 96, imageFormat);
+        Ptr<MgByteReader> tileTR = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 2100, 2985, 13, 96, imageFormat);
+        Ptr<MgByteReader> tileBL = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 2099, 2986, 13, 96, imageFormat);
+        Ptr<MgByteReader> tileBR = m_svcRendering->RenderTileXYZ(map, L"BaseLayers", 2100, 2986, 13, 96, imageFormat);
+
+        tileTL->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_TopLeft", imageFormat, extension));
+        tileTR->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_TopRight", imageFormat, extension));
+        tileBL->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_BottomLeft", imageFormat, extension));
+        tileBR->ToFile(GetPath(L"../UnitTestFiles/RenderTileXYZ_BottomRight", imageFormat, extension));
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+}
+
 STRING TestRenderingService::GetPath(CREFSTRING basePath, CREFSTRING imageFormat, CREFSTRING extension)
 {
 	STRING ret;

Modified: trunk/MgDev/Server/src/UnitTesting/TestRenderingService.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestRenderingService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestRenderingService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -25,6 +25,8 @@
     CPPUNIT_TEST_SUITE(TestRenderingService);
     CPPUNIT_TEST(TestStart); // This must be the very first unit test
 
+    CPPUNIT_TEST(TestCase_RenderTileBaseline);
+
     CPPUNIT_TEST(TestCase_StylizationFunctionsPNG);
 
     CPPUNIT_TEST(TestCase_SymbologyPointsPNG);
@@ -50,6 +52,8 @@
     CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSPNG);
     CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSPNG);
     CPPUNIT_TEST(TestCase_LayerWatermarkPNG);
+    CPPUNIT_TEST(TestCase_RenderTilePNG);
+    CPPUNIT_TEST(TestCase_RenderTileXYZ_PNG);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsPNG8);
 
@@ -76,6 +80,8 @@
     CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSPNG8);
     CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSPNG8);
     CPPUNIT_TEST(TestCase_LayerWatermarkPNG8);
+    CPPUNIT_TEST(TestCase_RenderTilePNG8);
+    CPPUNIT_TEST(TestCase_RenderTileXYZ_PNG8);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsGIF);
 
@@ -102,6 +108,8 @@
     CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSGIF);
     CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSGIF);
     CPPUNIT_TEST(TestCase_LayerWatermarkGIF);
+    CPPUNIT_TEST(TestCase_RenderTileGIF);
+    CPPUNIT_TEST(TestCase_RenderTileXYZ_GIF);
 
     CPPUNIT_TEST(TestCase_StylizationFunctionsJPG);
 
@@ -128,6 +136,8 @@
     CPPUNIT_TEST(TestCase_RenderLegendMultiFTSSingleCTSJPG);
     CPPUNIT_TEST(TestCase_RenderLegendSingleFTSMultiCTSJPG);
     CPPUNIT_TEST(TestCase_LayerWatermarkJPG);
+    CPPUNIT_TEST(TestCase_RenderTileJPG);
+    CPPUNIT_TEST(TestCase_RenderTileXYZ_JPG);
 
     CPPUNIT_TEST(TestCase_QueryFeatures);
 
@@ -146,6 +156,9 @@
     void TestEnd();
 
     void TestCase_QueryFeatures();
+    void TestCase_RenderTileBaseline();
+    void TestCase_RenderTile(CREFSTRING imageFormat, CREFSTRING extension);
+    void TestCase_RenderTileXYZ(CREFSTRING imageFormat, CREFSTRING extension);
 
     //Parameterized versions that all format-specific tests call into
     void TestCase_RenderDynamicOverlay(CREFSTRING imageFormat, CREFSTRING extension);
@@ -198,6 +211,8 @@
     void TestCase_RenderLegendSingleFTSMultiCTSPNG() { TestCase_RenderLegendSingleFTSMultiCTS(L"PNG", L"png"); }
     void TestCase_StylizationFunctionsPNG() { TestCase_StylizationFunctions(L"PNG", L"png"); }
     void TestCase_LayerWatermarkPNG() { TestCase_LayerWatermark(L"PNG", L"png"); }
+    void TestCase_RenderTilePNG() { TestCase_RenderTile(L"PNG", L"png"); }
+    void TestCase_RenderTileXYZ_PNG() { TestCase_RenderTileXYZ(L"PNG", L"png"); }
 
     //PNG8 output tests
     void TestCase_RenderDynamicOverlayPNG8() { TestCase_RenderDynamicOverlay(L"PNG8", L"png"); }
@@ -222,6 +237,8 @@
     void TestCase_RenderLegendSingleFTSMultiCTSPNG8() { TestCase_RenderLegendSingleFTSMultiCTS(L"PNG8", L"png"); }
     void TestCase_StylizationFunctionsPNG8() { TestCase_StylizationFunctions(L"PNG8", L"png"); }
     void TestCase_LayerWatermarkPNG8() { TestCase_LayerWatermark(L"PNG8", L"png"); }
+    void TestCase_RenderTilePNG8() { TestCase_RenderTile(L"PNG8", L"png"); }
+    void TestCase_RenderTileXYZ_PNG8() { TestCase_RenderTileXYZ(L"PNG8", L"png"); }
 
     //GIF output tests
     void TestCase_RenderDynamicOverlayGIF() { TestCase_RenderDynamicOverlay(L"GIF", L"gif"); }
@@ -246,6 +263,8 @@
     void TestCase_RenderLegendSingleFTSMultiCTSGIF() { TestCase_RenderLegendSingleFTSMultiCTS(L"GIF", L"gif"); }
     void TestCase_StylizationFunctionsGIF() { TestCase_StylizationFunctions(L"GIF", L"gif"); }
     void TestCase_LayerWatermarkGIF() { TestCase_LayerWatermark(L"GIF", L"gif"); }
+    void TestCase_RenderTileGIF() { TestCase_RenderTile(L"GIF", L"gif"); }
+    void TestCase_RenderTileXYZ_GIF() { TestCase_RenderTileXYZ(L"GIF", L"gif"); }
 
     //JPG output tests
     void TestCase_RenderDynamicOverlayJPG() { TestCase_RenderDynamicOverlay(L"JPG", L"jpg"); }
@@ -270,6 +289,8 @@
     void TestCase_RenderLegendSingleFTSMultiCTSJPG() { TestCase_RenderLegendSingleFTSMultiCTS(L"JPG", L"jpg"); }
     void TestCase_StylizationFunctionsJPG() { TestCase_StylizationFunctions(L"JPG", L"jpg"); }
     void TestCase_LayerWatermarkJPG() { TestCase_LayerWatermark(L"JPG", L"jpg"); }
+    void TestCase_RenderTileJPG() { TestCase_RenderTile(L"JPG", L"jpg"); }
+    void TestCase_RenderTileXYZ_JPG() { TestCase_RenderTileXYZ(L"JPG", L"jpg"); }
 
     //void TestCase_RendererPerformance();
 

Modified: trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -27,6 +27,10 @@
 // determines the number of requests to make, as a factor of the number of tiles
 #define REQUEST_FACTOR 20
 
+// determines the interval of requests made for the ACE thread manager to wait for the entire thread group to complete
+// (to avoid deadlock issues on Linux)
+#define REQUEST_WAIT_INTERVAL 25
+
 // define thread group for tiling tests
 #define THREAD_GROUP 65535
 
@@ -118,6 +122,21 @@
         Ptr<MgByteReader> mdfrdr1 = mdfsrc1->GetReader();
         m_svcResource->SetResource(mapres1, mdfrdr1, NULL);
 
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+        Ptr<MgByteSource> mdfsrc2 = new MgByteSource(L"../UnitTestFiles/UT_LinkedTileSet.mdf", false);
+        Ptr<MgByteReader> mdfrdr2 = mdfsrc2->GetReader();
+        m_svcResource->SetResource(mapres2, mdfrdr2, NULL);
+
+        Ptr<MgResourceIdentifier> tilesetres1 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc1 = new MgByteSource(L"../UnitTestFiles/UT_BaseMap.tsd", false);
+        Ptr<MgByteReader> tsdrdr1 = tsdsrc1->GetReader();
+        m_svcResource->SetResource(tilesetres1, tsdrdr1, NULL);
+
+        Ptr<MgResourceIdentifier> tilesetres2 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ.TileSetDefinition");
+        Ptr<MgByteSource> tsdsrc2 = new MgByteSource(L"../UnitTestFiles/UT_XYZ.tsd", false);
+        Ptr<MgByteReader> tsdrdr2 = tsdsrc2->GetReader();
+        m_svcResource->SetResource(tilesetres2, tsdrdr2, NULL);
+
         // publish the layer definitions
         Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
         Ptr<MgByteSource> ldfsrc1 = new MgByteSource(L"../UnitTestFiles/UT_RoadCenterLines.ldf", false);
@@ -196,6 +215,12 @@
         Ptr<MgResourceIdentifier> mapres1 = new MgResourceIdentifier(L"Library://UnitTests/Maps/BaseMap.MapDefinition");
         m_svcResource->DeleteResource(mapres1);
 
+        Ptr<MgResourceIdentifier> mapres2 = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+        m_svcResource->DeleteResource(mapres2);
+
+        Ptr<MgResourceIdentifier> tilesetres1 = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        m_svcResource->DeleteResource(tilesetres1);
+
         // delete the layer definitions
         Ptr<MgResourceIdentifier> ldfres1 = new MgResourceIdentifier(L"Library://UnitTests/Layers/RoadCenterLines.LayerDefinition");
         m_svcResource->DeleteResource(ldfres1);
@@ -251,6 +276,8 @@
     Ptr<MgMap> map;
     INT32 tileRow;
     INT32 tileCol;
+    INT32 tileScale;
+    STRING tileSetId;
 };
 
 
@@ -422,7 +449,7 @@
                 break;
 
             // under Linux we get a deadlock if we don't call this every once in a while
-            if (nRequest % 25 == 0)
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
                 manager->wait_grp(THREAD_GROUP);
             else
             {
@@ -451,7 +478,198 @@
     }
 }
 
+// the method which gets executed by the ACE worker thread
+ACE_THR_FUNC_RETURN GetTileLinkedWorker(void* param)
+{
+    // get the data for this thread
+    TileThreadData* threadData = (TileThreadData*)param;
+    INT32 threadId = threadData->threadId;
+    INT32 tileRow  = threadData->tileRow;
+    INT32 tileCol  = threadData->tileCol;
+    INT32 tileScale = threadData->tileScale;
+    bool saveTile  = threadData->saveTile;
+    Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(threadData->tileSetId);
+    #ifdef _DEBUG
+    printf("> thread %d started, tile %d,%d\n", threadId, tileRow, tileCol);
+    #endif
 
+    try
+    {
+        // set user info
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
+        userInfo->SetLocale(TEST_LOCALE);
+        MgUserInformation::SetCurrentUserInfo(userInfo);
+
+        // get the tile service instance
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        Ptr<MgTileService> svcTile = dynamic_cast<MgTileService*>(
+            serviceManager->RequestService(MgServiceType::TileService));
+        assert(svcTile != NULL);
+
+        // get the tile
+        Ptr<MgByteReader> img = svcTile->GetTile(tsId, L"BaseLayers", tileCol, tileRow, tileScale);
+        CHECKNULL((MgByteReader*)img, L"GetTileLinkedWorker");
+
+        // save the image to a file if necessary
+        if (saveTile)
+        {
+            wchar_t imgName[PATH_LEN] = { 0 };
+            swprintf(imgName, PATH_LEN, L"./temp_tiles/tile%d_%d.png", tileRow, tileCol);
+            (MgByteSink(img)).ToFile(imgName);
+        }
+
+        // clear the user info to prevent leaks
+        MgUserInformation::SetCurrentUserInfo(NULL);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+
+    #ifdef _DEBUG
+//  printf("> thread %d done\n", threadId);
+    #endif
+
+    threadData->done = true;
+    return 0;
+}
+
+void TestTileService::TestCase_GetTileLinked()
+{
+    // specify the number of threads to use
+    const INT32 numThreads = MG_TEST_THREADS;
+    TileThreadData threadData[numThreads];
+
+    // define the range of tiles to get
+    INT32 tileRowMin =  0;
+    INT32 tileRowMax = 12;
+    INT32 tileColMin =  3;
+    INT32 tileColMax = 11;
+
+    try
+    {
+        // need a thread manager
+        ACE_Thread_Manager* manager = ACE_Thread_Manager::instance();
+
+        // make the runtime map
+        Ptr<MgMap> map = CreateMapLinked();
+        Ptr<MgResourceIdentifier> tsId;
+        Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+        Ptr<MgLayerGroup> group = groups->GetItem(L"BaseLayers");
+        tsId = map->GetTileSetDefinition();
+
+        // set up the tile indices
+        INT32 numTileRows = tileRowMax - tileRowMin + 1;
+        INT32 numTileCols = tileColMax - tileColMin + 1;
+        INT32 numTiles    = numTileRows * numTileCols;
+
+        INT32* tileRows = new INT32[numTiles];
+        INT32* tileCols = new INT32[numTiles];
+
+        INT32 nRequest = 0;
+        for (INT32 tileRow = tileRowMin; tileRow <= tileRowMax; ++tileRow)
+        {
+            for (INT32 tileCol = tileColMin; tileCol <= tileColMax; ++tileCol)
+            {
+                tileRows[nRequest] = tileRow;
+                tileCols[nRequest] = tileCol;
+                nRequest++;
+            }
+        }
+
+        // initialize the thread data
+        for (INT32 i=0; i<numThreads; i++)
+        {
+            // each thread works with its own instance of the map
+            threadData[i].threadId = i;
+            threadData[i].done     = true;
+            threadData[i].saveTile = false;
+            threadData[i].tileRow  = 0;
+            threadData[i].tileCol  = 0;
+            threadData[i].tileScale = 4;
+            threadData[i].tileSetId = tsId->ToString().c_str();
+        }
+
+        // execute the requests to randomly access the tiles
+        #ifdef _DEBUG
+        printf("\n");
+        #endif
+        nRequest = 0;
+        for (;;)
+        {
+            INT32 dc = 0;
+            for (INT32 i=0; i<numThreads; i++)
+            {
+                // check if the thread is available
+                if (threadData[i].done)
+                {
+                    // if we're not yet done then give the thread a new request
+                    if (nRequest < REQUEST_FACTOR*numTiles)
+                    {
+                        // pick a random request to execute...
+                        INT32 nTile = Rand(numTiles);
+
+                        // ... but make every REQUEST_FACTOR-th tile non-random to
+                        // ensure we get each tile at least once
+                        if (nRequest % REQUEST_FACTOR == 0)
+                            nTile = nRequest / REQUEST_FACTOR;
+
+                        threadData[i].done     = false;
+                        threadData[i].saveTile = (nRequest % REQUEST_FACTOR == 0);
+                        threadData[i].tileRow  = tileRows[nTile];
+                        threadData[i].tileCol  = tileCols[nTile];
+
+                        // spawn a new thread using a specific group id
+                        int thid = manager->spawn(ACE_THR_FUNC(GetTileLinkedWorker), &threadData[i], 0, NULL, NULL, 0, THREAD_GROUP);
+                        nRequest++;
+                    }
+
+                    // keep a tally of all the done threads
+                    if (threadData[i].done)
+                        ++dc;
+                }
+            }
+
+            // move on if all threads are done
+            if (dc == numThreads)
+                break;
+
+            // under Linux we get a deadlock if we don't call this every once in a while
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
+                manager->wait_grp(THREAD_GROUP);
+            else
+            {
+                // pause briefly (10ms) before checking again
+                ACE_Time_Value t(0, 10000);
+                ACE_OS::sleep(t);
+            }
+        }
+
+        // make sure all threads in the group have completed
+        manager->wait_grp(THREAD_GROUP);
+
+        // done with the tile indices
+        delete [] tileRows;
+        delete [] tileCols;
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 ////////////////////////////////////////////////////////////////
 /// SetTile methods
 ////////////////////////////////////////////////////////////////
@@ -617,7 +835,7 @@
                 break;
 
             // under Linux we get a deadlock if we don't call this every once in a while
-            if (nRequest % 25 == 0)
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
                 manager->wait_grp(THREAD_GROUP);
             else
             {
@@ -680,7 +898,7 @@
                 break;
 
             // under Linux we get a deadlock if we don't call this every once in a while
-            if (nRequest % 25 == 0)
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
                 manager->wait_grp(THREAD_GROUP);
             else
             {
@@ -815,7 +1033,7 @@
                 break;
 
             // under Linux we get a deadlock if we don't call this every once in a while
-            if (nRequest % 25 == 0)
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
                 manager->wait_grp(THREAD_GROUP);
             else
             {
@@ -844,7 +1062,6 @@
     }
 }
 
-
 ////////////////////////////////////////////////////////////////
 /// ClearCache methods
 ////////////////////////////////////////////////////////////////
@@ -855,7 +1072,7 @@
     try
     {
         // call the API with a NULL argument
-        CPPUNIT_ASSERT_THROW_MG(m_svcTile->ClearCache(NULL), MgNullArgumentException*);
+        CPPUNIT_ASSERT_THROW_MG(m_svcTile->ClearCache((MgMap*)NULL), MgNullArgumentException*);
 
         // call the API with a map having a different name
         Ptr<MgMap> map = CreateMap(L"blah");
@@ -880,7 +1097,541 @@
     }
 }
 
+// the method which gets executed by the ACE worker thread
+ACE_THR_FUNC_RETURN GetTileXYZWorker(void* param)
+{
+    // get the data for this thread
+    TileThreadData* threadData = (TileThreadData*)param;
+    INT32 threadId = threadData->threadId;
+    INT32 tileRow  = threadData->tileRow;
+    INT32 tileCol  = threadData->tileCol;
+    INT32 tileScale = threadData->tileScale;
+    bool saveTile  = threadData->saveTile;
+    Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(threadData->tileSetId);
+    #ifdef _DEBUG
+    printf("> thread %d started, tile %d,%d\n", threadId, tileRow, tileCol);
+    #endif
 
+    try
+    {
+        // set user info
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(L"Administrator", L"admin");
+        userInfo->SetLocale(TEST_LOCALE);
+        MgUserInformation::SetCurrentUserInfo(userInfo);
+
+        // get the tile service instance
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        Ptr<MgTileService> svcTile = dynamic_cast<MgTileService*>(
+            serviceManager->RequestService(MgServiceType::TileService));
+        assert(svcTile != NULL);
+
+        // get the tile
+        Ptr<MgByteReader> img = svcTile->GetTile(tsId, L"BaseLayers", tileCol, tileRow, tileScale);
+        CHECKNULL((MgByteReader*)img, L"GetTileXYZWorker");
+
+        // save the image to a file if necessary
+        if (saveTile)
+        {
+            wchar_t imgName[PATH_LEN] = { 0 };
+            swprintf(imgName, PATH_LEN, L"./temp_tiles/tile%d_%d.png", tileRow, tileCol);
+            (MgByteSink(img)).ToFile(imgName);
+        }
+
+        // clear the user info to prevent leaks
+        MgUserInformation::SetCurrentUserInfo(NULL);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+
+    #ifdef _DEBUG
+//  printf("> thread %d done\n", threadId);
+    #endif
+
+    threadData->done = true;
+    return 0;
+}
+
+
+void TestTileService::TestCase_GetTileXYZ()
+{
+    // specify the number of threads to use
+    const INT32 numThreads = MG_TEST_THREADS;
+    TileThreadData threadData[numThreads];
+
+    // define the range of tiles to get
+    INT32 tileRowMin = 33587;
+    INT32 tileRowMax = 33601;
+    INT32 tileColMin = 47766;
+    INT32 tileColMax = 47784;
+
+    try
+    {
+        // need a thread manager
+        ACE_Thread_Manager* manager = ACE_Thread_Manager::instance();
+
+        // make the runtime map
+        Ptr<MgMap> map = CreateMap();
+
+        // set up the tile indices
+        INT32 numTileRows = tileRowMax - tileRowMin + 1;
+        INT32 numTileCols = tileColMax - tileColMin + 1;
+        INT32 numTiles    = numTileRows * numTileCols;
+
+        INT32* tileRows = new INT32[numTiles];
+        INT32* tileCols = new INT32[numTiles];
+
+        INT32 nRequest = 0;
+        for (INT32 tileRow = tileRowMin; tileRow <= tileRowMax; ++tileRow)
+        {
+            for (INT32 tileCol = tileColMin; tileCol <= tileColMax; ++tileCol)
+            {
+                tileRows[nRequest] = tileRow;
+                tileCols[nRequest] = tileCol;
+                nRequest++;
+            }
+        }
+
+        // initialize the thread data
+        for (INT32 i=0; i<numThreads; i++)
+        {
+            threadData[i].threadId = i;
+            threadData[i].done     = true;
+            threadData[i].saveTile = false;
+            threadData[i].tileSetId = L"Library://UnitTests/TileSets/XYZ.TileSetDefinition";
+            threadData[i].tileRow  = 0;
+            threadData[i].tileCol  = 0;
+            threadData[i].tileScale = 17; //z
+        }
+
+        // execute the requests to randomly access the tiles
+        #ifdef _DEBUG
+        printf("\n");
+        #endif
+        nRequest = 0;
+        for (;;)
+        {
+            INT32 dc = 0;
+            for (INT32 i=0; i<numThreads; i++)
+            {
+                // check if the thread is available
+                if (threadData[i].done)
+                {
+                    // if we're not yet done then give the thread a new request
+                    if (nRequest < REQUEST_FACTOR*numTiles)
+                    {
+                        // pick a random request to execute...
+                        INT32 nTile = Rand(numTiles);
+
+                        // ... but make every REQUEST_FACTOR-th tile non-random to
+                        // ensure we get each tile at least once
+                        if (nRequest % REQUEST_FACTOR == 0)
+                            nTile = nRequest / REQUEST_FACTOR;
+
+                        threadData[i].done     = false;
+                        threadData[i].saveTile = (nRequest % REQUEST_FACTOR == 0);
+                        threadData[i].tileRow  = tileRows[nTile];
+                        threadData[i].tileCol  = tileCols[nTile];
+
+                        // spawn a new thread using a specific group id
+                        int thid = manager->spawn(ACE_THR_FUNC(GetTileXYZWorker), &threadData[i], 0, NULL, NULL, 0, THREAD_GROUP);
+                        nRequest++;
+                    }
+
+                    // keep a tally of all the done threads
+                    if (threadData[i].done)
+                        ++dc;
+                }
+            }
+
+            // move on if all threads are done
+            if (dc == numThreads)
+                break;
+
+            // under Linux we get a deadlock if we don't call this every once in a while
+            if (nRequest % REQUEST_WAIT_INTERVAL == 0)
+                manager->wait_grp(THREAD_GROUP);
+            else
+            {
+                // pause briefly (10ms) before checking again
+                ACE_Time_Value t(0, 10000);
+                ACE_OS::sleep(t);
+            }
+        }
+
+        // make sure all threads in the group have completed
+        manager->wait_grp(THREAD_GROUP);
+
+        // done with the tile indices
+        delete [] tileRows;
+        delete [] tileCols;
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+
+void TestTileService::TestCase_ClearCacheLinked()
+{
+    try
+    {
+        // call the API with a NULL argument
+        CPPUNIT_ASSERT_THROW_MG(m_svcTile->ClearCache((MgResourceIdentifier*)NULL), MgNullArgumentException*);
+
+        Ptr<MgResourceIdentifier> tsId = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        m_svcTile->ClearCache(tsId);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+
+void TestTileService::TestCase_MgMap_Inline()
+{
+    try
+    {
+        STRING mapName = L"TestCase_MgMap_Inline";
+        Ptr<MgMap> map = CreateMap(mapName);
+
+        Ptr<MgEnvelope> extents = map->GetMapExtent();
+        Ptr<MgCoordinate> ll = extents->GetLowerLeftCoordinate();
+        Ptr<MgCoordinate> ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.79786601383196, ll->GetX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181,   ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.66452777186925, ur->GetX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.8037962206133,  ur->GetY(), 0.0000000000001);
+        Ptr<MgResourceIdentifier> tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL == (MgResourceIdentifier*)tsId);
+
+        Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMap == group->GetLayerGroupType());
+        }
+
+        // Initialize service objects.
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        Ptr<MgServerSiteService> svcSite = dynamic_cast<MgServerSiteService*>(serviceManager->RequestService(MgServiceType::SiteService));
+        Ptr<MgResourceService> svcRes = dynamic_cast<MgResourceService*>(serviceManager->RequestService(MgServiceType::ResourceService));
+        assert(svcSite != NULL);
+        assert(svcRes != NULL);
+        // Set the current MgUserInformation
+        // This must be done before calling CreateSession()
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(
+            L"Administrator", L"admin");
+        userInfo->SetLocale(TEST_LOCALE);
+        MgUserInformation::SetCurrentUserInfo(userInfo);
+        STRING session = svcSite->CreateSession();
+
+        Ptr<MgResourceIdentifier> mapStateId = new MgResourceIdentifier(MgRepositoryType::Session, session, L"", map->GetName(), MgResourceType::Map);
+        map->Save(svcRes, mapStateId);
+
+        map = NULL;
+
+        Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
+        userInfo = new MgUserInformation(session);
+        siteConn->Open(userInfo);
+        map = new MgMap(siteConn);
+        map->Open(mapName);
+
+        //Re-check. All should be the same
+        extents = map->GetMapExtent();
+        ll = extents->GetLowerLeftCoordinate();
+        ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.79786601383196, ll->GetX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181,   ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.66452777186925, ur->GetX(), 0.00000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.8037962206133,  ur->GetY(), 0.0000000000001);
+        tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL == (MgResourceIdentifier*)tsId);
+
+        groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMap == group->GetLayerGroupType());
+        }
+
+        svcSite->DestroySession(session);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_MgMap_Linked()
+{
+    try
+    {
+        STRING mapName = L"TestCase_MgMap_Linked";
+        Ptr<MgMap> map = CreateMapLinked(mapName);
+
+        //Bounds should be that of the tile set
+        Ptr<MgEnvelope> extents = map->GetMapExtent();
+        Ptr<MgCoordinate> ll = extents->GetLowerLeftCoordinate();
+        Ptr<MgCoordinate> ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.797866013831, ll->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181, ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.664527771869, ur->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.803796220613, ur->GetY(), 0.000000000001);
+        Ptr<MgResourceIdentifier> tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != (MgResourceIdentifier*)tsId);
+        CPPUNIT_ASSERT(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition" == tsId->ToString());
+
+        Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMapFromTileSet == group->GetLayerGroupType());
+        }
+
+        // Initialize service objects.
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        Ptr<MgServerSiteService> svcSite = dynamic_cast<MgServerSiteService*>(serviceManager->RequestService(MgServiceType::SiteService));
+        Ptr<MgResourceService> svcRes = dynamic_cast<MgResourceService*>(serviceManager->RequestService(MgServiceType::ResourceService));
+        assert(svcSite != NULL);
+        assert(svcRes != NULL);
+        // Set the current MgUserInformation
+        // This must be done before calling CreateSession()
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(
+            L"Administrator", L"admin");
+        userInfo->SetLocale(TEST_LOCALE);
+        MgUserInformation::SetCurrentUserInfo(userInfo);
+        STRING session = svcSite->CreateSession();
+
+        Ptr<MgResourceIdentifier> mapStateId = new MgResourceIdentifier(MgRepositoryType::Session, session, L"", map->GetName(), MgResourceType::Map);
+        map->Save(svcRes, mapStateId);
+
+        map = NULL;
+
+        Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
+        userInfo = new MgUserInformation(session);
+        siteConn->Open(userInfo);
+        map = new MgMap(siteConn);
+        map->Open(mapName);
+
+        //Re-check. All should be the same
+        extents = map->GetMapExtent();
+        ll = extents->GetLowerLeftCoordinate();
+        ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.797866013831, ll->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181, ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.664527771869, ur->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.803796220613, ur->GetY(), 0.000000000001);
+        tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != (MgResourceIdentifier*)tsId);
+        CPPUNIT_ASSERT(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition" == tsId->ToString());
+
+        groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMapFromTileSet == group->GetLayerGroupType());
+        }
+
+        svcSite->DestroySession(session);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_MgMapFromXYZTileSetStrict()
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgResourceIdentifier> tsdres = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ.TileSetDefinition");
+        MgMap* map = new MgMap(m_siteConnection);
+        map->Create(tsdres, L"XYZTileSet");
+
+        CPPUNIT_FAIL("MgUnsupportedTileProviderException should've been thrown");
+    }
+    catch (MgException* e)
+    {
+        bool isCorrectException = e->IsOfClass(MapGuide_Exception_MgUnsupportedTileProviderException);
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_ASSERT_MESSAGE(MG_WCHAR_TO_CHAR(message), isCorrectException);
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_MgMapFromXYZTileSetLoose()
+{
+    try
+    {
+        // make a runtime map
+        Ptr<MgResourceIdentifier> tsdres = new MgResourceIdentifier(L"Library://UnitTests/TileSets/XYZ.TileSetDefinition");
+        MgMap* map = new MgMap(m_siteConnection);
+        map->Create(m_svcResource, tsdres, L"XYZTileSet", false);
+
+        CPPUNIT_ASSERT(0 == map->GetFiniteDisplayScaleCount());
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_MgMapFromTileSet()
+{
+    try
+    {
+        STRING mapName = L"TestCase_MgMapFromTileSet";
+
+        // make a runtime map
+        Ptr<MgResourceIdentifier> tsdres = new MgResourceIdentifier(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition");
+        MgMap* map = new MgMap(m_siteConnection);
+        map->Create(tsdres, mapName);
+
+        Ptr<MgResourceIdentifier> mdfId = map->GetMapDefinition();
+        CPPUNIT_ASSERT(NULL == (MgResourceIdentifier*)mdfId);
+
+        //Bounds should be that of the tile set
+        Ptr<MgEnvelope> extents = map->GetMapExtent();
+        Ptr<MgCoordinate> ll = extents->GetLowerLeftCoordinate();
+        Ptr<MgCoordinate> ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.797866013831, ll->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181, ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.664527771869, ur->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.803796220613, ur->GetY(), 0.000000000001);
+        Ptr<MgResourceIdentifier> tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != (MgResourceIdentifier*)tsId);
+        CPPUNIT_ASSERT(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition" == tsId->ToString());
+
+        Ptr<MgLayerGroupCollection> groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMapFromTileSet == group->GetLayerGroupType());
+        }
+
+        // Initialize service objects.
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        Ptr<MgServerSiteService> svcSite = dynamic_cast<MgServerSiteService*>(serviceManager->RequestService(MgServiceType::SiteService));
+        Ptr<MgResourceService> svcRes = dynamic_cast<MgResourceService*>(serviceManager->RequestService(MgServiceType::ResourceService));
+        assert(svcSite != NULL);
+        assert(svcRes != NULL);
+        // Set the current MgUserInformation
+        // This must be done before calling CreateSession()
+        Ptr<MgUserInformation> userInfo = new MgUserInformation(
+            L"Administrator", L"admin");
+        userInfo->SetLocale(TEST_LOCALE);
+        MgUserInformation::SetCurrentUserInfo(userInfo);
+        STRING session = svcSite->CreateSession();
+
+        Ptr<MgResourceIdentifier> mapStateId = new MgResourceIdentifier(MgRepositoryType::Session, session, L"", map->GetName(), MgResourceType::Map);
+        map->Save(svcRes, mapStateId);
+
+        map = NULL;
+
+        Ptr<MgSiteConnection> siteConn = new MgSiteConnection();
+        userInfo = new MgUserInformation(session);
+        siteConn->Open(userInfo);
+        map = new MgMap(siteConn);
+        map->Open(mapName);
+
+        //Re-check. All should be the same
+        extents = map->GetMapExtent();
+        ll = extents->GetLowerLeftCoordinate();
+        ur = extents->GetUpperRightCoordinate();
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.797866013831, ll->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.686857862181, ll->GetY(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(-87.664527771869, ur->GetX(), 0.000000000001);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL( 43.803796220613, ur->GetY(), 0.000000000001);
+        tsId = map->GetTileSetDefinition();
+        CPPUNIT_ASSERT(NULL != (MgResourceIdentifier*)tsId);
+        CPPUNIT_ASSERT(L"Library://UnitTests/TileSets/Sheboygan.TileSetDefinition" == tsId->ToString());
+
+        groups = map->GetLayerGroups();
+        for (INT32 i = 0; i < groups->GetCount(); i++)
+        {
+            Ptr<MgLayerGroup> group = groups->GetItem(i);
+            CPPUNIT_ASSERT(MgLayerGroupType::BaseMapFromTileSet == group->GetLayerGroupType());
+        }
+
+        svcSite->DestroySession(session);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestTileService::TestCase_GetTileProviders()
+{
+    try
+    {
+        Ptr<MgByteReader> content = m_svcTile->GetTileProviders();
+        Ptr<MgByteSink> sink = new MgByteSink(content);
+        sink->ToFile(L"../UnitTestFiles/GetTileProviders_Result.xml");
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 ////////////////////////////////////////////////////////////////
 /// Helpers
 ////////////////////////////////////////////////////////////////
@@ -911,6 +1662,30 @@
 }
 
 
+MgMap* TestTileService::CreateMapLinked(CREFSTRING mapName)
+{
+    // set a default name if not supplied
+    STRING name = (mapName.empty())? L"UnitTestBaseMapLinked" : mapName;
+
+    // make a runtime map
+    Ptr<MgResourceIdentifier> mdfres = new MgResourceIdentifier(L"Library://UnitTests/Maps/LinkedTileSet.MapDefinition");
+    MgMap* map = new MgMap(m_siteConnection);
+    map->Create(mdfres, name);
+
+    // set the view
+    Ptr<MgCoordinate> coordNewCenter = new MgCoordinateXY(-87.723636, 43.715015);
+    Ptr<MgPoint> ptNewCenter = new MgPoint(coordNewCenter);
+    map->SetViewCenter(ptNewCenter);
+    map->SetDisplayDpi(96);
+    map->SetDisplayWidth(1024);
+    map->SetDisplayHeight(1024);
+
+    // render at a scale of 1:12500
+    map->SetViewScale(12500.0);
+
+    return map;
+}
+
 // returns a random integer in the range 0 to n-1
 INT32 TestTileService::Rand(INT32 n)
 {

Modified: trunk/MgDev/Server/src/UnitTesting/TestTileService.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestTileService.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Server/src/UnitTesting/TestTileService.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -25,10 +25,19 @@
     CPPUNIT_TEST_SUITE(TestTileService);
     CPPUNIT_TEST(TestStart); // This must be the very first unit test
 
+    CPPUNIT_TEST(TestCase_GetTileProviders);
+    CPPUNIT_TEST(TestCase_MgMap_Inline);
+    CPPUNIT_TEST(TestCase_MgMap_Linked);
+    CPPUNIT_TEST(TestCase_MgMapFromXYZTileSetStrict);
+    CPPUNIT_TEST(TestCase_MgMapFromXYZTileSetLoose);
+    CPPUNIT_TEST(TestCase_MgMapFromTileSet);
     CPPUNIT_TEST(TestCase_GetTile);
     CPPUNIT_TEST(TestCase_SetTile);
     CPPUNIT_TEST(TestCase_GetSetTile);
     CPPUNIT_TEST(TestCase_ClearCache);
+    CPPUNIT_TEST(TestCase_GetTileLinked);
+    CPPUNIT_TEST(TestCase_GetTileXYZ);
+    CPPUNIT_TEST(TestCase_ClearCacheLinked);
 
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
     CPPUNIT_TEST_SUITE_END();
@@ -42,13 +51,23 @@
     void TestStart();
     void TestEnd();
 
+    void TestCase_GetTileProviders();
+    void TestCase_MgMap_Inline();
+    void TestCase_MgMap_Linked();
+    void TestCase_MgMapFromXYZTileSetStrict();
+    void TestCase_MgMapFromXYZTileSetLoose();
+    void TestCase_MgMapFromTileSet();
     void TestCase_GetTile();
     void TestCase_SetTile();
     void TestCase_GetSetTile();
+    void TestCase_GetTileXYZ();
     void TestCase_ClearCache();
+    void TestCase_GetTileLinked();
+    void TestCase_ClearCacheLinked();
 
 private:
     MgMap* CreateMap(CREFSTRING mapName = L"");
+    MgMap* CreateMapLinked(CREFSTRING mapName = L"");
     INT32 Rand(INT32 n);
 
 private:

Modified: trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml
===================================================================
--- trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0.0" xsi:noNamespaceSchemaLocation="LayerDefinition-1.0.0.xsd">
   <VectorLayerDefinition>
     <ResourceId>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</ResourceId>
@@ -9,7 +9,7 @@
       <MinScale>10000</MinScale>
       <AreaTypeStyle>
         <AreaRule>
-          <LegendLabel />
+          <LegendLabel/>
           <Label>
             <Unit>Points</Unit>
             <SizeContext>DeviceUnits</SizeContext>

Modified: trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_CONTENT.xml
===================================================================
--- trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_CONTENT.xml	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_CONTENT.xml	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.4.0" xsi:noNamespaceSchemaLocation="LayerDefinition-2.4.0.xsd">
   <VectorLayerDefinition>
     <ResourceId>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</ResourceId>
-    <Watermarks />
+    <Watermarks/>
     <FeatureName>Default:VotingDistricts</FeatureName>
     <FeatureNameType>FeatureClass</FeatureNameType>
     <Geometry>Geometry</Geometry>
@@ -10,7 +10,7 @@
       <MinScale>10000</MinScale>
       <CompositeTypeStyle>
         <CompositeRule>
-          <LegendLabel />
+          <LegendLabel/>
           <CompositeSymbolization>
             <SymbolInstance>
               <SimpleSymbolDefinition>
@@ -192,21 +192,21 @@
                   </Parameter>
                   <Parameter>
                     <Identifier>GHOSTCOLOR</Identifier>
-                    <DefaultValue />
+                    <DefaultValue/>
                     <DisplayName>Ghost Color</DisplayName>
                     <Description>Ghost Color</Description>
                     <DataType>GhostColor</DataType>
                   </Parameter>
                   <Parameter>
                     <Identifier>FRAMELINECOLOR</Identifier>
-                    <DefaultValue />
+                    <DefaultValue/>
                     <DisplayName>Frame Line Color</DisplayName>
                     <Description>Frame Line Color</Description>
                     <DataType>FrameLineColor</DataType>
                   </Parameter>
                   <Parameter>
                     <Identifier>FRAMEFILLCOLOR</Identifier>
-                    <DefaultValue />
+                    <DefaultValue/>
                     <DisplayName>Frame Fill Color</DisplayName>
                     <Description>Frame Fill Color</Description>
                     <DataType>FrameFillColor</DataType>

Modified: trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml
===================================================================
--- trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<MapDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.4.0" xsi:noNamespaceSchemaLocation="MapDefinition-2.4.0.xsd">
+<MapDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="MapDefinition-3.0.0.xsd" version="3.0.0">
   <Name>Sheboygan Tiled Map</Name>
   <CoordinateSystem>GEOGCS["WGS84 Lat/Long's, Degrees, -180 ==> +180",DATUM["D_WGS_1984",SPHEROID["World_Geodetic_System_of_1984",6378137,298.257222932867]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]</CoordinateSystem>
   <Extents>
@@ -9,79 +9,9 @@
     <MaxY>43.797520000480347</MaxY>
   </Extents>
   <BackgroundColor>ffcdbd9c</BackgroundColor>
-  <BaseMapDefinition>
-    <FiniteDisplayScale>1000</FiniteDisplayScale>
-    <FiniteDisplayScale>1930.69773</FiniteDisplayScale>
-    <FiniteDisplayScale>3727.59372</FiniteDisplayScale>
-    <FiniteDisplayScale>7196.85673</FiniteDisplayScale>
-    <FiniteDisplayScale>13894.95494</FiniteDisplayScale>
-    <FiniteDisplayScale>26826.95795</FiniteDisplayScale>
-    <FiniteDisplayScale>51794.74679</FiniteDisplayScale>
-    <FiniteDisplayScale>100000</FiniteDisplayScale>
-    <BaseMapLayerGroup>
-      <Name>Base Layer Group</Name>
-      <Visible>true</Visible>
-      <ShowInLegend>true</ShowInLegend>
-      <ExpandInLegend>true</ExpandInLegend>
-      <LegendLabel>Tiled Layers</LegendLabel>
-      <BaseMapLayer>
-        <Name>Roads</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Roads.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Roads</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>Districts</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Districts.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Districts</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>Buildings</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Buildings.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Buildings</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>Parcels</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition</ResourceId>
-        <Selectable>true</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Parcels</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>Islands</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Islands.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Islands</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>Hydrography</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/Hydrography.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>Hydrography</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-      <BaseMapLayer>
-        <Name>CityLimits</Name>
-        <ResourceId>Library://Samples/Sheboygan/Layers/CityLimits.LayerDefinition</ResourceId>
-        <Selectable>false</Selectable>
-        <ShowInLegend>true</ShowInLegend>
-        <LegendLabel>CityLimits</LegendLabel>
-        <ExpandInLegend>true</ExpandInLegend>
-      </BaseMapLayer>
-    </BaseMapLayerGroup>
-  </BaseMapDefinition>
+  <TileSetSource>
+    <ResourceId>Library://Samples/Sheboygan/TileSets/Sheboygan.TileSetDefinition</ResourceId>
+  </TileSetSource>
   <Watermarks>
     <Watermark>
       <Name>MapTiledText</Name>

Modified: trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/MgResourcePackageManifest.xml
===================================================================
--- trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/MgResourcePackageManifest.xml	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/TestData/Samples/Sheboygan/MgResourcePackageManifest.xml	2014-08-12 11:11:22 UTC (rev 8330)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no" ?><ResourcePackageManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ResourcePackageManifest-1.0.0.xsd"><Operations><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/S
 amples/Sheboygan/Layers/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/MapsTiled/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/MapsTiled/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samp
 les/Sheboygan/Layouts/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/S
 heboygan/Watermarks/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/CityLimits.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</
 ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/CityLimits.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Buildings.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Buildings.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>
 Library://Samples/Sheboygan/Layers/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Hydrography.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Hydrography.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>
 Library://Samples/Sheboygan/Layers/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Islands.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Islands.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboyga
 n/Layers/Parcels.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Parcels.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Tracks.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Tracks.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</Conte
 ntType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</
 Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0
 .0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value
 >Library/Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout</Value></Para
 meter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout</Value></Parameter></Paramete
 rs></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_CONTENT.xml</Value><ContentType>text/xml<
 /ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_DATA_symbols.dwf</Value><ContentType>model/vnd.dwf</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>5594</Value></Parameter><Parameter><Name>DATANAME</Name><Value>symbols.dwf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Versio
 n><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_DATA_symbols.dwf</Value><ContentType>model/vnd.dwf</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>22760</Value></Parameter><P
 arameter><Name>DATANAME</Name><Value>symbols.dwf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.Fe
 atureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.FeatureSource_DATA_BuildingOutlines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>8038400</Value></Parameter><Parameter><Name>DATANAME</Name><Value>BuildingOutlines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>C
 ONTENT</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_DATA_CityLimits.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Parameter><Name>DATANAME</Name><Value>CityLimits.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.Fe
 atureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLines.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLines.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLin
 es.FeatureSource_DATA_HydrographicLines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>768000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>HydrographicLines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Sa
 mples/Sheboygan/Data/HydrographicPolygons.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource_DATA_HydrographicPolygons.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>512000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>HydrographicPolygons.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters
 ><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_DATA_Islands.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Paramet
 er><Name>DATANAME</Name><Value>Islands.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters
 ></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_DATA_LandUse.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>1996800</Value></Parameter><Parameter><Name>DATANAME</Name><Value>LandUse.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_CONTENT.x
 ml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_DATA_Parcels.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>11929600</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Parcels.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Versio
 n>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_DATA_Rail.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>870400</Value></Paramete
 r><Parameter><Name>DATANAME</Name><Value>Rail.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSo
 urce</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSource_DATA_RoadCenterLines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>665600</Value></Parameter><Parameter><Name>DATANAME</Name><Value>RoadCenterLines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Val
 ue>Library/Samples/Sheboygan/Data/Soils.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Soils.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Soils.FeatureSource_DATA_Soils.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>4556800</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Soils.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Opera
 tion><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_DATA_Trees.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Paramete
 r><Name>DATALENGTH</Name><Value>6656000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Trees.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value
 >Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_DATA_VotingDistricts.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Parameter><Name>DATANAME</Name><Value>VotingDistricts.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Ver
 sion>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Roads.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Libr
 ary/Samples/Sheboygan/Layers/Roads.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapText.WatermarkD
 efinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><V
 alue>Library://Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><P
 arameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganV26.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganV26.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layou
 ts/SheboyganV26.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganV26.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Flexibl
 eLayouts/SlateCommercial.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RE
 SOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operat
 ion><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition_CONTENT.x
 ml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition_HEADER.xml<
 /Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Trees.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Trees.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE<
 /Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Soils.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Soils.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><
 Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/S
 heboygan/Maps/SheboyganCommercial.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Adv
 anced/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name
 ><Value>Library://Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter>
 <Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Sample
 s/Sheboygan/Layers_Advanced/Soils.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Track
 s.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Rail.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Rail.SymbolDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Rail.SymbolDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Rail.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Trees.SymbolDefinition</Val
 ue></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Trees.SymbolDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Trees.SymbolDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Trees.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition_CONTENT.xml</Val
 ue><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition_HEADER.xml</Value><ContentType
 >text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Oper
 ation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition</Value></Parameter></Paramet
 ers></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition
 _CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout_HEADER.xml</Value><ContentType>t
 ext/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout</Value></Parameter></Parameters></Operation></Operations></ResourcePackageManifest>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?><ResourcePackageManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ResourcePackageManifest-1.0.0.xsd"><Operations><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/S
 amples/Sheboygan/Layers/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/MapsTiled/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/MapsTiled/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samp
 les/Sheboygan/Layouts/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/S
 heboygan/Watermarks/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/TileSets/_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/TileSets/</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEI
 D</Name><Value>Library://Samples/Sheboygan/Layers/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/CityLimits.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/CityLimits.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><V
 alue>Library/Samples/Sheboygan/Layers/Buildings.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Buildings.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Hydrography.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Hydrography.LayerDefinit
 ion_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Islands.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Islands.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DE
 LETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Parcels.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Parcels.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Ve
 rsion>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Tracks.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Tracks.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Valu
 e>Library/Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhpTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAspTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganA
 spTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJspTiled.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/She
 boyganPhp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganPhp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout_CONTEN
 T.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>
 RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganJsp.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID
 </Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary_DATA_symbols.dwf</Value><ContentType>model/vnd.dwf</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>5594</Value></Parameter><Paramete
 r><Name>DATANAME</Name><Value>symbols.dwf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/BasicSymbols.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter><
 /Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Symbols/Logos.SymbolLibrary_DATA_symbols.dwf</Value><ContentType>model/vnd.dwf</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>22760</Value></Parameter><Parameter><Name>DATANAME</Name><Value>symbols.dwf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Logos.SymbolLibrary</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.Featu
 reSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/BuildingOutlines.FeatureSource_DATA_BuildingOutlines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>8038400</Value></Parameter><Parameter><Name>DATANAME</Name><Value>BuildingOutlines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/BuildingOutlines.FeatureSource</Value></Parameter
 ></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/CityLimits.FeatureSource_DATA_CityLimits.sdf</Value><ContentType>applicat
 ion/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Parameter><Name>DATANAME</Name><Value>CityLimits.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/CityLimits.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLines.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLines.FeatureSource_HEADER.xml</Value><ContentType>text/xml
 </ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/HydrographicLines.FeatureSource_DATA_HydrographicLines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>768000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>HydrographicLines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource<
 /Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource_DATA_HydrographicPolygons.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>512000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>H
 ydrographicPolygons.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/HydrographicPolygons.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Ope
 ration><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Islands.FeatureSource_DATA_Islands.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Islands.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Islands.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_CONTENT.xml</Val
 ue><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/LandUse.FeatureSource_DATA_LandUse.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>1996800</Value></Parameter><Parameter><Name>DATANAME</Name><Value>LandUse.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/LandUse.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0<
 /Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Parcels.FeatureSource_DATA_Parcels.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>11929600</Valu
 e></Parameter><Parameter><Name>DATANAME</Name><Value>Parcels.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Parcels.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></
 Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Rail.FeatureSource_DATA_Rail.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>870400</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Rail.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Rail.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSou
 rce_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/RoadCenterLines.FeatureSource_DATA_RoadCenterLines.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>665600</Value></Parameter><Parameter><Name>DATANAME</Name><Value>RoadCenterLines.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/RoadCenterLines.FeatureSource</Value></Parameter></Parameter
 s></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Soils.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Soils.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Soils.FeatureSource_DATA_Soils.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter>
 <Parameter><Name>DATALENGTH</Name><Value>4556800</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Soils.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Soils.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sh
 eboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/Trees.FeatureSource_DATA_Trees.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>6656000</Value></Parameter><Parameter><Name>DATANAME</Name><Value>Trees.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/Trees.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Valu
 e>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/VotingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCEDATA</Name><Version>1.0.0</Version><Parameters><Parameter><Name>DATA</Name><Value>Library/Samples/Sheboygan/Data/VotingDistricts.FeatureSource_DATA_VotingDistricts.sdf</Value><ContentType>application/octet-stream</ContentType></Parameter><Parameter><Name>DATALENGTH</Name><Value>307200</Value></Parameter><Parameter><Name>DATANAME</Name><Value>VotingDistricts.sdf</Value></Parameter><Parameter><Name>DATATYPE</Name><Value>File</Value></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Data/V
 otingDistricts.FeatureSource</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Districts.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Roads
 .LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Roads.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Roads.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition
 _CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition_HEADE
 R.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapCommercialText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapTiledText.WatermarkDefinition</Value
 ></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganV26.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganV26.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/SheboyganV26.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/SheboyganV26.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition</
 Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/SlateCommercial.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Li
 brary/Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name>
 <Value>Library/Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/TurquoiseYellow.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCE
 ID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Aqua.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/LimeGold.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Ve
 rsion>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/FlexibleLayouts/Maroon.ApplicationDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Oper
 ation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Trees.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers/Trees.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers/Soils.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HE
 ADER</Name><Value>Library/Samples/Sheboygan/Layers/Soils.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value><
 /Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/SheboyganCommercial.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/CityLimit
 s.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/CityLimits.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/
 Sheboygan/Layers_Advanced/Hydrography.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Hydrography.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Ad
 vanced/Islands.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Islands.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Roads.LayerDefinition</Va
 lue></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Soils.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Tracks.L
 ayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Tracks.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Rail.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Rail.Symbol
 Definition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Rail.SymbolDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Rail.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Trees.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Symbols/Trees.SymbolDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Symbols/Trees.SymbolDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><P
 arameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Symbols/Trees.SymbolDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Maps/Sheboygan_Advanced.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Par
 ameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Watermarks/MapAdvancedText.WatermarkDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation>
 <Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Parcels.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml
 </ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Trees.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Par
 ameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Buildings.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layers_Advanced/Districts.LayerDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Ve
 rsion>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/Layouts/AdvancedStylization.WebLayout</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/TileSets/Sheboygan.TileSetDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOU
 RCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/TileSets/Sheboygan.TileSetDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/TileSets/Sheboygan.TileSetDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/TileSets/Sheboygan.TileSetDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Par
 ameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/TileSets/SheboyganXYZ.TileSetDefinition</Value></Parameter></Parameters></Operation><Operation><Name>DELETERESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>RESOURCEID</Name><Value>Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation><Operation><Name>SETRESOURCE</Name><Version>1.0.0</Version><Parameters><Parameter><Name>CONTENT</Name><Value>Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_CONTENT.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>HEADER</Name><Value>Library/Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition_HEADER.xml</Value><ContentType>text/xml</ContentType></Parameter><Parameter><Name>RESOURCEID</Name><Value>Li
 brary://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition</Value></Parameter></Parameters></Operation></Operations></ResourcePackageManifest>
\ No newline at end of file

Copied: trunk/MgDev/UnitTest/TestData/TileService/UT_BaseMap.tsd (from rev 8208, sandbox/jng/tiling/UnitTest/TestData/TileService/UT_BaseMap.tsd)
===================================================================
--- trunk/MgDev/UnitTest/TestData/TileService/UT_BaseMap.tsd	                        (rev 0)
+++ trunk/MgDev/UnitTest/TestData/TileService/UT_BaseMap.tsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TileSetDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TileSetDefinition-3.0.0.xsd">
+  <TileStoreParameters>
+    <TileProvider>Default</TileProvider>
+    <Parameter>
+      <Name>TilePath</Name>
+      <Value>%MG_TILE_CACHE_PATH%</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileWidth</Name>
+      <Value>256</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileHeight</Name>
+      <Value>256</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileFormat</Name>
+      <Value>PNG</Value>
+    </Parameter>
+    <Parameter>
+      <Name>FiniteScaleList</Name>
+      <Value>200000,100000,50000,25000,12500,6250,3125,1562.5,781.25,390.625</Value>
+    </Parameter>
+    <Parameter>
+      <Name>CoordinateSystem</Name>
+      <Value>GEOGCS["LL84",DATUM["WGS 84",SPHEROID["WGS 84",6378137,298.25722293287],TOWGS84[0,0,0,0,0,0,0]],PRIMEM["Greenwich",0],UNIT["Degrees",0.01745329252]]</Value>
+    </Parameter>
+  </TileStoreParameters>
+  <Extents>
+    <MinX>-87.79786601383196</MinX>
+    <MaxX>-87.66452777186925</MaxX>
+    <MinY>43.6868578621819</MinY>
+    <MaxY>43.8037962206133</MaxY>
+  </Extents>
+  <BaseMapLayerGroup>
+    <Name>BaseLayers</Name>
+    <Visible>true</Visible>
+    <ShowInLegend>true</ShowInLegend>
+    <ExpandInLegend>true</ExpandInLegend>
+    <LegendLabel>Base Layers</LegendLabel>
+    <BaseMapLayer>
+      <Name>Parcels</Name>
+      <ResourceId>Library://UnitTests/Layers/Parcels.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Parcels</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+    <BaseMapLayer>
+      <Name>VotingDistricts</Name>
+      <ResourceId>Library://UnitTests/Layers/VotingDistricts.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Voting Districts</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+  </BaseMapLayerGroup>
+</TileSetDefinition>

Copied: trunk/MgDev/UnitTest/TestData/TileService/UT_LinkedTileSet.mdf (from rev 8208, sandbox/jng/tiling/UnitTest/TestData/TileService/UT_LinkedTileSet.mdf)
===================================================================
--- trunk/MgDev/UnitTest/TestData/TileService/UT_LinkedTileSet.mdf	                        (rev 0)
+++ trunk/MgDev/UnitTest/TestData/TileService/UT_LinkedTileSet.mdf	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<MapDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="MapDefinition-3.0.0.xsd" version="3.0.0">
+  <Name>Base Map linked to Tile Set</Name>
+  <CoordinateSystem>PROJCS["WGS84.PseudoMercator",GEOGCS["LL84",DATUM["WGS84",SPHEROID["WGS84",6378137.000,298.25722293]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Popular Visualisation Pseudo Mercator"],PARAMETER["false_easting",0.000],PARAMETER["false_northing",0.000],PARAMETER["central_meridian",0.00000000000000],UNIT["Meter",1.00000000000000]]</CoordinateSystem>
+  <Extents>
+    <MinX>-9773613.7373958</MinX>
+    <MaxX>-9758770.5921973</MaxX>
+    <MinY>5417109.9090669</MinY>
+    <MaxY>5435129.2308673</MaxY>
+  </Extents>
+  <BackgroundColor>FFF7E1D2</BackgroundColor>
+  <MapLayer>
+    <Name>RoadCenterLines</Name>
+    <ResourceId>Library://UnitTests/Layers/RoadCenterLines.LayerDefinition</ResourceId>
+    <Selectable>false</Selectable>
+    <ShowInLegend>true</ShowInLegend>
+    <LegendLabel>Road CenterLines</LegendLabel>
+    <ExpandInLegend>false</ExpandInLegend>
+    <Visible>true</Visible>
+    <Group></Group>
+  </MapLayer>
+  <TileSetSource>
+    <ResourceId>Library://UnitTests/TileSets/Sheboygan.TileSetDefinition</ResourceId>
+  </TileSetSource>
+</MapDefinition>

Copied: trunk/MgDev/UnitTest/TestData/TileService/UT_XYZ.tsd (from rev 8208, sandbox/jng/tiling/UnitTest/TestData/TileService/UT_XYZ.tsd)
===================================================================
--- trunk/MgDev/UnitTest/TestData/TileService/UT_XYZ.tsd	                        (rev 0)
+++ trunk/MgDev/UnitTest/TestData/TileService/UT_XYZ.tsd	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TileSetDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TileSetDefinition-3.0.0.xsd">
+  <TileStoreParameters>
+    <TileProvider>XYZ</TileProvider>
+    <Parameter>
+      <Name>TilePath</Name>
+      <Value>%MG_TILE_CACHE_PATH%</Value>
+    </Parameter>
+    <Parameter>
+      <Name>TileFormat</Name>
+      <Value>PNG</Value>
+    </Parameter>
+  </TileStoreParameters>
+  <Extents>
+    <MinX>-87.79786601383196</MinX>
+    <MaxX>-87.66452777186925</MaxX>
+    <MinY>43.6868578621819</MinY>
+    <MaxY>43.8037962206133</MaxY>
+  </Extents>
+  <BaseMapLayerGroup>
+    <Name>BaseLayers</Name>
+    <Visible>true</Visible>
+    <ShowInLegend>true</ShowInLegend>
+    <ExpandInLegend>true</ExpandInLegend>
+    <LegendLabel>Base Layers</LegendLabel>
+    <BaseMapLayer>
+      <Name>Parcels</Name>
+      <ResourceId>Library://UnitTests/Layers/Parcels.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Parcels</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+    <BaseMapLayer>
+      <Name>VotingDistricts</Name>
+      <ResourceId>Library://UnitTests/Layers/VotingDistricts.LayerDefinition</ResourceId>
+      <Selectable>true</Selectable>
+      <ShowInLegend>true</ShowInLegend>
+      <LegendLabel>Voting Districts</LegendLabel>
+      <ExpandInLegend>false</ExpandInLegend>
+    </BaseMapLayer>
+  </BaseMapLayerGroup>
+</TileSetDefinition>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cleartilecacheform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cleartilecacheform.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cleartilecacheform.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -13,7 +13,7 @@
             <p>
                 Client Agent: <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
             <p>
-                Map definition: <input type="text" name="MAPDEFINITION" value="Library://" size="100" ID="Text3">
+                Map/TileSet definition: <input type="text" name="MAPDEFINITION" value="Library://" size="100" ID="Text3">
             <p>
                 Session id (optional): <input type="text" name="SESSION" size="100" ID="Text4">
             <p>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizexform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizexform.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizexform.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -9,10 +9,12 @@
             <div nowrap="true">
             <b>Operation:</b> <input type="text" name="OPERATION" value="GETDEFAULTTILESIZEX" size="50" ID="Text1">
             <p>
-                Version: <input type="text" name="VERSION" value="1.0.0" size="10" ID="Text2">
+                Version: <input type="text" name="VERSION" value="3.0.0" size="10" ID="Text2">
             <p>
                 Client Agent: <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
             <p>
+                Tile Set Definition: <input type="text" name="TILESET" value="" size="100">
+            <p>
                 <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
             </div>
         </form>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizeyform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizeyform.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/getdefaulttilesizeyform.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -9,10 +9,12 @@
             <div nowrap="true">
             <b>Operation:</b> <input type="text" name="OPERATION" value="GETDEFAULTTILESIZEY" size="50" ID="Text1">
             <p>
-                Version: <input type="text" name="VERSION" value="1.0.0" size="10" ID="Text2">
+                Version: <input type="text" name="VERSION" value="3.0.0" size="10" ID="Text2">
             <p>
                 Client Agent: <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
             <p>
+                Tile Set Definition: <input type="text" name="TILESET" value="" size="100">
+            <p>
                 <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
             </div>
         </form>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileimageform2.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -13,7 +13,7 @@
             <p>
                 Client Agent: <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
             <p>
-                Map name: <input type="text" name="MAPDEFINITION" value="Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition" size="100" ID="Text4">
+                Map/TileSet Definition: <input type="text" name="MAPDEFINITION" value="Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition" size="100" ID="Text4">
             <p>
                 BaseMapLayerGroup name: <input type="text" name="BASEMAPLAYERGROUPNAME" value="Base Layer Group" size="100" ID="Text5">
             <p>

Copied: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileprovidersform.html (from rev 8208, sandbox/jng/tiling/UnitTest/WebTier/MapAgent/MapAgentForms/gettileprovidersform.html)
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileprovidersform.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/gettileprovidersform.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,20 @@
+<html>
+    <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <script type="text/javascript" src="setactiontarget.js" >
+    </script>
+    </head>
+    <body>
+        <form name="input" action="" method="get" ID="Form1">
+            <div nowrap="true">
+            <b>Operation:</b> <input type="text" name="OPERATION" value="GETTILEPROVIDERS" size="50" ID="Text1">
+            <p>
+                Version: <input type="text" name="VERSION" value="3.0.0" size="10" ID="Text2">
+            <p>
+                Client Agent: <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
+            <p>
+                <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+            </div>
+        </form>
+    </body>
+</html>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/tileserviceapi.html	2014-08-12 11:11:22 UTC (rev 8330)
@@ -13,6 +13,8 @@
             <LI>
                 <A href="gettileimageform2.html" target="showform">GetTileImage R2</a></LI>
             <LI>
+                <A href="gettileprovidersform.html" target="showform">GetTileProviders</a></LI>
+            <LI>
                 <A href="cleartilecacheform.html" target="showform">ClearTileCache</a></LI>
             <LI>
                 <A href="getdefaulttilesizexform.html" target="showform">GetDefaultTileSizeX</a></LI>

Modified: trunk/MgDev/Web/src/HttpHandler/HttpClearTileCache.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpClearTileCache.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpClearTileCache.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -67,20 +67,30 @@
     }
 
     // Need a resource identifier
-    Ptr<MgResourceIdentifier> mapDefinition = new MgResourceIdentifier(m_mapDefinition);
+    Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(m_mapDefinition);
 
-    // Get Resource Service instance
-    Ptr<MgResourceService> resourceService = (MgResourceService*)CreateService(MgServiceType::ResourceService);
+    if (resource->IsResourceTypeOf(MgResourceType::MapDefinition))
+    {
+        // Get Resource Service instance
+        Ptr<MgResourceService> resourceService = (MgResourceService*)CreateService(MgServiceType::ResourceService);
 
-    // Create MgMap
-    Ptr<MgMap> map = new MgMap();
-    map->Create(resourceService, mapDefinition, mapDefinition->GetName());
+        // Create MgMap
+        Ptr<MgMap> map = new MgMap();
+        map->Create(resourceService, resource, resource->GetName());
 
-    // Get Proxy Tile Service instance
-    Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
+        // Get Proxy Tile Service instance
+        Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
 
-    // Call the C++ API
-    service->ClearCache(map);
+        // Call the C++ API
+        service->ClearCache(map);
+    }
+    else if (resource->IsResourceTypeOf(MgResourceType::TileSetDefinition))
+    {
+        // Get Proxy Tile Service instance
+        Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
 
+        // Call the C++ API
+        service->ClearCache(resource);
+    }
     MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpClearTileCache.Execute")
 }

Modified: trunk/MgDev/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpCreateRuntimeMap.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -118,7 +118,7 @@
     }
 
     Ptr<MgMappingService> mappingService = (MgMappingService*)CreateService(MgServiceType::MappingService);
-    byteReader = mappingService->CreateRuntimeMap(mdfId, mapName, sessionId, m_iconFormat, m_iconWidth, m_iconHeight, m_requestDataMask, m_iconLimitPerScaleRange);
+    byteReader = mappingService->CreateRuntimeMap(mdfId, mapName, sessionId, m_iconFormat, m_iconWidth, m_iconHeight, m_requestDataMask, m_iconLimitPerScaleRange, m_userInfo->GetApiVersion());
     // Convert to requested response format, if necessary
     ProcessFormatConversion(byteReader);
 
@@ -138,11 +138,12 @@
 
     // There are multiple supported versions
     INT32 version = m_userInfo->GetApiVersion();
-    if (version != MG_API_VERSION(2,6,0))
+    if (version != MG_API_VERSION(2,6,0) &&
+        version != MG_API_VERSION(3,0,0))
     {
         throw new MgInvalidOperationVersionException(
         L"MgHttpCreateRuntimeMap.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCreateRuntimeMap.ValidateOperationVersion");
-}
+}
\ No newline at end of file

Modified: trunk/MgDev/Web/src/HttpHandler/HttpDescribeRuntimeMap.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpDescribeRuntimeMap.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpDescribeRuntimeMap.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -98,7 +98,7 @@
     map->Open(m_mapName);
 
     Ptr<MgMappingService> mappingService = (MgMappingService*)CreateService(MgServiceType::MappingService);
-    byteReader = mappingService->DescribeRuntimeMap(map, m_iconFormat, m_iconWidth, m_iconHeight, m_requestDataMask, m_iconLimitPerScaleRange);
+    byteReader = mappingService->DescribeRuntimeMap(map, m_iconFormat, m_iconWidth, m_iconHeight, m_requestDataMask, m_iconLimitPerScaleRange, m_userInfo->GetApiVersion());
     // Convert to requested response format, if necessary
     ProcessFormatConversion(byteReader);
 
@@ -118,11 +118,12 @@
 
     // There are multiple supported versions
     INT32 version = m_userInfo->GetApiVersion();
-    if (version != MG_API_VERSION(2,6,0))
+    if (version != MG_API_VERSION(2,6,0) &&
+        version != MG_API_VERSION(3,0,0))
     {
         throw new MgInvalidOperationVersionException(
         L"MgHttpDescribeRuntimeMap.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
     MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpDescribeRuntimeMap.ValidateOperationVersion");
-}
+}
\ No newline at end of file

Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -35,6 +35,11 @@
     InitializeCommonParameters(hRequest);
 
     Ptr<MgHttpRequestParam> params = hRequest->GetRequestParam();
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version == MG_API_VERSION(3,0,0))
+    {
+        m_tilesetId = params->GetParameterValue(MgHttpResourceStrings::reqTileSet);
+    }
 }
 
 /// <summary>
@@ -55,9 +60,19 @@
 
     // Get Proxy Tile Service instance
     Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
-    INT32 size = service->GetDefaultTileSizeX();
-
-    Ptr<MgHttpPrimitiveValue> value = new MgHttpPrimitiveValue(size);
+    Ptr<MgHttpPrimitiveValue> value;
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version == MG_API_VERSION(3, 0, 0) && !m_tilesetId.empty())
+    {
+        Ptr<MgResourceIdentifier> tileSetId = new MgResourceIdentifier(m_tilesetId);
+        INT32 size = service->GetDefaultTileSizeX(tileSetId);
+        value = new MgHttpPrimitiveValue(size);
+    }
+    else
+    {
+        INT32 size = service->GetDefaultTileSizeX();
+        value = new MgHttpPrimitiveValue(size);
+    }
     if(!value)
         throw new MgOutOfMemoryException(L"", __LINE__, __WFILE__, NULL, L"", NULL);
 
@@ -65,3 +80,24 @@
 
     MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpGetDefaultTileSizeX.Execute")
 }
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpGetDefaultTileSizeX::ValidateOperationVersion()
+{
+    MG_HTTP_HANDLER_TRY()
+
+    // There are multiple supported versions
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version != MG_API_VERSION(1,0,0) &&
+        version != MG_API_VERSION(3,0,0))
+    {
+        throw new MgInvalidOperationVersionException(
+        L"MgHttpGetDefaultTileSizeX.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpGetDefaultTileSizeX.ValidateOperationVersion");
+}
\ No newline at end of file

Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeX.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -51,7 +51,16 @@
     /// </returns>
     MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
 
+protected:
+    /// <summary>
+    /// This method is responsible for checking if
+    /// a valid version was given
+    /// </summary>
+    /// <returns>Returns nothing</returns>
+    virtual void ValidateOperationVersion();
+
 private:
+    STRING m_tilesetId;
 };
 
 #endif  // _FS_GET_DEFAULT_TILE_SIZE_X_H

Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -35,6 +35,11 @@
     InitializeCommonParameters(hRequest);
 
     Ptr<MgHttpRequestParam> params = hRequest->GetRequestParam();
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version == MG_API_VERSION(3,0,0))
+    {
+        m_tilesetId = params->GetParameterValue(MgHttpResourceStrings::reqTileSet);
+    }
 }
 
 /// <summary>
@@ -55,9 +60,19 @@
 
     // Get Proxy Tile Service instance
     Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
-    INT32 size = service->GetDefaultTileSizeY();
-
-    Ptr<MgHttpPrimitiveValue> value = new MgHttpPrimitiveValue(size);
+    Ptr<MgHttpPrimitiveValue> value;
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version == MG_API_VERSION(3, 0, 0) && !m_tilesetId.empty())
+    {
+        Ptr<MgResourceIdentifier> tileSetId = new MgResourceIdentifier(m_tilesetId);
+        INT32 size = service->GetDefaultTileSizeY(tileSetId);
+        value = new MgHttpPrimitiveValue(size);
+    }
+    else
+    {
+        INT32 size = service->GetDefaultTileSizeY();
+        value = new MgHttpPrimitiveValue(size);
+    }
     if(!value)
         throw new MgOutOfMemoryException(L"", __LINE__, __WFILE__, NULL, L"", NULL);
 
@@ -65,3 +80,24 @@
 
     MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpGetDefaultTileSizeY.Execute")
 }
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpGetDefaultTileSizeY::ValidateOperationVersion()
+{
+    MG_HTTP_HANDLER_TRY()
+
+    // There are multiple supported versions
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version != MG_API_VERSION(1,0,0) &&
+        version != MG_API_VERSION(3,0,0))
+    {
+        throw new MgInvalidOperationVersionException(
+        L"MgHttpGetDefaultTileSizeY.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpGetDefaultTileSizeY.ValidateOperationVersion");
+}

Modified: trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetDefaultTileSizeY.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -51,7 +51,16 @@
     /// </returns>
     MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
 
+protected:
+    /// <summary>
+    /// This method is responsible for checking if
+    /// a valid version was given
+    /// </summary>
+    /// <returns>Returns nothing</returns>
+    virtual void ValidateOperationVersion();
+
 private:
+    STRING m_tilesetId;
 };
 
 #endif  // _FS_GET_DEFAULT_TILE_SIZE_Y_H

Copied: trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.cpp (from rev 8208, sandbox/jng/tiling/Web/src/HttpHandler/HttpGetTileProviders.cpp)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.cpp	                        (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,87 @@
+//
+//  Copyright (C) 2004-2014 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 "HttpHandler.h"
+#include "HttpGetTileProviders.h"
+
+HTTP_IMPLEMENT_CREATE_OBJECT(MgHttpGetTileProviders)
+
+/// <summary>
+/// Initializes the common parameters and parameters specific to this request.
+/// </summary>
+/// <param name="name">Input
+/// MgHttpRequest
+/// This contains all the parameters of the request.
+/// </param>
+/// <returns>
+/// nothing
+/// </returns>
+MgHttpGetTileProviders::MgHttpGetTileProviders(MgHttpRequest *hRequest)
+{
+    InitializeCommonParameters(hRequest);
+}
+
+/// <summary>
+/// Executes the specific request.
+/// </summary>
+/// <returns>
+/// MgHttpResponse
+/// This contains the response (including MgHttpResult and StatusCode) from the server.
+/// </returns>
+void MgHttpGetTileProviders::Execute(MgHttpResponse& hResponse)
+{
+    Ptr<MgHttpResult> hResult = hResponse.GetResult();
+
+    MG_HTTP_HANDLER_TRY()
+
+    // Check common parameters
+    ValidateCommonParameters();
+
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version == MG_API_VERSION(3,0,0))
+    {
+        // Get Proxy Tile Service instance
+        Ptr<MgTileService> service = (MgTileService*)(CreateService(MgServiceType::TileService));
+
+        // Call the C++ API
+        Ptr<MgByteReader> providers = service->GetTileProviders();
+
+        // Set the result
+        hResult->SetResultObject(providers, providers->GetMimeType());
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpGetTileProviders.Execute")
+}
+
+/// <summary>
+/// This method is responsible for checking if
+/// a valid version was given
+/// </summary>
+/// <returns>Returns nothing</returns>
+void MgHttpGetTileProviders::ValidateOperationVersion()
+{
+    MG_HTTP_HANDLER_TRY()
+
+    // There are multiple supported versions
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version != MG_API_VERSION(3,0,0))
+    {
+        throw new MgInvalidOperationVersionException(
+        L"MgHttpGetTileProviders.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpGetTileProviders.ValidateOperationVersion");
+}

Copied: trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.h (from rev 8208, sandbox/jng/tiling/Web/src/HttpHandler/HttpGetTileProviders.h)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.h	                        (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/HttpGetTileProviders.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -0,0 +1,64 @@
+//
+//  Copyright (C) 2004-2014 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 _FS_GET_TILE_PROVIDERS_H
+#define _FS_GET_TILE_PROVIDERS_H
+
+class MgHttpGetTileProviders : public MgHttpRequestResponseHandler
+{
+HTTP_DECLARE_CREATE_OBJECT()
+
+public:
+    /// <summary>
+    /// Initializes the common parameters of the request.
+    /// </summary>
+    /// <param name="name">Input
+    /// MgHttpRequest
+    /// This contains all the parameters of the request.
+    /// </param>
+    /// <returns>
+    /// nothing
+    /// </returns>
+    MgHttpGetTileProviders(MgHttpRequest *hRequest);
+
+    /// <summary>
+    /// Executes the specific request.
+    /// </summary>
+    /// <param name="hResponse">Input
+    /// This contains the response (including MgHttpResult and StatusCode) from the server.
+    /// </param>
+    void Execute(MgHttpResponse& hResponse);
+
+    /// <summary>
+    /// Returns the classification of this request/response handler
+    /// </summary>
+    /// <returns>
+    /// Classification of handler
+    /// </returns>
+    MgRequestClassification GetRequestClassification() { return MgHttpRequestResponseHandler::mrcViewer; }
+
+protected:
+    /// <summary>
+    /// This method is responsible for checking if
+    /// a valid version was given
+    /// </summary>
+    /// <returns>Returns nothing</returns>
+    virtual void ValidateOperationVersion();
+
+};
+
+#endif  // _FS_GET_TILE_PROVIDERS_H

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj	2014-08-12 11:11:22 UTC (rev 8330)
@@ -312,6 +312,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="HttpGetTileProviders.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="HttpInheritPermissionsFrom.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -956,6 +962,7 @@
     <ClInclude Include="HttpGetResourceContent.h" />
     <ClInclude Include="HttpGetResourceData.h" />
     <ClInclude Include="HttpGetResourceHeader.h" />
+    <ClInclude Include="HttpGetTileProviders.h" />
     <ClInclude Include="HttpInheritPermissionsFrom.h" />
     <ClInclude Include="HttpMoveResource.h" />
     <ClInclude Include="HttpRenameResourceData.h" />

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters	2014-08-12 11:11:22 UTC (rev 8330)
@@ -380,7 +380,12 @@
     <ClCompile Include="ReaderByteSourceImpl.cpp">
       <Filter>Byte Source Adapters</Filter>
     </ClCompile>
-    <ClCompile Include="HttpDescribeRuntimeMap.cpp" />
+    <ClCompile Include="HttpGetTileProviders.cpp">
+      <Filter>Tile Service</Filter>
+    </ClCompile>
+    <ClCompile Include="HttpDescribeRuntimeMap.cpp">
+      <Filter>Mapping Service</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="HttpApplyResourcePackage.h">
@@ -746,7 +751,12 @@
     <ClInclude Include="ReaderByteSourceImpl.h">
       <Filter>Byte Source Adapters</Filter>
     </ClInclude>
-    <ClInclude Include="HttpDescribeRuntimeMap.h" />
+    <ClInclude Include="HttpGetTileProviders.h">
+      <Filter>Tile Service</Filter>
+    </ClInclude>
+    <ClInclude Include="HttpDescribeRuntimeMap.h">
+      <Filter>Mapping Service</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="HttpHandler.rc" />

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -90,6 +90,7 @@
 #include "HttpGetSiteVersion.cpp"
 #include "HttpGetSpatialContexts.cpp"
 #include "HttpGetTileImage.cpp"
+#include "HttpGetTileProviders.cpp"
 #include "HttpGetVisibleMapExtent.cpp"
 #include "HttpHeader.cpp"
 #include "HttpInheritPermissionsFrom.cpp"

Modified: trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -89,6 +89,7 @@
 // Http Tile Service operations
 #include "HttpGetTileImage.h"
 #include "HttpClearTileCache.h"
+#include "HttpGetTileProviders.h"
 
 // Http Kml Service operations
 #include "HttpKmlGetMap.h"
@@ -397,6 +398,7 @@
     httpClassCreators[MgHttpResourceStrings::opQueryMapFeatures] = MgHttpQueryMapFeatures::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opGetTileImage] = MgHttpGetTileImage::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opClearTileCache] = MgHttpClearTileCache::CreateObject;
+    httpClassCreators[MgHttpResourceStrings::opGetTileProviders] = MgHttpGetTileProviders::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opWmsGetCapabilities] = MgHttpWmsGetCapabilities::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opWmsGetMap] = MgHttpWmsGetMap::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opWmsCapabilities] = MgHttpWmsGetCapabilities::CreateObject;

Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -259,12 +259,14 @@
 
 // Predefined Tile Service Request Parameters
 const STRING MgHttpResourceStrings::reqTileMapDefinition = L"MAPDEFINITION";
+const STRING MgHttpResourceStrings::reqTileSet = L"TILESET";
 
 // Tile Service Operation Requests
 const STRING MgHttpResourceStrings::opGetTileImage = L"GETTILEIMAGE";
 const STRING MgHttpResourceStrings::opClearTileCache = L"CLEARTILECACHE";
 const STRING MgHttpResourceStrings::opGetDefaultTileSizeX = L"GETDEFAULTTILESIZEX";
 const STRING MgHttpResourceStrings::opGetDefaultTileSizeY = L"GETDEFAULTTILESIZEY";
+const STRING MgHttpResourceStrings::opGetTileProviders = L"GETTILEPROVIDERS";
 
 // Predefined Kml Service Request Parameters
 const STRING MgHttpResourceStrings::reqKmlMapDefinition = L"MAPDEFINITION";

Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h	2014-08-12 11:11:22 UTC (rev 8330)
@@ -189,6 +189,7 @@
 
     // PREDEFINED TILE REQUEST PARAMETERS
     static const STRING reqTileMapDefinition;
+    static const STRING reqTileSet;
 
     // PREDEFINED KML REQUEST PARAMETERS
     static const STRING reqKmlMapDefinition;
@@ -317,6 +318,7 @@
     static const STRING opClearTileCache;
     static const STRING opGetDefaultTileSizeX;
     static const STRING opGetDefaultTileSizeY;
+    static const STRING opGetTileProviders;
 
     // Kml services
     static const STRING opGetMapKml;

Modified: trunk/MgDev/Web/src/HttpHandler/Makefile.am
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/Makefile.am	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/HttpHandler/Makefile.am	2014-08-12 11:11:22 UTC (rev 8330)
@@ -90,6 +90,7 @@
   HttpGetSiteVersion.cpp \
   HttpGetSpatialContexts.cpp \
   HttpGetTileImage.cpp \
+  HttpGetTileProviders.cpp \
   HttpGetVisibleMapExtent.cpp \
   HttpKmlGetMap.cpp \
   HttpKmlGetLayer.cpp \
@@ -214,6 +215,7 @@
   HttpGetSiteVersion.h \
   HttpGetSpatialContexts.h \
   HttpGetTileImage.h \
+  HttpGetTileProviders.h \
   HttpGetVisibleMapExtent.h \
   HttpHandler.h \
   HttpHandlerApiDllExport.h \

Modified: trunk/MgDev/Web/src/mapviewerjava/legend.jsp
===================================================================
--- trunk/MgDev/Web/src/mapviewerjava/legend.jsp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewerjava/legend.jsp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -78,7 +78,7 @@
 {
     output = new StringBuffer("\nvar layerData = new Array();\n");
     intermediateVar = 0;
-    
+
     // Initialize web tier with the site configuration file.
     InitializeWebTier();
 
@@ -299,7 +299,7 @@
                                                            rtLayerGroup.GetDisplayInLegend()? "true": "false",
                                                            rtLayerGroup.GetObjectId(),
                                                            StrEscape(rtLayerGroup.GetName()),
-                                                           rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMap? "true": "false"}));
+                                                           (rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMap || rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMapFromTileSet)? "true": "false"}));
                     }
                     else
                     {

Modified: trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp
===================================================================
--- trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewerjava/mapframe.jsp	2014-08-12 11:11:22 UTC (rev 8330)
@@ -61,16 +61,26 @@
     MgSiteConnection site = new MgSiteConnection();
     site.Open(userInfo);
 
-    MgTileService tileSrvc = (MgTileService)site.CreateService(MgServiceType.TileService);
-    int tileSizeX = tileSrvc.GetDefaultTileSizeX();
-    int tileSizeY = tileSrvc.GetDefaultTileSizeY();
-
     MgResourceService resourceSrvc = (MgResourceService)site.CreateService(MgServiceType.ResourceService);
 
     MgMap map = new MgMap(site);
     MgResourceIdentifier resId = new MgResourceIdentifier(mapDefinition);
     String mapName = resId.GetName();
     map.Create(resId, mapName);
+    
+    MgResourceIdentifier tileSetId = map.GetTileSetDefinition();
+    
+    MgTileService tileSrvc = (MgTileService)site.CreateService(MgServiceType.TileService);
+    int tileSizeX = tileSrvc.GetDefaultTileSizeX();
+    int tileSizeY = tileSrvc.GetDefaultTileSizeY();
+    if (null != tileSetId)
+    {
+        //Overwrite the map definition with tile set id (this is for GETTILE requests) and
+        //use size settings from that tile set
+        mapDefinition = tileSetId.ToString();
+        tileSizeX = tileSrvc.GetDefaultTileSizeX(tileSetId);
+        tileSizeY = tileSrvc.GetDefaultTileSizeY(tileSetId);
+    }
 
     //create an empty selection object and store it in the session repository
     MgSelection sel = new MgSelection(map);

Modified: trunk/MgDev/Web/src/mapviewernet/legend.aspx
===================================================================
--- trunk/MgDev/Web/src/mapviewernet/legend.aspx	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewernet/legend.aspx	2014-08-12 11:11:22 UTC (rev 8330)
@@ -302,7 +302,7 @@
                                                         rtLayerGroup.GetDisplayInLegend() ? "true" : "false",
                                                         rtLayerGroup.GetObjectId(),
                                                         StrEscape(rtLayerGroup.GetName()),
-                                                        rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMap? "true": "false"));
+                                                        (rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMap || rtLayerGroup.GetLayerGroupType() == MgLayerGroupType.BaseMapFromTileSet)? "true": "false"));
                     }
                     else
                     {

Modified: trunk/MgDev/Web/src/mapviewernet/mapframe.aspx
===================================================================
--- trunk/MgDev/Web/src/mapviewernet/mapframe.aspx	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewernet/mapframe.aspx	2014-08-12 11:11:22 UTC (rev 8330)
@@ -75,11 +75,27 @@
         String mapName = resId.GetName();
         map.Create(resId, mapName);
 
+        MgMap map = new MgMap(site);
+        MgResourceIdentifier resId = new MgResourceIdentifier(mapDefinition);
+        String mapName = resId.GetName();
+        map.Create(resId, mapName);
+        
+        MgTileService tileSrvc = (MgTileService)site.CreateService(MgServiceType.TileService);
+        int tileSizeX = tileSrvc.GetDefaultTileSizeX();
+        int tileSizeY = tileSrvc.GetDefaultTileSizeY();
+        if (null != tileSetId)
+        {
+            //Overwrite the map definition with tile set id (this is for GETTILE requests) and
+            //use size settings from that tile set
+            mapDefinition = tileSetId.ToString();
+            tileSizeX = tileSrvc.GetDefaultTileSizeX(tileSetId);
+            tileSizeY = tileSrvc.GetDefaultTileSizeY(tileSetId);
+        }
+        
         //create an empty selection object and store it in the session repository
         MgSelection sel = new MgSelection(map);
         sel.Save(resourceSrvc, mapName);
 
-
         //get the map extent and calculate the scale factor
         //
         MgEnvelope mapExtent = map.GetMapExtent();

Modified: trunk/MgDev/Web/src/mapviewerphp/legend.php
===================================================================
--- trunk/MgDev/Web/src/mapviewerphp/legend.php	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewerphp/legend.php	2014-08-12 11:11:22 UTC (rev 8330)
@@ -231,7 +231,7 @@
                                                         $node->rtObject->GetDisplayInLegend()? "true": "false",
                                                         $node->rtObject->GetObjectId(),
                                                         StrEscape($node->rtObject->GetName()),
-                                                        $node->rtObject->GetLayerGroupType() == MgLayerGroupType::BaseMap? "true": "false");
+                                                        ($node->rtObject->GetLayerGroupType() == MgLayerGroupType::BaseMap || $node->rtObject->GetLayerGroupType() == MgLayerGroupType::BaseMapFromTileSet)? "true": "false");
                     }
                     else
                     {

Modified: trunk/MgDev/Web/src/mapviewerphp/mapframe.php
===================================================================
--- trunk/MgDev/Web/src/mapviewerphp/mapframe.php	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/Web/src/mapviewerphp/mapframe.php	2014-08-12 11:11:22 UTC (rev 8330)
@@ -54,17 +54,26 @@
     $site = new MgSiteConnection();
     $site->Open($userInfo);
 
-    $tileSrvc = $site->CreateService(MgServiceType::TileService);
-
-    $tileSizeX = $tileSrvc->GetDefaultTileSizeX();
-    $tileSizeY = $tileSrvc->GetDefaultTileSizeY();
-
     $resourceSrvc = $site->CreateService(MgServiceType::ResourceService);
 
     $map = new MgMap($site);
     $resId = new MgResourceIdentifier($mapDefinition);
     $mapName = $resId->GetName();
     $map->Create($resId, $mapName);
+    
+    $tileSetId = $map->GetTileSetDefinition();
+    
+    $tileSrvc = $site->CreateService(MgServiceType::TileService);
+    $tileSizeX = $tileSrvc->GetDefaultTileSizeX();
+    $tileSizeY = $tileSrvc->GetDefaultTileSizeY();
+    if (NULL != $tileSetId)
+    {
+        //Overwrite the map definition with tile set id (this is for GETTILE requests) and
+        //use size settings from that tile set
+        $mapDefinition = $tileSetId->ToString();
+        $tileSizeX = $tileSrvc->GetDefaultTileSizeX($tileSetId);
+        $tileSizeY = $tileSrvc->GetDefaultTileSizeY($tileSetId);
+    }
 
     //create an empty selection object and store it in the session repository
     $sel = new MgSelection($map);

Modified: trunk/MgDev/run_tests.bat
===================================================================
--- trunk/MgDev/run_tests.bat	2014-08-11 02:43:51 UTC (rev 8329)
+++ trunk/MgDev/run_tests.bat	2014-08-12 11:11:22 UTC (rev 8330)
@@ -14,13 +14,15 @@
 REM SET WEBCONFIGINI=C:\Program Files\OSGeo\MapGuide\Web\www\webconfig.ini
 REM SET SERVER_PORT=80
 SET PHP_TEST_CWD=%CD%\Web\src\mapagent
-SET PHP_EXT_DIR=C:\Program Files\OSGeo\MapGuide\Web\Php\ext
+REM SET PHP_EXT_DIR=C:\Program Files\OSGeo\MapGuide\Web\Php\ext
+SET PHP_EXT_DIR=D:\mg-trunk\MgDev\Release\Web\Php\ext
 
 SET START_MGSERVER=1
 SET START_WEBSERVER=1
+SET PREPARE_PHP_WEBSERVER=1
 SET RUN_SERVER_TESTS=0
 SET RUN_PHP_TESTS=1
-SET RUN_DOTNET_TESTS=1
+SET RUN_DOTNET_TESTS=0
 
 SET RETURN_CODE=0
 
@@ -66,14 +68,16 @@
     popd
 )
 :prepare_webconfig
-pushd UnitTest
-SET TEST_COMPONENT=Prepare webtier test suites
-php -n -d display_errors=Off -d extension_dir="%PHP_EXT_DIR%" -d extension=php_mbstring.dll -d extension=php_curl.dll -d extension=php_MapGuideApi.dll -d extension=php_SQLitePhpApi.dll prepare.php
-if %ERRORLEVEL% neq 0 (
-    set RETURN_CODE=%ERRORLEVEL%
-    goto error
+if "%PREPARE_PHP_WEBSERVER%" == "1" (
+    pushd UnitTest
+    SET TEST_COMPONENT=Prepare webtier test suites
+    php -n -d display_errors=Off -d extension_dir="%PHP_EXT_DIR%" -d extension=php_mbstring.dll -d extension=php_curl.dll -d extension=php_MapGuideApi.dll -d extension=php_SQLitePhpApi.dll prepare.php
+    if %ERRORLEVEL% neq 0 (
+        set RETURN_CODE=%ERRORLEVEL%
+        goto error
+    )
+    popd
 )
-popd
 :start_php_webserver
 if "%START_WEBSERVER%" == "1" (
     echo [test]: Starting PHP web server. Waiting %MGSERVER_WAIT%s



More information about the mapguide-commits mailing list