/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.uima.ruta.ide.validator;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;

import org.antlr.runtime.Token;
import org.apache.commons.lang3.StringUtils;
import org.apache.uima.UIMAFramework;
import org.apache.uima.cas.CAS;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.impl.ResourceManager_impl;
import org.apache.uima.resource.metadata.FeatureDescription;
import org.apache.uima.resource.metadata.TypeDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.resource.metadata.impl.FeatureDescription_impl;
import org.apache.uima.ruta.ide.RutaIdeUIPlugin;
import org.apache.uima.ruta.ide.core.IRutaKeywords;
import org.apache.uima.ruta.ide.core.RutaCorePreferences;
import org.apache.uima.ruta.ide.core.RutaExtensionManager;
import org.apache.uima.ruta.ide.core.RutaKeywordsManager;
import org.apache.uima.ruta.ide.core.builder.RutaProjectUtils;
import org.apache.uima.ruta.ide.core.extensions.IIDEActionExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDEBlockExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDEBooleanFunctionExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDEConditionExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDENumberFunctionExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDEStringFunctionExtension;
import org.apache.uima.ruta.ide.core.extensions.IIDETypeFunctionExtension;
import org.apache.uima.ruta.ide.core.extensions.IRutaExtension;
import org.apache.uima.ruta.ide.parser.ast.FeatureMatchExpression;
import org.apache.uima.ruta.ide.parser.ast.ForEachBlock;
import org.apache.uima.ruta.ide.parser.ast.NullExpression;
import org.apache.uima.ruta.ide.parser.ast.RutaAction;
import org.apache.uima.ruta.ide.parser.ast.RutaBlock;
import org.apache.uima.ruta.ide.parser.ast.RutaCondition;
import org.apache.uima.ruta.ide.parser.ast.RutaDeclareDeclarationsStatement;
import org.apache.uima.ruta.ide.parser.ast.RutaExpression;
import org.apache.uima.ruta.ide.parser.ast.RutaFeatureDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaFunction;
import org.apache.uima.ruta.ide.parser.ast.RutaImportStatement;
import org.apache.uima.ruta.ide.parser.ast.RutaImportTypesStatement;
import org.apache.uima.ruta.ide.parser.ast.RutaListExpression;
import org.apache.uima.ruta.ide.parser.ast.RutaMacroDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaPackageDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaRegExpRule;
import org.apache.uima.ruta.ide.parser.ast.RutaRule;
import org.apache.uima.ruta.ide.parser.ast.RutaRuleElement;
import org.apache.uima.ruta.ide.parser.ast.RutaStatementConstants;
import org.apache.uima.ruta.ide.parser.ast.RutaStringExpression;
import org.apache.uima.ruta.ide.parser.ast.RutaStructureAction;
import org.apache.uima.ruta.ide.parser.ast.RutaTypeConstants;
import org.apache.uima.ruta.ide.parser.ast.RutaTypeDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaVariableDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaVariableReference;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.ast.ASTListNode;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.compiler.problem.IProblem;
import org.eclipse.dltk.compiler.problem.IProblemReporter;
import org.eclipse.dltk.compiler.problem.ProblemSeverity;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.builder.ISourceLineTracker;
import org.eclipse.jface.preference.IPreferenceStore;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

public class LanguageCheckerVisitor extends ASTVisitor {

  private IProblemReporter pr;

  private ISourceLineTracker linetracker;

  private ISourceModule sourceModule;

  private Map<String, IIDEConditionExtension> conditionExtensions;

  private Map<String, IIDEActionExtension> actionExtensions;

  private Map<String, IIDENumberFunctionExtension> numberFunctionExtensions;

  private Map<String, IIDEBooleanFunctionExtension> booleanFunctionExtensions;

  private Map<String, IIDEStringFunctionExtension> stringFunctionExtensions;

  private Map<String, IIDETypeFunctionExtension> typeFunctionExtensions;

  private Map<String, IIDEBlockExtension> blockExtensions;

  /**
   * Mapping from short type name (e.g. {@code W}) to their disambiguated long type names (e.g.
   * {@code org.apache.uima.ruta.type.W}).
   */
  private Map<String, String> namespaces;

  /**
   * Mapping from ambiguous short type names to all their possible long type names.
   */
  private Map<String, Set<String>> ambiguousTypeAlias;

  /**
   * Known variables for each block environment
   */
  private final Stack<Map<String, Integer>> knownLocalVariables;

  /**
   * Name of each block
   */
  private final Stack<String> blocks;

  /**
   * each (inlined) rules
   */
  private final Stack<RutaRule> rules;

  /**
   * Caching the matched type of a rule element
   */
  private String matchedType;

  /**
   * Caching the declared package of the script
   */
  private String packageName = "";

  /**
   * Mapping all long type names of the type system to their type description
   */
  private Map<String, TypeDescription> typeDescriptionMap;

  /**
   * Mapping all long type names of all declared feature description
   */
  private Map<String, Set<FeatureDescription>> featureDescriptionMap;

  /**
   * The type system description of the script file
   */
  private TypeSystemDescription typeSystemDescription;

  private final String implicitString = "Implicit";

  private Set<String> finalTypes;

  private boolean reportWarningOnShortNames;

  private RutaCheckerProblemFactory problemFactory;

  private ResourceManager resourceManager;

  private Set<String> allLongTypeNames;

  private String parentTypeInDeclaration;

  private ClassLoader classLoader;

  private String packagePathString;

  private boolean packageChecked = false;

  private Collection<String> currentLabels = new HashSet<>();

  public LanguageCheckerVisitor(IProblemReporter problemReporter, ISourceLineTracker linetracker,
          ISourceModule sourceModule, ClassLoader classLoader) {
    super();
    this.pr = problemReporter;
    this.linetracker = linetracker;
    this.sourceModule = sourceModule;
    this.classLoader = classLoader;
    this.problemFactory = new RutaCheckerProblemFactory(sourceModule.getElementName(), linetracker);

    namespaces = new TreeMap<String, String>();
    ambiguousTypeAlias = new TreeMap<String, Set<String>>();
    allLongTypeNames = new HashSet<String>();
    knownLocalVariables = new Stack<Map<String, Integer>>();
    knownLocalVariables.push(new HashMap<String, Integer>());
    blocks = new Stack<String>();
    rules = new Stack<RutaRule>();
    packagePathString = "";

    initializePredefinedInformation();
    initializeExtensionInformation();

    IProject project = sourceModule.getScriptProject().getProject();
    IPath location = sourceModule.getResource().getLocation();
    try {
      IPath packagePath = RutaProjectUtils.getPackagePath(location, project);
      if (packagePath != null) {
        packagePathString = packagePath.toPortableString().replaceAll("/", ".");
      }
    } catch (CoreException e) {
      RutaIdeUIPlugin.error(e);
    }

    IPreferenceStore store = RutaIdeUIPlugin.getDefault().getPreferenceStore();
    reportWarningOnShortNames = !store
            .getBoolean(RutaCorePreferences.BUILDER_IGNORE_DUPLICATE_SHORTNAMES);

  }

