class QueryableStoreProvider {

    public <T> T getStore(final StoreQueryParameters<T> storeQueryParameters) {
        final String storeName = storeQueryParameters.storeName();
        final QueryableStoreType<T> queryableStoreType = storeQueryParameters.queryableStoreType();
        final List<T> globalStore = globalStoreProvider.stores(storeName, queryableStoreType);
        if (!globalStore.isEmpty()) {
            return queryableStoreType.create(globalStoreProvider, storeName);
        }
        final List<T> allStores = new ArrayList<>();
        for (final StreamThreadStateStoreProvider storeProvider : storeProviders) {
            final List<T> stores = storeProvider.stores(storeQueryParameters);
            if (!stores.isEmpty()) {
                allStores.addAll(stores);
                if (storeQueryParameters.partition() != null) {
                    break;
                }
            }
        }
        if (allStores.isEmpty()) {
            if (storeQueryParameters.partition() != null) {
                throw new InvalidStateStoreException(
                        String.format("The specified partition %d for store %s does not exist.",
                                storeQueryParameters.partition(),
                                storeName));
            }
            throw new InvalidStateStoreException("The state store, " + storeName + ", may have migrated to another instance.");
        }
        return queryableStoreType.create(
            new WrappingStoreProvider(storeProviders, storeQueryParameters),
            storeName
        );
    }

    public  QueryableStoreProvider(final List<StreamThreadStateStoreProvider> storeProviders,
                                  final GlobalStateStoreProvider globalStateStoreProvider);

}