docs: protected Collection<String> featuresC(PaddedList<IN> cInfo, int loc) {
      CoreLabel c = cInfo.get(loc);
      CoreLabel n = cInfo.get(loc + 1);
      CoreLabel n2 = cInfo.get(loc + 2);
      CoreLabel p = cInfo.get(loc - 1);
      CoreLabel p2 = cInfo.get(loc - 2);
      CoreLabel p3 = cInfo.get(loc - 3);
  
      String cWord = getWord(c);
      String pWord = getWord(p);
      String nWord = getWord(n);
      String cShape = c.getString(ShapeAnnotation.class);
  
      Collection<String> featuresC = new ArrayList<String>();
  
      if (flags.useDistSim) {
        distSimAnnotate(cInfo);
      }
  
      if (flags.useDistSim && flags.useMoreTags) {
        featuresC.add(p.get(DistSimAnnotation.class) + '-' + cWord + "-PDISTSIM-CWORD");
      }
      
      if (flags.useMorphologyFeatures) {
      	annotateMorphoFeatures(c);
      }
  
  
      if (flags.useDistSim) {
        featuresC.add(c.get(DistSimAnnotation.class) + "-DISTSIM");
      }
  
  
      if (flags.useTitle) {
        Matcher m = titlePattern.matcher(cWord);
        if (m.matches()) {
          featuresC.add("IS_TITLE");
        }
      }
  
  
      if (flags.useInternal && flags.useExternal ) {
  
        if (flags.useWord) {
          featuresC.add(cWord + "-WORD");
        }
  
        if (flags.use2W) {
          featuresC.add(getWord(p2) + "-P2W");
          featuresC.add(getWord(n2) + "-N2W");
        }
  
        if (flags.useLC) {
          featuresC.add(cWord.toLowerCase() + "-CL");
          featuresC.add(pWord.toLowerCase() + "-PL");
          featuresC.add(nWord.toLowerCase() + "-NL");
        }
  
        if (flags.useUnknown) { // for true casing
          featuresC.add(c.get(UnknownAnnotation.class)+"-UNKNOWN");
          featuresC.add(p.get(UnknownAnnotation.class)+"-PUNKNOWN");
          featuresC.add(n.get(UnknownAnnotation.class)+"-NUNKNOWN");
        }
  
        if (flags.useLemmas) {
          String lem = c.getString(LemmaAnnotation.class);
          if (! "".equals(lem)) {
            featuresC.add(lem + "-LEM");
          }
        }
        if (flags.usePrevNextLemmas) {
          String plem = p.getString(LemmaAnnotation.class);
          String nlem = n.getString(LemmaAnnotation.class);
          if (! "".equals(plem)) {
            featuresC.add(plem + "-PLEM");
          }
          if (! "".equals(nlem)) {
            featuresC.add(nlem + "-NLEM");
          }
        }
  
        if (flags.checkNameList) {
          try {
            if (lastNames == null) {
              lastNames = new HashSet<String>();
  
              for (String line : ObjectBank.getLineIterator(flags.lastNameList)) {
                String[] cols = line.split("\\s+");
                lastNames.add(cols[0]);
              }
            }
            if (maleNames == null) {
              maleNames = new HashSet<String>();
              for (String line : ObjectBank.getLineIterator(flags.maleNameList)) {
                String[] cols = line.split("\\s+");
                maleNames.add(cols[0]);
              }
            }
            if (femaleNames == null) {
              femaleNames = new HashSet<String>();
              for (String line : ObjectBank.getLineIterator(flags.femaleNameList)) {
                String[] cols = line.split("\\s+");
                femaleNames.add(cols[0]);
              }
            }
  
            String name = cWord.toUpperCase();
            if (lastNames.contains(name)) {
              featuresC.add("LAST_NAME");
            }
  
            if (maleNames.contains(name)) {
              featuresC.add("MALE_NAME");
            }
  
            if (femaleNames.contains(name)) {
              featuresC.add("FEMALE_NAME");
            }
  
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }
  
        if (flags.binnedLengths != null) {
          int len = cWord.length();
          String featureName = null;
          for (int i = 0; i <= flags.binnedLengths.length; i++) {
            if (i == flags.binnedLengths.length) {
              featureName = "Len-" + flags.binnedLengths[flags.binnedLengths.length - 1] + "-Inf";
            } else if (len <= flags.binnedLengths[i]) {
              featureName = "Len-" + ((i == 0) ? 1 : flags.binnedLengths[i - 1]) + '-' + flags.binnedLengths[i];
              break;
            }
          }
          featuresC.add(featureName);
        }
  
        if (flags.useABGENE) {
          featuresC.add(c.get(AbgeneAnnotation.class) + "-ABGENE");
          featuresC.add(p.get(AbgeneAnnotation.class) + "-PABGENE");
          featuresC.add(n.get(AbgeneAnnotation.class) + "-NABGENE");
        }
  
        if (flags.useABSTRFreqDict) {
          featuresC.add(c.get(AbstrAnnotation.class) + "-ABSTRACT" + c.get(FreqAnnotation.class) + "-FREQ" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
          featuresC.add(c.get(AbstrAnnotation.class) + "-ABSTRACT" + c.get(DictAnnotation.class) + "-DICT" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
          featuresC.add(c.get(AbstrAnnotation.class) + "-ABSTRACT" + c.get(DictAnnotation.class) + "-DICT" + c.get(FreqAnnotation.class) + "-FREQ" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
        }
  
        if (flags.useABSTR) {
          featuresC.add(c.get(AbstrAnnotation.class) + "-ABSTRACT");
          featuresC.add(p.get(AbstrAnnotation.class) + "-PABSTRACT");
          featuresC.add(n.get(AbstrAnnotation.class) + "-NABSTRACT");
        }
  
        if (flags.useGENIA) {
          featuresC.add(c.get(GeniaAnnotation.class) + "-GENIA");
          featuresC.add(p.get(GeniaAnnotation.class) + "-PGENIA");
          featuresC.add(n.get(GeniaAnnotation.class) + "-NGENIA");
        }
        if (flags.useWEBFreqDict) {
          featuresC.add(c.get(WebAnnotation.class) + "-WEB" + c.get(FreqAnnotation.class) + "-FREQ" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
          featuresC.add(c.get(WebAnnotation.class) + "-WEB" + c.get(DictAnnotation.class) + "-DICT" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
          featuresC.add(c.get(WebAnnotation.class) + "-WEB" + c.get(DictAnnotation.class) + "-DICT" + c.get(FreqAnnotation.class) + "-FREQ" + c.getString(PartOfSpeechAnnotation.class) + "-TAG");
        }
  
        if (flags.useWEB) {
          featuresC.add(c.get(WebAnnotation.class) + "-WEB");
          featuresC.add(p.get(WebAnnotation.class) + "-PWEB");
          featuresC.add(n.get(WebAnnotation.class) + "-NWEB");
        }
  
        if (flags.useIsURL) {
          featuresC.add(c.get(IsURLAnnotation.class) + "-ISURL");
        }
        if (flags.useEntityRule) {
          featuresC.add(c.get(EntityRuleAnnotation.class)+"-ENTITYRULE");
        }
        if (flags.useEntityTypes) {
          featuresC.add(c.get(EntityTypeAnnotation.class) + "-ENTITYTYPE");
        }
        if (flags.useIsDateRange) {
          featuresC.add(c.get(IsDateRangeAnnotation.class) + "-ISDATERANGE");
        }
  
        if (flags.useABSTRFreq) {
          featuresC.add(c.get(AbstrAnnotation.class) + "-ABSTRACT" + c.get(FreqAnnotation.class) + "-FREQ");
        }
  
        if (flags.useFREQ) {
          featuresC.add(c.get(FreqAnnotation.class) + "-FREQ");
        }
  
        if (flags.useMoreTags) {
          featuresC.add(p.getString(PartOfSpeechAnnotation.class) + '-' + cWord + "-PTAG-CWORD");
        }
  
        if (flags.usePosition) {
          featuresC.add(c.get(PositionAnnotation.class) + "-POSITION");
        }
        if (flags.useBeginSent) {
          if ("0".equals(c.get(PositionAnnotation.class))) {
            featuresC.add("BEGIN-SENT");
            featuresC.add(cShape + "-BEGIN-SENT");
          } else {
            featuresC.add("IN-SENT");
            featuresC.add(cShape + "-IN-SENT");
          }
        }
        if (flags.useTags) {
          featuresC.add(c.getString(PartOfSpeechAnnotation.class) + "-TAG");
        }
  
        if (flags.useOrdinal) {
          if (isOrdinal(cInfo, loc)) {
            featuresC.add("C_ORDINAL");
            if (isOrdinal(cInfo, loc-1)) {
              //System.err.print(getWord(p) + " ");
              featuresC.add("PC_ORDINAL");
            }
            //System.err.println(cWord);
          }
          if (isOrdinal(cInfo, loc-1)) {
            featuresC.add("P_ORDINAL");
          }
        }
  
        if (flags.usePrev) {
          featuresC.add(pWord + "-PW");
          if (flags.useTags) {
            featuresC.add(p.getString(PartOfSpeechAnnotation.class) + "-PTAG");
          }
          if (flags.useDistSim) {
            featuresC.add(p.get(DistSimAnnotation.class) + "-PDISTSIM");
          }
          if (flags.useIsURL) {
            featuresC.add(p.get(IsURLAnnotation.class) + "-PISURL");
          }
          if (flags.useEntityTypes) {
            featuresC.add(p.get(EntityTypeAnnotation.class) + "-PENTITYTYPE");
          }
        }
  
        if (flags.useNext) {
          featuresC.add(nWord + "-NW");
          if (flags.useTags) {
            featuresC.add(n.getString(PartOfSpeechAnnotation.class) + "-NTAG");
          }
          if (flags.useDistSim) {
            featuresC.add(n.get(DistSimAnnotation.class) + "-NDISTSIM");
          }
          if (flags.useIsURL) {
            featuresC.add(n.get(IsURLAnnotation.class) + "-NISURL");
          }
          if (flags.useEntityTypes) {
            featuresC.add(n.get(EntityTypeAnnotation.class) + "-NENTITYTYPE");
          }
        }
        /*here, entityTypes refers to the type in the PASCAL IE challenge:
         * i.e. certain words are tagged "Date" or "Location" */
  
  
        if (flags.useEitherSideWord) {
          featuresC.add(pWord + "-EW");
          featuresC.add(nWord + "-EW");
        }
  
        if (flags.useWordPairs) {
          featuresC.add(cWord + '-' + pWord + "-W-PW");
          featuresC.add(cWord + '-' + nWord + "-W-NW");
        }
  
        if (flags.useSymTags) {
          if (flags.useTags) {
            featuresC.add(p.getString(PartOfSpeechAnnotation.class) + '-' + c.getString(PartOfSpeechAnnotation.class) + '-' + n.getString(PartOfSpeechAnnotation.class) + "-PCNTAGS");
            featuresC.add(c.getString(PartOfSpeechAnnotation.class) + '-' + n.getString(PartOfSpeechAnnotation.class) + "-CNTAGS");
            featuresC.add(p.getString(PartOfSpeechAnnotation.class) + '-' + c.getString(PartOfSpeechAnnotation.class) + "-PCTAGS");
          }
          if (flags.useDistSim) {
            featuresC.add(p.get(DistSimAnnotation.class) + '-' + c.get(DistSimAnnotation.class) + '-' + n.get(DistSimAnnotation.class) + "-PCNDISTSIM");
            featuresC.add(c.get(DistSimAnnotation.class) + '-' + n.get(DistSimAnnotation.class) + "-CNDISTSIM");
            featuresC.add(p.get(DistSimAnnotation.class) + '-' + c.get(DistSimAnnotation.class) + "-PCDISTSIM");
          }
  
        }
  
  
        if (flags.useSymWordPairs) {
          featuresC.add(pWord + '-' + nWord + "-SWORDS");
        }
  
        if (flags.useGazFeatures) {
          if (!c.get(GazAnnotation.class).equals(flags.dropGaz)) {
            featuresC.add(c.get(GazAnnotation.class) + "-GAZ");
          }
          if (!n.get(GazAnnotation.class).equals(flags.dropGaz)) {
            featuresC.add(n.get(GazAnnotation.class) + "-NGAZ");
          }
          if (!p.get(GazAnnotation.class).equals(flags.dropGaz)) {
            featuresC.add(p.get(GazAnnotation.class) + "-PGAZ");
          }
        }
  
        if (flags.useMoreGazFeatures) {
          if (!c.get(GazAnnotation.class).equals(flags.dropGaz)) {
            featuresC.add(c.get(GazAnnotation.class) + '-' + cWord + "-CG-CW-GAZ");
            if (!n.get(GazAnnotation.class).equals(flags.dropGaz)) {
              featuresC.add(c.get(GazAnnotation.class) + '-' + n.get(GazAnnotation.class) + "-CNGAZ");
            }
            if (!p.get(GazAnnotation.class).equals(flags.dropGaz)) {
              featuresC.add(p.get(GazAnnotation.class) + '-' + c.get(GazAnnotation.class) + "-PCGAZ");
            }
          }
        }
  
        if (flags.useAbbr || flags.useMinimalAbbr) {
          featuresC.add(c.get(AbbrAnnotation.class) + "-ABBR");
        }
  
        if (flags.useAbbr1 || flags.useMinimalAbbr1) {
          if (!c.get(AbbrAnnotation.class).equals("XX")) {
            featuresC.add(c.get(AbbrAnnotation.class) + "-ABBR");
          }
        }
  
        if (flags.useAbbr) {
          featuresC.add(p.get(AbbrAnnotation.class) + '-' + c.get(AbbrAnnotation.class) + "-PCABBR");
          featuresC.add(c.get(AbbrAnnotation.class) + '-' + n.get(AbbrAnnotation.class) + "-CNABBR");
          featuresC.add(p.get(AbbrAnnotation.class) + '-' + c.get(AbbrAnnotation.class) + '-' + n.get(AbbrAnnotation.class) + "-PCNABBR");
        }
  
        if (flags.useAbbr1) {
          if (!c.get(AbbrAnnotation.class).equals("XX")) {
            featuresC.add(p.get(AbbrAnnotation.class) + '-' + c.get(AbbrAnnotation.class) + "-PCABBR");
            featuresC.add(c.get(AbbrAnnotation.class) + '-' + n.get(AbbrAnnotation.class) + "-CNABBR");
            featuresC.add(p.get(AbbrAnnotation.class) + '-' + c.get(AbbrAnnotation.class) + '-' + n.get(AbbrAnnotation.class) + "-PCNABBR");
          }
        }
  
        if (flags.useChunks) {
          featuresC.add(p.get(ChunkAnnotation.class) + '-' + c.get(ChunkAnnotation.class) + "-PCCHUNK");
          featuresC.add(c.get(ChunkAnnotation.class) + '-' + n.get(ChunkAnnotation.class) + "-CNCHUNK");
          featuresC.add(p.get(ChunkAnnotation.class) + '-' + c.get(ChunkAnnotation.class) + '-' + n.get(ChunkAnnotation.class) + "-PCNCHUNK");
        }
  
        if (flags.useMinimalAbbr) {
          featuresC.add(cWord + '-' + c.get(AbbrAnnotation.class) + "-CWABB");
        }
  
        if (flags.useMinimalAbbr1) {
          if (!c.get(AbbrAnnotation.class).equals("XX")) {
            featuresC.add(cWord + '-' + c.get(AbbrAnnotation.class) + "-CWABB");
          }
        }
  
        String prevVB = "", nextVB = "";
        if (flags.usePrevVB) {
          for (int j = loc - 1; ; j--) {
            CoreLabel wi = cInfo.get(j);
            if (wi == cInfo.getPad()) {
              prevVB = "X";
              featuresC.add("X-PVB");
              break;
            } else if (wi.getString(PartOfSpeechAnnotation.class).startsWith("VB")) {
              featuresC.add(getWord(wi) + "-PVB");
              prevVB = getWord(wi);
              break;
            }
          }
        }
  
        if (flags.useNextVB) {
          for (int j = loc + 1; ; j++) {
            CoreLabel wi = cInfo.get(j);
            if (wi == cInfo.getPad()) {
              featuresC.add("X-NVB");
              nextVB = "X";
              break;
            } else if (wi.getString(PartOfSpeechAnnotation.class).startsWith("VB")) {
              featuresC.add(getWord(wi) + "-NVB");
              nextVB = getWord(wi);
              break;
            }
          }
        }
  
        if (flags.useVB) {
          featuresC.add(prevVB + '-' + nextVB + "-PNVB");
        }
  
        if (flags.useShapeConjunctions) {
          featuresC.add(c.get(PositionAnnotation.class) + cShape + "-POS-SH");
          if (flags.useTags) {
            featuresC.add(c.tag() + cShape + "-TAG-SH");
          }
          if (flags.useDistSim) {
            featuresC.add(c.get(DistSimAnnotation.class) + cShape + "-DISTSIM-SH");
          }
  
        }
  
        if (flags.useWordTag) {
          featuresC.add(cWord + '-' + c.getString(PartOfSpeechAnnotation.class) + "-W-T");
          featuresC.add(cWord + '-' + p.getString(PartOfSpeechAnnotation.class) + "-W-PT");
          featuresC.add(cWord + '-' + n.getString(PartOfSpeechAnnotation.class) + "-W-NT");
        }
  
        if (flags.useNPHead) {
          featuresC.add(c.get(TreeCoreAnnotations.HeadWordAnnotation.class) + "-HW");
          if (flags.useTags) {
            featuresC.add(c.get(TreeCoreAnnotations.HeadWordAnnotation.class) + "-" + c.getString(PartOfSpeechAnnotation.class) + "-HW-T");
          }
          if (flags.useDistSim) {
            featuresC.add(c.get(TreeCoreAnnotations.HeadWordAnnotation.class) + "-" + c.get(DistSimAnnotation.class) + "-HW-DISTSIM");
          }
        }
  
        if (flags.useNPGovernor) {
          featuresC.add(c.get(GovernorAnnotation.class) + "-GW");
          if (flags.useTags) {
            featuresC.add(c.get(GovernorAnnotation.class) + '-' + c.getString(PartOfSpeechAnnotation.class) + "-GW-T");
          }
          if (flags.useDistSim) {
            featuresC.add(c.get(GovernorAnnotation.class) + '-' + c.get(DistSimAnnotation.class) + "-DISTSIM-T1");
          }
        }
  
        if (flags.useHeadGov) {
          featuresC.add(c.get(TreeCoreAnnotations.HeadWordAnnotation.class) + "-" + c.get(GovernorAnnotation.class) + "-HW_GW");
        }
  
        if (flags.useClassFeature) {
          featuresC.add("###");
        }
  
        if (flags.useFirstWord) {
          String firstWord = getWord(cInfo.get(0));
          featuresC.add(firstWord);
        }
  
        if (flags.useNGrams) {
          Collection<String> subs = wordToSubstrings.get(cWord);
          if (subs == null) {
            subs = new ArrayList<String>();
            String word = '<' + cWord + '>';
            if (flags.lowercaseNGrams) {
              word = word.toLowerCase();
            }
            if (flags.dehyphenateNGrams) {
              word = dehyphenate(word);
            }
            if (flags.greekifyNGrams) {
              word = greekify(word);
            }
            for (int i = 0; i < word.length(); i++) {
              for (int j = i + 2; j <= word.length(); j++) {
                if (flags.noMidNGrams && i != 0 && j != word.length()) {
                  continue;
                }
                if (flags.maxNGramLeng >= 0 && j - i > flags.maxNGramLeng) {
                  continue;
                }
                subs.add(intern('#' + word.substring(i, j) + '#'));
              }
            }
            if (flags.cacheNGrams) {
              wordToSubstrings.put(cWord, subs);
            }
          }
          featuresC.addAll(subs);
          if (flags.conjoinShapeNGrams) {
            for (String str : subs) {
              String feat = str + '-' + cShape + "-CNGram-CS";
              featuresC.add(feat);
            }
          }
        }
  
        if (flags.useGazettes) {
          if (flags.sloppyGazette) {
            Collection<String> entries; 
            /*
             * PP - expect gazette entries to contain lemmas only
             */
            if (flags.useLemmas) {
          	  String lem = c.getString(LemmaAnnotation.class);
          	  entries = wordToGazetteEntries.get(lem);
            } else entries = wordToGazetteEntries.get(cWord);
            
            if (entries != null) {
              featuresC.addAll(entries);
            }
          }
          if (flags.cleanGazette) {           
            Collection<GazetteInfo> infos = wordToGazetteInfos.get(cWord);
            if (flags.useLemmas) // Search for gazeteer entries matching the lemma, not the wordform 
          	  infos = wordToGazetteInfos.get(c.getString(LemmaAnnotation.class).toLowerCase()); //TODO - case sensitivity nosaukumiem tomēr var noderēt... bet nevar īsti paļauties uz to, kādā case būs atgrieztā lemma
            
            if (infos != null) {
          	//System.err.println("Meklējam gazetē vārdu " + getWord(cInfo.get(loc)));
              for (GazetteInfo gInfo : infos) {
                boolean ok = true;
                for (int gLoc = 0; gLoc < gInfo.words.length; gLoc++) {
              	  //TODO - entītiju nosaukumu locīšana varētu būt labāk
              	  if (flags.useLemmas) {
              		  String gazeteerLemma = cInfo.get(loc + gLoc - gInfo.loc).getString(LemmaAnnotation.class);
              		  ok &= gInfo.words[gLoc].equalsIgnoreCase(gazeteerLemma);
              	  } else
              		  ok &= gInfo.words[gLoc].equals(getWord(cInfo.get(loc + gLoc - gInfo.loc)));
                  
                }
                if (ok) {
              	  //System.err.println("Atradām gazetē vārdu" + getWord(cInfo.get(loc)) + " gazetes ieraksts " + Arrays.toString(gInfo.words));            	  
                    featuresC.add(gInfo.feature);
                    //featuresC.add(gInfo.source); // filename doesnot help
                    for (int gLoc = 0; gLoc < gInfo.words.length; gLoc++) {
                  	  CoreLabel lab = cInfo.get(loc + gLoc - gInfo.loc);
                  	  Set<String> cats = lab.get(LVGazAnnotation.class);
                        if (cats == null) cats = new HashSet<>();
                        cats.add(gInfo.type);
                        lab.set(LVGazAnnotation.class, cats);
                        Set<String> files = lab.get(LVGazFileAnnotation.class);
                        if (files == null) files = new HashSet<>();
                        files.add(gInfo.source);
                        lab.set(LVGazFileAnnotation.class, files);
                    }
                }
              }
            }
          }
        }
        
        /**
         * @author Artūrs Znotiņš
         */
        if (flags.useMorphoCase) {
      	  featuresC.add("MORPHO-CASE-C-" + c.getString(LVMorphoCaseAnnotation.class));
      	  featuresC.add("MORPHO-CASE-P-" + p.getString(LVMorphoCaseAnnotation.class));
      	  featuresC.add("MORPHO-CASE-N-" + n.getString(LVMorphoCaseAnnotation.class));
        }
        if (flags.useMorphoNumber) {
      	  featuresC.add("MORPHO-NUMBER-C-" + c.getString(LVMorphoNumberAnnotation.class));
      	  featuresC.add("MORPHO-NUMBER-P-" + p.getString(LVMorphoNumberAnnotation.class));
      	  featuresC.add("MORPHO-NUMBER-N-" + n.getString(LVMorphoNumberAnnotation.class));
        }
        if (flags.useMorphoPOS) {
      	  featuresC.add("MORPHO-POS-C-" + c.getString(LVMorphoPOSAnnotation.class));
      	  featuresC.add("MORPHO-POS-P-" + p.getString(LVMorphoPOSAnnotation.class));
      	  featuresC.add("MORPHO-POS-N-" + n.getString(LVMorphoPOSAnnotation.class));
        }
        if (flags.useMorphoLetaLemma) {
      	  featuresC.add("MORPHO-LETA-LEMMA-C-" + c.getString(LVMorphoLetaLemmaAnnotation.class));
      	  featuresC.add("MORPHO-LETA-LEMMA-P-" + p.getString(LVMorphoLetaLemmaAnnotation.class));
      	  featuresC.add("MORPHO-LETA-LEMMA-N-" + n.getString(LVMorphoLetaLemmaAnnotation.class));
        }
        
  //      if (flags.useMorphologyFeatures) {
  //    	  String s = c.get(MorphologyFeatureStringAnnotation.class);
  //    	  if (s != null) {
  //	    	  String[] morphoFeatures =  s.split("\\|");
  //	    	  for (String f : morphoFeatures) {
  //	    		  if (f.startsWith("Locījums") || f.startsWith("Skaitlis") || f.startsWith("Vārdšķira") || f.startsWith("LETA_lemma") ) {
  //	    			  featuresC.add("MORPHO-" + f);
  //    		  }
  //    	  }
  //      }
  
  //    if (true) {   
  //  	if (knowLC.contains(c.lemma().toLowerCase())) {
  //  		featuresC.add("DocKnownLC");  
  //  	} else if (c.index() > 1 && !isNameCase(c.word())) {
  //  		knowLC.add(c.lemma().toLowerCase());
  //  	}
  //  	if (knowUC.contains(c.lemma().toLowerCase())) {
  //  		featuresC.add("DocKnownUC");  
  //  	} else if (c.index() > 1 && isNameCase(c.word())) {
  //  		knowUC.add(c.lemma().toLowerCase());
  //  	}
  //  }
  
  //  	Syntax experiments
  //    featuresC.add("CRole-" + c.getString(RoleAnnotation.class));
  //    featuresC.add("NRole-" + n.getString(RoleAnnotation.class));
  //    featuresC.add("PRole-" + p.getString(RoleAnnotation.class));
  //    featuresC.add("N2Role-" + n2.getString(RoleAnnotation.class));
  //    featuresC.add("P2Role-" + p2.getString(RoleAnnotation.class));
  //    featuresC.add("P3Role-" + p3.getString(RoleAnnotation.class));
      
      
      //System.out.println(c.getString(NerFeatureStringAnnotation.class));
      // featuresC.add("CRole-" + extractNerFeature(c, "dep"));
      // featuresC.add("NRole-" + extractNerFeature(n, "dep"));
      // featuresC.add("N2Role-" + extractNerFeature(n2, "dep"));
      // featuresC.add("PRole-" + extractNerFeature(p, "dep"));
      // featuresC.add("P2Role-" + extractNerFeature(p2, "dep"));
      // featuresC.add("P3Role-" + extractNerFeature(p3, "dep"));
  
  
      // CoreLabel par = getParent(c, cInfo);
      // if (par != null) {
      	// if (par.tag() != null)  featuresC.add("ParentTag-" + par.tag().substring(0, 1));
    		// featuresC.add("ParentLetaLemma-" + extractNerFeature(par, "LETA_lemma"));
    		// featuresC.add("ParentLemma-" + par.lemma());
    		// featuresC.add("ParentWord-" + par.word());
    		// featuresC.add("ParentRole-" + extractNerFeature(par, "dep"));
    		
    		// CoreLabel par2 = getParent(par, cInfo);
    		// if (par2 != null) {
    			// if (par2.tag() != null)  featuresC.add("Parent2Tag-" + par2.tag().substring(0, 1));
  	  		// featuresC.add("Parent2LetaLemma-" + extractNerFeature(par2, "LETA_lemma"));
  	  		// featuresC.add("Parent2Lemma-" + par2.lemma());
  	  		// featuresC.add("Parent2Word-" + par2.word());
  	  		// featuresC.add("Parent2Role-" + extractNerFeature(par2, "dep")); 
    		// }
      // }
      
  //    CoreLabel head = c;
  //    while (par != null && par.tag().length() > 4 && (par.tag().startsWith("n") || par.tag().startsWith("a")) && par.tag().charAt(4) == 'g') {
  //    	head = par;
  //    	par = getParent(par, cInfo);
  //    }
  //    if (head != null) {
  //    	if (head.tag() != null) featuresC.add("HeadTag-" + head.tag().substring(0, 1));
  //  		featuresC.add("HeadLetaLemma-" + extractNerFeature(head, "LETA_lemma"));
  //  		featuresC.add("HeadLemma-" + head.lemma());
  //  		featuresC.add("HeadWord-" + head.word());
  //  		featuresC.add("HeadRole-" + extractNerFeature(head, "dep"));
  //    }
  //	
  //	
  //	head = p;
  //	par = getParent(p, cInfo);
  //    while (par != null && par.tag().length() > 4 && (par.tag().startsWith("n") || par.tag().startsWith("a")) && par.tag().charAt(4) == 'g') {
  //    	head = par;
  //    	par = getParent(par, cInfo);
  //    }
  //    if (head != null) {
  //    	if (head.tag() != null) featuresC.add("PHeadTag-" + head.tag().substring(0, 1));
  //  		featuresC.add("PHeadLetaLemma-" + extractNerFeature(head, "LETA_lemma"));
  //  		featuresC.add("PHeadLemma-" + head.lemma());
  //  		featuresC.add("PHeadWord-" + head.word());
  //  		featuresC.add("PHeadRole-" + extractNerFeature(head, "dep"));
  //    }
  //	
  //	
  //	head = n;
  //	par = getParent(n, cInfo);
  //    while (par != null && par.tag().length() > 4 && (par.tag().startsWith("n") || par.tag().startsWith("a")) && par.tag().charAt(4) == 'g') {
  //    	head = par;
  //    	par = getParent(par, cInfo);
  //    }
  //    if (head != null) {
  //    	if (head.tag() != null) featuresC.add("NHeadTag-" + head.tag().substring(0, 1));
  //  		featuresC.add("NHeadLetaLemma-" + extractNerFeature(head, "LETA_lemma"));
  //  		featuresC.add("NHeadLemma-" + head.lemma());
  //  		featuresC.add("NHeadWord-" + head.word());
  //  		featuresC.add("NHeadRole-" + extractNerFeature(head, "dep"));
  //    }
  	
      
  
        if ((flags.wordShape > WordShapeClassifier.NOWORDSHAPE) || (flags.useShapeStrings)) {
          featuresC.add(cShape + "-TYPE");
          if (flags.useTypeSeqs) {
            String pShape = p.get(ShapeAnnotation.class);
            String nShape = n.get(ShapeAnnotation.class);
            featuresC.add(pShape + "-PTYPE");
            featuresC.add(nShape + "-NTYPE");
            featuresC.add(pWord + "..." + cShape + "-PW_CTYPE");
            featuresC.add(cShape + "..." + nWord + "-NW_CTYPE");
            featuresC.add(pShape + "..." + cShape + "-PCTYPE");
            featuresC.add(cShape + "..." + nShape + "-CNTYPE");
            featuresC.add(pShape + "..." + cShape + "..." + nShape + "-PCNTYPE");
          }
        }
  
        if (flags.useLastRealWord) {
          if (pWord.length() <= 3) {
            // extending this to check for 2 short words doesn't seem to help....
            featuresC.add(getWord(p2) + "..." + cShape + "-PPW_CTYPE");
          }
        }
  
        if (flags.useNextRealWord) {
          if (nWord.length() <= 3) {
            // extending this to check for 2 short words doesn't seem to help....
            featuresC.add(getWord(n2) + "..." + cShape + "-NNW_CTYPE");
          }
        }
  
        if (flags.useOccurrencePatterns) {
          featuresC.addAll(occurrencePatterns(cInfo, loc));
        }
  
        if (flags.useDisjunctive) {
          for (int i = 1; i <= flags.disjunctionWidth; i++) {
            CoreLabel dn = cInfo.get(loc + i);
            CoreLabel dp = cInfo.get(loc - i);
            featuresC.add(getWord(dn) + "-DISJN");
            if (flags.useDisjunctiveShapeInteraction) {
              featuresC.add(getWord(dn) + '-' + cShape + "-DISJN-CS");
            }
            featuresC.add(getWord(dp) + "-DISJP");
            if (flags.useDisjunctiveShapeInteraction) {
              featuresC.add(getWord(dp) + '-' + cShape + "-DISJP-CS");
            }
          }
        }
  
        if (flags.useWideDisjunctive) {
          for (int i = 1; i <= flags.wideDisjunctionWidth; i++) {
            featuresC.add(getWord(cInfo.get(loc + i)) + "-DISJWN");
            featuresC.add(getWord(cInfo.get(loc - i)) + "-DISJWP");
          }
        }
  
        if (flags.useEitherSideDisjunctive) {
          for (int i = 1; i <= flags.disjunctionWidth; i++) {
            featuresC.add(getWord(cInfo.get(loc + i)) + "-DISJWE");
            featuresC.add(getWord(cInfo.get(loc - i)) + "-DISJWE");
          }
        }
  
        if (flags.useDisjShape) {
          for (int i = 1; i <= flags.disjunctionWidth; i++) {
            featuresC.add(cInfo.get(loc + i).get(ShapeAnnotation.class) + "-NDISJSHAPE");
            // featuresC.add(cInfo.get(loc - i).get(ShapeAnnotation.class) + "-PDISJSHAPE");
            featuresC.add(cShape + '-' + cInfo.get(loc + i).get(ShapeAnnotation.class) + "-CNDISJSHAPE");
            // featuresC.add(c.get(ShapeAnnotation.class) + "-" + cInfo.get(loc - i).get(ShapeAnnotation.class) + "-CPDISJSHAPE");
          }
        }
  
        if (flags.useExtraTaggySequences) {
          if (flags.useTags) {
            featuresC.add(p2.getString(PartOfSpeechAnnotation.class) + '-' + p.getString(PartOfSpeechAnnotation.class) + '-' + c.getString(PartOfSpeechAnnotation.class) + "-TTS");
            featuresC.add(p3.getString(PartOfSpeechAnnotation.class) + '-' + p2.getString(PartOfSpeechAnnotation.class) + '-' + p.getString(PartOfSpeechAnnotation.class) + '-' + c.getString(PartOfSpeechAnnotation.class) + "-TTTS");
          }
          if (flags.useDistSim) {
            featuresC.add(p2.get(DistSimAnnotation.class) + '-' + p.get(DistSimAnnotation.class) + '-' + c.get(DistSimAnnotation.class) + "-DISTSIM_TTS1");
            featuresC.add(p3.get(DistSimAnnotation.class) + '-' + p2.get(DistSimAnnotation.class) + '-' + p.get(DistSimAnnotation.class) + '-' + c.get(DistSimAnnotation.class) + "-DISTSIM_TTTS1");
          }
        }
  
        if (flags.useMUCFeatures) {
          featuresC.add(c.get(SectionAnnotation.class)+"-SECTION");
          featuresC.add(c.get(WordPositionAnnotation.class)+"-WORD_POSITION");
          featuresC.add(c.get(CoreAnnotations.SentencePositionAnnotation.class)+"-SENT_POSITION");
          featuresC.add(c.get(ParaPositionAnnotation.class)+"-PARA_POSITION");
          featuresC.add(c.get(WordPositionAnnotation.class)+ '-' +c.get(ShapeAnnotation.class)+"-WORD_POSITION_SHAPE");
        }
      } else if (flags.useInternal) {
  
        if (flags.useWord) {
          featuresC.add(cWord + "-WORD");
        }
  
        if (flags.useNGrams) {
          Collection<String> subs = wordToSubstrings.get(cWord);
          if (subs == null) {
            subs = new ArrayList<String>();
            String word = '<' + cWord + '>';
            if (flags.lowercaseNGrams) {
              word = word.toLowerCase();
            }
            if (flags.dehyphenateNGrams) {
              word = dehyphenate(word);
            }
            if (flags.greekifyNGrams) {
              word = greekify(word);
            }
            for (int i = 0; i < word.length(); i++) {
              for (int j = i + 2; j <= word.length(); j++) {
                if (flags.noMidNGrams && i != 0 && j != word.length()) {
                  continue;
                }
                if (flags.maxNGramLeng >= 0 && j - i > flags.maxNGramLeng) {
                  continue;
                }
                //subs.add(intern("#" + word.substring(i, j) + "#"));
                subs.add(intern('#' + word.substring(i, j) + '#'));
              }
            }
            if (flags.cacheNGrams) {
              wordToSubstrings.put(cWord, subs);
            }
          }
          featuresC.addAll(subs);
          if (flags.conjoinShapeNGrams) {
            String shape = c.get(ShapeAnnotation.class);
            for (String str : subs) {
              String feat = str + '-' + shape + "-CNGram-CS";
              featuresC.add(feat);
            }
          }
        }
  
        if ((flags.wordShape > WordShapeClassifier.NOWORDSHAPE) || (flags.useShapeStrings)) {
          featuresC.add(cShape + "-TYPE");
        }
  
        if (flags.useOccurrencePatterns) {
          featuresC.addAll(occurrencePatterns(cInfo, loc));
        }
  
      } else if (flags.useExternal) {
  
        if (flags.usePrev) {
          featuresC.add(pWord + "-PW");
        }
  
        if (flags.useNext) {
          featuresC.add(nWord + "-NW");
        }
  
        if (flags.useWordPairs) {
          featuresC.add(cWord + '-' + pWord + "-W-PW");
          featuresC.add(cWord + '-' + nWord + "-W-NW");
        }
  
        if (flags.useSymWordPairs) {
          featuresC.add(pWord + '-' + nWord + "-SWORDS");
        }
  
        if ((flags.wordShape > WordShapeClassifier.NOWORDSHAPE) || (flags.useShapeStrings)) {
          if (flags.useTypeSeqs) {
            String pShape = p.get(ShapeAnnotation.class);
            String nShape = n.get(ShapeAnnotation.class);
            featuresC.add(pShape + "-PTYPE");
            featuresC.add(nShape + "-NTYPE");
            featuresC.add(pWord + "..." + cShape + "-PW_CTYPE");
            featuresC.add(cShape + "..." + nWord + "-NW_CTYPE");
            if (flags.maxLeft > 0) featuresC.add(pShape + "..." + cShape + "-PCTYPE"); // this one just isn't useful, at least given c,pc,s,ps.  Might be useful 0th-order
            featuresC.add(cShape + "..." + nShape + "-CNTYPE");
            featuresC.add(pShape + "..." + cShape + "..." + nShape + "-PCNTYPE");
          }
        }
  
        if (flags.useLastRealWord) {
          if (pWord.length() <= 3) {
            featuresC.add(getWord(p2) + "..." + cShape + "-PPW_CTYPE");
          }
        }
  
        if (flags.useNextRealWord) {
          if (nWord.length() <= 3) {
            featuresC.add(getWord(n2) + "..." + cShape + "-NNW_CTYPE");
          }
        }
  
        if (flags.useDisjunctive) {
          for (int i = 1; i <= flags.disjunctionWidth; i++) {
            CoreLabel dn = cInfo.get(loc + i);
            CoreLabel dp = cInfo.get(loc - i);
            featuresC.add(getWord(dn) + "-DISJN");
            if (flags.useDisjunctiveShapeInteraction) {
              featuresC.add(getWord(dn) + '-' + c.get(ShapeAnnotation.class) + "-DISJN-CS");
            }
            featuresC.add(getWord(dp) + "-DISJP");
            if (flags.useDisjunctiveShapeInteraction) {
              featuresC.add(getWord(dp) + '-' + c.get(ShapeAnnotation.class) + "-DISJP-CS");
            }
          }
        }
  
        if (flags.useWideDisjunctive) {
          for (int i = 1; i <= flags.wideDisjunctionWidth; i++) {
            featuresC.add(getWord(cInfo.get(loc + i)) + "-DISJWN");
            featuresC.add(getWord(cInfo.get(loc - i)) + "-DISJWP");
          }
        }
  
        if (flags.useDisjShape) {
          for (int i = 1; i <= flags.disjunctionWidth; i++) {
            featuresC.add(cInfo.get(loc + i).get(ShapeAnnotation.class) + "-NDISJSHAPE");
            // featuresC.add(cInfo.get(loc - i).get(ShapeAnnotation.class) + "-PDISJSHAPE");
            featuresC.add(c.get(ShapeAnnotation.class) + '-' + cInfo.get(loc + i).get(ShapeAnnotation.class) + "-CNDISJSHAPE");
            // featuresC.add(c.get(ShapeAnnotation.class) + "-" + cInfo.get(loc - i).get(ShapeAnnotation.class) + "-CPDISJSHAPE");
          }
        }
  
      }
  
      // Stuff to add binary features from the additional columns
      if (flags.twoStage) {
        featuresC.add(c.get(Bin1Annotation.class) + "-BIN1");
        featuresC.add(c.get(Bin2Annotation.class) + "-BIN2");
        featuresC.add(c.get(Bin3Annotation.class) + "-BIN3");
        featuresC.add(c.get(Bin4Annotation.class) + "-BIN4");
        featuresC.add(c.get(Bin5Annotation.class) + "-BIN5");
        featuresC.add(c.get(Bin6Annotation.class) + "-BIN6");
      }
  
      if(flags.useIfInteger){
        try {
          int val = Integer.parseInt(cWord);
          if(val > 0) featuresC.add("POSITIVE_INTEGER");
          else if(val < 0) featuresC.add("NEGATIVE_INTEGER");
          // System.err.println("FOUND INTEGER");
        } catch(NumberFormatException e){
          // not an integer value, nothing to do
        }
      }
  
      //Stuff to add arbitrary features
      if (flags.useGenericFeatures) {
        //see if we need to cach the keys
        if (genericAnnotationKeys == null) {
          makeGenericKeyCache(c);
        }
        //now look through the cached keys
        for (Class<? extends GenericAnnotation> key : genericAnnotationKeys) {
          System.err.println("Adding feature: " + CoreLabel.genericValues.get(key) + " with value " + c.get(key));
          featuresC.add(c.get(key) + "-" + CoreLabel.genericValues.get(key));
        }
      }
  
      if(flags.useTopics){
        //featuresC.add(p.get(TopicAnnotation.class) + '-' + cWord + "--CWORD");
        featuresC.add(c.get(TopicAnnotation.class)+ "-TopicID");
        featuresC.add(p.get(TopicAnnotation.class) + "-PTopicID");
        featuresC.add(n.get(TopicAnnotation.class) + "-NTopicID");
        //featuresC.add(p.get(TopicAnnotation.class) + '-' + c.get(TopicAnnotation.class) + '-' + n.get(TopicAnnotation.class) + "-PCNTopicID");
        //featuresC.add(c.get(TopicAnnotation.class) + '-' + n.get(TopicAnnotation.class) + "-CNTopicID");
        //featuresC.add(p.get(TopicAnnotation.class) + '-' + c.get(TopicAnnotation.class) + "-PCTopicID");
        //featuresC.add(c.get(TopicAnnotation.class) + cShape + "-TopicID-SH");
        //asdasd
      }
  
      // NER tag annotations from a previous NER system
      if (c.get(StackedNamedEntityTagAnnotation.class) != null) {
        featuresC.add(c.get(StackedNamedEntityTagAnnotation.class)+ "-CStackedNERTag");
        featuresC.add(cWord + "-" + c.get(StackedNamedEntityTagAnnotation.class)+ "-WCStackedNERTag");
  
        if (flags.useNext) {
          featuresC.add(c.get(StackedNamedEntityTagAnnotation.class) + '-' + n.get(StackedNamedEntityTagAnnotation.class) + "-CNStackedNERTag");
          featuresC.add(cWord + "-" + c.get(StackedNamedEntityTagAnnotation.class) + '-' + n.get(StackedNamedEntityTagAnnotation.class) + "-WCNStackedNERTag");
  
          if (flags.usePrev) {
            featuresC.add(p.get(StackedNamedEntityTagAnnotation.class) + '-' + c.get(StackedNamedEntityTagAnnotation.class) + '-' + n.get(StackedNamedEntityTagAnnotation.class) + "-PCNStackedNERTag");
            featuresC.add(p.get(StackedNamedEntityTagAnnotation.class) + '-' + cWord + " -" + c.get(StackedNamedEntityTagAnnotation.class)
                + '-' + n.get(StackedNamedEntityTagAnnotation.class) + "-PWCNStackedNERTag");
          }
        }
        if (flags.usePrev) {
          featuresC.add(p.get(StackedNamedEntityTagAnnotation.class) + '-' + c.get(StackedNamedEntityTagAnnotation.class) + "-PCStackedNERTag");
        }
      }
      if(flags.useWordnetFeatures)
        featuresC.add(c.get(WordnetSynAnnotation.class)+"-WordnetSyn");
      if(flags.useProtoFeatures)
        featuresC.add(c.get(ProtoAnnotation.class)+"-Proto");
      if(flags.usePhraseWordTags)
        featuresC.add(c.get(PhraseWordsTagAnnotation.class)+"-PhraseTag");
      if(flags.usePhraseWords)
      {
        for(String w: c.get(PhraseWordsAnnotation.class))
        featuresC.add(w+"-PhraseWord");
      }
      if(flags.useCommonWordsFeature)
        featuresC.add(c.get(CommonWordsAnnotation.class));
      
      
      if (flags.useLVMorphoAnalyzer && c != null && c.word() != null) {
      	featuresC.addAll(addMorphoTag(c, ""));
      	if (flags.useLVMorphoAnalyzerPrev && p != null && p.word() != null) featuresC.addAll(addMorphoTag(p, "-PREV"));
      	//if (flags.useLVMorphoAnalyzerPrev && p2 != null && p2.word() != null) featuresC.addAll(addMorphoTag(p2, "-PREV2"));
      	if (flags.useLVMorphoAnalyzerNext && n != null && n.word() != null) featuresC.addAll(addMorphoTag(n, "-NEXT"));
      	//if (flags.useLVMorphoAnalyzerNext && n2 != null && n2.word() != null) featuresC.addAll(addMorphoTag(n2, "-NEXT2"));
      	
      	lv.semti.morphology.analyzer.Word c_all = c.get(LVMorphologyAnalysis.class);
      	Wordform c_best = c.get(LVMorphologyAnalysisBest.class);
      	
      	//numurs pēc kārtas teikumā
      	//featuresC.add(Integer.toString(loc) + "-LV-NPK");
      	
      	if (flags.useLVMorphoAnalyzerItemIDs && c_all != null) {
      		for (Wordform wf : c_all.wordforms) {
      		  String endingId = wf.getValue(AttributeNames.i_EndingID);
      		  if (endingId != null) featuresC.add(endingId + "-LV-ENDID");
      		  String lexemeId = wf.getValue(AttributeNames.i_LexemeID);
      		  if (lexemeId != null) featuresC.add(endingId + "-LV-LEXID");
      		}
      		if (c_best != null) {
          		String endingId = c_best.getValue(AttributeNames.i_EndingID);
          		if (endingId != null) featuresC.add(endingId + "-LV-BEST-ENDID");
          		String lexemeId = c_best.getValue(AttributeNames.i_LexemeID);
          		if (lexemeId != null) featuresC.add(endingId + "-LV-BEST-LEXID");    			
      		}
      	}
      }
      return featuresC;
    }