  @Override
  public boolean visit(Statement s) throws Exception {
    if (s instanceof RutaPackageDeclaration) {
      this.packageName = ((RutaPackageDeclaration) s).getName();
      checkPackage(s);
      return false;
    }
    if (s instanceof RutaMacroDeclaration) {
      RutaMacroDeclaration decl = (RutaMacroDeclaration) s;
      Map<Token, Token> definition = decl.getDefinition();
      String name = decl.getName();
      int kind = decl.getKind();
      if (kind == RutaTypeConstants.RUTA_TYPE_A) {
        actionExtensions.put(name, null);
      } else if (kind == RutaTypeConstants.RUTA_TYPE_C) {
        conditionExtensions.put(name, null);
      }
      Set<Entry<Token, Token>> entrySet = definition.entrySet();
      Map<String, Integer> map = new HashMap<>();
      for (Entry<Token, Token> entry : entrySet) {
        String varName = entry.getKey().getText();
        String varType = entry.getValue().getText();
        int vt = getType(varType);
        map.put(varName, vt);
      }
      knownLocalVariables.push(map);
    }
    if (s instanceof RutaImportTypesStatement) {
      RutaImportTypesStatement stmt = (RutaImportTypesStatement) s;
      SimpleReference tsExpr = (SimpleReference) stmt.getExpression();
      Token typeToken = stmt.getTypeToken();
      Token pkgToken = stmt.getPkgToken();
      Token aliasToken = stmt.getAliasToken();
      if (tsExpr != null) {
        String localPath = tsExpr.getName();
        processCompleteTypeSystemImport(tsExpr, localPath, typeToken, pkgToken, aliasToken);
      } else {
        // TODO package import not supported in Workbench
      }

    } else if (s instanceof RutaImportStatement) {
      // handle type system imports
      if (((RutaImportStatement) s).getType() == RutaStatementConstants.S_IMPORT_TYPESYSTEM) {
        SimpleReference sRef = (SimpleReference) ((RutaImportStatement) s).getExpression();
        String localPath = sRef.getName();
        processCompleteTypeSystemImport(sRef, localPath);
        return false;
      }
      // handle script-imports
      if (((RutaImportStatement) s).getType() == RutaStatementConstants.S_IMPORT_SCRIPT) {
        SimpleReference sRef = (SimpleReference) ((RutaImportStatement) s).getExpression();
        String localPath = sRef.getName();

        // HOTFIX Peter add also the imported types of the imported type system!
        try {
          URL url = null;
          IFile file = RutaCheckerUtils.checkScriptImport(localPath,
                  sourceModule.getScriptProject());
          if (file == null) {
            String typesystemSuffix = RutaProjectUtils
                    .getTypeSystemSuffix(sourceModule.getScriptProject().getProject());
            url = RutaCheckerUtils.checkImportExistence(localPath + typesystemSuffix, "xml",
                    classLoader);
          }
          if (file == null && url == null) {
            pr.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
          } else {
            IProject referredProject = sourceModule.getScriptProject().getProject();
            if (file != null) {
              // script in other project? use that if the file was found in the workspace
              referredProject = file.getProject();
              IPath typeSystemDescriptorPath = RutaProjectUtils.getTypeSystemDescriptorPath(
                      file.getLocation(), referredProject, classLoader);
              TypeSystemDescription tsDesc = importCompleteTypeSystem(typeSystemDescriptorPath,
                      url);

              List<String> checkDuplicateShortNames = checkOnAmbiguousShortNames(tsDesc);
              if (!checkDuplicateShortNames.isEmpty()) {
                pr.reportProblem(problemFactory.createDuplicateShortNameInImported(sRef, localPath,
                        checkDuplicateShortNames, ProblemSeverity.WARNING));
              }
            }
          }
        } catch (IOException e) {
          pr.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
        }
        return false;
      }
    }

    if (s instanceof RutaDeclareDeclarationsStatement) {
      RutaDeclareDeclarationsStatement dds = (RutaDeclareDeclarationsStatement) s;
      ASTNode parent = dds.getParent();
      if (parent != null && parent instanceof RutaVariableReference) {
        RutaVariableReference p = (RutaVariableReference) parent;
        String name = p.getName();
        name = expand(name);
        parentTypeInDeclaration = name;
        // TODO remember name for new types and their features!
        if (finalTypes.contains(name)) {
          IProblem problem = problemFactory.createInheritenceFinalProblem(p);
          pr.reportProblem(problem);
        }
      }
      return true;
    }
    if (s instanceof RutaTypeDeclaration) {
      RutaTypeDeclaration newType = (RutaTypeDeclaration) s;
      String shortName = newType.getName();
      String longName = getLongNameOfNewType(shortName);

      if (namespaces.values().contains(longName)) {
        IProblem problem = problemFactory.createIdConflictsWithTypeProblem(newType);
        pr.reportProblem(problem);
        return false;
      }

      if (reportWarningOnShortNames && namespaces.containsKey(shortName)) {
        IProblem problem = problemFactory.createDuplicateShortName(newType,
                ProblemSeverity.WARNING);
        pr.reportProblem(problem);
        return false;
      }
      if (knowsVariable(shortName)) {
        IProblem problem = problemFactory.createIdConflictsWithVariableProblem(newType);
        pr.reportProblem(problem);
        return false;
      }
      List<RutaFeatureDeclaration> features = newType.getFeatures();
      Set<FeatureDescription> feats = new HashSet<FeatureDescription>();
      if (parentTypeInDeclaration != null) {
        Set<FeatureDescription> set = featureDescriptionMap.get(parentTypeInDeclaration);
        if (set != null) {
          feats.addAll(set);
        }
      }
      if (features != null) {
        for (RutaFeatureDeclaration each : features) {
          // TODO create correct feature description! Works right now because the type is not
          // checked
          String type = each.getType();
          type = translate(type);
          type = expand(type);
          FeatureDescription f = new FeatureDescription_impl(each.getName(), "", type);
          feats.add(f);
          if (type.equals("INT") || type.equals("STRING") || type.equals("DOUBLE")
                  || type.equals("FLOAT") || type.equals("BOOLEAN")) {
            continue;
          }
          if (!namespaces.keySet().contains(type) && !namespaces.values().contains(type)) {
            IProblem problem = problemFactory.createUnknownFeatureTypeProblem(each);
            pr.reportProblem(problem);
          }

        }
        featureDescriptionMap.put(longName, feats);
      }
      addDeclaredType(shortName);
      return false;
    }
    if (s instanceof RutaVariableDeclaration) {
      RutaVariableDeclaration newVar = (RutaVariableDeclaration) s;
      if (knowsVariable(newVar.getName())) {
        IProblem problem = problemFactory.createIdConflictsWithVariableProblem(newVar);
        pr.reportProblem(problem);
        return false;
      }
      if (namespaces.containsKey(newVar.getName())) {
        IProblem problem = problemFactory.createIdConflictsWithTypeProblem(newVar);
        pr.reportProblem(problem);
        return false;
      }
      knownLocalVariables.peek().put(newVar.getName(), newVar.getKind());
      return false;
    }
    if (s instanceof RutaRegExpRule) {
      RutaRegExpRule rule = (RutaRegExpRule) s;
      Map<Expression, Map<Expression, Expression>> faMap = rule.getFeats();
      Set<Entry<Expression, Map<Expression, Expression>>> typeEntrySet = faMap.entrySet();
      for (Entry<Expression, Map<Expression, Expression>> entry : typeEntrySet) {
        Expression struct = entry.getKey();
        String structure = "";
        if (struct != null) {
          structure = sourceModule.getSource().substring(struct.sourceStart(), struct.sourceEnd());
          structure = expand(structure);
        }
        Map<Expression, Expression> fmap = entry.getValue();
        Set<Expression> keySet = fmap.keySet();
        for (Expression fkey : keySet) {
          if (fkey instanceof RutaExpression && fkey.getKind() == RutaTypeConstants.RUTA_TYPE_S) {
            String feat = fkey.toString();
            feat = getFeatureName(fkey, feat);
            boolean findFeature = findFeature(structure, feat, -1);
            if (!findFeature) {
              IProblem problem = problemFactory.createUnknownFeatureProblem(fkey, structure);
              pr.reportProblem(problem);
            }
          }
        }
      }
    }
    if (s instanceof RutaRule) {
      if (rules.isEmpty()) {
        collectAllLabels((RutaRule) s);
      }
      rules.push((RutaRule) s);
    }
    return true;
  }

