/// <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 = new AvlNode <T> (min.Value, left, newgt);
         return(newroot.FixRootBalance());
     }
     else
     {
         AvlNode <T> max;
         var         newlt   = left.RemoveMax(out max);
         var         newroot = new AvlNode <T> (max.Value, newlt, right);
         return(newroot.FixRootBalance());
     }
 }
 AvlNode <T> RemoveMax(out AvlNode <T> max)
 {
     if (IsEmpty)
     {
         max = Empty;
         return(Empty);
     }
     if (right.IsEmpty)
     {
         //We are the max:
         max = this;
         return(left);
     }
     else
     {
         //Go down:
         var newgt   = right.RemoveMax(out max);
         var newroot = new AvlNode <T> (Value, left, newgt);
         return(newroot.FixRootBalance());
     }
 }