/**
   * Validates that the parent parameter was acceptable.
   *
   * @return True if the parent parameter is valid for the current container.
   */
  private boolean validateParent(GadgetContext context) {
    String container = context.getContainer();
    String parent = context.getParameter("parent");

    if (parent == null) {
      // If there is no parent parameter, we are still safe because no
      // dependent code ever has to trust it anyway.
      return true;
    }

    List<Object> parents = containerConfig.getList(container, "gadgets.parent");
    if (parents.isEmpty()) {
      // Allow all.
      return true;
    }

    // We need to check each possible parent parameter against this regex.
    for (Object pattern : parents) {
      if (Pattern.matches(pattern.toString(), parent)) {
        return true;
      }
    }

    return false;
  }
  /**
   * 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;
    }
  }