gt:             for (Transition transition : getTransitions()) {
context: /*
   * Copyright (C) 2008-2010 Martin Riesz <riesz.martin at gmail.com>
   * 
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package org.atid.petrinet;
  
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.locks.ReadWriteLock;
  import java.util.concurrent.locks.ReentrantReadWriteLock;
  import org.atid.util.CollectionTools;
  
  /**
   * Marking stores and manages information about tokens.
   *
   * @author Martin Riesz <riesz.martin at gmail.com>
   */
  public class Marking {
  
      protected Map<SimpleActivityNode, Integer> map = new ConcurrentHashMap<SimpleActivityNode, Integer>();
      private PetriNet petriNet;
      private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); //fair
  
      /**
       * Copy constructor.
       *
       * @param marking the marking to be copied.
       */
      public Marking(Marking marking) {
          marking.getLock().readLock().lock();
          try {
              this.map = new ConcurrentHashMap<SimpleActivityNode, Integer>(marking.map);
          } finally {
              marking.getLock().readLock().unlock();
          }
          this.petriNet = marking.petriNet;
      }
  
      /**
       * Creates EMPTY marking of the specified Petri net.
       *
       * @param petriNet Petri net to create marking from.
       */
      public Marking(PetriNet petriNet) {
          this.petriNet = petriNet;
      }
  
      public ReadWriteLock getLock() {
          return lock;
      }
  
      private Set<Transition> getTransitions() {
          return petriNet.getRootCompositeActivity().getTransitionsRecursively();
      }
  
      public PetriNet getPetriNet() {
          return petriNet;
      }
  
      /**
       * Returns the number of tokens based on the specified SimpleActivityNode (SimpleActivity or
   ReferenceSimpleActivity). If specified SimpleActivityNode is ReferenceSimpleActivity, it will return
   number of tokens of its connected SimpleActivity. If the specified ReferenceSimpleActivity
   is not connected to any SimpleActivity, it will return zero. If the resulting
   SimpleActivity is static, number of tokens will be given from initial marking
   instead.
       */
      public int getTokens(SimpleActivityNode simpleActivityNode) {
          SimpleActivityNode simpleActivity = simpleActivityNode.getSimpleActivity();
          if (simpleActivity == null) { // In case of disconnected ReferenceSimpleActivity, we want it to appear with zero tokens. Disconnected ReferenceSimpleActivitys can be found in stored subnets.
              return 0;
          }
  
          Marking marking;
          if (simpleActivity.isStatic()) {
              marking = petriNet.getInitialMarking();
          } else {
              marking = this;
          }
  
          if (marking.map.get(simpleActivity) == null) { // SimpleActivity has zero tokens in the beginning. Not every simpleActivity is in map. Only those previously edited.
              return 0;
          }
  
          return marking.map.get(simpleActivity);
      }
  
      /**
       * Sets the number of tokens to the specified SimpleActivityNode (SimpleActivity or
   ReferenceSimpleActivity). If specified SimpleActivityNode is ReferenceSimpleActivity, it will set
   number of tokens to its connected SimpleActivity. If the specified ReferenceSimpleActivity
   is not connected to any SimpleActivity, it will throw RuntimeException. If the
   specified number of tokens is negative, it will throw RuntimeException.
   If the resulting SimpleActivity is static, number of tokens will be set to initial
   marking instead.
       */
      public void setTokens(SimpleActivityNode simpleActivityNode, int tokens) {
          if (tokens < 0) {
              //throw new RuntimeException("Number of tokens must be non-negative");
              throw new IllegalStateException("Number of tokens must be non-negative");
          }
  
          SimpleActivityNode simpleActivity = simpleActivityNode.getSimpleActivity();
  
          if (simpleActivity == null) {
              //throw new RuntimeException("setTokens() to disconnected ReferenceSimpleActivity");
              throw new IllegalStateException("setTokens() to disconnected ReferenceSimpleActivity");
          }
  
          if (simpleActivityNode.isStatic()) {
              petriNet.getInitialMarking().map.put(simpleActivityNode, tokens);
          } else {
              this.map.put(simpleActivity, tokens);
          }
      }
  
      /**
       * Determines if a transition is enabled in this marking
       *
       * @param transition - transition to be checked
       * @return true if transition is enabled in the marking, otherwise false
       */
      public boolean isEnabled(Transition transition) {
          boolean isEnabled = true;
          lock.readLock().lock();
          try {
              for (Arc arc : transition.getConnectedArcs()) {
                  if (arc.isSimpleActivityToTransition()) {
                      if (arc.getType().equals(Arc.RESET)) {//reset arc is always fireable
                          continue;      //but can be blocked by other arcs 
                      } else {
                          if (!arc.getType().equals(Arc.INHIBITOR)) {
                              if (getTokens(arc.getSimpleActivityNode()) < arc.getMultiplicity()) {  //normal arc
                                  isEnabled = false;
                                  break;
                              }
                          } else {
                              if (getTokens(arc.getSimpleActivityNode()) >= arc.getMultiplicity()) {//inhibitory arc
                                  isEnabled = false;
                                  break;
                              }
                          }
                      }
                  }
              }
          } finally {
              lock.readLock().unlock();
          }
          return isEnabled;
      }
  
      /**
       * Fires a transition in this marking. Changes this marking.
       *
       * @param transition transition to be fired in the marking
       * @return false if the specified transition was not enabled, otherwise true
       */
      public boolean fire(Transition transition) {
          boolean success;
          lock.writeLock().lock();
          try {
              if (isEnabled(transition)) {
                  for (Arc arc : transition.getConnectedArcs()) {
                     if(!(arc.getSource() instanceof Event)){
                          if (arc.isSimpleActivityToTransition()) {
                              int tokens = getTokens(arc.getSimpleActivityNode());
                              if (!arc.getType().equals(Arc.INHIBITOR)) {					//inhibitor arc doesnt consume tokens
                                  if (arc.getType().equals(Arc.RESET)) {						//reset arc consumes them all
                                      setTokens(arc.getSimpleActivityNode(), 0);
                                  } else {
                                      setTokens(arc.getSimpleActivityNode(), tokens - arc.getMultiplicity());
                                  }
                              }
                          } else {
                              int tokens = getTokens(arc.getSimpleActivityNode());
                              setTokens(arc.getSimpleActivityNode(), tokens + arc.getMultiplicity());
                          }
                     } else continue;
                  }
                  success = true;
              } else {
                  success = false;
              }
          } finally {
              lock.writeLock().unlock();
          }
          return success;
      }
  
      public boolean canBeUnfired(Transition transition) {
          boolean canBeUnfired = true;
          lock.readLock().lock();
          try {
              for (Arc arc : transition.getConnectedArcs()) {
                  if(!(arc.getSource() instanceof Event)){
                      if (!arc.isSimpleActivityToTransition()) {
                          if (getTokens(arc.getSimpleActivityNode()) < arc.getMultiplicity()) {
                              canBeUnfired = false;
                              break;
                          }
                      }
                  }
              }
          } finally {
              lock.readLock().unlock();
          }
          return canBeUnfired;
      }
  
      public void undoFire(Transition transition) {
          lock.writeLock().lock();
          try {
              if (canBeUnfired(transition)) {
                  for (Arc arc : transition.getConnectedArcs()) {
                     if(!(arc.getSource() instanceof Event)){
                          if (!arc.isSimpleActivityToTransition()) {
                              int tokens = getTokens(arc.getSimpleActivityNode());
                              setTokens(arc.getSimpleActivityNode(), tokens - arc.getMultiplicity());
                          } else {
                              int tokens = getTokens(arc.getSimpleActivityNode());
                              setTokens(arc.getSimpleActivityNode(), tokens + arc.getMultiplicity());
                          }
                      }
                  }
              }
          } finally {
              lock.writeLock().unlock();
          }
      }
  
      /**
       * Returns a new marking after firing a transition. Original marking is not
       * changed.
       *
       * @param transition transition to be fired
       * @return new marking with fired transition
       */
      public Marking getMarkingAfterFiring(Transition transition) {
          if (!this.isEnabled(transition)) {
              return null;
          }
          Marking newMarking = new Marking(this);
          newMarking.fire(transition);
          return newMarking;
      }
  
      public Set<Transition> getEnabledTransitions(Set<Transition> transitions) {
          Set<Transition> enabledTransitions = new HashSet<Transition>();
          for (Transition transition : transitions) {
              if (isEnabled(transition)) {
                  enabledTransitions.add(transition);
              }
          }
          return enabledTransitions;
      }
  
      /**
       * Returns a set of all enabled transitions
       *
       * @return set of all enabled transitions
       */
      public Set<Transition> getAllEnabledTransitions() {
          Set<Transition> enabledTransitions = new HashSet<Transition>();
          lock.readLock().lock();
          try {
              for (Transition transition : getTransitions()) {
                  if (isEnabled(transition)) {
                      enabledTransitions.add(transition);
                  }
              }
          } finally {
              lock.readLock().unlock();
          }
          return enabledTransitions;
      }
  
      private List<Transition> getAllEnabledTransitionsByList() {
          List<Transition> fireableTransitions = new ArrayList<Transition>();
          lock.readLock().lock();
          try {
  