/** Inline */
  public Statement inline(Environment env, Context ctx) {
    ctx = new Context(ctx, this);
    cond = cond.inlineValue(env, ctx);

    // The compiler currently needs to perform inlining on both
    // branches of the if statement -- even if `cond' is a constant
    // true or false.  Why?  The compiler will later try to compile
    // all classes that it has seen; this includes classes that
    // appear in dead code.  If we don't inline the dead branch here
    // then the compiler will never perform inlining on any local
    // classes appearing on the dead code.  When the compiler tries
    // to compile an un-inlined local class with uplevel references,
    // it dies.  (bug 4059492)
    //
    // A better solution to this would be to walk the dead branch and
    // mark any local classes appearing therein as unneeded.  Then the
    // compilation phase could skip these classes.
    if (ifTrue != null) {
      ifTrue = ifTrue.inline(env, ctx);
    }
    if (ifFalse != null) {
      ifFalse = ifFalse.inline(env, ctx);
    }
    if (cond.equals(true)) {
      return eliminate(env, ifTrue);
    }
    if (cond.equals(false)) {
      return eliminate(env, ifFalse);
    }
    if ((ifTrue == null) && (ifFalse == null)) {
      return eliminate(env, new ExpressionStatement(where, cond).inline(env, ctx));
    }
    if (ifTrue == null) {
      cond = new NotExpression(cond.where, cond).inlineValue(env, ctx);
      return eliminate(env, new IfStatement(where, cond, ifFalse, null));
    }
    return this;
  }