Program: 55898
Project: 55898
Buggy source:
/** 
 * {@inheritDoc}
 */
@Override public void executionStateChanged(final JobID jobID,final ExecutionVertexID vertexID,final ExecutionState newExecutionState,final String optionalMessage){
  final ExecutionGraph eg=this.executionVertex.getExecutionGraph();
  if (newExecutionState == ExecutionState.FINISHED) {
    final ExecutionGroupVertex groupVertex=this.executionVertex.getGroupVertex();
    for (int i=0; i < groupVertex.getCurrentNumberOfGroupMembers(); ++i) {
      final ExecutionVertex groupMember=groupVertex.getGroupMember(i);
      if (groupMember.getExecutionState() == ExecutionState.SCHEDULED) {
        groupMember.setAllocatedResource(this.executionVertex.getAllocatedResource());
        groupMember.updateExecutionState(ExecutionState.READY);
        this.scheduler.deployAssignedVertices(eg);
        return;
      }
    }
    final Iterator<ExecutionVertex> it=new ExecutionGraphIterator(eg,eg.getIndexOfCurrentExecutionStage(),true,true);
    while (it.hasNext()) {
      final ExecutionVertex nextVertex=it.next();
      if (nextVertex.getExecutionState() == ExecutionState.SCHEDULED) {
        if (nextVertex.getAllocatedResource().getInstanceType().equals(this.executionVertex.getAllocatedResource().getInstanceType())) {
          nextVertex.setAllocatedResource(this.executionVertex.getAllocatedResource());
          nextVertex.updateExecutionState(ExecutionState.READY);
          this.scheduler.deployAssignedVertices(eg);
          return;
        }
      }
    }
  }
  if (newExecutionState == ExecutionState.FINISHED || newExecutionState == ExecutionState.CANCELED || newExecutionState == ExecutionState.FAILED) {
    this.scheduler.checkAndReleaseAllocatedResource(eg,this.executionVertex.getAllocatedResource());
  }
  if (newExecutionState == ExecutionState.FAILED) {
    if (this.executionVertex.hasRetriesLeft()) {
      this.executionVertex.updateExecutionState(ExecutionState.SCHEDULED);
    }
  }
}

Fixed version (ground truth):
/** 
 * {@inheritDoc}
 */
@Override public void executionStateChanged(final JobID jobID,final ExecutionVertexID vertexID,final ExecutionState newExecutionState,final String optionalMessage){
  final ExecutionGraph eg=this.executionVertex.getExecutionGraph();
synchronized (eg) {
    if (newExecutionState == ExecutionState.FINISHED) {
      final ExecutionGroupVertex groupVertex=this.executionVertex.getGroupVertex();
      for (int i=0; i < groupVertex.getCurrentNumberOfGroupMembers(); ++i) {
        final ExecutionVertex groupMember=groupVertex.getGroupMember(i);
        if (groupMember.getExecutionState() == ExecutionState.SCHEDULED) {
          groupMember.setAllocatedResource(this.executionVertex.getAllocatedResource());
          groupMember.updateExecutionState(ExecutionState.READY);
          this.scheduler.deployAssignedVertices(eg);
          return;
        }
      }
      final Iterator<ExecutionVertex> it=new ExecutionGraphIterator(eg,eg.getIndexOfCurrentExecutionStage(),true,true);
      while (it.hasNext()) {
        final ExecutionVertex nextVertex=it.next();
        if (nextVertex.getExecutionState() == ExecutionState.SCHEDULED) {
          if (nextVertex.getAllocatedResource().getInstanceType().equals(this.executionVertex.getAllocatedResource().getInstanceType())) {
            nextVertex.setAllocatedResource(this.executionVertex.getAllocatedResource());
            nextVertex.updateExecutionState(ExecutionState.READY);
            this.scheduler.deployAssignedVertices(eg);
            return;
          }
        }
      }
    }
    if (newExecutionState == ExecutionState.FINISHED || newExecutionState == ExecutionState.CANCELED || newExecutionState == ExecutionState.FAILED) {
      this.scheduler.checkAndReleaseAllocatedResource(eg,this.executionVertex.getAllocatedResource());
    }
    if (newExecutionState == ExecutionState.FAILED) {
      if (this.executionVertex.hasRetriesLeft()) {
        this.executionVertex.updateExecutionState(ExecutionState.SCHEDULED);
      }
    }
  }
}