private int getArrayDims(IReducedSymbol reducedSym) {
   IType type = reducedSym.getType();
   if (type == JavaTypes.OBJECT()) {
     // Special case for handling Object -- pcf does strange stuff where it says a var is Object
     // but expects a on dim array
     return -1;
   }
   int iDims;
   for (iDims = 0; type.isArray(); iDims++) {
     type = type.getComponentType();
   }
   return iDims;
 }
  public IRExpression pushSymbolValue(ISymbol symbol) {
    IType type = symbol.getType();
    Class symClass;
    IReducedSymbol reducedSym;
    if (symbol instanceof ReducedSymbol.SyntheticSymbol) {
      reducedSym = ((ReducedSymbol.SyntheticSymbol) symbol).getReducedSymbol();
      symClass = reducedSym.getSymbolClass();
    } else {
      reducedSym = symbol;
      symClass = symbol.getClass();
    }
    if (_cc().isExternalSymbol(reducedSym.getName())) {
      // unbox( symbols.getValue( name ) )
      return unboxValueToType(
          reducedSym.getType(),
          callMethod(
              IExternalSymbolMap.class,
              "getValue",
              new Class[] {String.class, int.class},
              pushExternalSymbolsMap(),
              Arrays.asList(
                  pushConstant(reducedSym.getName()), pushConstant(getArrayDims(reducedSym)))));
    } else if (DynamicSymbol.class.isAssignableFrom(symClass)) {
      // Instance or Static field

      IRProperty irProp = IRPropertyFactory.createIRProperty(reducedSym);
      if (!irProp.isStatic()) {
        if (isMemberOnEnclosingType(reducedSym) != null) {
          // Instance field from 'outer'
          return getField_new(
              irProp, pushOuter(reducedSym.getGosuClass()), getDescriptor(reducedSym.getType()));
        } else {
          // Instance field from 'this'
          return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType()));
        }
      } else {
        // Static field
        return getField_new(irProp, null, getDescriptor(reducedSym.getType()));
      }
    } else if (CapturedSymbol.class.isAssignableFrom(symClass)) {
      // Captured symbol is stored as a Field on an anonymous inner class (one elem array of
      // symbol's type)
      // e.g., val$myFiield[0] = value. Note a captured symbol is duplicated in all nested classes.
      IRProperty irProp = IRPropertyFactory.createIRProperty(getGosuClass(), reducedSym);
      return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType()));
    } else if (reducedSym.getIndex() >= 0) {
      // Local var

      if (reducedSym.isValueBoxed()) {
        // Local var is captured in an anonymous inner class.
        // Symbol's value maintained as a one elem array of symbol's type.
        return buildArrayLoad(
            identifier(_cc().getSymbol(reducedSym.getName())), 0, getDescriptor(type));
      } else {
        // Simple local var
        return identifier(_cc().getSymbol(reducedSym.getName()));
      }
    } else if (DynamicPropertySymbol.class.isAssignableFrom(symClass)) {
      IRProperty irProp;
      if (reducedSym instanceof DynamicPropertySymbol) {
        irProp = IRPropertyFactory.createIRProperty((DynamicPropertySymbol) reducedSym);
      } else {
        irProp = IRPropertyFactory.createIRProperty((ReducedDynamicPropertySymbol) reducedSym);
      }

      IRExpression root;
      if (irProp.isStatic()) {
        root = null;
      } else {
        ICompilableType targetType = isMemberOnEnclosingType(reducedSym);
        if (targetType != null) {
          root = pushOuter(targetType);
        } else {
          root = pushThis();
        }
      }
      IRExpression getterCall =
          callMethod(irProp.getGetterMethod(), root, Collections.<IRExpression>emptyList());
      return castResultingTypeIfNecessary(
          getDescriptor(reducedSym.getType()), irProp.getType(), getterCall);
    } else {
      throw new UnsupportedOperationException(
          "Don't know how to compile symbol: "
              + reducedSym.getClass().getSimpleName()
              + ": "
              + reducedSym.getName()
              + ": "
              + reducedSym.getType());
    }
  }