@Test
  public void testConcurrentCreateAndDestroy() throws Exception {
    String name = nameRule.getMethodName();
    RegionFactory f = cache.createRegionFactory(RegionShortcut.REPLICATE);
    final DistributedRegion region = (DistributedRegion) f.create(name);

    // simulate a put() getting into AbstractRegionMap.basicPut() and creating an entry
    // that has not yet been initialized with values. Then do a destroy that will encounter
    // the entry
    String key = "destroyedKey1";
    VersionedThinRegionEntryHeap entry =
        new VersionedThinRegionEntryHeapObjectKey(region, key, Token.REMOVED_PHASE1);
    ((AbstractRegionMap) region.getRegionMap()).putEntryIfAbsentForTest(entry);
    cache.getLogger().info("entry inserted into cache: " + entry);

    EntryEventImpl ev = EntryEventImpl.create(region, Operation.DESTROY, key, null, null, true,
        new InternalDistributedMember(InetAddress.getLocalHost(), 1234));
    VersionTag tag = VersionTag.create((InternalDistributedMember) ev.getDistributedMember());
    tag.setIsRemoteForTesting();
    tag.setEntryVersion(2);
    tag.setRegionVersion(12345);
    tag.setVersionTimeStamp(System.currentTimeMillis());
    tag.setDistributedSystemId(1);
    ev.setVersionTag(tag);
    cache.getLogger()
        .info("destroyThread is trying to destroy the entry: " + region.getRegionEntry(key));
    region.basicDestroy(ev, false, null); // expectedOldValue not supported on
    entry = (VersionedThinRegionEntryHeap) region.getRegionEntry(key);
    region.dumpBackingMap();
    Assert.assertTrue(entry != null, "expected to find a region entry for " + key);
    Assert.assertTrue(entry.isTombstone(),
        "expected entry to be found and be a tombstone but it is " + entry);
    Assert.assertTrue(entry.getVersionStamp().getEntryVersion() == tag.getEntryVersion(),
        "expected " + tag.getEntryVersion() + " but found "
            + entry.getVersionStamp().getEntryVersion());


    RegionMap map = region.getRegionMap();
    tag = entry.asVersionTag();
    map.removeTombstone(entry, tag);

    // now do an op that has local origin
    entry = new VersionedThinRegionEntryHeapObjectKey(region, key, Token.REMOVED_PHASE1);
    ((AbstractRegionMap) region.getRegionMap()).putEntryIfAbsentForTest(entry);
    cache.getLogger().info("entry inserted into cache: " + entry);

    ev = EntryEventImpl.create(region, Operation.DESTROY, key, null, null, false, cache.getMyId());
    tag = VersionTag.create((InternalDistributedMember) ev.getDistributedMember());
    tag.setEntryVersion(2);
    tag.setRegionVersion(12345);
    tag.setVersionTimeStamp(System.currentTimeMillis());
    tag.setDistributedSystemId(1);
    ev.setVersionTag(tag);
    cache.getLogger()
        .info("destroyThread is trying to destroy the entry: " + region.getRegionEntry(key));
    boolean caught = false;
    try {
      region.basicDestroy(ev, false, null); // expectedOldValue not supported on
    } catch (EntryNotFoundException e) {
      caught = true;
    }
    Assert.assertTrue(caught,
        "expected an EntryNotFoundException for origin=local destroy operation");
  }
In bug #47868 a thread puts a REMOVED_PHASE1 entry in the map but is unable to lock the entry
before a Destroy thread gets it. The Destroy thread did not apply its operation but threw an
EntryNotFoundException. It is supposed to create a Tombstone.
geode-core/src/integrationTest/java/org/apache/geode/internal/cache/TombstoneCreationJUnitTest.java