private IHyperlink openModule(Node current, ITextViewer textViewer, int offset) {
    while (current != null && !(current instanceof Element)) {
      current = current.getParentNode();
    }
    if (current == null) {
      return null;
    }
    String pathUp = XmlUtils.pathUp(current, 2);
    if (!"modules/module".equals(pathUp)) { // $NON-NLS-1$
      // just in case we are in some random plugin configuration snippet..
      return null;
    }

    ITextFileBuffer buf =
        FileBuffers.getTextFileBufferManager().getTextFileBuffer(textViewer.getDocument());
    if (buf == null) {
      // for repository based poms..
      return null;
    }
    IFileStore folder = buf.getFileStore().getParent();

    String path = XmlUtils.getTextValue(current);
    final String fPath = path;
    // construct IPath for the child pom file, handle relative paths..
    while (folder != null && path.startsWith("../")) { // $NON-NLS-1$
      folder = folder.getParent();
      path = path.substring("../".length()); // $NON-NLS-1$
    }
    if (folder == null) {
      return null;
    }
    IFileStore modulePom = folder.getChild(path);
    if (!modulePom.getName().endsWith("xml")) { // $NON-NLS-1$
      modulePom = modulePom.getChild("pom.xml"); // $NON-NLS-1$
    }
    final IFileStore fileStore = modulePom;
    if (!fileStore.fetchInfo().exists()) {
      return null;
    }
    assert current instanceof IndexedRegion;
    final IndexedRegion region = (IndexedRegion) current;

    return new IHyperlink() {
      public IRegion getHyperlinkRegion() {
        return new Region(region.getStartOffset(), region.getEndOffset() - region.getStartOffset());
      }

      public String getHyperlinkText() {
        return NLS.bind(Messages.PomHyperlinkDetector_open_module, fPath);
      }

      public String getTypeLabel() {
        return "pom-module"; //$NON-NLS-1$
      }

      public void open() {
        openXmlEditor(fileStore);
      }
    };
  }
  static ManagedArtifactRegion findManagedArtifactRegion(
      Node current, ITextViewer textViewer, int offset) {
    while (current != null && !(current instanceof Element)) {
      current = current.getParentNode();
    }
    if (current != null) {
      Node artNode = null;
      Node groupNode = null;
      if (ARTIFACT_ID.equals(current.getNodeName())) { // $NON-NLS-1$
        artNode = current;
      }
      if (GROUP_ID.equals(current.getNodeName())) { // $NON-NLS-1$
        groupNode = current;
      }
      // only on artifactid and groupid elements..
      if (artNode == null && groupNode == null) {
        return null;
      }
      Node root = current.getParentNode();
      boolean isDependency = false;
      boolean isPlugin = false;
      if (root != null) {
        String name = root.getNodeName();
        if (DEPENDENCY.equals(name)) { // $NON-NLS-1$
          isDependency = true;
        }
        if (PLUGIN.equals(name)) { // $NON-NLS-1$
          isPlugin = true;
        }
      } else {
        return null;
      }
      if (!isDependency && !isPlugin) {
        // some kind of other identifier
        return null;
      }
      // now see if version is missing
      NodeList childs = root.getChildNodes();
      for (int i = 0; i < childs.getLength(); i++) {
        Node child = childs.item(i);
        if (child instanceof Element) {
          Element el = (Element) child;
          if (VERSION.equals(el.getNodeName())) { // $NON-NLS-1$
            return null;
          }
          if (artNode == null && ARTIFACT_ID.equals(el.getNodeName())) { // $NON-NLS-1$
            artNode = el;
          }
          if (groupNode == null && GROUP_ID.equals(el.getNodeName())) { // $NON-NLS-1$
            groupNode = el;
          }
        }
      }
      if (groupNode != null && artNode != null) {
        assert groupNode instanceof IndexedRegion;
        assert artNode instanceof IndexedRegion;

        IndexedRegion groupReg = (IndexedRegion) groupNode;
        IndexedRegion artReg = (IndexedRegion) artNode;
        int startOffset = Math.min(groupReg.getStartOffset(), artReg.getStartOffset());
        int length = Math.max(groupReg.getEndOffset(), artReg.getEndOffset()) - startOffset;
        String groupId = XmlUtils.getTextValue(groupNode);
        String artifactId = XmlUtils.getTextValue(artNode);
        final MavenProject prj = XmlUtils.extractMavenProject(textViewer);
        if (prj != null) {
          // now we can create the region I guess,
          return new ManagedArtifactRegion(
              startOffset, length, groupId, artifactId, isDependency, isPlugin, prj);
        }
      }
    }
    return null;
  }