code: private Object doName(
          Object obj, boolean toLHS,
          CallStack callstack, Interpreter interpreter)
          throws EvalError, ReflectError
      {
          // .length on array
          if ( field.equals("length") && obj.getClass().isArray() )
              if ( toLHS )
                  throw new EvalError(
                      "Can't assign array length", this, callstack );
              else
                  return new Primitive(Array.getLength(obj));
          // field access
          if ( jjtGetNumChildren() == 0 )
              if ( toLHS ) try {
                  return Reflect.getLHSObjectField(obj, field);
              } catch (Throwable t) {
                  return new LHS(obj, field);
              }
              else try {
                  return Reflect.getObjectFieldValue( obj, field );
              } catch (Throwable t) {
                  try {
                      return Reflect.getObjectProperty( obj, field );
                  } catch (Throwable tt) {
                      return Primitive.VOID;
                  }
              }
          // Method invocation
          // (LHS or non LHS evaluation can both encounter method calls)
          Object[] oa = ((BSHArguments)jjtGetChild(0)).getArguments(
              callstack, interpreter);
  
          try {
              return Reflect.invokeObjectMethod(
                  obj, field, oa, interpreter, callstack, this );
          } catch ( ReflectError e ) {
              throw new EvalError(
                  "Error in method invocation: " + e.getMessage(),
                  this, callstack, e );
          } catch ( InvocationTargetException e )
          {
              String msg = "Method Invocation "+field;
              Throwable te = e.getCause();
  
              /*
                  Try to squeltch the native code stack trace if the exception
                  was caused by a reflective call back into the bsh interpreter
                  (e.g. eval() or source()
              */
              boolean isNative = true;
              if ( te instanceof EvalError )
                  if ( te instanceof TargetError )
                      isNative = ((TargetError)te).inNativeCode();
                  else
                      isNative = false;
  
              throw new TargetError( msg, te, this, callstack, isNative );
          }
  
      }
docs: /*
  Field access, .length on array, or a method invocation
  Must handle toLHS case for each.