private void assertErrorContains(boolean squareTags, String ftl, String... expectedSubstrings) {
   try {
     if (squareTags) {
       ftl = ftl.replace('<', '[').replace('>', ']');
     }
     new Template("adhoc", ftl, cfg);
     fail("The tempalte had to fail");
   } catch (ParseException e) {
     String msg = e.getMessage();
     for (String needle : expectedSubstrings) {
       if (needle.startsWith("\\!")) {
         String netNeedle = needle.substring(2);
         if (msg.contains(netNeedle)) {
           fail(
               "The message shouldn't contain substring "
                   + StringUtil.jQuote(netNeedle)
                   + ":\n"
                   + msg);
         }
       } else if (!msg.contains(needle)) {
         fail("The message didn't contain substring " + StringUtil.jQuote(needle) + ":\n" + msg);
       }
     }
     showError(e);
   } catch (IOException e) {
     // Won't happen
     throw new RuntimeException(e);
   }
 }
 /**
  * Show class name and some details that are useful in template-not-found errors.
  *
  * @since 2.3.21
  */
 @Override
 public String toString() {
   return TemplateLoaderUtils.getClassNameForToString(this)
       + "(subdirPath="
       + StringUtil.jQuote(subdirPath)
       + ", servletContext={contextPath="
       + StringUtil.jQuote(getContextPath())
       + ", displayName="
       + StringUtil.jQuote(servletContext.getServletContextName())
       + "})";
 }
 public NestedContentNotSupportedException(String description, Exception cause, Environment env) {
   super(
       "Nested content (body) not supported."
           + (description == null ? " " + StringUtil.jQuote(description) : ""),
       cause,
       env);
 }