private EntryExpiryTask createExpiryTask(RegionEntry regionEntry) {
    if (regionEntry == null || regionEntry.isDestroyedOrRemoved()) {
      return null;
    }
    if (customEntryIdleTimeout != null || customEntryTimeToLive != null) {
      ExpiryRegionEntry expiryRegionEntry = new ExpiryRegionEntry(this, regionEntry);
      ExpirationAttributes ttlAttributes = null;
      final RegionAttributes<?, ?> regionAttributes = getAttributes();

      final CustomExpiry<?, ?> customTTL = regionAttributes.getCustomEntryTimeToLive();
      if (customTTL != null) {
        try {
          ttlAttributes = customTTL.getExpiry(expiryRegionEntry);
          if (ttlAttributes != null) {
            checkEntryTimeoutAction("timeToLive", ttlAttributes.getAction());
          }
        } catch (RegionDestroyedException ignore) {
          // Ignore
        } catch (EntryNotFoundException | EntryDestroyedException ignore) {
          // Ignore
        } catch (Exception e) {
          logger.fatal(String.format("Error calculating expiration %s", e.getMessage()),
              e);
        }
      }
      if (ttlAttributes == null) {
        ttlAttributes = regionAttributes.getEntryTimeToLive();
      }

      CustomExpiry<?, ?> customIdle = regionAttributes.getCustomEntryIdleTimeout();
      ExpirationAttributes idleAttributes = null;
      if (customIdle != null) {
        try {
          idleAttributes = customIdle.getExpiry(expiryRegionEntry);
          if (idleAttributes != null) {
            checkEntryTimeoutAction("idleTimeout", idleAttributes.getAction());
          }
        } catch (RegionDestroyedException ignore) {
          // Ignore
        } catch (EntryNotFoundException | EntryDestroyedException ignore) {
          // Ignore
        } catch (Exception e) {
          logger.fatal(String.format("Error calculating expiration %s", e.getMessage()),
              e);
        }
      }
      if (idleAttributes == null) {
        idleAttributes = regionAttributes.getEntryIdleTimeout();
      }

      final boolean ttlDisabled = ttlAttributes == null || ttlAttributes.getTimeout() == 0;
      final boolean idleDisabled = idleAttributes == null || idleAttributes.getTimeout() == 0;

      if (ttlDisabled && idleDisabled) {
        return null;
      }
      if ((ttlDisabled || ttlAttributes.equals(regionAttributes.getEntryTimeToLive()))
          && (idleDisabled || idleAttributes.equals(regionAttributes.getEntryIdleTimeout()))) {
        // no need for custom since we can just use the region's expiration attributes.
        return new EntryExpiryTask(this, regionEntry);
      }
      return new CustomEntryExpiryTask(this, regionEntry, ttlAttributes, idleAttributes);

    }
    if (isEntryExpiryPossible()) {
      return new EntryExpiryTask(this, regionEntry);
    }
    return null;
  }
If custom expiration returns non-null expiration attributes then create a CustomEntryExpiryTask
for this region and the given entry and return it. Otherwise if the region is configured for
expiration then create an EntryExpiryTask for this region and the given entry and return it.
Null is returned if the expiration attributes indicate that expiration is disabled.
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java