https://www.w3.org/TR/html5/syntax.html
        See: 8.2.5 Tree construction
967712
def parse(self, parent):
        

        last_child = None

        for event, element in self.stream:

            tag = element.tag

            if event == 'start':

                last_child = element

                if isinstance(parent.behavior, Table):

                    # these are not direct descendants of <table>, add missing parent

                    if tag in ('td', 'th', 'tr'):
                        parent = parent.behavior.tbody or self.make_child(parent, 'tbody', {})

                    elif tag == 'col':
                        parent = parent.behavior.columns or self.make_child(parent, 'colgroup', {})

                elif isinstance(parent.behavior, TableRowGroup):

                    # these are not direct descendants of <tbody>, add missing parent

                    if tag in ('td', 'th'):
                        parent = self.make_child(parent, 'tr', {})

                node = self.make_child(parent, tag, element.attrib)

                if isinstance(node.behavior, Table) and self.table_columns:
                    measurements_data = self.table_columns.pop(0)
                    node.behavior.columns.behavior.measurements = measurements_data['maximums']
                    node.behavior.columns.behavior.span = measurements_data['span']

                if isinstance(node.behavior, Table) and parent.tag == 'body':
                    yield from self.parse(node)

                else:

                    # root tables are a very special case
                    # where the table and row groups
                    # are not yielded but the table rows
                    # themselves are yielded as "root nodes"

                    skip_root_table_meta_groups = (  # don't yield <colgroup>, <thead>, <tbody>, <tfoot>
                        parent.parent and parent.parent.tag == 'body' and
                        isinstance(node.behavior, (TableRowGroup, TableColumnGroup, TableCaption))
                    )

                    yield_root_table_rows = (  # do yield <tr> that's inside <tbody>
                        skip_root_table_meta_groups and
                        node.style.display == 'table-row-group'
                    )

                    position = 0
                    position_of_type = {}

                    for previous, (child_element, child_node), last in iter_previous_current_last(self.parse(node)):
                        if previous is not None:
                            if node.text_allowed and previous[0].tail:
                                # insert text between previous node and current node
                                node.insert(len(node.children)-2, previous[0].tail)
                        position_of_type.setdefault(child_node.tag, 0)
                        child_node.position = position = position + 1
                        child_node.position_of_type = position_of_type[child_node.tag] = position_of_type[child_node.tag] + 1
                        child_node.last = last
                        if yield_root_table_rows and isinstance(child_node.behavior, TableRow):
                            self.css.apply_recursively(child_node)
                            yield child_element, child_node

                    if node.text_allowed and element.text:
                        node.insert(0, element.text)

                    if not skip_root_table_meta_groups:
                        yield element, node

            else:

                if parent.text_allowed and last_child is not None and last_child.tail:
                    parent.add(last_child.tail)

                break
1170648
function(oUnitTest) {
          var _,
              /**
               * An array-like object representing the <abbr title=
               * "abstract syntax tree">AST</abbr> obtained after consolidation.
               * @type {!TSyntacticCodeUnit}
               */
              oSyntacticCodeUnitActual =
                  exports.ast_consolidate(oParser.parse(oUnitTest.sInput)),
              /**
               * An array-like object representing the expected <abbr title=
               * "abstract syntax tree">AST</abbr>.
               * @type {!TSyntacticCodeUnit}
               */
              oSyntacticCodeUnitExpected = oParser.parse(
                  oUnitTest.hasOwnProperty('sOutput') ?
                  oUnitTest.sOutput : oUnitTest.sInput);

          delete oSyntacticCodeUnitActual.scope;
          oWalker = oProcessor.ast_walker();
          oWalker.with_walkers(
              oWalkersPurifiers,
              cContext(oWalker, oSyntacticCodeUnitActual));
          try {
            oAssert.deepEqual(
                oSyntacticCodeUnitActual,
                oSyntacticCodeUnitExpected);
          } catch (oException) {
            console.error(
                '########## A unit test has failed.\n' +
                oUnitTest.sTitle + '\n' +
                '#####  actual code  (' +
                oProcessor.gen_code(oSyntacticCodeUnitActual).length +
                ' bytes)\n' +
                oProcessor.gen_code(
                    oSyntacticCodeUnitActual,
                    oCodeGenerationOptions) + '\n' +
                '##### expected code (' +
                oProcessor.gen_code(oSyntacticCodeUnitExpected).length +
                ' bytes)\n' +
                oProcessor.gen_code(
                    oSyntacticCodeUnitExpected,
                    oCodeGenerationOptions));
          }
        }
