throws Throwable
  public Value range(Env env,                     @ReadOnly Value start,                     @ReadOnly Value end,                     @Optional("1") long step)    throws Throwable  {    if (step < 1)      step = 1;    if (!start.getType().equals(end.getType())) {      start = LongValue.create(start.toLong());      end = LongValue.create(end.toLong());    }    else if (Character.isDigit(start.toChar())) {      start = LongValue.create(start.toLong());      end = LongValue.create(end.toLong());    }    else {      start = rangeIncrement(start, 0);      end = rangeIncrement(end, 0);    }    if (start.eq(end)) {    }    else if (start instanceof StringValue &&             (Math.abs(end.toChar() - start.toChar()) < step)) {      env.warning("steps exceeds the specified range");      return BooleanValue.FALSE;    }    else if (start instanceof LongValue &&             (Math.abs(end.toLong() - start.toLong()) < step)) {      env.warning("steps exceeds the specified range");      return BooleanValue.FALSE;    }    boolean increment = true;    if (! end.geq(start)) {      step *= -1;      increment = false;    }    ArrayValue array = new ArrayValueImpl();    do {      array.put(start);      start = rangeIncrement(start, step);    } while ((increment && start.leq(end)) ||             (!increment && start.geq(end)));    return array;  }