Reads a sentence with syntax annotation (parsed from a TigerXML
        file) into this directed graph. Adds an attribute named 'tokens'
        to the sentence root node containing a sorted list of token node
        IDs. (The same list is also stored in ``self.tokens``).

        Parameters
        ----------
        sentence : lxml.etree._Element
            a sentence from a TigerXML file in etree element format

def __tigersentence2graph(self, sentence):
        """
        Reads a sentence with syntax annotation (parsed from a TigerXML
        file) into this directed graph. Adds an attribute named 'tokens'
        to the sentence root node containing a sorted list of token node
        IDs. (The same list is also stored in ``self.tokens``).

        Parameters
        ----------
        sentence : lxml.etree._Element
            a sentence from a TigerXML file in etree element format
        """
        # add sentence root to graph
        self.add_node(self.root,
                      layers={self.ns, self.ns+':sentence',
                              self.ns+':sentence:root',
                              self.ns+':syntax'})

        token_ids = []
        # add terminals to graph (tokens)
        for t in sentence.iterfind('./graph/terminals/t'):
            terminal_id = t.attrib['id']
            token_ids.append(terminal_id)
            # all token attributes shall belong to the tiger namespace
            terminal_features = add_prefix(t.attrib, self.ns+':')
            # convert tokens to unicode
            terminal_features[self.ns+':token'] = ensure_unicode(
                terminal_features[self.ns+':word'])
            self.add_node(terminal_id, layers={self.ns, self.ns+':token'},
                          attr_dict=terminal_features,
                          label=terminal_features[self.ns+':token'])

            # add secedge pointing relations from tokens to other tokens or
            # syntactic categories
            for secedge in t.iterfind('./secedge'):
                to_id = secedge.attrib['idref']
                secedge_attribs = add_prefix(secedge.attrib, self.ns+':')
                if to_id not in self:  # if graph doesn't contain to-node, yet
                    self.add_node(to_id, layers={self.ns, self.ns+':secedge'})
                self.add_edge(terminal_id, to_id,
                              layers={self.ns, self.ns+':secedge'},
                              attr_dict=secedge_attribs,
                              edge_type=EdgeTypes.pointing_relation)

        # add sorted list of all token node IDs to sentence root node
        # to make queries simpler/faster
        sorted_token_ids = sorted(token_ids, key=natural_sort_key)
        self.node[self.root].update({'tokens': sorted_token_ids})
        self.tokens = sorted_token_ids

        # add nonterminals (syntax categories) to graph
        for nt in sentence.iterfind('./graph/nonterminals/nt'):
            from_id = nt.attrib['id']
            nt_feats = add_prefix(nt.attrib, self.ns+':')
            nt_feats['label'] = nt_feats[self.ns+':cat']
            # root node already exists, but doesn't have a cat value
            if from_id in self:
                self.node[from_id].update(nt_feats)
            else:
                self.add_node(from_id, layers={self.ns, self.ns+':syntax'},
                              attr_dict=nt_feats)

            # add edges to graph (syntax cat dominances token/other cat)
            for edge in nt.iterfind('./edge'):
                to_id = edge.attrib['idref']
                if to_id not in self:  # if graph doesn't contain to-node, yet
                    self.add_node(to_id, layers={self.ns, self.ns+':secedge'})
                edge_attribs = add_prefix(edge.attrib, self.ns+':')

                # add a spanning relation from a syntax cat to a token
                if self.ns+':token' in self.node[to_id]['layers']:
                    edge_type = EdgeTypes.spanning_relation
                else:  # add a dominance relation between two syntax categories
                    edge_type = EdgeTypes.dominance_relation

                self.add_edge(from_id, to_id,
                              layers={self.ns, self.ns+':edge'},
                              attr_dict=edge_attribs,
                              label=edge_attribs[self.ns+':label'],
                              edge_type=edge_type)

            # add secondary edges to graph (cat points to other cat/token)
            for secedge in nt.iterfind('./secedge'):
                to_id = secedge.attrib['idref']
                if to_id not in self:  # if graph doesn't contain to-node, yet
                    self.add_node(to_id, layers={self.ns, self.ns+':secedge'})
                secedge_attribs = add_prefix(secedge.attrib, self.ns+':')
                self.add_edge(from_id, to_id,
                              layers={self.ns, self.ns+':secedge'},
                              attr_dict=secedge_attribs,
                              label=edge_attribs[self.ns+':label'],
                              edge_type=EdgeTypes.pointing_relation)