public static com.liferay.opensocial.model.Gadget getGadget(PortletPreferences portletPreferences)
      throws Exception {

    String url = portletPreferences.getValue("url", StringPool.BLANK);

    if (Validator.isNull(url)) {
      return null;
    }

    com.liferay.opensocial.model.Gadget gadget = new GadgetImpl();

    GadgetSpec gadgetSpec = null;

    try {
      gadgetSpec = ShindigUtil.getGadgetSpec(url);
    } catch (Exception e) {
      throw new GadgetURLException(e);
    }

    ModulePrefs modulePrefs = gadgetSpec.getModulePrefs();

    gadget.setName(modulePrefs.getTitle());
    gadget.setUrl(url);

    return gadget;
  }
  public static Map<String, OAuthService> getOAuthServices(String url) throws Exception {

    GadgetSpec gadgetSpec = getGadgetSpec(url);

    ModulePrefs modulePrefs = gadgetSpec.getModulePrefs();

    if (modulePrefs == null) {
      return null;
    }

    OAuthSpec oAuthSpec = modulePrefs.getOAuthSpec();

    if (oAuthSpec == null) {
      return null;
    }

    return oAuthSpec.getServices();
  }
  private Iterable<String> getUnsupportedFeatureNames(ModulePrefs prefs) {
    Collection<String> unsupportedFeatures = new LinkedList<String>();

    // first, get the required (not optional) features only
    Collection<String> requiredFeatures = new LinkedList<String>();
    Map<String, org.apache.shindig.gadgets.spec.Feature> shindigFeatures = prefs.getFeatures();
    for (Map.Entry<String, org.apache.shindig.gadgets.spec.Feature> shindigFeature :
        shindigFeatures.entrySet()) {
      if (shindigFeature.getValue().getRequired()) {
        requiredFeatures.add(shindigFeature.getKey());
      }
    }

    gadgetFeatureRegistry.getFeatures(requiredFeatures, unsupportedFeatures);
    return unmodifiableCollection(unsupportedFeatures);
  }
  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);
    }
  }