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() {
      @Override
      public void afterUpdate(EntryEvent e) {
        clLastEvent = e;
        clInvokeCount++;
      }

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

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

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

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

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

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

      @Override
      public void afterRegionCreate(RegionEvent e) {}

      @Override
      public void afterRegionLive(RegionEvent e) {}

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

    doCreateOtherVm();

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

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

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

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

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

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

      getOtherVm().invoke(new CacheSerializableRunnable("do putAll") {
        @Override
        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, clInvokeCount);
      // @todo darrel; check putAll events
      clInvokeCount = 0;

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

    } else {
      getOtherVm().invoke(new CacheSerializableRunnable("do entry ops") {
        @Override
        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, 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() {
        @Override
        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;
          }
        }

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

    receivedMsgs = stats.getReceivedMessages();
    getOtherVm().invoke(new CacheSerializableRunnable("check net loader") {
      @Override
      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 ignored) {
        }
      }
    });
    assertTrue(stats.getReceivedMessages() > receivedMsgs);
    if (ip.isAll()) {
      assertEquals(1, clInvokeCount);
      assertEquals(Operation.NET_LOAD_CREATE, clLastEvent.getOperation());
      assertEquals(true, clLastEvent.isOriginRemote());
      assertEquals(otherId, clLastEvent.getDistributedMember());
      assertEquals(null, ((EntryEvent) clLastEvent).getOldValue());
      assertEquals(false, ((EntryEvent) clLastEvent).isOldValueAvailable());
      clInvokeCount = 0;
    } else {
      assertEquals(0, clInvokeCount);
    }

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

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

    clLastEvent = null;
    getOtherVm().invoke(new CacheSerializableRunnable("check region destroy") {
      @Override
      public void run2() throws CacheException {
        Region r = getRootRegion("ProxyDUnitTest");
        r.destroyRegion();
      }
    });
    assertEquals(3, clInvokeCount);
    assertEquals(Operation.REGION_DESTROY, clLastEvent.getOperation());
    assertEquals(true, clLastEvent.isOriginRemote());
    assertEquals(otherId, clLastEvent.getDistributedMember());
    assertTrue(r.isDestroyed());
  }
check remote ops done in a normal vm are correctly distributed to PROXY regions
geode-core/src/distributedTest/java/org/apache/geode/cache30/ProxyDUnitTest.java