private void endCacheLoader() {
    Declarable d = createDeclarable();
    if (!(d instanceof CacheLoader)) {
      throw new CacheXmlException(
          String.format("A %s is not an instance of a CacheLoader.",
              d.getClass().getName()));
    }
    // Two peeks required to handle dynamic region context
    Object a = stack.peek();
    // check for disk-dir
    if ((a instanceof File)) {
      Object sav = stack.pop();
      a = stack.peek();
      if (!(a instanceof RegionAttributesCreation)) {
        throw new CacheXmlException(
            "A cache-loader must be defined in the context of region-attributes.");
      }
      stack.push(sav);
      RegionAttributesCreation attrs = (RegionAttributesCreation) a;
      attrs.setCacheLoader((CacheLoader) d);
    }
    // check for normal region-attributes
    else if (a instanceof RegionAttributesCreation) {
      RegionAttributesCreation attrs = (RegionAttributesCreation) a;
      attrs.setCacheLoader((CacheLoader) d);
    } else {
      throw new CacheXmlException(
          String.format("A %s must be defined in the context of region-attributes or %s",
              CACHE_LOADER, DYNAMIC_REGION_FACTORY));
    }
  }
When a <code>cache-loader</code> element is finished, the {@link Parameter}s and class names
are popped off the stack. The cache loader is instantiated and initialized with the parameters,
if appropriate. When the loader is being created in a dynamic-region-factory, there may be a
disk-dir element on the stack, represented by a File object. Otherwise, dynamic-region-factory
uses a RegionAttributesCreation, just like a region, and is treated the same.<p) The loader may
also be created in the context of partition-attributes.
geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParser.java