It takes a KAF document calls to getParse() and outputs the parse tree as
KAF constituents elements.

@param kaf
document containing WF and Term elements
@throws IOException
if io error
772800
public void parseToKAF(final KAFDocument kaf) throws IOException {
    final StringBuffer parsingDoc = getParse(kaf);
    try {
      kaf.addConstituencyFromParentheses(parsingDoc.toString());
    } catch (final Exception e) {
      e.printStackTrace();
    }
  }
203611
public static KAFDocument createFromStream(Reader stream) throws IOException, JDOMException {
	KAFDocument kaf = null;
	kaf = ReadWriteManager.load(stream);
	return kaf;
    }
573123
public List<String> getAllWFIdsFromTerms(KAFDocument kaf) {
    List<Term> terms = kaf.getTerms();
    List<String> wfTermIds = new ArrayList<>();
    for (int i = 0; i < terms.size(); i++) {
      List<WF> sentTerms = terms.get(i).getWFs();
      for (WF form : sentTerms) {
        wfTermIds.add(form.getId());
      }
    }
    return wfTermIds;
  }
810120
private String getAnnotations(final Properties properties,
      final String stringFromClient) throws IOException, JDOMException {

    BufferedReader breader;
    KAFDocument kaf;
    String kafString = null;
    String lang = properties.getProperty("language");
    String outputFormat = properties.getProperty("outputFormat");
    Boolean inputKafRaw = Boolean.valueOf(properties.getProperty("inputkaf"));
    Boolean noTok = Boolean.valueOf(properties.getProperty("notok"));
    String kafVersion = properties.getProperty("kafversion");
    Boolean offsets = Boolean.valueOf(properties.getProperty("offsets"));
    if (noTok) {
      final BufferedReader noTokReader = new BufferedReader(
          new StringReader(stringFromClient));
      kaf = new KAFDocument(lang, kafVersion);
      final KAFDocument.LinguisticProcessor newLp = kaf.addLinguisticProcessor(
          "text", "ixa-pipe-tok-notok-" + lang, version + "-" + commit);
      newLp.setBeginTimestamp();
      Annotate.tokensToKAF(noTokReader, kaf);
      newLp.setEndTimestamp();
      kafString = kaf.toString();
      noTokReader.close();
    } else {
      if (inputKafRaw) {
        final BufferedReader kafReader = new BufferedReader(
            new StringReader(stringFromClient));
        kaf = KAFDocument.createFromStream(kafReader);
        final String text = kaf.getRawText();
        final StringReader stringReader = new StringReader(text);
        breader = new BufferedReader(stringReader);
      } else {
        kaf = new KAFDocument(lang, kafVersion);
        breader = new BufferedReader(new StringReader(stringFromClient));
      }
      final Annotate annotator = new Annotate(breader, properties);
      if (outputFormat.equalsIgnoreCase("conll")) {
        if (offsets) {
          kafString = annotator.tokenizeToCoNLL();
        } else {
          kafString = annotator.tokenizeToCoNLLOffsets();
        }
      } else if (outputFormat.equalsIgnoreCase("oneline")) {
        kafString = annotator.tokenizeToText();
      } else {
        final KAFDocument.LinguisticProcessor newLp = kaf
            .addLinguisticProcessor("text", "ixa-pipe-tok-" + lang,
                version + "-" + commit);
        newLp.setBeginTimestamp();
        annotator.tokenizeToKAF(kaf);
        newLp.setEndTimestamp();
        kafString = kaf.toString();
      }
      breader.close();
    }
    return kafString;
  }
477903
public static Element parse(InputSource source) throws IOException
   {
      try
      {
         Document doc;
         DocumentBuilder builder = getDocumentBuilder();
         synchronized (builder) //synchronize to prevent concurrent parsing on the same DocumentBuilder
         {
            doc = builder.parse(source);
         }
         return doc.getDocumentElement();
      }
      catch (SAXException se)
      {
         throw new IOException(se.toString());
      }
      finally
      {
         InputStream is = source.getByteStream();
         if (is != null)
         {
            is.close();
         }
         Reader r = source.getCharacterStream();
         if (r != null)
         {
            r.close();
         }
      }
   }
1020674
protected Document parseContent(final InputStream in) throws Throwable {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);

    DocumentBuilder builder = factory.newDocumentBuilder();

    return builder.parse(new InputSource(new InputStreamReader(in)));
  }
