public void writeBigInteger(BigInteger v)
                       throws IOException {
    if (trace == API_TRACE_DETAILED) {
      Log.current.println("writeBigInteger = " + v);
    }

    // If the absolute value of the BigInteger is less than 2^31, it can to be
    // transmitted as a CFASL Fixnum.  Why do we use v.abs().bitLength()
    // instead of just v.bitLength()?  There is exactly 1 case that is
    // different: -2^31 has a bitLength of 31 while 2^31 has a bitLength of 32.
    if (v.abs().bitLength() < 32) {
      writeFixnum(v.intValue());

      return;
    }

    // Determine the sign, transmit the opcode, and take the absolute value
    if (v.signum() < 0) {
      write(CFASL_N_BIGNUM);
      v = v.abs();
    }
    else {
      write(CFASL_P_BIGNUM);
    }

    // Convert the number to an array of bytes in big-endian order (MSB at 0)
    byte[] parts = v.toByteArray();


    // Transmit the size of the Bignum
    writeFixnum(parts.length);

    // Transmit the bytes of the Bignum in little-endian order (LSB first)
    for (int i = parts.length - 1; i >= 0; i--) {
      // Log.current.println("b\t" + (parts[i] & 0x00FF));
      // It sure seems dumb to send each byte as a fixnum instead of as
      // a raw byte.  But that is the way the CFASL protocol was written.
      writeFixnum(parts[i] & 0x00FF);
    }
  }