package software.committed.rejux.utils;

import java.util.List;

import software.committed.rejux.interfaces.Dispatcher;
import software.committed.rejux.interfaces.Middleware;
import software.committed.rejux.interfaces.State;

public final class MiddlewareUtils {

  private MiddlewareUtils() {
    // Singleton
  }

  public static <S> Dispatcher createChain(final Dispatcher firstDispatcher, final S store,
      final List<Middleware<? super S>> middlewares, final Dispatcher lastDispatcher) {
    Dispatcher dispatcher = lastDispatcher;

    if (middlewares != null && !middlewares.isEmpty()) {
      for (int i = middlewares.size() - 1; i >= 0; i--) {
        final Middleware<? super S> m = middlewares.get(i);
        final Dispatcher previous = dispatcher;
        dispatcher = (action) -> m.apply(firstDispatcher, store, action, previous);
      }
    }

    return dispatcher;
  }

  public static <S> Dispatcher createChain(final Dispatcher firstDispatcher, final State<S> holder,
      final List<Middleware<? super S>> middlewares, final Dispatcher lastDispatcher) {
    Dispatcher dispatcher = lastDispatcher;

    if (middlewares != null && !middlewares.isEmpty()) {
      for (int i = middlewares.size() - 1; i >= 0; i--) {
        final Middleware<? super S> m = middlewares.get(i);
        final Dispatcher previous = dispatcher;
        dispatcher = (action) -> m.apply(firstDispatcher, holder.get(), action, previous);
      }
    }

    return dispatcher;
  }

}

@@ -56,16 +56,52 @@
 il.List;
+%0Aimport java.util.function.Supplier;
 %0A%0Aimport
@@ -207,58 +207,8 @@
 are;
-%0Aimport software.committed.rejux.interfaces.State;
 %0A%0Apu
@@ -483,383 +483,112 @@
     
-Dispatcher dispatcher = lastDispatcher;%0A%0A    if (middlewares != null && !middlewares.isEmpty()) %7B%0A      for (int i = middlewares.size() - 1; i %3E= 0; i--) %7B%0A        final Middleware%3C? super S%3E m = middlewares.get(i);%0A        final Dispatcher previous = dispatcher;%0A        dispatcher = (action) -%3E m.apply(firstDispatcher, store, action, previous);%0A      %7D%0A    %7D%0A%0A    return d
+Supplier%3CS%3E supplier = () -%3E store;%0A    return createChain(firstDispatcher, supplier, middlewares, lastD
 ispa
@@ -588,24 +588,25 @@
 stDispatcher
+)
 ;%0A  %7D%0A%0A  pub
@@ -676,24 +676,30 @@
 patcher,
+%0A     
  final S
 tate%3CS%3E 
@@ -694,29 +694,25 @@
 al S
-tate%3CS%3E holder,%0A     
+upplier%3CS%3E store,
  fin
@@ -746,32 +746,38 @@
 S%3E%3E middlewares,
+%0A     
  final Dispatche
@@ -1126,14 +1126,13 @@
 er, 
-holder
+store
 .get
@@ -1197,10 +1197,12 @@
 r;%0A  %7D%0A%0A
+%0A%0A
 %7D%0A

Reimplement middleware utils as common code