@SuppressWarnings({"unchecked", "rawtypes"})
  public static void replaceTranslatedStrings(
      final ContentSpec contentSpec, final Map<String, String> translations) {
    if (contentSpec == null || translations == null || translations.size() == 0) return;

    /*
     * Get the translation strings and the nodes that the string maps to. We
     * assume that the text being provided here is an exact match for the
     * text that was supplied to getTranslatableStrings originally, which we
     * then assume matches the strings supplied as the keys in the
     * translations parameter.
     */
    final List<StringToCSNodeCollection> stringToNodeCollections =
        getTranslatableStrings(contentSpec, false);

    if (stringToNodeCollections == null || stringToNodeCollections.size() == 0) return;

    for (final StringToCSNodeCollection stringToNodeCollection : stringToNodeCollections) {
      final String originalString = stringToNodeCollection.getTranslationString();
      final ArrayList<ArrayList<Node>> nodeCollections =
          stringToNodeCollection.getNodeCollections();

      if (nodeCollections != null && nodeCollections.size() != 0) {
        /* Zanata will change the format of the strings that it returns. Here we account for any trimming that was done. */
        final ZanataStringDetails fixedStringDetails =
            new ZanataStringDetails(translations, originalString);
        if (fixedStringDetails.getFixedString() != null) {
          if (translations.containsKey(fixedStringDetails.getFixedString())) {
            final String translation = translations.get(fixedStringDetails.getFixedString());

            /* Build up the padding that Zanata removed */
            final StringBuilder leftTrimPadding = new StringBuilder();
            final StringBuilder rightTrimPadding = new StringBuilder();

            for (int i = 0; i < fixedStringDetails.getLeftTrimCount(); ++i)
              leftTrimPadding.append(" ");

            for (int i = 0; i < fixedStringDetails.getRightTrimCount(); ++i)
              rightTrimPadding.append(" ");

            final String fixedTranslation =
                leftTrimPadding.toString() + translation + rightTrimPadding.toString();

            for (final ArrayList<Node> nodes : nodeCollections) {
              if (nodes != null && nodes.size() != 0) {
                for (final Node node : nodes) {
                  if (node instanceof Level) {
                    ((Level) node).setTitle(fixedTranslation);
                  } else if (node instanceof KeyValueNode) {
                    ((KeyValueNode) node).setValue(fixedTranslation);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  private static StringToCSNodeCollection findExistingText(
      final String text, final List<StringToCSNodeCollection> translationStrings) {
    for (final StringToCSNodeCollection stringToNodeCollection : translationStrings) {
      if (stringToNodeCollection.getTranslationString().equals(text)) return stringToNodeCollection;
    }

    return null;
  }
  private static void addTranslationToNodeDetailsToCollection(
      final String text,
      final ArrayList<Node> nodes,
      final boolean allowDuplicates,
      final List<StringToCSNodeCollection> translationStrings) {

    if (allowDuplicates) {
      translationStrings.add(new StringToCSNodeCollection(text).addNodeCollection(nodes));
    } else {
      final StringToCSNodeCollection stringToNodeCollection =
          findExistingText(text, translationStrings);

      if (stringToNodeCollection == null)
        translationStrings.add(new StringToCSNodeCollection(text).addNodeCollection(nodes));
      else stringToNodeCollection.addNodeCollection(nodes);
    }
  }