Program: 174045
Project: 174045
Buggy source:
/** 
 * Completes the tracking by updating the dependencies on the observer to match the observables that were observed during tracking. The _tracker is added or removed as an observer on an observable if the observer is a new dependency or previously was a dependency but no longer is, respectively.
 */
void completeTracking(){
  if (null == _tracker) {
    invariant(() -> null == _observables,() -> "String_Node_Str" + getName() + "String_Node_Str"+ "String_Node_Str");
    return;
  }
  _tracker.invariantDependenciesUnique("String_Node_Str");
  invariant(() -> _tracker.getState() != ObserverState.INACTIVE || _tracker.isDisposed(),() -> "String_Node_Str" + getName() + "String_Node_Str"+ "String_Node_Str");
  ObserverState newDerivationState=ObserverState.UP_TO_DATE;
  boolean dependenciesChanged=false;
  int currentIndex=0;
  if (null != _observables && !_tracker.isDisposed()) {
    final int size=_observables.size();
    for (int i=0; i < size; i++) {
      final Observable observable=_observables.get(i);
      if (!observable.isInCurrentTracking() && !observable.isDisposed()) {
        observable.putInCurrentTracking();
        if (i != currentIndex) {
          _observables.set(currentIndex,observable);
        }
        currentIndex++;
        if (observable.hasOwner()) {
          final Observer owner=observable.getOwner();
          final ObserverState dependenciesState=owner.getState();
          if (dependenciesState == ObserverState.STALE) {
            newDerivationState=dependenciesState;
          }
        }
      }
    }
  }
  final ArrayList<Observable<?>> dependencies=_tracker.getDependencies();
  for (int i=dependencies.size() - 1; i >= 0; i--) {
    final Observable observable=dependencies.get(i);
    if (!observable.isInCurrentTracking()) {
      observable.removeObserver(_tracker);
      dependenciesChanged=true;
    }
 else {
      observable.removeFromCurrentTracking();
    }
  }
  if (!_tracker.isDisposed() && ObserverState.UP_TO_DATE != newDerivationState) {
    _tracker.setState(newDerivationState);
  }
  if (null != _observables) {
    for (int i=currentIndex - 1; i >= 0; i--) {
      final Observable observable=_observables.get(i);
      if (observable.isInCurrentTracking()) {
        observable.removeFromCurrentTracking();
        observable.addObserver(_tracker);
        dependenciesChanged=true;
        final ObserverState leastStaleObserverState=observable.getLeastStaleObserverState();
        if (leastStaleObserverState == ObserverState.INACTIVE || leastStaleObserverState.ordinal() > newDerivationState.ordinal()) {
          fail(() -> "String_Node_Str" + getName() + "String_Node_Str"+ observable.getName()+ "String_Node_Str");
          observable.setLeastStaleObserverState(newDerivationState);
        }
      }
    }
  }
  if (null != _observables) {
    for (int i=_observables.size() - 1; i >= currentIndex; i--) {
      _observables.remove(i);
    }
    if (dependenciesChanged) {
      _tracker.replaceDependencies(_observables);
    }
  }
 else {
    if (dependenciesChanged) {
      _tracker.replaceDependencies(new ArrayList<>());
    }
  }
  if (_disposeTracker) {
    _tracker.setState(ObserverState.INACTIVE);
  }
 else   if (_tracker.isDerivation() && !_tracker.getDerivedValue().hasObservers()) {
    queueForDeactivation(_tracker.getDerivedValue());
  }
  if (BrainCheckConfig.checkInvariants()) {
    if (null != _observables) {
      for (      final Observable observable : _observables) {
        observable.invariantLeastStaleObserverState();
        observable.invariantObserversLinked();
      }
    }
    _tracker.invariantDependenciesUnique("String_Node_Str");
    _tracker.invariantDependenciesBackLink("String_Node_Str");
    _tracker.invariantDependenciesNotDisposed();
  }
}