501828
function initContentStructureTree( $rootNodeID, $fetchHidden, $classFilter = false )
    {
        // create initial subtree with root node and empty children.
        $nodes = false;
        $rootTreeNode = eZContentObjectTreeNode::fetch( $rootNodeID );
        if ( $rootTreeNode && $rootTreeNode->canRead() )
        {
            if ( !$fetchHidden && ( $rootTreeNode->attribute( 'is_hidden' ) || $rootTreeNode->attribute( 'is_invisible' ) ) )
            {
                return false;
            }
            else
            {
                $contentObject = $rootTreeNode->attribute( 'object' );

                $viewNodeAllowed = true;
                if ( is_array( $classFilter ) && count( $classFilter ) > 0 )
                {
                    $contentClassIdentifier = $contentObject->attribute( 'class_identifier' );

                    if ( !in_array( $contentClassIdentifier, $classFilter ) )
                        $viewNodeAllowed = false;
                }

                if ( $viewNodeAllowed )
                {
                    $rootNode = array( 'node' => array( 'node_id' => $rootTreeNode->attribute( 'node_id' ),
                                                        'path_identification_string' => $rootTreeNode->pathWithNames(),
                                                        'children_count' => $rootTreeNode->attribute( 'children_count' ),
                                                        'sort_array' => $rootTreeNode->attribute( 'sort_array' ),
                                                        'path_string' => $rootTreeNode->attribute( 'path_string' ),
                                                        'depth' => $rootTreeNode->attribute( 'depth' ),
                                                        'is_hidden' => $rootTreeNode->attribute( 'is_hidden' ),
                                                        'is_invisible' => $rootTreeNode->attribute( 'is_invisible' ) ),
                                                        'classes_js_array' => eZContentObjectTreeNode::availableClassListJsArray( array( 'node' => &$rootTreeNode ) ),
                                       'object' => array( 'id' => $contentObject->attribute( 'id' ),
                                                          'name' => $contentObject->attribute( 'name' ),
                                                          'class_identifier' => $contentObject->attribute( 'class_identifier' ),
                                                          'class_name' => $contentObject->attribute('class_name'),
                                                          'published' => $contentObject->attribute( 'published' ),
                                                          'is_container' => true,
                                                          'language_js_array' => eZContentLanguage::jsArrayByMask( $contentObject->attribute( 'language_mask' ) ) ) );

                    $nodes = array( 'parent_node' => &$rootNode,
                                    'children' => array() );
                }
            }
        }

        return $nodes;
    }
686954
function syntaxHighlight(json) {
  json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
    var cls = 'number',
        url = false;
    if (/^"/.test(match)) {
        if (/:$/.test(match)) {
          cls = 'key';
        } else {
          cls = 'string';
          if(match.indexOf('"https://') === 0){
            // url = true;
            cls += ' link';
          }
        }
    } else if (/true|false/.test(match)) {
      cls = 'boolean';
    } else if (/null/.test(match)) {
      cls = 'null';
    }
    var html = '<span class="' + cls + '">' + match + '</span>';
    if(url){
      html = '<a href>' + html + '</a>';
    }
    return html;
  });
}
1073910
private RulesTrees buildTrees() {
		long start = System.nanoTime();
		
		// Reset the trees.
		List<List<State>> rawRulesTrees = new ArrayList<List<State>>(RulesProperties.NUMBER_OF_TREES);
		// Creating trees (and their initial state) and setting state vars
		// for each of them.
		// For this implementation, we have:
		// - tree.get(0) = the general tree
		// - tree.get(1) = the phrase-local tree
		// - tree.get(2) = the subject-verb tree
		for (int i = 0; i < RulesProperties.NUMBER_OF_TREES; i++) {
			rawRulesTrees.add(new ArrayList<State>());
			// Start state is the only state that does not need an element.
			rawRulesTrees.get(i).add(new State(0, new PatternElement()));
			this.currentState[i] = 0;
			// Next state to be created.			
			this.nextState[i] = 1;
		}
		
		// For each active rule.
		for (Rule rule : this.rulesProvider.getRules().getRule()) {
			if (isActive(rule)) {
				// For each element.
				int i = 0;
				// See to which tree the rules refers to.
				int treeIndex = 0;
				if (rule.getMethod() == Method.GENERAL) {
					treeIndex = RulesProperties.GENERAL_TREE;
				} else if (rule.getMethod() == Method.PHRASE_LOCAL) {
					treeIndex = RulesProperties.PHRASE_LOCAL_TREE;
				} else if (rule.getMethod() == Method.SUBJECT_VERB) {
					treeIndex = RulesProperties.SUBJECT_VERB_TREE;
				}
				for (PatternElement element : rule.getPattern().getPatternElement()) {
					int reuseStateIndex = -1;
					List<State> nextStates;
					nextStates = rawRulesTrees.get(treeIndex).get(this.currentState[treeIndex]).getNextStates();
					if (nextStates.isEmpty()) {
						// A state must be created.
						this.createState(rawRulesTrees, i, element, nextStates, rule, treeIndex);
					} else {
						// Check if from the current state in the tree there's a reachable state that has the same element.
						for (int j = 0; j < nextStates.size(); j++) {
							if (EqualsUtils.arePatternElementEquals(nextStates.get(j).getElement(), element)) {
								reuseStateIndex = nextStates.get(j).getName();
								break;
							}
						}
						if (reuseStateIndex == -1) {
							this.createState(rawRulesTrees, i, element, nextStates, rule, treeIndex);
						} else {
							this.currentState[treeIndex] = reuseStateIndex;
						}
					}
					i++;
				}
			}
		}
		
		LOGGER.info("Rules trees built in " + (System.nanoTime() - start) / 1000000 + "ms");
		
		return this.buildRulesTrees(rawRulesTrees);
	}
