public static <K> void moveBucketByKey(Region<K, ?> region, DistributedMember source,
      DistributedMember destination, K key) {
    PartitionedRegion pr = isPartitionedCheck(region);
    if (pr.isFixedPartitionedRegion()) {
      throw new IllegalStateException("Cannot move data in a fixed partitioned region");
    }
    int bucketId = pr.getKeyInfo(key).getBucketId();
    ExplicitMoveDirector director = new ExplicitMoveDirector(key, bucketId, source, destination,
        region.getCache().getDistributedSystem());
    PartitionedRegionRebalanceOp rebalance =
        new PartitionedRegionRebalanceOp(pr, false, director, true, true);
    rebalance.execute();
  }
Moves the bucket which contains the given key from the source member to the destination member.
The bucket will be fully transferred once this method is complete, if the method does not throw
an exception.
<p>
All keys which exist in the same bucket will also be moved to the new node.
<p>
Any data in colocated regions that are colocated with this key will also be moved.
<p>
This method allows direct control of what data to move. To automatically balance buckets, see
{@link ResourceManager#createRebalanceFactory()}

@param <K> The key type of the region
@param region The region in which to move the bucket. Data in regions colocated with this
       region will also be moved.
@param source A member that is currently hosting this bucket. The bucket is moved off of this
       member.
@param destination A member that is not currently hosting this bucket, but has the partitioned
       region defined. The bucket is moved to this member.
@param key A key which maps to the bucket to move. This key does not actually need to exist in
       the region, but if using a {@link PartitionResolver} the resolver should be able to get
       the routing object from this key to determine the bucket to move.

@throws IllegalStateException if the bucket is not present on the source, if the source or
        destination are not valid members of the system, if the destination already hosts a
        copy of the bucket, or if the bucket does not exist.

@since GemFire 7.1
geode-core/src/main/java/org/apache/geode/cache/partition/PartitionRegionHelper.java