private static EModelElementRef findReferencedMetamodelElement(
      CSTNode syntaxElement, IRegion region) {
    Object astObj = syntaxElement.getAst();

    if (astObj instanceof EClassifier) {
      if (syntaxElement instanceof SimpleNameCS) {
        if (astObj instanceof EModelElement) {
          return new EModelElementRef(
              (EModelElement) astObj, HyperlinkUtil.createRegion(syntaxElement));
        }
      } else if (syntaxElement instanceof PathNameCS && !isConstructorCS(syntaxElement)) {
        if (astObj instanceof ENamedElement) {
          PathNameCS pathNameCS = (PathNameCS) syntaxElement;

          int[] selectedNamePos = new int[1];
          // IRegion resultRegion = refineRegion(pathNameCS, region, selectedNamePos);
          IRegion resultRegion = getPathRegion(pathNameCS, region, selectedNamePos);
          if (resultRegion != null) {
            ENamedElement ast = (ENamedElement) pathNameCS.getAst();
            int pos = selectedNamePos[0];
            final EList<SimpleNameCS> csNames = pathNameCS.getSimpleNames();

            if (pos >= 0 && pos < csNames.size() - 1) {
              QvtOperationalEnv env = getEnv(pathNameCS);

              List<SimpleNameCS> selectedNames = csNames.subList(0, pos + 1);
              List<String> stringNames = new ArrayList<String>(selectedNames.size());
              for (SimpleNameCS nameCS : selectedNames) {
                stringNames.add(nameCS.getValue());
              }

              ast = env.lookupClassifier(stringNames);
              if (ast == null) {
                ast = env.lookupPackage(stringNames);
              }
            }

            if (ast != null) {
              return new EModelElementRef(ast, resultRegion);
            }
          }
        }
      }
    } else if (astObj instanceof EEnumLiteral) {
      return new EModelElementRef((EEnumLiteral) astObj, HyperlinkUtil.createRegion(syntaxElement));
    }

    return null;
  }