1135183
function Node(cfg) {

  this.namespace     = cfg.namespace || null;
  this.text          = cfg.text;
  this._selfCloseTag = cfg.selfCloseTag;


  Object.defineProperties(this, {
    nodeType: {
      value: cfg.nodeType
    },
    nodeName: {
      value: cfg.nodeType == 1 ? cfg.nodeName : '#text'
    },
    childNodes: {
      value: cfg.childNodes
    },
    firstChild: {
      get: function(){
        return this.childNodes[0] || null;
      }
    },
    lastChild: {
      get: function(){
        return this.childNodes[this.childNodes.length-1] || null;
      }
    },
    parentNode: {
      value: cfg.parentNode || null
    },
    attributes: {
      value: cfg.attributes || []
    },
    innerHTML: {
      get: function(){
        var
          result = '',
          cNode;
        for (var i = 0, l = this.childNodes.length; i < l; i++) {
          cNode = this.childNodes[i];
          result += cNode.nodeType === 3 ? cNode.text : cNode.outerHTML;
        }
        return result;
      }
    },
    outerHTML: {
      get: function(){
        if (this.nodeType != 3){
          var
            str,
            attrs = (this.attributes.map(function(elem){
              return elem.name + (elem.value ? '=' + '"'+ elem.value +'"' : '');
            }) || []).join(' '),
            childs = '';

          str = '<' + this.nodeName + (attrs ? ' ' + attrs : '') + (this._selfCloseTag ? '/' : '') + '>';

          if (!this._selfCloseTag){
            childs = (this._selfCloseTag ? '' : this.childNodes.map(function(child){
              return child.outerHTML;
            }) || []).join('');

            str += childs;
            str += '</' + this.nodeName + '>';
          }
        }
        else{
          str = this.textContent;
        }
        return str;
      }
    },
    textContent: {
      get: function(){
        if (this.nodeType == Node.TEXT_NODE){
          return this.text;
        }
        else{
          return this.childNodes.map(function(node){
            return node.textContent;
          }).join('').replace(/\x20+/g, ' ');
        }
      }
    }
  });
}
869714
def pretty_tree(x, kids, show):
    
    (MID, END, CONT, LAST, ROOT) = (u'|-- ', u'`-- ', u'|   ', u'    ', u'')

    def rec(x, indent, sym):
        line = indent + sym + show(x)
        xs = kids(x)
        if len(xs) == 0:
            return line
        else:
            if sym == MID:
                next_indent = indent + CONT
            elif sym == ROOT:
                next_indent = indent + ROOT
            else:
                next_indent = indent + LAST
            syms = [MID] * (len(xs) - 1) + [END]
            lines = [rec(x, next_indent, sym) for x, sym in zip(xs, syms)]
            return u'\n'.join([line] + lines)

    return rec(x, u'', ROOT)
