gt: 		else if (currentElement.compareTo("constructor") == 0)
context: package jdiff;
  
  import java.util.LinkedList;
  
  /* For SAX parsing in APIHandler */
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.helpers.DefaultHandler;
  
  /**
   * Handle the parsing of an XML file and the generation of an API object.
   * 
   * See the file LICENSE.txt for copyright details.
   * 
   * @author Matthew Doar, mdoar@pobox.com
   */
  class APIHandler extends DefaultHandler
  {
  
  	/** The API object which is populated from the XML file. */
  	public API api_;
  
  	/** Default constructor. */
  	public APIHandler(API api, boolean createGlobalComments)
  	{
  		api_ = api;
  		createGlobalComments_ = createGlobalComments;
  		tagStack = new LinkedList<>();
  	}
  
  	/** If set, then check that each comment is a sentence. */
  	public static boolean checkIsSentence = false;
  
  	/**
  	 * Contains the name of the current package element type where documentation is being added.
  	 * Also used as the level at which to add documentation into an element, i.e. class-level or
  	 * package-level.
  	 */
  	private String currentElement = null;
  
  	/** If set, then create the global list of comments. */
  	private boolean createGlobalComments_ = false;
  
  	/** Set if inside a doc element. */
  	private boolean inDoc = false;
  
  	/** The current comment text being assembled. */
  	private String currentText = null;
  
  	/** The current text from deprecation, null if empty. */
  	private String currentDepText = null;
  
  	/**
  	 * The stack of SingleComment objects awaiting the comment text currently being assembled.
  	 */
  	private LinkedList<String> tagStack = null;
  
  	/** Called at the start of the document. */
  	@Override
  	public void startDocument()
  	{
  	}
  
  	/** Called when the end of the document is reached. */
  	@Override
  	public void endDocument()
  	{
  		if (trace)
  			api_.dump();
  		System.out.println(" finished");
  	}
  
  	/** Called when a new element is started. */
  	@Override
  	public void startElement(java.lang.String uri, java.lang.String localName,
  		java.lang.String qName, Attributes attributes)
  	{
  		// The change to JAXP compliance produced this change.
  		if (localName.equals(""))
  			localName = qName;
  		if (localName.compareTo("api") == 0)
  		{
  			String apiName = attributes.getValue("name");
  			XMLToAPI.nameAPI(apiName);
  		}
  		else if (localName.compareTo("package") == 0)
  		{
  			currentElement = localName;
  			String pkgName = attributes.getValue("name");
  			XMLToAPI.addPackage(pkgName);
  		}
  		else if (localName.compareTo("class") == 0)
  		{
  			currentElement = localName;
  			String className = attributes.getValue("name");
  			String parentName = attributes.getValue("extends");
  			boolean isAbstract = false;
  			if (attributes.getValue("abstract").compareTo("true") == 0)
  				isAbstract = true;
  			XMLToAPI.addClass(className, parentName, isAbstract, getModifiers(attributes));
  		}
  		else if (localName.compareTo("interface") == 0)
  		{
  			currentElement = localName;
  			String className = attributes.getValue("name");
  			String parentName = attributes.getValue("extends");
  			boolean isAbstract = false;
  			if (attributes.getValue("abstract").compareTo("true") == 0)
  				isAbstract = true;
  			XMLToAPI.addInterface(className, parentName, isAbstract, getModifiers(attributes));
  		}
  		else if (localName.compareTo("implements") == 0)
  		{
  			String interfaceName = attributes.getValue("name");
  			XMLToAPI.addImplements(interfaceName);
  		}
  		else if (localName.compareTo("constructor") == 0)
  		{
  			currentElement = localName;
  			String ctorType = attributes.getValue("type");
  			XMLToAPI.addCtor(ctorType, getModifiers(attributes));
  		}
  		else if (localName.compareTo("method") == 0)
  		{
  			currentElement = localName;
  			String methodName = attributes.getValue("name");
  			String returnType = attributes.getValue("return");
  			boolean isAbstract = false;
  			if (attributes.getValue("abstract").compareTo("true") == 0)
  				isAbstract = true;
  			boolean isNative = false;
  			if (attributes.getValue("native").compareTo("true") == 0)
  				isNative = true;
  			boolean isSynchronized = false;
  			if (attributes.getValue("synchronized").compareTo("true") == 0)
  				isSynchronized = true;
  			XMLToAPI.addMethod(methodName, returnType, isAbstract, isNative, isSynchronized,
  				getModifiers(attributes));
  		}
  		else if (localName.compareTo("field") == 0)
  		{
  			currentElement = localName;
  			String fieldName = attributes.getValue("name");
  			String fieldType = attributes.getValue("type");
  			boolean isTransient = false;
  			if (attributes.getValue("transient").compareTo("true") == 0)
  				isTransient = true;
  			boolean isVolatile = false;
  			if (attributes.getValue("volatile").compareTo("true") == 0)
  				isVolatile = true;
  			String value = attributes.getValue("value");
  			XMLToAPI.addField(fieldName, fieldType, isTransient, isVolatile, value,
  				getModifiers(attributes));
  		}
  		else if (localName.compareTo("param") == 0)
  		{
  			String paramName = attributes.getValue("name");
  			String paramType = attributes.getValue("type");
  			XMLToAPI.addParam(paramName, paramType);
  		}
  		else if (localName.compareTo("exception") == 0)
  		{
  			String paramName = attributes.getValue("name");
  			String paramType = attributes.getValue("type");
  			XMLToAPI.addException(paramName, paramType, currentElement);
  		}
  		else if (localName.compareTo("doc") == 0)
  		{
  			inDoc = true;
  			currentText = null;
  		}
  		else
  		{
  			if (inDoc)
  			{
  				// Start of an element, probably an HTML element
  				addStartTagToText(localName, attributes);
  			}
  			else
  			{
  				System.out.println("Error: unknown element type: " + localName);
  				System.exit(-1);
  			}
  		}
  	}
  
  	/** Called when the end of an element is reached. */
  	@Override
  	public void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)
  	{
  		if (localName.equals(""))
  			localName = qName;
  		// Deal with the end of doc blocks
  		if (localName.compareTo("doc") == 0)
  		{
  			inDoc = false;
  			// Add the assembled comment text to the appropriate current
  			// program element, as determined by currentElement.
  			addTextToComments();
  		}
  		else if (inDoc)
  		{
  			// An element was found inside the HTML text
  			addEndTagToText(localName);
  		}
  		else if (currentElement.compareTo("constructor") == 0 &&
  			localName.compareTo("constructor") == 0)
  		{
  			currentElement = "class";
  		}
  		else if (currentElement.compareTo("method") == 0 && localName.compareTo("method") == 0)
  		{
  			currentElement = "class";
  		}
  		else if (currentElement.compareTo("field") == 0 && localName.compareTo("field") == 0)
  		{
  			currentElement = "class";
  		}
  		else if (currentElement.compareTo("class") == 0 ||
  			currentElement.compareTo("interface") == 0)
  		{
  			// Feature request 510307 and bug 517383: duplicate comment ids.
  			// The end of a member element leaves the currentElement at the
  			// "class" level, but the next class may in fact be an interface
  			// and so the currentElement here will be "interface".
  			if (localName.compareTo("class") == 0 || localName.compareTo("interface") == 0)
  			{
  				currentElement = "package";
  			}
  		}
  	}
  
  	/** Called to process text. */
  	@Override
  	public void characters(char[] ch, int start, int length)
  	{
  		if (inDoc)
  		{
  			String chunk = new String(ch, start, length);
  			if (currentText == null)
  				currentText = chunk;
  			else
  				currentText += chunk;
  		}
  	}
  
  	/**
  	 * Trim the current text, check it is a sentence and add it to the current program element.
  	 */
  	public void addTextToComments()
  	{
  		// Eliminate any whitespace at each end of the text.
  		currentText = currentText.trim();
  		// Convert any @link tags to HTML links.
  		if (convertAtLinks)
  		{
  			currentText = Comments.convertAtLinks(currentText, currentElement, api_.currPkg_,
  				api_.currClass_);
  		}
  		// Check that it is a sentence
  		if (checkIsSentence && !currentText.endsWith(".") &&
  			currentText.compareTo(Comments.placeHolderText) != 0)
  		{
  			System.out.println("Warning: text of comment does not end in a period: " + currentText);
  		}
  		// The construction of the commentID assumes that the
  		// documentation is the final element to be parsed. The format matches
  		// the format used in the report generator to look up comments in the
  		// the existingComments object.
  		String commentID = null;
  		// Add this comment to the current API element.
  		if (currentElement.compareTo("package") == 0)
  		{
  			api_.currPkg_.doc_ = currentText;
  			commentID = api_.currPkg_.name_;
  		}
  		else if (currentElement.compareTo("class") == 0 ||
  			currentElement.compareTo("interface") == 0)
  		{
  			api_.currClass_.doc_ = currentText;
  			commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_;
  		}
  