creates an etree representation of a <multiFeat> file that describes
        all the annotations that only span one token (e.g. POS, lemma etc.).

        Note: discoursegraphs will create one token annotation file for each
        top level layer (e.g. conano, tiger etc.).

def __gen_token_anno_file(self, top_level_layer):
        """
        creates an etree representation of a <multiFeat> file that describes
        all the annotations that only span one token (e.g. POS, lemma etc.).

        Note: discoursegraphs will create one token annotation file for each
        top level layer (e.g. conano, tiger etc.).
        """
        base_paula_id = '{0}.{1}.tok'.format(self.corpus_name, self.name)
        paula_id = '{0}.{1}.{2}.tok_multiFeat'.format(top_level_layer,
                                                   self.corpus_name,
                                                   self.name)
        E, tree = gen_paula_etree(paula_id)
        mflist = E('multiFeatList',
                   {XMLBASE: base_paula_id+'.xml'})

        for token_id in self.dg.tokens:
            mfeat = E('multiFeat',
                      {XLINKHREF: '#{0}'.format(token_id)})
            token_dict = self.dg.node[token_id]
            for feature in token_dict:
                # TODO: highly inefficient! refactor!1!!
                if feature not in IGNORED_TOKEN_ATTRIBS \
                   and feature.startswith(top_level_layer):
                    mfeat.append(E('feat',
                                   {'name': feature,
                                    'value': token_dict[feature]}))

            if self.human_readable:  # adds token string as a <!-- comment -->
                mfeat.append(Comment(token_dict[self.dg.ns+':token']))
            mflist.append(mfeat)

        tree.append(mflist)
        self.files[paula_id] = tree
        self.file2dtd[paula_id] = PaulaDTDs.multifeat
        return paula_id