/// <summary>
 /// Return a new dict with the root key-value pair removed
 /// </summary>
 AvlNode <T> RemoveRoot()
 {
     if (IsEmpty)
     {
         return(this);
     }
     if (_left.IsEmpty)
     {
         return(_right);
     }
     if (_right.IsEmpty)
     {
         return(_left);
     }
     //Neither are empty:
     if (_left._count < _right._count)
     {
         //LTDict has fewer, so promote from GTDict to minimize depth
         AvlNode <T> min;
         var         newGt   = _right.RemoveMin(out min);
         var         newRoot = NewOrMutate(min.Value, _left, newGt);
         return(newRoot.FixRootBalance());
     }
     else
     {
         AvlNode <T> max;
         var         newLt   = _left.RemoveMax(out max);
         var         newRoot = NewOrMutate(max.Value, newLt, _right);
         return(newRoot.FixRootBalance());
     }
 }
        AvlNode <T> RemoveMin(out AvlNode <T> min)
        {
            if (IsEmpty)
            {
                min = Empty;
                return(Empty);
            }
            if (_left.IsEmpty)
            {
                //We are the minimum:
                min = this;
                return(_right);
            }
            //Go down:
            var newLt   = _left.RemoveMin(out min);
            var newRoot = NewOrMutate(Value, newLt, _right);

            return(newRoot.FixRootBalance());
        }