  private void collectAllLabels(RutaRule rule) {
    try {
      RuleElementLabelVisitor visitor = new RuleElementLabelVisitor();
      rule.traverse(visitor);
      currentLabels = visitor.getLabels();
    } catch (Exception e) {
      RutaIdeUIPlugin.error(e);
    }
  }

  private void checkPackage(ASTNode node) {
    if (!StringUtils.equals(packageName, packagePathString) && !packageChecked) {
      pr.reportProblem(problemFactory.createWrongPackageProblem(node));
    }
    packageChecked = true;
  }

  private void processCompleteTypeSystemImport(SimpleReference sRef, String localPath)
          throws CoreException {
    processCompleteTypeSystemImport(sRef, localPath, null, null, null);
  }

  private void processCompleteTypeSystemImport(SimpleReference sRef, String localPath,
          Token typeToken, Token pkgToken, Token aliasToken) throws CoreException {
    try {
      URL url = null;
      IFile file = RutaCheckerUtils.checkTypeSystemImport(localPath,
              sourceModule.getScriptProject());
      if (file == null) {
        url = RutaCheckerUtils.checkImportExistence(localPath, "xml", classLoader);
      }
      if (file == null && url == null) {
        pr.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
      } else {
        IPath path = file == null ? null : file.getLocation();
        TypeSystemDescription tsDesc = importTypeSystem(path, url, typeToken, pkgToken, aliasToken);
        if (reportWarningOnShortNames) {
          List<String> checkDuplicateShortNames = checkOnAmbiguousShortNames(tsDesc);
          if (!checkDuplicateShortNames.isEmpty()) {
            pr.reportProblem(problemFactory.createDuplicateShortNameInImported(sRef, localPath,
                    checkDuplicateShortNames, ProblemSeverity.WARNING));
          }
        }
      }
    } catch (IOException e) {
      pr.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
    } catch (InvalidXMLException e) {
      pr.reportProblem(problemFactory.createXMLProblem(sRef, localPath));
    }
  }

  private List<String> checkOnAmbiguousShortNames(TypeSystemDescription tsDesc) {
    List<String> checkDuplicateShortNames = new ArrayList<String>();
    for (TypeDescription each : tsDesc.getTypes()) {
      String longName = each.getName();
      String shortName = getShortName(longName);
      Set<String> set = ambiguousTypeAlias.get(shortName);
      if (set != null && set.size() > 1) {
        checkDuplicateShortNames.addAll(set);
      }
    }
    return checkDuplicateShortNames;
  }

  private TypeSystemDescription importTypeSystem(IPath path, URL url, Token typeToken,
          Token pkgToken, Token aliasToken)
          throws InvalidXMLException, IOException, MalformedURLException, CoreException {
    TypeSystemDescription tsDesc = null;
    if (path != null) {
      tsDesc = UIMAFramework.getXMLParser()
              .parseTypeSystemDescription(new XMLInputSource(path.toFile()));
    } else {
      tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription(new XMLInputSource(url));
    }

    ResourceManager resMgr = getResourceManager(classLoader);
    tsDesc.resolveImports(resMgr);
    for (TypeDescription each : tsDesc.getTypes()) {
      String longName = each.getName();
      String shortName = getShortName(longName);
      if (pkgToken != null) {
        String pkg = pkgToken.getText();
        if (!longName.startsWith(pkg + ".")) {
          continue;
        }
      }
      if (typeToken != null) {
        String type = typeToken.getText();
        if (!longName.equals(type)) {
          continue;
        }
      }
      if (aliasToken != null) {
        String alias = aliasToken.getText();
        if (typeToken == null) {
          shortName = alias + "." + shortName;
        } else {
          shortName = alias;
        }
      }
      importType(longName, shortName);
    }
    return tsDesc;
  }

  private ResourceManager getResourceManager(ClassLoader classloader)
          throws MalformedURLException, CoreException {
    if (resourceManager == null) {
      resourceManager = new ResourceManager_impl(classloader);
      List<IFolder> folders = RutaProjectUtils
              .getAllDescriptorFolders(sourceModule.getScriptProject().getProject());
      StringBuilder sb = new StringBuilder();
      Iterator<IFolder> iterator = folders.iterator();
      while (iterator.hasNext()) {
        IFolder iFolder = iterator.next();
        sb.append(iFolder.getLocation().toPortableString());
        if (iterator.hasNext()) {
          sb.append(System.getProperty("path.separator"));
        }
      }
      resourceManager.setDataPath(sb.toString());
    }
    return resourceManager;
  }

