// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/AddTodoAction.java
// public class AddTodoAction implements Action {
//     public static final String TAG = AddTodoAction.class.getSimpleName();
// 
//     private final String text;
// 
//     public AddTodoAction(String text) {
//         this.text = text;
//     }
// 
//     public String getText() {
//         return text;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ClearCompletedTodoAction.java
// public class ClearCompletedTodoAction implements Action {
//     public static final String TAG = ClearCompletedTodoAction.class.getSimpleName();
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/DeleteTodoAction.java
// public class DeleteTodoAction implements Action {
//     public static final String TAG = DeleteTodoAction.class.getSimpleName();
// 
//     private final long id;
// 
//     public DeleteTodoAction(long id) {
//         this.id = id;
//     }
// 
//     public long getId() {
//         return id;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ToggleCompletedTodoAction.java
// public class ToggleCompletedTodoAction implements Action {
//     public static final String TAG = ToggleCompletedTodoAction.class.getSimpleName();
// 
//     private final int id;
// 
//     public ToggleCompletedTodoAction(int id) {
//         this.id = id;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/entity/TodoList.java
// public class TodoList extends ArrayList<TodoList.Todo> implements UndoableState<TodoList> {
//     public static final String TAG = TodoList.class.getSimpleName();
// 
//     public TodoList() {
//     }
// 
//     public TodoList(List<Todo> list) {
//         super(list);
//     }
// 
//     public Todo getTodoById(int id) {
//         return Observable.fromIterable(this)
//                 .filter(todo -> id == todo.getId()).blockingFirst();
//     }
// 
//     @Override
//     public TodoList clone() {
//         return (TodoList) super.clone();
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// 
//     public static class Todo {
//         private final int id;
//         private final boolean completed;
//         private final String text;
// 
//         public Todo(int id, String text) {
//             this.id = id;
//             this.text = text;
//             this.completed = false;
//         }
// 
//         public Todo(int id, String text, boolean isCompleted) {
//             this.id = id;
//             this.text = text;
//             this.completed = isCompleted;
//         }
// 
//         public int getId() {
//             return id;
//         }
// 
//         public boolean isCompleted() {
//             return completed;
//         }
// 
//         public String getText() {
//             return text;
//         }
// 
//         @Override
//         public String toString() {
//             return new Gson().toJson(this);
//         }
//     }
// }


import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Undoable;
import info.izumin.android.droidux.example.todoswithundo.action.AddTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.ClearCompletedTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.DeleteTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.ToggleCompletedTodoAction;
import info.izumin.android.droidux.example.todoswithundo.entity.TodoList;
import io.reactivex.Observable;
package info.izumin.android.droidux.example.todoswithundo.reducer;


/**
 * Created by izumin on 11/4/15.
 */
@Undoable
@Reducer(TodoList.class)
public class TodoListReducer {
    public static final String TAG = TodoListReducer.class.getSimpleName();

    @Dispatchable(AddTodoAction.class)
    public TodoList onAddedTodo(TodoList state, AddTodoAction action) {
        if (state.isEmpty()) {
            TodoList newState = new TodoList(state);
            newState.add(new TodoList.Todo(0, action.getText()));
            return newState;
        }
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/AddTodoAction.java
// public class AddTodoAction implements Action {
//     public static final String TAG = AddTodoAction.class.getSimpleName();
// 
//     private final String text;
// 
//     public AddTodoAction(String text) {
//         this.text = text;
//     }
// 
//     public String getText() {
//         return text;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ClearCompletedTodoAction.java
// public class ClearCompletedTodoAction implements Action {
//     public static final String TAG = ClearCompletedTodoAction.class.getSimpleName();
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/DeleteTodoAction.java
// public class DeleteTodoAction implements Action {
//     public static final String TAG = DeleteTodoAction.class.getSimpleName();
// 
//     private final long id;
// 
//     public DeleteTodoAction(long id) {
//         this.id = id;
//     }
// 
//     public long getId() {
//         return id;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ToggleCompletedTodoAction.java
// public class ToggleCompletedTodoAction implements Action {
//     public static final String TAG = ToggleCompletedTodoAction.class.getSimpleName();
// 
//     private final int id;
// 
//     public ToggleCompletedTodoAction(int id) {
//         this.id = id;
//     }
// 
//     public int getId() {
//         return id;
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// }
// 
// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/entity/TodoList.java
// public class TodoList extends ArrayList<TodoList.Todo> implements UndoableState<TodoList> {
//     public static final String TAG = TodoList.class.getSimpleName();
// 
//     public TodoList() {
//     }
// 
//     public TodoList(List<Todo> list) {
//         super(list);
//     }
// 
//     public Todo getTodoById(int id) {
//         return Observable.fromIterable(this)
//                 .filter(todo -> id == todo.getId()).blockingFirst();
//     }
// 
//     @Override
//     public TodoList clone() {
//         return (TodoList) super.clone();
//     }
// 
//     @Override
//     public String toString() {
//         return new Gson().toJson(this);
//     }
// 
//     public static class Todo {
//         private final int id;
//         private final boolean completed;
//         private final String text;
// 
//         public Todo(int id, String text) {
//             this.id = id;
//             this.text = text;
//             this.completed = false;
//         }
// 
//         public Todo(int id, String text, boolean isCompleted) {
//             this.id = id;
//             this.text = text;
//             this.completed = isCompleted;
//         }
// 
//         public int getId() {
//             return id;
//         }
// 
//         public boolean isCompleted() {
//             return completed;
//         }
// 
//         public String getText() {
//             return text;
//         }
// 
//         @Override
//         public String toString() {
//             return new Gson().toJson(this);
//         }
//     }
// }


// Path: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/reducer/TodoListReducer.java
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Undoable;
import info.izumin.android.droidux.example.todoswithundo.action.AddTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.ClearCompletedTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.DeleteTodoAction;
import info.izumin.android.droidux.example.todoswithundo.action.ToggleCompletedTodoAction;
import info.izumin.android.droidux.example.todoswithundo.entity.TodoList;
import io.reactivex.Observable;

package info.izumin.android.droidux.example.todoswithundo.reducer;


/**
 * Created by izumin on 11/4/15.
 */
@Undoable
@Reducer(TodoList.class)
public class TodoListReducer {
    public static final String TAG = TodoListReducer.class.getSimpleName();

    @Dispatchable(AddTodoAction.class)
    public TodoList onAddedTodo(TodoList state, AddTodoAction action) {
        if (state.isEmpty()) {
            TodoList newState = new TodoList(state);
            newState.add(new TodoList.Todo(0, action.getText()));
            return newState;
        }
        int id = Observable.fromIterable(state)