public FlowInfo analyseCode(
      BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
    // determine the rank until which we now we do not need any actual value for the field access
    int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;

    boolean needValue = otherBindingsCount == 0 ? valueRequired : !this.otherBindings[0].isStatic();
    boolean complyTo14 =
        currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
    switch (this.bits & ASTNode.RestrictiveFlagMASK) {
      case Binding.FIELD: // reading a field
        break;
      case Binding.LOCAL: // reading a local variable
        LocalVariableBinding localBinding;
        if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
          if (localBinding.declaringScope instanceof CompilationUnitScope)
            currentScope.problemReporter().uninitializedGlobalVariable(localBinding, this);
          else currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
        }
        if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
          localBinding.useFlag = LocalVariableBinding.USED;
        } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
          localBinding.useFlag = LocalVariableBinding.FAKE_USED;
        }
        checkNPE(currentScope, flowContext, flowInfo, true);
    }
    if (needValue) {
      manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
      // only for first binding (if value needed only)
    }
    if (this.otherBindings != null) {
      for (int i = 0; i < otherBindingsCount; i++) {
        needValue =
            i < otherBindingsCount - 1 ? !this.otherBindings[i + 1].isStatic() : valueRequired;
        if (needValue || complyTo14) {
          TypeBinding lastReceiverType = getGenericCast(i);
          if (lastReceiverType == null) {
            if (i == 0) {
              lastReceiverType = ((VariableBinding) this.binding).type;
            } else {
              lastReceiverType = this.otherBindings[i - 1].type;
            }
          }
        }
      }
    }
    return flowInfo;
  }
  public FlowInfo analyseAssignment(
      BlockScope currentScope,
      FlowContext flowContext,
      FlowInfo flowInfo,
      Assignment assignment,
      boolean isCompound) {
    // determine the rank until which we now we do not need any actual value for the field access
    int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
    boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
    boolean complyTo14 =
        currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
    FieldBinding lastFieldBinding = null;
    switch (this.bits & ASTNode.RestrictiveFlagMASK) {
      case Binding.FIELD: // reading a field
        lastFieldBinding = (FieldBinding) this.binding;
        break;
      case Binding.LOCAL:
        // first binding is a local variable
        LocalVariableBinding localBinding;
        if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
          currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
        }
        if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
          localBinding.useFlag = LocalVariableBinding.USED;
        } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
          localBinding.useFlag = LocalVariableBinding.FAKE_USED;
        }
        checkNPE(currentScope, flowContext, flowInfo, true);
    }

    if (needValue) {
      manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
      // only for first binding
    }
    // all intermediate field accesses are read accesses
    if (this.otherBindings != null) {
      for (int i = 0; i < otherBindingsCount - 1; i++) {
        lastFieldBinding = this.otherBindings[i];
        needValue = !this.otherBindings[i + 1].isStatic();
      }
      lastFieldBinding = this.otherBindings[otherBindingsCount - 1];
    }

    if (isCompound) {
      TypeBinding lastReceiverType;
      switch (otherBindingsCount) {
        case 0:
          lastReceiverType = this.actualReceiverType;
          break;
        case 1:
          lastReceiverType = ((VariableBinding) this.binding).type;
          break;
        default:
          lastReceiverType = this.otherBindings[otherBindingsCount - 2].type;
          break;
      }
    }

    if (assignment.expression != null) {
      flowInfo =
          assignment
              .expression
              .analyseCode(currentScope, flowContext, flowInfo)
              .unconditionalInits();
    }

    // equivalent to valuesRequired[maxOtherBindings]
    TypeBinding lastReceiverType;
    switch (otherBindingsCount) {
      case 0:
        lastReceiverType = this.actualReceiverType;
        break;
      case 1:
        lastReceiverType = ((VariableBinding) this.binding).type;
        break;
      default:
        lastReceiverType = this.otherBindings[otherBindingsCount - 2].type;
        break;
    }

    return flowInfo;
  }