public static Map<String, PsiElement> getTemplateAnnotationFiles(PhpDocTag phpDocTag) {

    // find template name on annotation parameter
    // @Template("templatename")
    PhpPsiElement phpDocAttrList = phpDocTag.getFirstPsiChild();
    if (phpDocAttrList == null) {
      return null;
    }

    String tagValue = phpDocAttrList.getText();
    Matcher matcher = Pattern.compile("\\(\"(.*)\"").matcher(tagValue);

    Map<String, PsiElement> templateFiles = new HashMap<String, PsiElement>();

    if (matcher.find()) {
      // @TODO: only one should possible; refactor getTemplatePsiElements
      PsiElement[] psiElement =
          TwigHelper.getTemplatePsiElements(phpDocTag.getProject(), matcher.group(1));
      if (psiElement.length > 0) {
        templateFiles.put(matcher.group(1), psiElement[0]);
      }
    }

    return templateFiles;
  }
  public ArrayList<TwigBlock> walk(
      @Nullable PsiFile file, String shortcutName, ArrayList<TwigBlock> current, int depth) {

    if (file == null) {
      return current;
    }

    // @TODO: we dont use psielements here, check if Pattern faster or not

    // dont match on self file !?
    if (depth > 0) {
      Matcher matcherBlocks =
          Pattern.compile("\\{%[\\s+]*block[\\s+]*(.*?)[\\s+]*%}").matcher(file.getText());
      while (matcherBlocks.find()) {
        current.add(new TwigBlock(matcherBlocks.group(1), shortcutName, file));
      }
    }

    // limit recursive calls
    if (depth++ > 20) {
      return current;
    }

    // find extend in self
    Matcher matcher = Pattern.compile(EXTENDS_TEMPLATE_NAME_PATTERN).matcher(file.getText());
    while (matcher.find()) {
      if (twigFilesByName.containsKey(TwigHelper.normalizeTemplateName(matcher.group(1)))) {
        TwigFile twigFile = twigFilesByName.get(matcher.group(1));
        this.walk(twigFile, matcher.group(1), current, depth);
      }
    }

    return current;
  }
  public static ArrayList<TwigMacro> getImportedMacrosNamespaces(PsiFile psiFile) {

    ArrayList<TwigMacro> macros = new ArrayList<TwigMacro>();

    String str = psiFile.getText();

    // {% import '@foo/bar.html.twig' as macro1 %}
    String regex = "\\{%\\s?import\\s?['\"](.*?)['\"]\\s?as\\s?(.*?)\\s?%}";
    Matcher matcher = Pattern.compile(regex).matcher(str.replace("\n", " "));

    Map<String, TwigFile> twigFilesByName = TwigHelper.getTwigFilesByName(psiFile.getProject());
    while (matcher.find()) {

      String templateName = matcher.group(1);
      String asName = matcher.group(2);

      if (twigFilesByName.containsKey(templateName)) {
        for (Map.Entry<String, String> entry :
            new TwigMarcoParser().getMacros(twigFilesByName.get(templateName)).entrySet()) {
          macros.add(new TwigMacro(asName + '.' + entry.getKey(), templateName));
        }
      }
    }

    return macros;
  }
 protected List<PsiFile> templateGoto(PsiElement psiElement, String templateName) {
   return Arrays.asList(TwigHelper.getTemplatePsiElements(psiElement.getProject(), templateName));
 }