private static string GetCacheKeyFromVirtualPath(VirtualPath virtualPath, out bool keyFromVPP) {

            // Check if the VirtualPathProvider needs to use a non-default cache key
            string key = virtualPath.GetCacheKey();

            // If so, just return it
            if (key != null) {
                keyFromVPP = true;
                return key.ToLowerInvariant();
            }

            // The VPP didn't return a key, so use our standard key algorithm
            keyFromVPP = false;

            // Check if the key for this virtual path is already cached
            key = _keyCache[virtualPath.VirtualPathString] as string;
            if (key != null) return key;

            // Compute the key
            key = GetCacheKeyFromVirtualPathInternal(virtualPath);

            // The key should always be lower case
            Debug.Assert(key == key.ToLowerInvariant());

            // Cache it for next time
            _keyCache[virtualPath.VirtualPathString] = key;

            return key;
        }