  @Override
  public boolean visit(Expression s) throws Exception {

    if (s instanceof RutaRuleElement) {
      RutaRuleElement re = (RutaRuleElement) s;
      Expression head = re.getHead();
      if (head instanceof FeatureMatchExpression) {
        FeatureMatchExpression fme = (FeatureMatchExpression) head;
        String text = fme.getFeature().getText();
        int lastIndexOf = text.lastIndexOf('.');
        String twf = text.substring(0, lastIndexOf);
        Integer variableType = getVariableType(twf);
        if (variableType != null && variableType == RutaTypeConstants.RUTA_TYPE_AT) {
          matchedType = twf;
        } else {
          twf = expand(twf);
          matchedType = isFeatureMatch(twf);
        }
      } else if (head != null) {
        matchedType = sourceModule.getSource().substring(head.sourceStart(), head.sourceEnd());
      }
      // cache long name
      matchedType = expand(matchedType);
      if (matchedType == null) {
        matchedType = "uima.tcas.Annotation";
      }
    }
    if (s instanceof FeatureMatchExpression) {
      FeatureMatchExpression fme = (FeatureMatchExpression) s;
      String featText = fme.getFeature().getText();
      // HOTFIX: parser creates wrong AST element
      if (allLongTypeNames.contains(featText)) {
        return true;
      }
      if (namespaces.keySet().contains(featText)) {
        // wrong ast elements, alias interpreted as feature expression
        return false;
      }
      checkTypeOfFeatureMatch(featText, fme);
      return true;
    }
    if (s instanceof RutaVariableReference) {
      if (s instanceof NullExpression) {
        return false;
      }
      RutaVariableReference ref = (RutaVariableReference) s;
      if (ref.getType() == RutaTypeConstants.RUTA_TYPE_WT
              || ref.getType() == RutaTypeConstants.RUTA_TYPE_WL) {
        if (StringUtils.isBlank(ref.getName())) {
          // declaration with a string expression: do not check
          return false;
        }
      }
      if ((ref.getType() & RutaTypeConstants.RUTA_TYPE_AT) != 0) {
        // types
        String name = ref.getName();
        if (name.equals("Document")) {
          return false;
        }

        Set<String> set = ambiguousTypeAlias.get(name);
        if (set != null && !set.isEmpty()) {
          pr.reportProblem(
                  problemFactory.createAmbiguousShortName(ref, set, ProblemSeverity.ERROR));
          return false;
        }
        if (namespaces.keySet().contains(name) || namespaces.values().contains(name)
                || allLongTypeNames.contains(name)) {
          return false;
        }
        Integer variableType = getVariableType(name);
        if (variableType != null && (variableType == RutaTypeConstants.RUTA_TYPE_AT
                || variableType == RutaTypeConstants.RUTA_TYPE_UA
                || variableType == RutaTypeConstants.RUTA_TYPE_UAL)) {
          return false;
        }
        if (isFeatureMatch(name) != null) {
          return false;
        }
        if (isLabel(name)) {
          return false;
        }
        if (name.indexOf(".") != -1) {
          String[] split = name.split("[.]");
          if (StringUtils.equals(split[split.length - 1], "ct")
                  || StringUtils.equals(split[split.length - 1], "coveredText")) {
            return false;
          }
          Integer prefixType = getVariableType(split[0]);
          if (prefixType == RutaTypeConstants.RUTA_TYPE_UA
                  || prefixType == RutaTypeConstants.RUTA_TYPE_UAL) {
            return false;
          }
        }

        pr.reportProblem(problemFactory.createTypeProblem(ref, sourceModule));
        return false;
      }
      if (!isVariableDeclared(ref)) {
        return false;
      }
      checkTypeOfVariable(ref);
      return false;
    }
    // check assign types
    if (s instanceof RutaAction) {
      RutaAction tma = (RutaAction) s;

      String actionName = sourceModule.getSource().substring(tma.getNameStart(), tma.getNameEnd());
      String[] keywords = RutaKeywordsManager.getKeywords(IRutaKeywords.ACTION);
      List<String> asList = Arrays.asList(keywords);
      if (!StringUtils.isEmpty(actionName) && !"-".equals(actionName)
              && !asList.contains(actionName) && !implicitString.equals(tma.getName())
              && !actionExtensions.keySet().contains(actionName)) {
        IProblem problem = problemFactory.createUnknownActionProblem(tma);
        pr.reportProblem(problem);
      }

      IRutaExtension extension = actionExtensions.get(actionName);
      if (extension != null) {
        extension.checkSyntax(tma, problemFactory, pr);
      }

      if (tma.getName().equals("GETFEATURE") || tma.getName().equals("SETFEATURE")) {
        List<?> childs = tma.getChilds();
        RutaStringExpression stringExpr = (RutaStringExpression) childs.get(0);
        String feat = stringExpr.toString();
        feat = getFeatureName(stringExpr, feat);
        boolean featureFound = findFeature(matchedType, feat, -1);
        if (!featureFound) {
          IProblem problem = problemFactory.createUnknownFeatureProblem(stringExpr, matchedType);
          pr.reportProblem(problem);
        }
      }

      if (s instanceof RutaStructureAction) {
        RutaStructureAction sa = (RutaStructureAction) s;
        Expression struct = sa.getStructure();
        String structure = null;
        if (struct != null) {
          structure = sourceModule.getSource().substring(struct.sourceStart(), struct.sourceEnd());
          structure = expand(structure);
        }
        Map<Expression, Expression> assignments = sa.getAssignments();
        // hotfix... correct name in ast
        String action = sourceModule.getSource().substring(sa.getNameStart(), sa.getNameEnd());
        if (assignments != null && !action.equals("TRIE")) {
          for (Expression each : assignments.keySet()) {
            // TODO refactor to visitor?
            String feat = each.toString();
            // List<?> childs = each.getChilds();
            feat = getFeatureName(each, feat);
            boolean featureFound = findFeature(structure, feat, -1);
            if (!featureFound) {
              IProblem problem = problemFactory.createUnknownFeatureProblem(each, structure);
              pr.reportProblem(problem);
            }
          }
        } else if (assignments != null && action.equals("TRIE")) {
          for (Expression each : assignments.values()) {
            if (each instanceof RutaListExpression) {
              RutaListExpression rle = (RutaListExpression) each;
              List<?> childs = rle.getExprs().getChilds();
              if (childs.size() != 2 && childs.size() != 3) {
                IProblem problem = problemFactory.createWrongNumberOfArgumentsProblem(actionName,
                        rle, 2);
                pr.reportProblem(problem);
              }
              Object arg1 = childs.get(0);
              if (arg1 instanceof RutaExpression) {
                RutaExpression e1 = (RutaExpression) arg1;
                if (e1.getKind() != RutaTypeConstants.RUTA_TYPE_AT) {
                  IProblem problem = problemFactory.createWrongArgumentTypeProblem(e1, "Type");
                  pr.reportProblem(problem);
                }
              }
              Object arg2 = childs.get(1);
              if (arg2 instanceof RutaExpression) {
                RutaExpression e2 = (RutaExpression) arg2;
                if (e2.getKind() != RutaTypeConstants.RUTA_TYPE_S) {
                  IProblem problem = problemFactory.createWrongArgumentTypeProblem(e2, "String");
                  pr.reportProblem(problem);
                }
              }
            }
          }
        }
      }
    }
    if (s instanceof RutaCondition) {
      RutaCondition cond = (RutaCondition) s;
      String conditionName = sourceModule.getSource().substring(cond.getNameStart(),
              cond.getNameEnd());
      String[] keywords = RutaKeywordsManager.getKeywords(IRutaKeywords.CONDITION);
      List<String> asList = Arrays.asList(keywords);
      if (!StringUtils.isEmpty(conditionName) && !"-".equals(conditionName)
              && !asList.contains(conditionName) && !implicitString.equals(cond.getName())
              && !conditionExtensions.keySet().contains(conditionName)) {
        IProblem problem = problemFactory.createUnknownConditionProblem(cond);
        pr.reportProblem(problem);
      }

      IRutaExtension extension = conditionExtensions.get(conditionName);
      if (extension != null) {
        // boolean checkSyntax =
        extension.checkSyntax(cond, problemFactory, pr);
      }

      if (conditionName.equals("FEATURE")) {
        if (matchedType != null) {
          List<?> args = cond.getChilds();
          RutaStringExpression se = (RutaStringExpression) args.get(0);
          String feat = se.toString();
          feat = getFeatureName(se, feat);
          boolean featureFound = findFeature(matchedType, feat, -1);
          if (!featureFound) {
            String featureMatch = isFeatureMatch(matchedType);
            if (featureMatch != null) {
              featureFound = findFeature(featureMatch, feat, -1);
            }
          }
          if (!featureFound) {
            IProblem problem = problemFactory.createUnknownFeatureProblem(se, matchedType);
            pr.reportProblem(problem);
          }
        }
      }
      if (conditionName.equals("CONTAINS")) {
        List<?> args = cond.getChilds();
        boolean valid = checkContainsArguments(args);
        if (!valid) {
          IProblem problem = problemFactory.createWrongArgumentTypeProblem(cond,
                  "different combination of arguments.");
          pr.reportProblem(problem);
        }
      }

    }
    if (s instanceof RutaFunction) {
      RutaFunction f = (RutaFunction) s;
      String name = f.getName();
      if (s.getKind() == RutaTypeConstants.RUTA_TYPE_AT) {
        IRutaExtension extension = typeFunctionExtensions.get(name);
        if (extension != null) {
          extension.checkSyntax(s, problemFactory, pr);
        }
      } else if (s.getKind() == RutaTypeConstants.RUTA_TYPE_B) {
        IRutaExtension extension = booleanFunctionExtensions.get(name);
        if (extension != null) {
          extension.checkSyntax(s, problemFactory, pr);
        }
      } else if (s.getKind() == RutaTypeConstants.RUTA_TYPE_N) {
        IRutaExtension extension = numberFunctionExtensions.get(name);
        if (extension != null) {
          extension.checkSyntax(s, problemFactory, pr);
        }
      } else if (s.getKind() == RutaTypeConstants.RUTA_TYPE_S) {
        IRutaExtension extension = stringFunctionExtensions.get(name);
        if (extension != null) {
          extension.checkSyntax(s, problemFactory, pr);
        }
      }
    }
    return true;
  }

