final void setNestedBlock(TemplateElement nestedBlock) {
   if (nestedBlock != null) {
     nestedBlock.parent = this;
     nestedBlock.index = 0;
   }
   this.nestedBlock = nestedBlock;
 }
 /**
  * Walk the AST subtree rooted by this element, and do simplifications where possible, also remove
  * superfluous whitespace.
  *
  * @param stripWhitespace whether to remove superfluous whitespace
  * @return The element this element should be replaced with in the parent. If it's the same as
  *     this element, no actual replacement will happen. Note that adjusting the {@link #parent}
  *     and {@link #index} of the result is the duty of the caller, not of this method.
  */
 TemplateElement postParseCleanup(boolean stripWhitespace) throws ParseException {
   int regulatedChildCount = this.regulatedChildCount;
   if (regulatedChildCount != 0) {
     for (int i = 0; i < regulatedChildCount; i++) {
       TemplateElement te = regulatedChildBuffer[i];
       te = te.postParseCleanup(stripWhitespace);
       regulatedChildBuffer[i] = te;
       te.parent = this;
       te.index = i;
     }
     if (stripWhitespace) {
       for (int i = 0; i < regulatedChildCount; i++) {
         TemplateElement te = regulatedChildBuffer[i];
         if (te.isIgnorable()) {
           regulatedChildCount--;
           for (int j = i; j < regulatedChildCount; j++) {
             final TemplateElement te2 = regulatedChildBuffer[j + 1];
             regulatedChildBuffer[j] = te2;
             te2.index = j;
           }
           regulatedChildBuffer[regulatedChildCount] = null;
           this.regulatedChildCount = regulatedChildCount;
           i--;
         }
       }
     }
     if (regulatedChildCount < regulatedChildBuffer.length
         && regulatedChildCount <= regulatedChildBuffer.length * 3 / 4) {
       TemplateElement[] trimmedregulatedChildBuffer = new TemplateElement[regulatedChildCount];
       for (int i = 0; i < regulatedChildCount; i++) {
         trimmedregulatedChildBuffer[i] = regulatedChildBuffer[i];
       }
       regulatedChildBuffer = trimmedregulatedChildBuffer;
     }
   } else if (nestedBlock != null) {
     nestedBlock = nestedBlock.postParseCleanup(stripWhitespace);
     if (nestedBlock.isIgnorable()) {
       nestedBlock = null;
     } else {
       nestedBlock.parent = this;
     }
   }
   return this;
 }
 public void setChildAt(int index, TemplateElement element) {
   if (nestedBlock instanceof MixedContent) {
     nestedBlock.setChildAt(index, element);
   } else if (nestedBlock != null) {
     if (index == 0) {
       nestedBlock = element;
       element.index = 0;
       element.parent = this;
     } else {
       throw new IndexOutOfBoundsException("invalid index");
     }
   } else if (regulatedChildBuffer != null) {
     regulatedChildBuffer[index] = element;
     element.index = index;
     element.parent = this;
   } else {
     throw new IndexOutOfBoundsException("element has no children");
   }
 }
  final void addRegulatedChild(int index, TemplateElement nestedElement) {
    final int lRegulatedChildCount = regulatedChildCount;

    TemplateElement[] lRegulatedChildBuffer = regulatedChildBuffer;
    if (lRegulatedChildBuffer == null) {
      lRegulatedChildBuffer = new TemplateElement[INITIAL_REGULATED_CHILD_BUFFER_CAPACITY];
      regulatedChildBuffer = lRegulatedChildBuffer;
    } else if (lRegulatedChildCount == lRegulatedChildBuffer.length) {
      setRegulatedChildBufferCapacity(lRegulatedChildCount != 0 ? lRegulatedChildCount * 2 : 1);
      lRegulatedChildBuffer = regulatedChildBuffer;
    }
    // At this point: nestedElements == this.nestedElements, and has sufficient capacity.

    for (int i = lRegulatedChildCount; i > index; i--) {
      TemplateElement movedElement = lRegulatedChildBuffer[i - 1];
      movedElement.index = i;
      lRegulatedChildBuffer[i] = movedElement;
    }
    nestedElement.index = index;
    nestedElement.parent = this;
    lRegulatedChildBuffer[index] = nestedElement;
    regulatedChildCount = lRegulatedChildCount + 1;
  }