#**### no explicit constructor is created by default
#**#
#**### for model checking support generate copy and hashing operations
#**##if ($utility.isDerivedfrom($class, "de.fujaba.Node") && ! ("de.fujaba.Graph" == $class.getFullClassName()) )
#*   *##set( $return = $imports.addToImports("de.fujaba.Node") )
#*   *##set( $return = $imports.addToImports("de.fujaba.Graph") )
#*   *#   // node create operator
#*   *#   public Node create ()
#*   *#   {
#*   *#      return new ${class}();
#*   *#   }
#*   *#   
#*   *#   // computing level 0 hash code based just on plain attributes
#*   *#   public long attrHash ()
#*   *#   {
#*   *#      long attrHash = this.getAttrHashCash ();
#*   *#      if (attrHash != 0)
#*   *#      {
#*   *#         // use cashed value
#*   *#         return attrHash;
#*   *#      }
#*   *#      
#*   *#      // add type hash
#*   *#      attrHash = 17 + this.getClass().hashCode();
#*   *#      
#*   *#      // add hash for attr values
#*   *#      Object value;
#*   *#      
#*   *##foreach( $attr in $class.iteratorOfAllAttrs() )
#*      *##if ( ! $attr.isStatic() && ! $attr.isTransient() )
#*         *##set( $methodPrefix = "get" )
#*         *##if( $attr.getAttrType().getName() == "Boolean" )
#*            *##set( $methodPrefix = "is" )
#*         *##end
#*         *##set( $methodSuffix = $utility.upFirstChar($attr.name) )
#*         *#      value = this.$methodPrefix${methodSuffix}();
#*         *#      if (value != null)
#*         *#      {
#*         *#         attrHash = attrHash * 37 + value.hashCode();
#*         *#      }
#*         *#
#*      *##end
#*   *##end    
#*   *#      this.setAttrHashCash(attrHash);
#*   *#      return attrHash;
#*   *#   }
#*   *#
#*   *##if ( ! $utility.isDerivedfrom($class, "de.fujaba.Graph"))   
#*      *#   // computing level 1 hash code based on attr hash of all neighbors
#*      *#   public long fullHash ()
#*      *#   {
#*      *#      long fullHash = this.getFullHashCash ();
#*      *#      if (fullHash != 0)
#*      *#      {
#*      *#         // use cashed value
#*      *#         return fullHash;
#*      *#      }
#*      *#   
#*      *#      // start with the attr based hash
#*      *#      fullHash = this.attrHash();
#*      *#
#*      *#      // add attr hash values via links  
#*      *#      Node neighbor;
#*      *#      
#*      *##foreach( $role in $class.iteratorOfAllRoles() )
#*         *##set( $partnerRole = $role.getPartnerRole() )
#*         *##set( $partnerClass = $partnerRole.getTarget() )
#*         *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*         *##if( $partnerRole.hasKeyInStereotypes("usage") )
#*            *##if( $partnerRole.getCard() == "0..1" )
#*               *#      // role $partnerRole.getName() $partnerRole.getCard()
#*               *#      neighbor = this.get${methodSuffix}();
#*               *#      if (neighbor != null)
#*               *#      {
#*               *#         fullHash = fullHash * 37 + $partnerRole.getName().hashCode() * neighbor.attrHash();
#*               *#      }
#*               *#      
#*            *##else
#*               *#      // role $partnerRole.getName() $partnerRole.getCard()
#*               *#      for (java.util.Iterator iter = this.iteratorOf$methodSuffix(); iter.hasNext();)
#*               *#      {
#*               *#         neighbor = (Node) iter.next();
#*               *#         fullHash = fullHash + $partnerRole.getName().hashCode() * neighbor.attrHash();
#*               *#      }
#*               *#      
#*            *##end
#*         *##end      
#*      *##end      
#*      *#      this.setFullHashCash(fullHash);
#*      *#      return fullHash;
#*      *#   }
#*      *#      
#*   *##end
#*   *#   // hierarchical graphs copy operator
#*   *#   public void copyTo (Graph clone )
#*   *#   {
#*   *#      // provide clone object (perhabs already partially created)
#*   *#      $class myClone = ($class) clone.createOrGetCopyOf(this);
#*   *#      
#*   *#      // copy attr values
#*   *##foreach( $attr in $class.iteratorOfAllAttrs() )
#*      *##if ( ! $attr.isStatic() && ! $attr.isTransient() )
#*         *##set( $methodPrefix = "get" )
#*         *##if( $attr.getAttrType().getName() == "Boolean" )
#*            *##set( $methodPrefix = "is" )
#*         *##end
#*         *##set( $methodSuffix = $utility.upFirstChar($attr.name) )
#*         *#      myClone.set${methodSuffix}( this.$methodPrefix${methodSuffix}());  
#*      *##end
#*   *##end    
#*   *#
#*   *#      // copy links  
#*   *#      Node neighbor;
#*   *#      Node neighborClone;
#*   *#      
#*   *##foreach( $role in $class.iteratorOfAllRoles() )
#*      *##set( $partnerRole = $role.getPartnerRole() )
#*      *##set( $partnerClass = $partnerRole.getTarget() )
#*      *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*      *##if( $role.getRevLeftRole() && $partnerRole.hasKeyInStereotypes("usage") )
#*         *##if( $partnerRole.getCard() == "0..1" )
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      neighbor = this.get${methodSuffix}();
#*            *#      neighborClone = clone.createOrGetCopyOf(neighbor);
#*            *#      myClone.set${methodSuffix}(($partnerClass)neighborClone);
#*            *#      
#*         *##else
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      for (java.util.Iterator iter = this.iteratorOf$methodSuffix(); iter.hasNext();)
#*            *#      {
#*            *#         neighbor = (Node) iter.next();
#*            *#         neighborClone = clone.createOrGetCopyOf(neighbor);
#*            *#         myClone.addTo$methodSuffix(($partnerClass) neighborClone);
#*            *#      }
#*            *#      
#*         *##end
#*      *##end      
#*   *##end      
#*   *#   }
#*   *#
#*   *#
#*   *##set( $return = $imports.addToImports("de.fujaba.TodoList") )
#*   *#   // method for simple isomorphism checking
#*   *#   public boolean isIsomorphicTo (Node other , TodoList todoList , TodoList rightCandidates )
#*   *#   {
#*   *#      // equal types?
#*   *#      if (this.getClass() != other.getClass()) return false;
#*   *#
#*   *#      $class right = ($class) other;
#*   *#      
#*   *#      // check attr fields
#*   *##foreach( $attr in $class.iteratorOfAllAttrs() )
#*      *##if ( ! $attr.isStatic() && ! $attr.isTransient() )
#*         *##set( $methodPrefix = "get" )
#*         *##if( $attr.getAttrType().getName() == "Boolean" )
#*            *##set( $methodPrefix = "is" )
#*         *##end
#*         *##set( $methodSuffix = $utility.upFirstChar($attr.name) )
#*         *#      if (this.$methodPrefix${methodSuffix}() != right.$methodPrefix${methodSuffix}()) return false;  
#*         *#
#*      *##end
#*   *##end    
#*   *#      // check to-one links  
#*   *#      Node leftNeighbor;
#*   *#      Node rightNeighbor;
#*   *#            
#*   *##foreach( $role in $class.iteratorOfAllRoles() )
#*      *##set( $partnerRole = $role.getPartnerRole() )
#*      *##set( $partnerClass = $partnerRole.getTarget() )
#*      *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*      *##if( $partnerRole.hasKeyInStereotypes("usage") )
#*         *##if( $partnerRole.getCard() == "0..1" )
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      leftNeighbor = this.get${methodSuffix}();
#*            *#      rightNeighbor = right.get${methodSuffix}();
#*            *#      
#*            *#      if (leftNeighbor == null || rightNeighbor == null)
#*            *#      {
#*            *#         if (leftNeighbor != rightNeighbor)
#*            *#         {
#*            *#            return false;
#*            *#         }
#*            *#      }
#*            *#      else
#*            *#      {
#*            *#         // we have neighbors, do they match?
#*            *#         if (todoList.hasInMap(leftNeighbor, rightNeighbor))
#*            *#         {
#*            *#            // yes, they map from previous attempts
#*            *#         }
#*            *#         else if (leftNeighbor.checkMapping(rightNeighbor, todoList, rightCandidates))
#*            *#         {
#*            *#            // fine, go on with the next neighbor
#*            *#         }
#*            *#         else
#*            *#         {
#*            *#            // not a match
#*            *#            return false;
#*            *#         }    
#*            *#      }
#*            *#      
#*         *##end
#*      *##end      
#*   *##end      
#*   *##set( $return = $imports.addToImports("java.util.Collection") )
#*   *#      // check to-many links  
#*   *#      Collection leftCollection;
#*   *#      Collection rightCollection;
#*   *#            
#*   *##foreach( $role in $class.iteratorOfAllRoles() )
#*      *##set( $partnerRole = $role.getPartnerRole() )
#*      *##set( $partnerClass = $partnerRole.getTarget() )
#*      *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*      *##if( $partnerRole.hasKeyInStereotypes("usage") )
#*         *##if( $partnerRole.getCard() != "0..1" )
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      leftCollection = this.get${methodSuffix}();
#*            *#      rightCollection = right.get${methodSuffix}();
#*            *#      
#*            *#      if (checkMapping(leftCollection, rightCollection, todoList, rightCandidates))
#*            *#      {
#*            *#         // it fits, go on with next assoc
#*            *#      }
#*            *#      else
#*            *#      {
#*            *#         return false;
#*            *#      }
#*            *#      
#*         *##end
#*      *##end      
#*   *##end      
#*   *#      
#*   *#      return true;
#*   *#   }
#*   *#
#*   *#   
#*   *##set( $return = $imports.addToImports("de.fujaba.Mapping") )
#*   *#   // compare this node with potential partner, return true, iff they are equivalent 
#*   *#   public boolean validateMapping (Mapping mapping , Node _right )
#*   *#   {
#*   *#      // equal types?
#*   *#      if (this.getClass() != _right.getClass()) return false;
#*   *#      
#*   *#      $class right = ($class) _right;
#*   *#      
#*   *#      // check attr fields
#*   *##foreach( $attr in $class.iteratorOfAllAttrs() )
#*      *##if ( ! $attr.isStatic() && ! $attr.isTransient() )
#*         *##set( $methodPrefix = "get" )
#*         *##if( $attr.getAttrType().getName() == "Boolean" )
#*            *##set( $methodPrefix = "is" )
#*         *##end
#*         *##set( $methodSuffix = $utility.upFirstChar($attr.name) )
#*         *#      if (this.$methodPrefix${methodSuffix}() != right.$methodPrefix${methodSuffix}()) return false;  
#*         *#
#*      *##end
#*   *##end    
#*   *#      
#*   *#      // check to-one links  
#*   *#      Node leftNeighbor;
#*   *#      Node rightNeighbor;
#*   *#            
#*   *##foreach( $role in $class.iteratorOfAllRoles() )
#*      *##set( $partnerRole = $role.getPartnerRole() )
#*      *##set( $partnerClass = $partnerRole.getTarget() )
#*      *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*      *##if( $partnerRole.hasKeyInStereotypes("usage") )
#*         *##if( $partnerRole.getCard() == "0..1" )
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      leftNeighbor = this.get${methodSuffix}();
#*            *#      rightNeighbor = right.get${methodSuffix}();
#*            *#      
#*            *#      if (leftNeighbor == null || rightNeighbor == null)
#*            *#      {
#*            *#         if (leftNeighbor != rightNeighbor)
#*            *#         {
#*            *#            return false;
#*            *#         }
#*            *#      }
#*            *#      else
#*            *#      {
#*            *#         if ( ! validateNeighborMapping(leftNeighbor, rightNeighbor))
#*            *#         {
#*            *#            return false;
#*            *#         }      
#*            *#      }
#*            *#      
#*         *##end
#*      *##end      
#*   *##end      
#*   *##set( $return = $imports.addToImports("java.util.Collection") )
#*   *#      // check to-many links  
#*   *#      Collection leftCollection;
#*   *#      Collection rightCollection;
#*   *#            
#*   *##foreach( $role in $class.iteratorOfAllRoles() )
#*      *##set( $partnerRole = $role.getPartnerRole() )
#*      *##set( $partnerClass = $partnerRole.getTarget() )
#*      *##set( $methodSuffix = $utility.upFirstChar($partnerRole.name) )
#*      *##if( $partnerRole.hasKeyInStereotypes("usage") )
#*         *##if( $partnerRole.getCard() != "0..1" )
#*            *#      // role $partnerRole.getName() $partnerRole.getCard()
#*            *#      leftCollection = this.get${methodSuffix}();
#*            *#      rightCollection = right.get${methodSuffix}();
#*            *#      
#*            *#      if ( ! mapping.validateToManyField(this, right, leftCollection, rightCollection))
#*            *#      {
#*            *#         return false;
#*            *#      }
#*            *#      
#*         *##end
#*      *##end      
#*   *##end      
#*   *#
#*   *#      return true;
#*   *#   }
#*   *#
#*   *#   // helper method
#*   *#   private boolean validateNeighborMapping(Node leftNeighbor, Node rightNeighbor)
#*   *#   {
#*   *#      boolean foundCount2Mapping;
#*   *#      Mapping gt2Mapping;
#*   *#      
#*   *#      foundCount2Mapping = false;
#*   *#      gt2Mapping = null;
#*   *#      for (java.util.Iterator iter = leftNeighbor.iteratorOfLeftMappings(); ! foundCount2Mapping && iter.hasNext();)
#*   *#      {
#*   *#         Mapping neighborMapping = (Mapping) iter.next();
#*   *#         if (neighborMapping.hasInRightNodes(rightNeighbor))
#*   *#         {
#*   *#            int count = neighborMapping.getCount();
#*   *#            if (count == 2)
#*   *#            {
#*   *#               foundCount2Mapping = true;
#*   *#            }
#*   *#            else if (count > 2 && gt2Mapping == null)
#*   *#            {
#*   *#               gt2Mapping = neighborMapping;
#*   *#            }
#*   *#         }
#*   *#      }
#*   *#      
#*   *#      if ( ! foundCount2Mapping)
#*   *#      {
#*   *#         if (gt2Mapping != null)
#*   *#         {
#*   *#            gt2Mapping.splitMapping(leftNeighbor, rightNeighbor);
#*   *#         }
#*   *#         else
#*   *#         {
#*   *#            return false;
#*   *#         }
#*   *#      }
#*   *#      
#*   *#      return true;
#*   *#   }
#*   *#
#*   *#      
#*   *#    
#**##end