  @SuppressWarnings("unused")
  private boolean checkContainsArguments(List<?> args) {
    if (args.size() == 1) {
      Object arg = args.get(0);
      // if (arg instanceof ITypeExpression) {
      return true;
      // }
    } else if (args.size() == 2) {
      Object arg1 = args.get(0);
      Object arg2 = args.get(1);
      // if (arg1 instanceof ListExpression) {
      return true;
      // }
    } else if (args.size() == 3) {
      Object arg1 = args.get(0);
      Object arg2 = args.get(1);
      Object arg3 = args.get(2);
      // if (arg1 instanceof ITypeExpression && arg2 instanceof INumberExpression
      // && arg3 instanceof INumberExpression) {
      return true;
      // }
    } else if (args.size() == 4) {
      Object arg1 = args.get(0);
      Object arg2 = args.get(1);
      Object arg3 = args.get(2);
      Object arg4 = args.get(3);
      // if (arg1 instanceof ITypeExpression && arg2 instanceof INumberExpression
      // && arg3 instanceof INumberExpression && arg4 instanceof IBooleanExpression) {
      return true;
      // }
    } else if (args.size() == 5) {
      Object arg1 = args.get(0);
      Object arg2 = args.get(1);
      Object arg3 = args.get(2);
      Object arg4 = args.get(3);
      Object arg5 = args.get(3);
      // if (arg1 instanceof ListExpression && arg3 instanceof INumberExpression
      // && arg4 instanceof INumberExpression && arg5 instanceof IBooleanExpression) {
      return true;
      // }
    }
    return false;
  }

  private boolean isLabel(String name) {

    if (currentLabels.contains(name)) {
      return true;
    }

    if (name.contains(".")) {
      String[] split = name.split("[.]");
      if (split.length > 0) {
        return currentLabels.contains(split[0]);
      }
    }

    return false;
  }

  private String expand(String shortName) {
    if (shortName == null) {
      return null;
    }
    String longName = shortName;
    String string = namespaces.get(shortName);
    if (string != null) {
      longName = string;
    }
    return longName;
  }

  private void checkTypeOfFeatureMatch(String featText, FeatureMatchExpression fme) {
    int lastIndexOf = featText.lastIndexOf(".");
    int firstIndexOf = featText.indexOf(".");
    if (lastIndexOf == -1) {
      return;
    }
    String bref = featText.substring(0, firstIndexOf);
    String aref = featText.substring(0, lastIndexOf);
    String fref = featText.substring(lastIndexOf + 1, featText.length());
    if (currentLabels.contains(aref) || currentLabels.contains(bref)) {
      return;
    }
    String match = isFeatureMatch(aref);
    Integer variableType1 = getVariableType(aref);
    Integer variableType2 = getVariableType(bref);
    if (match == null && variableType1 != null && variableType2 != null
            && (variableType1 == RutaTypeConstants.RUTA_TYPE_AT
                    || variableType2 == RutaTypeConstants.RUTA_TYPE_AT
                    || variableType1 == RutaTypeConstants.RUTA_TYPE_UA)) {
      // do not check on variables!
      return;
    }

    // match expression against local annotation variables cannot be checked
    if (variableType2 == RutaTypeConstants.RUTA_TYPE_UA
            || variableType2 == RutaTypeConstants.RUTA_TYPE_UAL) {
      return;
    }

    match = expand(match);
    if (match != null) {
      int kind = -1;
      if (fme.getValue() != null) {
        kind = fme.getValue().getKind();
        if (fme.getValue() instanceof StringLiteral) {
          kind = RutaTypeConstants.RUTA_TYPE_S;
        } else if (fme.getValue() instanceof NumericLiteral) {
          kind = RutaTypeConstants.RUTA_TYPE_N;
        } else if (fme.getValue() instanceof RutaVariableReference) {
          kind = ((RutaVariableReference) fme.getValue()).getType();
        } else if (fme.getValue() instanceof RutaFunction) {
          // check on function deactivates, requires correct parsing of AST with external factory
          kind = -1;
        }
      }
      boolean findFeature = findFeature(match, fref, kind);
      if (findFeature || fme.getValue() instanceof NullExpression) {

      } else {
        pr.reportProblem(problemFactory.createUnknownFeatureProblem(fme, aref));
      }
    } else {
      pr.reportProblem(problemFactory.createTypeProblem(fme, sourceModule));
      pr.reportProblem(problemFactory.createUnknownFeatureProblem(fme, aref));
    }
  }

  @Override
  public boolean endvisit(Expression s) throws Exception {
    if (s instanceof RutaRuleElement) {
      matchedType = null;
    }
    return super.endvisit(s);
  }

  @Override
  public boolean endvisit(Statement s) throws Exception {
    if (s instanceof RutaDeclareDeclarationsStatement) {
      parentTypeInDeclaration = null;
    }
    if (s instanceof ForEachBlock) {
      knownLocalVariables.pop();
    }
    if (s instanceof RutaMacroDeclaration) {
      knownLocalVariables.pop();
    }
    if (!packageChecked) {
      checkPackage(null);
    }
    if (s instanceof RutaRule) {
      rules.pop();
      if (rules.isEmpty()) {
        currentLabels.clear();
      }
    }

    return super.endvisit(s);
  }

