class AssetPagingIterator extends AssetPropertyBase implements Iterator<AssetPropertyBase> {

    @Override
    public AssetPropertyBase next()
    {
        /*
         * Check more elements available
         */
        if (this.hasNext())
        {
            AssetPropertyBase retrievedElement;

            /*
             * If the pointer is at the end of the cache then retrieve more content from the property (metadata)
             * server.
             */
            if (cachedElementPointer == cachedElementList.size())
            {
                try
                {
                    cachedElementList = iterator.getCachedList(cachedElementStart, maxCacheSize);
                    cachedElementPointer = 0;
                }
                catch (PropertyServerException error)
                {
                    /*
                     * Problem retrieving next cache.  The exception includes a detailed error message,
                     */
                    throw new OCFRuntimeException(OCFErrorCode.PROPERTIES_NOT_AVAILABLE.getMessageDefinition(error.getReportedErrorMessage(),
                                                                                                             this.toString()),
                                                  this.getClass().getName(),
                                                  "next",
                                                  error);
                }
            }

            retrievedElement = iterator.cloneElement(getParentAsset(), cachedElementList.get(cachedElementPointer));
            cachedElementPointer++;
            cachedElementStart++;

            log.debug("Returning next element:");
            log.debug("==> totalElementCount: " + totalElementCount);
            log.debug("==> cachedElementPointer: " + cachedElementPointer);
            log.debug("==> cachedElementStart:" + cachedElementStart);
            log.debug("==> maxCacheSize:" + maxCacheSize);

            return retrievedElement;
        }
        else
        {
            /*
             * Throw runtime exception to show the caller they are not using the list correctly.
             */
            throw new OCFRuntimeException(OCFErrorCode.NO_MORE_ELEMENTS.getMessageDefinition(this.getClass().getSimpleName(),
                                                                                             super.getParentAssetName(),
                                                                                             super.getParentAssetTypeName()),
                                          this.getClass().getName(),
                                          "next");
        }
    }

    public  AssetPagingIterator(AssetDescriptor           parentAsset,
                               AssetPropertyIteratorBase iterator,
                               int                       totalElementCount,
                               int                       maxCacheSize);
    public  AssetPagingIterator(AssetDescriptor           parentAsset,
                               AssetPropertyIteratorBase iterator,
                               AssetPagingIterator       templateIterator);

}