/// <summary>
            /// This finds brains that are really close together, and turns them into sets (the rest of the brains become 1 item sets)
            /// </summary>
            internal static Set2D[] IOLinks_PreMergeBrains(Item2D[] brains, SortedList<Tuple<int, int>, double> links)
            {
                if (!IOPREMERGE_SHOULD)
                {
                    return Enumerable.Range(0, brains.Length).Select(o => new Set2D(o, brains)).ToArray();
                }

                // Get the AABB of the brains, and use the diagonal as the size
                var aabb = Math2D.GetAABB(brains.Select(o => o.Position));
                double maxDistance = (aabb.Item2 - aabb.Item1).Length;

                // Figure out the max distance allowed for a merge
                double threshold = maxDistance * IOPREMERGE_DISTANCE;

                // Find links that should be merged
                var closePairs = links.
                    Where(o => o.Value <= threshold).
                    OrderBy(o => o.Value).
                    ToArray();

                if (closePairs.Length == 0)
                {
                    return Enumerable.Range(0, brains.Length).Select(o => new Set2D(o, brains)).ToArray();
                }

                // Combine any close pairs that share a point (turn pairs into triples)
                List<List<int>> sets = IOLinks_PreMergeBrains_Sets(closePairs);

                // Build the final list
                return IOLinks_PreMergeBrains_Centers(sets, brains, links);
            }
            /// <summary>
            /// Link brains to each other (delaunay graph, then prune thin triangles)
            /// </summary>
            internal static void BrainLinks(out SortedList<Tuple<int, int>, double> all, out LinkBrain2D[] pruned, Item2D[] brains)
            {
                if (brains.Length < 2)
                {
                    throw new ArgumentException("This method requires at least two brains: " + brains.Length.ToString());
                }
                else if (brains.Length == 2)
                {
                    all = GetLengths(new[] { Tuple.Create(0, 1) }, brains);
                    pruned = all.Keys.Select(o => new LinkBrain2D(o.Item1, o.Item2, brains)).ToArray();
                    return;
                }

                TriangleIndexed[] triangles = Math2D.GetDelaunayTriangulation(brains.Select(o => o.Position).ToArray(), brains.Select(o => o.Position.ToPoint3D()).ToArray());

                all = GetLengths(TriangleIndexed.GetUniqueLines(triangles), brains);

                // Prune links that don't make sense
                pruned = PruneBrainLinks(triangles, all, brains);
            }