  @Override
  public boolean endvisit(MethodDeclaration s) throws Exception {
    if (s instanceof RutaBlock) {
      knownLocalVariables.pop();
      blocks.pop();
    }
    return super.endvisit(s);
  }

  @Override
  public boolean visit(MethodDeclaration s) throws Exception {
    if (s instanceof RutaBlock) {
      RutaBlock b = (RutaBlock) s;
      String name = b.getName();
      HashMap<String, Integer> map = new HashMap<String, Integer>();
      if (b instanceof ForEachBlock) {
        map.put(name, RutaTypeConstants.RUTA_TYPE_UA);
      }
      knownLocalVariables.push(map);
      blocks.push(name);
      // TODO add syntax check for block extensions
    }
    return true;
  }

  private boolean findFeature(String longTypeName, String featureName, int kind) {
    if (longTypeName == null) {
      return false;
    }
    if (longTypeName.equals("Document") || longTypeName.equals("org.apache.uima.ruta.type.Document")
            || longTypeName.equals("uima.tcas.DocumentAnnotation")) {
      if (featureName.equals("language") || featureName.equals("begin")
              || featureName.equals("end")) {
        return true;
      }
    }
    if (featureName.equals("begin") || featureName.equals("end")) {
      return kind == -1 || kind == RutaTypeConstants.RUTA_TYPE_N;
    }
    if (featureName.equals("ct") || featureName.equals("coveredText")) {
      return kind == -1 || kind == RutaTypeConstants.RUTA_TYPE_S;
    }
    Set<FeatureDescription> set = featureDescriptionMap.get(longTypeName);
    if (set != null) {
      for (FeatureDescription featureDescription : set) {
        String fName = featureDescription.getName();
        // TODO check on correct feature type, e.g., the type of the annotation
        if (fName.equals(featureName)
                && (kind == -1 || checkFeatureKind(featureDescription, kind))) {
          return true;
        }
      }
    }
    return false;
  }

  private boolean checkFeatureKind(FeatureDescription f, int kind) {
    if (kind == -1) {
      return true;
    }
    String t = f.getRangeTypeName();
    if (t.equals(CAS.TYPE_NAME_BOOLEAN) && RutaTypeConstants.RUTA_TYPE_B == kind) {
      return true;
    } else if (t.equals(CAS.TYPE_NAME_STRING) && RutaTypeConstants.RUTA_TYPE_S == kind) {
      return true;
    } else if ((t.equals(CAS.TYPE_NAME_BYTE) || t.equals(CAS.TYPE_NAME_DOUBLE)
            || t.equals(CAS.TYPE_NAME_FLOAT) || t.equals(CAS.TYPE_NAME_INTEGER)
            || t.equals(CAS.TYPE_NAME_LONG) || t.equals(CAS.TYPE_NAME_SHORT))
            && RutaTypeConstants.RUTA_TYPE_N == kind) {
      return true;
    } else if (RutaTypeConstants.RUTA_TYPE_AT == kind) {
      return true;
    }
    return false;
  }

  private void addDeclaredType(String shortName) {
    String longName = getLongNameOfNewType(shortName);
    importType(longName, shortName);
  }

  private String getLongNameOfNewType(String shortName) {
    String moduleName = sourceModule.getElementName();
    moduleName = moduleName.substring(0, moduleName.length() - 5);
    String packagePrefix = "";
    if (!packageName.isEmpty()) {
      packagePrefix = packageName + ".";
    }
    for (String each : blocks) {
      packagePrefix += each + ".";
    }
    String longName = packagePrefix + moduleName + "." + shortName;
    return longName;
  }

  /**
   * Import a type in the current namespace.
   * 
   * @param longName
   *          Complete type name.
   * @param shortName
   *          Short type name (without namespace).
   */
  private void importType(String longName, String shortName) {
    if (allLongTypeNames.contains(longName)) {
      // TODO: in conflict with double import
      // pr.reportProblem(problemFactory.createIdenticalLongTypeNameProblem(longName,
      // sourceModule));
    } else {
      allLongTypeNames.add(longName);
    }
    Set<String> targets = ambiguousTypeAlias.get(shortName);
    if (targets != null) {
      // shortName is already ambiguous, add longName to its list of possible targets
      targets.add(longName);
    } else {
      String existing = namespaces.put(shortName, longName);

      if (existing != null && !existing.equals(longName)) {
        // shortName can now be resolved to "existing" or "longName"
        targets = new HashSet<String>(2);
        targets.add(existing);
        targets.add(longName);

        // add existing mapping and longName to its list of possible targets
        ambiguousTypeAlias.put(shortName, targets);

        // remove shortName from the namespace because it is ambiguous
        namespaces.remove(shortName);
      }
    }
  }

  private boolean knowsVariable(String name) {
    for (Map<String, Integer> each : knownLocalVariables) {
      if (each.containsKey(name)) {
        return true;
      }
    }
    return false;
  }

  private Integer getVariableType(String name) {
    for (Map<String, Integer> each : knownLocalVariables) {
      Integer integer = each.get(name);
      if (integer != null) {
        return integer;
      }
    }
    return null;
  }

  private String getFeatureName(Expression expression, String defaultValue) {
    // TODO refactor AST. This is not a really straightforward!
    String result = defaultValue;
    List<?> childs = expression.getChilds();
    if (childs != null && !childs.isEmpty()) {
      Object object = childs.get(0);
      if (object instanceof ASTListNode) {
        List<?> childs2 = ((ASTListNode) object).getChilds();
        if (childs2 != null && !childs2.isEmpty()) {
          Object object2 = childs2.get(0);
          if (object2 instanceof StringLiteral) {
            StringLiteral sl = (StringLiteral) object2;
            result = sl.getValue().replaceAll("\"", "");
          }
        }
      }
    }
    return result;
  }

