public Set<PartitionRebalanceInfo> execute() {
    long start = System.nanoTime();
    InternalResourceManager resourceManager =
        InternalResourceManager.getInternalResourceManager(leaderRegion.getCache());
    MembershipListener listener = new MembershipChangeListener();
    if (isRebalance) {
      InternalResourceManager.getResourceObserver().rebalancingStarted(targetRegion);
    } else {
      InternalResourceManager.getResourceObserver().recoveryStarted(targetRegion);
    }
    RecoveryLock lock = null;
    try {
      if (!checkAndSetColocatedRegions()) {
        return Collections.emptySet();
      }

      // Early out if this was an automatically triggered rebalance and we now
      // have full redundancy.
      if (!isRebalanceNecessary()) {
        return Collections.emptySet();
      }

      if (!simulate) {
        lock = leaderRegion.getRecoveryLock();
        lock.lock();
      }

      // Check this again after getting the lock, because someone might
      // have fixed it already.
      if (!isRebalanceNecessary()) {
        return Collections.emptySet();
      }

      // register a listener to notify us if the new members leave or join.
      // When a membership change occurs, we want to restart the rebalancing
      // from the beginning.
      // TODO rebalance - we should really add a membership listener to ALL of
      // the colocated regions.
      leaderRegion.getRegionAdvisor().addMembershipListener(listener);
      PartitionedRegionLoadModel loadModel = null;

      InternalCache cache = leaderRegion.getCache();
      Map<PartitionedRegion, InternalPRInfo> detailsMap = fetchDetails(cache);
      BucketOperatorWrapper serialOperator = getBucketOperator(detailsMap);
      ParallelBucketOperator parallelOperator = new ParallelBucketOperator(MAX_PARALLEL_OPERATIONS,
          cache.getDistributionManager().getExecutors().getWaitingThreadPool(), serialOperator);
      loadModel = buildModel(parallelOperator, detailsMap, resourceManager);
      for (PartitionRebalanceDetailsImpl details : serialOperator.getDetailSet()) {
        details.setPartitionMemberDetailsBefore(
            loadModel.getPartitionedMemberDetails(details.getRegionPath()));
      }

      director.initialize(loadModel);
      String operationType = "Rebalancing";
      if (director instanceof CompositeDirector
          && ((CompositeDirector) director).isRestoreRedundancy()) {
        operationType = "Restoring redundancy";
      }

      for (;;) {
        if (cancelled.get()) {
          return Collections.emptySet();
        }
        if (membershipChange) {
          membershipChange = false;
          // refetch the partitioned region details after
          // a membership change.
          debug(operationType + " {} detected membership changes. Refetching details",
              leaderRegion);
          if (stats != null) {
            stats.incRebalanceMembershipChanges(1);
          }
          loadModel.waitForOperations();
          detailsMap = fetchDetails(cache);
          loadModel = buildModel(parallelOperator, detailsMap, resourceManager);
          director.membershipChanged(loadModel);
        }

        leaderRegion.checkClosed();
        cache.getCancelCriterion().checkCancelInProgress(null);

        if (logger.isDebugEnabled()) {
          logger.debug(operationType + " {} Model:{}\n", leaderRegion, loadModel);
        }

        if (!director.nextStep()) {
          // Stop when the director says we can't rebalance any more.
          break;
        }
      }

      debug(operationType + " {} complete. Model:{}\n", leaderRegion, loadModel);
      long end = System.nanoTime();

      for (PartitionRebalanceDetailsImpl details : serialOperator.getDetailSet()) {
        if (!simulate) {
          details.setTime(end - start);
        }
        details.setPartitionMemberDetailsAfter(
            loadModel.getPartitionedMemberDetails(details.getRegionPath()));
      }

      return Collections.unmodifiableSet(serialOperator.getDetailSet());
    } finally {
      if (lock != null) {
        try {
          lock.unlock();
        } catch (CancelException e) {
          // lock service has been destroyed
        } catch (Exception e) {
          logger.error("Unable to release recovery lock",
              e);
        }
      }
      try {
        if (isRebalance) {
          InternalResourceManager.getResourceObserver().rebalancingFinished(targetRegion);
        } else {
          InternalResourceManager.getResourceObserver().recoveryFinished(targetRegion);
        }
      } catch (Exception e) {
        logger.error("Error in resource observer", e);
      }

      try {
        leaderRegion.getRegionAdvisor().removeMembershipListener(listener);
      } catch (Exception e) {
        logger.error("Error in resource observer", e);
      }
    }
  }
Do the actual rebalance

@return the details of the rebalance.
geode-core/src/main/java/org/apache/geode/internal/cache/partitioned/PartitionedRegionRebalanceOp.java