@SuppressWarnings({"unchecked", "rawtypes"})
  public List<TokenPatternMatchFeature<?>> parseDescriptor(FunctionDescriptor descriptor) {
    MONITOR.startTask("parseDescriptor");
    try {
      List<TokenPatternMatchFeature<?>> wrappedFeatures =
          new ArrayList<TokenPatternMatchFeature<?>>();

      List<Feature<TokenPatternMatch, ?>> tokenPatternMatchFeatures = this.parse(descriptor);

      for (Feature<TokenPatternMatch, ?> tokenPatternMatchFeature : tokenPatternMatchFeatures) {
        TokenPatternMatchFeature<?> wrappedFeature = null;
        if (tokenPatternMatchFeature instanceof TokenPatternMatchFeature) {
          wrappedFeature = (TokenPatternMatchFeature<?>) tokenPatternMatchFeature;
        } else {
          wrappedFeature = new TokenPatternMatchFeatureWrapper(tokenPatternMatchFeature);
        }
        wrappedFeatures.add(wrappedFeature);
      }

      return wrappedFeatures;
    } finally {
      MONITOR.endTask();
    }
  }