private static Animation CreateAnimationOfOperations(Interval renderInterval, Interval targetInterval, params Operation[] operations)
        {
            var keyNodes = new Dictionary<int, Tuple<NestingDepthTreeNode, Interval, NestingDepthTreeNode>>();
            var activeOperation = default(Operation);

            var dt = 1.0;
            var ani = new Animation();

            ani.Add(new TextDesc("Using a Tree to Track Referenced Intervals", new Point(250, 5), new Point(0, 0), fontSize:20));
            ani.Add(new TextDesc("Referenced" + Environment.NewLine + "Intervals", new Point(10, 80)));
            ani.Add(new TextDesc("Tree", new Point(10, 220)));
            ani.Add(new TextDesc("Nesting" + Environment.NewLine + "Depth", new Point(10, 350)));
            ani.Add(new LineSegmentDesc(new Point(0, 30).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(0, 100).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(0, 300).Sweep(new Vector(10000, 0)), Brushes.Black, 1));
            ani.Add(new LineSegmentDesc(new Point(75, 0).Sweep(new Vector(0, 10000)), Brushes.Black, 1));

            var i = 0.0;
            var dealloced = new HashSet<int>();
            for (var i2 = 0; i2 < renderInterval.Length; i2++) {
                if (i2 + renderInterval.Offset < targetInterval.Offset || i2 + renderInterval.Offset >= targetInterval.Offset + targetInterval.Length) {
                    dealloced.Add(i2 + renderInterval.Offset);
                }
            }
            var x = 100;
            var y = 90;
            Func<double, Animation> addFrame = focus => {
                var roots = keyNodes.Select(e => NestingDepthTreeNode.RootOf(e.Value.Item1)).Distinct().ToArray();

                var a = new Animation();

                var s = 10;
                if (!double.IsNaN(focus) && !double.IsInfinity(focus)) {
                    var dx = focus - renderInterval.Offset;
                    a.Add(new LineSegmentDesc(new LineSegment(new Point(x + dx*s, 0), new Point(x + dx*s, 10000)), activeOperation.Interval.HasValue ? Brushes.Green : Brushes.Red, 1, 1.0));
                }

                foreach (var r in roots) a.Add(RenderTree(renderInterval, r, dealloced));
                ani.LimitedNewTime(i.Seconds(), (i + dt).Seconds()).Add(a);
                i += dt;

                var bb = 0;
                foreach (var e in keyNodes) {
                    Brush brush;
                    if (e.Key == activeOperation.Key && !double.IsInfinity(focus)) {
                        brush = activeOperation.Interval.HasValue ? Brushes.Green : Brushes.Red;
                    } else {
                        brush = Brushes.Yellow;
                    }
                    var inv = e.Value.Item2;
                    var dx = inv.Offset - renderInterval.Offset;
                    a.Add(new RectDesc(new Rect(x + dx * s, y - (bb+1) * s*1.1, s*inv.Length, s), fill: brush, stroke: Brushes.Black, strokeThickness: 1));

                    bb += 1;
                }

                return a;
            };

            foreach (var e in operations) {
                activeOperation = e;
                var affectedRoot =
                    e.Interval.HasValue ?
                    keyNodes.Select(n => NestingDepthTreeNode.RootOf(n.Value.Item1)).FirstOrDefault(n => NestingDepthTreeNode.GetInterval(n).Overlaps(e.Interval.Value))
                    : NestingDepthTreeNode.RootOf(keyNodes[e.Key].Item1);

                if (e.Interval.HasValue) {
                    keyNodes.Add(e.Key, Tuple.Create((NestingDepthTreeNode)null, e.Interval.Value, (NestingDepthTreeNode)null));

                    addFrame(double.NaN);
                    addFrame(e.Interval.Value.Offset);

                    var a1 = NestingDepthTreeNode.Include(affectedRoot, e.Interval.Value.Offset, +1, +1);
                    a1.AdjustedNode._fakeRefCount += 2;
                    keyNodes[e.Key] = Tuple.Create(a1.AdjustedNode, e.Interval.Value, (NestingDepthTreeNode)null);
                    addFrame(e.Interval.Value.Offset);

                    addFrame(e.Interval.Value.Offset + e.Interval.Value.Length);
                    var a2 = NestingDepthTreeNode.Include(a1.NewRoot, e.Interval.Value.Offset + e.Interval.Value.Length, -1, +1);
                    a2.AdjustedNode._fakeRefCount += 2;
                    keyNodes[e.Key] = Tuple.Create(a1.AdjustedNode, e.Interval.Value, a2.AdjustedNode);

                    addFrame(e.Interval.Value.Offset + e.Interval.Value.Length);
                    addFrame(double.PositiveInfinity);
                }
                else {
                    var xs = keyNodes[e.Key];

                    var r = NestingDepthTreeNode.RootOf(xs.Item1);
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, +1, 0).NewRoot;
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset, -1, 0).NewRoot;
                    var hh = new HashSet<int>();
                    foreach (var ex in NestingDepthTreeNode.FindHolesIn(NestingDepthTreeNode.GetInterval(r), r)) {
                        for (var ii = ex.Offset; ii < ex.Offset + ex.Length; ii++) {
                            hh.Add(ii);
                        }
                    }
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, -1, 0).NewRoot;
                    r = NestingDepthTreeNode.Include(r, xs.Item2.Offset, +1, 0).NewRoot;

                    xs.Item3._fakeRefCount -= 1;
                    xs.Item3._fakeRefCount -= 1;
                    xs.Item1._fakeRefCount -= 1;
                    addFrame(xs.Item2.Offset + xs.Item2.Length);
                    var r1 = NestingDepthTreeNode.Include(r, xs.Item2.Offset + xs.Item2.Length, +1, -1);
                    addFrame(xs.Item2.Offset + xs.Item2.Length);

                    xs.Item1._fakeRefCount -= 1;
                    addFrame(xs.Item2.Offset);
                    var r2 = NestingDepthTreeNode.Include(r1.NewRoot, xs.Item2.Offset, -1, -1);
                    keyNodes.Remove(e.Key);
                    addFrame(double.NaN);

                    foreach (var xxx in hh) {
                        dealloced.Add(xxx);
                    }

                    NestingDepthTreeNode.PartitionAroundHoles(r2.NewRoot);

                    addFrame(double.NaN);
                }
            }

            var xx = new Animation();
            xx.Periodic(i.Seconds()).Add(ani);
            return xx;
        }