docs: @Override
      protected void executeRuntimeStep(OperationContext context, ModelNode operation) {
          final PathAddress address = PathAddress.pathAddress(operation.require(OP_ADDR));
          final String cacheContainerName = address.getElement(address.size() - 2).getValue();
          final String cacheName = address.getLastElement().getValue();
          final String attrName = operation.require(NAME).asString();
          final ServiceController<?> controller = context.getServiceRegistry(false).getService(CacheServiceName.CACHE.getServiceName(cacheContainerName, cacheName));
          Cache<?, ?> cache = (Cache<?, ?>) controller.getValue();
          CacheMetrics metric = CacheMetrics.getStat(attrName);
          ModelNode result = new ModelNode();
  
          if (metric == null) {
              context.getFailureDescription().set(String.format("Unknown metric %s", attrName));
          } else if (cache == null) {
              context.getFailureDescription().set(String.format("Unavailable cache %s", attrName));
          } else {
              AdvancedCache<?, ?> aCache = cache.getAdvancedCache();
              DefaultLockManager lockManager = (DefaultLockManager) SecurityActions.getLockManager(aCache);
              RpcManagerImpl rpcManager = (RpcManagerImpl) SecurityActions.getRpcManager(aCache);
              List<AsyncInterceptor> interceptors = SecurityActions.getInterceptorChain(aCache);
              ComponentRegistry registry = SecurityActions.getComponentRegistry(aCache);
              ComponentStatus status = SecurityActions.getCacheStatus(aCache);
              BasePerCacheInboundInvocationHandler handler = (BasePerCacheInboundInvocationHandler) registry.getPerCacheInboundInvocationHandler();
              switch (metric) {
                  case CACHE_STATUS:
                      result.set(status.toString());
                      break;
                  case CONCURRENCY_LEVEL:
                      result.set(lockManager.getConcurrencyLevel());
                      break;
                  case NUMBER_OF_LOCKS_AVAILABLE:
                      result.set(lockManager.getNumberOfLocksAvailable());
                      break;
                  case NUMBER_OF_LOCKS_HELD:
                      result.set(lockManager.getNumberOfLocksHeld());
                      break;
                  case AVERAGE_READ_TIME: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getAverageReadTime() : 0);
                      break;
                  }
                  case AVERAGE_WRITE_TIME: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getAverageWriteTime() : 0);
                      break;
                  }
                  case AVERAGE_REMOVE_TIME: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getAverageRemoveTime() : 0);
                      break;
                  }
                  case TIME_SINCE_START: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getTimeSinceStart() : 0);
                      break;
                  }
                  case EVICTIONS: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getEvictions() : 0);
                      break;
                  }
                  case HIT_RATIO: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getHitRatio() : 0);
                      break;
                  }
                  case HITS: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getHits() : 0);
                      break;
                  }
                  case MISSES: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getMisses() : 0);
                      break;
                  }
                  case NUMBER_OF_ENTRIES: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getNumberOfEntries() : 0);
                      break;
                  }
                  case NUMBER_OF_ENTRIES_IN_MEMORY: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getNumberOfEntriesInMemory() : 0);
                      break;
                  }
                  case DATA_MEMORY_USED: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getDataMemoryUsed() : 0);
                      break;
                  }
                  case OFF_HEAP_MEMORY_USED: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getOffHeapMemoryUsed() : 0);
                      break;
                  }
                  case MINIMUM_REQUIRED_NODES: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getRequiredMinimumNumberOfNodes() : 0);
                      break;
                  }
                  case READ_WRITE_RATIO: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getReadWriteRatio() : 0);
                      break;
                  }
                  case REMOVE_HITS: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getRemoveHits() : 0);
                      break;
                  }
                  case REMOVE_MISSES: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getRemoveMisses() : 0);
                      break;
                  }
                  case STORES: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getStores() : 0);
                      break;
                  }
                  case TIME_SINCE_RESET: {
                      CacheMgmtInterceptor cacheMgmtInterceptor = getFirstInterceptorWhichExtends(interceptors, CacheMgmtInterceptor.class);
                      result.set(cacheMgmtInterceptor != null ? cacheMgmtInterceptor.getTimeSinceReset() : 0);
                      break;
                  }
                  case AVERAGE_REPLICATION_TIME: {
                      result.set(rpcManager.getAverageReplicationTime());
                      break;
                  }
                  case REPLICATION_COUNT:
                      result.set(rpcManager.getReplicationCount());
                      break;
                  case REPLICATION_FAILURES:
                      result.set(rpcManager.getReplicationFailures());
                      break;
                  case SUCCESS_RATIO:
                      result.set(rpcManager.getSuccessRatioFloatingPoint());
                      break;
                  case AVG_XSITE_TIME:
                      result.set(rpcManager.getAverageXSiteReplicationTime());
                      break;
                  case MAX_XSITE_TIME:
                      result.set(rpcManager.getMaximumXSiteReplicationTime());
                      break;
                  case MIN_XSITE_TIME:
                      result.set(rpcManager.getMinimumXSiteReplicationTime());
                      break;
                  case SYNC_XSITE_COUNT:
                      result.set(rpcManager.getSyncXSiteCount());
                      break;
                  case ASYNC_XSITE_COUNT:
                      result.set(rpcManager.getAsyncXSiteCount());
                      break;
                  case SYNC_XSITE_COUNT_RECEIVED:
                      result.set(handler.getSyncXSiteRequestsReceived());
                      break;
                  case ASYNC_XSITE_COUNT_RECEIVED:
                      result.set(handler.getAsyncXSiteRequestsReceived());
                      break;
                  case COMMITS: {
                      TxInterceptor txInterceptor = getFirstInterceptorWhichExtends(interceptors, TxInterceptor.class);
                      result.set(txInterceptor != null ? txInterceptor.getCommits() : 0);
                      break;
                  }
                  case PREPARES: {
                      TxInterceptor txInterceptor = getFirstInterceptorWhichExtends(interceptors, TxInterceptor.class);
                      result.set(txInterceptor != null ? txInterceptor.getPrepares() : 0);
                      break;
                  }
                  case ROLLBACKS: {
                      TxInterceptor txInterceptor = getFirstInterceptorWhichExtends(interceptors, TxInterceptor.class);
                      result.set(txInterceptor != null ? txInterceptor.getRollbacks() : 0);
                      break;
                  }
                  case INVALIDATIONS: {
                      InvalidationInterceptor invInterceptor = getFirstInterceptorWhichExtends(interceptors, InvalidationInterceptor.class);
                      result.set(invInterceptor != null ? invInterceptor.getInvalidations() : 0);
                      break;
                  }
                  case PASSIVATIONS: {
                      PassivationManager manager = registry.getComponent(PassivationManager.class);
                      result.set(manager != null ? manager.getPassivations() : 0);
                      break;
                  }
                  case ACTIVATIONS: {
                      ActivationManager manager = registry.getComponent(ActivationManager.class);
                      result.set(manager != null ? manager.getActivationCount() : 0);
                      break;
                  }
                  case CACHE_LOADER_LOADS: {
                      CacheLoaderInterceptor
                            interceptor = getFirstInterceptorWhichExtends(interceptors, CacheLoaderInterceptor.class);
                      result.set(interceptor != null ? interceptor.getCacheLoaderLoads() : 0);
                      break;
                  }
                  case CACHE_LOADER_MISSES: {
                      CacheLoaderInterceptor interceptor = getFirstInterceptorWhichExtends(interceptors, CacheLoaderInterceptor.class);
                      result.set(interceptor != null ? interceptor.getCacheLoaderMisses() : 0);
                      break;
                  }
                  case CACHE_LOADER_STORES: {
                      CacheWriterInterceptor
                            interceptor = getFirstInterceptorWhichExtends(interceptors, CacheWriterInterceptor.class);
                      result.set(interceptor != null ? interceptor.getWritesToTheStores() : 0);
                      break;
                  }
                  case CACHE_NAME: {
                      result.set(cache.getName());
                      break;
                  }
                  case VERSION: {
                      result.set(SecurityActions.getCacheVersion(aCache));
                      break;
                  }
                  case OFFLINE_SITES:
                  case ONLINE_SITES:
                  case MIXED_SITES: {
                      Collection<String> sites = filterSitesByStatus(registry.getComponent(XSiteAdminOperations.class), metric);
                      if (sites.isEmpty()) {
                          result.setEmptyList();
                      } else {
                          result.set(toModelNodeCollection(sites));
                      }
                      break;
                  }
                  default:{
                      context.getFailureDescription().set(String.format("Unknown metric %s", metric));
                      break;
                  }
              }
              context.getResult().set(result);
          }
      }