// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:html';
import 'dart:math' as Math;
import 'dart:typed_data';
import 'package:observatory/models.dart' as M;
import 'package:observatory/object_graph.dart';
import 'package:observatory/src/elements/class_ref.dart';
import 'package:observatory/src/elements/containers/virtual_tree.dart';
import 'package:observatory/src/elements/curly_block.dart';
import 'package:observatory/src/elements/helpers/any_ref.dart';
import 'package:observatory/src/elements/helpers/nav_bar.dart';
import 'package:observatory/src/elements/helpers/nav_menu.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/custom_element.dart';
import 'package:observatory/src/elements/helpers/uris.dart';
import 'package:observatory/src/elements/nav/isolate_menu.dart';
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/refresh.dart';
import 'package:observatory/src/elements/nav/top_menu.dart';
import 'package:observatory/src/elements/nav/vm_menu.dart';
import 'package:observatory/src/elements/tree_map.dart';
import 'package:observatory/repositories.dart';
import 'package:observatory/utils.dart';

enum HeapSnapshotTreeMode {
  classesTable,
  classesTableDiff,
  classesTreeMap,
  classesTreeMapDiff,
  dominatorTree,
  dominatorTreeMap,
  mergedDominatorTree,
  mergedDominatorTreeDiff,
  mergedDominatorTreeMap,
  mergedDominatorTreeMapDiff,
  ownershipTable,
  ownershipTableDiff,
  ownershipTreeMap,
  ownershipTreeMapDiff,
  predecessors,
  successors,
}

// Note the order of these lists is reflected in the UI, and the first option
// is the default.
const viewModes = [
  HeapSnapshotTreeMode.mergedDominatorTreeMap,
  HeapSnapshotTreeMode.mergedDominatorTree,
  HeapSnapshotTreeMode.dominatorTreeMap,
  HeapSnapshotTreeMode.dominatorTree,
  HeapSnapshotTreeMode.ownershipTreeMap,
  HeapSnapshotTreeMode.ownershipTable,
  HeapSnapshotTreeMode.classesTreeMap,
  HeapSnapshotTreeMode.classesTable,
  HeapSnapshotTreeMode.successors,
  HeapSnapshotTreeMode.predecessors,
];

const diffModes = [
  HeapSnapshotTreeMode.mergedDominatorTreeMapDiff,
  HeapSnapshotTreeMode.mergedDominatorTreeDiff,
  HeapSnapshotTreeMode.ownershipTreeMapDiff,
  HeapSnapshotTreeMode.ownershipTableDiff,
  HeapSnapshotTreeMode.classesTreeMapDiff,
  HeapSnapshotTreeMode.classesTableDiff,
];

class DominatorTreeMap extends NormalTreeMap<SnapshotObject> {
  HeapSnapshotElement element;
  DominatorTreeMap(this.element);

  int getSize(SnapshotObject node) => node.retainedSize;
  String getType(SnapshotObject node) => node.klass.name;
  String getName(SnapshotObject node) => node.description;
  SnapshotObject getParent(SnapshotObject node) => node.parent;
  Iterable<SnapshotObject> getChildren(SnapshotObject node) => node.children;
  void onSelect(SnapshotObject node) {
    element.selection = List.from(node.objects);
    element._r.dirty();
  }

