<T extends Enum<T>> OperationStatistic<T> findLowestTierStatistic(
      Cache<?, ?> cache, Class<T> type, String statName) {

    Query statQuery =
        queryBuilder()
            .descendants()
            .filter(
                context(
                    attributes(
                        Matchers.<Map<String, Object>>allOf(
                            hasAttribute("name", statName), hasAttribute("type", type)))))
            .build();

    Set<TreeNode> statResult =
        statQuery.execute(Collections.singleton(ContextManager.nodeFor(cache)));

    if (statResult.size() < 1) {
      throw new RuntimeException(
          "Failed to find lowest tier statistic: "
              + statName
              + " , valid result Set sizes must 1 or more.  Found result Set size of: "
              + statResult.size());
    }

    // if only 1 store then you don't need to find the lowest tier
    if (statResult.size() == 1) {
      return (OperationStatistic)
          statResult.iterator().next().getContext().attributes().get("this");
    }

    String lowestStoreType = "onheap";
    TreeNode lowestTierNode = null;
    for (TreeNode treeNode : statResult) {
      if (((Set) treeNode.getContext().attributes().get("tags")).size() != 1) {
        throw new RuntimeException(
            "Failed to find lowest tier statistic. \"tags\" set must be size 1");
      }

      String storeType = treeNode.getContext().attributes().get("tags").toString();
      if (storeType.compareToIgnoreCase(lowestStoreType) < 0) {
        lowestStoreType = treeNode.getContext().attributes().get("tags").toString();
        lowestTierNode = treeNode;
      }
    }

    return (OperationStatistic) lowestTierNode.getContext().attributes().get("this");
  }
 private OperationStatistic<StoreOperationOutcomes.ExpirationOutcome> getExpirationStatistic(
     Store<?, ?> store) {
   StatisticsManager statisticsManager = new StatisticsManager();
   statisticsManager.root(store);
   TreeNode treeNode =
       statisticsManager.queryForSingleton(
           QueryBuilder.queryBuilder()
               .descendants()
               .filter(
                   org.terracotta.context.query.Matchers.context(
                       org.terracotta.context.query.Matchers.<ContextElement>allOf(
                           org.terracotta.context.query.Matchers.identifier(
                               org.terracotta.context.query.Matchers.subclassOf(
                                   OperationStatistic.class)),
                           org.terracotta.context.query.Matchers.attributes(
                               org.terracotta.context.query.Matchers.hasAttribute(
                                   "name", "expiration")))))
               .build());
   return (OperationStatistic<StoreOperationOutcomes.ExpirationOutcome>)
       treeNode.getContext().attributes().get("this");
 }
  static <T extends Enum<T>> OperationStatistic<T> findCacheStatistic(
      Cache<?, ?> cache, Class<T> type, String statName) {
    Query query =
        queryBuilder()
            .children()
            .filter(
                context(
                    attributes(
                        Matchers.<Map<String, Object>>allOf(
                            hasAttribute("name", statName), hasAttribute("type", type)))))
            .build();

    Set<TreeNode> result = query.execute(Collections.singleton(ContextManager.nodeFor(cache)));
    if (result.size() > 1) {
      throw new RuntimeException("result must be unique");
    }
    if (result.isEmpty()) {
      throw new RuntimeException("result must not be null");
    }
    return (OperationStatistic<T>) result.iterator().next().getContext().attributes().get("this");
  }