function syncTrees(treeIn, treeOut, pathToMedia) {
    var lastElement = null;
    for (var i = 0, childIn; childIn = treeIn.childNodes[i]; i++) {
      if (!childIn.tagName) {
        // Skip over text.
        continue;
      }
      switch (childIn.tagName.toUpperCase()) {
        case 'CATEGORY':
          var childOut = rootOut.createNode(childIn.getAttribute('name'));
          childOut.blocks = [];
          treeOut.add(childOut);
          var custom = childIn.getAttribute('custom');
          if (custom) {
            // Variables and procedures are special dynamic categories.
            childOut.blocks = custom;
          } else {
            syncTrees(childIn, childOut, pathToMedia);
          }
          var colour = childIn.getAttribute('colour');
          if (goog.isString(colour)) {
            if (colour.match(/^#[0-9a-fA-F]{6}$/)) {
              childOut.hexColour = colour;
            } else {
              childOut.hexColour = Blockly.hueToRgb(colour);
            }
            hasColours = true;
          } else {
            childOut.hexColour = '';
          }
          if (childIn.getAttribute('expanded') == 'true') {
            if (childOut.blocks.length) {
              rootOut.setSelectedItem(childOut);
            }
            childOut.setExpanded(true);
          } else {
            childOut.setExpanded(false);
          }
          lastElement = childIn;
          break;
        case 'SEP':
          if (lastElement) {
            if (lastElement.tagName.toUpperCase() == 'CATEGORY') {
              // Separator between two categories.
              // <sep></sep>
              treeOut.add(new Blockly.Toolbox.TreeSeparator(
                  that.treeSeparatorConfig_));
            } else {
              // Change the gap between two blocks.
              // <sep gap="36"></sep>
              // The default gap is 24, can be set larger or smaller.
              // Note that a deprecated method is to add a gap to a block.
              // <block type="math_arithmetic" gap="8"></block>
              var newGap = parseFloat(childIn.getAttribute('gap'));
              if (!isNaN(newGap)) {
                var oldGap = parseFloat(lastElement.getAttribute('gap'));
                var gap = isNaN(oldGap) ? newGap : oldGap + newGap;
                lastElement.setAttribute('gap', gap);
              }
            }
          }
          break;
        case 'BLOCK':
        case 'SHADOW':
          treeOut.blocks.push(childIn);
          lastElement = childIn;
          break;
      }
    }
  }
Fill the toolbox with categories and blocks.
@param {Node} newTree DOM tree of blocks, or null.
@private