@Override
 public void setMyObjectClass(final ObjectClass_Definition objectClass) {
   super.setMyObjectClass(objectClass);
   if (fieldSpecification != null) {
     fieldSpecification.setMyObjectClass(objectClass);
   }
 }
  @Override
  public FieldSpecification getLast() {
    if (lastTimeChecked == null) {
      check(CompilationTimeStamp.getBaseTimestamp());
    }

    return fieldSpecification.getLast();
  }
  @Override
  public ISetting getDefault() {
    if (lastTimeChecked == null) {
      check(CompilationTimeStamp.getBaseTimestamp());
    }

    return fieldSpecification.getDefault();
  }
  @Override
  public boolean hasDefault() {
    if (fieldSpecification != null) {
      return fieldSpecification.hasDefault();
    }

    return (defaultSetting1 != null) || (mDefaultSetting != null);
  }
 @Override
 protected boolean memberAccept(ASTVisitor v) {
   if (identifier != null && !identifier.accept(v)) {
     return false;
   }
   if (fieldSpecification != null && !fieldSpecification.accept(v)) {
     return false;
   }
   return true;
 }
  @Override
  public void check(final CompilationTimeStamp timestamp) {
    if (lastTimeChecked != null && !lastTimeChecked.isLess(timestamp)) {
      return;
    }

    fieldSpecification = null;
    classifyFieldSpecification(timestamp);

    if (fieldSpecification != null) {
      fieldSpecification.check(timestamp);
    }

    lastTimeChecked = timestamp;
  }
  private void classifyFieldSpecification(final CompilationTimeStamp timestamp) {
    final IReferenceChain temporalReferenceChain =
        ReferenceChain.getInstance(IReferenceChain.CIRCULARREFERENCE, true);

    if (isOptional && (null != defaultSetting1 || null != mDefaultSetting)) {
      location.reportSemanticError("OPTIONAL and DEFAULT are mutually exclusive");
      isOptional = false;
    }

    if (temporalReferenceChain.add(this) && null != governorReference) {
      governorReference.setMyScope(myObjectClass.getMyScope());

      if (null != defaultSetting1) {
        defaultSetting1.setMyScope(myObjectClass.getMyScope());
      }

      if (identifier.isvalidAsnObjectSetFieldReference()
          && governorReference.refersToSettingType(
              timestamp, Setting_type.S_OC, temporalReferenceChain)) {
        ObjectSet defaultObjectset = null;
        if (null != mDefaultSetting) {
          defaultObjectset = ParserFactory.createObjectSetDefinition(mDefaultSetting);
        }
        fieldSpecification =
            new ObjectSet_FieldSpecification(
                identifier, new ObjectClass_refd(governorReference), isOptional, defaultObjectset);
      } else if (identifier.isvalidAsnObjectFieldReference()
          && governorReference.refersToSettingType(
              timestamp, Setting_type.S_OC, temporalReferenceChain)) {
        ASN1Object defaultObject = null;
        if (null != defaultSetting1) {
          defaultObject = new ReferencedObject(defaultSetting1);
        } else if (null != mDefaultSetting) {
          defaultObject = new Object_Definition(mDefaultSetting);
        }

        fieldSpecification =
            new Object_FieldSpecification(
                identifier, new ObjectClass_refd(governorReference), isOptional, defaultObject);
      } else if (identifier.isvalidAsnValueFieldReference()
          && (governorReference.refersToSettingType(
                  timestamp, Setting_type.S_T, temporalReferenceChain)
              || governorReference.refersToSettingType(
                  timestamp, Setting_type.S_VS, temporalReferenceChain))) {
        IValue defaultValue = null;

        if (null != defaultSetting1) {
          if (defaultSetting1 instanceof Defined_Reference
              && null == defaultSetting1.getModuleIdentifier()) {
            defaultValue =
                new Undefined_LowerIdentifier_Value(defaultSetting1.getId().newInstance());
          } else {
            defaultValue = new Referenced_Value(defaultSetting1);
          }
        } else if (null != mDefaultSetting) {
          defaultValue = ParserFactory.createUndefinedBlockValue(mDefaultSetting);
        }
        fieldSpecification =
            new FixedTypeValue_FieldSpecification(
                identifier,
                new Referenced_Type(governorReference),
                false,
                isOptional,
                null != defaultSetting1 && null != mDefaultSetting,
                defaultValue);
      }
    }

    if (null == fieldSpecification) {
      location.reportSemanticError(CANNOTRECOGNISE);
      fieldSpecification =
          new Erroneous_FieldSpecification(
              identifier, isOptional, null != defaultSetting1 || null != mDefaultSetting);
    } else {
      if (null != myObjectClass) {
        fieldSpecification.setMyObjectClass(myObjectClass);
      }
    }

    fieldSpecification.setFullNameParent(getNameParent());
    fieldSpecification.setLocation(location);

    temporalReferenceChain.release();
  }
 @Override
 public void addProposal(final ProposalCollector propCollector, final int i) {
   if (fieldSpecification != null) {
     fieldSpecification.addProposal(propCollector, i);
   }
 }
 @Override
 public void addDeclaration(final DeclarationCollector declarationCollector, final int i) {
   if (fieldSpecification != null) {
     fieldSpecification.addDeclaration(declarationCollector, i);
   }
 }