@Test
  public void testServerEventsInLonerClient() throws Exception {
    boolean[] firedAdapter = new boolean[3];
    DistributedMember[] memberAdapter = new DistributedMember[3];
    String[] memberIdAdapter = new String[3];
    boolean[] isClientAdapter = new boolean[3];

    boolean[] firedBridge = new boolean[3];
    DistributedMember[] memberBridge = new DistributedMember[3];
    String[] memberIdBridge = new String[3];
    boolean[] isClientBridge = new boolean[3];

    boolean[] firedAdapterDuplicate = new boolean[3];
    boolean[] firedBridgeDuplicate = new boolean[3];

    UniversalMembershipListenerAdapter adapter = new UniversalMembershipListenerAdapter() {
      @Override
      public synchronized void memberJoined(MembershipEvent event) {
        firedAdapterDuplicate[JOINED] = firedAdapter[JOINED];
        firedAdapter[JOINED] = true;
        memberAdapter[JOINED] = event.getDistributedMember();
        memberIdAdapter[JOINED] = event.getMemberId();
        if (event instanceof AdaptedMembershipEvent) {
          isClientAdapter[JOINED] = ((AdaptedMembershipEvent) event).isClient();
        }
        notifyAll();
      }

      @Override
      public synchronized void memberLeft(MembershipEvent event) {
        firedAdapterDuplicate[LEFT] = firedAdapter[LEFT];
        firedAdapter[LEFT] = true;
        memberAdapter[LEFT] = event.getDistributedMember();
        memberIdAdapter[LEFT] = event.getMemberId();
        if (event instanceof AdaptedMembershipEvent) {
          isClientAdapter[LEFT] = ((AdaptedMembershipEvent) event).isClient();
        }
        notifyAll();
      }

      @Override
      public synchronized void memberCrashed(MembershipEvent event) {
        firedAdapterDuplicate[CRASHED] = firedAdapter[CRASHED];
        firedAdapter[CRASHED] = true;
        memberAdapter[CRASHED] = event.getDistributedMember();
        memberIdAdapter[CRASHED] = event.getMemberId();
        if (event instanceof AdaptedMembershipEvent) {
          isClientAdapter[CRASHED] = ((AdaptedMembershipEvent) event).isClient();
        }
        notifyAll();
      }
    };

    ClientMembershipListener bridgeListener = new ClientMembershipListener() {
      @Override
      public synchronized void memberJoined(ClientMembershipEvent event) {
        firedBridgeDuplicate[JOINED] = firedBridge[JOINED];
        firedBridge[JOINED] = true;
        memberBridge[JOINED] = event.getMember();
        memberIdBridge[JOINED] = event.getMemberId();
        isClientBridge[JOINED] = event.isClient();
        notifyAll();
      }

      @Override
      public synchronized void memberLeft(ClientMembershipEvent event) {
        firedBridgeDuplicate[LEFT] = firedBridge[LEFT];
        firedBridge[LEFT] = true;
        memberBridge[LEFT] = event.getMember();
        memberIdBridge[LEFT] = event.getMemberId();
        isClientBridge[LEFT] = event.isClient();
        notifyAll();
      }

      @Override
      public synchronized void memberCrashed(ClientMembershipEvent event) {
        firedBridgeDuplicate[CRASHED] = firedBridge[CRASHED];
        firedBridge[CRASHED] = true;
        memberBridge[CRASHED] = event.getMember();
        memberIdBridge[CRASHED] = event.getMemberId();
        isClientBridge[CRASHED] = event.isClient();
        notifyAll();
      }
    };

    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    String name = getUniqueName();
    int[] ports = getRandomAvailableTCPPorts(1);
    assertThat(ports[0] != 0).isTrue();

    Properties config = new Properties();
    config.put(MCAST_PORT, "0");
    config.put(LOCATORS, "");
    config.setProperty(ENABLE_NETWORK_PARTITION_DETECTION, "false");
    getSystem(config);

    // register the bridge listener
    ClientMembership.registerClientMembershipListener(bridgeListener);

    // create CacheServer in vm0...
    SerializableCallable createBridgeServer = new SerializableCallable("Create BridgeServer") {
      @Override
      public Object call() {
        getSystem();
        AttributesFactory factory = new AttributesFactory();
        factory.setScope(Scope.LOCAL);
        Region region = createRegion(name, factory.create());
        assertThat(region).isNotNull();
        assertThat(getRootRegion().getSubregion(name)).isNotNull();

        try {
          serverPort = startBridgeServer(ports[0]);
        } catch (IOException e) {
          throw new AssertionError(e);
        }

        return basicGetSystem().getDistributedMember();
      }
    };

    vm0.invoke(createBridgeServer);

    // gather details for later creation of pool...
    assertThat((int) vm0.invoke("getServerPort", () -> serverPort)).isEqualTo(ports[0]);

    // create region which connects to cache server
    AttributesFactory factory = new AttributesFactory();
    factory.setScope(Scope.LOCAL);
    configureConnectionPool(factory, getServerHostName(host), ports, false, -1, -1, null);
    createRegion(name, factory.create());
    assertThat(getRootRegion().getSubregion(name)).isNotNull();

    await("wait for join").until(() -> {
      synchronized (adapter) {
        return firedAdapter[JOINED];
      }
    });
    await("wait for join").until(() -> {
      synchronized (bridgeListener) {
        return firedBridge[JOINED];
      }
    });

    assertArrayFalse(firedAdapterDuplicate);
    assertArrayFalse(firedBridgeDuplicate);

    assertThat(firedBridge[JOINED]).isTrue();
    assertThat(memberBridge[JOINED]).isNotNull();
    assertThat(memberIdBridge[JOINED]).isNotNull();
    assertThat(isClientBridge[JOINED]).isFalse();
    assertThat(firedBridge[LEFT]).isFalse();
    assertThat(memberBridge[LEFT]).isNull();
    assertThat(memberIdBridge[LEFT]).isNull();
    assertThat(isClientBridge[LEFT]).isFalse();
    assertThat(firedBridge[CRASHED]).isFalse();
    assertThat(memberBridge[CRASHED]).isNull();
    assertThat(memberIdBridge[CRASHED]).isNull();
    assertThat(isClientBridge[CRASHED]).isFalse();

    resetArraysForTesting(firedBridge, memberBridge, memberIdBridge, isClientBridge);

    assertThat(firedAdapter[JOINED]).isTrue();
    assertThat(memberIdAdapter[JOINED]).isNotNull();
    assertThat(isClientAdapter[JOINED]).isFalse();
    assertThat(firedAdapter[LEFT]).isFalse();
    assertThat(memberAdapter[LEFT]).isNull();
    assertThat(memberIdAdapter[LEFT]).isNull();
    assertThat(isClientAdapter[LEFT]).isFalse();
    assertThat(firedAdapter[CRASHED]).isFalse();
    assertThat(memberAdapter[CRASHED]).isNull();
    assertThat(memberIdAdapter[CRASHED]).isNull();
    assertThat(isClientAdapter[CRASHED]).isFalse();

    resetArraysForTesting(firedAdapter, memberAdapter, memberIdAdapter, isClientAdapter);

    String poolName = getRootRegion().getSubregion(name).getAttributes().getPoolName();
    PoolImpl pool = (PoolImpl) PoolManager.find(poolName);
    waitForClientToFullyConnect(pool);

    addIgnoredException(IOException.class.getName());
    addIgnoredException(ConnectException.class.getName());

    vm0.invoke(new SerializableRunnable("Disconnect cache server") {
      @Override
      public void run() {
        closeCache();
      }
    });

    await("wait for server to leave").until(() -> {
      synchronized (adapter) {
        return firedAdapter[LEFT] || firedAdapter[CRASHED];
      }
    });
    await("wait for server to leave").until(() -> {
      synchronized (bridgeListener) {
        return firedBridge[LEFT] || firedBridge[CRASHED];
      }
    });

    // done with IgnoredExceptions

    assertArrayFalse(firedAdapterDuplicate);
    assertArrayFalse(firedBridgeDuplicate);

    assertThat(firedBridge[JOINED]).isFalse();
    assertThat(memberIdBridge[JOINED]).isNull();
    assertThat(memberBridge[JOINED]).isNull();
    assertThat(isClientBridge[JOINED]).isFalse();
    assertThat(firedBridge[LEFT]).isFalse();
    assertThat(memberBridge[LEFT]).isNull();
    assertThat(memberIdBridge[LEFT]).isNull();
    assertThat(isClientBridge[LEFT]).isFalse();
    assertThat(firedBridge[CRASHED]).isTrue();
    assertThat(memberBridge[CRASHED]).isNotNull();
    assertThat(memberIdBridge[CRASHED]).isNotNull();
    assertThat(isClientBridge[CRASHED]).isFalse();

    resetArraysForTesting(firedBridge, memberBridge, memberIdBridge, isClientBridge);

    assertThat(firedAdapter[JOINED]).isFalse();
    assertThat(memberAdapter[JOINED]).isNull();
    assertThat(memberIdAdapter[JOINED]).isNull();
    assertThat(isClientAdapter[JOINED]).isFalse();
    assertThat(firedAdapter[LEFT]).isFalse();
    assertThat(memberAdapter[LEFT]).isNull();
    assertThat(memberIdAdapter[LEFT]).isNull();
    assertThat(isClientAdapter[LEFT]).isFalse();
    // CRASHED fired by Bridge listener
    assertThat(firedAdapter[CRASHED]).isTrue();
    assertThat(memberAdapter[CRASHED]).isNotNull();
    assertThat(memberIdAdapter[CRASHED]).isNotNull();
    assertThat(isClientAdapter[CRASHED]).isFalse();

    resetArraysForTesting(firedAdapter, memberAdapter, memberIdAdapter, isClientAdapter);

    // reconnect bridge client to test for crashed event
    vm0.invoke(createBridgeServer);

    // gather details for later creation of pool...
    assertThat((int) vm0.invoke(() -> serverPort)).isEqualTo(ports[0]);

    await("wait for join").until(() -> {
      synchronized (adapter) {
        return firedAdapter[JOINED];
      }
    });
    await("wait for join").until(() -> {
      synchronized (bridgeListener) {
        return firedBridge[JOINED];
      }
    });

    assertArrayFalse(firedAdapterDuplicate);
    assertArrayFalse(firedBridgeDuplicate);

    assertThat(firedBridge[JOINED]).isTrue();
    assertThat(memberBridge[JOINED]).isNotNull();
    assertThat(memberIdBridge[JOINED]).isNotNull();
    assertThat(isClientBridge[JOINED]).isFalse();
    assertThat(firedBridge[LEFT]).isFalse();
    assertThat(memberBridge[LEFT]).isNull();
    assertThat(memberIdBridge[LEFT]).isNull();
    assertThat(isClientBridge[LEFT]).isFalse();
    assertThat(firedBridge[CRASHED]).isFalse();
    assertThat(memberBridge[CRASHED]).isNull();
    assertThat(memberIdBridge[CRASHED]).isNull();
    assertThat(isClientBridge[CRASHED]).isFalse();

    resetArraysForTesting(firedBridge, memberBridge, memberIdBridge, isClientBridge);

    assertThat(firedAdapter[JOINED]).isTrue();
    assertThat(memberAdapter[JOINED]).isNotNull();
    assertThat(memberIdAdapter[JOINED]).isNotNull();
    assertThat(isClientAdapter[JOINED]).isFalse();
    assertThat(firedAdapter[LEFT]).isFalse();
    assertThat(memberAdapter[LEFT]).isNull();
    assertThat(memberIdAdapter[LEFT]).isNull();
    assertThat(isClientAdapter[LEFT]).isFalse();
    assertThat(firedAdapter[CRASHED]).isFalse();
    assertThat(memberAdapter[CRASHED]).isNull();
    assertThat(memberIdAdapter[CRASHED]).isNull();
    assertThat(isClientAdapter[CRASHED]).isFalse();

    resetArraysForTesting(firedAdapter, memberAdapter, memberIdAdapter, isClientAdapter);
  }
Tests notification of events for cache server in system bridge client process.
geode-core/src/distributedTest/java/org/apache/geode/management/UniversalMembershipListenerAdapterDUnitTest.java