void processMessage(SuspectMembersMessage<ID> incomingRequest) {
    if (isStopping) {
      return;
    }
    if (beingSick || playingDead) {
      logger.debug("sick member is ignoring suspect message");
      return;
    }

    logSuspectRequests(incomingRequest, incomingRequest.getSender());

    stats.incSuspectsReceived();

    GMSMembershipView<ID> cv = currentView;

    if (cv == null) {
      return;
    }

    List<SuspectRequest<ID>> suspectRequests = incomingRequest.getMembers();

    ID sender = incomingRequest.getSender();
    int viewId = sender.getVmViewId();
    if (cv.getViewId() >= viewId && !cv.contains(incomingRequest.getSender())) {
      logger.info("Membership ignoring suspect request for " + incomingRequest + " from non-member "
          + incomingRequest.getSender());
      services.getJoinLeave().remove(sender,
          "this process is initiating suspect processing but is no longer a member");
      return;
    }

    // take care of any suspicion of this member by sending a heartbeat back
    for (Iterator<SuspectRequest<ID>> it = incomingRequest.getMembers().iterator(); it.hasNext();) {
      SuspectRequest<ID> req = it.next();
      if (req.getSuspectMember().equals(localAddress)) {
        HeartbeatMessage<ID> message = new HeartbeatMessage<>(-1);
        message.setRecipient(sender);
        try {
          services.getMessenger().send(message);
          stats.incHeartbeatsSent();
          it.remove();
        } catch (MembershipClosedException e) {
          return;
        }
      }
    }

    logger.debug("Processing {}", incomingRequest);
    if (cv.getCoordinator().equals(localAddress)) {
      // This process is the membership coordinator and should perform a final check
      checkIfAvailable(sender, suspectRequests, cv);

    } else {
      // Another process has raised suspicion - check to see if
      // this process should become the membership coordinator if
      // all current suspects are gone
      GMSMembershipView<ID> check = new GMSMembershipView<>(cv, cv.getViewId() + 1);
      ArrayList<SuspectRequest<ID>> membersToCheck = new ArrayList<>();
      synchronized (suspectRequestsInView) {
        recordSuspectRequests(suspectRequests, cv);
        Set<SuspectRequest<ID>> suspectsInView = suspectRequestsInView.get(cv);
        logger.debug("Current suspects are {}", suspectsInView);
        for (final SuspectRequest<ID> sr : suspectsInView) {
          check.remove(sr.getSuspectMember());
          membersToCheck.add(sr);
        }
      }
      List<ID> membersLeaving = new ArrayList<>();
      for (ID member : cv.getMembers()) {
        if (services.getJoinLeave().isMemberLeaving(member)) {
          membersLeaving.add(member);
        }
      }
      if (!membersLeaving.isEmpty()) {
        logger.debug("Current leave requests are {}", membersLeaving);
        check.removeAll(membersLeaving);
      }
      logger.debug(
          "Proposed view with suspects & leaving members removed is {}\nwith coordinator {}\nmy address is {}",
          check,
          check.getCoordinator(), localAddress);

      ID coordinator = check.getCoordinator();
      if (coordinator != null && coordinator.equals(localAddress)) {
        // new coordinator
        checkIfAvailable(sender, membersToCheck, cv);
      }
    }

  }
Process a Suspect request from another member. This may cause this member to become the new
membership coordinator. it will to final check on that member and then it will send remove
request for that member
geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java