private GadgetSpec getGadgetSpec(
      final URI specUri,
      final Map<String, String> userPrefs,
      final GadgetRequestContext gadgetRequestContext)
      throws GadgetParsingException {
    final URI absoluteSpecUri =
        Uri.resolveUriAgainstBase(applicationProperties.getBaseUrl(), specUri);
    GadgetContext gadgetContext =
        new GadgetContext() {
          @Override
          public URI getUrl() {
            return absoluteSpecUri;
          }

          @Override
          public boolean getIgnoreCache() {
            return gadgetRequestContext.getIgnoreCache();
          }

          @Override
          public RenderingContext getRenderingContext() {
            return RenderingContext.CONTAINER;
          }

          @Override
          public UserPrefs getUserPrefs() {
            return new UserPrefs(userPrefs);
          }

          @Override
          public Locale getLocale() {
            if (gadgetRequestContext.getLocale() != null) {
              return gadgetRequestContext.getLocale();
            }
            return new Locale("");
          }

          @Override
          public boolean getDebug() {
            return gadgetRequestContext.isDebuggingEnabled();
          }
        };

    try {
      org.apache.shindig.gadgets.spec.GadgetSpec shindigGadgetSpec =
          substituter.substitute(gadgetContext, shindigFactory.getGadgetSpec(gadgetContext));
      ModulePrefs prefs = shindigGadgetSpec.getModulePrefs();

      return GadgetSpec.gadgetSpec(specUri)
          .userPrefs(transform(shindigGadgetSpec.getUserPrefs(), UserPrefToUserPrefSpec.FUNCTION))
          .viewsNames(shindigGadgetSpec.getViews().keySet())
          .scrolling(prefs.getScrolling())
          .height(prefs.getHeight())
          .width(prefs.getWidth())
          .title(prefs.getTitle())
          .titleUrl(nullSafeToJavaUri(prefs.getTitleUrl()))
          .thumbnail(nullSafeToJavaUri(prefs.getThumbnail()))
          .author(prefs.getAuthor())
          .authorEmail(prefs.getAuthorEmail())
          .description(prefs.getDescription())
          .directoryTitle(prefs.getDirectoryTitle())
          .features(
              unmodifiableMap(
                  transformValues(prefs.getFeatures(), ShindigFeatureToFeature.FUNCTION)))
          .unsupportedFeatureNames(getUnsupportedFeatureNames(prefs))
          .build();
    } catch (GadgetException e) {
      throw new GadgetParsingException(e);
    }
  }