divide(BigInteger.make(x), BigInteger.make(y),
divide(valueOf(x), valueOf(y),
  private static void divide(long x, long y,			     BigInteger quotient, BigInteger remainder,			     int rounding_mode)  {    boolean xNegative, yNegative;    if (x < 0)      {	xNegative = true;	if (x == Long.MIN_VALUE)	  {	    divide(BigInteger.make(x), BigInteger.make(y),		   quotient, remainder, rounding_mode);	    return;	  }	x = -x;      }    else      xNegative = false;    if (y < 0)      {	yNegative = true;	if (y == Long.MIN_VALUE)	  {	    if (rounding_mode == TRUNCATE)	      { // x != Long.Min_VALUE implies abs(x) < abs(y)		if (quotient != null)		  quotient.set(0);		if (remainder != null)		  remainder.set(x);	      }	    else	      divide(BigInteger.make(x), BigInteger.make(y),		      quotient, remainder, rounding_mode);	    return;	  }	y = -y;      }    else      yNegative = false;    long q = x / y;    long r = x % y;    boolean qNegative = xNegative ^ yNegative;    boolean add_one = false;    if (r != 0)      {	switch (rounding_mode)	  {	  case TRUNCATE:	    break;	  case CEILING:	  case FLOOR:	    if (qNegative == (rounding_mode == FLOOR))	      add_one = true;	    break;	  case ROUND:	    add_one = r > ((y - (q & 1)) >> 1);	    break;	  }      }    if (quotient != null)      {	if (add_one)	  q++;	if (qNegative)	  q = -q;	quotient.set(q);      }    if (remainder != null)      {	// The remainder is by definition: X-Q*Y	if (add_one)	  {	    // Subtract the remainder from Y.	    r = y - r;	    // In this case, abs(Q*Y) > abs(X).	    // So sign(remainder) = -sign(X).	    xNegative = ! xNegative;	  }	else	  {	    // If !add_one, then: abs(Q*Y) <= abs(X).	    // So sign(remainder) = sign(X).	  }	if (xNegative)	  r = -r;	remainder.set(r);      }  }