private void checkVariable(Tree.Term term, Node node) {
   if (isEffectivelyBaseMemberExpression(term)) { // Note: other cases handled in ExpressionVisitor
     Tree.StaticMemberOrTypeExpression mte = (Tree.StaticMemberOrTypeExpression) term;
     Declaration member = mte.getDeclaration();
     if (member == declaration) {
       if ((declaration.isFormal() || declaration.isDefault()) && !isForwardReferenceable()) {
         term.addError(
             "member is formal or default and may not be assigned here: '"
                 + member.getName()
                 + "'");
       } else if (!isVariable() && !isLate()) {
         if (member instanceof Value) {
           if (node instanceof Tree.AssignOp) {
             term.addError(
                 "value is not a variable and may not be assigned here: '"
                     + member.getName()
                     + "'",
                 803);
           } else {
             term.addError("value is not a variable: '" + member.getName() + "'", 800);
           }
         } else {
           term.addError("not a variable value: '" + member.getName() + "'");
         }
       }
     }
   }
 }
 @Override
 public void visit(Tree.SpecifierStatement that) {
   Tree.Term term = that.getBaseMemberExpression();
   boolean parameterized = false;
   while (term instanceof Tree.ParameterizedExpression) {
     Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) term;
     term = pe.getPrimary();
     parameterized = true;
   }
   if (term instanceof Tree.StaticMemberOrTypeExpression) {
     Tree.StaticMemberOrTypeExpression bme = (Tree.StaticMemberOrTypeExpression) term;
     //            Declaration member = getTypedDeclaration(bme.getScope(),
     //                    name(bme.getIdentifier()), null, false, bme.getUnit());
     Declaration member = bme.getDeclaration();
     if (member == declaration) {
       if ((declaration.isFormal() || declaration.isDefault()) && !isForwardReferenceable()) {
         // TODO: is this error correct?! look at the condition above
         bme.addError(
             "member is formal and may not be specified: '"
                 + member.getName()
                 + "' is declared formal");
       }
       if (that.getRefinement()) {
         declare();
       }
       Tree.SpecifierExpression se = that.getSpecifierExpression();
       boolean lazy = se instanceof Tree.LazySpecifierExpression;
       if (declaration instanceof Value) {
         Value value = (Value) declaration;
         if (!value.isVariable() && lazy != value.isTransient()) {
           // check that all assignments to a non-variable, in
           // different paths of execution, all use the same
           // kind of specifier, all =>, or all =
           // TODO: sometimes this error appears only because
           //       of a later line which illegally reassigns
           se.addError(
               "value must be specified using => lazy specifier: '" + member.getName() + "'");
         }
         if (lazy) {
           if (value.isVariable()) {
             se.addError(
                 "variable value may not be specified using => lazy specifier: '"
                     + member.getName()
                     + "'");
           } else if (value.isLate()) {
             se.addError(
                 "late reference may not be specified using => lazy specifier: '"
                     + member.getName()
                     + "'");
           }
         }
       }
       if (!lazy || !parameterized) {
         se.visit(this);
       }
       boolean constant = !isVariable() && !isLate();
       Scope scope = that.getScope();
       if (constant && !declaration.isDefinedInScope(scope)) {
         // this error is added by ExpressionVisitor
         //                    that.addError("inherited member is not variable and may not be
         // specified here: '" +
         //                            member.getName() + "'");
       } else if (!declared && constant) {
         bme.addError(shortdesc() + " is not yet declared: '" + member.getName() + "'");
       } else if (inLoop && constant && !(endsInBreakReturnThrow && lastContinue == null)) {
         if (specified.definitely) {
           bme.addError(
               longdesc() + " is aready definitely specified: '" + member.getName() + "'", 803);
         } else {
           bme.addError(
               longdesc() + " is not definitely unspecified in loop: '" + member.getName() + "'",
               803);
         }
       } else if (withinDeclaration && constant && !that.getRefinement()) {
         Declaration dec = getContainingDeclarationOfScope(scope);
         if (dec != null && dec.equals(member)) {
           bme.addError(
               "cannot specify "
                   + shortdesc()
                   + " from within its own body: '"
                   + member.getName()
                   + "'");
         } else {
           bme.addError(
               "cannot specify "
                   + shortdesc()
                   + " declared in outer scope: '"
                   + member.getName()
                   + "'",
               803);
         }
       } else if (specified.possibly && constant) {
         if (specified.definitely) {
           bme.addError(
               longdesc() + " is aready definitely specified: '" + member.getName() + "'", 803);
         } else {
           bme.addError(
               longdesc() + " is not definitely unspecified: '" + member.getName() + "'", 803);
         }
       } else {
         specify();
         term.visit(this);
       }
       if (lazy && parameterized) {
         se.visit(this);
       }
     } else {
       super.visit(that);
     }
   } else {
     super.visit(that);
   }
 }
  private void visitReference(Tree.Primary that) {
    Declaration member;
    boolean assigned;
    boolean metamodel;
    if (that instanceof Tree.MemberOrTypeExpression) {
      Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) that;
      member = mte.getDeclaration();
      assigned = mte.getAssigned();
      metamodel = false;
    } else if (that instanceof Tree.MetaLiteral) {
      Tree.MetaLiteral ml = (Tree.MetaLiteral) that;
      member = ml.getDeclaration();
      assigned = false;
      metamodel = true;
    } else {
      return;
    }

    if (member == declaration && member.isDefinedInScope(that.getScope())) {
      if (!declared) {
        // you are allowed to refer to later
        // declarations in a class declaration
        // section or interface
        if (withinAttributeInitializer
            && member instanceof Value
            && !(((Value) member).isTransient())) {
          that.addError(
              "reference to value within its initializer: '" + member.getName() + "'", 1460);
        } else if (!metamodel && !isForwardReferenceable() && !hasParameter) {
          Scope container = declaration.getContainer();
          if (container instanceof Class) {
            that.addError(
                "forward reference to class member in initializer: '"
                    + member.getName()
                    + "' is not yet declared (forward references must occur in declaration section)");
          } else {
            that.addError(
                "forward reference to local declaration: '"
                    + member.getName()
                    + "' is not yet declared");
          }
        }
      } else if (!specified.definitely || declaration.isFormal()) {
        // you are allowed to refer to formal
        // declarations in a class declaration
        // section or interface
        if (declaration.isFormal()) {
          if (!isForwardReferenceable()) {
            that.addError(
                "formal member may not be used in initializer: '" + member.getName() + "'");
          }
        } else if (!metamodel
            && !isNativeHeader(declaration)
            && (!isLate() || !isForwardReferenceable())) {
          if (isVariable()) {
            that.addError("not definitely initialized: '" + member.getName() + "'");
          } else {
            that.addError("not definitely specified: '" + member.getName() + "'");
          }
        }
      }
      if (!assigned && member.isDefault() && !isForwardReferenceable()) {
        that.addError("default member may not be used in initializer: '" + member.getName() + "'");
      }
      if (inAnonFunctionOrComprehension && specified.definitely && isVariable()) {
        that.addError(
            "variable member may not be captured by comprehension or function in extends clause: '"
                + member.getName()
                + "'");
      }
    }
  }