/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

//Source file: D:/Projects/Isolde/parser/Parser.java

/* Revision History

   Added Wordnet support, assuming that the user has wordnet installed 
   on their computer - brasser, july2001

   Added facilities for the prepositionPosition for the contextual type.
   kvlinden, 23jan2002

   */

package parser.FSParser;

import java.util.*;
import domainModel.*;
import utility.*;
import taskModellingTool.*;
import javax.swing.tree.*;
import org.omg.CORBA.StringHolder;

import jwnl.data.*;
import jwnl.data.list.pointer_target.PointerTargetList;
import jwnl.data.list.pointer_target.PointerTargetTree;
import jwnl.data.relationship.*;
import jwnl.dictionary.DictionaryDatabase;
import jwnl.dictionary.hashtable.HashtableBackedDictionary;
import jwnl.dictionary.flatfile.FileBackedDictionary;
import java.util.Hashtable;
import java.io.RandomAccessFile;

/**
The parser can run any finite-state grammar similar to the ones shown in the current 
grammar files.  We chose a finite-state mechanism because it is simple and sufficient
for the task.  We will need grammars for the simple default case (3-word expressions -
agent-process-patient) as well as an action grammar (see action.grammar) and a state
grammar.

Notes: 
   - The code assumes that the "process" constituent is the verb and that all
     others are case-roll fillers of some sort.

   - The parser has to know about the guards on the transitions - these can't be 
     declarative.  We'll assume noun/verb/preposition/word.

   - The parser needs an accessor to return the constituents table numbers to the GUI 
     interface so it can set the heads and constituent boundaries properly.
*/
public class Parser {
  private Grammar _grammar;          // the finite-state grammar we are currently using
  public DmManager _dmManager;       // pointer to the domain model
  private Vector _constituentTables; // list of constituent tables
  //private Hashtable name2Index;      // maps from constituent name to constituent table index
  private String _cnlString;         // the string being parsed
  
  private GenericComponent _gc = null;   // shijian 20-4-2001
  private DictionaryDatabase db;     // access to wordnet. brasser 2001-6-6
  private ConstituentTable _currentTable;  //the constituent table currently being used //brasser 2001-7-12
  private String _currentToken;         // the current word of the input, used as a return value

  private Vector specialDelimiters;  // a list of paired delimiters, e.g., {}, (), "", []

  public Parser(DmManager inDmManager, String filename)
  {
    // Set up the grammar - parse() will initialize the grammar.
    _grammar = new Grammar(filename);
    _dmManager = inDmManager;
    db = new FileBackedDictionary(); //brasser 2001-6-6

    // Load a set of special delimiter pairs.  There should always be an even number
    // because you must add the start and stop delimiter.  Add more if you'd like, but 
    // make sure to update the grammar guards so that they can be automatically
    // recognized - kvlinden, 10jan2002
    specialDelimiters = new Vector();
    specialDelimiters.add("(");
    specialDelimiters.add(")");
    specialDelimiters.add("[");
    specialDelimiters.add("]");
    specialDelimiters.add("{");
    specialDelimiters.add("}");
    specialDelimiters.add("\"");
    specialDelimiters.add("\"");

    // create the list of constituent tables, initially with a single table //brasser 2001-7-12
    _constituentTables = new Vector();
    _currentTable = new ConstituentTable(_dmManager, _grammar);
    //_constituentTables.add(_currentTable);

  }


  //utility function for inserting a space in front of punctuation
  //used in parse function to add spaces in front of commas
  //code from java.sun.com
  //brasser 2001-7-19
  public static String replaceString (String oldString, String newString, String inputString){
    String outputString = "";
    int i;
    for (i=0; i<inputString.length(); i++) {
      if (!(inputString.regionMatches (true, i, oldString, 0, oldString.length())))
	outputString += inputString.charAt(i);
      else {
	outputString += newString;
	i += oldString.length()-1;
      }
    }
    return outputString;
  }

