anchor.diff:    final dir = await Directory.systemTemp.createTemp('heap-snapshot');
     final path = dir.path + '/merged-dominator.html';
     final file = await File(path).create();
  -  final tree = makeJson(snapshot.mergedRoot);
  -  await file.writeAsString(html.replaceAll('__JSON__', tree));
  +  final tree = makeData(snapshot.mergedRoot);
  +  await file.writeAsString(html.replaceAll('__DATA__', tree));
     print('Wrote file://' + path);
   }
  
positive.code:   return reader.done;
  }
  
  String makeJson(root) {
    // 'root' can be arbitrarily deep, so we need to use an explicit stack
    // instead of the call stack. We also must avoid using a JSON expression to
    // avoid stack overflow in the JS engine parser.
    final ids = new Map<dynamic, int>();
    final sb = new StringBuffer();
    final worklist = new List<dynamic>();
    worklist.add(root);
  
    var id = 0;
    while (id < worklist.length) {
      var object = worklist[id];
      ids[object] = id++;
      worklist.addAll(object.children);
    }
  
    while (!worklist.isEmpty) {
      var object = worklist.removeLast();
      var id = ids[object];
  
      sb.write('var node');
      sb.write(id.toString());
      sb.write(' = {"name":"');
      sb.write(object.description);
      sb.write('","type":"');
      sb.write(object.klass.name);
      sb.write('","size":');
      sb.write(object.retainedSize.toString());
      sb.write(',"children":[');
  
      bool first = true;
      for (var child in object.children) {
        if (!first) {
          sb.write(',');
        }
        first = false;
        sb.write('node');
        sb.write(ids[child].toString());
      }
  
      sb.write(']};\n');
    }
  
    return sb.toString();
  }
  
  var css = '''
  
negative.code:   content.appendChild(topTile);
  }
  
  function inflateData(flattened) {
    // 'root' can be arbitrarily deep, so we need to use an explicit stack
    // instead of the call stack.
    let nodes = new Array();
    let i = 0;
    while (i < flattened.length) {
      let node = {
        "name": flattened[i++],
        "type": flattened[i++],
        "size": flattened[i++],
        "children": [],
        "parent": null
      };
      nodes.push(node);
  
      let parentIndex = flattened[i++];
      if (parentIndex != null) {
        let parent = nodes[parentIndex];
        parent.children.push(node);
        node.parent = parent;
      }
    }
  
    return nodes[0];
  }
  
  var root = __DATA__;
  root = inflateData(root);
  
  showDominatorTree(root);
  ''';
  
  