17180
private final void parseDocument(Node currentNode) {
	    	try {
	    		mutex.acquire();
	        String nodeName = currentNode.getNodeName();
	
	        if ((currentNode.getNodeType() == Node.ELEMENT_NODE)
	                && (nodeName.equals("type"))
	        ) {
	            String typeName = ((Element) currentNode).getAttribute("name");
	            mapFilter.put(
	                typeName + ".filter",
	                new ArrayList()
	            );
	            mapFilter.put(
	                typeName + ".tag",
	                new ArrayList()
	            );
	            mapFilter.put(
	                typeName + ".merge",
	                new ArrayList()
	            );
	        }
	
	        if ((currentNode.getNodeType() == Node.ELEMENT_NODE)
	                && (currentNode.getParentNode() != null)
	        ) {
	            if (nodeName.equals("filter")) {
	                String typeName =
	                    ((Element) currentNode.getParentNode()
	                                          .getParentNode()).getAttribute(
	                        "name"
	                    );
	                ArrayList vMapFilter =
	                    (ArrayList) mapFilter.get(typeName + ".filter");
	                ArrayList vFilter = new ArrayList();
	                int iOrder =
	                    ((Element) currentNode).getAttribute("order")
	                     .equals("")
	                    ? vMapFilter.size()
	                    : Integer.parseInt(
	                        ((Element) currentNode).getAttribute("order")
	                    );
	                String replacement = "";
	                NodeList nl = currentNode.getChildNodes();
	
	                for (int i = 0; i < nl.getLength(); i++) {
	                    Node childNode = nl.item(i);
	
	                    if (childNode.getNodeName()
	                                     .equals("replacement")) {
	                        NodeList nl2 = childNode.getChildNodes();
	
	                        for (int j = 0; j < nl2.getLength(); j++) {
	                            Node child = nl2.item(j);
	
	                            if (child.getNodeType() == Node.TEXT_NODE) {
	                                replacement =
	                                    replacement + child.getNodeValue();
	                            }
	                        }
	                    } else if (childNode.getNodeName()
	                                            .equals("match")) {
	                        String match = "";
	                        NodeList nl2 = childNode.getChildNodes();
	
	                        for (int j = 0; j < nl2.getLength(); j++) {
	                            Node child = nl2.item(j);
	
	                            if (child.getNodeType() == Node.TEXT_NODE) {
	                                match = match + child.getNodeValue();
	                            }
	                        }
	
	                        Pattern p = null;
	
	                        try {
	                            p = Pattern.compile(
	                                    match,
	                                    Pattern.MULTILINE | Pattern.DOTALL
	                                );
	                            vFilter.add(p);
	                        } catch (Exception ignore) {
	                        }
	                    }
	                }
	
	                vMapFilter.add(
	                    iOrder,
	                    new Object[] {
	                        replacement,
	                        vFilter
	                    }
	                );
	            } else if ((nodeName.equals("tag"))
	                    && (
	                        currentNode.getParentNode().getNodeName().equals(
	                            "tags"
	                        )
	                    )
	            ) {
	                String typeName =
	                    ((Element) currentNode.getParentNode()
	                                          .getParentNode()
	                                          .getParentNode()).getAttribute(
	                        "name"
	                    );
	                String tagName = ((Element) currentNode).getAttribute("name");
	                ArrayList vMapTags =
	                    (ArrayList) mapFilter.get(typeName + ".tag");
	                ArrayList vAttributes = new ArrayList();
	                NodeList nl = currentNode.getChildNodes();
	
	                for (int i = 0; i < nl.getLength(); i++) {
	                    Node childNode = nl.item(i);
	
	                    if (childNode.getNodeName()
	                                     .equals("attribute")) {
	                        vAttributes.add(
	                            (String) ((Element) childNode).getAttribute("name")
	                        );
	                    }
	                }
	
	                vMapTags.add(new Object[] {
	                        tagName,
	                        vAttributes
	                    }
	                );
	            } else if (nodeName.equals("source_attribute")) {
	                String typeName =
	                    ((Element) currentNode.getParentNode()
	                                          .getParentNode()
	                                          .getParentNode()
	                                          .getParentNode()).getAttribute(
	                        "name"
	                    );
	                String tagName =
	                    ((Element) currentNode.getParentNode()).getAttribute(
	                        "name"
	                    );
	                String attribName =
	                    ((Element) currentNode).getAttribute("name");
	                String srcAttribNameInDest =
	                    ((Element) currentNode).getAttribute("name_in_destination");
	                ArrayList vMapMerge =
	                    (ArrayList) mapFilter.get(typeName + ".merge");
	                String separator = null;
	                String destAttribName = null;
	                ArrayList match = new ArrayList();
	                ArrayList value = new ArrayList();
	                NodeList nl = currentNode.getChildNodes();
	
	                for (int i = 0; i < nl.getLength(); i++) {
	                    Node childNode = nl.item(i);
	
	                    if (childNode.getNodeName()
	                                     .equals("destination_attribute")) {
	                        destAttribName =
	                            ((Element) childNode).getAttribute("name");
	                    } else if (childNode.getNodeName()
	                                            .equals("separator")) {
	                        separator = ((Element) childNode).getAttribute("value");
	                    } else if (childNode.getNodeName()
	                                            .equals("replace")) {
	                        match.add(((Element) childNode).getAttribute("match"));
	                        value.add(((Element) childNode).getAttribute("value"));
	                    }
	                }
	
	                vMapMerge.add(
	                    new Object[] {
	                        tagName,
	                        attribName,
	                        srcAttribNameInDest,
	                        destAttribName,
	                        separator,
	                        match,
	                        value
	                    }
	                );
	            }
	        }
	
	        NodeList nl = currentNode.getChildNodes();
	
	        for (int i = 0; i < nl.getLength(); i++) {
	            parseDocument(nl.item(i));
	        }
	    	}
	    	finally {
	    		try{mutex.release();}catch(Throwable ignore){}
	    	}
    }
283102
def to_kaf(self):
        
        if self.type == 'NAF':
            self.type = 'KAF'
            for node in self.__get_node_terms():
                node.set('cid', node.get('id'))
                del node.attrib['id']
292988
public static Parse parseParse(String parse) {
    StringBuffer text = new StringBuffer();
    int offset = 0;
    Stack stack = new Stack();
    List cons = new LinkedList();
    for (int ci = 0, cl = parse.length(); ci < cl; ci++) {
      char c = parse.charAt(ci);
      if (c == '(') {
        String rest = parse.substring(ci + 1);
        String type = getType(rest);
        if (type == null) {
          System.err.println("null type for: " + rest);
        }
        String token = getToken(rest);
        stack.push(new Object[] { type, new Integer(offset)});
        if (token != null && !type.equals("-NONE-")) {
          cons.add(new Object[] { ParserME.TOK_NODE, new Span(offset, offset + token.length())});
          text.append(token).append(" ");
          offset += token.length() + 1;
        }
      }
      else if (c == ')') {
        Object[] parts = (Object[]) stack.pop();
        String type = (String) parts[0];
        if (!type.equals("-NONE-")) {
          int start = ((Integer) parts[1]).intValue();
          cons.add(new Object[] { parts[0], new Span(start, offset - 1)});
        }
      }
    }
    String txt = text.toString();
    Parse p = new Parse(txt, new Span(0, txt.length()), ParserME.TOP_NODE, 1);
    /*
    for (int ti=0;ti < tokens.size();ti++) {
      Object[] parts = (Object[]) cons.get(ti);
      String type = (String) parts[0];
      if (!type.equals(ParserME.TOP_NODE)) {
        Parse con = new Parse(txt, (Span) parts[1], type, 1);
        System.err.println("insert "+type+" "+con.toString());
        p.insert(con);
      }
    }
    */
    for (int ci=0;ci < cons.size();ci++) {
      Object[] parts = (Object[]) cons.get(ci);
      String type = (String) parts[0];
      if (!type.equals(ParserME.TOP_NODE)) {
        Parse con = new Parse(txt, (Span) parts[1], type, 1);
        //System.err.println("insert["+ci+"] "+type+" "+con.toString()+" "+con.hashCode());
        p.insert(con);
        //codeTree(p);
      }
    }
    return p;
  }
1366714
public static void convertPKUtoCWS(String inputFolder, String outputFile, final int begin, final int end) throws IOException
    {
        final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
        CorpusLoader.walk(inputFolder, new CorpusLoader.Handler()
                          {
                              int doc = 0;

                              @Override
                              public void handle(Document document)
                              {
                                  ++doc;
                                  if (doc < begin || doc > end) return;
                                  try
                                  {
                                      List<List<Word>> sentenceList = convertComplexWordToSimpleWord(document.getComplexSentenceList());
                                      if (sentenceList.size() == 0) return;
                                      for (List<Word> sentence : sentenceList)
                                      {
                                          if (sentence.size() == 0) continue;
                                          int index = 0;
                                          for (IWord iWord : sentence)
                                          {
                                              bw.write(iWord.getValue());
                                              if (++index != sentence.size())
                                              {
                                                  bw.write(' ');
                                              }
                                          }
                                          bw.newLine();
                                      }
                                  }
                                  catch (IOException e)
                                  {
                                      e.printStackTrace();
                                  }
                              }
                          }

        );
        bw.close();
    }
462267
protected void parse(Node node) {
		parsed = true;
		NodeList childNodes = node.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++) {
			Node child = childNodes.item(i);
			String nodeName = child.getNodeName();
			if ("Name".equalsIgnoreCase(nodeName)) {
				name = getValueRecursive(child);
			} else if ("Title".equalsIgnoreCase(nodeName)) {
				title = getValueRecursive(child);
			} else if ("Abstract".equalsIgnoreCase(nodeName)) {
				abstractt = getValueRecursive(child);
			} else if ("Keywords".equalsIgnoreCase(nodeName)) {
				addKeyWords(child);
			} else if ("SRS".equalsIgnoreCase(nodeName)) {
				defaultCrs = getValueRecursive(child);
			} else if ("LatLongBoundingBox".equalsIgnoreCase(nodeName)) {
				addLatLonBoundingBox(child);
			}
		}
	}
