private boolean setTemplate(final TemplateToken token, TemplateImpl template) {
   if (template == null) {
     template = myGenerator.createTemplateByKey(token.getKey());
   }
   if (template == null) {
     return false;
   }
   return doSetTemplate(token, template, myCallback);
 }
 public static boolean doSetTemplate(
     final TemplateToken token, TemplateImpl template, CustomTemplateCallback callback) {
   token.setTemplate(template);
   final XmlFile xmlFile = parseXmlFileInTemplate(template.getString(), callback, true);
   token.setFile(xmlFile);
   XmlDocument document = xmlFile.getDocument();
   final XmlTag tag = document != null ? document.getRootTag() : null;
   if (token.getAttribute2Value().size() > 0 && tag == null) {
     return false;
   }
   if (tag != null) {
     if (!containsAttrsVar(template) && token.getAttribute2Value().size() > 0) {
       ApplicationManager.getApplication()
           .runWriteAction(
               new Runnable() {
                 public void run() {
                   addMissingAttributes(tag, token.getAttribute2Value());
                 }
               });
     }
   }
   return true;
 }
  /**
   * Do you smell something? I'm smelling that this class needs to be redesigned to not need a
   * central method this large and hard to test. I think a lot of instance and local variables need
   * to be bundled up into some kind of process object. This code is effectively too big to be
   * tested except through integration testing.
   */
  private void loadTemplateForComponent(final ComponentPageElement loadingElement) {
    this.loadingElement = loadingElement;
    loadingComponentModel = loadingElement.getComponentResources().getComponentModel();

    String componentClassName = loadingComponentModel.getComponentClassName();
    ComponentTemplate template = templateSource.getTemplate(loadingComponentModel, locale);

    // When the template for a component is missing, we pretend it consists of just a RenderBody
    // phase. Missing is not an error ... many component simply do not have a template.

    if (template.isMissing()) {
      this.loadingElement.addToTemplate(new RenderBodyElement(this.loadingElement));
      return;
    }

    // Pre-allocate ids to avoid later name collisions.

    // Don't have a case-insensitive Set, so we'll make due with a Map
    Map<String, Boolean> embeddedIds = collectedEmbeddedComponentIds(loadingComponentModel);

    idAllocator.clear();

    final Map<String, Location> componentIdsMap = template.getComponentIds();

    for (String id : componentIdsMap.keySet()) {
      idAllocator.allocateId(id);
      embeddedIds.remove(id);
    }

    if (!embeddedIds.isEmpty())
      throw new RuntimeException(
          ServicesMessages.embeddedComponentsNotInTemplate(
              embeddedIds.keySet(), componentClassName, template.getResource()));

    addAttributesAsComponentBindings = false;

    // The outermost elements of the template belong in the loading component's template list,
    // not its body list. This shunt allows everyone else to not have to make that decision,
    // they can add to the "body" and (if there isn't an active component), the shunt will
    // add the element to the component's template.

    BodyPageElement shunt =
        new BodyPageElement() {
          public void addToBody(PageElement element) {
            loadingElement.addToTemplate(element);
          }
        };

    bodyPageElementStack.push(shunt);

    for (TemplateToken token : template.getTokens()) {
      switch (token.getTokenType()) {
        case TEXT:
          text((TextToken) token);
          break;

        case EXPANSION:
          expansion((ExpansionToken) token);
          break;

        case BODY:
          body();
          break;

        case START_ELEMENT:
          startElement((StartElementToken) token);
          break;

        case START_COMPONENT:
          startComponent((StartComponentToken) token);
          break;

        case ATTRIBUTE:
          attribute((AttributeToken) token);
          break;

        case END_ELEMENT:
          endElement();
          break;

        case COMMENT:
          comment((CommentToken) token);
          break;

        case BLOCK:
          block((BlockToken) token);
          break;

        case PARAMETER:
          parameter((ParameterToken) token);
          break;

        case DTD:
          dtd((DTDToken) token);
          break;

        case DEFINE_NAMESPACE_PREFIX:
          defineNamespacePrefix((DefineNamespacePrefixToken) token);
          break;

        case CDATA:
          cdata((CDATAToken) token);
          break;

        default:
          throw new IllegalStateException("Not implemented yet: " + token);
      }
    }

    // For neatness / symmetry:

    bodyPageElementStack.pop(); // the shunt

    // TODO: Check that all stacks are empty. That should never happen, as long
    // as the ComponentTemplate is valid.
  }