docs: def generate_features( self, sentence_text, wid ):
          ''' Generates and returns a list of strings, containing tab-separated
              features ID, FORM, LEMMA, CPOSTAG, POSTAG, FEATS of the word
              (the word with index *wid* from the given *sentence_text*).
  
              Parameters
              -----------
              sentence_text : estnltk.text.Text
                  Text object corresponding to a single sentence.
                  Words of the sentence, along with their morphological analyses,
                  should be accessible via the layer WORDS.
                  And each word should be a dict, containing morphological features
                  in ANALYSIS part;
  
              wid : int
                  Index of the word/token, whose features need to be generated;
  
          '''
          assert WORDS in sentence_text and len(sentence_text[WORDS])>0, \
                 " (!) 'words' layer missing or empty in given Text!"
          sentence = sentence_text[WORDS]
          assert -1 < wid and wid < len(sentence), ' (!) Invalid word id: '+str(wid)
  
          # 1) Pre-process (if required)
          if wid == 0:
              #  *** Add adposition (_K_) type
              if self.kSubCatRelsLex:
                  self.kFeatures = \
                      _findKsubcatFeatures( sentence, self.kSubCatRelsLex, addFeaturesToK = True )
              #  *** Add verb chain info
              if self.addVerbcGramm or self.addNomAdvVinf:
                  self.vcFeatures = generate_verb_chain_features( sentence_text, \
                                                                  addGrammPred=self.addVerbcGramm, \
                                                                  addNomAdvVinf=self.addNomAdvVinf )
              #  *** Add sentence ending saying verbs
              if self.addSeSayingVerbs:
                  self.sayingverbs = detect_sentence_ending_saying_verbs( sentence_text )
              #  *** Add clause boundary info
              if self.addClauseBound:
                  self.clbFeatures = []
                  for tag in sentence_text.clause_annotations:
                      if not tag:
                          self.clbFeatures.append( [] )
                      elif tag == EMBEDDED_CLAUSE_START:
                          self.clbFeatures.append( ['emb_cl_start'] )
                      elif tag == EMBEDDED_CLAUSE_END:
                          self.clbFeatures.append( ['emb_cl_end'] )
                      elif tag == CLAUSE_BOUNDARY:
                          self.clbFeatures.append (['clb'] )
  
          # 2) Generate the features
          estnltkWord = sentence[wid]
          # Pick the first analysis
          firstAnalysis = estnltkWord[ANALYSIS][0]
          strForm = []
          # *** ID
          strForm.append( str(wid+1) )
          strForm.append( '\t' )
          # *** FORM
          word_text = estnltkWord[TEXT]
          word_text = word_text.replace(' ', '_')
          strForm.append( word_text )
          strForm.append( '\t' )
          # *** LEMMA
          word_root = firstAnalysis[ROOT]
          word_root = word_root.replace(' ', '_')
          if len(word_root) == 0:
              word_root = "??"
          strForm.append( word_root )
          strForm.append( '\t' )
          # *** CPOSTAG
          strForm.append( firstAnalysis[POSTAG] )
          strForm.append( '\t' )
          # *** POSTAG
          finePos = firstAnalysis[POSTAG]
          if self.addAmbiguousPos and len(estnltkWord[ANALYSIS]) > 1:
              pos_tags = sorted(list(set([ a[POSTAG] for a in estnltkWord[ANALYSIS] ])))
              finePos  = '_'.join(pos_tags)
          #if self.kFeatures and wid in self.kFeatures:
          #    finePos += '_'+self.kFeatures[wid]
          strForm.append( finePos )
          strForm.append( '\t' )
          # *** FEATS  (grammatical categories)
          grammCats = []
          if len(firstAnalysis[FORM]) != 0:
              forms = firstAnalysis[FORM].split()
              grammCats.extend( forms )
          # add features from verb chains:
          if self.vcFeatures and self.vcFeatures[wid]:
              grammCats.extend( self.vcFeatures[wid] )
          # add features from clause boundaries:
          if self.addClauseBound and self.clbFeatures[wid]:
              grammCats.extend( self.clbFeatures[wid] )
          # add adposition type ("post" or "pre")
          if self.kFeatures and wid in self.kFeatures:
              grammCats.extend( [self.kFeatures[wid]] )
          # add saying verb features
          if self.sayingverbs and wid in self.sayingverbs:
              grammCats.extend( [self.sayingverbs[wid]] )
          # wrap up
          if not grammCats:
              grammCats = '_'
          else:
              grammCats = '|'.join( grammCats )
          strForm.append( grammCats )
          strForm.append( '\t' )
          return strForm