@SuppressWarnings({"rawtypes", "unchecked"})
  protected <M extends Map, F> M buildCompositeMap(
      Function<F, M> mapMaker,
      PreferenceValueFunction<M> preferenceValueFunction,
      Collection<? extends IStylesheetData> defaults,
      M... extraDataMaps) {
    final M compositeMap = mapMaker.apply(null);

    // Add data from the stylesheet descriptor
    for (final IStylesheetData defaultData : defaults) {
      final String defaultValue = defaultData.getDefaultValue();
      final String name = defaultData.getName();
      compositeMap.put(name, defaultValue);
    }

    // Add any pre-existing data to the composite map
    for (final M existingValue : extraDataMaps) {
      compositeMap.putAll(existingValue);
    }

    // Iterate through scopes adding data from each stylesheet user prefs objects
    for (final Scope scope : Scope.values()) {
      final IStylesheetUserPreferences stylesheetUserPreferences =
          this.getStylesheetUserPreferences(scope, false);
      if (stylesheetUserPreferences != null) {
        final Map preferences = preferenceValueFunction.getPreferences(stylesheetUserPreferences);
        compositeMap.putAll(preferences);
      }
    }

    return compositeMap;
  }
 /** The scope to use for the descriptor, handles persistentReadOnly logic */
 protected Scope getWriteScope(final IStylesheetData descriptor) {
   Scope scope = descriptor.getScope();
   if (this.persistentReadOnly && Scope.PERSISTENT == scope) {
     scope = Scope.SESSION;
   }
   return scope;
 }