@Override
  public String getHelp(Property property) {
    CssModule cssModule = property.getCssModule();
    if (cssModule == null) {
      return null;
    }
    String moduleDocBase = cssModule.getSpecificationURL();
    if (moduleDocBase == null) {
      return null;
    }

    if ("http://www.w3.org/TR/CSS2".equals(moduleDocBase)) { // NOI18N
      // css2 help is treated by the legacy help resolver
      return null;
    }

    if (moduleDocBase.startsWith(W3C_SPEC_URL_PREFIX)) {
      String moduleFolderName = moduleDocBase.substring(W3C_SPEC_URL_PREFIX.length());
      StringBuilder propertyUrl = new StringBuilder();
      propertyUrl.append(getSpecURL());
      propertyUrl.append(MODULE_ARCHIVE_PATH);
      propertyUrl.append(moduleFolderName);
      propertyUrl.append('/');
      propertyUrl.append(INDEX_HTML_FILE_NAME);
      propertyUrl.append('#');
      propertyUrl.append(property.getName());
      try {
        URL propertyHelpURL = new URL(propertyUrl.toString());
        String urlContent = URLRetriever.getURLContentAndCache(propertyHelpURL);

        assert urlContent != null : "null " + propertyHelpURL;

        // 1. find the anchor

        // there are some exceptions where the anchors are defined under different
        // ids than the property names
        String modifiedPropertyName = propertyNamesTranslationTable.get(property.getName());
        String propertyName =
            modifiedPropertyName != null ? modifiedPropertyName : property.getName();

        // following forms of anchors are supported:
        // <dfn id="property">
        // <dfn id="property0"> ... sometimes the property is referred with a number suffix

        String elementName = "ruby".equals(cssModule.getName()) ? "a" : "dfn";

        String patternImg =
            String.format("(?s)<%s\\s+id=['\"]?\\w*-??%s\\d?['\"]?>", elementName, propertyName);

        Pattern pattern = Pattern.compile(patternImg); // DOTALL mode
        Matcher matcher = pattern.matcher(urlContent);

        // 2. go backward and find h3 or h2 section start
        if (matcher.find()) {
          int sectionStart = -1;
          int from = matcher.start();

          int state = 0;
          loop:
          for (int i = from; i > 0; i--) {
            char c = urlContent.charAt(i);
            switch (state) {
              case 0:
                if (c == '2' || c == '3') {
                  state = 1;
                }
                break;
              case 1:
                if (c == 'h') {
                  state = 2;
                } else {
                  state = 0;
                }
                break;
              case 2:
                if (c == '<') {
                  // found <h2 or <h3
                  sectionStart = i;
                  break loop;
                } else {
                  state = 0;
                }
                break;
            }
          }

          // 3.go forward and find next section start (h2 or h3)
          // note: the section end can be limited by different heading
          // level than was the opening heading!
          if (sectionStart >= 0) {
            // find next section
            Pattern sectionEndFinder = Pattern.compile("(?s)<h[23]"); // NOI18N
            Matcher findSectionEnd =
                sectionEndFinder.matcher(urlContent.subSequence(from, urlContent.length()));
            if (findSectionEnd.find()) {
              return urlContent.substring(sectionStart, from + findSectionEnd.start());
            }
          }

        } else {
          // no pattern found, likely a bit different source
          LOGGER.warning(
              String.format(
                  "No property anchor section pattern found for property '%s'",
                  property.getName())); // NOI18N

          // strip the <style>...</style> section from the source since it causes a garbage in the
          // swingbrowser
          int styleSectionStart = urlContent.indexOf("<style type=\"text/css\">"); // NOI18N
          if (styleSectionStart >= 0) {
            final String styleEndTag = "</style>"; // NOI18N
            int styleSectionEnd = urlContent.indexOf(styleEndTag, styleSectionStart);
            if (styleSectionEnd >= 0) {
              StringBuilder buf = new StringBuilder();
              buf.append(urlContent.subSequence(0, styleSectionStart));
              buf.append(
                  urlContent.subSequence(
                      styleSectionEnd + styleEndTag.length(), urlContent.length()));

              return buf.toString();
            }
          }

          return urlContent;
        }
      } catch (MalformedURLException ex) {
        LOGGER.log(Level.WARNING, null, ex);
      }
    }

    return NO_HELP_MSG;
  }