gt: 			e_reaction = (Element) nodes.item(i);
context: //==============================================================================
  //	
  //	Copyright (c) 2002-
  //	Authors:
  //	* Dave Parker <d.a.parker@cs.bham.ac.uk> (University of Birmingham/Oxford)
  //	
  //------------------------------------------------------------------------------
  //	
  //	This file is part of PRISM.
  //	
  //	PRISM is free software; you can redistribute it and/or modify
  //	it under the terms of the GNU General Public License as published by
  //	the Free Software Foundation; either version 2 of the License, or
  //	(at your option) any later version.
  //	
  //	PRISM 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 PRISM; if not, write to the Free Software Foundation,
  //	Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  //	
  //==============================================================================
  
  package prism;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.PrintStream;
  import java.util.ArrayList;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  
  public class SBML2Prism extends Reactions2Prism implements EntityResolver
  {
  	/** Name of the original SBML file */
  	protected String parsedFileName;
  	/** Temporary storage of the parsed XML */
  	protected Document parsedSBML;
  
  	// Constructors
  
  	public SBML2Prism()
  	{
  		super();
  	}
  
  	public SBML2Prism(PrismLog mainLog)
  	{
  		super(mainLog);
  	}
  
  	@Override
  	public String getName()
  	{
  		return "sbml";
  	}
  
  	@Override
  	public void load(File file) throws PrismException
  	{
  		// Store filename for later use before parsing
  		parsedFileName = file.getPath();
  		super.load(file);
  	}
  
  	@Override
  	public void load(InputStream in) throws PrismException
  	{
  		DocumentBuilderFactory factory;
  		DocumentBuilder builder;
  		parsedSBML = null;
  
  		// Create XML parser
  		factory = DocumentBuilderFactory.newInstance();
  		factory.setValidating(false);
  		factory.setIgnoringElementContentWhitespace(true);
  		try {
  			builder = factory.newDocumentBuilder();
  			builder.setEntityResolver(this);
  			builder.setErrorHandler(new ErrorHandler()
  			{
  				public void fatalError(SAXParseException e) throws SAXException
  				{
  					throw e;
  				}
  
  				public void error(SAXParseException e) throws SAXException
  				{
  					throw e;
  				}
  
  				public void warning(SAXParseException e)
  				{
  				}
  			});
  		} catch (ParserConfigurationException e) {
  			throw new PrismException("Couldn't create XML parser");
  		}
  
  		// Parse XML
  		try {
  			parsedSBML = builder.parse(in);
  		} catch (IOException e) {
  			throw new PrismException("Error reading SBML: " + e.getMessage());
  		} catch (SAXException e) {
  			throw new PrismException("Invalid XML file:\n" + e.getMessage());
  		}
  	}
  
  	/**
  	 * Function used by parseSBML() above to find the SBML DTD
  	 * (this currently unused since we do not validate the SBML file when reading)
  	 * (and since the DTD specified in the SBML files is not local)
  	 * (if validation is enabled, put the DTD file "sbml.dtd" in PRISM's "dtds" directory)
  	 */
  	public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
  	{
  		InputSource inputSource = null;
  
  		// override the resolve method for the dtd
  		if (systemId.endsWith("dtd")) {
  			// get appropriate dtd from classpath
  			InputStream inputStream = this.getClass().getResourceAsStream("dtds/sbml.dtd");
  			if (inputStream != null)
  				inputSource = new InputSource(inputStream);
  		}
  
  		return inputSource;
  	}
  
  	@Override
  	public void translate(PrintStream out) throws PrismException
  	{
  		checkSBMLVersion(parsedSBML);
  		extractModelFromSBML(parsedSBML);
  		// Generate PRISM code
  		prismCodeHeader = "// File generated by automatic SBML-to-PRISM conversion\n";
  		if (parsedFileName != null) {
  			prismCodeHeader += "// Original SBML file: " + parsedFileName + "\n\n";
  		}
  		convertToPRISMCode(out);
  		// Reset filename storage
  		parsedFileName = null;
  	}
  
  	/**
  	 * Check that we can handle whatever level/version this file is.
  	 */
  	private void checkSBMLVersion(Document doc) throws PrismException
  	{
  		String level, s;
  
  		level = doc.getDocumentElement().getAttribute("level");
  		if (!("2".equals(level))) {
  			s = "The translator only handles Level 2 SBML files - this is a Level " + level + " file";
  			throw new PrismException(s);
  		}
  	}
  
  	/**
  	 * Build the reaction set model from a parsed SBML file.
  	 */
  	private void extractModelFromSBML(Document doc) throws PrismException
  	{
  		Element e, e_model, e_list;
  		Element e_comp, e_species, e_parameter, e_reaction, e_kinetics, e_mathml;
  		NodeList nodes, nodes2;
  		Node node = null;
  		Species species;
  		Parameter parameter;
  		Reaction reaction;
  		int i, j, k, n, m;
  		double d;
  		String s, s2;
  		boolean found;
  
  		// Get "model" element of SBML file
  		nodes = doc.getDocumentElement().getElementsByTagName("model");
  		e_model = (Element) nodes.item(0);
  
  		// Process compartment info (if present)
  		// Just need to extract the size in case used
  		e_list = (Element) e_model.getElementsByTagName("listOfCompartments").item(0);
  		nodes = e_list.getElementsByTagName("compartment");
  		n = nodes.getLength();
  		// Make sure there is at most one
  		if (n > 1)
  			throw new PrismException("Only one compartment is permitted");
  		// And if present, store size info
  		compartmentName = null;
  		if (n == 1) {
  			e_comp = (Element) nodes.item(0);
  			if (!"".equals(e_comp.getAttribute("size"))) {
  				compartmentName = e_comp.getAttribute("id");
  				if ("".equals(compartmentName))
  					throw new PrismException("Missing compartment name");
  				compartmentSize = Double.parseDouble(e_comp.getAttribute("size"));
  			}
  		}
  
  		// Process list of species
  		speciesList = new ArrayList<Species>();
  		e_list = (Element) e_model.getElementsByTagName("listOfSpecies").item(0);
  		nodes = e_list.getElementsByTagName("species");
  		n = nodes.getLength();
  		for (i = 0; i < n; i++) {
  			e_species = (Element) nodes.item(i);
  			speciesId = e_species.getAttribute("id");
  			initialAmountString = e_species.getAttribute("initialAmount");
  			if ("".equals(initialAmountString))
  				throw new PrismException("Missing initial amount for species " + speciesId);
  			try {
  				d = Double.parseDouble(initialAmountString);
  			} catch (NumberFormatException nfe) {
  				String msg = "Badly formatted initialAmount \"" + initialAmountString + "\" for species " + speciesId;
  				throw new PrismException(msg);
  			}
  			species = new Species(speciesId, e_species.getAttribute("name"), d);
  			s = e_species.getAttribute("boundaryCondition");
  			if (s.equals("true"))
  				species.boundaryCondition = true;
  			speciesList.add(species);
  		}
  
  		// Process list of parameters (if present)
  		parameterList = new ArrayList<Parameter>();
  		// Look at direct children only (there might be listOfParameters nodes lower in the tree)
  		nodes = e_model.getChildNodes();
  		n = nodes.getLength();
  		found = false;
  		for (i = 0; i < n; i++) {
  			node = nodes.item(i);
  			if ("listOfParameters".equals(node.getNodeName())) {
  				found = true;
  				break;
  			}
  		}
  		if (found) {
  			e_list = (Element) node;
  			nodes = e_list.getElementsByTagName("parameter");
  			n = nodes.getLength();
  			for (i = 0; i < n; i++) {
  				e_parameter = (Element) nodes.item(i);
  				parameter = new Parameter(e_parameter.getAttribute("id"), e_parameter.getAttribute("value"));
  				parameterList.add(parameter);
  			}
  		}
  
  		// Process list of reactions
  		reactionList = new ArrayList<Reaction>();
  		e_list = (Element) e_model.getElementsByTagName("listOfReactions").item(0);
  		nodes = e_list.getElementsByTagName("reaction");
  		n = nodes.getLength();
  		for (i = 0; i < n; i++) {
  
  			// Process a single reaction...
  