private static void scanFile(File file, TreeMap<String, String> strings) throws IOException {
        Document doc = Jsoup.parse(file, "UTF-8");

        // First, scan for elements with the 'apiman-i18n-key' attribute.  These require translating.
        Elements elements = doc.select("*[apiman-i18n-key]");
        for (Element element : elements) {
            String i18nKey = element.attr("apiman-i18n-key");
            boolean isNecessary = false;

            // Process the element text (if the element has no children)
            if (strings.containsKey(i18nKey)) {
                if (hasNoChildren(element)) {
                    isNecessary = true;
                    String elementVal = element.text();
                    if (elementVal.trim().length() > 0 && !elementVal.contains("{{")) {
                        String currentValue = strings.get(i18nKey);
                        if (!currentValue.equals(elementVal)) {
                            throw new IOException("Duplicate i18n key found with different default values.  Key=" + i18nKey + "  Value1=" + elementVal + "  Value2=" + currentValue);
                        }
                    }
                }
            } else {
                if (hasNoChildren(element)) {
                    String elementVal = element.text();
                    if (elementVal.trim().length() > 0 && !elementVal.contains("{{")) {
                        isNecessary = true;
                        strings.put(i18nKey, elementVal);
                    }
                }
            }

            // Process the translatable attributes
            for (String tattr : TRANSLATABLE_ATTRIBUTES) {
                if (element.hasAttr(tattr)) {
                    String attrValue = element.attr(tattr);
                    if (attrValue.contains("{{")) {
                        continue;
                    }
                    String attrI18nKey = i18nKey + '.' + tattr;
                    String currentAttrValue = strings.get(attrI18nKey);
                    if (currentAttrValue == null) {
                        isNecessary = true;
                        strings.put(attrI18nKey, attrValue);
                    } else if (!currentAttrValue.equals(attrValue)) {
                        throw new IOException(
                                "Duplicate i18n key found with different default values (for attribute '"
                                        + tattr + "').  Key=" + attrI18nKey + "  Value1=" + attrValue
                                        + "  Value2=" + currentAttrValue);
                    } else {
                        isNecessary = true;
                    }
                }
            }

            if (!isNecessary) {
                throw new IOException("Detected an unnecessary apiman-i18n-key attribute in file '"
                        + file.getName() + "' on element: " + element);
            }
        }

        // Next, scan all elements to see if the element *should* be marked for translation
        elements = doc.select("*");
        for (Element element : elements) {
            if (element.hasAttr("apiman-i18n-key") || element.hasAttr("apiman-i18n-skip")) {
                continue;
            }
            if (hasNoChildren(element)) {
                String value = element.text();
                if (value != null && value.trim().length() > 0) {
                    if (!value.contains("{{")) {
                        throw new IOException("Found an element in '" + file.getName() + "' that should be translated:  " + element);
                    }
                }
            }
        }

        // Next scan elements with a translatable attribute and fail if any of those elements
        // are missing the apiman-i18n-key attribute.
        for (String tattr : TRANSLATABLE_ATTRIBUTES) {
            elements = doc.select("*[" + tattr + "]");
            for (Element element : elements) {
                if (element.hasAttr("apiman-i18n-key") || element.hasAttr("apiman-i18n-skip") || element.attr(tattr).contains("{{")) {
                    continue;
                } else {
                    throw new IOException("In template '" + file.getName() + "', found an element with a '"
                            + tattr + "' attribute but missing 'apiman-i18n-key': " + element);
                }
            }
        }

    }
Scan the given html template using jsoup and find all strings that require translation.  This is
done by finding all elements with a "apiman-i18n-key" attribute.
@param file
@param strings
@throws IOException
tools/i18n/src/main/java/io/apiman/tools/i18n/TemplateScanner.java