  /**
    Takes a string, parses it, and creates DM concepts/instances as appropriate.
    It returns a boolean indicating if the parse worked or not.

    It will include its own view (i.e., the parser interface).

    For now, it will "reparse" by clearing the previous parse and starting from scratch.
    It will set all the constituent starts to length(parseString).
    initialize the grammar
    tokenize the input string
    set currentPosition and workingBufferStart = 0
    gets list of guards, picks one, transitions the grammar - if none works,
    do an unknown transition.
    gets list of required operations and does them.
    @roseuid 395A007A02AB
    */
  public boolean parse(String cnlString)
  {
    //brasser 2001-7-19
    //organizes the string to be ready for use with String Tokenizer (spaces in front of punctuation, and all lowercase)
    //we may want to do the lowercase in a different place if we start using capitalization in some special way
    cnlString = replaceString(".\"", "\".", cnlString);
    cnlString = replaceString(",", " ,", cnlString);
    cnlString = replaceString(".", " .", cnlString);
    cnlString = replaceString("  ", " ", cnlString); //these can give us trouble
    //we may want to add spaces elsewhere in the future (such as at _"_ or _(_ )
    cnlString = cnlString.toLowerCase();
    _cnlString = cnlString;

    // Some working variables for the parser
    int currentPosition;         // a cnlString index of the current parser position
    int workingBufferStart;      // an index to the beginning of the current constituent
    StringTokenizer tokenizedInput; // tokenized list of input words to parse
    Vector possibleTransitions;  // a vector of outgoing links from the current state
    String currentToken;         // the current word of the input
    String previousToken = null; // the previous word of the inpput
    String currentTransition;    // the chosen transition
    String nounReference;        // the name of the DM object instance found by isNoun
    String verbReference;        // the name of the DM concept instance found by isVerb
    String adjReference;         // the name of the DM ? instance found by isAdjective
    String pronReference;        // the name of the DM ? instance found by isPronoun
    String artReference;		 // the name of the DM ? instance found by isArticle
    Vector currentOperations;    // operations to perform as specified by the grammar
    String headReference;        // name of the DM thing referenced by the head
    String previousState;        // name of the previous state in the parse
    String previousState2;
    int headLength;              // number of words of the constituent head
    StringBuffer tokenHolder;    // a utility for string reference parameters

    // Initialize the grammar, the constituent table, the context variables
    //     and the tokenized input.
    _grammar.initialize();
    _constituentTables.clear(); //brasser 2001-7-13
    _currentTable.setRole("action"); //brasser 2001-7-18
    for (int i = 0; i < _currentTable.getConstituents().size(); i++) //brasser 2001-7-12
      ((Constituent)(_currentTable.getConstituents().elementAt(i))).initialize();
    currentPosition = 0;
    workingBufferStart = 0;
    if (cnlString.equals(""))
      return _grammar.inTerminalState();
    tokenizedInput = new StringTokenizer(cnlString);
    
    /*    // test code for the tokenizer
	  StringTokenizer test = new StringTokenizer(cnlString);
	  while (test.hasMoreTokens())
	  System.out.println(test.nextToken());
	  */

    //2001-8-13
    //shijian
    // mark the second word as "verb", if it is not
    // recognized word and marked the third word as "noun"
    // if it is not recognised
    boolean thereIsNoun= false;
    boolean thereIsVerb= false; 
 	
    // Loop through the words of the input to drive the grammar.
    while (tokenizedInput.hasMoreTokens()) {
      currentToken = tokenizedInput.nextToken();

      // Now, combine sequences of tokens where the first token starts with a 
      // known delimiter, e.g., "(", and the last token ends with a matching one,
      // e.g., ")".  We want to combine these and treat them as literals 
      // - kvlinden, 10jan2002
      String startDelimiter, stopDelimiter;
      for (int i = 0; i < specialDelimiters.size(); i += 2) {
	startDelimiter = (String)specialDelimiters.elementAt(i);
	stopDelimiter = (String)specialDelimiters.elementAt(i+1);
	if (currentToken.startsWith(startDelimiter) && 
	    !currentToken.endsWith(stopDelimiter))
	  for (;;) {
	    if (tokenizedInput.hasMoreTokens())
	      currentToken += ' ' + tokenizedInput.nextToken();
	    else {
	      // This output is not that useful, and gets printed prematurely during
	      // interactive parsing, so I've removed it - kvlinden, 14jan2002
	      //System.err.println("Unmatched " + startDelimiter + " in input string: " + 
	      //				 currentToken + " looking for " + stopDelimiter);
	      break;
	    }
	    if (currentToken.endsWith(stopDelimiter))
	      break;
	  }
      }

      possibleTransitions = _grammar.possibleTransitions();
      currentTransition = "unknown";   // default
      headReference = "";              // default
      headLength = 0;                  // default

      // determine the POS of the input (there could be more than one of them I suppose)
      //check if the token is punctuation -- jwnl doesn't handle the lookup well
      //brasser 2001-7-

      // First, if the token has any special delimiters, then skip this step.
      // This indicates that it is a literal string of some sort and we shouldn't
      // try to match it with the DM or WordNet
      // - kvlinden, 10Jan2002
      boolean treatAsLiteral = false;
      for (int i = 0; i < specialDelimiters.size(); i++)
	if (currentToken.indexOf((String)specialDelimiters.elementAt(i)) != -1)
	  treatAsLiteral = true;

      if (!isPunctuation(currentToken) && !treatAsLiteral) {

		// Check if current token is a noun (i.e., a known DM object or wordNet noun).
		//System.out.println("isNoun(" + currentToken + ")");
		artReference = isArticle(currentToken);
		if (artReference.equals("")){

			nounReference = isNoun(currentToken, tokenizedInput, 
					       cnlString.substring(currentPosition, cnlString.length()));
			// The reference may be a multi-word match.  isNoun() will automatically
			// eat the next token(s) in tokenizedInput.  Because currentToken must be changed 
			// as well, we must modify it here by grabbing the returned value stored in 
			// _currentToken.  This would have been easier if Java had supported String 
			// reference parameters;  it doesn't, so we had to use a global variable.
			// - kvlinden, 14jan2002
			if (!nounReference.equals("")) {
			  currentToken = _currentToken;
			  	//System.out.println("singlar noun= " + nounReference);
			}
		
			// Do the same for the verbs (see the treatment of nounReference above)...
			verbReference = isVerb(currentToken, tokenizedInput,
					       cnlString.substring(currentPosition, cnlString.length()));
			if (!verbReference.equals(""))
			  currentToken = _currentToken;
		
			// Now, just check for 1-word adjectives, pronouns, and articles.
			adjReference = isAdjective(currentToken);
			pronReference = isPronoun(currentToken);
		}else{
			nounReference = "";
			verbReference = "";
			adjReference = "";
			pronReference = "";
		}
		
		
	} else {
		nounReference = "";
		verbReference = "";
		adjReference = "";
		pronReference = "";
		artReference = "";
      }

      //shijian 2001-8-13
      if (!(nounReference.equals(""))) thereIsNoun = true;
   	if (!(verbReference.equals(""))) {
		thereIsVerb = true;
		thereIsNoun = false;
   	}
      if (nounReference.equals("") && verbReference.equals("") &&
	  adjReference.equals("") && pronReference.equals("") && 
	  artReference.equals("")){

		if(!thereIsVerb && !thereIsNoun) {
		
		  nounReference = currentToken;
		  
		  thereIsNoun = true;
		  //	System.out.println(ii+ " noun: " +currentToken);
	
		} else if(thereIsNoun && !thereIsVerb) {
		  verbReference =currentToken;
		  thereIsVerb = true;
		  //thereIsNoun = false;
		  //	System.out.println(ii+ " verb: " +currentToken);
		} else {	//if (!thereIsNoun && thereIsVerb){
		
		nounReference = currentToken;
		
		  thereIsNoun = true;
		  //	System.out.println(ii+ " noun: " +currentToken);
		}
	  			
      }

      // pick a transition that matches the POS and take it
      for (int i = 0; i < possibleTransitions.size(); i++) {	
	//shijian, 23-10-2001
	//		System.out.println("transition guard = "+
	//			possibleTransitions.elementAt(i));
	// Check for a literal word match (e.g., "at", "from")
	if (literalTransitionMatch(currentToken,
				   ((String)(possibleTransitions.elementAt(i))))) {
	  currentTransition = ((String)(possibleTransitions.elementAt(i)));
	  break;
	}
	// Check for an article match
	else if ((possibleTransitions.elementAt(i).equals("article")) &&
		 (artReference != "")) {
	  currentTransition = "article";
	  break;
	}
	// Check for a verb/process match
	else if ((possibleTransitions.elementAt(i).equals("verb")) &&
		 (verbReference != "")) {
	  currentTransition = "verb";
	  headReference = verbReference;
	  headLength = currentToken.length(); //brasser 2001-6-22
	  //headLength = verbReference.length();
	  break;
	}
	// Check for a noun match (agent or object)
	else if ((possibleTransitions.elementAt(i).equals("noun")) &&
		 (nounReference != "")) {
	  currentTransition = "noun";
	  headReference = nounReference;
	  headLength = currentToken.length(); //brasser 2001-6-22
	  //headLength = nounReference.length();
	  break;
	}
	// Check for an adjective match
	else if ((possibleTransitions.elementAt(i).equals("adjective")) &&
		 (adjReference != "")) {
	  currentTransition = "adjective";
	  break;
	}
	// Check for a pronoun match
	else if ((possibleTransitions.elementAt(i).equals("pronoun")) &&
		 (pronReference != "")) {
	  currentTransition = "pronoun";
	  break;
	}
	// Check for simple word guards (for simple grammars that don't care about POS)
	else if (possibleTransitions.elementAt(i).equals("word")) {
	  currentTransition = "word";
				  
	  //shijian 8-2-2001
	  // mark head of constituents for simple grammar
	  headReference = currentToken;
	  headLength = currentToken.length();
	  break;
	}
      }

      //System.out.println("      perform transition: " + currentTransition);
      //previousState = _grammar.getCurrentState();  // save this for one of the operations
      previousState = _grammar.getCurrentConstituent();
      previousState2 = _grammar.getCurrentState();
      currentOperations = _grammar.transition(currentTransition);
      
     /*                          //Some handy trace prints...
	 System.out.println("current CNL: " + cnlString);
	 System.out.println("current token: |" + currentToken + "|");
	 System.out.println("current token length: " + currentToken.length());
	 System.out.println("transition: " + currentTransition);
	 System.out.println("constituent: " + _grammar.getCurrentConstituent());
	 System.out.println("previous state: " + previousState);
	 System.out.println("current state: " + _grammar.getCurrentState());
	 System.out.println("current position: " + currentPosition + "\n");
	 System.out.println(_currentTable);
	 System.out.println("\n\n");
	*/
      // perform the operations specified by the grammar
      for (int i = 0; i < currentOperations.size(); i++) //change here
	switch (((Integer)(currentOperations.elementAt(i))).intValue())
	  {
	  case Transition.INCREMENT_CURRENT:
	    currentPosition += currentToken.length() + 1;
	    break;
	  case Transition.START_EQ_CURRENT:
	    //((Constituent)(_constituents.elementAt(((Integer)(name2Index.get(_grammar.getCurrentState()))).intValue()))).setStartPosition(currentPosition);
	    //System.out.println("START_EQ_CURRENT: " + _grammar.getCurrentConstituent() + currentPosition + "\n");
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setStartPosition(currentPosition);
	    break;
	  case Transition.PREPSTART_EQ_CURRENT:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
				getCurrentConstituent())))).setPrepositionPosition(currentPosition);
	    break;
	  case Transition.PREPSTART_EQ_WORKING:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
			getCurrentConstituent())))).setPrepositionPosition(workingBufferStart);
	    break;
	  case Transition.DETSTART_EQ_CURRENT:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
				getCurrentConstituent())))).setDeterminerStart(currentPosition);
	    break;
	  case Transition.DETSTART_EQ_WORKING:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
			getCurrentConstituent())))).setDeterminerStart(workingBufferStart);
	    break;
	  case Transition.START_EQ_WORKING:
	    //System.out.println("START_EQ_WORKING: " + _grammar.getCurrentConstituent() + workingBufferStart + "\n");
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setStartPosition(workingBufferStart);
	    break;
	  case Transition.WORKING_EQ_START:
	    workingBufferStart = ((Constituent)(_currentTable.
						getConstituents().elementAt(_currentTable.name2Index(_grammar.
												     getCurrentConstituent())))).startPosition();
	    break;
	  case Transition.WORKING_EQ_CURRENT:
	    workingBufferStart = currentPosition;
	    break;
	  case Transition.END_EQ_CURRENT_MINUS_1:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(previousState)))).
	      setEndPosition(currentPosition - 1);
	    break;
	  case Transition.HEAD_EQ_CURRENT:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setHeadPosition(currentPosition);
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setHeadLength(headLength);
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setDomainObjectName(headReference);
	    break;
	  case Transition.ADD_TO_HEAD:
	    changeHead(_grammar.getCurrentConstituent(), 
		       new Integer(((Constituent)(_currentTable.getConstituents().
						  elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).
				   startPosition()), new Integer(currentPosition-1));
	    break;
	  case Transition.RESTART_PARSER:
	    /*	    	     // trace prints...
	    System.out.println("Restarting parser...");
	    System.out.println("current CNL: " + cnlString);
	    System.out.println("currentPosition: " + currentPosition);
	    System.out.println("current constituent: " + _grammar.getCurrentConstituent());
	    System.out.println(_currentTable);
	    */

	    _constituentTables.add(_currentTable);

	    //brasser 2001-7-18
	    //this variable should probably be renamed to previousState, and previousState to previous constituent //look here
	    if (previousState2.equals("period"))
	      _constituentTables.add(".");

	    _currentTable = new ConstituentTable(_dmManager, _grammar);
	    for (int j = 0; j < _currentTable.getConstituents().size(); j++)
	      ((Constituent)(_currentTable.getConstituents().elementAt(j))).initialize();
	    _grammar.initialize();
	    break;
	  case Transition.SET_ROLE:
	    //	    System.out.println("role: " + previousState);
	    _currentTable.setRole(previousState);
	    break;
	  }
	  

      //brasser 2001-7-17
      //this is a repetition of the code above. It is here to take care of epsilon moves
      //we don't want to get the next token before performing an epsilon move, so we do it here
      possibleTransitions = _grammar.possibleTransitions();
      for (int k = 0; k < possibleTransitions.size(); k++) {
	// Check for an epsilon move
	if (possibleTransitions.elementAt(k).equals("E")) {
	  currentTransition = "E";
	  headReference = currentToken;
	  headLength = currentToken.length();
			  
	  previousState = _grammar.getCurrentState();
	  currentOperations = _grammar.transition(currentTransition);
	  //System.out.println("transition: " + currentTransition);
	  //System.out.println("constituent: " + _grammar.getCurrentConstituent());
	  //System.out.println("previous state: " + previousState);
	  //System.out.println("current state: " + _grammar.getCurrentState() + "\n");
	  //printConstituentTable();
	  //System.out.println("\n\n");

	  // perform the operations specified by the grammar
	  for (int i = 0; i < currentOperations.size(); i++) //change here
	    switch (((Integer)(currentOperations.elementAt(i))).intValue())
	      {
	      case Transition.INCREMENT_CURRENT:
		currentPosition += currentToken.length() + 1;
				break;
	      case Transition.START_EQ_CURRENT:
				//((Constituent)(_constituents.elementAt(((Integer)(name2Index.get(_grammar.getCurrentState()))).intValue()))).setStartPosition(currentPosition);
				//		System.out.println("START_EQ_CURRENT: " + _grammar.getCurrentConstituent() + currentPosition + "\n");
				((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setStartPosition(currentPosition);
				break;
	  		case Transition.PREPSTART_EQ_CURRENT:
		((Constituent)(_currentTable.getConstituents().
			elementAt(_currentTable.name2Index(_grammar.
				getCurrentConstituent())))).setPrepositionPosition(currentPosition);
		    	break;
	  		case Transition.PREPSTART_EQ_WORKING:
	    		((Constituent)(_currentTable.getConstituents().
			   	elementAt(_currentTable.name2Index(_grammar.
							      getCurrentConstituent())))).setPrepositionPosition(workingBufferStart);
	    		break;
	  case Transition.DETSTART_EQ_CURRENT:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
				getCurrentConstituent())))).setDeterminerStart(currentPosition);
	    break;
	  case Transition.DETSTART_EQ_WORKING:
	    ((Constituent)(_currentTable.getConstituents().
			   elementAt(_currentTable.name2Index(_grammar.
			getCurrentConstituent())))).setDeterminerStart(workingBufferStart);
	    break;
	      case Transition.START_EQ_WORKING:
		((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setStartPosition(workingBufferStart);
				break;
	      case Transition.WORKING_EQ_START:
				workingBufferStart = ((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).startPosition();
				break;
  	  		case Transition.WORKING_EQ_CURRENT:
	    		workingBufferStart = currentPosition;
	    		break;
	      case Transition.END_EQ_CURRENT_MINUS_1:
		((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(previousState)))).setEndPosition(currentPosition - 1);
				break;
	      case Transition.HEAD_EQ_CURRENT:
		((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setHeadPosition(currentPosition);
		((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setHeadLength(headLength);
				((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setDomainObjectName(headReference);
				break;
	      case Transition.ADD_TO_HEAD:
				//headLength = currentPosition - ((Constituent)(_constituents.elementAt(((Integer)(name2Index.get(_grammar.getCurrentState()))).intValue()))).startPosition() - 1;
				//((Constituent)(_constituents.elementAt(((Integer)(name2Index.get(_grammar.getCurrentConstituent()))).intValue()))).setHeadLength(headLength);
				changeHead(_grammar.getCurrentConstituent(), new Integer(((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).startPosition()), new Integer(currentPosition-1));
				//((Constituent)(_constituents.elementAt(((Integer)(name2Index.get(_grammar.getCurrentConstituent()))).intValue()))).setDomainObjectName(headReference);
				break;
	      case Transition.RESTART_PARSER:
			/*				// trace prints
			System.out.println("Restarting parser...");
			System.out.println("current CNL: " + cnlString);
			System.out.println("currentPosition: " + currentPosition);
			System.out.println("current constituent: " + _grammar.getCurrentConstituent());
			System.out.println(_currentTable);
			*/

				// Save the current Constituent table.
				_constituentTables.add(_currentTable);

				workingBufferStart = currentPosition; // gets rid of wrong premodifiers
			//brasser 2001-7-18
		if (previousState.equals("period"))
		  _constituentTables.add(".");
		_currentTable = new ConstituentTable(_dmManager, _grammar);
		for (int j = 0; j < _currentTable.getConstituents().size(); j++)
			  ((Constituent)(_currentTable.getConstituents().elementAt(j))).initialize();
			_grammar.initialize();
				break;
	      case Transition.SET_ROLE:
				//		System.out.println("role: " + previousState);
				_currentTable.setRole(previousState);
				break;
	      }
	}
      }
	  
    }

    //System.out.println("out of the loop in state: " + _grammar.getCurrentState());

    // fix one special case: the last sentence constituent will have a
    // startPosition and a -1 endPosition.  
    // Make sure it is a constituent //brasser 2001-7-6
    // This must be fixed on a restart as well (see above) - kvlinden, 10jan2002
    if (_grammar.getCurrentConstituent() != null) //changed here //brasser 2001-7-12 
      ((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index(_grammar.getCurrentConstituent())))).setEndPosition(cnlString.trim().length());  // trim the string to remove trailing spaces - kvlinden, 25oct2001
    _constituentTables.add(_currentTable); //brasser 2001-7-13
	
         // A trace print feature
       System.out.println("CNL: " + cnlString);
       for (int i = 0; i < _constituentTables.size(); i++)
       System.out.println(_constituentTables.elementAt(i) + "\n");
      

    // return the appropriate status
    return _grammar.inTerminalState();
  }

/**
    Checks the list of known GUI and domain objects

    Returns the name of the DM object that was recognized, or "" otherwise.

    It will match the longest possible DM object (e.g., "task model" rather than
    just "task"). When is matches a multiple word concept, it automatically eats
    up the tokenizer tokens in st (it's passed by reference).  The calling program
    will have to change the current token value appropriately - kvlinden, 8jan2002
    @roseuid 395A021B0097
    */
	
  public String isNoun(String token, StringTokenizer st, String cnlStringRest)
  {
    //if (token.equals("a")) return "";//23-1-2002
    String returnValue = "";
    _currentToken = token;  // Save in a global variable so it can be returned - kvlinden, 15jan2002
    int index;

    // Try to find a DM concept with a name matching the next words in the input string.
    // Start with all the words in the rest of the string, and loop through successively
    // shortening the string by one word, stopping when we find a matching DM concept name
    // or when we run out of string.  
    for (;;) {
      // Break when there is no more CNL string left.
      if (cnlStringRest.length() < 1)
	break;
      // Try to find a concept with the current name.
      returnValue = findDMObject(cnlStringRest);
      // If we find one, eat the right number of tokens from st and then return
      // name of the found concept.
      if (!returnValue.equals("")) {
			_currentToken = token = cnlStringRest;  // set the full token name (potentially multiple words)
			StringTokenizer newST = new StringTokenizer(cnlStringRest);
			for (int i = 1; i < newST.countTokens(); i++)
	  			st.nextToken();
			return returnValue;
      }
      // If we don't have a match, chop a word off the end and try again.
      else {
			index = cnlStringRest.lastIndexOf(" ");
			if (index > 0)
	  			cnlStringRest = cnlStringRest.substring(0,index);
			else
	  		cnlStringRest = "";  // Don't chop when there is only 1 word left.
      }
    }

    // If we can't find a matching DM concept, try looking in wordNet.
    try {
      IndexWord iw = db.lookupBaseForm(POS.NOUN, token);
      if (iw != null)
	return iw.getLemma();
    }
    catch (Exception e) {
      //System.err.println("Exception in WordNet: " +e);
      return "";
    }

    // Otherwise, return empty string indicating a failure to find anything.
    return "";
  }

  private String findDMObject(String token) 
  {
    // Check the domain model for the 3 "types" of objects.
    // We shouldn't have to do this, there should be one "object" parent concept.
    if ((_dmManager.getEConcept(token) != null)
	|| (_dmManager.getUserConcept(token) != null)
	|| (_dmManager.getInterfaceConcept(token) != null)
	|| (_dmManager.getSystemConcept(token) != null)
	 )
      return token;
    else 
      return "";
  }


  // brasser 2001-6-6
  private String isAdjective(String token)
  {
    IndexWord iw;
    
    //shijian
    //5-11-2001
    //try to catch IndexWordException
    try{

      iw = db.lookupBaseForm(POS.ADJECTIVE, token);
		
      if (iw != null)
	return token;  
      else
	return "";
    }
    catch (Exception e)
      {
	//System.err.println("Exception in WordNet: " +e);
	return "";
      }
  }
  
  // brasser 2001-6-6
  private String isPronoun(String token)
  {
    if ((token.equals("this")) || (token.equals("that")) || (token.equals("these"))
	|| (token.equals("those")) || (token.equals("his")) || (token.equals("her"))
	|| (token.equals("you")) || (token.equals("he")) || (token.equals("she"))
	|| (token.equals("it")) || (token.equals("s/he"))) 
      return token;  
    else
      return "";
  }

  /**
    Checks the list of predefined verb concepts, and if that fails, it checks wordnet.

    Returns the concept name, or "" on failure.  See comments on isNoun() for the proper
    handling of multi-word verbs.

    @roseuid 395A0243035C
    */
	
  //added wordnet lookup. brasser 2001-6-6
  public String isVerb(String token, StringTokenizer st, String cnlStringRest)
  {
    int index;
    _currentToken = token; // save in global variable, see isNoun() - kvlinden, 15jan2002

    // Try to find a DM action concept with a name matching the next words in the 
    // input string.  This is very similar to the processing in isNoun(), so see the
    // comments above.
    for (;;) {
      // Break when there is no more CNL string left.
      if (cnlStringRest.length() < 1)
	break;
      // Try to find a concept with the current name.
      if (_dmManager.getAConcept(cnlStringRest) != null) {
	_currentToken = token = cnlStringRest;  // set the full token name (potentially multiple words)
	StringTokenizer newST = new StringTokenizer(cnlStringRest);
	for (int i = 1; i < newST.countTokens(); i++)
	  st.nextToken();
	return cnlStringRest;
      }
      // If we don't have a match, chop a word off the end and try again.
      else {
	index = cnlStringRest.lastIndexOf(" ");
	if (index > 0)
	  cnlStringRest = cnlStringRest.substring(0,index);
	else
	  cnlStringRest = "";  // Don't chop when there is only 1 word left.
      }
    }

    // If we can't find a matching DM concept, try looking in wordNet.
    try {
      IndexWord iw = db.lookupBaseForm(POS.VERB, token);
      if (iw != null) {
	//System.out.println("token: " + token + " lemma: " + iw.getLemma() + 
	// " found in WordNet");
	return iw.getLemma();
      }
    }
    catch (Exception e) {
      //System.err.println("Exception in WordNet: " +e);
      return "";
    }

    // Otherwise, return empty string indicating a failure to find anything.
    //    System.out.println("token: " + token + " not found in DM or WordNet");
    return "";
  }

  //brasser 2001-7-6
  public String isArticle(String token)
  {
    if ((token.equals("a")) || (token.equals("an")) || (token.equals("the"))
    	|| (token.equals("all")) || (token.equals("any")) || (token.equals("each"))
    	|| (token.equals("every")) || (token.equals("few")) || (token.equals("many")))
      return token;  
    else
      return "";
  }
  
  //check to see if something is punctuation //brasser 2001-7-6
  public boolean isPunctuation(String token) 
  {
    if ((token.equals(".")) || (token.equals(","))) 
      return true; 
    else
      return false;
  }

  /**
    returns true if the current token matches a literal transition (surrounded by quotes
    in the grammar)
    @roseuid 395A024902EC
    */
  public boolean literalTransitionMatch(String token, String transition)
  {
    return (transition.startsWith("\"") &&
	    token.equals(transition.substring(1,transition.length() - 1)));
  }

  /*  // a utility for debugging.
      // moved to ConstituentTable.java where it belongs - kvlinden, 9jan2002
      public void printConstituentTable()
      {
      for (int i = 0; i < _currentTable.getConstituents().size(); i++) //changed here //brasser 2001-7-12
      ((Constituent)(_currentTable.getConstituents().elementAt(i))).print();
      }
      */

  /**
    goes through the constituent start positions, creating DM concepts and instances
    as required.  It is careful not to "recreate" entities when they already exist in the DM.
    It is hard-coded for the constituents we know to be in the grammar.
    @roseuid 395A07B50266
    */
	
  //brasser 2001-7-13
  //make this function a wrapper class for the function in ConstituentTable
  public ActionInstance createDM(GenericComponent gc)
  {
    //    System.out.println("createDM");
    //    printConstituentTable();

    ActionInstance ai;  // a utility variable for entity instances
    //    System.out.println("Size: " + _constituentTables.size());
    //shijian, 22-10-2001
    ai = _currentTable.createDM(gc, _cnlString, _cnlString);
    return ai;
    /*   if (_constituentTables.size() < 2) 
	 {
	 ai = _currentTable.createDM(gc, _cnlString, _cnlString);
	 return ai;
	 }
	 else 
	 {
	 System.out.println("*WARNING*");
	 return null;
	 }
	 */  
    
  } 
  
 //shijian, 22-1-2002
 public GenericComponent createTM(GenericComponent gc) 
  {
    Task  t = null;
    ConstituentTable _otherTable = null;
    String previousTask = null;
    String prevHighTask = null;
    boolean pass = false;
    Vector temp = new Vector();
    ActionInstance ai;        // a utility variable
	
    for (int i = 0; i < _constituentTables.size(); i++) 
      {
	if (((_constituentTables.elementAt(i)).getClass()).
		isAssignableFrom(_currentTable.getClass()))
	  {
	    _currentTable = (ConstituentTable)_constituentTables.elementAt(i);
	    //	    System.out.println(_currentTable.getRole());
	    pass = false;
			
	    //to take care of blank ones at the end
	    if(((Constituent)(_currentTable.getConstituents().
	    	elementAt(_currentTable.name2Index("process")))).startPosition()==-1)
	      pass=true;
	  }
	else
	  pass = true;
		
	//System.out.println(((ConstituentTable)_constituentTables.elementAt(i)).getRole());
		
	//take care of a purpose clause in the first sentence - 
	// will be purpose for whole paragraph
	if (i == 0) //eventually we may want to add more guards, 
			//especially if it is for a more structured text
	  {
		
	    while ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	    			//go until period or end of vector
	      {
		_currentTable = (ConstituentTable)_constituentTables.elementAt(i);
		if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) 
		  {
		    t = NewManager.newTask(-1,-1, createName(_currentTable), true);
		    setStyle(t, _currentTable); //brasser 2001-8-17
		    ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		    t.setSemantics(ai.getID());
				
		  }
		else
		  {
		    temp.add(_currentTable);
		  }
		i++;
				
	      }
	    if (temp.size() < 1)         //brasser 2001-8-17. 
	    					//fixes a bug for sentences with no period at the end
	      temp.add(_currentTable);
				
	    _constituentTables.addAll(i+1, temp); //brasser 2001-7-27
	    _constituentTables.add(".");
	  }
		
	//depending on the type of clause, we need to string the tasks together differently
	else if (pass)
	    ; //do nothing for punctuation
	else if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE)
	  {
	    t = NewManager.newTask(-1,-1,createName(_currentTable));
	    setStyle(t, _currentTable); //brasser 2001-8-17
	    ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
	    t.setSemantics(ai.getID());
	    if (prevHighTask != null)			
	      NewManager.newLink(prevHighTask,createName(_currentTable));
	    while ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	    				//go until period or end of vector
	      {
		_otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
		setStyle(t2, _otherTable); //brasser 2001-8-17
		if (previousTask != null)			
		  NewManager.newLink(t.getName(), previousTask,t2.getName());
		//NewManager.newLink(t.getName(), previousTask,createName(_otherTable));
		previousTask = t2.getName();
		ai =_otherTable.createDM(gc, _cnlString, createName(_otherTable));
		t2.setSemantics(ai.getID());
				
		i++;
	      }
	    prevHighTask = t.getName();
	  }
	else if (_currentTable.getRole() == ConstituentTable.PRECONDITION)
	  {
	    if ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	      {
		_otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		t = NewManager.newTask(-1,-1,createName(_otherTable));
		setStyle(t, _otherTable); //brasser 2001-8-17
		t.setPrecon(createName(_currentTable));
		if (prevHighTask != null)			
		  NewManager.newLink(prevHighTask,t.getName());
		//NewManager.newLink(prevHighTask,createName(_otherTable));
		prevHighTask = t.getName();
		ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		t.setSemantics(ai.getID());
		i++;
	      }
			
	  }
	else if (_currentTable.getRole() == ConstituentTable.ACTION_CLAUSE) 
	  {
			
	    if (i < (_constituentTables.size()-1)) { //check to see there is something in the next spot
	      if (((_constituentTables.elementAt(i+1)).getClass()).
	      	isAssignableFrom(_currentTable.getClass())) //check to make sure it isn't punctuation...
		{
		  _otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		  if (_otherTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) 
		  //regular clause followed by purpose clause 
		    {
		      //create the parent task
		      t = NewManager.newTask(-1,-1,createName(_otherTable));
		      setStyle(t, _otherTable); //brasser 2001-8-17
		      ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		      t.setSemantics(ai.getID());
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      //create the child task with the correct parent
		      Task t2 = NewManager.newTask(t.getName(),createName(_currentTable), _cnlString, true);
		      setStyle(t2, _currentTable); //brasser 2001-8-17
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t2.setSemantics(ai.getID());
		      //linking???
		      //need to add onto i because we have already created the next object
		      i++;
		    }
		  else if (_otherTable.getRole() == ConstituentTable.PRECONDITION) 
		    {
		      t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      t.setPrecon(createName(_otherTable));
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t.setSemantics(ai.getID());
		      i++;	
		    }
		  else if (_otherTable.getRole() == ConstituentTable.IMPLEMENT_CLAUSE) //HAVEN'T TESTED YET 
		    {
		      //create the parent task
		      t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t.setSemantics(ai.getID());
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      //create the child task with the correct parent
		      Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
		      setStyle(t2, _otherTable); //brasser 2001-8-17
		      ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		      t2.setSemantics(ai.getID());
		      //linking???
		      //need to add onto i because we have already created the next object
		      i++;	
		    }
		  else //if next is not a purpose clause or precondition...regular clause
		    {
		      t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
		      t.setSemantics(ai.getID());
		    }
		}
	      else //if next is punctuation...regular clause
		{
		  t = NewManager.newTask(-1,-1,createName(_currentTable));
		  setStyle(t, _currentTable); //brasser 2001-8-17
		  if (prevHighTask != null)			
		    NewManager.newLink(prevHighTask,t.getName());
		  prevHighTask = t.getName();
		  ai =_currentTable.createDM(gc, _cnlString, createName(_currentTable));
		  t.setSemantics(ai.getID()); 
		  //increment i to skip over the punctuation
		  i++;
		}
				
	    }
	    else //regular clause
	      {
		t = NewManager.newTask(-1,-1,createName(_currentTable));
		setStyle(t, _currentTable); //brasser 2001-8-17
		if (prevHighTask != null)			
		  NewManager.newLink(prevHighTask,t.getName());
		prevHighTask = t.getName();
		ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
		t.setSemantics(ai.getID());
	      }

	  }
		
      }
      return t;
  }
  /*  
//brasser 2001-7-13
  //creates task and domain model information
  public void createTM(GenericComponent gc) 
  {
    ConstituentTable _otherTable = null;
    String previousTask = null;
    String prevHighTask = null;
    boolean pass = false;
    Vector temp = new Vector();
    ActionInstance ai;        // a utility variable
  */
  /* System.out.println("**************************************************");
      for (int i = 0; i < _constituentTables.size(); i++) 
      {
      System.out.println(_constituentTables.elementAt(i));
      }
      System.out.println("**************************************************");*/
/*	
    for (int i = 0; i < _constituentTables.size(); i++) 
      {
	if (((_constituentTables.elementAt(i)).getClass()).
		isAssignableFrom(_currentTable.getClass()))
	  {
	    _currentTable = (ConstituentTable)_constituentTables.elementAt(i);
	    //	    System.out.println(_currentTable.getRole());
	    pass = false;
			
	    //to take care of blank ones at the end
	    if(((Constituent)(_currentTable.getConstituents().
	    	elementAt(_currentTable.name2Index("process")))).startPosition()==-1)
	      pass=true;
	  }
	else
	  pass = true;
		
	//System.out.println(((ConstituentTable)_constituentTables.elementAt(i)).getRole());
		
	//take care of a purpose clause in the first sentence - 
	// will be purpose for whole paragraph
	if (i == 0) //eventually we may want to add more guards, 
			//especially if it is for a more structured text
	  {
		
	    while ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	    			//go until period or end of vector
	      {
		_currentTable = (ConstituentTable)_constituentTables.elementAt(i);
		if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) 
		  {
		    Task t = NewManager.newTask(-1,-1, createName(_currentTable), true);
		    setStyle(t, _currentTable); //brasser 2001-8-17
		    ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		    t.setSemantics(ai.getID());
				
		  }
		else
		  {
		    temp.add(_currentTable);
		  }
		i++;
				
	      }
	    if (temp.size() < 1)         //brasser 2001-8-17. 
	    					//fixes a bug for sentences with no period at the end
	      temp.add(_currentTable);
				
	    _constituentTables.addAll(i+1, temp); //brasser 2001-7-27
	    _constituentTables.add(".");
	  }
		
	//depending on the type of clause, we need to string the tasks together differently
	else if (pass)
	    ; //do nothing for punctuation
	else if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE)
	  {
	    Task t = NewManager.newTask(-1,-1,createName(_currentTable));
	    setStyle(t, _currentTable); //brasser 2001-8-17
	    ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
	    t.setSemantics(ai.getID());
	    if (prevHighTask != null)			
	      NewManager.newLink(prevHighTask,createName(_currentTable));
	    while ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	    				//go until period or end of vector
	      {
		_otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
		setStyle(t2, _otherTable); //brasser 2001-8-17
		if (previousTask != null)			
		  NewManager.newLink(t.getName(), previousTask,t2.getName());
		//NewManager.newLink(t.getName(), previousTask,createName(_otherTable));
		previousTask = t2.getName();
		ai =_otherTable.createDM(gc, _cnlString, createName(_otherTable));
		t2.setSemantics(ai.getID());
				
		i++;
	      }
	    prevHighTask = t.getName();
	  }
	else if (_currentTable.getRole() == ConstituentTable.PRECONDITION)
	  {
	    if ((i < (_constituentTables.size()-1)) && (((_constituentTables.
	    	elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
	      {
		_otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		Task t = NewManager.newTask(-1,-1,createName(_otherTable));
		setStyle(t, _otherTable); //brasser 2001-8-17
		t.setPrecon(createName(_currentTable));
		if (prevHighTask != null)			
		  NewManager.newLink(prevHighTask,t.getName());
		//NewManager.newLink(prevHighTask,createName(_otherTable));
		prevHighTask = t.getName();
		ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		t.setSemantics(ai.getID());
		i++;
	      }
			
	  }
	else if (_currentTable.getRole() == ConstituentTable.ACTION_CLAUSE) 
	  {
			
	    if (i < (_constituentTables.size()-1)) { //check to see there is something in the next spot
	      if (((_constituentTables.elementAt(i+1)).getClass()).
	      	isAssignableFrom(_currentTable.getClass())) //check to make sure it isn't punctuation...
		{
		  _otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
		  if (_otherTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) 
		  //regular clause followed by purpose clause 
		    {
		      //create the parent task
		      Task t = NewManager.newTask(-1,-1,createName(_otherTable));
		      setStyle(t, _otherTable); //brasser 2001-8-17
		      ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		      t.setSemantics(ai.getID());
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      //create the child task with the correct parent
		      Task t2 = NewManager.newTask(t.getName(),createName(_currentTable), _cnlString, true);
		      setStyle(t2, _currentTable); //brasser 2001-8-17
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t2.setSemantics(ai.getID());
		      //linking???
		      //need to add onto i because we have already created the next object
		      i++;
		    }
		  else if (_otherTable.getRole() == ConstituentTable.PRECONDITION) 
		    {
		      Task t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      t.setPrecon(createName(_otherTable));
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t.setSemantics(ai.getID());
		      i++;	
		    }
		  else if (_otherTable.getRole() == ConstituentTable.IMPLEMENT_CLAUSE) //HAVEN'T TESTED YET 
		    {
		      //create the parent task
		      Task t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));
		      t.setSemantics(ai.getID());
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      //create the child task with the correct parent
		      Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
		      setStyle(t2, _otherTable); //brasser 2001-8-17
		      ai = _otherTable.createDM(gc, _cnlString, createName(_otherTable));
		      t2.setSemantics(ai.getID());
		      //linking???
		      //need to add onto i because we have already created the next object
		      i++;	
		    }
		  else //if next is not a purpose clause or precondition...regular clause
		    {
		      Task t = NewManager.newTask(-1,-1,createName(_currentTable));
		      setStyle(t, _currentTable); //brasser 2001-8-17
		      if (prevHighTask != null)			
			NewManager.newLink(prevHighTask,t.getName());
		      prevHighTask = t.getName();	
		      ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
		      t.setSemantics(ai.getID());
		    }
		}
	      else //if next is punctuation...regular clause
		{
		  Task t = NewManager.newTask(-1,-1,createName(_currentTable));
		  setStyle(t, _currentTable); //brasser 2001-8-17
		  if (prevHighTask != null)			
		    NewManager.newLink(prevHighTask,t.getName());
		  prevHighTask = t.getName();
		  ai =_currentTable.createDM(gc, _cnlString, createName(_currentTable));
		  t.setSemantics(ai.getID()); 
		  //increment i to skip over the punctuation
		  i++;
		}
				
	    }
	    else //regular clause
	      {
		Task t = NewManager.newTask(-1,-1,createName(_currentTable));
		setStyle(t, _currentTable); //brasser 2001-8-17
		if (prevHighTask != null)			
		  NewManager.newLink(prevHighTask,t.getName());
		prevHighTask = t.getName();
		ai = _currentTable.createDM(gc, _cnlString, createName(_currentTable));	
		t.setSemantics(ai.getID());
	      }

	  }
		
      }
  }
 */
  // Try this new wrapper so we can consolidate the two versions of createTM.
  // The createTM(GenericComponent) version (see above) was added so that the
  // calling program can use an existing task, rather than having createTM()
  // create a new one automatically  - kvlinden, 11jan2002
/*  public GenericComponent createTM() 
  {
    Task t= null;	//1-11-2001
    createTM(t);
    return t;
  }
  */
/*
   //Replaced by a wrapper, see above - kvlinden, 11jan2002

     //shijian
     //1-11-2001
     //return the task been created
     public GenericComponent createTM()	//Task t) 
     {
     ConstituentTable _otherTable = null;
     String previousTask = null;
     String prevHighTask = null;
     boolean pass = false;
     Vector temp = new Vector();
     ActionInstance ai;        // a utility variable
     Task t= null;	//1-11-2001
     String taskName=_cnlString;	//5-11-2001
     for (int i = 0; i < _constituentTables.size(); i++) 
     {
     if (((_constituentTables.elementAt(i)).getClass()).isAssignableFrom(_currentTable.getClass()))
     {
     _currentTable = (ConstituentTable)_constituentTables.elementAt(i);
     //	    System.out.println(_currentTable.getRole());
     pass = false;
				
     //to take care of blank ones at the end
     if(((Constituent)(_currentTable.getConstituents().elementAt(_currentTable.name2Index("process")))).startPosition()==-1)
     pass=true;
     }else
     pass = true;
		
     //System.out.println(((ConstituentTable)_constituentTables.elementAt(i)).getRole());
		
     //take care of a purpose clause in the first sentence - will be purpose for whole paragraph
     if (i == 0) //eventually we may want to add more guards, especially if it is for a more structured text
     {
		
     while ((i < (_constituentTables.size()-1)) && (((_constituentTables.elementAt(i)).getClass()).isAssignableFrom(_currentTable.getClass()))) //go until period or end of vector
     {
     _currentTable = (ConstituentTable)_constituentTables.elementAt(i);
     if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) 
     {
     t = NewManager.newTask(-1,-1, taskName, true);

     //t = NewManager.newTask(-1,-1, createName(_currentTable), true);
     setStyle(t, _currentTable); //brasser 2001-8-17
     ai = _currentTable.createDM(t, _cnlString, createName(_currentTable));
     t.setSemantics(ai.getID());
				
     }
     else
     {
     temp.add(_currentTable);
     }
     i++;
				
     }
     if (temp.size() < 1)         //brasser 2001-8-17. fixes a bug for sentences with no period at the end
     temp.add(_currentTable);
				
     _constituentTables.addAll(i+1, temp); //brasser 2001-7-27
     _constituentTables.add(".");
     }
		
     //depending on the type of clause, we need to string the tasks together differently
     else if (pass)
     ; //do nothing for punctuation
     else if (_currentTable.getRole() == ConstituentTable.PURPOSE_CLAUSE)
     {
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     ai = _currentTable.createDM(t, _cnlString, taskName);	
     t.setSemantics(ai.getID());
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,taskName);
     while ((i < (_constituentTables.size()-1)) && (((_constituentTables.elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) //go until period or end of vector
     {
     _otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
     Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
     setStyle(t2, _otherTable); //brasser 2001-8-17
     if (previousTask != null)			
     NewManager.newLink(t.getName(), previousTask,t2.getName());
     //NewManager.newLink(t.getName(), previousTask,createName(_otherTable));
     previousTask = t2.getName();
     ai =_otherTable.createDM(t2, _cnlString, createName(_otherTable));
     t2.setSemantics(ai.getID());
				
     i++;
     }
     prevHighTask = t.getName();
     }
     else if (_currentTable.getRole() == ConstituentTable.PRECONDITION)
     {
     if ((i < (_constituentTables.size()-1)) && (((_constituentTables.elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass()))) 
     {
     _otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
     t = NewManager.newTask(-1,-1,createName(_otherTable));
     setStyle(t, _otherTable); //brasser 2001-8-17
     t.setPrecon(taskName);
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     //NewManager.newLink(prevHighTask,createName(_otherTable));
     prevHighTask = t.getName();
     ai = _otherTable.createDM(t, _cnlString, createName(_otherTable));
     t.setSemantics(ai.getID());
     i++;
     }
			
     }
     else if (_currentTable.getRole() == ConstituentTable.ACTION_CLAUSE) 
     {
			
     if (i < (_constituentTables.size()-1)) { //check to see there is something in the next spot
     if (((_constituentTables.elementAt(i+1)).getClass()).isAssignableFrom(_currentTable.getClass())) //check to make sure it isn't punctuation...
     {
     _otherTable = (ConstituentTable)_constituentTables.elementAt(i+1);
     if (_otherTable.getRole() == ConstituentTable.PURPOSE_CLAUSE) //regular clause followed by purpose clause 
     {
     //create the parent task
     t = NewManager.newTask(-1,-1,createName(_otherTable));
     setStyle(t, _otherTable); //brasser 2001-8-17
     ai = _otherTable.createDM(t, _cnlString, createName(_otherTable));
     t.setSemantics(ai.getID());
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();	
     //create the child task with the correct parent
     Task t2 = NewManager.newTask(t.getName(),taskName, _cnlString, true);
     setStyle(t2, _currentTable); //brasser 2001-8-17
     ai = _currentTable.createDM(t2, _cnlString, taskName);
     t2.setSemantics(ai.getID());
     //linking???
     //need to add onto i because we have already created the next object
     i++;
     }
     else if (_otherTable.getRole() == ConstituentTable.PRECONDITION) 
     {
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     t.setPrecon(createName(_otherTable));
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();	
     ai = _currentTable.createDM(t, _cnlString, taskName);
     t.setSemantics(ai.getID());
     i++;	
     }
     else if (_otherTable.getRole() == ConstituentTable.IMPLEMENT_CLAUSE) //HAVEN'T TESTED YET 
     {
     //create the parent task
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     ai = _currentTable.createDM(t, _cnlString, taskName);
     t.setSemantics(ai.getID());
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();	
     //create the child task with the correct parent
     Task t2 = NewManager.newTask(t.getName(),createName(_otherTable), _cnlString, true);
     setStyle(t2, _otherTable); //brasser 2001-8-17
     ai = _otherTable.createDM(t2, _cnlString, createName(_otherTable));
     t2.setSemantics(ai.getID());
     //linking???
     //need to add onto i because we have already created the next object
     i++;	
     }
     else //if next is not a purpose clause or precondition...regular clause
     {
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();	
     ai = _currentTable.createDM(t, _cnlString, taskName);	
     t.setSemantics(ai.getID());
     }
     }
     else //if next is punctuation...regular clause
     {
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();
     ai =_currentTable.createDM(t, _cnlString, taskName);
     t.setSemantics(ai.getID()); 
     //increment i to skip over the punctuation
     i++;
     }
				
     }
     else //regular clause
     {
     t = NewManager.newTask(-1,-1,taskName);
     setStyle(t, _currentTable); //brasser 2001-8-17
     if (prevHighTask != null)			
     NewManager.newLink(prevHighTask,t.getName());
     prevHighTask = t.getName();
     ai = _currentTable.createDM(t, _cnlString, taskName);	
     t.setSemantics(ai.getID());
     }

     }
		
     }
     return t;
     }
   */    
  
  //shijian
  //22-1-2002
  // instead of composing task names, 
  // using original cnl string for task names
  private String createName(ConstituentTable inTable) 
  {
    int nameStart = 1000, nameEnd=0;
    int conStart= 0, conEnd = 0;
    
    Vector conttts= inTable.getConstituents();
    Constituent con;
    
    //re-initialise nameStart and nameEnd
    for (int i = 0; i < conttts.size(); i++) { 
    	con = (Constituent)conttts.elementAt(i);
    	conStart = con.startPosition();
    	conEnd = con.endPosition();
    	//get the smallest constituent start
    	if (conStart != -1 )
    		nameStart = conStart;
    	//get the largest constituent end
    	if (nameEnd != -1)
    		nameEnd = conEnd;
  	
    }
    
    for (int j = 0; j < conttts.size(); j++) { 
    	con = (Constituent)conttts.elementAt(j);
    	conStart = con.startPosition();
    	conEnd = con.endPosition();
    	
    	//get the smallest constituent start
    	if (conStart >= 0 && nameStart > conStart)
    		nameStart = conStart;
    	//get the largest constituent end
    	if (nameEnd < conEnd)
    		nameEnd = conEnd;
  	
    }
    System.out.println("name start: " + nameStart+ "   name end:"+nameEnd );   
    System.out.println("cnlString== " + _cnlString );
    String newName =_cnlString.substring(nameStart, nameEnd);
    return newName; //get rid of white space at end
  }  

 /* 
  private String createName(ConstituentTable inTable) 
  {
    //get the seperate pieces, and then we can create our own custom tasks
    //"after clicking the button" --> "user click button"
    String process = "";
    String actor = "";
    String actee = "";
    String instrument = "";
    String location = "";
    String source = "";
    String destination = "";
    String spatialLocation = "";
    String rolePlaying = "";
    Constituent c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("process"))));
    process = c.domainObjectName() + _cnlString.substring(c.headPosition() + c.headLength(), c.endPosition()) + " ";
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("actor"))));
    if (c.startPosition() != -1)
      actor = _cnlString.substring(c.startPosition(), c.endPosition()) + " ";
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("actee"))));
    if (c.startPosition() != -1)
      actee = _cnlString.substring(c.startPosition(), c.endPosition()) + " ";
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("instrument"))));
    if (c.startPosition() != -1)
      instrument = "using " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";	
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("location"))));
    if (c.startPosition() != -1)
      location = "at " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("source"))));
    if (c.startPosition() != -1)
      source = "from " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("destination"))));
    if (c.startPosition() != -1)
      destination = "to " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";	
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("spatial-location"))));
    if (c.startPosition() != -1)
      spatialLocation = "on " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";	
    c = ((Constituent)(inTable.getConstituents().elementAt(inTable.name2Index("role-playing"))));
    if (c.startPosition() != -1)
      rolePlaying = "as " + _cnlString.substring(c.startPosition(), c.endPosition()) + " ";	

	
    //System.out.println("actor: " + actor);
    //System.out.println("process: " + process);
    //System.out.println("actee: " + actee);
	
	
    String newName = actor + process + actee + rolePlaying + location + spatialLocation + source + destination + instrument;
    return newName.trim(); //get rid of white space at end
  }  
*/
  /**
    This function will assume that it will never be asked to move a start forward or
    backward beyond the next start in the default constituent order.

    The constituent will either be agent/process/patient/prepositional phrase.
    @roseuid 395B42DC03C8
    */
  public boolean moveConstituent(String constituentName, Integer newStartPosition, Integer newEndPosition)
  { 
    System.out.println("moveConstituent: " + constituentName + " newStartPosition: " + newStartPosition + " newEndPosition: " + newEndPosition);

    // if the user moved the sliders so that the constituent goes away,
    // then set its boundaries to nothing - kvlinden, 25oct2001
    if (newStartPosition.intValue() >= newEndPosition.intValue())
      newStartPosition = newEndPosition = new Integer(-1);

    ((Constituent)(_currentTable.getConstituents().
		   elementAt(_currentTable.name2Index(constituentName)))).
      setStartPosition(newStartPosition.intValue());
    ((Constituent)(_currentTable.getConstituents().
		   elementAt(_currentTable.name2Index(constituentName)))).
      setEndPosition(newEndPosition.intValue());

    //    System.out.println("after:");
    //    printConstituentTable();

    return false;
  }

  /**
    Changes the head of the passed constituent.
    @roseuid 395B49E3004A
    */
  public boolean changeHead(String constituentName, Integer newHeadStart, Integer newHeadEnd)
  {
    // System.out.println("changeHead: " + constituentName + " newHeadStart:: " + 
    // newHeadStart + " newHeadEnd: " + newHeadEnd);
    //    System.out.println("before:");
    //    printConstituentTable();

    // If a constituent is being removed, its head will be changed to position
    // -1,-1.  Computing the domain object name will crash with these indexes, 
    // so we manually set it to "" here - kvlinden, 25oct2001 
    String head;
    if ((newHeadStart.intValue() == -1) || (newHeadEnd.intValue() == -1))
      head = "";
    else
      head = _cnlString.substring(newHeadStart.intValue(),
				  newHeadEnd.intValue());

    ((Constituent)(_currentTable.getConstituents().
		   elementAt(_currentTable.name2Index(constituentName)))).
      setHeadPosition(newHeadStart.intValue());
    ((Constituent)(_currentTable.getConstituents().
		   elementAt(_currentTable.name2Index(constituentName)))).
      setHeadLength(newHeadEnd.intValue() - newHeadStart.intValue());
    ((Constituent)(_currentTable.getConstituents().
		   elementAt(_currentTable.name2Index(constituentName)))).
      setDomainObjectName(head);  // use the new head - kvlinden, 25oct2001

    //    System.out.println("after:");
    //    printConstituentTable();

    return false;
  }

  public String cnlString()
  {
    return _cnlString;
  }
  //change here //brasser 2001-7
  public Vector constituents()
  {
    return _currentTable.getConstituents();
  }

  public Vector possibleTransitions()
  {
    return _grammar.possibleTransitions();
  }
  
  //brasser 2001-8-13
  public Vector allGuards() 
  {
    Vector v = new Vector();
    v.add("noun");
    v.add("verb");
    v.add("adjective");
    v.add("article");
    v.add("pronoun");
	
    return v;
  }
  
  //brasser 2001-8-13
  public Vector allTransitions() 
  {
    Vector v = new Vector();
    v.add("INCREMENT_CURRENT");
    v.add("START_EQ_CURRENT");
    v.add("START_EQ_WORKING");
    v.add("WORKING_EQ_START");
    v.add("HEAD_EQ_CURRENT");
    v.add("END_EQ_CURRENT_MINUS_1");
    v.add("ADD_TO_HEAD");
    v.add("RESTART_PARSER");
    v.add("SET_ROLE");
	
    return v;
  }
  
  //brasser 2001-8-17
  private void setStyle(Task t, ConstituentTable table) 
  {
    Constituent c = ((Constituent)(table.getConstituents().elementAt(table.name2Index("actor"))));
    if(c.headLength() > 0 && _cnlString.substring(c.headPosition(), c.endPosition()).equals("system"))
      t.setStyle("Automatic");
	
  	
  }
  
  //Shijian
  //26-10-2001
  public ConstituentTable getCurrentTable(){
    return  _currentTable;
  	
  }
  
  //Shijian
  //31-10-2001
  public boolean parse(ActionInstance ai)
  {
  	System.out.println("this aI: " );

    if (ai == null) return false;
    if (ai.getName() == null || ai.getName().trim().equals(""))
      return false;
  	
    // Initialize the grammar, the constituent table, 
    _grammar.initialize();
    _constituentTables.clear(); 
    
    //setcnl string
    _cnlString = ai.getName().trim();
    _currentTable.setRole("action"); 
    for (int i = 0; i < _currentTable.getConstituents().size(); i++)   //changed here //brasser 2001-7-12
      ((Constituent)(_currentTable.getConstituents().
		     elementAt(i))).initialize();
      		
    //calculate constituent and head positions
    TreeMap actRel = ai.getActionRelations();
    EntityInstance enIns;
    DmConcept concept;
    Constituent consttt;
    String insName, constttName, conceptName;
    int conStart, conEnd, headStart, headLength;
    for (int i = 0; i < _currentTable.getConstituents().size(); i++) {  //changed here //brasser 2001-7-12
      consttt = (Constituent)(_currentTable.getConstituents().elementAt(i));
      constttName = consttt.name();
      conStart=-1;
      conEnd=-1;
      headStart=-1;
      headLength=0;

	  	//System.out.println("constitunent name: "+ constttName);

      if (!(constttName.equals("process"))){
	if (actRel.get(consttt.name()) != null){
	  enIns = (EntityInstance) actRel.get(constttName);
	  insName = enIns.getName();
	  conStart = _cnlString.indexOf(insName);
	  //if no entity-name found in semantics return false
	  if (conStart != -1)
	    conEnd = conStart + insName.length();
	  //else return false;
	  else {
	  consttt.setStartPosition(conStart);
	  consttt.setEndPosition(conEnd);
	  consttt.setHeadPosition(headStart);
	  consttt.setHeadLength(headLength);

	}    		
	  consttt.setStartPosition(conStart);
	  consttt.setEndPosition(conEnd);
	  consttt.setDomainObjectName(insName);
	      		
	  if (enIns.getConceptOf() != null){
	    concept = enIns.getConceptOf();	
	    conceptName = concept.getName();
	    //set head only if head is identified
	    if (insName.indexOf(conceptName) != -1){
	      headStart = conStart + insName.indexOf(conceptName);
	      headLength = conceptName.length();
	      consttt.setHeadPosition(headStart);
	      consttt.setHeadLength(headLength);
	    }
	  }
	   
	} 
	      		
      }else{	//this is a process
	StringBuffer processName = new StringBuffer();
	concept = ai.getConceptOf();
	conceptName =concept.getName();
	
	//26-6-2002, get non-imperative form if exists
	TreeMap contextT = ai.getEContextTypes();
	String nonImperativeForm =(String)contextT.get(DmRelation.ACTION_PROCESS);
	if (nonImperativeForm != null && !(nonImperativeForm.equals("")))
		conceptName = nonImperativeForm;
      //System.out.println("verb actual form: " +conceptName);
	
	if (ai.getPreModifier() != null && 
	    (!ai.getPreModifier().trim().equals(""))){
	  processName.append(ai.getPreModifier().trim());
	  processName.append(" ");
	}  
	processName.append(conceptName);
	if (ai.getPostModifier() != null && 
	    (!ai.getPostModifier().trim().equals(""))){
	  processName.append( " ").
	    append(ai.getPostModifier().trim());
	}
	String actName = processName.toString();
	String actName1 = actName + " "; //shijian
	conStart = _cnlString.indexOf(actName1);
	//if no process-name found in semantics return false
	if (conStart != -1)
	  conEnd = conStart + actName.length();
	else return false;
      		
	consttt.setStartPosition(conStart);
	consttt.setEndPosition(conEnd);
	consttt.setDomainObjectName(_cnlString);
	if (actName.indexOf(conceptName) != -1){
	  headStart = conStart + actName.indexOf(conceptName);
	  headLength = conceptName.length();
	  consttt.setHeadPosition(headStart);
	  consttt.setHeadLength(headLength);
	}
      }
      /**
      	System.out.println("constituten name: " +constttName);
		System.out.println("88888constituten start: " +consttt.startPosition());
		System.out.println("88888constituten end: " +consttt.endPosition());
		System.out.println("88888head start: " +consttt.headPosition());
		System.out.println("88888head length: " +consttt.headLength());
	**/	
    }
      	
    return true;

  }
  
  //SHijian
  //1-11-2001
  /* all constituents cannot be overlapping with each other.
   * (1) any constituent which is either partially or fully overlapping
   * 		with constituents of constituentName will be re-initialised.  
   */
  public void resolveConsConflicts(String constituentName,int start, int end){
    //resolve constituent conflicts
    Constituent consttt;
    String constttName;
    int conStart, conEnd;

    // Check each existing constituent, and modify its boundaries based on the 
    // new boundaries for constituentName.
    for (int i = 0; i < _currentTable.getConstituents().size(); i++) {  
      consttt = (Constituent)(_currentTable.getConstituents().elementAt(i));
      constttName = consttt.name();
      conStart=consttt.startPosition();
      conEnd=consttt.endPosition();
	
      if (!(constttName.equals(constituentName))){
	if ((conStart < start) && (start < conEnd) && (conEnd <= end))
	  // The new constituent starts in the old.
	  consttt.setEndPosition(start);
	else if ((start <= conStart) && (conStart < end) && (end < conEnd))
	  // The new constituent ends in the old.
	  consttt.setStartPosition(end);
	else if ((start <= conStart) && (conEnd <= end))
	  // The new constituent subsumes the old.
	  consttt.initialize();
      }

	/*  This is Shijian's original code for this function.  The new code
            above appears to work better with the slider without messing up
            the features of the manual constituent setting - kvlinden, 15jan2002
        if ((conStart > start && conStart < end) ||
	    (conEnd > start && conEnd < end))
	  consttt.initialize();
	if ((conStart == start && conEnd > end) )
	  if (_cnlString.substring(end, conEnd).trim() != "")
	    consttt.setStartPosition(end);
	  else
	    consttt.initialize();
	if ((conStart < start && conEnd == end) )
	  if (_cnlString.substring(conStart, start).trim() != "")
	    consttt.setEndPosition(start);
	  else
	    consttt.initialize();
	    */
    }
  }
  
  //SHijian
  //1-11-2001
  /** 
   * if the original head of the constituent's head is outside the
   * 		scope for the constituent, the head will be un-set.
   */
  public void resolveHeadConflicts(String constituentName,int start, int end){
    //resolve constituent conflicks
    Constituent consttt =(Constituent)(_currentTable.getConstituents().
				       elementAt(_currentTable.name2Index(constituentName)));
    int headStart =consttt.headPosition();
    int headLength = consttt.headLength();
    int headEnd = headStart + headLength -1;
	    
    if (headStart < start || headStart > end ||
	headEnd  < start || headEnd > end){
      consttt.setHeadPosition(-1);
      consttt.setHeadLength(0);
    }
      		
  }
  
    //shijian 2001-6-26
  public boolean article(String token)
  {
    if ((token.equals("a")) || (token.equals("an")) || (token.equals("the")))
      return true;  
    else
      return false;
  }
  

}
