boolean isEquivalentInstance(
     @Nonnull Object invocationInstance, @Nonnull Object invokedInstance) {
   return invocationInstance == invokedInstance
       || invocationInstance == replacementMap.get(invokedInstance)
       || invocationInstance == instanceMap.get(invokedInstance)
       || invokedInstance == instanceMap.get(invocationInstance)
       || TestRun.getExecutingTest()
           .isInvokedInstanceEquivalentToCapturedInstance(invocationInstance, invokedInstance);
 }
  private void registerReplacementInstanceIfApplicable(
      @Nullable Object mock, @Nonnull ExpectedInvocation invocation) {
    Object replacementInstance = invocation.replacementInstance;

    if (replacementInstance != null && replacementInstance != invocation.instance) {
      replacementMap.put(mock, replacementInstance);
    }
  }
  boolean areInDifferentEquivalenceSets(@Nonnull Object mock1, @Nonnull Object mock2) {
    if (mock1 == mock2 || instanceMap.isEmpty()) {
      return false;
    }

    Object mock1Equivalent = instanceMap.get(mock1);
    Object mock2Equivalent = instanceMap.get(mock2);

    if (mock1Equivalent == mock2 || mock2Equivalent == mock1) {
      return false;
    }

    if (mock1Equivalent != null && mock2Equivalent != null) {
      return true;
    }

    return instanceMapHasMocksInSeparateEntries(mock1, mock2);
  }
 @Override
 void markAsCoveredIfNoUnreadValuesAreLeft() {
   for (Boolean withUnreadValue : testIdsToAssignments.values()) {
     if (withUnreadValue == null) {
       covered = true;
       break;
     }
   }
 }
  private boolean instanceMapHasMocksInSeparateEntries(
      @Nonnull Object mock1, @Nonnull Object mock2) {
    boolean found1 = false;
    boolean found2 = false;

    for (Entry<Object, Object> entry : instanceMap.entrySet()) {
      if (!found1 && isInMapEntry(entry, mock1)) {
        found1 = true;
      }

      if (!found2 && isInMapEntry(entry, mock2)) {
        found2 = true;
      }

      if (found1 && found2) {
        return true;
      }
    }

    return false;
  }
 @Nullable
 Object getReplacementInstanceForMethodInvocation(
     @Nonnull Object invokedInstance, @Nonnull String methodNameAndDesc) {
   return methodNameAndDesc.charAt(0) == '<' ? null : replacementMap.get(invokedInstance);
 }
 void registerRead() {
   int testId = TestRun.getTestId();
   testIdsToAssignments.put(testId, null);
   readCount++;
 }
 void registerAssignment() {
   int testId = TestRun.getTestId();
   testIdsToAssignments.put(testId, Boolean.TRUE);
   writeCount++;
 }