<commit_before>/*
 *  Copyright (c) 2015 RoboSwag (<NAME>, <NAME>)
 *
 *  This file is part of RoboSwag library.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package ru.touchin.roboswag.components.navigation;

import android.content.Context;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import ru.touchin.roboswag.components.navigation.activities.ViewControllerActivity;
import ru.touchin.roboswag.components.navigation.fragments.SimpleViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.StatelessTargetedViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.StatelessViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.TargetedViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.ViewControllerFragment;
import rx.functions.Func1;

/**
 * Created by <NAME> on 07/03/2016.
 * Navigation based on {@link ViewController}s which are creating by {@link Fragment}s.
 * So basically it is just {@link FragmentNavigation} where most of fragments should be inherited from {@link ViewControllerFragment}.
 *
 * @param <TActivity> Type of activity where {@link ViewController}s should be showed.
 */
public class ViewControllerNavigation<TActivity extends ViewControllerActivity<?>> extends FragmentNavigation {

    public ViewControllerNavigation(@NonNull final Context context,
                                    @NonNull final FragmentManager fragmentManager,
                                    @IdRes final int containerViewId) {
        super(context, fragmentManager, containerViewId);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate;
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void push(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                    @NonNull final TState state) {
        addToStack(fragmentClass, null, ViewControllerFragment.createState(state), null, null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void push(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                    @Nullable final TState state,
                                                    @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addToStack(fragmentClass, null, ViewControllerFragment.createState(state), null, transactionSetup);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific target fragment.
     *
     * @param fragmentClass  Class of {@link ViewControllerFragment} to instantiate;
     * @param targetFragment Target fragment to be set as {@link Fragment#getTargetFragment()} of instantiated {@link Fragment};
     * @param state          Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>       Type of state of fragment.
     */
    public <TState extends AbstractState> void pushForResult(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                             @NonNull final Fragment targetFragment,
                                                             @NonNull final TState state) {
        addToStack(fragmentClass, targetFragment, ViewControllerFragment.createState(state),
                fragmentClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific target fragment and specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param targetFragment   Target fragment to be set as {@link Fragment#getTargetFragment()} of instantiated {@link Fragment};
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void pushForResult(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                             @NonNull final Fragment targetFragment,
                                                             @Nullable final TState state,
                                                             @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addToStack(fragmentClass, targetFragment, ViewControllerFragment.createState(state),
                fragmentClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, transactionSetup);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with {@link #TOP_FRAGMENT_TAG_MARK} tag used for simple up/back navigation.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate.
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void setAsTop(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                        @NonNull final TState state) {
        setAsTop(fragmentClass, ViewControllerFragment.createState(state), null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific transaction setup
     * and with {@link #TOP_FRAGMENT_TAG_MARK} tag used for simple up/back navigation.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate.
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void setAsTop(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                        @Nullable final TState state,
                                                        @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        setAsTop(fragmentClass, ViewControllerFragment.createState(state), transactionSetup);
    }

    /**
     * Pops all {@link Fragment}s and places new initial {@link ViewControllerFragment} on top of stack.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate;
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void setInitial(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                          @NonNull final TState state) {
        setInitial(fragmentClass, ViewControllerFragment.createState(state), null);
    }

    /**
     * Pops all {@link Fragment}s and places new initial {@link ViewControllerFragment} on top of stack with specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void setInitial(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                          @Nullable final TState state,
                                                          @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        setInitial(fragmentClass, ViewControllerFragment.createState(state), transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed.
     */
    public void pushViewController(@NonNull final Class<? extends ViewController<TActivity,
            StatelessViewControllerFragment<TActivity>>> viewControllerClass) {
        addStatelessViewControllerToStack(viewControllerClass, null, null, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link ViewControllerFragment#getState()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param state               {@link AbstractState} of {@link ViewController}'s fragment;
     * @param <TState>            Type of state of fragment.
     */
    public <TState extends AbstractState> void pushViewController(@NonNull final Class<? extends ViewController<TActivity,
            SimpleViewControllerFragment<TState, TActivity>>> viewControllerClass,
                                                                  @NonNull final TState state) {
        addViewControllerToStack(viewControllerClass, null, state, null, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;.
     */
    public void pushViewController(
            @NonNull final Class<? extends ViewController<TActivity, StatelessViewControllerFragment<TActivity>>> viewControllerClass,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addStatelessViewControllerToStack(viewControllerClass, null, null, transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link ViewControllerFragment#getState()} and with specific transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param state               {@link AbstractState} of {@link ViewController}'s fragment;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>            Type of state of fragment.
     */
    public <TState extends AbstractState> void pushViewController(
            @NonNull final Class<? extends ViewController<TActivity, SimpleViewControllerFragment<TState, TActivity>>> viewControllerClass,
            @NonNull final TState state,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addViewControllerToStack(viewControllerClass, null, state, null, transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getState()}
     * and with specific {@link TargetedViewControllerFragment#getTarget()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushStatelessTargetedViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    TargetedViewControllerFragment<AbstractState, TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment) {
        addToStack(StatelessTargetedViewControllerFragment.class, targetFragment,
                StatelessTargetedViewControllerFragment.createState(viewControllerClass),
                viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getTarget()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    StatelessTargetedViewControllerFragment<TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment) {
        addTargetedStatelessViewControllerToStack(viewControllerClass, targetFragment,
                viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getTarget()} and transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    StatelessTargetedViewControllerFragment<TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addTargetedStatelessViewControllerToStack(viewControllerClass, targetFragment,<commit_msg>Feature/push stateless targeted view controller for result (#116)<commit_after>/*
 *  Copyright (c) 2015 RoboSwag (<NAME>, <NAME>)
 *
 *  This file is part of RoboSwag library.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package ru.touchin.roboswag.components.navigation;

import android.content.Context;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import ru.touchin.roboswag.components.navigation.activities.ViewControllerActivity;
import ru.touchin.roboswag.components.navigation.fragments.SimpleViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.StatelessTargetedViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.StatelessViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.TargetedViewControllerFragment;
import ru.touchin.roboswag.components.navigation.fragments.ViewControllerFragment;
import rx.functions.Func1;

/**
 * Created by <NAME> on 07/03/2016.
 * Navigation based on {@link ViewController}s which are creating by {@link Fragment}s.
 * So basically it is just {@link FragmentNavigation} where most of fragments should be inherited from {@link ViewControllerFragment}.
 *
 * @param <TActivity> Type of activity where {@link ViewController}s should be showed.
 */
public class ViewControllerNavigation<TActivity extends ViewControllerActivity<?>> extends FragmentNavigation {

    public ViewControllerNavigation(@NonNull final Context context,
                                    @NonNull final FragmentManager fragmentManager,
                                    @IdRes final int containerViewId) {
        super(context, fragmentManager, containerViewId);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate;
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void push(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                    @NonNull final TState state) {
        addToStack(fragmentClass, null, ViewControllerFragment.createState(state), null, null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void push(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                    @Nullable final TState state,
                                                    @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addToStack(fragmentClass, null, ViewControllerFragment.createState(state), null, transactionSetup);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific target fragment.
     *
     * @param fragmentClass  Class of {@link ViewControllerFragment} to instantiate;
     * @param targetFragment Target fragment to be set as {@link Fragment#getTargetFragment()} of instantiated {@link Fragment};
     * @param state          Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>       Type of state of fragment.
     */
    public <TState extends AbstractState> void pushForResult(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                             @NonNull final Fragment targetFragment,
                                                             @NonNull final TState state) {
        addToStack(fragmentClass, targetFragment, ViewControllerFragment.createState(state),
                fragmentClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific target fragment and specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param targetFragment   Target fragment to be set as {@link Fragment#getTargetFragment()} of instantiated {@link Fragment};
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void pushForResult(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                             @NonNull final Fragment targetFragment,
                                                             @Nullable final TState state,
                                                             @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addToStack(fragmentClass, targetFragment, ViewControllerFragment.createState(state),
                fragmentClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, transactionSetup);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with {@link #TOP_FRAGMENT_TAG_MARK} tag used for simple up/back navigation.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate.
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void setAsTop(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                        @NonNull final TState state) {
        setAsTop(fragmentClass, ViewControllerFragment.createState(state), null);
    }

    /**
     * Pushes {@link ViewControllerFragment} on top of stack with specific transaction setup
     * and with {@link #TOP_FRAGMENT_TAG_MARK} tag used for simple up/back navigation.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate.
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void setAsTop(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                        @Nullable final TState state,
                                                        @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        setAsTop(fragmentClass, ViewControllerFragment.createState(state), transactionSetup);
    }

    /**
     * Pops all {@link Fragment}s and places new initial {@link ViewControllerFragment} on top of stack.
     *
     * @param fragmentClass Class of {@link ViewControllerFragment} to instantiate;
     * @param state         Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param <TState>      Type of state of fragment.
     */
    public <TState extends AbstractState> void setInitial(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                          @NonNull final TState state) {
        setInitial(fragmentClass, ViewControllerFragment.createState(state), null);
    }

    /**
     * Pops all {@link Fragment}s and places new initial {@link ViewControllerFragment} on top of stack with specific transaction setup.
     *
     * @param fragmentClass    Class of {@link ViewControllerFragment} to instantiate;
     * @param state            Specific {@link AbstractState} of {@link ViewControllerFragment};
     * @param transactionSetup Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>         Type of state of fragment.
     */
    public <TState extends AbstractState> void setInitial(@NonNull final Class<? extends ViewControllerFragment<TState, TActivity>> fragmentClass,
                                                          @Nullable final TState state,
                                                          @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        setInitial(fragmentClass, ViewControllerFragment.createState(state), transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed.
     */
    public void pushViewController(@NonNull final Class<? extends ViewController<TActivity,
            StatelessViewControllerFragment<TActivity>>> viewControllerClass) {
        addStatelessViewControllerToStack(viewControllerClass, null, null, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link ViewControllerFragment#getState()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param state               {@link AbstractState} of {@link ViewController}'s fragment;
     * @param <TState>            Type of state of fragment.
     */
    public <TState extends AbstractState> void pushViewController(@NonNull final Class<? extends ViewController<TActivity,
            SimpleViewControllerFragment<TState, TActivity>>> viewControllerClass,
                                                                  @NonNull final TState state) {
        addViewControllerToStack(viewControllerClass, null, state, null, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;.
     */
    public void pushViewController(
            @NonNull final Class<? extends ViewController<TActivity, StatelessViewControllerFragment<TActivity>>> viewControllerClass,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addStatelessViewControllerToStack(viewControllerClass, null, null, transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link ViewControllerFragment#getState()} and with specific transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param state               {@link AbstractState} of {@link ViewController}'s fragment;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TState>            Type of state of fragment.
     */
    public <TState extends AbstractState> void pushViewController(
            @NonNull final Class<? extends ViewController<TActivity, SimpleViewControllerFragment<TState, TActivity>>> viewControllerClass,
            @NonNull final TState state,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addViewControllerToStack(viewControllerClass, null, state, null, transactionSetup);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getState()}
     * and with specific {@link TargetedViewControllerFragment#getTarget()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    @SuppressWarnings("CPD-START")
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushStatelessTargetedViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    TargetedViewControllerFragment<AbstractState, TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment) {
        addToStack(StatelessTargetedViewControllerFragment.class, targetFragment,
                StatelessTargetedViewControllerFragment.createState(viewControllerClass),
                viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getTarget()}.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    @SuppressWarnings("CPD-END")
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    StatelessTargetedViewControllerFragment<TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment) {
        addTargetedStatelessViewControllerToStack(viewControllerClass, targetFragment,
                viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, null);
    }

    /**
     * Pushes {@link ViewController} on top of stack with specific {@link StatelessTargetedViewControllerFragment#getTarget()} and transaction setup.
     *
     * @param viewControllerClass Class of {@link ViewController} to be pushed;
     * @param targetFragment      {@link ViewControllerFragment} to be set as target;
     * @param transactionSetup    Function to setup transaction before commit. It is useful to specify transition animations or additional info;
     * @param <TTargetState>      Type of state of target fragment. State is using to affect on that fragment;
     * @param <TTargetFragment>   Type of target fragment.
     */
    public <TTargetState extends AbstractState,
            TTargetFragment extends ViewControllerFragment<? extends TTargetState, TActivity>> void pushViewControllerForResult(
            @NonNull final Class<? extends ViewController<TActivity,
                    StatelessTargetedViewControllerFragment<TTargetState, TActivity>>> viewControllerClass,
            @NonNull final TTargetFragment targetFragment,
            @Nullable final Func1<FragmentTransaction, FragmentTransaction> transactionSetup) {
        addTargetedStatelessViewControllerToStack(viewControllerClass, targetFragment,
{'fraction_non_alphanumeric': 0.07305155142926949, 'fraction_numerical': 0.0017407769362325922, 'mean_word_length': 3.058123683232123, 'pattern_counts': {'":': 0, '<': 167, '<?xml version=': 0, '>': 167, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 64, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6545160', 'n_tokens_mistral': 7408, 'n_tokens_neox': 7277, 'n_words': 2558}