Program: 72953
Project: 72953
Buggy source:
/** 
 * Return the dependency between the specified input port and the specified output port.  This is done by checking the guards and actions of all the transitions. When called for the first time since a change in the model structure, this method performs the complete analysis of the FSM and caches the result. Subsequent calls just look up the result.
 * @param input The input port.
 * @param output The output port, or null to update thedependencies (and record equivalence classes) without requiring there to be an output port.
 * @return The dependency between the specified input portand the specified output port, or null if a null output is port specified.
 * @exception IllegalActionException If a guard expression cannot be parsed.
 */
public Dependency getDependency(IOPort input,IOPort output) throws IllegalActionException {
  FSMActor actor=(FSMActor)_actor;
  long workspaceVersion=actor.workspace().getVersion();
  if (_dependencyVersion != workspaceVersion) {
    boolean stateDependentCausality=((BooleanToken)actor.stateDependentCausality.getToken()).booleanValue();
    try {
      actor.workspace().getReadAccess();
      _reverseDependencies=new HashMap<IOPort,Map<IOPort,Dependency>>();
      _forwardDependencies=new HashMap<IOPort,Map<IOPort,Dependency>>();
      _equivalenceClasses=new HashMap<IOPort,Collection<IOPort>>();
      List<IOPort> actorInputs=_actor.inputPortList();
      for (      IOPort actorInput : actorInputs) {
        Set<IOPort> equivalences=new HashSet<IOPort>();
        equivalences.add(actorInput);
        _equivalenceClasses.put(actorInput,equivalences);
      }
      Collection<IOPort> stateEquivalentPorts=new HashSet<IOPort>();
      Collection<Transition> transitions;
      if (!stateDependentCausality) {
        transitions=actor.relationList();
      }
 else {
        State currentState=actor.currentState();
        transitions=currentState.outgoingPort.linkedRelationList();
      }
      for (      Transition transition : transitions) {
        Set<IOPort> outputs=new HashSet<IOPort>();
        List<AbstractActionsAttribute> actions=transition.choiceActionList();
        for (        AbstractActionsAttribute action : actions) {
          List<String> names=action.getDestinationNameList();
          for (          String name : names) {
            NamedObj destination=action.getDestination(name);
            if (destination instanceof IOPort && ((IOPort)destination).isOutput()) {
              outputs.add((IOPort)destination);
            }
          }
        }
        Set<IOPort> inputs=new HashSet<IOPort>();
        String guard=transition.getGuardExpression();
        if (guard.trim().equals("String_Node_Str")) {
          continue;
        }
        PtParser parser=new PtParser();
        try {
          ASTPtRootNode guardParseTree=parser.generateParseTree(guard);
          ParseTreeFreeVariableCollector collector=new ParseTreeFreeVariableCollector();
          Set<String> freeVariables=collector.collectFreeVariables(guardParseTree);
          for (          String freeVariable : freeVariables) {
            IOPort port=actor._getPortForIdentifier(freeVariable);
            if (port != null && port.isInput()) {
              inputs.add(port);
            }
          }
        }
 catch (        IllegalActionException ex) {
          throw new IllegalActionException(actor,ex,"String_Node_Str" + guard + "String_Node_Str");
        }
        if (inputs.isEmpty()) {
          continue;
        }
        stateEquivalentPorts.addAll(inputs);
        for (        IOPort writtenOutput : outputs) {
          Map<IOPort,Dependency> outputMap=_reverseDependencies.get(writtenOutput);
          if (outputMap == null) {
            outputMap=new HashMap<IOPort,Dependency>();
            _reverseDependencies.put(writtenOutput,outputMap);
          }
          for (          IOPort readInput : inputs) {
            outputMap.put(readInput,_defaultDependency.oTimesIdentity());
            Map<IOPort,Dependency> inputMap=_forwardDependencies.get(readInput);
            if (inputMap == null) {
              inputMap=new HashMap<IOPort,Dependency>();
              _forwardDependencies.put(readInput,inputMap);
            }
            inputMap.put(writtenOutput,_defaultDependency.oTimesIdentity());
          }
        }
      }
      Collection<State> states;
      if (!stateDependentCausality) {
        states=actor.entityList();
      }
 else {
        State currentState=actor.currentState();
        states=new HashSet<State>();
        states.add(currentState);
      }
      for (      State state : states) {
        TypedActor[] refinements=state.getRefinement();
        if (refinements != null && refinements.length > 0) {
          for (          TypedActor refinement : refinements) {
            if (!((CompositeActor)refinement).isOpaque()) {
              throw new IllegalActionException(refinement,"String_Node_Str");
            }
            CausalityInterface causality=refinement.getCausalityInterface();
            Collection<IOPort> outputs=refinement.outputPortList();
            for (            IOPort refinementOutput : outputs) {
              Collection<IOPort> inputs=causality.dependentPorts(refinementOutput);
              for (              IOPort refinementInput : inputs) {
                Collection<IOPort> equivalents=causality.equivalentPorts(refinementInput);
                for (                IOPort equivalent : equivalents) {
                  IOPort port=(IOPort)actor.getPort(equivalent.getName());
                  if (port != null) {
                    stateEquivalentPorts.add(port);
                  }
                }
              }
            }
          }
        }
      }
      List<IOPort> inputs=_actor.inputPortList();
      for (      IOPort actorInput : inputs) {
        if (actorInput instanceof ParameterPort) {
          stateEquivalentPorts=inputs;
          break;
        }
      }
      for (      IOPort equivalent : stateEquivalentPorts) {
        _equivalenceClasses.put(equivalent,stateEquivalentPorts);
      }
    }
  finally {
      actor.workspace().doneReading();
    }
    _dependencyVersion=workspaceVersion;
  }
  if (output == null) {
    return null;
  }
  Map<IOPort,Dependency> inputMap=_forwardDependencies.get(input);
  if (inputMap != null) {
    Dependency result=inputMap.get(output);
    if (result != null) {
      return result;
    }
  }
  return _defaultDependency.oPlusIdentity();
}