1183866
def __make_tree(self):
        """"""

        # create div with "container" class
        div = E.DIV(E.CLASS("container"))

        # append header with title
        div.append(E.H2(self.__title))

        # next, iterate through subtrees appending each tree to div
        for subtree in self.__subtrees:
            div.append(subtree.get_html())

        # Connect div to body
        body = E.BODY(div)

        # attach body to html
        self.__htmltree = E.HTML(
            E.HEAD(
                E.TITLE(self.__title)
                ),
            body
            )
218524
function htmlTreeAsString (elem) {
  var MAX_TRAVERSE_HEIGHT = 5
  var MAX_OUTPUT_LEN = 80
  var out = []
  var height = 0
  var len = 0
  var separator = ' > '
  var sepLength = separator.length
  var nextStr

  while (elem && height++ < MAX_TRAVERSE_HEIGHT) {
    nextStr = htmlElementAsString(elem)
    // bail out if
    // - nextStr is the 'html' element
    // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
    //   (ignore this limit if we are on the first iteration)
    if (
      nextStr === 'html' ||
      (height > 1 &&
       len + (out.length * sepLength) + nextStr.length >= MAX_OUTPUT_LEN)
    ) {
      break
    }

    out.push(nextStr)

    len += nextStr.length
    elem = elem.parentNode
  }

  return out.reverse().join(separator)
}
451134
void  build() {
           // If there were no rules, just return.  This situation can easily arise
           //   for the reverse rules.
           if (fRB.fTreeRoots[fRootIx]==null) {
               return;
           }

           //
           // Walk through the tree, replacing any references to $variables with a copy of the
           //   parse tree for the substition expression.
           //
           fRB.fTreeRoots[fRootIx] = fRB.fTreeRoots[fRootIx].flattenVariables();
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("ftree")>=0) {
               System.out.println("Parse tree after flattening variable references.");
               fRB.fTreeRoots[fRootIx].printTree(true);
           }

           //
           // If the rules contained any references to {bof}
           //   add a {bof} <cat> <former root of tree> to the
           //   tree.  Means that all matches must start out with the
           //   {bof} fake character.
           //
           if (fRB.fSetBuilder.sawBOF()) {
               RBBINode bofTop    = new RBBINode(RBBINode.opCat);
               RBBINode bofLeaf   = new RBBINode(RBBINode.leafChar);
               bofTop.fLeftChild  = bofLeaf;
               bofTop.fRightChild = fRB.fTreeRoots[fRootIx];
               bofLeaf.fParent    = bofTop;
               bofLeaf.fVal       = 2;      // Reserved value for {bof}.
               fRB.fTreeRoots[fRootIx] = bofTop;
           }

           //
           // Add a unique right-end marker to the expression.
           //   Appears as a cat-node, left child being the original tree,
           //   right child being the end marker.
           //
           RBBINode cn = new RBBINode(RBBINode.opCat);
           cn.fLeftChild = fRB.fTreeRoots[fRootIx];
           fRB.fTreeRoots[fRootIx].fParent = cn;
           cn.fRightChild = new RBBINode(RBBINode.endMark);
           cn.fRightChild.fParent = cn;
           fRB.fTreeRoots[fRootIx] = cn;

           //
           //  Replace all references to UnicodeSets with the tree for the equivalent
           //      expression.
           //
           fRB.fTreeRoots[fRootIx].flattenSets();
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("stree")>=0) {
               System.out.println("Parse tree after flattening Unicode Set references.");
               fRB.fTreeRoots[fRootIx].printTree(true);
           }


           //
           // calculate the functions nullable, firstpos, lastpos and followpos on
           // nodes in the parse tree.
           //    See the alogrithm description in Aho.
           //    Understanding how this works by looking at the code alone will be
           //       nearly impossible.
           //
           calcNullable(fRB.fTreeRoots[fRootIx]);
           calcFirstPos(fRB.fTreeRoots[fRootIx]);
           calcLastPos(fRB.fTreeRoots[fRootIx]);
           calcFollowPos(fRB.fTreeRoots[fRootIx]);
           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("pos")>=0) {
               System.out.print("\n");
               printPosSets(fRB.fTreeRoots[fRootIx]);
           }

           //
           //  For "chained" rules, modify the followPos sets
           //
           if (fRB.fChainRules) {
               calcChainedFollowPos(fRB.fTreeRoots[fRootIx]);
           }

           //
           //  BOF (start of input) test fixup.
           //
           if (fRB.fSetBuilder.sawBOF()) {
               bofFixup();
           }

           //
           // Build the DFA state transition tables.
           //
           buildStateTable();
           flagAcceptingStates();
           flagLookAheadStates();
           flagTaggedStates();

           //
           // Update the global table of rule status {tag} values
           // The rule builder has a global vector of status values that are common
           //    for all tables.  Merge the ones from this table into the global set.
           //
           mergeRuleStatusVals();

           if (fRB.fDebugEnv!=null && fRB.fDebugEnv.indexOf("states")>=0) {printStates();}
       }