  void onDetails(SnapshotObject node) {
    element.selection = List.from(node.objects);
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

class MergedDominatorTreeMap extends NormalTreeMap<SnapshotMergedDominator> {
  HeapSnapshotElement element;
  MergedDominatorTreeMap(this.element);

  int getSize(SnapshotMergedDominator node) => node.retainedSize;
  String getType(SnapshotMergedDominator node) => node.klass.name;
  String getName(SnapshotMergedDominator node) => node.description;
  SnapshotMergedDominator getParent(SnapshotMergedDominator node) =>
      node.parent;
  Iterable<SnapshotMergedDominator> getChildren(SnapshotMergedDominator node) =>
      node.children;
  void onSelect(SnapshotMergedDominator node) {
    element.mergedSelection = node;
    element._r.dirty();
  }

  void onDetails(SnapshotMergedDominator node) {
    element.selection = List.from(node.objects);
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

class MergedDominatorDiffTreeMap extends DiffTreeMap<MergedDominatorDiff> {
  HeapSnapshotElement element;
  MergedDominatorDiffTreeMap(this.element);

  int getSizeA(MergedDominatorDiff node) => node.retainedSizeA;
  int getSizeB(MergedDominatorDiff node) => node.retainedSizeB;
  int getGain(MergedDominatorDiff node) => node.retainedGain;
  int getLoss(MergedDominatorDiff node) => node.retainedLoss;
  int getCommon(MergedDominatorDiff node) => node.retainedCommon;

  String getType(MergedDominatorDiff node) => node.name;
  String getName(MergedDominatorDiff node) => "instances of ${node.name}";
  MergedDominatorDiff? getParent(MergedDominatorDiff node) => node.parent;
  Iterable<MergedDominatorDiff> getChildren(MergedDominatorDiff node) =>
      node.children!;
  void onSelect(MergedDominatorDiff node) {
    element.mergedDiffSelection = node;
    element._r.dirty();
  }

  void onDetails(MergedDominatorDiff node) {
    element._snapshotA = element._snapshotB;
    element.selection = node.objectsB;
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

// Using `null` to represent the root.
class ClassesShallowTreeMap extends NormalTreeMap<SnapshotClass> {
  HeapSnapshotElement element;
  SnapshotGraph snapshot;

  ClassesShallowTreeMap(this.element, this.snapshot);

  int getSize(SnapshotClass node) =>
      node == null ? snapshot.size : node.shallowSize;
  String getType(SnapshotClass node) => node == null ? "Classes" : node.name;
  String getName(SnapshotClass node) => node == null
      ? "${snapshot.classes.length} classes"
      : "${node.instanceCount} instances of ${node.name}";

  SnapshotClass? getParent(SnapshotClass node) => null;
  Iterable<SnapshotClass> getChildren(SnapshotClass node) =>
      node == null ? snapshot.classes : <SnapshotClass>[];
  void onSelect(SnapshotClass node) {}
  void onDetails(SnapshotClass node) {
    element.selection = List.from(node.instances);
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

// Using `null` to represent the root.
class ClassesShallowDiffTreeMap extends DiffTreeMap<SnapshotClassDiff> {
  HeapSnapshotElement element;
  List<SnapshotClassDiff> classes;

  ClassesShallowDiffTreeMap(this.element, this.classes);

  int getSizeA(SnapshotClassDiff node) {
    if (node != null) return node.shallowSizeA;
    int s = 0;
    for (var cls in classes) s += cls.shallowSizeA;
    return s;
  }

  int getSizeB(SnapshotClassDiff node) {
    if (node != null) return node.shallowSizeB;
    int s = 0;
    for (var cls in classes) s += cls.shallowSizeB;
    return s;
  }

  int getGain(SnapshotClassDiff node) {
    if (node != null) return node.shallowSizeGain;
    int s = 0;
    for (var cls in classes) s += cls.shallowSizeGain;
    return s;
  }

  int getLoss(SnapshotClassDiff node) {
    if (node != null) return node.shallowSizeLoss;
    int s = 0;
    for (var cls in classes) s += cls.shallowSizeLoss;
    return s;
  }

  int getCommon(SnapshotClassDiff node) {
    if (node != null) return node.shallowSizeCommon;
    int s = 0;
    for (var cls in classes) s += cls.shallowSizeCommon;
    return s;
  }

  String getType(SnapshotClassDiff node) =>
      node == null ? "Classes" : node.name;
  String getName(SnapshotClassDiff node) =>
      node == null ? "${classes.length} classes" : "instances of ${node.name}";
  SnapshotClassDiff? getParent(SnapshotClassDiff node) => null;
  Iterable<SnapshotClassDiff> getChildren(SnapshotClassDiff node) =>
      node == null ? classes : <SnapshotClassDiff>[];
  void onSelect(SnapshotClassDiff node) {}
  void onDetails(SnapshotClassDiff node) {
    element._snapshotA = element._snapshotB;
    element.selection = node.objectsB;
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

// Using `null` to represent the root.
class ClassesOwnershipTreeMap extends NormalTreeMap<SnapshotClass> {
  HeapSnapshotElement element;
  SnapshotGraph snapshot;

  ClassesOwnershipTreeMap(this.element, this.snapshot);

  int getSize(SnapshotClass node) =>
      node == null ? snapshot.size : node.ownedSize;
  String getType(SnapshotClass node) => node == null ? "classes" : node.name;
  String getName(SnapshotClass node) => node == null
      ? "${snapshot.classes.length} Classes"
      : "${node.instanceCount} instances of ${node.name}";
  SnapshotClass? getParent(SnapshotClass node) => null;
  Iterable<SnapshotClass> getChildren(SnapshotClass node) =>
      node == null ? snapshot.classes : <SnapshotClass>[];
  void onSelect(SnapshotClass node) {}
  void onDetails(SnapshotClass node) {
    element.selection = List.from(node.instances);
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

// Using `null` to represent the root.
class ClassesOwnershipDiffTreeMap extends DiffTreeMap<SnapshotClassDiff> {
  HeapSnapshotElement element;
  List<SnapshotClassDiff> classes;

  ClassesOwnershipDiffTreeMap(this.element, this.classes);

  int getSizeA(SnapshotClassDiff node) {
    if (node != null) return node.ownedSizeA;
    int s = 0;
    for (var cls in classes) s += cls.ownedSizeA;
    return s;
  }

  int getSizeB(SnapshotClassDiff node) {
    if (node != null) return node.ownedSizeB;
    int s = 0;
    for (var cls in classes) s += cls.ownedSizeB;
    return s;
  }

  int getGain(SnapshotClassDiff node) {
    if (node != null) return node.ownedSizeGain;
    int s = 0;
    for (var cls in classes) s += cls.ownedSizeGain;
    return s;
  }

  int getLoss(SnapshotClassDiff node) {
    if (node != null) return node.ownedSizeLoss;
    int s = 0;
    for (var cls in classes) s += cls.ownedSizeLoss;
    return s;
  }

  int getCommon(SnapshotClassDiff node) {
    if (node != null) return node.ownedSizeCommon;
    int s = 0;
    for (var cls in classes) s += cls.ownedSizeCommon;
    return s;
  }

  String getType(SnapshotClassDiff node) =>
      node == null ? "Classes" : node.name;
  String getName(SnapshotClassDiff node) =>
      node == null ? "${classes.length} classes" : "instances of ${node.name}";
  SnapshotClassDiff? getParent(SnapshotClassDiff node) => null;
  Iterable<SnapshotClassDiff> getChildren(SnapshotClassDiff node) =>
      node == null ? classes : <SnapshotClassDiff>[];
  void onSelect(SnapshotClassDiff node) {}
  void onDetails(SnapshotClassDiff node) {
    element._snapshotA = element._snapshotB;
    element.selection = node.objectsB;
    element._mode = HeapSnapshotTreeMode.successors;
    element._r.dirty();
  }
}

class SnapshotClassDiff {
  SnapshotClass? _a;
  SnapshotClass? _b;

  int get shallowSizeA => _a == null ? 0 : _a!.shallowSize;
  int get ownedSizeA => _a == null ? 0 : _a!.ownedSize;
  int get instanceCountA => _a == null ? 0 : _a!.instanceCount;

  int get shallowSizeB => _b == null ? 0 : _b!.shallowSize;
  int get ownedSizeB => _b == null ? 0 : _b!.ownedSize;
  int get instanceCountB => _b == null ? 0 : _b!.instanceCount;

  int get shallowSizeDiff => shallowSizeB - shallowSizeA;
  int get ownedSizeDiff => ownedSizeB - ownedSizeA;
  int get instanceCountDiff => instanceCountB - instanceCountA;

  int get shallowSizeGain =>
      shallowSizeB > shallowSizeA ? shallowSizeB - shallowSizeA : 0;
  int get ownedSizeGain =>
      ownedSizeB > ownedSizeA ? ownedSizeB - ownedSizeA : 0;
  int get shallowSizeLoss =>
      shallowSizeA > shallowSizeB ? shallowSizeA - shallowSizeB : 0;
  int get ownedSizeLoss =>
      ownedSizeA > ownedSizeB ? ownedSizeA - ownedSizeB : 0;
  int get shallowSizeCommon =>
      shallowSizeB > shallowSizeA ? shallowSizeA : shallowSizeB;
  int get ownedSizeCommon => ownedSizeB > ownedSizeA ? ownedSizeA : ownedSizeB;

  String get name => _a == null ? _b!.name : _a!.name;

  List<SnapshotObject> get objectsA =>
      _a == null ? const <SnapshotObject>[] : _a!.instances.toList();
  List<SnapshotObject> get objectsB =>
      _b == null ? const <SnapshotObject>[] : _b!.instances.toList();

  static List<SnapshotClassDiff> from(
      SnapshotGraph graphA, SnapshotGraph graphB) {
    // Matching classes by SnapshotClass.qualifiedName.
    var classesB = new Map<String, SnapshotClass>();
    var classesDiff = <SnapshotClassDiff>[];
    for (var classB in graphB.classes) {
      classesB[classB.qualifiedName] = classB;
    }
    for (var classA in graphA.classes) {
      var classDiff = new SnapshotClassDiff();
      var qualifiedName = classA.qualifiedName;
      var name = classA.name;
      classDiff._a = classA;
      var classB = classesB[qualifiedName];
      if (classB != null) {
        classesB.remove(qualifiedName);
        classDiff._b = classB;
      }
      classesDiff.add(classDiff);
    }
    for (var classB in classesB.values) {
      var classDiff = new SnapshotClassDiff();
      classDiff._b = classB;
      classesDiff.add(classDiff);
    }
    return classesDiff;
  }
}

class MergedDominatorDiff {
  SnapshotMergedDominator? _a;
  SnapshotMergedDominator? _b;
  MergedDominatorDiff? parent;
  List<MergedDominatorDiff>? children;
  int retainedGain = -1;
  int retainedLoss = -1;
  int retainedCommon = -1;

  int get shallowSizeA => _a == null ? 0 : _a!.shallowSize;
  int get retainedSizeA => _a == null ? 0 : _a!.retainedSize;
  int get instanceCountA => _a == null ? 0 : _a!.instanceCount;

  int get shallowSizeB => _b == null ? 0 : _b!.shallowSize;
  int get retainedSizeB => _b == null ? 0 : _b!.retainedSize;
  int get instanceCountB => _b == null ? 0 : _b!.instanceCount;

  int get shallowSizeDiff => shallowSizeB - shallowSizeA;
  int get retainedSizeDiff => retainedSizeB - retainedSizeA;
  int get instanceCountDiff => instanceCountB - instanceCountA;

  String get name => _a == null ? _b!.klass.name : _a!.klass.name;

  List<SnapshotObject> get objectsA =>
      _a == null ? const <SnapshotObject>[] : _a!.objects.toList();
  List<SnapshotObject> get objectsB =>
      _b == null ? const <SnapshotObject>[] : _b!.objects.toList();

  static MergedDominatorDiff from(
      SnapshotMergedDominator a, SnapshotMergedDominator b) {
    var root = new MergedDominatorDiff();
    root._a = a;
    root._b = b;

    // We must use an explicit stack instead of the call stack because the
    // dominator tree can be arbitrarily deep. We need to compute the full
    // tree to compute areas, so we do this eagerly to avoid having to
    // repeatedly test for initialization.
    var worklist = <MergedDominatorDiff>[];
    worklist.add(root);
    // Compute children top-down.
    for (var i = 0; i < worklist.length; i++) {
      worklist[i]._computeChildren(worklist);
    }
    // Compute area botton-up.
    for (var i = worklist.length - 1; i >= 0; i--) {
      worklist[i]._computeArea();
    }

    return root;
  }

  void _computeChildren(List<MergedDominatorDiff> worklist) {
    assert(children == null);
    children = <MergedDominatorDiff>[];

    // Matching children by MergedObjectVertex.klass.qualifiedName.
    final childrenB = <String, SnapshotMergedDominator>{};
    if (_b != null)
      for (var childB in _b!.children) {
        childrenB[childB.klass.qualifiedName] = childB;
      }
    if (_a != null)
      for (var childA in _a!.children) {
        var childDiff = new MergedDominatorDiff();
        childDiff.parent = this;
        childDiff._a = childA;
        var qualifiedName = childA.klass.qualifiedName;
        var childB = childrenB[qualifiedName];
        if (childB != null) {
          childrenB.remove(qualifiedName);
          childDiff._b = childB;
        }
        children!.add(childDiff);
        worklist.add(childDiff);
      }
    for (var childB in childrenB.values) {
      var childDiff = new MergedDominatorDiff();
      childDiff.parent = this;
      childDiff._b = childB;
      children!.add(childDiff);
      worklist.add(childDiff);
    }

    if (children!.length == 0) {
      // Compress.
      children = const <MergedDominatorDiff>[];
    }
  }

  void _computeArea() {
    int g = 0;
    int l = 0;
    int c = 0;
    for (var child in children!) {
      g += child.retainedGain;
      l += child.retainedLoss;
      c += child.retainedCommon;
    }
    int d = shallowSizeDiff;
    if (d > 0) {
      g += d;
      c += shallowSizeA;
    } else {
      l -= d;
      c += shallowSizeB;
    }
    assert(retainedSizeA + g - l == retainedSizeB);
    retainedGain = g;
    retainedLoss = l;
    retainedCommon = c;
  }
}

class HeapSnapshotElement extends CustomElement implements Renderable {
  late RenderingScheduler<HeapSnapshotElement> _r;

  Stream<RenderedEvent<HeapSnapshotElement>> get onRendered => _r.onRendered;

  late M.VM _vm;
  late M.IsolateRef _isolate;
  late M.EventRepository _events;
  late M.NotificationRepository _notifications;
  late M.HeapSnapshotRepository _snapshots;
  late M.ObjectRepository _objects;
  SnapshotReader? _reader;
  String? _status;
  List<SnapshotGraph> _loadedSnapshots = <SnapshotGraph>[];
  SnapshotGraph? _snapshotA;
  SnapshotGraph? _snapshotB;
  HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.mergedDominatorTreeMap;
  M.IsolateRef get isolate => _isolate;
  M.NotificationRepository get notifications => _notifications;
  M.HeapSnapshotRepository get profiles => _snapshots;
  M.VMRef get vm => _vm;

  List<SnapshotObject>? selection;
  SnapshotMergedDominator? mergedSelection;
  MergedDominatorDiff? mergedDiffSelection;

  factory HeapSnapshotElement(
      M.VM vm,
      M.IsolateRef isolate,
      M.EventRepository events,
      M.NotificationRepository notifications,
      M.HeapSnapshotRepository snapshots,
      M.ObjectRepository objects,
      {RenderingQueue? queue}) {
    assert(vm != null);
    assert(isolate != null);
    assert(events != null);
    assert(notifications != null);
    assert(snapshots != null);
    assert(objects != null);
    HeapSnapshotElement e = new HeapSnapshotElement.created();
    e._r = new RenderingScheduler<HeapSnapshotElement>(e, queue: queue);
    e._vm = vm;
    e._isolate = isolate;
    e._events = events;
    e._notifications = notifications;
    e._snapshots = snapshots;
    e._objects = objects;
    return e;
  }

  HeapSnapshotElement.created() : super.created('heap-snapshot');

  @override
  attached() {
    super.attached();
    _r.enable();
    _refresh();
  }

  @override
  detached() {
    super.detached();
    _r.disable(notify: true);
    children = <Element>[];
  }

  void render() {
    final content = <Element>[
      navBar(<Element>[
        new NavTopMenuElement(queue: _r.queue).element,
        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
        navMenu('heap snapshot'),
        (new NavRefreshElement(queue: _r.queue)
              ..disabled = _reader != null
              ..onRefresh.listen((e) {
                _refresh();
              }))
            .element,
        (new NavRefreshElement(label: 'save', queue: _r.queue)
              ..disabled = _reader != null
              ..onRefresh.listen((e) {
                _save();
              }))
            .element,
        (new NavRefreshElement(label: 'load', queue: _r.queue)
              ..disabled = _reader != null
              ..onRefresh.listen((e) {
                _load();
              }))
            .element,
        new NavNotifyElement(_notifications, queue: _r.queue).element
      ]),
    ];
    if (_reader != null) {
      // Loading
      content.addAll(_createStatusMessage('Loading snapshot...',
          description: _status!, progress: 1));
    } else if (_snapshotA != null) {
      // Loaded
      content.addAll(_createReport());
    }
    children = content;
  }

  _refresh() {
    _reader = null;
    _snapshotLoading(_snapshots.get(isolate));
  }

  _save() {
    var blob = new Blob(_snapshotA!.chunks, 'application/octet-stream');
    var blobUrl = Url.createObjectUrl(blob);
    var link = new AnchorElement();
    // ignore: unsafe_html
    link.href = blobUrl;
    var now = new DateTime.now();
    link.download = 'dart-heap-${now.year}-${now.month}-${now.day}.bin';
    link.click();
  }

  _load() {
    var input = new InputElement();
    input.type = 'file';
    input.multiple = false;
    input.onChange.listen((event) {
      var file = input.files![0];
      var reader = new FileReader();
      reader.onLoad.listen((event) async {
        var encoded = <Uint8List>[reader.result as Uint8List];
        var snapshotReader = new SnapshotReader();
        _snapshotLoading(snapshotReader);
        snapshotReader.add(reader.result as Uint8List);
        snapshotReader.close();
      });
      reader.readAsArrayBuffer(file);
    });
    input.click();
  }

  _snapshotLoading(SnapshotReader reader) async {
    _status = '';
    _reader = reader;
    reader.onProgress.listen((String status) {
      _status = status;
      _r.dirty();
    });
    _snapshotLoaded(await reader.done);
  }

  _snapshotLoaded(SnapshotGraph snapshot) {
    _reader = null;
    _loadedSnapshots.add(snapshot);
    _snapshotA = snapshot;
    _snapshotB = snapshot;
    selection = null;
    mergedSelection = null;
    mergedDiffSelection = null;
    _r.dirty();
  }

  static List<Element> _createStatusMessage(String message,
      {String description: '', double progress: 0.0}) {
    return [
      new DivElement()
        ..classes = ['content-centered-big']
        ..children = <Element>[
          new DivElement()
            ..classes = ['statusBox', 'shadow', 'center']
            ..children = <Element>[
              new DivElement()
                ..classes = ['statusMessage']
                ..text = message,
              new DivElement()
                ..classes = ['statusDescription']
                ..text = description,
              new DivElement()
                ..style.background = '#0489c3'
                ..style.width = '$progress%'
                ..style.height = '15px'
                ..style.borderRadius = '4px'
            ]
        ]
    ];
  }

  VirtualTreeElement? _tree;

  void _createTreeMap<T>(List<HtmlElement> report, TreeMap<T> treemap, T root) {
    final content = new DivElement();
    content.style.border = '1px solid black';
    content.style.width = '100%';
    content.style.height = '100%';
    content.text = 'Performing layout...';
    Timer.run(() {
      // Generate the treemap after the content div has been added to the
      // document so that we can ask the browser how much space is
      // available for treemap layout.
      treemap.showIn(root, content);
    });

    final text =
        'Double-click a tile to zoom in. Double-click the outermost tile to zoom out. Right-click a tile to inspect its objects.';
    report.addAll([
      new DivElement()
        ..classes = ['content-centered-big', 'explanation']
        ..text = text,
      new DivElement()
        ..classes = ['content-centered-big']
        ..style.width = '100%'
        ..style.height = '100%'
        ..children = [content]
    ]);
  }

  List<Element> _createReport() {
    var report = <HtmlElement>[
      new DivElement()
        ..classes = ['content-centered-big']
        ..children = <Element>[
          new DivElement()
            ..classes = ['memberList']
            ..children = <Element>[
              new DivElement()
                ..classes = ['memberItem']
                ..children = <Element>[
                  new DivElement()
                    ..classes = ['memberName']
                    ..text = 'Snapshot A',
                  new DivElement()
                    ..classes = ['memberName']
                    ..children = _createSnapshotSelectA()
                ],
              new DivElement()
                ..classes = ['memberItem']
                ..children = <Element>[
                  new DivElement()
                    ..classes = ['memberName']
                    ..text = 'Snapshot B',
                  new DivElement()
                    ..classes = ['memberName']
                    ..children = _createSnapshotSelectB()
                ],
              new DivElement()
                ..classes = ['memberItem']
                ..children = <Element>[
                  new DivElement()
                    ..classes = ['memberName']
                    ..text = (_snapshotA == _snapshotB) ? 'View ' : 'Compare ',
                  new DivElement()
                    ..classes = ['memberName']
                    ..children = _createModeSelect()
                ]
            ]
        ],
    ];
    switch (_mode) {
      case HeapSnapshotTreeMode.dominatorTree:
        if (selection == null) {
          selection = List.from(_snapshotA!.extendedRoot.objects);
        }
        _tree = new VirtualTreeElement(
            _createDominator, _updateDominator, _getChildrenDominator,
            items: selection!, queue: _r.queue);
        if (selection!.length == 1) {
          _tree!.expand(selection!.first);
        }
        final text = 'In a heap dominator tree, an object X is a parent of '
            'object Y if every path from the root to Y goes through '
            'X. This allows you to find "choke points" that are '
            'holding onto a lot of memory. If an object becomes '
            'garbage, all its children in the dominator tree become '
            'garbage as well.';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.dominatorTreeMap:
        if (selection == null) {
          selection = List.from(_snapshotA!.extendedRoot.objects);
        }
        _createTreeMap(report, new DominatorTreeMap(this), selection!.first);
        break;
      case HeapSnapshotTreeMode.mergedDominatorTree:
        _tree = new VirtualTreeElement(_createMergedDominator,
            _updateMergedDominator, _getChildrenMergedDominator,
            items: _getChildrenMergedDominator(_snapshotA!.extendedMergedRoot),
            queue: _r.queue);
        _tree!.expand(_snapshotA!.extendedMergedRoot);
        final text = 'A heap dominator tree, where siblings with the same class'
            ' have been merged into a single node.';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.mergedDominatorTreeDiff:
        var root = MergedDominatorDiff.from(
            _snapshotA!.mergedRoot, _snapshotB!.mergedRoot);
        _tree = new VirtualTreeElement(_createMergedDominatorDiff,
            _updateMergedDominatorDiff, _getChildrenMergedDominatorDiff,
            items: _getChildrenMergedDominatorDiff(root), queue: _r.queue);
        _tree!.expand(root);
        final text = 'A heap dominator tree, where siblings with the same class'
            ' have been merged into a single node.';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.mergedDominatorTreeMap:
        if (mergedSelection == null) {
          mergedSelection = _snapshotA!.extendedMergedRoot;
        }
        _createTreeMap(
            report, new MergedDominatorTreeMap(this), mergedSelection);
        break;
      case HeapSnapshotTreeMode.mergedDominatorTreeMapDiff:
        if (mergedDiffSelection == null) {
          mergedDiffSelection = MergedDominatorDiff.from(
              _snapshotA!.mergedRoot, _snapshotB!.mergedRoot);
        }
        _createTreeMap(
            report, new MergedDominatorDiffTreeMap(this), mergedDiffSelection);
        break;
      case HeapSnapshotTreeMode.ownershipTable:
        final items =
            _snapshotA!.classes.where((c) => c.ownedSize > 0).toList();
        items.sort((a, b) => b.ownedSize - a.ownedSize);
        _tree = new VirtualTreeElement(
            _createOwnership, _updateOwnership, _getChildrenOwnership,
            items: items, queue: _r.queue);
        _tree!.expand(_snapshotA!.root);
        final text = 'An object X is said to "own" object Y if X is the only '
            'object that references Y, or X owns the only object that '
            'references Y. In particular, objects "own" the space of any '
            'unshared lists or maps they reference.';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.ownershipTableDiff:
        final items = SnapshotClassDiff.from(_snapshotA!, _snapshotB!);
        items.sort((a, b) => b.ownedSizeB - a.ownedSizeB);
        items.sort((a, b) => b.ownedSizeA - a.ownedSizeA);
        items.sort((a, b) => b.ownedSizeDiff - a.ownedSizeDiff);
        _tree = new VirtualTreeElement(_createOwnershipDiff,
            _updateOwnershipDiff, _getChildrenOwnershipDiff,
            items: items, queue: _r.queue);
        _tree!.expand(_snapshotA!.root);
        final text = 'An object X is said to "own" object Y if X is the only '
            'object that references Y, or X owns the only object that '
            'references Y. In particular, objects "own" the space of any '
            'unshared lists or maps they reference.';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.ownershipTreeMap:
        _createTreeMap(
            report, new ClassesOwnershipTreeMap(this, _snapshotA!), null);
        break;
      case HeapSnapshotTreeMode.ownershipTreeMapDiff:
        final items = SnapshotClassDiff.from(_snapshotA!, _snapshotB!);
        _createTreeMap(
            report, new ClassesOwnershipDiffTreeMap(this, items), null);
        break;
      case HeapSnapshotTreeMode.successors:
        if (selection == null) {
          selection = List.from(_snapshotA!.root.objects);
        }
        _tree = new VirtualTreeElement(
            _createSuccessor, _updateSuccessor, _getChildrenSuccessor,
            items: selection!, queue: _r.queue);
        if (selection!.length == 1) {
          _tree!.expand(selection!.first);
        }
        final text = '';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.predecessors:
        if (selection == null) {
          selection = List.from(_snapshotA!.root.objects);
        }
        _tree = new VirtualTreeElement(
            _createPredecessor, _updatePredecessor, _getChildrenPredecessor,
            items: selection!, queue: _r.queue);
        if (selection!.length == 1) {
          _tree!.expand(selection!.first);
        }
        final text = '';
        report.addAll([
          new DivElement()
            ..classes = ['content-centered-big', 'explanation']
            ..text = text,
          _tree!.element
        ]);
        break;
      case HeapSnapshotTreeMode.classesTable:
        final items = _snapshotA!.classes.toList();
        items.sort((a, b) => b.shallowSize - a.shallowSize);
        _tree = new VirtualTreeElement(
            _createClass, _updateClass, _getChildrenClass,
            items: items, queue: _r.queue);
        report.add(_tree!.element);
        break;
      case HeapSnapshotTreeMode.classesTableDiff:
        final items = SnapshotClassDiff.from(_snapshotA!, _snapshotB!);
        items.sort((a, b) => b.shallowSizeB - a.shallowSizeB);
        items.sort((a, b) => b.shallowSizeA - a.shallowSizeA);
        items.sort((a, b) => b.shallowSizeDiff - a.shallowSizeDiff);
        _tree = new VirtualTreeElement(
            _createClassDiff, _updateClassDiff, _getChildrenClassDiff,
            items: items, queue: _r.queue);
        report.add(_tree!.element);
        break;
      case HeapSnapshotTreeMode.classesTreeMap:
        _createTreeMap(
            report, new ClassesShallowTreeMap(this, _snapshotA!), null);
        break;

      case HeapSnapshotTreeMode.classesTreeMapDiff:
        final items = SnapshotClassDiff.from(_snapshotA!, _snapshotB!);
        _createTreeMap(
            report, new ClassesShallowDiffTreeMap(this, items), null);
        break;
      default:
        break;
    }
    return report;
  }

  static HtmlElement _createDominator(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap being retained',
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size',
        new SpanElement()..classes = ['lines'],
        new ButtonElement()
          ..classes = ['expander']
          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
        new SpanElement()..classes = ['name'],
        new AnchorElement()
          ..classes = ['link']
          ..text = "[inspect]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[incoming]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[dominator-map]",
      ];
  }

  static HtmlElement _createSuccessor(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()..classes = ['lines'],
        new ButtonElement()
          ..classes = ['expander']
          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size',
        new SpanElement()
          ..classes = ['edge']
          ..title = 'name of outgoing field',
        new SpanElement()..classes = ['name'],
        new AnchorElement()
          ..classes = ['link']
          ..text = "[incoming]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[dominator-tree]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[dominator-map]",
      ];
  }

  static HtmlElement _createPredecessor(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()..classes = ['lines'],
        new ButtonElement()
          ..classes = ['expander']
          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size',
        new SpanElement()
          ..classes = ['edge']
          ..title = 'name of incoming field',
        new SpanElement()..classes = ['name'],
        new SpanElement()
          ..classes = ['link']
          ..text = "[inspect]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[dominator-tree]",
        new AnchorElement()
          ..classes = ['link']
          ..text = "[dominator-map]",
      ];
  }

  static HtmlElement _createMergedDominator(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap being retained',
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size',
        new SpanElement()..classes = ['lines'],
        new ButtonElement()
          ..classes = ['expander']
          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
        new SpanElement()..classes = ['name']
      ];
  }

  static HtmlElement _createMergedDominatorDiff(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap being retained',
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size A',
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap being retained',
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size B',
        new SpanElement()
          ..classes = ['size']
          ..title = 'retained size change',
        new SpanElement()..classes = ['lines'],
        new ButtonElement()
          ..classes = ['expander']
          ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
        new SpanElement()..classes = ['name']
      ];
  }

  static HtmlElement _createOwnership(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap owned',
        new SpanElement()
          ..classes = ['size']
          ..title = 'owned size',
        new SpanElement()..classes = ['name']
      ];
  }

  static HtmlElement _createOwnershipDiff(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap owned A',
        new SpanElement()
          ..classes = ['size']
          ..title = 'owned size A',
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap owned B',
        new SpanElement()
          ..classes = ['size']
          ..title = 'owned size B',
        new SpanElement()
          ..classes = ['size']
          ..title = 'owned size change',
        new SpanElement()..classes = ['name']
      ];
  }

  static HtmlElement _createClass(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['percentage']
          ..title = 'percentage of heap owned',
        new SpanElement()
          ..classes = ['size']
          ..title = 'shallow size',
        new SpanElement()
          ..classes = ['size']
          ..title = 'instance count',
        new SpanElement()..classes = ['name']
      ];
  }

  static HtmlElement _createClassDiff(toggle) {
    return new DivElement()
      ..classes = ['tree-item']
      ..children = <Element>[
        new SpanElement()
          ..classes = ['size']
          ..title = 'shallow size A',
        new SpanElement()
          ..classes = ['size']
          ..title = 'instance count A',
        new SpanElement()
          ..classes = ['size']
          ..title = 'shallow size B',
        new SpanElement()
          ..classes = ['size']
          ..title = 'instance count B',
        new SpanElement()
          ..classes = ['size']
          ..title = 'shallow size diff',
        new SpanElement()
          ..classes = ['size']
          ..title = 'instance count diff',
        new SpanElement()..classes = ['name']
      ];
  }

  static const int kMaxChildren = 100;
  static const int kMinRetainedSize = 4096;

  static Iterable _getChildrenDominator(nodeDynamic) {
    SnapshotObject node = nodeDynamic;
    final list = node.children
        .where((child) => child.retainedSize >= kMinRetainedSize)
        .toList();
    list.sort((a, b) => b.retainedSize - a.retainedSize);
    return list.take(kMaxChildren).toList();
  }

  static Iterable _getChildrenSuccessor(nodeDynamic) {
    SnapshotObject node = nodeDynamic;
    return node.successors.toList();
  }

  static Iterable _getChildrenPredecessor(nodeDynamic) {
    SnapshotObject node = nodeDynamic;
    return node.predecessors.take(kMaxChildren).toList();
  }

  static Iterable _getChildrenMergedDominator(nodeDynamic) {
    SnapshotMergedDominator node = nodeDynamic;
    final list = node.children
        .where((child) => child.retainedSize >= kMinRetainedSize)
        .toList();
    list.sort((a, b) => b.retainedSize - a.retainedSize);
    return list.take(kMaxChildren).toList();
  }

  static Iterable _getChildrenMergedDominatorDiff(nodeDynamic) {
    MergedDominatorDiff node = nodeDynamic;
    final list = node.children!
        .where((child) =>
            child.retainedSizeA >= kMinRetainedSize ||
            child.retainedSizeB >= kMinRetainedSize)
        .toList();
    list.sort((a, b) => b.retainedSizeDiff - a.retainedSizeDiff);
    return list.take(kMaxChildren).toList();
  }

  static Iterable _getChildrenOwnership(item) {
    return const [];
  }

  static Iterable _getChildrenOwnershipDiff(item) {
    return const [];
  }

  static Iterable _getChildrenClass(item) {
    return const [];
  }

  static Iterable _getChildrenClassDiff(item) {
    return const [];
  }

  void _updateDominator(HtmlElement element, nodeDynamic, int depth) {
    SnapshotObject node = nodeDynamic;
    element.children[0].text = Utils.formatPercentNormalized(
        node.retainedSize * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.retainedSize);
    _updateLines(element.children[2].children, depth);
    if (_getChildrenDominator(node).isNotEmpty) {
      element.children[3].text = _tree!.isExpanded(node) ? '▼' : '►';
    } else {
      element.children[3].text = '';
    }
    element.children[4].text = node.description;
    element.children[5].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.successors;
      _r.dirty();
    });
    element.children[6].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.predecessors;
      _r.dirty();
    });
    element.children[7].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
      _r.dirty();
    });
  }

  void _updateSuccessor(HtmlElement element, nodeDynamic, int depth) {
    SnapshotObject node = nodeDynamic;
    _updateLines(element.children[0].children, depth);
    if (_getChildrenSuccessor(node).isNotEmpty) {
      element.children[1].text = _tree!.isExpanded(node) ? '▼' : '►';
    } else {
      element.children[1].text = '';
    }
    element.children[2].text = Utils.formatSize(node.retainedSize);
    element.children[3].text = node.label;
    element.children[4].text = node.description;
    element.children[5].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.predecessors;
      _r.dirty();
    });
    element.children[6].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.dominatorTree;
      _r.dirty();
    });
    element.children[7].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
      _r.dirty();
    });
  }

  void _updatePredecessor(HtmlElement element, nodeDynamic, int depth) {
    SnapshotObject node = nodeDynamic;
    _updateLines(element.children[0].children, depth);
    if (_getChildrenSuccessor(node).isNotEmpty) {
      element.children[1].text = _tree!.isExpanded(node) ? '▼' : '►';
    } else {
      element.children[1].text = '';
    }
    element.children[2].text = Utils.formatSize(node.retainedSize);
    element.children[3].text = node.label;
    element.children[4].text = node.description;
    element.children[5].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.successors;
      _r.dirty();
    });
    element.children[6].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.dominatorTree;
      _r.dirty();
    });
    element.children[7].onClick.listen((_) {
      selection = List.from(node.objects);
      _mode = HeapSnapshotTreeMode.dominatorTreeMap;
      _r.dirty();
    });
  }

  void _updateMergedDominator(HtmlElement element, nodeDynamic, int depth) {
    SnapshotMergedDominator node = nodeDynamic;
    element.children[0].text = Utils.formatPercentNormalized(
        node.retainedSize * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.retainedSize);
    _updateLines(element.children[2].children, depth);
    if (_getChildrenMergedDominator(node).isNotEmpty) {
      element.children[3].text = _tree!.isExpanded(node) ? '▼' : '►';
    } else {
      element.children[3].text = '';
    }
    element.children[4]
      ..text = '${node.instanceCount} instances of ${node.klass.name}';
  }

  void _updateMergedDominatorDiff(HtmlElement element, nodeDynamic, int depth) {
    MergedDominatorDiff node = nodeDynamic;
    element.children[0].text = Utils.formatPercentNormalized(
        node.retainedSizeA * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.retainedSizeA);
    element.children[2].text = Utils.formatPercentNormalized(
        node.retainedSizeB * 1.0 / _snapshotB!.size);
    element.children[3].text = Utils.formatSize(node.retainedSizeB);
    element.children[4].text = (node.retainedSizeDiff > 0 ? '+' : '') +
        Utils.formatSize(node.retainedSizeDiff);
    element.children[4].style.color =
        node.retainedSizeDiff > 0 ? "red" : "green";
    _updateLines(element.children[5].children, depth);
    if (_getChildrenMergedDominatorDiff(node).isNotEmpty) {
      element.children[6].text = _tree!.isExpanded(node) ? '▼' : '►';
    } else {
      element.children[6].text = '';
    }
    element.children[7]
      ..text =
          '${node.instanceCountA} → ${node.instanceCountB} instances of ${node.name}';
  }

  void _updateOwnership(HtmlElement element, nodeDynamic, int depth) {
    SnapshotClass node = nodeDynamic;
    element.children[0].text =
        Utils.formatPercentNormalized(node.ownedSize * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.ownedSize);
    element.children[2].text = node.name;
  }

  void _updateOwnershipDiff(HtmlElement element, nodeDynamic, int depth) {
    SnapshotClassDiff node = nodeDynamic;
    element.children[0].text =
        Utils.formatPercentNormalized(node.ownedSizeA * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.ownedSizeA);
    element.children[2].text =
        Utils.formatPercentNormalized(node.ownedSizeB * 1.0 / _snapshotB!.size);
    element.children[3].text = Utils.formatSize(node.ownedSizeB);
    element.children[4].text = (node.ownedSizeDiff > 0 ? "+" : "") +
        Utils.formatSize(node.ownedSizeDiff);
    element.children[4].style.color = node.ownedSizeDiff > 0 ? "red" : "green";
    element.children[5].text = node.name;
  }

  void _updateClass(HtmlElement element, nodeDynamic, int depth) {
    SnapshotClass node = nodeDynamic;
    element.children[0].text = Utils.formatPercentNormalized(
        node.shallowSize * 1.0 / _snapshotA!.size);
    element.children[1].text = Utils.formatSize(node.shallowSize);
    element.children[2].text = node.instanceCount.toString();
    element.children[3].text = node.name;
  }

  void _updateClassDiff(HtmlElement element, nodeDynamic, int depth) {
    SnapshotClassDiff node = nodeDynamic;
    element.children[0].text = Utils.formatSize(node.shallowSizeA);
    element.children[1].text = node.instanceCountA.toString();
    element.children[2].text = Utils.formatSize(node.shallowSizeB);
    element.children[3].text = node.instanceCountB.toString();
    element.children[4].text = (node.shallowSizeDiff > 0 ? "+" : "") +
        Utils.formatSize(node.shallowSizeDiff);
    element.children[4].style.color =
        node.shallowSizeDiff > 0 ? "red" : "green";
    element.children[5].text = (node.instanceCountDiff > 0 ? "+" : "") +
        node.instanceCountDiff.toString();
    element.children[5].style.color =
        node.instanceCountDiff > 0 ? "red" : "green";
    element.children[6].text = node.name;
  }

  static _updateLines(List<Element> lines, int n) {
    n = Math.max(0, n);
    while (lines.length > n) {
      lines.removeLast();
    }
    while (lines.length < n) {
      lines.add(new SpanElement());
    }
  }

  static String modeToString(HeapSnapshotTreeMode mode) {
    switch (mode) {
      case HeapSnapshotTreeMode.dominatorTree:
        return 'Dominators (tree)';
      case HeapSnapshotTreeMode.dominatorTreeMap:
        return 'Dominators (treemap)';
      case HeapSnapshotTreeMode.mergedDominatorTree:
      case HeapSnapshotTreeMode.mergedDominatorTreeDiff:
        return 'Dominators (tree, siblings merged by class)';
      case HeapSnapshotTreeMode.mergedDominatorTreeMap:
      case HeapSnapshotTreeMode.mergedDominatorTreeMapDiff:
        return 'Dominators (treemap, siblings merged by class)';
      case HeapSnapshotTreeMode.ownershipTable:
      case HeapSnapshotTreeMode.ownershipTableDiff:
        return 'Ownership (table)';
      case HeapSnapshotTreeMode.ownershipTreeMap:
      case HeapSnapshotTreeMode.ownershipTreeMapDiff:
        return 'Ownership (treemap)';
      case HeapSnapshotTreeMode.classesTable:
      case HeapSnapshotTreeMode.classesTableDiff:
        return 'Classes (table)';
      case HeapSnapshotTreeMode.classesTreeMap:
      case HeapSnapshotTreeMode.classesTreeMapDiff:
        return 'Classes (treemap)';
      case HeapSnapshotTreeMode.successors:
        return 'Successors / outgoing references';
      case HeapSnapshotTreeMode.predecessors:
        return 'Predecessors / incoming references';
    }
    throw new Exception('Unknown HeapSnapshotTreeMode: $mode');
  }

  List<Element> _createModeSelect() {
    var s;
    var modes = _snapshotA == _snapshotB ? viewModes : diffModes;
    if (!modes.contains(_mode)) {
      _mode = modes[0];
      _r.dirty();
    }
    return [
      s = new SelectElement()
        ..classes = ['analysis-select']
        ..value = modeToString(_mode)
        ..children = modes.map((mode) {
          return new OptionElement(
              value: modeToString(mode), selected: _mode == mode)
            ..text = modeToString(mode);
        }).toList(growable: false)
        ..onChange.listen((_) {
          _mode = modes[s.selectedIndex];
          _r.dirty();
        })
    ];
  }

  String snapshotToString(snapshot) {
    if (snapshot == null) return "None";
    return snapshot.description +
        " " +
        Utils.formatSize(snapshot.capacity + snapshot.externalSize);
  }

  List<Element> _createSnapshotSelectA() {
    var s;
    return [
      s = new SelectElement()
        ..classes = ['analysis-select']
        ..value = snapshotToString(_snapshotA)
        ..children = _loadedSnapshots.map((snapshot) {
          return new OptionElement(
              value: snapshotToString(snapshot),
              selected: _snapshotA == snapshot)
            ..text = snapshotToString(snapshot);
        }).toList(growable: false)
        ..onChange.listen((_) {
          _snapshotA = _loadedSnapshots[s.selectedIndex];
          selection = null;
          mergedSelection = null;
          mergedDiffSelection = null;
          _r.dirty();
        })
    ];
  }

  List<Element> _createSnapshotSelectB() {
    var s;
    return [
      s = new SelectElement()
        ..classes = ['analysis-select']
        ..value = snapshotToString(_snapshotB)
        ..children = _loadedSnapshots.map((snapshot) {
          return new OptionElement(
              value: snapshotToString(snapshot),
              selected: _snapshotB == snapshot)
            ..text = snapshotToString(snapshot);
        }).toList(growable: false)
        ..onChange.listen((_) {
          _snapshotB = _loadedSnapshots[s.selectedIndex];
          selection = null;
          mergedSelection = null;
          mergedDiffSelection = null;
          _r.dirty();
        })
    ];
  }
}
