/**
  * Finds the parent layout template that will surround the inner layout template. By default it
  * will look in the same directory as the inner template for a template called 'layout'.
  *
  * @param newViewName not null.
  * @param templateLoader not null.
  * @return null if not found.
  * @throws Exception
  */
 protected String findParentLayoutTemplate(String newViewName, TemplateLoader templateLoader)
     throws Exception {
   String parentTemplate = null;
   String[] paths = StringUtils.tokenizeToStringArray(newViewName, "/");
   if (paths == null) return null;
   List<String> ps = new ArrayList<String>();
   String cur = "";
   for (String p : paths) {
     if (hasText(p)) {
       cur = cur + "/" + p;
       ps.add(cur);
     }
   }
   reverse(ps);
   if (!ps.isEmpty()) {
     ps.remove(0);
     for (String p : ps) {
       try {
         String n = p + "/" + getLayoutTemplateName();
         templateLoader.getTemplate(n);
         parentTemplate = n;
         break;
       } catch (FileNotFoundException e1) {
         // Ignore as there is no layout template.
       }
     }
   }
   return parentTemplate;
 }
  @Override
  protected AbstractUrlBasedView buildView(String viewName) throws Exception {

    final MustacheView view = (MustacheView) super.buildView(viewName);

    URI uri = new URI(viewName);
    String newViewName = uri.getPath();
    Map<String, String> aliases = parseQueryString(uri.getQuery());
    view.setPartialAliases(aliases);

    /*
     * Normalize the path.
     */
    if (endsWithIgnoreCase(getPrefix(), "/") && startsWithIgnoreCase(newViewName, "/")) {
      newViewName = trimLeadingCharacter(newViewName, '/');
    }
    TemplateLoader templateLoader = this.templateLoader.withPartialAliases(aliases);
    Compiler compiler = this.compiler.withLoader(templateLoader);
    /*
     * Reset the view url
     */
    view.setUrl(getPrefix() + newViewName + getSuffix());

    aliases.put(getInnerPartialAlias(), newViewName);
    /*
     * Go find the parent layout template if one is not defined.
     * We walk up the tree to find the parent.
     */
    if (!hasText(aliases.get(getLayoutPartialAlias()))) {
      String parentTemplate = findParentLayoutTemplate(newViewName, templateLoader);
      if (hasText(parentTemplate)) aliases.put(getLayoutPartialAlias(), parentTemplate);
    }

    String templateName = null;

    boolean found =
        hasText(templateName = aliases.get(getLayoutPartialAlias()))
            || hasText(templateName = aliases.get(getInnerPartialAlias()));

    if (found) view.setTemplate(compiler.compile(templateLoader.getTemplate(templateName)));
    else throw new IllegalStateException("Body is missing");

    return view;
  }