code: public Type checkLVal(LVal lval, Environment environment) {
  		Type type;
  		switch (lval.getOpcode()) {
  		case EXPR_variablecopy:
  			type = checkVariableLVal((Expr.VariableAccess) lval, environment);
  			break;
  		case EXPR_staticvariable:
  			type = checkStaticVariableLVal((Expr.StaticVariableAccess) lval, environment);
  			break;
  		case EXPR_arrayaccess:
  		case EXPR_arrayborrow:
  			type = checkArrayLVal((Expr.ArrayAccess) lval, environment);
  			break;
  		case EXPR_recordaccess:
  		case EXPR_recordborrow:
  			type = checkRecordLVal((Expr.RecordAccess) lval, environment);
  			break;
  		case EXPR_dereference:
  			type = checkDereferenceLVal((Expr.Dereference) lval, environment);
  			break;
  		default:
  			return internalFailure("unknown lval encountered (" + lval.getClass().getSimpleName() + ")", lval);
  		}
  		// Sanity check type. This can be non-sensical in the case of an upsteam type
  		// error
  		if (type != null) {
  			lval.setType(lval.getHeap().allocate(type));
  		}
  		return type;
  	}
docs: Type check a given lval assuming an initial environment. This returns the
  largest type which can be safely assigned to the lval. Observe that this type
  is determined by the declared type of the variable being assigned.
  
  @param expression
  @param environment
  @return
  @throws ResolutionError