1041592
static KAFDocument load(Reader stream) throws IOException, JDOMException, KAFNotValidException {
	SAXBuilder builder = new SAXBuilder();
	Document document = (Document) builder.build(stream);
	Element rootElem = document.getRootElement();
	return DOMToKAF(document);
    }
338926
protected Map<String, Object> readDocument() throws IOException {
		ObjectCodec codec = getCodec();
		if (codec == null) {
			throw new IllegalStateException("Could not parse embedded document " +
					"because BSON parser has no codec");
		}
		_currToken = handleNewDocument(false);
		return codec.readValue(this, new TypeReference<Map<String, Object>>() {});
	}
421408
public void setFields(XfdfReader xfdf) throws IOException, DocumentException {
        HashMap fd = xfdf.getFields();
        for (Iterator i = fd.keySet().iterator(); i.hasNext();) {
            String f = (String)i.next();
            String v = xfdf.getFieldValue(f);
            if (v != null)
                setField(f, v);
            List l = xfdf.getListValues(f);
            if (l != null)
            	setListSelection(v, (String[])l.toArray(new String[l.size()]));
        }
    }
877577
private void initDocumentParser() throws ParserConfigurationException {

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();

    docBuilderFactory.setNamespaceAware(false);
    docBuilderFactory.setValidating(true);

    docBuilderFactory.setAttribute(
        "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
        "http://www.w3.org/2001/XMLSchema");

    docBuilderFactory.setAttribute(
        "http://java.sun.com/xml/jaxp/properties/schemaSource", resolveSchemaSource());

    docBuilder = docBuilderFactory.newDocumentBuilder();

    docBuilder.setErrorHandler(this);

    xpath = XPathFactory.newInstance().newXPath();
  }
60807
public void parse() throws ResourceXMLParserException, IOException {
        final EntityResolver resolver = createEntityResolver();
        final SAXReader reader = new SAXReader(false);
        reader.setEntityResolver(resolver);

        try {

            final Document doc;
            if(null==this.doc){
                final InputStream in;
                if(null!=file){
                    in = new FileInputStream(file);
                }else{
                    in = input;
                }
                try{
                    doc=reader.read(in);
                }finally{
                    if(null!=file){
                        in.close();
                    }
                }
            }else{
                doc=this.doc;
            }

            final EntitySet set = new EntitySet();
            final Element root = doc.getRootElement();

            final List list = root.selectNodes(entityXpath);
            for (final Object n : list) {
                final Node node = (Node) n;
                final Entity ent = parseEnt(node, set);
                if (null != receiver) {
                    if (!receiver.resourceParsed(ent)) {
                        break;
                    }
                }
            }
            if (null != receiver) {
                receiver.resourcesParsed(set);
            }

        } catch (DocumentException e) {
            throw new ResourceXMLParserException(e);
        }
    }
