public void manageSyntheticAccessIfNecessary(
      BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;

    // If inlinable field, forget the access emulation, the code gen will directly target it
    if (this.constant != Constant.NotAConstant) return;

    if ((this.bits & Binding.FIELD) != 0) {
      FieldBinding fieldBinding = (FieldBinding) this.binding;
      FieldBinding codegenField = fieldBinding.original();
      if (((this.bits & ASTNode.DepthMASK) != 0)
          && (codegenField.isPrivate() // private access
              || (codegenField.isProtected() // implicit protected access
                  && codegenField.declaringClass.getPackage()
                      != currentScope.enclosingSourceType().getPackage()))) {
        if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2];
        this.syntheticAccessors[
                isReadAccess ? SingleNameReference.READ : SingleNameReference.WRITE] =
            ((SourceTypeBinding)
                    currentScope
                        .enclosingSourceType()
                        .enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT))
                .addSyntheticMethod(codegenField, isReadAccess, false /*not super access*/);
        currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
        return;
      }
    }
  }