public LispNumber     mul    (LispValue  args)
  {
    BigInteger product     = this.getBigIntegerValue();
    LispNumber term;
    LispValue arglist;

    // Make sure the argument is a list of numbers.
    arglist = args;
    if (! (arglist instanceof LispList))
      arglist = list(arglist);

    while (arglist != NIL)
    {
      term = assertNumber(car(arglist));

      // If a term is a float, we need to convert the
      // pending result to a LispReal and multiply the rest of
      // the numbers as reals.
      if (term instanceof LispReal)
      {
        // Do we print a warning?
        LispReal realValue = real(this.getDoubleValue());
        return realValue.mul(arglist);
      }

      if (term instanceof LispBignum)
      {
        //System.out.print("Bignum: multiplying " + this + " by Bignum " + ((LispBignum)term).getBigIntegerValue());
        product = product.multiply(((LispBignum)term).getBigIntegerValue());
        //System.out.println(", producing " + product);
      }
      else // (term instanceof LispInteger)
      {
        //System.out.print("Bignum: multiplying " + this + " by Integer " + ((LispInteger)term).getLongValue());
        product = product.multiply(BigInteger.valueOf(((LispInteger)term).getLongValue()));
        //System.out.println(", producing " + product);
      }

      arglist = cdr(arglist);
    };

    if ((product.compareTo(MAXINT) <= 0)    // If LispInteger size...
            && (product.compareTo(MININT) >= 0))
      return (integer(product.longValue()));
    else
      return (bignum(product));
  }