/*
 * call-seq:
 *   node.swap(another_node) => Node
 *
 * Swap one node with another.  Both nodes must respond to the #swap
 * method.  Returns the receiver.
 */
static VALUE node_swap(VALUE self, VALUE other)
{
  NODE * n1;
  NODE * n2;
  NODE tmp;

  if(!rb_obj_respond_to(other, rb_intern("swap"), 0))
  {
    rb_raise(rb_eArgError, "Argument must respond to #swap");
  }

  if(   ruby_safe_level >= 4
     || (ruby_safe_level >= 1 && (OBJ_TAINTED(other) || OBJ_TAINTED(self))))
  {
    /* no playing with knives in the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't swap node");
  }

  Data_Get_Struct(self, NODE, n1);
  Data_Get_Struct(other, NODE, n2);

  tmp = *n1;
  *n1 = *n2;
  *n2 = tmp;

  return self;
}