public class CamelCaseFeatureExtractor
    implements FeatureFunction
{

    public CamelCaseFeatureExtractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "CamelCase";

    @Override
    public List<Feature> apply(Feature feature)
    {

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("CapsFeature", "CapsFeature_null"));
        }

        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("CapsFeature", "CapsFeature_null"));
        }

        if (StringUtils.isAllUpperCase(value)) {
            return Collections.singletonList(new Feature("CapsFeature", StringUtils
                    .capitalize(value.toLowerCase())));
        }
        else {
            return Collections.singletonList(new Feature("CapsFeature", value));
        }

    }
} public class ClarkPosInductionFeatureExtractor
    implements FeatureFunction
{

    public ClarkPosInductionFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "ClarkPosInduction";

    @Override
    public List<Feature> apply(Feature feature)
    {
        Object featureValue = feature.getValue();
        try {
            if (featureValue == null) {
                return Collections.singletonList(new Feature("ClarkPOS", "ClarkPOS_null"));
            }

            return Collections.singletonList(new Feature("ClarkPOS", ClarkPosInduction.posInduction
                    .get(featureValue.toString())));
        }
        catch (Exception e) {
            return Collections.singletonList(new Feature("ClarkPOS", "ClarkPOS_null"));
        }
    }

} public class DBLocationListFeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> dbLocationNameList = new HashMap<String, String>();
    static int i = 0;

    public DBLocationListFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "DBPLocationName";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
              br = (BufferedReader) reader.getReader("location_wiki.list");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    for (int i = 0; i < sep.length; i++) {
                        if (i == 0) {
                            dbLocationNameList.put(sep[0], "B-LocationName");
                        }
                        else {
                            dbLocationNameList.put(sep[0], "I-LocationName");
                        }
                    }
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        String value = featureValue.toString();
        if (dbLocationNameList.get(value) != null) {
            return Collections.singletonList(new Feature("DBPLocationName", dbLocationNameList
                    .get(value)));
        }

        return Collections.singletonList(new Feature("DBPLocationName", "O"));
    }

} public class DBNachnamenListFeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> dbNachNamen = new HashMap<String, String>();
    static int i = 0;

    public DBNachnamenListFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "DBNachNamen";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("inDBnachnamen.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    dbNachNamen.put(sep[0], "true");
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        String value = featureValue.toString();
        if (dbNachNamen.get(value) != null) {
            return Collections.singletonList(new Feature("DBNachNamen", "true"));
        }

        return Collections.singletonList(new Feature("DBNachNamen", "false"));
    }

} public class DBPersonListFeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> dbPersonNameList = new HashMap<String, String>();
    static int i = 0;

    public DBPersonListFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "DBPersonName";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("inDBperson.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    for (int i = 0; i < sep.length; i++) {
                        if (i == 0) {
                            dbPersonNameList.put(sep[0], "B-PersonName");
                        }
                        else {
                            dbPersonNameList.put(sep[0], "I-PersonName");
                        }
                    }
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        String value = featureValue.toString();
        if (dbPersonNameList.get(value) != null) {
            return Collections.singletonList(new Feature("DBPersonName", dbPersonNameList
                    .get(value)));
        }

        return Collections.singletonList(new Feature("DBPersonName", "O"));
    }

} public class FreeBaseFeatureExtractor
    implements FeatureFunction
{

    public FreeBaseFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "FreebaseFeature";

    @Override
    public List<Feature> apply(Feature feature)
    {
        try {
            Object featureValue = feature.getValue();
            if (featureValue == null) {
                return Collections.singletonList(new Feature("FreeBase", "FreeBase_null"));
            }

            String k = FreeBaseFeature.freebaseFeature.remove();

            String value = featureValue.toString();
            if (value == null || value.length() == 0) {
                return Collections.emptyList();
            }

            return Collections.singletonList(new Feature("FreeBase", k));

        }
        catch (Exception e) {
            return Collections.singletonList(new Feature("FreeBase", "FreeBase_null"));
        }
    }

} public class LTCapitalTypeFeatureFunction
    implements FeatureFunction
{

    public static final String DEFAULT_NAME = "CapitalType";

    public enum CapitalType
    {
        ALL_UPPERCASE, ALL_LOWERCASE, INITIAL_UPPERCASE, MIXED_CASE, INVALID
    }

    /**
     * If the value of the feature is a StringValue and is determined to be one of ALL_UPPERCASE,
     * ALL_LOWERCASE, INITIAL_UPPERCASE, or MIXED_CASE, then a new feature containing one of those
     * four values is returned. If the value of the feature cannot be characterized by one of these
     * four values, then the empty list is returned (e.g. the value is an empty string, contains
     * only white space, or contains only digits, etc.)
     *
     * <P>
     * This method was inspired by CapitalizationTypeTagger.py written by Steven Bethard.
     *
     * @return a feature that has a value that is one of ALL_UPPERCASE, ALL_LOWERCASE,
     *         INITIAL_UPPERCASE, or MIXED_CASE. Otherwise the empty list is returned.
     */
    @Override
    public List<Feature> apply(Feature feature)
    {
        String featureName = Feature.createName(DEFAULT_NAME, feature.getName());
        Object featureValue = feature.getValue();
        if (featureValue == null) {
            return Collections.singletonList(new Feature(featureName, CapitalType.INVALID
                    .toString()));
        }
        else if (featureValue instanceof String) {
            String value = featureValue.toString();
            if (value == null || value.length() == 0) {
                return Collections.singletonList(new Feature(featureName, CapitalType.INVALID
                        .toString()));
            }

            String lowerCaseValue = value.toLowerCase();
            String upperCaseValue = value.toUpperCase();
            if (lowerCaseValue.equals(upperCaseValue)) {
                return Collections.singletonList(new Feature(featureName, CapitalType.INVALID
                        .toString()));
            }

            if (value.equals(value.toLowerCase())) {
                return Collections.singletonList(new Feature(featureName, CapitalType.ALL_LOWERCASE
                        .toString()));
            }
            else if (value.equals(value.toUpperCase())) {
                return Collections.singletonList(new Feature(featureName, CapitalType.ALL_UPPERCASE
                        .toString()));
            }

            if (CaseUtil.isInitialUppercase(value)) {
                return Collections.singletonList(new Feature(featureName,
                        CapitalType.INITIAL_UPPERCASE.toString()));
            }

            return Collections.singletonList(new Feature(featureName, CapitalType.MIXED_CASE
                    .toString()));
        }
        else {
            return Collections.singletonList(new Feature(featureName, CapitalType.INVALID
                    .toString()));
        }
    }

} public class LTCharacterCategoryPatternFunction<T extends Annotation>
    implements FeatureFunction
{

    /**
     * The type of pattern to generate in feature values.
     */
    public static enum PatternType
    {
        /**
         * The standard pattern, where one category abbreviation is added to the feature value for
         * each character in the text.
         */
        ONE_PER_CHAR,
        /**
         * A simplified pattern, where if the same category appears many times in a row, the
         * category is added to the feature value only once. For example "XX00" would get the
         * pattern "LuNd" since there are two uppercase letters followed by two digits.
         */
        REPEATS_MERGED,
        /**
         * Similar to REPEATS_MERGED, but distinguishes between the same category appearing once and
         * more than once in a row. If the same category appears twice or more in a row, then we
         * will mark that category with a Kleene plus '+'. For example "X000" would get the pattern
         * "LuNd+" since there is a single uppercase letter followed by more than one digit.
         */
        REPEATS_AS_KLEENE_PLUS
    }

    private PatternType patternType;

    private String name;

    public static <T extends Annotation> NamedFeatureExtractor1<T> createExtractor()
    {
        return createExtractor(PatternType.ONE_PER_CHAR);
    }

    /*
     * I would have returned a simple FeatureFunctionExtractor using the following code: return new
     * FeatureFunctionExtractor<T>(new CoveredTextExtractor<T>(), false, new
     * CharacterCategoryPatternFunction<T>()); but TimeAnnotator wanted a NamedFeatureExtractor1. So
     * I did the following to maintain backwards compatibility. After all, the converted feature
     * extractor was a NamedFeatureExtractor1.
     */

    public static <T extends Annotation> NamedFeatureExtractor1<T> createExtractor(
            PatternType patternType)
    {
        final LTCharacterCategoryPatternFunction<T> ccpf = new LTCharacterCategoryPatternFunction<T>(
                patternType);
        return new NamedFeatureExtractor1<T>()
        {

            @Override
            public List<Feature> extract(JCas view, Annotation focusAnnotation)
                throws CleartkExtractorException
            {
                String text = focusAnnotation.getCoveredText();
                return ccpf.apply(new Feature(null, text));
            }

            @Override
            public String getFeatureName()
            {
                return ccpf.getFeatureName();
            }
        };
    }

    /**
     * Create the standard feature extractor, where one category is added to the feature value for
     * each character in the text. See {@link PatternType#ONE_PER_CHAR}.
     */
    public LTCharacterCategoryPatternFunction()
    {
        this(PatternType.ONE_PER_CHAR);
    }

    /**
     * Create a feature extractor with the specified pattern type. See {@link PatternType} for the
     * acceptable pattern types.
     *
     * @param patternType
     *            The type of pattern to generate in feature values.
     */
    public LTCharacterCategoryPatternFunction(PatternType patternType)
    {
        this.patternType = patternType;
        switch (this.patternType) {
        case ONE_PER_CHAR:
            this.name = "CharPattern";
            break;
        case REPEATS_MERGED:
            this.name = "CharPatternRepeatsMerged";
            break;
        case REPEATS_AS_KLEENE_PLUS:
            this.name = "CharPatternRepeatsAsKleenePlus";
            break;
        }
    }

    public String getFeatureName()
    {
        return this.name;
    }

    @Override
    public List<Feature> apply(Feature feature)
    {
        String featureName = Feature.createName(getFeatureName(), feature.getName());
        Object featureValue = feature.getValue();
        if (featureValue == null) {
            return Collections
                    .singletonList(new Feature(featureName, "CharCatRepeatCategory_nuul"));
        }
        else if (featureValue instanceof String) {
            String text = featureValue.toString();
            StringBuilder builder = new StringBuilder();
            String lastType = null;
            boolean multipleRepeats = false;
            for (int i = 0; i < text.length(); i += 1) {
                char c = text.charAt(i);
                String type = classifyChar(c);
                switch (this.patternType) {
                case ONE_PER_CHAR:
                    builder.append(type);
                    break;
                case REPEATS_MERGED:
                    if (!type.equals(lastType)) {
                        builder.append(type);
                    }
                    break;
                case REPEATS_AS_KLEENE_PLUS:
                    if (!type.equals(lastType)) {
                        builder.append(type);
                        multipleRepeats = false;
                    }
                    else if (!multipleRepeats) {
                        builder.append('+');
                        multipleRepeats = true;
                    }
                }
                lastType = type;
            }
            return Collections.singletonList(new Feature(featureName, builder.toString()));
        }
        return Collections.singletonList(new Feature(featureName, "CharCatRepeatCategory_nuul"));
    }

    public String getCharCategory(String text, PatternType patternType)
    {
        StringBuilder builder = new StringBuilder();
        String lastType = null;
        boolean multipleRepeats = false;
        for (int i = 0; i < text.length(); i += 1) {
            char c = text.charAt(i);
            String type = this.classifyChar(c);
            switch (patternType) {
            case ONE_PER_CHAR:
                builder.append(type);
                break;
            case REPEATS_MERGED:
                if (!type.equals(lastType)) {
                    builder.append(type);
                }
                break;
            case REPEATS_AS_KLEENE_PLUS:
                if (!type.equals(lastType)) {
                    builder.append(type);
                    multipleRepeats = false;
                }
                else if (!multipleRepeats) {
                    builder.append('+');
                    multipleRepeats = true;
                }
            }
            lastType = type;
        }
        return builder.toString();
    }

    protected String classifyChar(char c)
    {
        int typeInt = Character.getType(c);
        switch (typeInt) {
        case Character.CONTROL:
            return "CC";
        case Character.FORMAT:
            return "Cf";
        case Character.UNASSIGNED:
            return "Cn";
        case Character.PRIVATE_USE:
            return "Co";
        case Character.SURROGATE:
            return "Cs";
        case Character.LOWERCASE_LETTER:
            return "Ll";
        case Character.MODIFIER_LETTER:
            return "Lm";
        case Character.OTHER_LETTER:
            return "Lo";
        case Character.TITLECASE_LETTER:
            return "Lt";
        case Character.UPPERCASE_LETTER:
            return "Lu";
        case Character.COMBINING_SPACING_MARK:
            return "Mc";
        case Character.ENCLOSING_MARK:
            return "Me";
        case Character.NON_SPACING_MARK:
            return "Mn";
        case Character.DECIMAL_DIGIT_NUMBER:
            return "Nd";
        case Character.LETTER_NUMBER:
            return "Nl";
        case Character.OTHER_NUMBER:
            return "No";
        case Character.CONNECTOR_PUNCTUATION:
            return "Pc";
        case Character.DASH_PUNCTUATION:
            return "Pd";
        case Character.END_PUNCTUATION:
            return "Pe";
        case Character.FINAL_QUOTE_PUNCTUATION:
            return "Pf";
        case Character.INITIAL_QUOTE_PUNCTUATION:
            return "Pi";
        case Character.OTHER_PUNCTUATION:
            return "Po";
        case Character.START_PUNCTUATION:
            return "Ps";
        case Character.CURRENCY_SYMBOL:
            return "Sc";
        case Character.MODIFIER_SYMBOL:
            return "Sk";
        case Character.MATH_SYMBOL:
            return "Sm";
        case Character.OTHER_SYMBOL:
            return "So";
        case Character.LINE_SEPARATOR:
            return "Zl";
        case Character.PARAGRAPH_SEPARATOR:
            return "Zp";
        case Character.SPACE_SEPARATOR:
            return "Zs";
        default:
            throw new RuntimeException("Unknown character type: " + typeInt);
        }
    }
} public static enum PatternType
{
    /**
     * The standard pattern, where one category abbreviation is added to the feature value for
     * each character in the text.
     */
    ONE_PER_CHAR,
    /**
     * A simplified pattern, where if the same category appears many times in a row, the
     * category is added to the feature value only once. For example "XX00" would get the
     * pattern "LuNd" since there are two uppercase letters followed by two digits.
     */
    REPEATS_MERGED,
    /**
     * Similar to REPEATS_MERGED, but distinguishes between the same category appearing once and
     * more than once in a row. If the same category appears twice or more in a row, then we
     * will mark that category with a Kleene plus '+'. For example "X000" would get the pattern
     * "LuNd+" since there is a single uppercase letter followed by more than one digit.
     */
    REPEATS_AS_KLEENE_PLUS
} public class LTCharacterNgramFeatureFunction implements FeatureFunction {

  public enum Orientation {
    RIGHT_TO_LEFT, LEFT_TO_RIGHT
  }

  Orientation orientation;

  int start;

  int end;

  int minimumValueLength;

  boolean lowerCase;

  private String name;

  /**
   * This feature function serves up character n-grams based on StringValued features. For example,
   * if you wanted trigram suffixes (e.g. 'ion' of 'emotion') for words that are of length 7 or more
   * you could call the constructor with the following:
   * CharacterNGramFeatureFunction(Orientation.RIGHT_TO_LEFT, 0, 3, 7, false)
   *
   * @param featureName
   *          a user-specified name for the feature function, to be included in all feature names.
   * @param orientation
   *          must be one of LEFT_TO_RIGHT or RIGHT_TO_LEFT. The orientation determines whether
   *          index 0 corresponds to the first character of the string value or the last. The
   *          orientation does not affect the ordering of the characters in the n-gram which are
   *          always returned in left-to-right order.
   * @param start
   *          the start of the n-gram (typically 0 for both orientations)
   * @param end
   *          the end of the n-gram (typically n for both orientations)
   * @param minimumValueLength
   *          This parameter allows you to skip string values that are too short. It must be greater
   *          than or equal to end.
   * @param lowerCase
   *          if true than the n-gram used as the feature value will be lowercased.
   */
  public LTCharacterNgramFeatureFunction(
      String featureName,
      Orientation orientation,
      int start,
      int end,
      int minimumValueLength,
      boolean lowerCase) {
    name = Feature.createName(
        "NGram",
        orientation == Orientation.RIGHT_TO_LEFT ? "Right" : "Left",
        String.valueOf(start),
        String.valueOf(end),
        String.valueOf(minimumValueLength),
        lowerCase ? "lower" : null,
        featureName);
    if (minimumValueLength < end) {
      throw new IllegalArgumentException(
          "minimumValueLength must be greater than or equal to the parameter end.");
    }
    this.orientation = orientation;
    this.start = start;
    this.end = end;
    this.minimumValueLength = minimumValueLength;
    this.lowerCase = lowerCase;
  }

  public LTCharacterNgramFeatureFunction(
      Orientation orientation,
      int start,
      int end,
      int minimumValueLength,
      boolean lowerCase) {
    this(null, orientation, start, end, minimumValueLength, lowerCase);
  }

  public LTCharacterNgramFeatureFunction(
      String featureName,
      Orientation orientation,
      int start,
      int end) {
    this(featureName, orientation, start, end, end - start, false);
  }

  public LTCharacterNgramFeatureFunction(Orientation orientation, int start, int end) {
    this(null, orientation, start, end);
  }

  /**
   * @return will return an empty list if the value of the feature is not a StringValue or is not as
   *         long as the minimumValueLength.
   */
  @Override
  public List<Feature> apply(Feature feature) {
    String featureName = Feature.createName(name, feature.getName());
    Object featureValue = feature.getValue();
    if (featureValue == null || !(featureValue instanceof String)) {
        return Collections.singletonList(new Feature(featureName, "OUT"));
    }

    String value = featureValue.toString();
    if (value == null || value.length() < minimumValueLength) {
        return Collections.singletonList(new Feature(featureName, "OUT"));
    }

    String ngram;
    if (orientation == Orientation.LEFT_TO_RIGHT) {
      ngram = value.substring(start, end);
    } else {
      ngram = value.substring(value.length() - end, value.length() - start);
    }
    if (lowerCase) {
        ngram = ngram.toLowerCase();
    }

    return Collections.singletonList(new Feature(featureName, ngram));
  }

} public enum Orientation {
  RIGHT_TO_LEFT, LEFT_TO_RIGHT
} public class PositionFeatureExtractor
    implements FeatureFunction
{

    public PositionFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "PositionFeature";

    @Override
    public List<Feature> apply(Feature feature)
    {
        Object featureValue = feature.getValue();
        try {
            if (featureValue == null) {
                return Collections.singletonList(new Feature("Position", -1));
            }
            int k = PositionFeature.posistion.remove();

            String value = featureValue.toString();
            if (value == null || value.length() == 0) {
                return Collections.emptyList();
            }

            return Collections.singletonList(new Feature("Position", Integer.toString(k)));
        }
        catch (Exception e) {
            return Collections.singletonList(new Feature("Position", -1));
        }
    }

} public class SimilarWord1Extractor
    implements FeatureFunction
{

    static Map<String, String> simWord1 = new HashMap<String, String>();
    static int i = 0;

    public SimilarWord1Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "SimilarWord1";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("200k_2d_wordlists");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    simWord1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }

        String output;
        output = simWord1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("SIMWO", output));
        }
        return Collections.singletonList(new Feature("SIMWO", "NA"));

    }

} public class SimilarWord2Extractor
    implements FeatureFunction
{

    static Map<String, String> simWord2 = new HashMap<String, String>();
    static int i = 0;

    public SimilarWord2Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "SimilarWord2";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("200k_2d_wordlists");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    simWord2.put(sep[0], sep[2]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }

        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.emptyList();
        }

        String output;
        output = simWord2.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("SIMWO", output));
        }
        return Collections.singletonList(new Feature("SIMWO", "NA"));
    }

} public class SimilarWord3Extractor
    implements FeatureFunction
{

    static Map<String, String> simWord3 = new HashMap<String, String>();
    static int i = 0;

    public SimilarWord3Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "SimilarWord3";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("200k_2d_wordlists");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    simWord3.put(sep[0], sep[3]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.emptyList();
        }
        String output;
        output = simWord3.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("SIMWO", output));
        }
        return Collections.singletonList(new Feature("SIMWO", "NA"));

    }

} public class SimilarWord4Extractor
    implements FeatureFunction
{

    static Map<String, String> simWord4 = new HashMap<String, String>();
    static int i = 0;

    public SimilarWord4Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "SimilarWord4";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("200k_2d_wordlists");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    simWord4.put(sep[0], sep[4]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }

        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("SIMWO", "NA"));
        }
        String output;
        output = simWord4.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("SIMWO", output));
        }
        return Collections.singletonList(new Feature("SIMWO", "NA"));
    }

} public class TopicClass1FeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> topicClass1 = new HashMap<String, String>();
    static int i = 0;

    public TopicClass1FeatureExtractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "TopicClass1";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("topicCluster.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    topicClass1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("TopicClass", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("TopicClass", "NA"));
        }

        String output;
        output = topicClass1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("TopicClass", output));
        }
        return Collections.singletonList(new Feature("TopicClass", "NA"));

    }

} public class TopicClass200Feature1Extractor
    implements FeatureFunction
{

    static Map<String, String> topicClass1 = new HashMap<String, String>();
    static int i = 0;

    public TopicClass200Feature1Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "TopicClass200";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("topicCluster200.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    topicClass1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("TopicClass200", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("TopicClass200", "NA"));
        }

        String output;
        output = topicClass1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("TopicClass200", output));
        }
        return Collections.singletonList(new Feature("TopicClass200", "NA"));

    }

} public class TopicClass500Feature1Extractor
    implements FeatureFunction
{

    File topicClassFile = new File("topicCluster500.txt");
    static Map<String, String> topicClass1 = new HashMap<String, String>();
    static int i = 0;

    public TopicClass500Feature1Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "TopicClass500";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("topicCluster500.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    topicClass1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("TopicClass500", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("TopicClass500", "NA"));
        }

        String output;
        output = topicClass1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("TopicClass500", output));
        }
        return Collections.singletonList(new Feature("TopicClass500", "NA"));

    }

} public class TopicClass50Feature1Extractor
    implements FeatureFunction
{

    static Map<String, String> topicClass1 = new HashMap<String, String>();
    static int i = 0;

    public TopicClass50Feature1Extractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "TopicClass50";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("topicCluster50.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    topicClass1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("TopicClass50", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("TopicClass50", "NA"));
        }

        String output;
        output = topicClass1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("TopicClass50", output));
        }
        return Collections.singletonList(new Feature("TopicClass50", "NA"));

    }

} public class UperCasedTopicClass1FeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> uperCaseTopicClass1 = new HashMap<String, String>();
    static int i = 0;

    public UperCasedTopicClass1FeatureExtractor()
        throws IOException
    {
        // read
    }

    public static final String DEFAULT_NAME = "UperCaseTopicClass1";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("uperCasetopicClaster.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    uperCaseTopicClass1.put(sep[0], sep[1]);
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // System.out.println("Size:"+simWord1.size());

            i++;
        }

        Object featureValue = feature.getValue();

        if (featureValue == null) {
            return Collections.singletonList(new Feature("UperCaseTopicClass1", "NA"));
        }
        String value = featureValue.toString();
        if (value == null || value.length() == 0) {
            return Collections.singletonList(new Feature("UperCaseTopicClass1", "NA"));
        }

        String output;
        output = uperCaseTopicClass1.get(value);
        // System.out.println("Size:"+i);
        if (output != null) {
            return Collections.singletonList(new Feature("UperCaseTopicClass1", output));
        }
        return Collections.singletonList(new Feature("UperCaseTopicClass1", "NA"));

    }

} public class VornameListFeatureExtractor
    implements FeatureFunction
{

    static Map<String, String> dbVorNamen = new HashMap<String, String>();
    static int i = 0;

    public VornameListFeatureExtractor()
    {

    }

    public static final String DEFAULT_NAME = "DBVorNamen";

    @Override
    public List<Feature> apply(Feature feature)
    {

        if (i == 0) {
            BufferedReader br;
            try {
                NERReader reader = new NERReader();
                br = (BufferedReader) reader.getReader("vornameList.txt");
                String input;
                while ((input = br.readLine()) != null) {
                    String[] sep = input.split("\\t");
                    dbVorNamen.put(sep[0], "true");
                }
                br.close();
            }
            catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            i++;
        }

        Object featureValue = feature.getValue();

        String value = featureValue.toString();
        if (dbVorNamen.get(value) != null) {
            return Collections.singletonList(new Feature("DBVorNamen", "true"));
        }

        return Collections.singletonList(new Feature("DBVorNamen", "false"));
    }

} public class MyFeatureFunctionExtractor
    implements FeatureExtractor1<Token>
{

    public MyFeatureFunctionExtractor(FeatureExtractor1<Token> extractor,
            FeatureFunction... featureFunctions)
    {
        this.extractor = extractor;
        this.featureFunctions = featureFunctions;
    }

    @Override
    public List<Feature> extract(JCas jCas, Token focusAnnotation)
        throws CleartkExtractorException
    {
        List<Feature> features = new ArrayList<Feature>();
        List<Feature> baseFeatures = this.extractor.extract(jCas, focusAnnotation);
        // features.addAll(baseFeatures);
        for (Function<Feature, List<Feature>> featureFunction : this.featureFunctions) {
            features.addAll(apply(featureFunction, baseFeatures));
        }
        return features;
    }

    public static List<Feature> apply(Function<Feature, List<Feature>> featureFunction,
            List<Feature> features)
    {
        List<Feature> returnValues = new ArrayList<Feature>();
        for (Feature feature : features) {
            returnValues.addAll(featureFunction.apply(feature));
        }
        return returnValues;
    }

    private FeatureExtractor1<Token> extractor;

    private FeatureFunction[] featureFunctions;
}
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import org.cleartk.ml.feature.extractor.CleartkExtractor;
import org.cleartk.ml.feature.extractor.CleartkExtractor.Following;
import org.cleartk.ml.feature.extractor.CleartkExtractor.Preceding;
import org.cleartk.ml.feature.extractor.CoveredTextExtractor;
import org.cleartk.ml.feature.extractor.FeatureExtractor1;
import org.cleartk.ml.feature.function.FeatureFunctionExtractor;
import com.thoughtworks.xstream.XStream;
import de.tu.darmstadt.lt.ner.feature.extractor.CamelCaseFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.ClarkPosInductionFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.DBLocationListFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.DBNachnamenListFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.DBPersonListFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.FreeBaseFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.LTCapitalTypeFeatureFunction;
import de.tu.darmstadt.lt.ner.feature.extractor.LTCharacterCategoryPatternFunction;
import de.tu.darmstadt.lt.ner.feature.extractor.LTCharacterCategoryPatternFunction.PatternType;
import de.tu.darmstadt.lt.ner.feature.extractor.LTCharacterNgramFeatureFunction;
import de.tu.darmstadt.lt.ner.feature.extractor.LTCharacterNgramFeatureFunction.Orientation;
import de.tu.darmstadt.lt.ner.feature.extractor.PositionFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.SimilarWord1Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.SimilarWord2Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.SimilarWord3Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.SimilarWord4Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.TopicClass1FeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.TopicClass200Feature1Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.TopicClass500Feature1Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.TopicClass50Feature1Extractor;
import de.tu.darmstadt.lt.ner.feature.extractor.UperCasedTopicClass1FeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.extractor.VornameListFeatureExtractor;
import de.tu.darmstadt.lt.ner.feature.variables.MyFeatureFunctionExtractor;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 2)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromLeft, 0, 2)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 2)),
                        new Following(1)));

        // Prefix(3) Feature
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 3)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromLeft, 0, 3)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 3)),
                        new Following(1)));
        // prefix(4)
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 4)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromLeft, 0, 4)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromLeft, 0, 4)),
                        new Following(1)));

        // Suffix(1) Feature
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 1)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromRight, 0, 1)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 1)),
                        new Following(1)));

        // Suffix(2) Feature
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 2)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromRight, 0, 2)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 2)),
                        new Following(1)));

        // Suffix(3) Feature
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 3)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromRight, 0, 3)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 3)),
                        new Following(1)));

        // Suffix (4) feature
        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 4)),
                        new Preceding(1)));

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new LTCharacterNgramFeatureFunction(fromRight, 0, 4)));

        germaNERfeatures
                .add(new CleartkExtractor<Token, Token>(Token.class,
                        new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                                new LTCharacterNgramFeatureFunction(fromRight, 0, 4)),
                        new Following(1)));

        // Vorname List Feature
        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new VornameListFeatureExtractor()));

        // Position Feature
        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new PositionFeatureExtractor()));
        // FreeBase Feature

        germaNERfeatures.add(new MyFeatureFunctionExtractor(new CoveredTextExtractor<Token>(),
                new FreeBaseFeatureExtractor()));