private static void PruneBrainLinks_Remove(TriangleIndexed triangle, TriangleEdge edge, List<Tuple<int[], int[]>> links)
            {
                int index1 = triangle.GetIndex(edge, true);
                int index2 = triangle.GetIndex(edge, false);

                Tuple<int[], int[]> existing = null;
                bool? is1in1 = null;

                // Find and remove the link that contains this edge
                for (int cntr = 0; cntr < links.Count; cntr++)
                {
                    if (links[cntr].Item1.Contains(index1) && links[cntr].Item2.Contains(index2))
                    {
                        is1in1 = true;
                    }
                    else if (links[cntr].Item1.Contains(index2) && links[cntr].Item2.Contains(index1))
                    {
                        is1in1 = false;
                    }
                    else
                    {
                        continue;
                    }

                    existing = links[cntr];
                    links.RemoveAt(cntr);
                    break;
                }

                if (existing == null)
                {
                    //throw new ArgumentException("Didn't find the link");

                    // A neighbor triangle probably removed it
                    return;
                }

                // Add back if there were more than 2 involved
                if (existing.Item1.Length == 1 && existing.Item2.Length == 1)
                {
                    // This link only holds one item on each side.  It's already removed from the list, so there is nothing left to do
                    return;
                }

                int[] newItem1 = PruneBrainLinks_Remove_Reduce(existing.Item1, index1, index2, is1in1.Value);
                int[] newItem2 = PruneBrainLinks_Remove_Reduce(existing.Item2, index2, index1, is1in1.Value);

                links.Add(Tuple.Create(newItem1, newItem2));
            }
            private static void PruneBrainLinks_Merge(TriangleIndexed triangle, TriangleEdge edge, List<Tuple<int[], int[]>> links)
            {
                // Figure out which indexes to look for
                int[] pair = new[] { triangle.GetIndex(edge, true), triangle.GetIndex(edge, false) };
                int other = triangle.IndexArray.First(o => !pair.Contains(o));

                // Extract the affected links out of the list
                List<Tuple<int[], int[]>> affected = new List<Tuple<int[], int[]>>();

                int index = 0;
                while (index < links.Count)
                {
                    var current = links[index];

                    if (current.Item1.Contains(other) && current.Item2.Any(o => pair.Contains(o)))
                    {
                        affected.Add(current);
                        links.RemoveAt(index);
                    }
                    else if (current.Item2.Contains(other) && current.Item1.Any(o => pair.Contains(o)))
                    {
                        affected.Add(Tuple.Create(current.Item2, current.Item1));       // reversing them so that Item1 is always other
                        links.RemoveAt(index);
                    }
                    else
                    {
                        index++;
                    }
                }

                // Combine the affected links (there shouldn't be more than two)
                var merged = Tuple.Create(
                    affected.SelectMany(o => o.Item1).Distinct().ToArray(),
                    affected.SelectMany(o => o.Item2).Distinct().ToArray());

                links.Add(merged);
            }