void basicDestroyRegion(RegionEventImpl event, boolean cacheWrite, boolean lock,
      boolean callbackEvents) throws CacheWriterException, TimeoutException {
    preDestroyChecks();

    final TXStateProxy tx = cache.getTXMgr().pauseTransaction();
    try {
      boolean acquiredLock = false;
      if (lock) {
        try {
          acquireDestroyLock();
          acquiredLock = true;
        } catch (CancelException ignore) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "basicDestroyRegion: acquireDestroyLock failed due to cache closure, region = {}",
                getFullPath());
          }
        }
      }

      try {
        // maintain destroy lock and TXStateInterface
        // I moved checkRegionDestroyed up out of the following
        // try block because it does not seem correct to deliver
        // a destroy event to the clients of the region was already
        // destroyed on the server.
        checkRegionDestroyed(false);
        boolean cancelledByCacheWriterException = false;
        HashSet eventSet = null;

        try { // ensure that destroy events are dispatched
          if (this instanceof PartitionedRegion
              && !((PartitionedRegion) this).getParallelGatewaySenderIds().isEmpty()) {
            ((PartitionedRegion) this).destroyParallelGatewaySenderRegion(event.getOperation(),
                cacheWrite, lock, callbackEvents);
          }

          if (parentRegion != null) {
            // "Bubble up" the cache statistics to parent if this regions are more recent
            parentRegion.updateStats();
          }

          try {
            eventSet = callbackEvents ? new HashSet() : null;
            destroyedSubregionSerialNumbers = collectSubregionSerialNumbers();
            recursiveDestroyRegion(eventSet, event, cacheWrite);
          } catch (CancelException e) {
            // This should be properly caught and ignored; if we see this there is
            // a serious problem.
            if (!cache.forcedDisconnect()) {
              logger.warn(String.format(
                  "recursiveDestroyRegion: recursion failed due to cache closure. region, %s",
                  getFullPath()),
                  e);
            }
          } catch (CacheWriterException cwe) {
            cancelledByCacheWriterException = true;
            throw cwe;
          }

          // at this point all subregions are destroyed and this region has been marked as destroyed
          // and postDestroyRegion has been called for each region. The only detail left is
          // unhooking this region from the parent subregion map, and sending listener events
          Assert.assertTrue(isDestroyed);

          // Added for M&M : At this point we can safely call ResourceEvent to remove the region
          // artifacts From Management Layer
          if (!isInternalRegion()) {
            InternalDistributedSystem system = cache.getInternalDistributedSystem();
            system.handleResourceEvent(ResourceEvent.REGION_REMOVE, this);
          }

          try {
            LocalRegion parent = parentRegion;
            if (parent == null) {
              cache.removeRoot(this);
            } else {
              parent.subregions.remove(regionName, this);
            }
          } catch (CancelException e) {
            if (!cache.forcedDisconnect()) {
              logger.warn(String.format(
                  "basicDestroyRegion: parent removal failed due to cache closure. region, %s",
                  getFullPath()),
                  e);
            }
          }

        } finally {
          // ensure that destroy events are dispatched
          if (!cancelledByCacheWriterException) {
            // We only need to notify bridgeClients of the top level region destroy
            // which it will take and do a localRegionDestroy.
            // So we pass it event and NOT eventSet
            event.setEventType(EnumListenerEvent.AFTER_REGION_DESTROY);
            notifyBridgeClients(event);
          }

          // call sendPendingRegionDestroyEvents even if cancelledByCacheWriterException
          // since some of the destroys happened.
          if (eventSet != null && callbackEvents) {
            try {
              sendPendingRegionDestroyEvents(eventSet);
            } catch (CancelException ignore) {
              // ignore, we're mute.
            }
          }
        }

      } finally {
        if (acquiredLock) {
          try {
            releaseDestroyLock();
          } catch (CancelException ignore) {
            // ignore
          }
        }
      }

    } finally {
      cache.getTXMgr().unpauseTransaction(tx);
    }
  }
@param cacheWrite if true, then we're just cleaning up the local cache and calling listeners,
@see DistributedRegion#basicDestroyRegion(RegionEventImpl, boolean, boolean, boolean)
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java