  private void initializePredefinedInformation() {

    typeDescriptionMap = new HashMap<String, TypeDescription>();
    featureDescriptionMap = new HashMap<String, Set<FeatureDescription>>();

    try {
      typeSystemDescription = getTypeSystemOfScript();
      IProject project = sourceModule.getScriptProject().getProject();
      List<IFolder> descriptorFolders = RutaProjectUtils.getDescriptorFolders(project);
      boolean exists = false;
      for (IFolder iFolder : descriptorFolders) {
        IPath basicTSD = iFolder.getLocation().append("BasicTypeSystem.xml");
        exists = basicTSD.toFile().exists();
        if (exists) {
          importCompleteTypeSystem(basicTSD, null);
          break;
        }
      }
      if (!exists) {
        // not in a common ruta project
        // try to find the file in the classpath
        URL resource = classLoader.getResource("org/apache/uima/ruta/engine/BasicTypeSystem.xml");
        importCompleteTypeSystem(null, resource);
      }
    } catch (Exception e) {
      RutaIdeUIPlugin.error(e);
    }
    if (typeSystemDescription != null) {
      TypeDescription[] descriptions = typeSystemDescription.getTypes();
      for (TypeDescription typeDescription : descriptions) {
        String typeName = typeDescription.getName();
        typeDescriptionMap.put(typeName, typeDescription);
      }

      for (TypeDescription typeDescription : descriptions) {
        Set<FeatureDescription> allFeatures = getAllDeclaredFeatures(typeDescription,
                typeDescriptionMap);
        featureDescriptionMap.put(typeDescription.getName(), allFeatures);
      }
    }

    List<String> uimaPredefTypes = Arrays.asList(new String[] { "uima.cas.Boolean", "uima.cas.Byte",
        "uima.cas.Short", "uima.cas.Integer", "uima.cas.Long", "uima.cas.Float", "uima.cas.Double",
        "uima.cas.String", "uima.cas.BooleanArray", "uima.cas.ByteArray", "uima.cas.ShortArray",
        "uima.cas.IntegerArray", "uima.cas.LongArray", "uima.cas.FloatArray",
        "uima.cas.DoubleArray", "uima.cas.StringArray", "uima.cas.FSArray",
        "uima.cas.AnnotationBase", "uima.tcas.Annotation", "uima.tcas.DocumentAnnotation",
        "uima.cas.FloatList", "uima.cas.IntegerList", "uima.cas.StringList", "uima.cas.FSList",
        "uima.cas.EmptyFloatList", "uima.cas.EmptyIntegerList", "uima.cas.EmptyStringList",
        "uima.cas.EmptyFSList", "uima.cas.NonEmptyFloatList", "uima.cas.NonEmptyIntegerList",
        "uima.cas.NonEmptyStringList", "uima.cas.NonEmptyFSList" });
    for (String longName : uimaPredefTypes) {
      String shortName = getShortName(longName);
      importType(longName, shortName);
    }

    this.finalTypes = new HashSet<String>();
    Set<String> uimaFinalTypes = new HashSet<String>();
    uimaFinalTypes.addAll(Arrays.asList(new String[] { "uima.cas.Boolean", "uima.cas.Byte",
        "uima.cas.Short", "uima.cas.Integer", "uima.cas.Long", "uima.cas.Float", "uima.cas.Double",
        "uima.cas.BooleanArray", "uima.cas.ByteArray", "uima.cas.ShortArray",
        "uima.cas.IntegerArray", "uima.cas.LongArray", "uima.cas.FloatArray",
        "uima.cas.DoubleArray", "uima.cas.StringArray", "uima.cas.FSArray" }));

    for (String string : uimaFinalTypes) {
      int indexOf = string.lastIndexOf('.');
      finalTypes.add(string);
      finalTypes.add(string.substring(indexOf + 1, string.length()));
    }
  }

  private TypeSystemDescription importCompleteTypeSystem(IPath path, URL url)
          throws InvalidXMLException, MalformedURLException, IOException, CoreException {
    return importTypeSystem(path, url, null, null, null);
  }

