public static <RestrictionT, PositionT> RestrictionTracker<RestrictionT, PositionT> observe(
      RestrictionTracker<RestrictionT, PositionT> restrictionTracker,
      ClaimObserver<PositionT> claimObserver) {
    if (restrictionTracker instanceof RestrictionTracker.HasProgress) {
      return new RestrictionTrackerObserverWithProgress<>(restrictionTracker, claimObserver);
    } else {
      return new RestrictionTrackerObserver<>(restrictionTracker, claimObserver);
    }
  }
@Test
  public void testObservingClaims() {
    RestrictionTracker<String, String> observedTracker =
        new RestrictionTracker() {

          @Override
          public boolean tryClaim(Object position) {
            return "goodClaim".equals(position);
          }

          @Override
          public Object currentRestriction() {
            throw new UnsupportedOperationException();
          }

          @Override
          public SplitResult<Object> trySplit(double fractionOfRemainder) {
            throw new UnsupportedOperationException();
          }

          @Override
          public void checkDone() throws IllegalStateException {
            throw new UnsupportedOperationException();
          }

          @Override
          public IsBounded isBounded() {
            return IsBounded.BOUNDED;
          }
        };

    List<String> positionsObserved = new ArrayList<>();
    ClaimObserver<String> observer =
        new ClaimObserver<String>() {

          @Override
          public void onClaimed(String position) {
            positionsObserved.add(position);
            assertEquals("goodClaim", position);
          }

          @Override
          public void onClaimFailed(String position) {
            positionsObserved.add(position);
          }
        };

    RestrictionTracker<String, String> observingTracker =
        RestrictionTrackers.observe(observedTracker, observer);
    observingTracker.tryClaim("goodClaim");
    observingTracker.tryClaim("badClaim");

    assertThat(positionsObserved, contains("goodClaim", "badClaim"));
  }