gt: 	        if (!matchResult.isSuccess()) {
context: /*
   * Native XML Equivalent Transformation Software Development Kit (NxET)
   * Copyright (C) 2004-2005, Telematics Architecture for Play-based Adaptable System,
   * (TAPAS), Department of Telematics, 
   * Norwegian University of Science and Technology (NTNU),
   * O.S.Bragstads Plass 2, N7491, Trondheim, Norway
   *
   * This file is a part of NxET.
   *
   * NxET is a 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 2
   * of the License, or (at your option) any later version.
   *
   * NxET 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, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   * 
   */
  
  package net.sf.xet.nxet.matcher;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Vector;
  import java.util.logging.Logger;
  import java.util.logging.Level;
  import net.sf.xet.nxet.config.Configuration;
  import net.sf.xet.nxet.core.Node;
  import net.sf.xet.nxet.core.Specialization;
  
  /**
   * Matcher matches a body atom with the head atom of a rule.
   * Matcher works in three modes:<br>
   * <br>
   * - Mode "sequential" determistic<br>
   * - Mode "sequantial" non-deterministic<br>
   * - Mode "set"<br>
   * <br>
   * In the set mode, there is only E-variable allowed in the
   * atom. In the sequential mode, more E-variables are allowed.
   * However, determistic means the first E-variable takes more
   * priority. This means that the first E-variable will never
   * take "NULL" value.
   * 
   * @author Paramai Supadulchai
   */
  public class Matcher {
      
      public static final int MODE_SEQ_D = 0;
      public static final int MODE_SEQ_N = 1;
      public static final int MODE_SET = 2;
      public static final int MODE_MAP = 3;
      
      public static String[] MODE = new String[] { 
              "SequenceD",
              "SequenceN",
              "Set",
              "Map"
              };
      
      Configuration config = null;
      boolean debug = false;
      
      Level logLevel = null;
      Logger logger = Logger.getLogger(Matcher.class.getName());
      
      /**
       * Constructor to create a new matcher class with a
       * configuration object and a printstream out. The
       * configuration object determines how the output
       * can be logged. The output printstream is where
       * the matcher class print its logging output.
       * 
       * 
       * @param config
       * @param out
       */
      public Matcher(Configuration config) {
          this.config = config;
      }
      
      /**
       * The only public method here is "match". Head is
       * normally a head atom of the rule or parts
       * of a head atom of the rule. The target is a 
       * target body atom to match with the head atom.
       * 
       * @param head The head atom or the part of the head atom
       * @param target The target atom or the part of the target atom
       * @return Returns the match result
       */
      
      /*
       *  change the rule variables to make the different between the same name variables in 
       *  different rules(for recursive definition)
       *  change by add time to the end of the variable name
       */
      public MatchResult match(Node head, Node target, int mode) {
      	switch (head.getNodeType()) {
          	// Match XML elements
          	case Node.NT_NVAR:
          	case Node.NT_DEFAULT: 
          	    return matchDefault(head, target, mode);
          	// Match string nodes
          	case Node.NT_STRING:
          	    return matchString(head, target);
          	// Match S-variable
          	case Node.NT_SVAR:
          	    return matchSvar(head, target);
          	// Match E1-variable
          	case Node.NT_E1VAR:
          	    return matchE1var(head, target);
          	// Match E-variable
          	case Node.NT_EVAR: 
          	    return matchMultipleEvar(head, target, mode);
          	// Match I-variable
          	case Node.NT_IVAR:
          	    return matchIvar(head, target, mode);
          	default:
          	    System.err.println("Matching with unrecognized node type " + head.nodeTypeText());
          }
          return new MatchResult(false);
      }    
          
      private MatchResult matchAttribute(String attrName, Node head, Node target) {
      	MatchResult matchResult = new MatchResult(true);
          
          try {
              
              // Head's NAME = Target's NAME and both VALUES are S-variables
              if (head.fullName().equals(target.fullName()) && 
                  head.getNodeValue().startsWith("Svar") &&
                  target.getNodeValue().startsWith("Svar")) {
          	    
                  // Add variable-rewriting if the S-variables are not the same
                  if (!head.getNodeValue().equals(target.getNodeValue())) {
                  				matchResult.getSpecialization().addSpecialization(
                                  head.getNodeValue(),
                              	target.getNodeValue()
      	                		);
                  }
                  matchResult.setSuccess(true);
          	// Head's NAME = Target's NAME and head's VALUE is an S-variable    
          	} else if (head.fullName().equals(target.fullName()) && 
          	        head.getNodeValue().startsWith("Svar")) {
          		// The attribute of the head contains S-variable
          	    matchResult.getSpecialization().addSpecialization(
          	            	head.getNodeValue(), 
          	                target.getNodeValue()
          	                );
          	    matchResult.setSuccess(true);
          	// Head's NAME = Target's NAME and target's VALUE is an S-variable
              } else if (head.fullName().equals(target.fullName()) && 
                         target.getNodeValue().startsWith("Svar")) {
              	
                  // The attribute of the head contains S-variable
                  matchResult.getSpecialization().addSpecialization(
                              target.getNodeValue(), 
                              head.getNodeValue()
                              );
                  matchResult.setSuccess(true);
              // Head's NAME = Target's NAME and head's VALUE = target's VALUE 
              } else if (head.fullName().equals(target.fullName()) &&
                         head.getNodeValue().equals(target.getNodeValue())) {
                  
                  matchResult.setSuccess(true);
              } else {
                  
                  // Can quit immediately
                  matchResult.setSuccess(false);
                  return matchResult;
              }
          } catch (Exception e) {
              //e.printStackTrace();
              // Trying to match an attribute with nothing...
              matchResult.setSuccess(false);
              return matchResult;
          }
          return matchResult;
      }
      
      private MatchResult matchDefault(Node head, Node target, int mode) {
          
          MatchResult matchResult = new MatchResult(false);
          MatchResult newMatchResult = new MatchResult(true);
          
          // This node is a "default" XML expression, which includes
          // 1. The target node is an I-variable
          // 2. XML Element
          // 3. N-Variable
          
      	if (target.getNodeType() == Node.NT_IVAR) { 
      	    
      		return match(target, head, mode);
      		
      	} else if ((head.fullName().equals(target.fullName())) || 
  	              ((head.getNodeType() == Node.NT_NVAR) && (target.getNodeType() == Node.NT_DEFAULT)) ||
  	              ((head.getNodeType() == Node.NT_NVAR) && (target.getNodeType() == Node.NT_NVAR))) { 
  	        
  	        matchResult.setSuccess(true);
  	        if (head.getNodeType() == Node.NT_NVAR) {
  	            if ((target.getNodeType() != Node.NT_NVAR) && (!target.isBuiltin())) {
  	                MatchResult attrResult = matchPvar(head, target);
  	                if (attrResult.isSuccess()) {
  	                    matchResult.getSpecialization().addSpecialization(head.fullName(), target.fullName() );
  	                    matchResult.merge(attrResult.getSpecialization());
  	                } else {
  	                    return attrResult;
  	                }
                  // Both are N-variables
  	            } else if (target.getNodeType() == Node.NT_NVAR) {
  	                // Add a variable-rewriting if both variables are not the same
  	                MatchResult attrResult = matchPvar(head, target);
  	                if (attrResult.isSuccess()) {
  	                    matchResult.merge(attrResult.getSpecialization());
  	                    if (!head.fullName().equals(target.fullName())) {
  	                        matchResult.getSpecialization().addSpecialization(head.fullName(), target.fullName());
  		                }
  	                } else {
  	                    return attrResult;
  	                }
  	            }
  	        } else { 
  	        	// Check all attributes
  		        MatchResult attrResult = matchPvar(head, target);
  		        matchResult.merge(attrResult);
  		        
  	        }
  	        
  	        // If the attributes cannot be matched, both nodes also
  	        // cannot be matched. The executor also can quit immediately.
  