Fixed version (ground truth):
/** 
 * Return the dependency between the specified input port and the specified output port.  This is done by checking the guards and actions of all the transitions. When called for the first time since a change in the model structure, this method performs the complete analysis of the FSM and caches the result. Subsequent calls just look up the result.
 * @param input The input port.
 * @param output The output port, or null to update thedependencies (and record equivalence classes) without requiring there to be an output port.
 * @return The dependency between the specified input portand the specified output port, or null if a null output is port specified.
 * @exception IllegalActionException If a guard expression cannot be parsed.
 */
public Dependency getDependency(IOPort input,IOPort output) throws IllegalActionException {
  FSMActor actor=(FSMActor)_actor;
  long workspaceVersion=actor.workspace().getVersion();
  if (_dependencyVersion != workspaceVersion) {
    boolean stateDependentCausality=((BooleanToken)actor.stateDependentCausality.getToken()).booleanValue();
    try {
      actor.workspace().getReadAccess();
      _reverseDependencies=new HashMap<IOPort,Map<IOPort,Dependency>>();
      _forwardDependencies=new HashMap<IOPort,Map<IOPort,Dependency>>();
      _equivalenceClasses=new HashMap<IOPort,Collection<IOPort>>();
      List<IOPort> actorInputs=_actor.inputPortList();
      for (      IOPort actorInput : actorInputs) {
        Set<IOPort> equivalences=new HashSet<IOPort>();
        equivalences.add(actorInput);
        _equivalenceClasses.put(actorInput,equivalences);
      }
      Collection<IOPort> stateEquivalentPorts=new HashSet<IOPort>();
      Collection<Transition> transitions;
      if (!stateDependentCausality) {
        transitions=actor.relationList();
      }
 else {
        State currentState=actor.currentState();
        transitions=currentState.outgoingPort.linkedRelationList();
      }
      for (      Transition transition : transitions) {
        Set<IOPort> outputs=new HashSet<IOPort>();
        List<AbstractActionsAttribute> actions=transition.choiceActionList();
        for (        AbstractActionsAttribute action : actions) {
          List<String> names=action.getDestinationNameList();
          for (          String name : names) {
            NamedObj destination=action.getDestination(name);
            if (destination instanceof IOPort && ((IOPort)destination).isOutput()) {
              outputs.add((IOPort)destination);
            }
          }
        }
        Set<IOPort> inputs=new HashSet<IOPort>();
        String guard=transition.getGuardExpression();
        if (guard.trim().equals("String_Node_Str")) {
          continue;
        }
        PtParser parser=new PtParser();
        try {
          ASTPtRootNode guardParseTree=parser.generateParseTree(guard);
          ParseTreeFreeVariableCollector collector=new ParseTreeFreeVariableCollector();
          Set<String> freeVariables=collector.collectFreeVariables(guardParseTree);
          for (          String freeVariable : freeVariables) {
            IOPort port=actor._getPortForIdentifier(freeVariable);
            if (port != null && port.isInput()) {
              inputs.add(port);
            }
          }
        }
 catch (        IllegalActionException ex) {
          throw new IllegalActionException(actor,ex,"String_Node_Str" + guard + "String_Node_Str");
        }
        if (inputs.isEmpty()) {
          continue;
        }
        stateEquivalentPorts.addAll(inputs);
        for (        IOPort writtenOutput : outputs) {
          Map<IOPort,Dependency> outputMap=_reverseDependencies.get(writtenOutput);
          if (outputMap == null) {
            outputMap=new HashMap<IOPort,Dependency>();
            _reverseDependencies.put(writtenOutput,outputMap);
          }
          for (          IOPort readInput : inputs) {
            outputMap.put(readInput,_defaultDependency.oTimesIdentity());
            Map<IOPort,Dependency> inputMap=_forwardDependencies.get(readInput);
            if (inputMap == null) {
              inputMap=new HashMap<IOPort,Dependency>();
              _forwardDependencies.put(readInput,inputMap);
            }
            inputMap.put(writtenOutput,_defaultDependency.oTimesIdentity());
          }
        }
      }
      Collection<State> states;
      if (!stateDependentCausality) {
        states=actor.entityList();
      }
 else {
        State currentState=actor.currentState();
        states=new HashSet<State>();
        states.add(currentState);
      }
      for (      State state : states) {
        TypedActor[] refinements=state.getRefinement();
        if (refinements != null && refinements.length > 0) {
          for (          TypedActor refinement : refinements) {
            CausalityInterface causality=refinement.getCausalityInterface();
            Collection<IOPort> outputs=refinement.outputPortList();
            for (            IOPort refinementOutput : outputs) {
              Collection<IOPort> inputs=causality.dependentPorts(refinementOutput);
              for (              IOPort refinementInput : inputs) {
                Collection<IOPort> equivalents=causality.equivalentPorts(refinementInput);
                for (                IOPort equivalent : equivalents) {
                  IOPort port=(IOPort)actor.getPort(equivalent.getName());
                  if (port != null) {
                    stateEquivalentPorts.add(port);
                  }
                }
              }
            }
          }
        }
      }
      List<IOPort> inputs=_actor.inputPortList();
      for (      IOPort actorInput : inputs) {
        if (actorInput instanceof ParameterPort) {
          stateEquivalentPorts=inputs;
          break;
        }
      }
      for (      IOPort equivalent : stateEquivalentPorts) {
        _equivalenceClasses.put(equivalent,stateEquivalentPorts);
      }
    }
  finally {
      actor.workspace().doneReading();
    }
    _dependencyVersion=workspaceVersion;
  }
  if (output == null) {
    return null;
  }
  Map<IOPort,Dependency> inputMap=_forwardDependencies.get(input);
  if (inputMap != null) {
    Dependency result=inputMap.get(output);
    if (result != null) {
      return result;
    }
  }
  return _defaultDependency.oPlusIdentity();
}