/**
         * Constructs a SessionCachePostProcessor with a specified cache and cache key, and an optional property listener
         * and property name.
         *
         * @param cache              cache that receives the retrieved data.
         * @param cacheKey           cache key to place the retrieved data under.
         * @param absentResourceList the absent resource list to update.
         * @param resourceID         the resource ID to use in the absent resource list.
         * @param propertyListener   property listener to notify when the data is available. Can be null.
         * @param propertyName       property name to use for the property event when the data is available. Can be null.
         */
        public SessionCacheRetrievalPostProcessor(SessionCache cache, Object cacheKey,
                                                  AbsentResourceList absentResourceList, long resourceID,
                                                  PropertyChangeListener propertyListener, String propertyName)
        {
            if (cache == null)
            {
                String message = Logging.getMessage("nullValue.CacheIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (cacheKey == null)
            {
                String message = Logging.getMessage("nullValue.CacheKeyIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            this.cache              = cache;
            this.cacheKey           = cacheKey;
            this.absentResourceList = absentResourceList;
            this.resourceID         = resourceID;
            this.propertyListener   = propertyListener;
            this.propertyName       = propertyName;
        }
        /**
         * Retrieves the contents of a specified {@link java.net.URL}. If successful, this places the URL
         * contents in a specified session cache with a specified key. This either marks the resource as available or
         * missing, depending on whether the retrieval succeeds or fails. Finally, this optionally notifies the caller that
         * the retrieval has succeeded by firing a property change event. If either the property listener or property name
         * are null, that functionality is disabled.
         *
         * @param url                the URL contents to retrieve.
         * @param cache              the cache which receives the retrieved data.
         * @param cacheKey           the cache key which identifies where the retrieved data is placed in the session
         *                           cache.
         * @param absentResourceList the absent resource list to update.
         * @param resourceID         the resource ID to use in the absent resource list.
         * @param propertyListener   the property change listener which is fired when the retrieved data is available.
         * @param propertyName       the property name to fire when retrieved data is available.
         *
         * @throws ArgumentException if any of the url, retrieval service, cache, or cache key are null.
         */
        public static void retrieveSessionData(java.net.URL url, SessionCache cache, Object cacheKey,
                                               AbsentResourceList absentResourceList, long resourceID, PropertyChangeListener propertyListener,
                                               String propertyName)
        {
            if (url == null)
            {
                String message = Logging.getMessage("nullValue.URLIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (cache == null)
            {
                String message = Logging.getMessage("nullValue.CacheIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (cacheKey == null)
            {
                String message = Logging.getMessage("nullValue.CacheKeyIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (WorldWind.getNetworkStatus().isHostUnavailable(url))
            {
                if (absentResourceList != null)
                {
                    absentResourceList.markResourceAbsent(resourceID);
                }
                return;
            }

            SessionCacheRetrievalPostProcessor postProcessor = new SessionCacheRetrievalPostProcessor(cache, cacheKey,
                                                                                                      absentResourceList, resourceID, propertyListener, propertyName);

            postProcessor.setName(url.ToString());

            Retriever retriever = URLRetriever.createRetriever(url, postProcessor);

            try
            {
                retriever.call();
            }
            catch (Exception e)
            {
                String message = Logging.getMessage("layers.TiledImageLayer.ExceptionRetrievingResources", url.ToString());
                Logging.logger().log(java.util.logging.Level.SEVERE, message, e);
            }
        }
        /**
         * Checks a session cache for a specified key, and if present attempts to interpret the cache entry as a {@link
         * WMSCapabilities} document. If the key does not map to a Capabilities document for any reason, this attempts to
         * asynchronously retrieve the Capabilities from a specified URL, and returns null.
         *
         * @param url                the URL contents to retrieve.
         * @param cache              the session cache.
         * @param cacheKey           the key to identify the object in the session cache.
         * @param absentResourceList the absent resource list to update.
         * @param resourceID         the resource ID to use in the absent resource list.
         * @param propertyListener   the property change listener which is fired when the retrieved data is available.
         * @param propertyName       the property name to fire when retrieved data is available.
         *
         * @return the Capabilities document in the session cache, or null if the document is not in the cache.
         *
         * @throws ArgumentException if either the url, retrieval service, cache or cache key are null.
         */
        public static WMSCapabilities getOrRetrieveSessionCapabilities(java.net.URL url, SessionCache cache,
                                                                       Object cacheKey, AbsentResourceList absentResourceList, long resourceID,
                                                                       PropertyChangeListener propertyListener, String propertyName)
        {
            if (url == null)
            {
                String message = Logging.getMessage("nullValue.URLIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (cache == null)
            {
                String message = Logging.getMessage("nullValue.CacheIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (cacheKey == null)
            {
                String message = Logging.getMessage("nullValue.CacheKeyIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            WMSCapabilities caps = getSessionCapabilities(cache, cacheKey, url.ToString());

            if (caps != null)
            {
                return(caps);
            }

            retrieveSessionData(url, cache, cacheKey, absentResourceList, resourceID, propertyListener, propertyName);

            // Try to get the caps after the retrieval attempt.
            return(getSessionCapabilities(cache, cacheKey, url.ToString()));
        }