/**
   * Attempts to render the requested gadget.
   *
   * @return The results of the rendering attempt.
   *     <p>TODO: Localize error messages.
   */
  public RenderingResults render(GadgetContext context) {
    if (!validateParent(context)) {
      return RenderingResults.error("Unsupported parent parameter. Check your container code.");
    }

    try {
      Gadget gadget = processor.process(context);

      if (gadget.getCurrentView() == null) {
        return RenderingResults.error(
            "Unable to locate an appropriate view in this gadget. "
                + "Requested: '"
                + gadget.getContext().getView()
                + "' Available: "
                + gadget.getSpec().getViews().keySet());
      }

      if (gadget.getCurrentView().getType() == View.ContentType.URL) {
        return RenderingResults.mustRedirect(gadget.getCurrentView().getHref());
      }

      if (!lockedDomainService.gadgetCanRender(context.getHost(), gadget, context.getContainer())) {
        return RenderingResults.error("Invalid domain");
      }

      return RenderingResults.ok(renderer.render(gadget));
    } catch (RenderingException e) {
      return logError(context.getUrl(), e);
    } catch (ProcessingException e) {
      return logError(context.getUrl(), e);
    } catch (RuntimeException e) {
      if (e.getCause() instanceof GadgetException) {
        return logError(context.getUrl(), e.getCause());
      }
      throw e;
    }
  }
 private RenderingResults logError(Uri gadgetUrl, Throwable t) {
   LOG.info("Failed to render gadget " + gadgetUrl + ": " + t.getMessage());
   return RenderingResults.error(t.getMessage());
 }