1342972
private static KAFDocument DOMToKAF(Document dom) throws KAFNotValidException {
	HashMap<String, WF> wfIndex = new HashMap<String, WF>();
	HashMap<String, Term> termIndex = new HashMap<String, Term>();
	HashMap<String, Relational> relationalIndex = new HashMap<String, Relational>();
	HashMap<String, Predicate> predicateIndex = new HashMap<String, Predicate>();
	HashMap<String, Timex3> timexIndex = new HashMap<String, Timex3>();
	Element rootElem = dom.getRootElement();
	String lang = getAttribute("lang", rootElem, Namespace.XML_NAMESPACE);
	String kafVersion = getAttribute("version", rootElem);
	KAFDocument kaf = new KAFDocument(lang, kafVersion);

	List<Element> rootChildrenElems = rootElem.getChildren();

	Element elem = rootElem.getChild("nafHeader");
	if (elem != null) {
	    List<Element> lpsElems = elem.getChildren("linguisticProcessors");
	    for (Element lpsElem : lpsElems) {
		String layer = getAttribute("layer", lpsElem);
		List<Element> lpElems = lpsElem.getChildren();
		for (Element lpElem : lpElems) {
		    String name = getAttribute("name", lpElem);
		    KAFDocument.LinguisticProcessor newLp = kaf.addLinguisticProcessor(layer, name);
		    String timestamp = getOptAttribute("timestamp", lpElem);
		    if (timestamp != null) {
			newLp.setTimestamp(timestamp);
		    }
		    String beginTimestamp = getOptAttribute("beginTimestamp", lpElem);
		    if (beginTimestamp != null) {
			newLp.beginTimestamp = beginTimestamp;
		    }
		    String endTimestamp = getOptAttribute("endTimestamp", lpElem);
		    if (endTimestamp != null) {
			newLp.setEndTimestamp(endTimestamp);
		    }
		    String version = getOptAttribute("version", lpElem);
		    if (version != null) {
			newLp.setVersion(version);
		    }
		    String hostname = getOptAttribute("hostname", lpElem);
		    if (hostname != null) {
			newLp.setHostname(hostname);
		    }
		}
	    }
	    Element fileDescElem = elem.getChild("fileDesc");
	    if (fileDescElem != null) {
		KAFDocument.FileDesc fd = kaf.createFileDesc();
		String author = getOptAttribute("author", fileDescElem);
		if (author != null) {
		    fd.author = author;
		}
		String title = getOptAttribute("title", fileDescElem);
		if (title != null) {
		    fd.title = title;
		}
		String publisher = getOptAttribute("publisher", fileDescElem);
		if (publisher != null) {
		    fd.publisher = publisher;
		}
		String section = getOptAttribute("section", fileDescElem);
		if (section != null) {
		    fd.section = section;
		}
		String location = getOptAttribute("location", fileDescElem);
		if (location != null) {
		    fd.location = location;
		}
		String magazine = getOptAttribute("magazine", fileDescElem);
		if (magazine != null) {
		    fd.magazine = magazine;
		}
		String filename = getOptAttribute("filename", fileDescElem);
		if (filename != null) {
		    fd.filename = filename;
		}
		String filetype = getOptAttribute("filetype", fileDescElem);
		if (filetype != null) {
		    fd.filetype = filetype;
		}
		String pages = getOptAttribute("pages", fileDescElem);
		if (pages != null) {
		    fd.pages = Integer.parseInt(pages);
		}
		String creationtime = getOptAttribute("creationtime", fileDescElem);
		if (creationtime != null) {
		    fd.creationtime = creationtime;
		}
	    }
	    Element publicElem = elem.getChild("public");
	    if (publicElem != null) {
		KAFDocument.Public pub = kaf.createPublic();
		String publicId = getOptAttribute("publicId", publicElem);
		if (publicId != null) {
		    pub.publicId = publicId;
		}
		String uri = getOptAttribute("uri", publicElem);
		if (uri != null) {
		    pub.uri = uri;
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("raw");
	if (elem != null) {
	    kaf.setRawText(elem.getText());
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("text");
	if (elem != null) {
	    List<Element> wfElems = elem.getChildren();
	    for (Element wfElem : wfElems) {
		String wid = getAttribute("id", wfElem);
		String wOffset = getAttribute("offset", wfElem);
		String wLength = getAttribute("length", wfElem);
		String wForm = wfElem.getText();
		String wSent = getAttribute("sent", wfElem);
		WF newWf = kaf.newWF(wid, Integer.valueOf(wOffset), Integer.valueOf(wLength), wForm, Integer.valueOf(wSent));
		String wPara = getOptAttribute("para", wfElem);
		if (wPara != null) {
		    newWf.setPara(Integer.valueOf(wPara));
		}
		String wPage = getOptAttribute("page", wfElem);
		if (wPage != null) {
		    newWf.setPage(Integer.valueOf(wPage));
		}
		String wXpath = getOptAttribute("xpath", wfElem);
		if (wXpath != null) {
		    newWf.setXpath(wXpath);
		}
		wfIndex.put(newWf.getId(), newWf);
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("terms");
	if (elem != null) {
	    List<Element> termElems = elem.getChildren();
	    for (Element termElem : termElems) {
		DOMToTerm(termElem, kaf, false, wfIndex, termIndex, null);
	    }
	    rootChildrenElems.remove(elem);
	}

	elem = rootElem.getChild("entities");
	if (elem != null) {
	    List<Element> entityElems = elem.getChildren();
	    for (Element entityElem : entityElems) {
		String entId = getAttribute("id", entityElem);
		List<Element> referencesElem = entityElem.getChildren("references");
		if (referencesElem.size() < 1) {
		    throw new IllegalStateException("Every entity must contain a 'references' element");
		}
		List<Element> spanElems = referencesElem.get(0).getChildren();
		if (spanElems.size() < 1) {
		    throw new IllegalStateException("Every entity must contain a 'span' element inside 'references'");
		}
		List<Span<Term>> references = new ArrayList<Span<Term>>();
		for (Element spanElem : spanElems) {
		    Span<Term> span = kaf.newTermSpan();
		    List<Element> targetElems = spanElem.getChildren();
		    if (targetElems.size() < 1) {
			throw new IllegalStateException("Every span in an entity must contain at least one target inside");  
		    }
		    for (Element targetElem : targetElems) {
			String targetTermId = getAttribute("id", targetElem);
			Term targetTerm = termIndex.get(targetTermId);
			if (targetTerm == null) {
			    throw new KAFNotValidException("Term " + targetTermId + " not found when loading entity " + entId);
			}
			boolean isHead = isHead(targetElem);
			span.addTarget(targetTerm, isHead);
		    }
		    references.add(span);
		}
		Entity newEntity = kaf.newEntity(entId, references);
		String entType = getOptAttribute("type", entityElem);
		if (entType != null) {
		    newEntity.setType(entType);
		}
		String entSource= getOptAttribute("source", entityElem);
		if (entSource != null) {
		    newEntity.setSource(entSource);
		}
		List<Element> externalReferencesElems = entityElem.getChildren("externalReferences");
		if (externalReferencesElems.size() > 0) {
		    List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
		    newEntity.addExternalRefs(externalRefs);
		}
		relationalIndex.put(newEntity.getId(), newEntity);
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("constituency");
	if (elem != null) {
	    List<Element> treeElems = elem.getChildren("tree");
	    for (Element treeElem : treeElems) {
		String type = getOptAttribute("type", treeElem);
		HashMap<String, TreeNode> treeNodes = new HashMap<String, TreeNode>();
		HashMap<String, Boolean> rootNodes = new HashMap<String, Boolean>();
		// Terminals
		List<Element> terminalElems = treeElem.getChildren("t");
		for (Element terminalElem : terminalElems) {
		    String id = getAttribute("id", terminalElem);
		    Element spanElem = terminalElem.getChild("span");
		    if (spanElem == null) {
			throw new KAFNotValidException("Constituent non terminal nodes need a span");
		    }
		    Span<Term> span = loadTermSpan(spanElem, termIndex, id);
		    treeNodes.put(id, kaf.newTerminal(id, span));
		    rootNodes.put(id, true);
		}
		// NonTerminals
		List<Element> nonTerminalElems = treeElem.getChildren("nt");
		for (Element nonTerminalElem : nonTerminalElems) {
		    String id = getAttribute("id", nonTerminalElem);
		    String label = getAttribute("label", nonTerminalElem);
		    treeNodes.put(id, kaf.newNonTerminal(id, label));
		    rootNodes.put(id, true);
		}
		// Edges
		List<Element> edgeElems = treeElem.getChildren("edge");
		for (Element edgeElem : edgeElems) {
		    String fromId = getAttribute("from", edgeElem);
		    String toId = getAttribute("to", edgeElem);
		    String edgeId = getOptAttribute("id", edgeElem);
		    String head = getOptAttribute("head", edgeElem);
		    boolean isHead = (head != null && head.equals("yes")) ? true : false;
		    TreeNode parentNode = treeNodes.get(toId);
		    TreeNode childNode = treeNodes.get(fromId);
		    if ((parentNode == null) || (childNode == null)) {
			throw new KAFNotValidException("There is a problem with the edge(" + fromId + ", " + toId + "). One of its targets doesn't exist.");
		    }
		    try {
			((NonTerminal) parentNode).addChild(childNode);
		    } catch(Exception e) {}
		    rootNodes.put(fromId, false);
		    if (edgeId != null) {
			childNode.setEdgeId(edgeId);
		    }
		    if (isHead) {
			((NonTerminal) childNode).setHead(isHead);
		    }
		}
		// Constituent objects
		for (Map.Entry<String, Boolean> areRoot : rootNodes.entrySet()) {
		    if (areRoot.getValue()) {
			TreeNode rootNode = treeNodes.get(areRoot.getKey());
			if (type == null) {
			    kaf.newConstituent(rootNode);
			} else {
			    kaf.newConstituent(rootNode, type);
			}
		    }
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("chunks");
	if (elem != null) {
	    //System.out.println("chunks");
	    List<Element> chunkElems = elem.getChildren();
	    for (Element chunkElem : chunkElems) {
		String chunkId = getAttribute("id", chunkElem);
		String headId = getAttribute("head", chunkElem);
		Term chunkHead = termIndex.get(headId);
		if (chunkHead == null) {
		    throw new KAFNotValidException("Term " + headId + " not found when loading chunk " + chunkId);
		}
		Element spanElem = chunkElem.getChild("span");
		if (spanElem == null) {
		    throw new IllegalStateException("Every chunk must contain a span element");
		}
		List<Element> chunksTermElems = spanElem.getChildren("target");
		Span<Term> span = kaf.newTermSpan();
		for (Element chunksTermElem : chunksTermElems) {
		    String termId = getAttribute("id", chunksTermElem);
		    boolean isHead = isHead(chunksTermElem);
		    Term targetTerm = termIndex.get(termId);
		    if (targetTerm == null) {
			throw new KAFNotValidException("Term " + termId + " not found when loading chunk " + chunkId);
		    }
		    span.addTarget(targetTerm, ((targetTerm == chunkHead) || isHead));
		}
		if (!span.hasTarget(chunkHead)) {
		    throw new KAFNotValidException("The head of the chunk is not in it's span.");
		}
		Chunk newChunk = kaf.newChunk(chunkId, span);
		String chunkPhrase = getOptAttribute("phrase", chunkElem);
		if (chunkPhrase != null) {
		    newChunk.setPhrase(chunkPhrase);
		}
		String chunkCase = getOptAttribute("case", chunkElem);
		if (chunkCase != null) {
		    newChunk.setCase(chunkCase);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("coreferences");
	if (elem != null) {
	    List<Element> corefElems = elem.getChildren();
	    for (Element corefElem : corefElems) {
		String coId = getAttribute("id", corefElem);
		List<Element> spanElems = corefElem.getChildren("span");
		if (spanElems.size() < 1) {
		    throw new IllegalStateException("Every coref must contain a 'span' element inside 'references'");
		}
		List<Span<Term>> mentions = new ArrayList<Span<Term>>();
		for (Element spanElem : spanElems) {
		    Span<Term> span = kaf.newTermSpan();
		    List<Element> targetElems = spanElem.getChildren();
		    if (targetElems.size() < 1) {
			throw new IllegalStateException("Every span in an entity must contain at least one target inside");  
		    }
		    for (Element targetElem : targetElems) {
			String targetTermId = getAttribute("id", targetElem);
			Term targetTerm = termIndex.get(targetTermId);
			if (targetTerm == null) {
			    throw new KAFNotValidException("Term " + targetTermId + " not found when loading coref " + coId);
			}
			boolean isHead = isHead(targetElem);
			span.addTarget(targetTerm, isHead);
		    }
		    mentions.add(span);
		}
		Coref newCoref = kaf.newCoref(coId, mentions);
		String corefType = getOptAttribute("type", corefElem);
		if (corefType != null) {
		    newCoref.setType(corefType);
		}
		List<Element> externalReferencesElems = corefElem.getChildren("externalReferences");
		if (externalReferencesElems.size() > 0) {
		    List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
		    newCoref.addExternalRefs(externalRefs);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("opinions");
	if (elem != null) {	    List<Element> opinionElems = elem.getChildren("opinion");
	    for (Element opinionElem : opinionElems) {
		String opinionId = getAttribute("id", opinionElem);
		Opinion opinion = kaf.newOpinion(opinionId);
		Element opinionHolderElem = opinionElem.getChild("opinion_holder");
		if (opinionHolderElem != null) {
		    Span<Term> span = kaf.newTermSpan();
		    Opinion.OpinionHolder opinionHolder = opinion.createOpinionHolder(span);
		    String ohType = getOptAttribute("type", opinionHolderElem);
		    if (ohType != null) {
			opinionHolder.setType(ohType);
		    }
		    Element spanElem = opinionHolderElem.getChild("span");
		    if (spanElem != null) {
			List<Element> targetElems = spanElem.getChildren("target");
			for (Element targetElem : targetElems) {
			    String refId = getOptAttribute("id", targetElem);
			    boolean isHead = isHead(targetElem);
			    Term targetTerm = termIndex.get(refId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term " + refId + " not found when loading opinion " + opinionId);
			    }
			    span.addTarget(targetTerm, isHead);
			}
		    }
		}
		Element opinionTargetElem = opinionElem.getChild("opinion_target");
		if (opinionTargetElem != null) {
		    Span<Term> span = kaf.newTermSpan();
		    Opinion.OpinionTarget opinionTarget = opinion.createOpinionTarget(span);
		    Element spanElem = opinionTargetElem.getChild("span");
		    if (spanElem != null) {
			List<Element> targetElems = spanElem.getChildren("target");
			for (Element targetElem : targetElems) {
			    String refId = getOptAttribute("id", targetElem);
			    boolean isHead = isHead(targetElem);
			    Term targetTerm = termIndex.get(refId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term " + refId + " not found when loading opinion " + opinionId);
			    }
			    span.addTarget(targetTerm, isHead);
			}
		    }
		}
		Element opinionExpressionElem = opinionElem.getChild("opinion_expression");
		if (opinionExpressionElem != null) {
		    Span<Term> span = kaf.newTermSpan();
		    String polarity = getOptAttribute("polarity", opinionExpressionElem);
		    String strength = getOptAttribute("strength", opinionExpressionElem);
		    String subjectivity = getOptAttribute("subjectivity", opinionExpressionElem);
		    String sentimentSemanticType = getOptAttribute("sentiment_semantic_type", opinionExpressionElem);
		    String sentimentProductFeature = getOptAttribute("sentiment_product_feature", opinionExpressionElem);
		    Opinion.OpinionExpression opinionExpression = opinion.createOpinionExpression(span);
		    if (polarity != null) {
			opinionExpression.setPolarity(polarity);
		    }
		    if (strength != null) {
			opinionExpression.setStrength(strength);
		    }
		    if (subjectivity != null) {
			opinionExpression.setSubjectivity(subjectivity);
		    }
		    if (sentimentSemanticType != null) {
			opinionExpression.setSentimentSemanticType(sentimentSemanticType);
		    }
		    if (sentimentProductFeature != null) {
			opinionExpression.setSentimentProductFeature(sentimentProductFeature);
		    }

		    Element spanElem = opinionExpressionElem.getChild("span");
		    if (spanElem != null) {
			List<Element> targetElems = spanElem.getChildren("target");
			for (Element targetElem : targetElems) {
			    String refId = getOptAttribute("id", targetElem);
			    boolean isHead = isHead(targetElem);
			    Term targetTerm = termIndex.get(refId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term " + refId + " not found when loading opinion " + opinionId);
			    }
			    span.addTarget(targetTerm, isHead);
			}
		    }
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("deps");
	if (elem != null) {
	    List<Element> depElems = elem.getChildren();
	    for (Element depElem : depElems) {
		String fromId = getAttribute("from", depElem);
		String toId = getAttribute("to", depElem);
		Term from = termIndex.get(fromId);
		if (from == null) {
		    throw new KAFNotValidException("Term " + fromId + " not found when loading Dep (" + fromId + ", " + toId + ")");
		}
		Term to = termIndex.get(toId);
		if (to == null) {
		    throw new KAFNotValidException("Term " + toId + " not found when loading Dep (" + fromId + ", " + toId + ")");
		}
		String rfunc = getAttribute("rfunc", depElem);
		Dep newDep = kaf.newDep(from, to, rfunc);
		String depcase = getOptAttribute("case", depElem);
		if (depcase != null) {
		    newDep.setCase(depcase);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("srl");
	if (elem != null) {
	    List<Element> predicateElems = elem.getChildren("predicate");
	    for (Element predicateElem : predicateElems) {
		String id = getAttribute("id", predicateElem);
		Span<Term> span = kaf.newTermSpan();
		Element spanElem = predicateElem.getChild("span");
		if (spanElem != null) {
		    List<Element> targetElems = spanElem.getChildren("target");
		    for (Element targetElem : targetElems) {
			String targetId = getAttribute("id", targetElem);
			boolean isHead = isHead(targetElem);
			Term targetTerm = termIndex.get(targetId);
			if (targetTerm == null) {
			    throw new KAFNotValidException("Term object " + targetId + " not found when loading predicate " + id);				
			}
			span.addTarget(targetTerm, isHead);
		    }
		}
		List<String> predTypes = new ArrayList<String>();
		List<Element> predTypeElems = predicateElem.getChildren("predType");
		for (Element predTypeElem : predTypeElems) {
		    String ptUri = getAttribute("uri", predTypeElem);
		    predTypes.add(ptUri);
		}
		Predicate newPredicate = kaf.newPredicate(id, span);
		String uri = getOptAttribute("uri", predicateElem);
		if (uri != null) {
		    newPredicate.setUri(uri);
		}
		List<Element> externalReferencesElems = predicateElem.getChildren("externalReferences");
		if (externalReferencesElems.size() > 0) {
		    List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
		    newPredicate.addExternalRefs(externalRefs);
		}
		String confidence = getOptAttribute("confidence", predicateElem);
		if (confidence != null) {
		    newPredicate.setConfidence(Float.valueOf(confidence));
		}
		List<Element> roleElems = predicateElem.getChildren("role");
		for (Element roleElem : roleElems) {
		    String rid = getAttribute("id", roleElem);
		    String semRole = getAttribute("semRole", roleElem);
		    Span<Term> roleSpan = kaf.newTermSpan();
		    Element roleSpanElem = roleElem.getChild("span");
		    if (roleSpanElem != null) {
			List<Element> targetElems = roleSpanElem.getChildren("target");
			for (Element targetElem : targetElems) {
			    String targetId = getAttribute("id", targetElem);
			    boolean isHead = isHead(targetElem);
			    Term targetTerm = termIndex.get(targetId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term object " + targetId + " not found when loading role " + rid);				
			    }
			    roleSpan.addTarget(targetTerm, isHead);
			}
		    }
		    Predicate.Role newRole = kaf.newRole(rid, newPredicate, semRole, roleSpan);
		    List<Element> rExternalReferencesElems = roleElem.getChildren("externalReferences");
		    if (rExternalReferencesElems.size() > 0) {
			List<ExternalRef> externalRefs = getExternalReferences(rExternalReferencesElems.get(0), kaf);
			newRole.addExternalRefs(externalRefs);
		    }
		    newPredicate.addRole(newRole);
		}
		predicateIndex.put(newPredicate.getId(), newPredicate);
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("timeExpressions");
	if (elem != null) {
	    List<Element> timex3Elems = elem.getChildren();
	    Map<Timex3, String> uncompleteBeginPointRefs = new HashMap<Timex3, String>();
	    Map<Timex3, String> uncompleteEndPointRefs = new HashMap<Timex3, String>();
	    for (Element timex3Elem : timex3Elems) {
		String timex3Id = getAttribute("id", timex3Elem);
		String timex3Type = getAttribute("type", timex3Elem);
		Timex3 timex3 = kaf.newTimex3(timex3Id, timex3Type);
		String timex3BeginPointId = getOptAttribute("beginPoint", timex3Elem);
		if (timex3BeginPointId != null) {
		    Timex3 beginPoint = timexIndex.get(timex3BeginPointId);
		    if (beginPoint == null) {
			uncompleteBeginPointRefs.put(timex3, timex3BeginPointId);
		    } else {
			timex3.setBeginPoint(beginPoint);
		    }
		}
		String timex3EndPointId = getOptAttribute("endPoint", timex3Elem);
		if (timex3EndPointId != null) {
		    Timex3 endPoint = timexIndex.get(timex3EndPointId);
		    if (endPoint == null) {
			uncompleteEndPointRefs.put(timex3, timex3EndPointId);
		    } else {
			timex3.setEndPoint(endPoint);
		    }
		}
		String timex3Quant = getOptAttribute("quant", timex3Elem);
		if (timex3Quant != null) {
		    timex3.setQuant(timex3Quant);
		}
		String timex3Freq = getOptAttribute("freq", timex3Elem);
		if (timex3Freq != null) {
		    timex3.setFreq(timex3Freq);
		}
		String timex3FuncInDoc = getOptAttribute("functionInDocument", timex3Elem);
		if (timex3FuncInDoc != null) {
		    timex3.setFunctionInDocument(timex3FuncInDoc);
		}
		String timex3TempFunc = getOptAttribute("temporalFunction", timex3Elem);
		if (timex3TempFunc != null) {
		    Boolean tempFunc = timex3TempFunc.equals("true");
		    timex3.setTemporalFunction(tempFunc);
		}
		String timex3Value = getOptAttribute("value", timex3Elem);
		if (timex3Value != null) {
		    timex3.setValue(timex3Value);
		}
		String timex3ValueFromFunction = getOptAttribute("valueFromFunction", timex3Elem);
		if (timex3ValueFromFunction != null) {
		    timex3.setValueFromFunction(timex3ValueFromFunction);
		}
		String timex3Mod = getOptAttribute("mod", timex3Elem);
		if (timex3Mod != null) {
		    timex3.setMod(timex3Mod);
		}
		String timex3AnchorTimeId = getOptAttribute("anchorTimeId", timex3Elem);
		if (timex3AnchorTimeId != null) {
		    timex3.setAnchorTimeId(timex3AnchorTimeId);
		}
		String timex3Comment = getOptAttribute("comment", timex3Elem);
		if (timex3Comment != null) {
		    timex3.setComment(timex3Comment);
		}
		Element spanElem = timex3Elem.getChild("span");
		if (spanElem != null) {
		    Span<WF> timex3Span = kaf.newWFSpan();
		    for (Element targetElem : spanElem.getChildren("target")) {
			String targetId = getAttribute("id", targetElem);
			WF wf = wfIndex.get(targetId);
			if (wf == null) {
			    throw new KAFNotValidException("Word form " + targetId + " not found when loading timex3 " + timex3Id);
			}
			boolean isHead = isHead(targetElem);
			timex3Span.addTarget(wf, isHead);
		    }
		    timex3.setSpan(timex3Span);
		}
		timexIndex.put(timex3.getId(), timex3);
	    }
	    for (Timex3 timex3 : uncompleteBeginPointRefs.keySet()) {
		timex3.setBeginPoint(timexIndex.get(uncompleteBeginPointRefs.get(timex3)));
	    }
	    for (Timex3 timex3 : uncompleteEndPointRefs.keySet()) {
		timex3.setEndPoint(timexIndex.get(uncompleteEndPointRefs.get(timex3)));
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("temporalRelations");
	if (elem != null) {
	    List<Element> tLinkElems = elem.getChildren("tlink");
	    for (Element tLinkElem : tLinkElems) {
		String tlid = getAttribute("id", tLinkElem);
		String fromId = getAttribute("from", tLinkElem);
		String toId = getAttribute("to", tLinkElem);
		String fromType = getAttribute("fromType", tLinkElem);
		String toType = getAttribute("toType", tLinkElem);
		String relType = getAttribute("relType", tLinkElem);
		TLinkReferable from = fromType.equals("event")
			? predicateIndex.get(fromId) : timexIndex.get(fromId);
		TLinkReferable to = toType.equals("event")
			? predicateIndex.get(toId) : timexIndex.get(toId);
		TLink tLink = kaf.newTLink(tlid, from, to, relType);
	    }

	    List<Element> predAnchorElems = elem.getChildren("predicateAnchor");
	    for (Element predAnchorElem : predAnchorElems) {
		String id = getAttribute("id", predAnchorElem);
		Element spanElem = predAnchorElem.getChild("span");
		Span<Predicate> predAnchorSpan = KAFDocument.newSpan();
		if (spanElem != null) {
		    for (Element targetElem : spanElem.getChildren("target")) {
			String targetId = getAttribute("id", targetElem);
			Predicate predicate = predicateIndex.get(targetId);
			if (predicate == null) {
			    throw new KAFNotValidException("Predicate " + targetId + " not found when loading PredicateAnchor " + id);
			}
			boolean isHead = isHead(targetElem);
			predAnchorSpan.addTarget(predicate, isHead);
		    }
		}
		PredicateAnchor newPa = kaf.newPredicateAnchor(id, predAnchorSpan);
		String anchorTimeId = getOptAttribute("anchorTime", predAnchorElem);
		if (anchorTimeId != null) {
		    Timex3 anchorTime = timexIndex.get(anchorTimeId);
		    if (anchorTime == null) {
			throw new IllegalStateException("Invalid timex ID (" + anchorTimeId + ") in predicateAnchor " + id);
		    }
		    newPa.setAnchorTime(anchorTime);
		}
		String beginPointId = getOptAttribute("beginPoint", predAnchorElem);
		if (beginPointId != null) {
		    Timex3 beginPoint = timexIndex.get(beginPointId);
		    if (beginPoint == null) {
			throw new IllegalStateException("Invalid timex ID (" + beginPointId + ") in predicateAnchor " + id);
		    }
		    newPa.setBeginPoint(beginPoint);
		}
		String endPointId = getOptAttribute("endPoint", predAnchorElem);
		if (endPointId != null) {
		    Timex3 endPoint = timexIndex.get(endPointId);
		    if (endPoint == null) {
			throw new IllegalStateException("Invalid timex ID (" + endPointId + ") in predicateAnchor " + id);
		    }
		    newPa.setEndPoint(endPoint);
		}
	    }
	    
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("causalRelations");
	if (elem != null) {
	    List<Element> clinkElems = elem.getChildren("clink");
	    for (Element clinkElem : clinkElems) {
		String clid = getAttribute("id", clinkElem);
		String fromId = getAttribute("from", clinkElem);
		String toId = getAttribute("to", clinkElem);
		String relType = getOptAttribute("relType", clinkElem);
		Predicate from = predicateIndex.get(fromId);
		Predicate to = predicateIndex.get(toId);
		CLink clink = kaf.newCLink(clid, from, to);
		if (relType != null) {
		    clink.setRelType(relType);
		}
	    }
	    rootChildrenElems.remove(elem);
	}

	elem = rootElem.getChild("factualities");
	if (elem != null) {
	    List<Element> factualityElems = elem.getChildren("factuality");
	    for (Element factualityElem : factualityElems) {
		String id = getAttribute("id", factualityElem);
		Element spanElem = factualityElem.getChild("span");
		if (spanElem == null) {
		    throw new IllegalStateException("Every factuality must contain a 'span' element");
		}
		Span<Term> span = loadTermSpan(spanElem, termIndex, id);
		Factuality newFactuality = kaf.newFactuality(id, span);
		List<Element> factValElems = factualityElem.getChildren("factVal");
		for (Element factValElem : factValElems) {
		    newFactuality.addFactVal(DOMToFactVal(factValElem, kaf));
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("factualityLayer");
	if (elem != null) {
	    List<Element> factualityElems = elem.getChildren("factvalue");
	    for (Element factualityElem : factualityElems) {
		String id = getAttribute("id", factualityElem);
		String prediction = getAttribute("prediction", factualityElem);
		String confidenceStr = getAttribute("confidence", factualityElem);
		Double confidence = null;
		if (confidenceStr != null) {
		    confidence = Double.parseDouble(confidenceStr);
		}
		Factvalue factuality = kaf.newFactvalue(wfIndex.get(id), prediction);
		if (confidence != null) {
		    factuality.setConfidence(confidence);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("features");
	if (elem != null) {
	    Element propertiesElem = elem.getChild("properties");
	    Element categoriesElem = elem.getChild("categories");
	    if (propertiesElem != null) {
		List<Element> propertyElems = propertiesElem.getChildren("property");
		for (Element propertyElem : propertyElems) {
		    String pid = getAttribute("id", propertyElem);
		    String lemma = getAttribute("lemma", propertyElem);
		    Element referencesElem = propertyElem.getChild("references");
		    if (referencesElem == null) {
			throw new IllegalStateException("Every property must contain a 'references' element");
		    }
		    List<Element> spanElems = referencesElem.getChildren("span");
		    if (spanElems.size() < 1) {
			throw new IllegalStateException("Every property must contain a 'span' element inside 'references'");
		    }
		    List<Span<Term>> references = new ArrayList<Span<Term>>();
		    for (Element spanElem : spanElems) {
			Span<Term> span = kaf.newTermSpan();
			List<Element> targetElems = spanElem.getChildren();
			if (targetElems.size() < 1) {
			    throw new IllegalStateException("Every span in a property must contain at least one target inside");  
			}
			for (Element targetElem : targetElems) {
			    String targetTermId = getAttribute("id", targetElem);
			    Term targetTerm = termIndex.get(targetTermId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term " + targetTermId + " not found when loading property " + pid);
			    }
			    boolean isHead = isHead(targetElem);
			    span.addTarget(targetTerm, isHead);
			}
			references.add(span);
		    }
		    Feature newProperty = kaf.newProperty(pid, lemma, references);
		    List<Element> externalReferencesElems = propertyElem.getChildren("externalReferences");
		    if (externalReferencesElems.size() > 0) {
			List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
			newProperty.addExternalRefs(externalRefs);
		    }
		    relationalIndex.put(newProperty.getId(), newProperty);
		}
	    }
	    if (categoriesElem != null) {
		List<Element> categoryElems = categoriesElem.getChildren("category");
		for (Element categoryElem : categoryElems) {
		    String cid = getAttribute("id", categoryElem);
		    String lemma = getAttribute("lemma", categoryElem);
		    Element referencesElem = categoryElem.getChild("references");
		    if (referencesElem == null) {
			throw new IllegalStateException("Every category must contain a 'references' element");
		    }
		    List<Element> spanElems = referencesElem.getChildren("span");
		    if (spanElems.size() < 1) {
			throw new IllegalStateException("Every category must contain a 'span' element inside 'references'");
		    }
		    List<Span<Term>> references = new ArrayList<Span<Term>>();
		    for (Element spanElem : spanElems) {
			Span<Term> span = kaf.newTermSpan();
			List<Element> targetElems = spanElem.getChildren();
			if (targetElems.size() < 1) {
			    throw new IllegalStateException("Every span in a property must contain at least one target inside");  
			}
			for (Element targetElem : targetElems) {
			    String targetTermId = getAttribute("id", targetElem);
			    Term targetTerm = termIndex.get(targetTermId);
			    if (targetTerm == null) {
				throw new KAFNotValidException("Term " + targetTermId + " not found when loading category " + cid);
			    }
			    boolean isHead = isHead(targetElem);
			    span.addTarget(targetTerm, isHead);
			}
			references.add(span);
		    }
		    Feature newCategory = kaf.newCategory(cid, lemma, references);
		    List<Element> externalReferencesElems = categoryElem.getChildren("externalReferences");
		    if (externalReferencesElems.size() > 0) {
			List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
			newCategory.addExternalRefs(externalRefs);
		    }
		    relationalIndex.put(newCategory.getId(), newCategory);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("relations");
	if (elem != null) {	    List<Element> relationElems = elem.getChildren("relation");
	    for (Element relationElem : relationElems) {
		String id = getAttribute("id", relationElem);
		String fromId = getAttribute("from", relationElem);
		String toId = getAttribute("to", relationElem);
		String confidenceStr = getOptAttribute("confidence", relationElem);
		float confidence = -1.0f;
		if (confidenceStr != null) {
		    confidence = Float.parseFloat(confidenceStr);
		}
		Relational from = relationalIndex.get(fromId);
		if (from == null) {
		    throw new KAFNotValidException("Entity/feature object " + fromId + " not found when loading relation " + id);
		}
		Relational to = relationalIndex.get(toId);
		if (to == null) {
		    throw new KAFNotValidException("Entity/feature object " + toId + " not found when loading relation " + id);
		}
		Relation newRelation = kaf.newRelation(id, from, to);
		if (confidence >= 0) {
		    newRelation.setConfidence(confidence);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("topics");
	if (elem != null) {
	    List<Element> topicElems = elem.getChildren("topic");
	    for (Element topicElem : topicElems) {
		String value = topicElem.getText();
		Topic topic = kaf.newTopic(value); 
		String source = getOptAttribute("source", topicElem);
		if (source != null){
		    topic.setSource(source);
		}
		String method = getOptAttribute("method", topicElem);
		if (method != null){
		    topic.setMethod(method);
		}
		String confidenceStr = getOptAttribute("confidence", topicElem);
		float confidence = -1.0f;
		if (confidenceStr != null) {
		    confidence = Float.parseFloat(confidenceStr);
		    topic.setConfidence(confidence);
		}
		String URI = getOptAttribute("uri", topicElem);
		if (URI != null){
		    topic.setURI(URI);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("markables");
	if (elem != null) {
	    List<Element> markElems = elem.getChildren();
	    for (Element markElem : markElems) {
		String sid = getAttribute("id", markElem);

		Element spanElem = markElem.getChild("span");
		if (spanElem == null) {
		    throw new IllegalStateException("Every mark must contain a span element");
		}
		List<Element> marksWfElems = spanElem.getChildren("target");
		Span<WF> span = kaf.newWFSpan();
		for (Element marksWfElem : marksWfElems) {
		    String wfId = getAttribute("id", marksWfElem);
		    boolean isHead = isHead(marksWfElem);
		    WF wf = wfIndex.get(wfId);
		    if (wf == null) {
			throw new KAFNotValidException("WF " + wfId + " not found when loading mark " + sid);
		    }
		    span.addTarget(wf, isHead);
		}
		String source = getOptAttribute("source", markElem);
		Mark newMark = (source == null) ? kaf.newMark(sid, span) : kaf.newMark(sid, source, span); 
		Element sentimentElem = markElem.getChild("sentiment");
		if (sentimentElem != null) {
		    newMark.setSentiment(DOMToSentiment(sentimentElem, kaf));
		}
		String type = getOptAttribute("type", markElem);
		if (type != null) {
		    newMark.setType(type);
		}
		String lemma = getOptAttribute("lemma", markElem);
		if (lemma != null) {
		    newMark.setLemma(lemma);
		}
		String pos = getOptAttribute("pos", markElem);
		if (pos != null) {
		    newMark.setPos(pos);
		}
		String tMorphofeat = getOptAttribute("morphofeat", markElem);
		if (tMorphofeat != null) {
		    newMark.setMorphofeat(tMorphofeat);
		}
		String markcase = getOptAttribute("case", markElem);
		if (markcase != null) {
		    newMark.setCase(markcase);
		}
		List<Element> externalReferencesElems = markElem.getChildren("externalReferences");
		if (externalReferencesElems.size() > 0) {
		    List<ExternalRef> externalRefs = getExternalReferences(externalReferencesElems.get(0), kaf);
		    newMark.addExternalRefs(externalRefs);
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	elem = rootElem.getChild("attribution");
	if (elem != null) {
	    List<Element> statementElems = elem.getChildren("statement");
	    for (Element statementElem : statementElems) {
		String statementId = getAttribute("id", statementElem);
		Element stTargetElem = statementElem.getChild("statement_target");
		if (stTargetElem == null) {
		    throw new KAFNotValidException("Statement " + statementId + " does not contain the compulsory StatementTarget element.");
		}
		Span<Term> span = kaf.newTermSpan();
		Statement.StatementTarget target = kaf.newStatementTarget(span);
		Element spanElem = stTargetElem.getChild("span");
		if (spanElem != null) {
		    List<Element> targetElems = spanElem.getChildren("target");
		    for (Element targetElem : targetElems) {
			String refId = getOptAttribute("id", targetElem);
			boolean isHead = isHead(targetElem);
			Term targetTerm = termIndex.get(refId);
			if (targetTerm == null) {
			    throw new KAFNotValidException("Term " + refId + " not found when loading statement " + statementId);
			}
			span.addTarget(targetTerm, isHead);
		    }
		}
		Statement statement = kaf.newStatement(statementId, target);
			
		Element stSourceElem = statementElem.getChild("statement_source");
		if (stSourceElem != null) {
		    Element sourceSpanElem = stSourceElem.getChild("span");
		    if (sourceSpanElem == null) {
			throw new KAFNotValidException("StatementSource elements need to contain the span element");
		    }
		    Span<Term> sourceSpan = loadTermSpan(sourceSpanElem, termIndex, statementId);
		    statement.setSource(kaf.newStatementSource(sourceSpan));
		}
		Element cueElem = statementElem.getChild("statement_cue");
		if (cueElem != null) {
		    Element cueSpanElem = cueElem.getChild("span");
		    if (cueSpanElem == null) {
			throw new KAFNotValidException("StatementCue elements need to contain the span element");
		    }
		    Span<Term> cueSpan = loadTermSpan(cueSpanElem, termIndex, statementId);
		    statement.setCue(kaf.newStatementCue(cueSpan));
		}
	    }
	    rootChildrenElems.remove(elem);
	}
	
	
	for (Element unknownLayerElem : rootChildrenElems) { // These layers are not recognised by the library
	    kaf.addUnknownLayer(unknownLayerElem);
	}

	return kaf;
    }