Fixed version (ground truth):
/** 
 * Completes the tracking by updating the dependencies on the observer to match the observables that were observed during tracking. The _tracker is added or removed as an observer on an observable if the observer is a new dependency or previously was a dependency but no longer is, respectively.
 */
void completeTracking(){
  if (null == _tracker) {
    invariant(() -> null == _observables,() -> "String_Node_Str" + getName() + "String_Node_Str"+ "String_Node_Str");
    return;
  }
  _tracker.invariantDependenciesUnique("String_Node_Str");
  invariant(() -> _tracker.getState() != ObserverState.INACTIVE || _tracker.isDisposed(),() -> "String_Node_Str" + getName() + "String_Node_Str"+ "String_Node_Str");
  ObserverState newDerivationState=ObserverState.UP_TO_DATE;
  boolean dependenciesChanged=false;
  int currentIndex=0;
  if (null != _observables && !_tracker.isDisposed()) {
    final int size=_observables.size();
    for (int i=0; i < size; i++) {
      final Observable observable=_observables.get(i);
      if (!observable.isInCurrentTracking() && !observable.isDisposed()) {
        observable.putInCurrentTracking();
        if (i != currentIndex) {
          _observables.set(currentIndex,observable);
        }
        currentIndex++;
        if (observable.hasOwner()) {
          final Observer owner=observable.getOwner();
          final ObserverState dependenciesState=owner.getState();
          if (dependenciesState == ObserverState.STALE) {
            newDerivationState=dependenciesState;
          }
        }
      }
    }
  }
  final ArrayList<Observable<?>> dependencies=_tracker.getDependencies();
  for (int i=dependencies.size() - 1; i >= 0; i--) {
    final Observable observable=dependencies.get(i);
    if (!observable.isInCurrentTracking()) {
      observable.removeObserver(_tracker);
      dependenciesChanged=true;
    }
 else {
      observable.removeFromCurrentTracking();
    }
  }
  if (!_tracker.isDisposed() && ObserverState.UP_TO_DATE != newDerivationState) {
    if (_tracker.getState().ordinal() < newDerivationState.ordinal()) {
      _tracker.setState(newDerivationState,false);
    }
  }
  if (null != _observables) {
    for (int i=currentIndex - 1; i >= 0; i--) {
      final Observable observable=_observables.get(i);
      if (observable.isInCurrentTracking()) {
        observable.removeFromCurrentTracking();
        observable.addObserver(_tracker);
        dependenciesChanged=true;
        final ObserverState leastStaleObserverState=observable.getLeastStaleObserverState();
        if (leastStaleObserverState == ObserverState.INACTIVE || leastStaleObserverState.ordinal() > newDerivationState.ordinal()) {
          fail(() -> "String_Node_Str" + getName() + "String_Node_Str"+ observable.getName()+ "String_Node_Str");
          observable.setLeastStaleObserverState(newDerivationState);
        }
      }
    }
  }
  if (null != _observables) {
    for (int i=_observables.size() - 1; i >= currentIndex; i--) {
      _observables.remove(i);
    }
    if (dependenciesChanged) {
      _tracker.replaceDependencies(_observables);
    }
  }
 else {
    if (dependenciesChanged) {
      _tracker.replaceDependencies(new ArrayList<>());
    }
  }
  if (_disposeTracker) {
    _tracker.setState(ObserverState.INACTIVE);
  }
 else   if (_tracker.isDerivation() && !_tracker.getDerivedValue().hasObservers()) {
    queueForDeactivation(_tracker.getDerivedValue());
  }
  if (BrainCheckConfig.checkInvariants()) {
    if (null != _observables) {
      for (      final Observable observable : _observables) {
        observable.invariantLeastStaleObserverState();
        observable.invariantObserversLinked();
      }
    }
    _tracker.invariantDependenciesUnique("String_Node_Str");
    _tracker.invariantDependenciesBackLink("String_Node_Str");
    _tracker.invariantDependenciesNotDisposed();
  }
}