private @Nullable Object getDataFromRuleInner(@NotNull GetDataRule rule,
                                                @NotNull String dataId,
                                                @NotNull GetDataRuleType ruleType,
                                                @Nullable Set<String> alreadyComputedIds,
                                                @NotNull DataProvider provider) {
    int[] depth = ourGetDataLevel.get();
    try {
      depth[0]++;
      Set<String> ids = alreadyComputedIds == null ? new HashSet<>() : alreadyComputedIds;
      ids.add(dataId);
      Object data = rule.getData(id -> {
        Object o = getDataFromProviderAndRulesInner(id, ruleType, ids, provider);
        return o == CustomizedDataContext.EXPLICIT_NULL ? null : o;
      });
      return data == null ? null :
             data == CustomizedDataContext.EXPLICIT_NULL ? data :
             DataValidators.validOrNull(data, dataId, rule);
    }
    finally {
      depth[0]--;
    }
  }
private @Nullable Object getDataFromRuleInner(@NotNull GetDataRule rule,
                                                @NotNull String dataId,
                                                @NotNull GetDataRuleType ruleType,
                                                @Nullable Set<String> alreadyComputedIds,
                                                @NotNull DataProvider provider)