public Object call() throws Exception {
   createRegion(rName, false, 1, new InvalidatePRWriter());
   Region r = getCache().getRegion(rName);
   InvalidatePRListener l = new InvalidatePRListener();
   l.originRemote = originRemote;
   r.getAttributesMutator().addCacheListener(l);
   return null;
 }
  /** check remote ops done in a normal vm are correctly distributed to PROXY regions */
  private void remoteOriginOps(DataPolicy dp, InterestPolicy ip) throws CacheException {
    initOtherId();
    AttributesFactory af = new AttributesFactory();
    af.setDataPolicy(dp);
    af.setSubscriptionAttributes(new SubscriptionAttributes(ip));
    af.setScope(Scope.DISTRIBUTED_ACK);
    CacheListener cl1 =
        new CacheListener() {
          public void afterUpdate(EntryEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterCreate(EntryEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterInvalidate(EntryEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterDestroy(EntryEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterRegionInvalidate(RegionEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterRegionDestroy(RegionEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterRegionClear(RegionEvent e) {
            clLastEvent = e;
            clInvokeCount++;
          }

          public void afterRegionCreate(RegionEvent e) {}

          public void afterRegionLive(RegionEvent e) {}

          public void close() {}
        };
    af.addCacheListener(cl1);
    Region r = createRootRegion("ProxyDUnitTest", af.create());
    this.clInvokeCount = 0;

    doCreateOtherVm();

    DMStats stats = getDMStats();
    long receivedMsgs = stats.getReceivedMessages();

    if (ip.isAll()) {
      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do put") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.put("p", "v");
                }
              });
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.CREATE, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable()); // failure
      assertEquals("v", ((EntryEvent) this.clLastEvent).getNewValue());
      assertEquals("p", ((EntryEvent) this.clLastEvent).getKey());
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do create") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.create("c", "v");
                }
              });
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.CREATE, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable());
      assertEquals("v", ((EntryEvent) this.clLastEvent).getNewValue());
      assertEquals("c", ((EntryEvent) this.clLastEvent).getKey());
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do update") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.put("c", "v2");
                }
              });
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.UPDATE, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable());
      assertEquals("v2", ((EntryEvent) this.clLastEvent).getNewValue());
      assertEquals("c", ((EntryEvent) this.clLastEvent).getKey());
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do invalidate") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.invalidate("c");
                }
              });
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.INVALIDATE, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getNewValue());
      assertEquals("c", ((EntryEvent) this.clLastEvent).getKey());
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do destroy") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.destroy("c");
                }
              });
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.DESTROY, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getNewValue());
      assertEquals("c", ((EntryEvent) this.clLastEvent).getKey());
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do putAll") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  Map m = new HashMap();
                  m.put("putAllKey1", "putAllValue1");
                  m.put("putAllKey2", "putAllValue2");
                  r.putAll(m);
                }
              });
      assertEquals(2, this.clInvokeCount);
      // @todo darrel; check putAll events
      this.clInvokeCount = 0;

      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do netsearch") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  assertEquals(null, r.get("loadkey")); // total miss
                }
              });
      assertEquals(0, this.clInvokeCount);

    } else {
      getOtherVm()
          .invoke(
              new CacheSerializableRunnable("do entry ops") {
                public void run2() throws CacheException {
                  Region r = getRootRegion("ProxyDUnitTest");
                  r.put("p", "v");
                  r.create("c", "v");
                  r.put("c", "v"); // update
                  r.invalidate("c");
                  r.destroy("c");
                  {
                    Map m = new HashMap();
                    m.put("putAllKey1", "putAllValue1");
                    m.put("putAllKey2", "putAllValue2");
                    r.putAll(m);
                  }
                  assertEquals(null, r.get("loadkey")); // total miss
                }
              });

      assertEquals(0, this.clInvokeCount);
      assertEquals(0, r.size());
      // check the stats to make sure none of the above sent up messages
      assertEquals(receivedMsgs, stats.getReceivedMessages());
    }

    {
      AttributesMutator am = r.getAttributesMutator();
      CacheLoader cl =
          new CacheLoader() {
            public Object load(LoaderHelper helper) throws CacheLoaderException {
              if (helper.getKey().equals("loadkey")) {
                return "loadvalue";
              } else if (helper.getKey().equals("loadexception")) {
                throw new CacheLoaderException("expected");
              } else {
                return null;
              }
            }

            public void close() {}
          };
      am.setCacheLoader(cl);
    }

    receivedMsgs = stats.getReceivedMessages();
    getOtherVm()
        .invoke(
            new CacheSerializableRunnable("check net loader") {
              public void run2() throws CacheException {
                Region r = getRootRegion("ProxyDUnitTest");
                assertEquals("loadvalue", r.get("loadkey")); // net load
                assertEquals(null, r.get("foobar")); // total miss
                try {
                  r.get("loadexception");
                  fail("expected CacheLoaderException");
                } catch (CacheLoaderException expected) {
                }
              }
            });
    assertTrue(stats.getReceivedMessages() > receivedMsgs);
    if (ip.isAll()) {
      assertEquals(1, this.clInvokeCount);
      assertEquals(Operation.NET_LOAD_CREATE, this.clLastEvent.getOperation());
      assertEquals(true, this.clLastEvent.isOriginRemote());
      assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) this.clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) this.clLastEvent).isOldValueAvailable());
      this.clInvokeCount = 0;
    } else {
      assertEquals(0, this.clInvokeCount);
    }

    {
      AttributesMutator am = r.getAttributesMutator();
      am.setCacheLoader(null);
      CacheWriter cw =
          new CacheWriterAdapter() {
            public void beforeCreate(EntryEvent event) throws CacheWriterException {
              throw new CacheWriterException("expected");
            }
          };
      am.setCacheWriter(cw);
    }
    receivedMsgs = stats.getReceivedMessages();
    getOtherVm()
        .invoke(
            new CacheSerializableRunnable("check net write") {
              public void run2() throws CacheException {
                Region r = getRootRegion("ProxyDUnitTest");
                try {
                  r.put("putkey", "putvalue");
                  fail("expected CacheWriterException");
                } catch (CacheWriterException expected) {
                }
              }
            });
    assertTrue(stats.getReceivedMessages() > receivedMsgs);
    {
      AttributesMutator am = r.getAttributesMutator();
      am.setCacheWriter(null);
    }
    assertEquals(0, this.clInvokeCount);
    this.clLastEvent = null;
    getOtherVm()
        .invoke(
            new CacheSerializableRunnable("check region invalidate") {
              public void run2() throws CacheException {
                Region r = getRootRegion("ProxyDUnitTest");
                r.invalidateRegion();
              }
            });
    assertEquals(1, this.clInvokeCount);
    assertEquals(Operation.REGION_INVALIDATE, this.clLastEvent.getOperation());
    assertEquals(true, this.clLastEvent.isOriginRemote());
    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());

    this.clLastEvent = null;
    getOtherVm()
        .invoke(
            new CacheSerializableRunnable("check region clear") {
              public void run2() throws CacheException {
                Region r = getRootRegion("ProxyDUnitTest");
                r.clear();
              }
            });
    assertEquals(2, this.clInvokeCount);
    assertEquals(Operation.REGION_CLEAR, this.clLastEvent.getOperation());
    assertEquals(true, this.clLastEvent.isOriginRemote());
    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());

    this.clLastEvent = null;
    getOtherVm()
        .invoke(
            new CacheSerializableRunnable("check region destroy") {
              public void run2() throws CacheException {
                Region r = getRootRegion("ProxyDUnitTest");
                r.destroyRegion();
              }
            });
    assertEquals(3, this.clInvokeCount);
    assertEquals(Operation.REGION_DESTROY, this.clLastEvent.getOperation());
    assertEquals(true, this.clLastEvent.isOriginRemote());
    assertEquals(this.otherId, this.clLastEvent.getDistributedMember());
    assertTrue(r.isDestroyed());
  }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private void doRegionTest(final RegionShortcut rs, final String rName, boolean compressed) {
    boolean isPersistent =
        rs == RegionShortcut.LOCAL_PERSISTENT
            || rs == RegionShortcut.REPLICATE_PERSISTENT
            || rs == RegionShortcut.PARTITION_PERSISTENT;
    GemFireCacheImpl gfc = createCache(isPersistent);
    Region r = null;
    try {
      gfc.setCopyOnRead(true);
      final MemoryAllocator ma = gfc.getOffHeapStore();
      assertNotNull(ma);
      assertEquals(0, ma.getUsedMemory());
      Compressor compressor = null;
      if (compressed) {
        compressor = SnappyCompressor.getDefaultInstance();
      }
      r = gfc.createRegionFactory(rs).setOffHeap(true).setCompressor(compressor).create(rName);
      assertEquals(true, r.isEmpty());
      assertEquals(0, ma.getUsedMemory());
      Object data = new Integer(123456789);
      r.put("key1", data);
      // System.out.println("After put of Integer value off heap used memory=" +
      // ma.getUsedMemory());
      assertTrue(ma.getUsedMemory() == 0);
      assertEquals(data, r.get("key1"));
      r.invalidate("key1");
      assertEquals(0, ma.getUsedMemory());
      r.put("key1", data);
      assertTrue(ma.getUsedMemory() == 0);
      long usedBeforeUpdate = ma.getUsedMemory();
      r.put("key1", data);
      assertEquals(usedBeforeUpdate, ma.getUsedMemory());
      assertEquals(data, r.get("key1"));
      r.destroy("key1");
      assertEquals(0, ma.getUsedMemory());

      data = new Long(0x007FFFFFL);
      r.put("key1", data);
      if (!compressed) {
        assertTrue(ma.getUsedMemory() == 0);
      }
      assertEquals(data, r.get("key1"));
      data = new Long(0xFF8000000L);
      r.put("key1", data);
      if (!compressed) {
        assertTrue(ma.getUsedMemory() == 0);
      }
      assertEquals(data, r.get("key1"));

      // now lets set data to something that will be stored offheap
      data = new Long(Long.MAX_VALUE);
      r.put("key1", data);
      assertEquals(data, r.get("key1"));
      // System.out.println("After put of Integer value off heap used memory=" +
      // ma.getUsedMemory());
      assertTrue(ma.getUsedMemory() > 0);
      data = new Long(Long.MIN_VALUE);
      r.put("key1", data);
      assertEquals(data, r.get("key1"));
      // System.out.println("After put of Integer value off heap used memory=" +
      // ma.getUsedMemory());
      assertTrue(ma.getUsedMemory() > 0);
      r.invalidate("key1");
      assertEquals(0, ma.getUsedMemory());
      r.put("key1", data);
      assertTrue(ma.getUsedMemory() > 0);
      usedBeforeUpdate = ma.getUsedMemory();
      r.put("key1", data);
      assertEquals(usedBeforeUpdate, ma.getUsedMemory());
      assertEquals(data, r.get("key1"));
      r.destroy("key1");
      assertEquals(0, ma.getUsedMemory());

      // confirm that byte[] do use off heap
      {
        byte[] originalBytes = new byte[1024];
        Object oldV = r.put("byteArray", originalBytes);
        long startUsedMemory = ma.getUsedMemory();
        assertEquals(null, oldV);
        byte[] readBytes = (byte[]) r.get("byteArray");
        if (originalBytes == readBytes) {
          fail("Expected different byte[] identity");
        }
        if (!Arrays.equals(readBytes, originalBytes)) {
          fail("Expected byte array contents to be equal");
        }
        assertEquals(startUsedMemory, ma.getUsedMemory());
        oldV = r.put("byteArray", originalBytes);
        if (!compressed) {
          assertEquals(null, oldV); // we default to old value being null for offheap
        }
        assertEquals(startUsedMemory, ma.getUsedMemory());

        readBytes = (byte[]) r.putIfAbsent("byteArray", originalBytes);
        if (originalBytes == readBytes) {
          fail("Expected different byte[] identity");
        }
        if (!Arrays.equals(readBytes, originalBytes)) {
          fail("Expected byte array contents to be equal");
        }
        assertEquals(startUsedMemory, ma.getUsedMemory());
        if (!r.replace("byteArray", readBytes, originalBytes)) {
          fail("Expected replace to happen");
        }
        assertEquals(startUsedMemory, ma.getUsedMemory());
        byte[] otherBytes = new byte[1024];
        otherBytes[1023] = 1;
        if (r.replace("byteArray", otherBytes, originalBytes)) {
          fail("Expected replace to not happen");
        }
        if (r.replace("byteArray", "bogus string", originalBytes)) {
          fail("Expected replace to not happen");
        }
        if (r.remove("byteArray", "bogus string")) {
          fail("Expected remove to not happen");
        }
        assertEquals(startUsedMemory, ma.getUsedMemory());

        if (!r.remove("byteArray", originalBytes)) {
          fail("Expected remove to happen");
        }
        assertEquals(0, ma.getUsedMemory());
        oldV = r.putIfAbsent("byteArray", "string value");
        assertEquals(null, oldV);
        assertEquals("string value", r.get("byteArray"));
        if (r.replace("byteArray", "string valuE", originalBytes)) {
          fail("Expected replace to not happen");
        }
        if (!r.replace("byteArray", "string value", originalBytes)) {
          fail("Expected replace to happen");
        }
        oldV = r.destroy("byteArray"); // we default to old value being null for offheap
        if (!compressed) {
          assertEquals(null, oldV);
        }
        MyCacheListener listener = new MyCacheListener();
        r.getAttributesMutator().addCacheListener(listener);
        try {
          Object valueToReplace = "string value1";
          r.put("byteArray", valueToReplace);
          assertEquals(null, listener.ohOldValue);
          if (!compressed) {
            assertEquals("string value1", listener.ohNewValue.getDeserializedForReading());
            valueToReplace = listener.ohNewValue;
          }
          if (!r.replace("byteArray", valueToReplace, "string value2")) {
            fail("expected replace to happen");
          }
          if (!compressed) {
            assertEquals("string value2", listener.ohNewValue.getDeserializedForReading());
            assertEquals("string value1", listener.ohOldValue.getDeserializedForReading());
          }
          // make sure that a custom equals/hashCode are not used when comparing values.

        } finally {
          r.getAttributesMutator().removeCacheListener(listener);
        }
      }
      assertTrue(ma.getUsedMemory() > 0);
      {
        Object key = "MyValueWithPartialEquals";
        MyValueWithPartialEquals v1 = new MyValueWithPartialEquals("s1");
        MyValueWithPartialEquals v2 = new MyValueWithPartialEquals("s2");
        MyValueWithPartialEquals v3 = new MyValueWithPartialEquals("s1");
        r.put(key, v1);
        try {
          if (r.replace(key, v2, "should not happen")) {
            fail("v1 should not be equal to v2 on an offheap region");
          }
          if (!r.replace(key, v3, "should happen")) {
            fail("v1 should be equal to v3 on an offheap region");
          }
          r.put(key, v1);
          if (r.remove(key, v2)) {
            fail("v1 should not be equal to v2 on an offheap region");
          }
          if (!r.remove(key, v3)) {
            fail("v1 should be equal to v3 on an offheap region");
          }
        } finally {
          r.remove(key);
        }
      }
      {
        Object key = "MyPdxWithPartialEquals";
        MyPdxWithPartialEquals v1 = new MyPdxWithPartialEquals("s", "1");
        MyPdxWithPartialEquals v2 = new MyPdxWithPartialEquals("s", "2");
        MyPdxWithPartialEquals v3 = new MyPdxWithPartialEquals("t", "1");
        r.put(key, v1);
        try {
          if (r.replace(key, v3, "should not happen")) {
            fail("v1 should not be equal to v3 on an offheap region");
          }
          if (!r.replace(key, v2, "should happen")) {
            fail("v1 should be equal to v2 on an offheap region");
          }
          r.put(key, v1);
          if (r.remove(key, v3)) {
            fail("v1 should not be equal to v3 on an offheap region");
          }
          if (!r.remove(key, v2)) {
            fail("v1 should be equal to v2 on an offheap region");
          }
        } finally {
          r.remove(key);
        }
      }
      byte[] value = new byte[1024];
      /*while (value != null) */ {
        r.put("byteArray", value);
      }
      r.remove("byteArray");
      assertEquals(0, ma.getUsedMemory());

      r.put("key1", data);
      assertTrue(ma.getUsedMemory() > 0);
      r.invalidateRegion();
      assertEquals(0, ma.getUsedMemory());

      r.put("key1", data);
      assertTrue(ma.getUsedMemory() > 0);
      try {
        r.clear();
        assertEquals(0, ma.getUsedMemory());
      } catch (UnsupportedOperationException ok) {
      }

      r.put("key1", data);
      assertTrue(ma.getUsedMemory() > 0);
      if (r.getAttributes().getDataPolicy().withPersistence()) {
        r.put("key2", Integer.valueOf(1234567890));
        r.put("key3", new Long(0x007FFFFFL));
        r.put("key4", new Long(0xFF8000000L));
        assertEquals(4, r.size());
        r.close();
        assertEquals(0, ma.getUsedMemory());
        // simple test of recovery
        r = gfc.createRegionFactory(rs).setOffHeap(true).create(rName);
        assertEquals(4, r.size());
        assertEquals(data, r.get("key1"));
        assertEquals(Integer.valueOf(1234567890), r.get("key2"));
        assertEquals(new Long(0x007FFFFFL), r.get("key3"));
        assertEquals(new Long(0xFF8000000L), r.get("key4"));
        closeCache(gfc, true);
        assertEquals(0, ma.getUsedMemory());
        gfc = createCache();
        if (ma != gfc.getOffHeapStore()) {
          fail("identity of offHeapStore changed when cache was recreated");
        }
        r = gfc.createRegionFactory(rs).setOffHeap(true).create(rName);
        assertTrue(ma.getUsedMemory() > 0);
        assertEquals(4, r.size());
        assertEquals(data, r.get("key1"));
        assertEquals(Integer.valueOf(1234567890), r.get("key2"));
        assertEquals(new Long(0x007FFFFFL), r.get("key3"));
        assertEquals(new Long(0xFF8000000L), r.get("key4"));
      }

      r.destroyRegion();
      assertEquals(0, ma.getUsedMemory());

    } finally {
      if (r != null && !r.isDestroyed()) {
        r.destroyRegion();
      }
      closeCache(gfc, false);
    }
  }
  /**
   * Tests that we are in {@link GemFireHealth#OKAY_HEALTH okay} health if cache loads take too
   * long.
   *
   * @see CacheHealthEvaluator#checkLoadTime
   */
  public void testCheckLoadTime() throws CacheException {
    Cache cache = CacheFactory.create(this.system);
    CachePerfStats stats = ((GemFireCacheImpl) cache).getCachePerfStats();

    AttributesFactory factory = new AttributesFactory();
    factory.setScope(Scope.LOCAL);
    factory.setCacheLoader(
        new CacheLoader() {
          public Object load(LoaderHelper helper) throws CacheLoaderException {

            return "Loaded";
          }

          public void close() {}
        });

    RegionAttributes attrs = factory.create();
    Region region = cache.createRegion(this.getName(), attrs);

    GemFireHealthConfig config = new GemFireHealthConfigImpl(null);
    config.setMaxLoadTime(100);

    CacheHealthEvaluator eval =
        new CacheHealthEvaluator(config, this.system.getDistributionManager());
    for (int i = 0; i < 10; i++) {
      region.get("Test1 " + i);
    }
    long firstLoadTime = stats.getLoadTime();
    long firstLoadsCompleted = stats.getLoadsCompleted();
    assertTrue(firstLoadTime >= 0);
    assertTrue(firstLoadsCompleted > 0);

    // First time should always be empty
    List status = new ArrayList();
    eval.evaluate(status);
    assertEquals(0, status.size());

    config = new GemFireHealthConfigImpl(null);
    config.setMaxLoadTime(10);
    eval = new CacheHealthEvaluator(config, this.system.getDistributionManager());
    eval.evaluate(status);

    long start = System.currentTimeMillis();
    for (int i = 0; i < 100; i++) {
      region.get("Test2 " + i);
    }
    assertTrue(System.currentTimeMillis() - start < 1000);
    long secondLoadTime = stats.getLoadTime();
    long secondLoadsCompleted = stats.getLoadsCompleted();
    assertTrue(
        "firstLoadTime=" + firstLoadTime + ", secondLoadTime=" + secondLoadTime,
        secondLoadTime >= firstLoadTime);
    assertTrue(secondLoadsCompleted > firstLoadsCompleted);

    // Averge should be less than 10 milliseconds
    status = new ArrayList();
    eval.evaluate(status);
    assertEquals(0, status.size());

    region
        .getAttributesMutator()
        .setCacheLoader(
            new CacheLoader() {
              public Object load(LoaderHelper helper) throws CacheLoaderException {

                try {
                  Thread.sleep(20);

                } catch (InterruptedException ex) {
                  fail("Why was I interrupted?");
                }
                return "Loaded";
              }

              public void close() {}
            });

    for (int i = 0; i < 50; i++) {
      region.get("Test3 " + i);
    }

    long thirdLoadTime = stats.getLoadTime();
    long thirdLoadsCompleted = stats.getLoadsCompleted();
    assertTrue(thirdLoadTime > secondLoadTime);
    assertTrue(thirdLoadsCompleted > secondLoadsCompleted);

    status = new ArrayList();
    eval.evaluate(status);
    assertEquals(1, status.size());

    AbstractHealthEvaluator.HealthStatus ill = (AbstractHealthEvaluator.HealthStatus) status.get(0);
    assertEquals(GemFireHealth.OKAY_HEALTH, ill.getHealthCode());
    String s = "The average duration of a Cache load";
    assertTrue(ill.getDiagnosis().indexOf(s) != -1);
  }