  private void initializeExtensionInformation() {
    conditionExtensions = new HashMap<String, IIDEConditionExtension>();
    actionExtensions = new HashMap<String, IIDEActionExtension>();
    numberFunctionExtensions = new HashMap<String, IIDENumberFunctionExtension>();
    booleanFunctionExtensions = new HashMap<String, IIDEBooleanFunctionExtension>();
    stringFunctionExtensions = new HashMap<String, IIDEStringFunctionExtension>();
    typeFunctionExtensions = new HashMap<String, IIDETypeFunctionExtension>();
    blockExtensions = new HashMap<String, IIDEBlockExtension>();
    IIDEConditionExtension[] cextensions = RutaExtensionManager.getDefault()
            .getIDEConditionExtensions();
    for (IIDEConditionExtension each : cextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        conditionExtensions.put(string, each);
      }
    }
    IIDEActionExtension[] aextensions = RutaExtensionManager.getDefault().getIDEActionExtensions();
    for (IIDEActionExtension each : aextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        actionExtensions.put(string, each);
      }
    }
    IIDENumberFunctionExtension[] nfextensions = RutaExtensionManager.getDefault()
            .getIDENumberFunctionExtensions();
    for (IIDENumberFunctionExtension each : nfextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        numberFunctionExtensions.put(string, each);
      }
    }
    IIDEBooleanFunctionExtension[] bfextensions = RutaExtensionManager.getDefault()
            .getIDEBooleanFunctionExtensions();
    for (IIDEBooleanFunctionExtension each : bfextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        booleanFunctionExtensions.put(string, each);
      }
    }
    IIDEStringFunctionExtension[] sfextensions = RutaExtensionManager.getDefault()
            .getIDEStringFunctionExtensions();
    for (IIDEStringFunctionExtension each : sfextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        stringFunctionExtensions.put(string, each);
      }
    }
    IIDETypeFunctionExtension[] tfextensions = RutaExtensionManager.getDefault()
            .getIDETypeFunctionExtensions();
    for (IIDETypeFunctionExtension each : tfextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        typeFunctionExtensions.put(string, each);
      }
    }
    IIDEBlockExtension[] bextensions = RutaExtensionManager.getDefault().getIDEBlockExtensions();
    for (IIDEBlockExtension each : bextensions) {
      String[] knownExtensions = each.getKnownExtensions();
      for (String string : knownExtensions) {
        blockExtensions.put(string, each);
      }
    }

  }

  private Set<FeatureDescription> getAllDeclaredFeatures(TypeDescription typeDescription,
          Map<String, TypeDescription> typeMap) {
    Set<FeatureDescription> result = new HashSet<FeatureDescription>();
    if (typeDescription == null) {
      return result;
    }
    FeatureDescription[] features = typeDescription.getFeatures();
    if (features == null) {
      return result;
    }
    result.addAll(Arrays.asList(features));
    String supertypeName = typeDescription.getSupertypeName();
    if (supertypeName != null) {
      TypeDescription parent = typeMap.get(supertypeName);
      result.addAll(getAllDeclaredFeatures(parent, typeMap));
    }
    return result;
  }

  private String isFeatureMatch(String text) {
    for (String each : namespaces.values()) {
      String t = checkFeatureMatch(text, each);
      if (t != null) {
        return t;
      }
    }
    for (String each : namespaces.keySet()) {
      String t = checkFeatureMatch(text, each);
      if (t != null) {
        return t;
      }
    }
    return null;
  }

  private String checkFeatureMatch(String name, String type) {
    if (name.startsWith(type)) {
      boolean foundAll = true;
      if (name.length() > type.length()) {
        String tail = name.substring(type.length() + 1);
        String[] split = tail.split("[.]");
        String typeToCheck = type;
        for (String feat : split) {
          typeToCheck = expand(typeToCheck);
          typeToCheck = checkFSFeatureOfType(feat, typeToCheck);
          if (StringUtils.contains(typeToCheck, CAS.TYPE_NAME_FS_ARRAY)) {
            // stop here because we do not know the type
            return CAS.TYPE_NAME_FS_ARRAY;
          }
          foundAll &= (typeToCheck != null);
          if (!foundAll) {
            return null;
          }
        }
        return typeToCheck;
      } else {
        return type;
      }
    } else {
      return null;
    }
  }

  private String checkFSFeatureOfType(String featureName, String longTypeName) {
    TypeDescription t = typeDescriptionMap.get(longTypeName);
    if (t == null) {
      return null;
    }
    FeatureDescription[] features = t.getFeatures();
    for (FeatureDescription featureDescription : features) {
      String name = featureDescription.getName();
      String rangeTypeName = featureDescription.getRangeTypeName();
      boolean isFS = isFeatureStructure(rangeTypeName);
      if (name.equals(featureName)) {
        if (isFS) {
          return rangeTypeName;
        } else if (StringUtils.equals(CAS.TYPE_NAME_FS_ARRAY, rangeTypeName)) {
          String elementType = featureDescription.getElementType();
          if (elementType == null) {
            return CAS.TYPE_NAME_FS_ARRAY;
          } else {
            return elementType;
          }
        }
      }
    }
    return null;
  }

  private boolean isFeatureStructure(String rangeTypeName) {
    if (rangeTypeName.equals("uima.tcas.Annotation") || rangeTypeName.equals("uima.cas.TOP")) {
      return true;
    }
    TypeDescription type = typeDescriptionMap.get(rangeTypeName);
    if (type == null) {
      return false;
    }
    String supertypeName = type.getSupertypeName();
    if (supertypeName != null) {
      return isFeatureStructure(supertypeName);
    }
    return false;
  }

  private boolean checkTypeOfVariable(RutaVariableReference ref) {
    Integer vt = getVariableType(ref.getName());
    if (vt == null) {
      IProblem problem = problemFactory.createUnknownVariableProblem(ref);
      pr.reportProblem(problem);
      return false;
    } else {
      int variableType = vt.intValue();
      int requiredType = ref.getType();
      // reject generic types
      if ((requiredType & RutaTypeConstants.RUTA_TYPE_G) != 0) {
        return true;
      }
      if ((variableType & requiredType) == 0) {
        String errMsg = "Variable \"" + ref.getName() + "\" has type "
                + RutaTypeConstants.typeStringOfInt.get(variableType) + ". But type "
                + RutaTypeConstants.typeStringOfInt.get(requiredType) + " is required.";
        IProblem problem = new RutaCheckerDefaultProblem(sourceModule.getElementName(), errMsg, ref,
                linetracker.getLineNumberOfOffset(ref.sourceStart()));
        pr.reportProblem(problem);
        return false;
      }
    }
    return true;
  }

  private boolean isVariableDeclared(RutaVariableReference ref) {
    if (!knowsVariable(ref.getName()) && !(ref instanceof NullExpression)) {
      // declared as type?
      if (namespaces.keySet().contains(ref.getName())) {
        String errMsg = "\"" + ref.getName() + "\" declared as a Type. Variable of type "
                + RutaTypeConstants.typeStringOfInt.get(ref.getType()) + " required.";
        IProblem problem = new RutaCheckerDefaultProblem(sourceModule.getElementName(), errMsg, ref,
                linetracker.getLineNumberOfOffset(ref.sourceStart()));
        pr.reportProblem(problem);
        return false;
      }
      String errMsgHead = "Variable \"";
      String errMsgTailDefault = " defined in this script or block!";

      // not found
      String errMsg = errMsgHead + ref.getName() + "\" not" + errMsgTailDefault;
      IProblem problem = new RutaCheckerDefaultProblem(sourceModule.getElementName(), errMsg, ref,
              linetracker.getLineNumberOfOffset(ref.sourceStart()));
      pr.reportProblem(problem);
      return false;
    }
    return true;
  }

  private String getShortName(String typeName) {
    String[] nameSpace = typeName.split("[.]");
    return nameSpace[nameSpace.length - 1];
  }

  private TypeSystemDescription getTypeSystemOfScript()
          throws InvalidXMLException, IOException, CoreException {
    IPath descriptorPath = RutaProjectUtils.getTypeSystemDescriptorPath(
            sourceModule.getResource().getLocation(), sourceModule.getScriptProject().getProject(),
            classLoader);
    if (descriptorPath == null) {
      return null;
    }

    TypeSystemDescription typeSysDescr = null;
    if (descriptorPath.toFile().exists()) {
      typeSysDescr = UIMAFramework.getXMLParser()
              .parseTypeSystemDescription(new XMLInputSource(descriptorPath.toPortableString()));
      ResourceManager resMgr = getResourceManager(classLoader);
      typeSysDescr.resolveImports(resMgr);
    } else {
      // backup: just search for the file named correctly
      String lastSegment = descriptorPath.lastSegment();
      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
              classLoader);
      String prefix = "classpath*:**/";
      String pattern = prefix + lastSegment;
      Resource[] resources = resolver.getResources(pattern);
      if (resources != null && resources.length != 0) {
        typeSysDescr = UIMAFramework.getXMLParser()
                .parseTypeSystemDescription(new XMLInputSource(resources[0].getURL()));
        ResourceManager resMgr = getResourceManager(classLoader);
        typeSysDescr.resolveImports(resMgr);
      }
    }
    return typeSysDescr;
  }

  private String translate(String name) {
    if (name == null) {
      return null;
    }
    if (name.equals("Annotation")) {
      return "uima.tcas.Annotation";
    } else if (name.equals("STRING")) {
      return CAS.TYPE_NAME_STRING;
    } else if (name.equals("INT")) {
      return CAS.TYPE_NAME_INTEGER;
    } else if (name.equals("DOUBLE")) {
      return CAS.TYPE_NAME_DOUBLE;
    } else if (name.equals("FLOAT")) {
      return CAS.TYPE_NAME_FLOAT;
    } else if (name.equals("BOOLEAN")) {
      return CAS.TYPE_NAME_BOOLEAN;
    } else if (name.equals("TYPE")) {
      return CAS.TYPE_NAME_STRING;
    }
    return name;
  }

  private int getType(String name) {
    if (name == null) {
      return 0;
    }
    // TODO reuse field in constants
    if (name.equals("STRING")) {
      return RutaTypeConstants.RUTA_TYPE_S;
    } else if (name.equals("STRINGLIST")) {
      return RutaTypeConstants.RUTA_TYPE_SL;
    } else if (name.equals("INT")) {
      return RutaTypeConstants.RUTA_TYPE_I;
    } else if (name.equals("INTLIST")) {
      return RutaTypeConstants.RUTA_TYPE_NL;
    } else if (name.equals("DOUBLE")) {
      return RutaTypeConstants.RUTA_TYPE_D;
    } else if (name.equals("DOUBLELIST")) {
      return RutaTypeConstants.RUTA_TYPE_NL;
    } else if (name.equals("FLOAT")) {
      return RutaTypeConstants.RUTA_TYPE_F;
    } else if (name.equals("FLOATLIST")) {
      return RutaTypeConstants.RUTA_TYPE_NL;
    } else if (name.equals("BOOLEAN")) {
      return RutaTypeConstants.RUTA_TYPE_B;
    } else if (name.equals("BOOLEANLIST")) {
      return RutaTypeConstants.RUTA_TYPE_BL;
    } else if (name.equals("TYPE")) {
      return RutaTypeConstants.RUTA_TYPE_AT;
    } else if (name.equals("TYPELIST")) {
      return RutaTypeConstants.RUTA_TYPE_TL;
    } else if (name.equals("ANNOTATION")) {
      return RutaTypeConstants.RUTA_TYPE_UA;
    } else if (name.equals("ANNOTATIONLIST")) {
      return RutaTypeConstants.RUTA_TYPE_UAL;
    }
    return 0;
  }

}