703509
def syntax(syntax = nil)
      @syntax = syntax if syntax
      syntax_list = []
      if parent
        syntax_list << parent.syntax.to_s.gsub(%r!<[\w\s-]+>!, "").gsub(%r!\[[\w\s-]+\]!, "").strip
      end
      syntax_list << (@syntax || name.to_s)
      syntax_list.join(" ")
    end
1131759
function buildTree(directory, depth, parentGitignoreList) {
  const files = fs.readdirSync(directory);
  const max_index = files.length - 1
  const color = chalk[colors[depth % colors.length]]
  parentGitignoreList = parentGitignoreList || []
  const gitignoreList = hideFilesInGitIgnore
    ? parentGitignoreList.concat(readGitignore(directory))
    : []

  for (let i = 0; i <= max_index; i++) {
    const file = files[i]
    depths[depth] = max_index - i
    const fullPath = path.resolve(directory, file)
    let printWithoutDescending = false
    let postfix = ''
    let prefix = buildPrefix(depth, i === max_index, directory)
    const stats = fs.statSync(fullPath)
    const isDirectory = stats.isDirectory()
    const size = prettybytes(stats.size)

    if (showTimeStamp) {
      prefix += dateTemplate.render(new Date(stats.mtime))
    }

    if (isDirectory) {
      directoryCount++
    } else {
      fileCount++
      totalFileSize += stats.size
    }

    if (!shouldBeIncluded(file)) {
      continue
    }

    if (hideFilesInGitIgnore) {
      let matchesGitIgnoreEntry = false
      let m = gitignoreList.length
      while (!matchesGitIgnoreEntry && m > 0) {
        matchesGitIgnoreEntry = minimatch(file, gitignoreList[m - 1])
        m--
      }

      if (matchesGitIgnoreEntry) {
        continue
      }
    }

    if (!isDirectory && showOnlyDirectories) {
      continue
    }

    if (isDirectory) {
      if (fileLimit !== Infinity || pruneEmptyDirectories) {
        const dirfiles = fs.readdirSync(fullPath).filter(shouldBeIncluded)
        if (pruneEmptyDirectories && dirfiles.length === 0) {
          continue
        }
        if (dirfiles.length > fileLimit) {
          printWithoutDescending = true
          postfix = ` [${dirfiles.length} entries exceeds filelimit (${fileLimit}), not opening dir]`
        }
      }
    }

    const filename = showFullPath ? color(fullPath.replace(cwd + '/', '')) : color(file)
    const JSXTags = createJSXTags(filename, isDirectory, size, fullPath)

    if (printJSX) {
      output += prefix + JSXTags.open + '\n'
    } else {
      output += prefix + filename + (!isDirectory && showSize ? ` (${size})` : '') + postfix + '\n';
    }
    if (printWithoutDescending) {
      continue
    }
    if (isDirectory && (depth + 1 < maxDepth)) {
      buildTree(path.resolve(directory, file), depth + 1, gitignoreList)
    }
    if (printJSX && JSXTags.close) {
      output += prefix + JSXTags.close + '\n'
    }
    --depths[depth]
  }
}
885326
function () {
                    var str, j = i, e;

                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
                    if (input.charAt(j) !== '`') { return }

                    e && $('~');

                    if (str = $(/^`([^`]*)`/)) {
                        return new(tree.JavaScript)(str[1], i, e);
                    }
                }
80080
public function buildTreeHtml($keys = [], $items = [], $config = [], $selected = []) {
        $configDefault = [
            'id' => 'nestable',
            'class' => 'dd',
            'containerClass' => 'dd-list',
            'itemClass' => 'dd-item',
            'labelClass' => 'dd-handle',
            'actions' => [],
        ];
        $config = array_merge($configDefault, $config);

        // root items
        $asRoot = false;
        if (empty($items)) {
            $asRoot = true;
            $items[] = [
                '_id' => $this->owner->getAttribute('_id'),
                'name' => $this->owner->getAttribute('name'),
                'lft' => $this->owner->getAttribute($this->leftAttribute),
                'rgt' => $this->owner->getAttribute($this->rightAttribute),
            ];
            $children = $this->children()->all();
            foreach ($children as $child) {
                $items[] = [
                    '_id' => $child->owner->getAttribute('_id'),
                    'name' => $child->owner->getAttribute('name'),
                    $this->leftAttribute => $child->owner->getAttribute($this->leftAttribute),
                    $this->rightAttribute => $child->owner->getAttribute($this->rightAttribute),
                ];
            }
            $keys = $this->buildTreeKeys($items);
        }
        
        $list = Html::beginTag('ol', ['class' => $config['containerClass']]);
        foreach ($keys as $key => $row) {
            if (isset($config['actions'])) {
                $actions = str_replace ('{_id}', $items[$key]['_id'], $config['actions']);

                if (is_array($selected) && in_array($items[$key]['_id'], $selected)) {
                    $actions = str_replace ('{check}', 'checked', $actions);
                }
            }

            if (count($row)) {
                $list .= Html::tag('li', $actions.'<div class="' . $config['labelClass'] . '">' . $items[$key]['name']  . '</div>' . $this->buildTreeHtml($row, $items, $config, $selected), ['class' => $config['itemClass'], 'data-id' => $items[$key]['_id']]);
            } else {
                $list .= Html::tag('li', $actions.'<div class="' . $config['labelClass'] . '">' . $items[$key]['name'] . '</div>', ['class' => $config['itemClass'], 'data-id' => $items[$key]['_id']]);
            }
        }
        $list .= Html::endTag('ol');

//        if (strpos($list, Html::beginTag('li', ['class' => $config['itemClass'], 'data-id' => $items[$key]['_id']])) === false) {
//            $list = '';
//        }
        
        if ($asRoot){
            $list = Html::tag('div', $list, ['id' => $config['id'], 'class' => $config['class']]);
        }
        return $list;
    }
1101180
function (tree) {
    var todo = tree.slice();
    var done = [];
    var current;
    while (todo.length) {
      current = todo.pop();
      if (current.nodes) {
        todo = todo.concat(current.nodes);
      } else if (current.leaf) {
        done.push(current);
      }
    }
    return done;
  }
1287298
function(syntax) {
			var cacheKey = 'all-' + syntax;
			if (!cache[cacheKey]) {
				var stack = [], sectionKey = syntax;
				var memo = [];

				do {
					var section = this.getSection(sectionKey);
					if (!section)
						break;

					['snippets', 'abbreviations'].forEach(function(sectionName) {
						var stackItem = {};
						each(section[sectionName] || null, function(v, k) {
							stackItem[k] = {
								nk: normalizeName(k),
								value: v,
								parsedValue: parseItem(k, v, sectionName),
								type: sectionName
							};
						});

						stack.push(stackItem);
					});

					memo.push(sectionKey);
					sectionKey = section['extends'];
				} while (sectionKey && !~memo.indexOf(sectionKey));


				cache[cacheKey] = utils.extend.apply(utils, stack.reverse());
			}

			return cache[cacheKey];
		}
634276
function Tree(type) {
    abstractions.Composite.call(this, type);
    if (!utilities.types.isProcedural(type)) {
        throw new utilities.Exception({
            $module: '/bali/composites/Tree',
            $procedure: '$Tree',
            $exception: '$invalidParameter',
            $parameter: utilities.types.symbolForType(type),
            $text: '"An invalid tree type was passed to the constructor."'
        });
    }

    // the array is a private attribute so methods that use it are defined in the constructor
    const array = [];

    this.toArray = function() {
        return array.slice(); // copy the array
    };

    this.getSize = function() {
        return array.length;
    };

    this.addChild = function(child) {
        array.push(child);
        child.getParent = function() { return this; };
    };

    this.getChild = function(index) {
        index = this.normalizeIndex(index) - 1;  // JS uses zero based indexing
        return array[index];
    };

    this.getParent = function() { };  // will be reset by parent when added as a child

    return this;
}