
//generic tree implementation
var Node = function(value) {

    this.value = value;
    this.children = [];
    this.parent = null;

    this.setParentNode = function(node) {
        this.parent = node;
        //FIXME this should also add the reverse (child) link to the parent node
    }

    this.getParentNode = function() {
        return this.parent;
    }

    this.addChild = function(node) {
        node.setParentNode(this);
        this.children[this.children.length] = node;
    }

    this.getChildren = function() {
        return this.children;
    }

    this.removeChildren = function() {
        this.children = [];
    }

    this.getTotalDescendantCount = function() {
        var count = 0;
        for (child of this.children) {
            count += child.getTotalDescendantCount();
        }
        return count + this.children.length;
    }
}


var PrBufNode = function(id, type, val) {
    this.value = {id, type, val}
    this.children = [];
    this.parent = null;
    if (undefined === id) {
        this.root = true;
    }
}

PrBufNode.prototype = new Node();
PrBufNode.prototype.constructor = PrBufNode;

//Compares the number of descendants with the value specified in the map element.
//If all the children have not yet been added, we continue adding to this element.
PrBufNode.prototype.findLatestIncompleteNode = function() {

    //if it's a branch (map) node ('m') and has room, or if it's the root, return this node
    if (((this.value.type === 'm') && (this.value.val > this.getTotalDescendantCount()))
        || (this.root)) {
        return this;
    }
    else {
        //if we've reached the root, return null
        if (this.parent === null) {
            return null;
        } else {
            //otherwise recurse up the tree
            return this.parent.findLatestIncompleteNode();
        }
    }
}



//parses the input URL 'data' protocol buffer parameter into a tree
var parse = function(urlToParse) {
    var root = null;
    var re = /data=!([^?&]+)/
    var dataArray = urlToParse.match(re);
    if (dataArray && dataArray.length >= 1) {
        console.log(dataArray);
        var elemArray = dataArray[1].split("!");

        var rootNode = new PrBufNode();
        var workingNode = rootNode;
        //we iterate through each of the elements, creating a node for it, and
        //deciding where to place it in the tree
        for (var i=0; i < elemArray.length; i++) {
            var elemRe = /^([0-9])([a-z])(.*)$/
            var elementCompositionArray = elemArray[i].match(elemRe);
            if (elementCompositionArray && elementCompositionArray.length > 3) {
                //console.log(elementCompositionArray);
                var id = elementCompositionArray[1];
                var type = elementCompositionArray[2];
                var value = elementCompositionArray[3];
                var elemNode = new PrBufNode(id, type, value);
                //if (!root) {
                //    root = elemNode;
                //    workingNode = root;
                //} else {
                    workingNode.addChild(elemNode);
                    workingNode = elemNode.findLatestIncompleteNode();
                    if (null == workingNode) {
                        //we've filled up the branches right back to the root, so nothing more we can add
                        break;
                    }
                //}
            }
        }
    }
    return rootNode;
}



@@ -1967,16 +1967,20 @@
 var root
+Node
  = null;
@@ -1976,24 +1976,24 @@
 ode = null;%0A
-
     var re =
@@ -2110,94 +2110,8 @@
     
-console.log(dataArray);%0A        var elemArray = dataArray%5B1%5D.split(%22!%22);%0A%0A        var 
 root
@@ -2290,32 +2290,81 @@
  it in the tree%0A
+        var elemArray = dataArray%5B1%5D.split(%22!%22);%0A
         for (var
@@ -2462,38 +2462,28 @@
     var elem
-entComposition
+Vals
 Array = elem
@@ -2530,495 +2530,149 @@
 elem
-entCompositionArray && elementCompositionArray.length %3E 3) %7B%0A                //console.log(elementCompositionArray);%0A                var id = elementCompositionArray%5B1%5D;%0A                var type = elementCompositionArray%5B2%5D;%0A                var value = elementCompositionArray%5B3%5D;%0A                var elemNode = new PrBufNode(id, type, value);%0A                //if (!root) %7B%0A                //    root = elemNode;%0A                //    workingNode = root;%0A                //%7D else %7B%0A    
+ValsArray && elemValsArray.length %3E 3) %7B%0A                var elemNode = new PrBufNode(elemValsArray%5B1%5D, elemValsArray%5B2%5D, elemValsArray%5B3%5D);%0A
     
@@ -2711,28 +2711,24 @@
 (elemNode);%0A
-    
             
@@ -2794,28 +2794,24 @@
             
-    
 if (null == 
@@ -2841,28 +2841,24 @@
             
-   
- 
 //we've fill
@@ -2947,20 +2947,16 @@
         
-    
 break;%0A 
@@ -2974,32 +2974,8 @@
     
-    %7D%0A                //
 %7D%0A  

Tidy up, remove obsolete code.