text:
#ifndef UTILS_HPP
#define UTILS_HPP

#include <string>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <sstream>
#include <iostream>

namespace utils {

template<class...> struct voider { using type = void; };
template<class... T> using void_t = typename voider<T...>::type;
// template<class...> using void_t = void;

#define mp_hasfn_with_signature_declare(FNNAME)                         \
    template<typename, typename T>                                      \
    struct mp_hasfn_with_signature_##FNNAME##_t {                       \
        static_assert(                                                  \
            std::integral_constant<T, false>::value,                    \
            "Second template parameter needs to be of function type."); \
    };                                                                  \
                                                                        \
    template<typename C, typename Ret, typename... Args>                \
    struct mp_hasfn_with_signature_##FNNAME##_t<C, Ret(Args...)> {      \
    private:                                                            \
    template<typename T>                                                \
    static inline constexpr auto check(T*)                              \
        -> typename                                                     \
        std::is_same<decltype(std::declval<T>().FNNAME(std::declval<Args>()... )), \
                     Ret                                                \
                     >::type                                            \
        {return {};}                                                    \
                                                                        \
    template<typename>                                                  \
    static inline constexpr std::false_type check(...){return {};}      \
                                                                        \
    typedef decltype(check<C>(0)) type;                                 \
                                                                        \
    public:                                                             \
    static constexpr bool value = type::value;                          \
    };                                                                  \
    template<class... T>                                                \
    inline constexpr bool mp_hasfn_with_signature_##FNNAME() {          \
        return mp_hasfn_with_signature_##FNNAME##_t<T...>::value;       \
    }

#define mp_hasfn_with_signature(CLASS, FNNAME, FN)  \
    mp_hasfn_with_signature_##FNNAME<CLASS, FN>()

#define mp_hasfn_with_params_declare(FNNAME)                            \
    template<typename C, typename... Args>                              \
    struct mp_hasfn_with_params_##FNNAME##_t {                          \
    private:                                                            \
    template<class T, class = void>                                     \
    struct mp_hasfunction_ : std::false_type {};                        \
                                                                        \
    template<class T>                                                   \
    struct mp_hasfunction_<T,                                           \
                           void_t<                                      \
                              decltype(                                 \
                                  std::declval<T&>().FNNAME(std::declval<Args>()...))>> \
        : std::true_type {};                                                     \
                                                                        \
    public:                                                             \
    using type = typename mp_hasfunction_<C>::type;                     \
    static constexpr bool value = type::value;                          \
    };                                                                  \
    template<class... T>                                                \
    constexpr bool mp_hasfn_with_params_##FNNAME() {                    \
        return mp_hasfn_with_params_##FNNAME##_t<T...>::value;          \
    }

#define mp_hasfn_with_params(CLASS, FNNAME, FN)  \
    mp_hasfn_with_params_##FNNAME<CLASS, FN>()

mp_hasfn_with_params_declare(push_back);
mp_hasfn_with_params_declare(push_front);
mp_hasfn_with_params_declare(insert);
mp_hasfn_with_params_declare(append);
mp_hasfn_with_params_declare(erase);
mp_hasfn_with_params_declare(pop_front);
mp_hasfn_with_params_declare(pop_back);
mp_hasfn_with_params_declare(reserve);
mp_hasfn_with_params_declare(at);
mp_hasfn_with_params_declare(find);
mp_hasfn_with_signature_declare(to_string);
mp_hasfn_with_signature_declare(toString);
mp_hasfn_with_signature_declare(at);
mp_hasfn_with_signature_declare(data);
mp_hasfn_with_params_declare(begin);

template<class T>
using ContainerElemT =
    typename std::decay<decltype(*std::begin(std::declval<T&>()))>::type;

/*******************************************************************************
 * size
 *******************************************************************************/

template<std::size_t N>
inline auto size_(const char(&param)[N]) -> std::size_t
{
    return std::string(param).size();
}

template<class T>
inline auto size_(const T& param) -> std::size_t
{
    return param.size();
}

inline auto size() -> std::size_t
{
    return 0;
}

template<class T, class... Args>
inline auto size(const T& param, Args&&... args) -> std::size_t
{
    return size_(param) + size(std::forward<Args>(args)...);
}

/*******************************************************************************
 * empty
 *******************************************************************************/

template<std::size_t N>
inline auto empty_(const char(&param)[N]) -> bool
{
    return std::string(param).empty();
}

template<class T>
inline auto empty_(const T& param) -> bool
{
    return param.empty();
}

inline auto empty() -> bool
{
    return false;
}

template<class T, class... Args>
inline auto empty(const T& param, Args&&... args) -> bool
{
    return empty_(param) || empty(std::forward<Args>(args)...);
}

namespace nocopy {

/*******************************************************************************
 * push_back
 *******************************************************************************/

template<class T, class V>
inline auto push_back_inner(T& list, V&& value) ->
    typename std::enable_if<
        decltype(list.push_back(std::forward<V>(value)), true){true},
        void
    >::type
{
    list.push_back(std::forward<V>(value));
}

template<class T, class V>
inline auto push_back_inner(T& list, V&& value) ->
    typename std::enable_if<
        decltype(list.insert(std::forward<V>(value)), true){true},
        void
    >::type
{
    list.insert(std::forward<V>(value));
}

inline auto push_back_inner(std::string& list, const std::string& value) -> void
{
    list.append(value);
}

template<class T, class V>
inline auto push_back_inner(T& list, const V& value) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ContainerElemT<V>>::value &&
        !std::is_array<T>::value && !std::is_array<V>::value,
        void
    >::type
{
    for (auto&& e : value) {
        push_back_inner(list, e);
    }
}

template<class T>
inline auto push_back(T&) -> void
{

}

template<class T, class V, class... Args>
inline auto push_back(T& list, V&& value, Args&&... args) -> void
{
    push_back_inner(list, std::forward<V>(value));
    push_back(list, std::forward<Args>(args)...);
}

/*******************************************************************************
 * push_front
 *******************************************************************************/

template<class T, class V>
inline auto push_front_inner(T& list, V&& value) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, push_front, V) &&
        std::is_same<ContainerElemT<T>, typename std::decay<V>::type>::value,
        void
    >::type
{
    list.push_front(std::forward<V>(value));
}

template<class T, class V>
inline auto push_front_inner(T& list, V&& value) ->
    typename std::enable_if<
        decltype(list.insert(std::begin(list), std::forward<V>(value)), true){true},
        void
    >::type
{
    list.insert(std::begin(list), std::forward<V>(value));
}

inline auto push_front_inner(std::string& list, const std::string& value) -> void
{
    list.insert(0, value);
}

template<class T, class V>
inline auto push_front_inner(T& list, V&& value) ->
    typename std::enable_if<
        decltype(list.insert(std::size_t{0}, std::forward<V>(value)), true){true},
        void
    >::type
{
    list.insert(0, std::forward<V>(value));
}

template<class T, class V>
inline auto push_front_inner(T& list, const V& value) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ContainerElemT<V>>::value &&
        !std::is_array<T>::value && !std::is_array<V>::value,
        void
    >::type
{
    for (auto&& e : value) {
        push_front_inner(list, e);
    }
}

template<class T>
inline auto push_front(T&) -> void
{

}

template<class T, class V, class... Args>
inline auto push_front(T& list, V&& value, Args&&... args) -> void
{
    push_front_inner(list, std::forward<V>(value));
    push_front(list, std::forward<Args>(args)...);
}

/*******************************************************************************
 * insert
 *******************************************************************************/

template<class T, class V>
inline auto insert_inner(T& list, const std::size_t i, V&& value) ->
    typename std::enable_if<
        mp_hasfn_with_params_insert<
            T,
            decltype(std::begin(list)),
            typename std::decay<V>::type>() &&
        !std::is_array<V>::value,
        void
    >::type
{
    if (i == 0) {
        push_front(list, std::forward<V>(value));
    }
    else if (i >= size(list)) {
        push_back(list, std::forward<V>(value));
    }
    else {
        auto it = std::begin(list);
        std::advance(it, std::min(i, size(list)));
        list.insert(it, std::forward<V>(value));
    }
}

template<class T, class V>
inline auto insert_inner(T& list, std::size_t i, const V& value) ->
    typename std::enable_if<
        mp_hasfn_with_params_insert<
            T,
            decltype(std::begin(list)),
            ContainerElemT<V>>() &&
        !std::is_array<V>::value,
        void
    >::type
{
    if (i >= size(list)) {
        for (auto&& e : value) {
            push_back(list, e);
        }
    }
    else {
        for (auto&& e : value) {
            auto it = std::begin(list);
            std::advance(it, std::min(i, size(list)));
            insert_inner(list, i, e);
            i++;
        }
    }
}

inline auto insert_inner(std::string& list, const std::size_t i, const std::string& value) ->
    void
{
    if (i == 0) {
        push_front(list, value);
    }
    else if (i >= size(list)) {
        push_back(list, value);
    }
    else {
        list.insert(i, value);
    }
}

template<class T>
inline auto insert(T& list, const std::size_t i) -> void
{

}

template<class T, class V, class... Args>
inline auto insert(T& list, const std::size_t i, V&& v, Args&&... args) -> void
{
    insert_inner(list, i, std::forward<V>(v));
    insert(list, i, std::forward<Args>(args)...);
}

/*******************************************************************************
 * pop_front
 *******************************************************************************/

template<class T>
inline auto pop_front(T& list) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, pop_front, void),
        void
    >::type
{
    if (list.empty()) {
        return;
    }

    list.pop_front();
}

template<class T>
inline auto pop_front(T& list) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, erase, decltype(std::begin(list))),
        void
    >::type
{
    if (list.empty()) {
        return;
    }

    list.erase(std::begin(list));
}

/*******************************************************************************
 * pop_back
 *******************************************************************************/

template<class T>
inline auto pop_back(T& list) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, pop_back, void),
        void
    >::type
{
    if (list.empty()) {
        return;
    }

    list.pop_back();
}

template<class T>
inline auto pop_back(T& list) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, erase, decltype(std::begin(list))),
        void
    >::type
{
    if (list.empty()) {
        return;
    }

    auto it = std::begin(list);
    std::advance(it, size(list) - 1);
    list.erase(it);
}

/*******************************************************************************
 * remove_n
 *******************************************************************************/

template<class T>
inline auto remove_n(T& list, const std::size_t i) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, erase, decltype(std::begin(list))),
        void
    >::type
{
    if (i >= size(list)) {
        return;
    }
    auto it = std::begin(list);
    std::advance(it, std::min(i, size(list)));
    list.erase(it);
}

/*******************************************************************************
 * remove
 *******************************************************************************/

template<class T, class ValueT>
inline auto remove_(T& list, const ValueT& value) ->
    typename std::enable_if<
        !std::is_array<ValueT>::value &&
        std::is_same<ContainerElemT<T>, ValueT>::value,
        void
    >::type
{
    auto it = std::find(std::begin(list), std::end(list), value);
    if (it != std::end(list)) {
        list.erase(it);
    }
}

template<class T, class V>
inline auto remove_(T& list1, const V& list2) ->
    typename std::enable_if<
        !std::is_array<V>::value &&
        std::is_same<ContainerElemT<T>, ContainerElemT<V>>::value,
        void
    >::type
{
    for (const auto& e : list2) {
        remove_(list1, e);
    }
}

inline auto remove_(std::string& list, const std::string& value) -> void
{
    if (size(value) > size(list)) {
        return;
    }

    auto found = list.find(value);
    if (found != std::string::npos) {
        auto it1 = std::begin(list);
        auto it2 = std::begin(list);
        std::advance(it1, found);
        std::advance(it2, found + size(value));
        list.erase(it1, it2);
    }
}

template<class T>
inline auto remove(T&& value) -> void
{

}

template<class T, class V, class... Args>
inline auto remove(T& list, const V& value, Args&&... args) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, erase, decltype(std::begin(list))),
        void
    >::type
{
    remove_(list, value);
    remove(list, std::forward<Args>(args)...);
}

/*******************************************************************************
 * reserve
 *******************************************************************************/

template<class T, class SizeT>
inline auto reserve(T&, const SizeT) ->
    typename std::enable_if<
        !mp_hasfn_with_params(T, reserve, SizeT),
        void
    >::type
{

}

template<class T, class SizeT>
inline auto reserve(T& list, const SizeT value) -> decltype(list.reserve(value), (void)0)
{
    list.reserve(value);
}

/*******************************************************************************
 * filter
 *******************************************************************************/

template<class T, class Fn>
inline auto filter(Fn fn, T& list) -> void
{
    list.erase(std::copy_if(
                   std::begin(list),
                   std::end(list),
                   std::begin(list),
                   std::forward<Fn>(fn)),
               std::end(list));
}

/*******************************************************************************
 * sort
 *******************************************************************************/

template<class T>
inline auto sort(T& list) -> void
{
    std::sort(
        std::begin(list),
        std::end((list)));
}

template<class T, class Comparator>
inline auto sort(Comparator&& comparator, T& list) -> void
{
    std::sort(
        std::begin(list),
        std::end(list),
        std::forward<Comparator>(comparator));
}

/*******************************************************************************
 * map
 *******************************************************************************/

template<class Fn, class T>
inline auto map(Fn fn, T& list) -> void
{
    list.erase(
        std::transform(std::begin(list), std::end(list), std::begin(list), fn),
        std::end(list));
}

/*******************************************************************************
 * foreach
 *******************************************************************************/

template<class Fn, template<class...> class T, class... U>
inline auto foreach(Fn fn, const T<U...>& list) -> void
{
    for (const auto& elem : list) {
        fn(elem);
    }
}

/*******************************************************************************
 * take
 *******************************************************************************/

template<class T>
inline auto take(T& list, const std::size_t N) -> void
{
    list.erase(std::copy_n(
                   std::begin(list),
                   N,
                   std::begin(list)),
               std::end(list));
}

/*******************************************************************************
 * take_while
 *******************************************************************************/

template<class T, class Fn>
inline auto take_while(T& list, Fn fn) -> void
{
    auto it = std::begin(list);

    for (const auto& elem : list) {
        if (not fn(elem)) {
            break;
        }

        ++it;
    }

    list.erase(it, std::end(list));
}

/*******************************************************************************
 * drop
 *******************************************************************************/

template<class T>
inline auto drop(T& list, const std::size_t N) -> void
{
    auto it = std::begin(list);

    std::size_t i = 0;
    while (it != std::end(list) and i++ < N) {
        ++it;
    }

    list.erase(std::begin(list), it);
}

/*******************************************************************************
 * drop_while
 *******************************************************************************/

template<class T, class Fn>
inline auto drop_while(T& list, Fn fn) -> void
{
    auto it = std::begin(list);

    while (it != std::end(list) and fn(*it)) {
        ++it;
    }

    list.erase(std::begin(list), it);
}

/*******************************************************************************
 * tail
 *******************************************************************************/

template<class T>
inline auto tail(T& list) -> void
{
    pop_front(list);
}

/*******************************************************************************
 * slice
 *******************************************************************************/

template<class T>
inline auto slice_inner(T& list, std::int64_t i) -> std::int64_t
{
    if (list.empty()) {
        return 0;
    }

    if (i < 0) {
        if (static_cast<std::size_t>(-i) >= size(list)) {
            i = 0;
        }
        else {
            i = size(list) - -i;
        }
    }

    return i;
}

template<class T>
inline auto slice_inner(const T& list, std::int64_t i, std::int64_t j) ->
    std::pair<std::int64_t, std::int64_t>
{
    if (list.empty()) {
        return {0, size(list)};
    }

    if (i < 0) {
        if (static_cast<std::size_t>(-i) >= size(list)) {
            i = 0;
        }
        else {
            i = size(list) - -i;
        }
    }
    else {
        if (static_cast<std::size_t>(i) >= size(list)) {
            return {};
        }
    }

    if (j < 0) {
        if (static_cast<std::size_t>(-j) >= size(list)) {
            return {};
        }
        else {
            j = size(list) - -j;
        }
    }
    else {
        if (static_cast<std::size_t>(j) >= size(list)) {
            j = size(list);
        }
    }

    if (i > j) {
        return {};
    }

    return {i, j};
}

template<class T>
inline auto slice(T&) -> void
{

}

template<class T>
inline auto slice(T& list, const std::int64_t i) -> void
{
    auto it = std::begin(list);
    std::advance(it, nocopy::slice_inner(list, i));

    list.erase(std::begin(list), it);
}

template<class T>
inline auto slice(T& list, const std::int64_t i, const std::int64_t j) -> void
{
    const auto ij = slice_inner(list, i, j);

    auto it1 = std::begin(list);
    std::advance(it1, ij.first);
    list.erase(std::begin(list), it1);

    auto it2 = std::begin(list);
    std::advance(it2, ij.second - ij.first);
    list.erase(it2, std::end(list));
}

/*******************************************************************************
 * combine
 *******************************************************************************/

template<class T, class... Args>
inline auto combine(T&& list1, Args... args) -> void
{
    nocopy::push_back(std::forward<T>(list1), std::forward<Args>(args)...);
}

} // namespace nocopy

/*******************************************************************************
 * push_front
 *******************************************************************************/

template<class T, class... Args>
inline auto push_front(const T& list, Args&&... args) -> T
{
    T result{list};
    nocopy::push_front(result, std::forward<Args>(args)...);
    return result;
}

template<class... Args>
inline auto push_front(const std::string& list, Args&&... args) -> std::string
{
    std::string result{list};
    nocopy::push_front(result, std::forward<Args>(args)...);
    return result;
}

/*******************************************************************************
 * push_back
 *******************************************************************************/

template<class T, class... Args>
inline auto push_back(const T& list, Args&&... args) -> T
{
    T result{list};
    nocopy::push_back(result, std::forward<Args>(args)...);
    return result;
}

template<class... Args>
inline auto push_back(const std::string& list, Args&&... args) -> std::string
{
    std::string result{list};
    nocopy::push_back(result, std::forward<Args>(args)...);
    return result;
}

/*******************************************************************************
 * pop_back
 *******************************************************************************/

template<class T>
inline auto pop_back(const T& list) -> T
{
    T result{list};
    nocopy::pop_back(result);
    return result;
}

template<std::size_t N>
inline auto pop_back(const char(&s)[N]) -> std::string
{
    std::string result{s};
    nocopy::pop_back(result);
    return result;
}

/*******************************************************************************
 * pop_front
 *******************************************************************************/

template<class T>
inline auto pop_front(const T& list) -> T
{
    T result{list};
    nocopy::pop_front(result);
    return result;
}

template<std::size_t N>
inline auto pop_front(const char(&s)[N]) -> std::string
{
    std::string result{s};
    nocopy::pop_front(result);
    return result;
}

/*******************************************************************************
 * insert
 *******************************************************************************/

template<class T, class... Args>
inline auto insert(const T& param, const std::size_t i, Args&&... args) -> T
{
    T result{param};
    nocopy::insert(result, i, std::forward<Args>(args)...);
    return result;
}

template<class... Args>
inline auto insert(const std::string& param, const std::size_t i, Args&&... args) ->
    std::string
{
    std::string result{param};
    nocopy::insert(result, i, std::forward<Args>(args)...);
    return result;
}

/*******************************************************************************
 * remove_n
 *******************************************************************************/

template<class T, class V>
inline auto remove_n(const T& list, const V i) ->
    typename std::enable_if<
        !std::is_floating_point<V>::value,
        T
    >::type
{
    T result{list};
    nocopy::remove_n(result, i);
    return result;
}

template<std::size_t N, class V>
inline auto remove_n(const char(&s)[N], const V i) ->
    typename std::enable_if<
        !std::is_floating_point<V>::value,
        std::string
    >::type
{
    std::string result{s};
    nocopy::remove_n(result, i);
    return result;
}

/*******************************************************************************
 * remove
 *******************************************************************************/

template<class T, class V, class... Args>
inline auto remove(const T& list, const V& value, Args&&... args) -> T
{
    T result{list};
    nocopy::remove(result, value);
    nocopy::remove(result, std::forward<Args>(args)...);
    return result;
}

template<class V, class... Args>
inline auto remove(const std::string& list, const V& value, Args&&... args) -> std::string
{
    std::string result{list};
    nocopy::remove(result, value);
    nocopy::remove(result, std::forward<Args>(args)...);
    return result;
}

/*******************************************************************************
 * reserve
 *******************************************************************************/

template<class... Args>
inline auto reserve(Args&& ...args) -> void
{
    nocopy::reserve(std::forward<Args>(args)...);
}

/*******************************************************************************
 * filter
 *******************************************************************************/

template<class FilterFn, class T>
inline auto filter(FilterFn filter, const T& list) -> typename std::decay<T>::type
{
    typename std::decay<T>::type result;
    reserve(result, size(list));

    for (const auto& elem : list) {
        if (filter(elem)) {
            nocopy::push_back(result, elem);
        }
    }

    return result;
}

template<class FilterFn, class T>
inline auto filter(FilterFn filter, T&& list) -> typename std::decay<T>::type
{
    typename std::decay<T>::type result;
    reserve(result, utils::size(list));

    for (auto&& elem : list) {
        if (filter(elem)) {
            nocopy::push_back(result, std::move(elem));
        }
    }

    return result;
}

/*******************************************************************************
 * sort
 *******************************************************************************/

template<class T>
inline auto sort(T&& list) -> typename std::decay<T>::type
{
    typename std::decay<T>::type result(std::forward<T>(list));
    nocopy::sort(result);
    return result;
}

template<class T, class Comparator>
inline auto sort(Comparator&& comparator, T&& list) -> typename std::decay<T>::type
{
    typename std::decay<T>::type result(std::forward<T>(list));
    nocopy::sort(std::forward<Comparator>(comparator), result);
    return result;
}

/*******************************************************************************
 * convert
 *******************************************************************************/

template<class ResultT, class T>
inline auto convert(T&& list) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ContainerElemT<ResultT>>::value,
        ResultT
    >::type
{
    return ResultT(std::begin(list), std::end(list));
}

/*******************************************************************************
 * map
 *******************************************************************************/

template<class Fn, template<class...> class T, class... U>
inline auto map(Fn fn, const T<U...>& list) -> T<decltype(fn(*std::begin(list)))>
{
    T<decltype(fn(*std::begin(list)))> result;
    for (const auto& elem : list) {
        nocopy::push_back(result, fn(elem));
    }
    return result;
}

/*******************************************************************************
 * combine
 *******************************************************************************/

template<class T, class... Args>
inline auto combine(const T& list1, Args... args) -> T
{
    T result;
    nocopy::push_back(result, list1, std::forward<Args>(args)...);
    return result;
}

template<class... Args>
inline auto combine(const std::string& list1, Args... args) -> std::string
{
    std::string result{};
    nocopy::push_back(result, list1, std::forward<Args>(args)...);
    return result;
}

/*******************************************************************************
 * to_string
 *******************************************************************************/

template<class T>
inline auto to_string(const T& value) ->
    decltype(std::to_string(value))
{
    return std::to_string(value);
}

template<class T>
inline auto to_string(const T& value) ->
    typename std::enable_if<
        !std::is_scalar<T>::value,
        decltype(std::declval<std::ostream&>() << value, std::string{})
        >::type
{
    std::ostringstream out;
    out << value;
    return out.str();
}

template<class T>
inline auto to_string(const T& value) ->
    typename std::enable_if<
        mp_hasfn_with_signature(T, to_string, std::string(void)),
        std::string
        >::type
{
    return value.to_string();
}

template<class T>
inline auto to_string(const T& value) ->
    typename std::enable_if<
        mp_hasfn_with_signature(T, toString, std::string(void)),
        std::string
        >::type
{
    return value.toString();
}

template<template<class...> class T, class V, class... Args>
inline auto to_string(const T<V, Args...>& value) ->
    typename std::enable_if<
        std::is_same<T<V, Args...>, std::vector<V, Args...>>::value,
        std::string
    >::type
{
    std::string result;
    for (auto it = std::begin(value); it != std::end(value); ++it) {
        if (not result.empty()) {
            result += ",";
        }
        result += to_string(*it);
    }
    return "[" + result + "]";
}

template<template<class...> class T, class V, class... Args>
inline auto to_string(const T<V, Args...>& value) ->
    typename std::enable_if<
        std::is_same<T<V, Args...>, std::set<V, Args...>>::value,
        std::string
    >::type
{
    std::string result;
    for (auto it = std::begin(value); it != std::end(value); ++it) {
        if (not result.empty()) {
            result += ",";
        }
        result += to_string(*it);
    }
    return "{" + result + "}";
}

template<template<class...> class T, class V, class... Args>
inline auto to_string(const T<V, Args...>& value) ->
    typename std::enable_if<
        std::is_same<T<V, Args...>, std::map<V, Args...>>::value,
        std::string
    >::type
{
    std::string result;
    for (auto it = std::begin(value); it != std::end(value); ++it) {
        if (not result.empty()) {
            result += ",\n";
        }
        result += "  " + to_string(it->first) + ": " + to_string(it->second);
    }
    return "{\n" + result + "\n}";
}

template<template<class...> class T, class V, class... Args>
inline auto to_string(const T<V, Args...>& value) ->
    typename std::enable_if<
        std::is_same<T<V, Args...>, std::unordered_map<V, Args...>>::value,
        std::string
    >::type
{
    std::string result;
    for (auto it = std::begin(value); it != std::end(value); ++it) {
        if (not result.empty()) {
            result += ",\n";
        }
        result += "  " + to_string(it->first) + ": " + to_string(it->second);
    }
    return "#{\n" + result + "\n}";
}

/*******************************************************************************
 * contains
 *******************************************************************************/

template<class T, std::size_t Size, class ValueT>
inline auto contains_(const std::array<T, Size>& list, const ValueT& value) ->
    typename std::enable_if<
        decltype(*std::begin(list), bool{}){true},
        bool
    >::type
{
    return std::find(std::begin(list), std::end(list), value) != std::end(list);
}

template<template<class...> class T, class ValueT, class... L>
inline auto contains_(const T<ValueT, L...>& list, const ValueT& value) ->
    typename std::enable_if<
        decltype(*std::begin(list), bool{}){true},
        bool
    >::type
{
    return std::find(std::begin(list), std::end(list), value) != std::end(list);
}

inline auto contains_(const std::string& list, const std::string& value) -> bool
{
    return list.find(value) != std::string::npos;
}

template<class T, class U>
inline auto contains_(const T& list, const U& list2) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ContainerElemT<U>>::value &&
        decltype(list2.empty(), bool{}){true} &&
        decltype(*std::begin(list), *std::begin(list2), bool{}){true},
        bool
    >::type
{
    if (list2.empty()) {
        return true;
    }

    for (auto it = std::begin(list); it != std::end(list); ++it) {
        if (static_cast<std::size_t>(
                std::abs(
                    std::distance(it, std::end(list)))) < size(list2)) {
            return false;
        }

        bool yes = true;
        auto itk = it;

        for (auto it2 = std::begin(list2); it2 != std::end(list2); ++itk, ++it2) {
            if (*itk != *it2) {
                yes = false;
                break;
            }
        }

        if (yes) {
            return true;
        }
    }
    return false;
}

template<std::size_t N, class V>
inline auto contains_(const char(&s)[N], V&& value) ->
    typename std::enable_if<
        std::is_same<V, char>::value,
        bool
    >::type
{
    for (const char& ch : s) {
        if (ch == value) {
            return true;
        }
    }
    return false;
}

template<std::size_t N, class V>
inline auto contains_(V&& values, const char(&s)[N]) -> bool
{
    return contains_(std::forward<V>(values), std::string(s));
}

template<class T>
inline auto contains(const T&) -> bool
{
    return true;
}

template<class T, class U, class... Args>
inline auto contains(T&& list, U&& list2, Args&&... args) -> bool
{
    return
        contains_(std::forward<T>(list), std::forward<U>(list2)) and
        contains(std::forward<T>(list), std::forward<Args>(args)...);
}

template<class U, class... Args>
inline auto contains(const std::string& list, U&& list2, Args&&... args) -> bool
{
    return
        contains_(list, std::forward<U>(list2)) and
        contains(list, std::forward<Args>(args)...);
}

/*******************************************************************************
 * contains_if
 *******************************************************************************/

template<class T,  class U>
inline auto contains_if_(T&& lambda, U&& values) -> bool
{
    for (const auto& value : values) {
        if (lambda(value)){
            return true;
        }
    }
    return false;
}

template<class T>
inline auto contains_if(T&&) -> bool
{
    return true;
}

template<class T,  class U, class... Args>
inline auto contains_if(T&& lambda, U&& values, Args&&... args) -> bool
{
    return
        contains_if_(std::forward<T>(lambda), std::forward<U>(values)) and
        contains_if(std::forward<T>(lambda), std::forward<Args>(args)...);
}

/*******************************************************************************
 * index
 *******************************************************************************/

template<class T, class ValueT>
inline auto index(T&& list, const ValueT& value) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ValueT>::value,
        std::size_t
     >::type
{
    std::size_t index = 0;
    for (const auto& elem : list) {
        if (elem == value) {
            return index;
        }
        index++;
    }
    return -1;
}

template<class T, class ValueT>
auto index(T&& list, const ValueT& value, const std::size_t start_i) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ValueT>::value,
        std::size_t
    >::type
{
    if (start_i >= size(list)) {
        return -1;
    }

    std::size_t index = 0;
    for (const auto& elem : list) {
        if (index < start_i) {
            index++;
            continue;
        }
        if (elem == value) {
            return index;
        }
        index++;
    }
    return -1;
}

inline auto index(const std::string& s, const std::string& value) ->
    std::size_t
{
    return s.find(value);
}

inline auto index(const std::string& s, const std::string& value, const std::size_t start_i) ->
    std::size_t
{
    if (start_i >= size(s)) {
        return -1;
    }
    return s.find(value, start_i);
}

/*******************************************************************************
 * find
 *******************************************************************************/

template<class T, class ValueT>
inline auto find(T&& list, const ValueT& value) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ValueT>::value,
        ValueT*
     >::type
{
    for (const auto& elem : list) {
        if (elem == value) {
            return const_cast<ValueT*>(&elem);
        }
    }
    return nullptr;
}

/*******************************************************************************
 * find_if
 *******************************************************************************/

template<class T, class FindFn>
inline auto find_if(FindFn fn, const T& list) -> decltype(&list.at(0))
{
    for (auto& elem : list) {
        if (fn(elem)) {
            return &elem;
        }
    }
    return nullptr;
}

/*******************************************************************************
 * get
 *******************************************************************************/

template<class T, class ValueT>
inline auto get(const T& list, const ValueT& value) ->
    typename std::enable_if<
        !std::is_array<T>::value &&
        std::is_same<ContainerElemT<T>, ValueT>::value,
        ValueT&
    >::type
{
    for (const auto& elem : list) {
        if (elem == value) {
            return *const_cast<ValueT*>(&elem);
        }
    }
    throw std::runtime_error(
        "Value does not exists in list.");
}

template<std::size_t N, class V>
inline auto get(const char(&s)[N], const V value) ->
    typename std::enable_if<
        sizeof(V) == sizeof(char),
        const char&
    >::type
{
    for (const char& c : s) {
        if (c == value) {
            return c;
        }
    }
    throw std::runtime_error(
        "No value found in literal string.");
}

/*******************************************************************************
 * nth
 *******************************************************************************/

template<class T>
inline auto nth(const T& list, const std::size_t N) ->
    typename std::decay<decltype(*std::begin(list))>::type&
{
    std::size_t i = 0;
    for (const auto& elem : list) {
        if (i < N) {
            ++i;
            continue;
        }
        return const_cast<typename std::decay<decltype(*std::begin(list))>::type&>(elem);
    }
    throw std::runtime_error(
        "nth: it is a wrong element position. [" + to_string(N) + "]");
}

/*******************************************************************************
 * get_if
 *******************************************************************************/

template<template<class...> class T, class ValueT, class... L, class FindFn>
inline auto get_if(FindFn fn, const T<ValueT, L...>& list) -> ValueT&
{
    for (const auto& elem : list) {
        if (fn(elem)) {
            return *const_cast<ValueT*>(&elem);
        }
    }
    throw std::runtime_error(
        "Value does not exists in the list.");
}

/*******************************************************************************
 * count
 *******************************************************************************/

template<class T, class ValueT>
inline auto count(const ValueT& val, const T& param) ->
    typename std::enable_if<
        decltype(std::begin(param), true){true},
        std::size_t
    >::type
{
    return
        std::count(
            std::begin(param),
            std::end(param),
            val);
}

template<class ValueT, class T>
inline auto count(const ValueT& value, const T& param) ->
    typename std::enable_if<
        decltype(value == param, true){true},
        std::size_t
    >::type
{
    return value == param ? 1 : 0;
}

template<class ValueT, class T, class... Args>
inline auto count(const ValueT& value, const T& param, Args&&... args) -> std::size_t
{
    return count(value, param) + count(value, std::forward<Args>(args)...);
}

/*******************************************************************************
 * count_if
 *******************************************************************************/

template<class T, class Fn>
inline auto count_if(Fn pred, const T& param) ->
    typename std::enable_if<
        decltype(std::begin(param), true){true},
        std::size_t
    >::type
{
    return
        std::count_if(
            std::begin(param),
            std::end(param),
            pred);
}

template<class Fn, class T>
inline auto count_if(const Fn& fn, const T& param) ->
    typename std::enable_if<
        decltype(fn(param), true){true},
        std::size_t
    >::type
{
    return fn(param) ? 1 : 0;
}

template<class Fn, class T, class... Args>
inline auto count_if(Fn fn, const T& param, Args&&... args) -> std::size_t
{
    return count_if(fn, param) + count_if(fn, std::forward<Args>(args)...);
}

/*******************************************************************************
 * all
 *******************************************************************************/

template<class T>
inline auto all(const T& param) ->
    typename std::enable_if<
        decltype(static_cast<bool>(param), true){true},
        bool
    >::type
{
    return param;
}

template<class T>
inline auto all(const T& param) ->
    typename std::enable_if<
        decltype(static_cast<bool>(*std::begin(param)), true){true},
        bool
    >::type
{
    for (const auto& e : param) {
        if (not all(e)) {
            return false;
        }
    }
    return true;
}

template<class T, class... Args>
inline auto all(const T& param, Args&&... args) -> bool
{
    return all(param) and all(std::forward<Args>(args)...);
}

/*******************************************************************************
 * all_if
 *******************************************************************************/

template<class T, class Fn>
inline auto all_if(Fn pred, const T& param) ->
    typename std::enable_if<
        decltype(static_cast<bool>(param), true){true},
        bool
    >::type
{
    return param;
}

template<class T, class Fn>
inline auto all_if(Fn pred, const T& container) ->
    typename std::enable_if<
        decltype(std::begin(container), true){true},
        bool
    >::type
{
    return
        std::all_of(
            std::begin(container),
            std::end(container),
            std::forward<Fn>(pred));
}

template<class Fn, class T, class... Args>
inline auto all_if(Fn pred, const T& param, Args&&... args) -> bool
{
    return all_if(pred, param) and all_if(pred, std::forward<Args>(args)...);
}

/*******************************************************************************
 * any
 *******************************************************************************/

template<class T>
inline auto any(const T& param) ->
    typename std::enable_if<
        decltype(static_cast<bool>(param), true){true},
        bool
    >::type
{
    return param;
}

template<class T>
inline auto any(const T& param) ->
    typename std::enable_if<
        decltype(std::begin(param), true){true},
        bool
    >::type
{
    for (auto&& e : param) {
        if (any(e)) {
            return true;
        }
    }
    return false;
}

template<class T, class... Args>
inline auto any(const T& param, Args&&... args) -> bool
{
    return any(param) or any(std::forward<Args>(args)...);
}

/*******************************************************************************
 * any_if
 *******************************************************************************/

template<class T, class Fn>
inline auto any_if(Fn pred, const T& param) ->
    typename std::enable_if<
        decltype(static_cast<bool>(param), true){true},
        bool
    >::type
{
    return param;
}

template<class T, class Fn>
inline auto any_if(Fn pred, const T& param) ->
    typename std::enable_if<
        decltype(std::begin(param), true){true},
        bool
    >::type
{
    return
        std::any_of(
            std::begin(param),
            std::end(param),
            std::forward<Fn>(pred));
}

template<class Fn, class T, class... Args>
inline auto any_if(Fn pred, const T& param, Args&&... args) -> bool
{
    return any_if(pred, param) or any_if(pred, std::forward<Args>(args)...);
}

/*******************************************************************************
 * is_sorted
 *******************************************************************************/

template<class Container>
inline auto is_sorted(const Container& container) -> bool
{
    return
        std::is_sorted(
            std::begin(container),
            std::end(container));
}

template<class Container, class Compare>
inline auto is_sorted(const Container& container, Compare&& comp) -> bool
{
    return
        std::is_sorted(
            std::begin(container),
            std::end(container),
            std::forward<Compare>(comp));
}

template<std::size_t N>
inline auto is_sorted(const char(&s)[N]) -> bool
{
    if (N == 1 or N == 2) {
        return true;
    }

    return is_sorted(std::string{s});
}

/*******************************************************************************
 * reduce
 *******************************************************************************/

template<class Container, class T>
inline auto reduce(const Container& container, T&& init) -> T
{
    for (const auto& elem : container) {
        init += elem;
    }
    return init;
}

template<class Container, class T, class BinaryOperation>
inline auto reduce(const Container& container, T&& init, const BinaryOperation& op) -> T
{
    for (const auto& elem : container) {
        init = op(std::forward<T>(init), elem);
    }
    return std::move(init);
}

/*******************************************************************************
 * flatten
 *******************************************************************************/

template<class T>
inline auto flatten(const T& list) -> ContainerElemT<T>
{
    ContainerElemT<T> result;
    for (const auto& elem : list) {
        result = combine(result, elem);
    }
    return result;
}

/*******************************************************************************
 * join
 *******************************************************************************/

template<template<class...> class T, class N, class... L>
inline auto join(const T<N, L...>& list, const std::string& delimiter = "") ->
    decltype(to_string(*std::begin(list)), std::string{})
{
    std::string result;
    for (const auto& elem : list) {
        if (not result.empty()) {
            result += delimiter;
        }
        result += to_string(elem);
    }
    return result;
}

inline auto join(const std::string& s) -> std::string
{
    return s;
}

/*******************************************************************************
 * split
 *******************************************************************************/

inline auto split(const std::string& text, const std::string& delims = " ") ->
    std::vector<std::string>
{
    std::vector<std::string> tokens;

    auto end = text.find_first_of(delims);
    decltype(end) start = 0;

    while (end != std::string::npos) {
        tokens.push_back(text.substr(start, end - start));

        start = end + 1;

        if (start == text.size()) {
            break;
        }

        end = text.find_first_of(delims, end + 1);
    }

    if (start != std::string::npos and not text.empty()) {
        tokens.push_back(text.substr(start));
    }

    return tokens;
}

/*******************************************************************************
 * ltrim
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto ltrim(T& s) -> void
{
    const auto wsfront = std::find_if_not(begin(s), end(s), ::isspace);
    s.erase(std::begin(s), wsfront);
}

} // namespace nocopy

template<class T>
inline auto ltrim(const T& s) -> T
{
    const auto wsfront=std::find_if_not(begin(s), end(s), ::isspace);
    const auto wsback=std::end(s);
    return wsback <= wsfront ? T{} : T{wsfront,wsback};
}

template<std::size_t N>
inline auto ltrim(const char(&s)[N]) -> std::string
{
    return ltrim(std::string{s});
}

/*******************************************************************************
 * rtrim
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto rtrim(T& s) -> void
{
    std::size_t i = size(s) - 1;
    while (i > 0 and ::isspace(s[i])) {
        i--;
    }
    if (i == 0 and ::isspace(s[i])) {
        s.clear();
    }
    auto wsback = std::begin(s);
    std::advance(wsback, i + 1);
    s.erase(wsback, std::end(s));
}

} // namespace nocopy

template<class T>
inline auto rtrim(const T& s) -> T
{
    const auto wsfront=std::begin(s);
    std::size_t i = size(s) - 1;
    while (i > 0 and ::isspace(s[i])) {
        i--;
    }
    if (i == 0 and ::isspace(s[i])) {
        return T{};
    }
    auto wsback = std::begin(s);
    std::advance(wsback, i + 1);
    return wsback <= wsfront ? T{} : T{wsfront,wsback};
}

template<std::size_t N>
inline auto rtrim(const char(&s)[N]) -> std::string
{
    return rtrim(std::string{s});
}

/*******************************************************************************
 * trim
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto trim(T& s) -> void
{
    if (s.empty()) {
        return;
    }

    const auto wsfront = std::find_if_not(std::begin(s), std::end(s), ::isspace);
    s.erase(std::begin(s), wsfront);

    std::size_t i = size(s) - 1;
    while (i > 0 and ::isspace(s[i])) {
        i--;
    }
    if (i == 0 and ::isspace(s[i])) {
        s.clear();
    }
    auto wsback = std::begin(s);
    std::advance(wsback, i + 1);
    s.erase(wsback, std::end(s));
}

} // namespace nocopy

template<class T>
inline auto trim(const T& s) -> T
{
    if (s.empty()) {
        return "";
    }

    const auto wsfront=std::find_if_not(begin(s),end(s), ::isspace);

    std::size_t i = size(s) - 1;
    while (i > 0 and ::isspace(s[i])) {
        i--;
    }
    if (i == 0 and ::isspace(s[i])) {
        return T{};
    }
    auto wsback = std::begin(s);
    std::advance(wsback, i + 1);

    return wsback <= wsfront ? T{} : T{wsfront,wsback};
}

template<std::size_t N>
inline auto trim(const char(&s)[N]) -> std::string
{
    return trim(std::string{s});
}

/*******************************************************************************
 * to_lower
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto to_lower(T& s) -> decltype(T().begin(), (void)1)
{
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}

} // namespace nocopy

template<class T>
inline auto to_lower(const T& s) -> decltype(T().begin(), T())
{
    T result(s);
    nocopy::to_lower(result);
    return result;
}

template<std::size_t N>
inline auto to_lower(const char(&s)[N]) -> std::string
{
    return to_lower(std::string{s});
}

/*******************************************************************************
 * to_upper
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto to_upper(T& s) -> decltype(T().begin(), (void)1)
{
    std::transform(s.begin(), s.end(), s.begin(), ::toupper);
}

} // namespace nocopy

template<class T>
inline auto to_upper(const T& s) -> decltype(T().begin(), T())
{
    T result(s);
    nocopy::to_upper(result);
    return result;
}

template<std::size_t N>
inline auto to_upper(const char(&s)[N]) -> std::string
{
    return to_upper(std::string{s});
}

/*******************************************************************************
 * starts_with
 *******************************************************************************/

template<class T, class U>
inline auto starts_with(const T& where, const U& what) ->
    typename std::enable_if<
        !mp_hasfn_with_params(T, find, ContainerElemT<U>) &&
        std::is_same<ContainerElemT<T>, ContainerElemT<U>>::value &&
        !std::is_array<T>::value && !std::is_array<U>::value,
        bool
    >::type
{
    auto it = std::begin(where);
    auto it2 = std::begin(what);

    for (;it2 != std::end(what) && it != std::end(where); it++, it2++) {
        if (*it != *it2) {
            return false;
        }
    }

    return it2 == std::end(what);
}

template<class T, class U>
inline auto starts_with(const T& where, const U& what) ->
    typename std::enable_if<
        !mp_hasfn_with_params(T, find, U) &&
        decltype(std::begin(where), true){true} &&
        !std::is_array<T>::value && !std::is_array<U>::value &&
        std::is_same<ContainerElemT<T>, U>::value,
        bool
    >::type
{
    auto it = std::find(std::begin(where), std::end(where), what);
    return it == std::begin(where);
}

template<class T>
inline auto starts_with(const T& where, const T& what) ->
    typename std::enable_if<
        decltype(where.find(what), true){true} &&
        !std::is_same<T, std::string>::value,
        bool
    >::type
{
    return where.find(what) == 0;
}

inline auto starts_with(const std::string& where, const std::string& what) -> bool
{
    return where.find(what) == 0;
}

/*******************************************************************************
 * ends_with
 *******************************************************************************/

template<class T, class U>
inline auto ends_with(const T& where, const U& what) ->
    typename std::enable_if<
        std::is_same<ContainerElemT<T>, ContainerElemT<U>>::value &&
        !std::is_array<T>::value && !std::is_array<U>::value,
        bool
    >::type
{
    if (size(where) < size(what)) {
        return false;
    }

    auto it = std::begin(where);
    auto it2 = std::begin(what);

    std::advance(it, size(where) - size(what));

    for (;it2 != std::end(what) && it != std::end(where); it++, it2++) {
        if (*it != *it2) {
            return false;
        }
    }

    return it2 == std::end(what);
}

template<class T, class U>
inline auto ends_with(const T& where, const U& what) ->
    typename std::enable_if<
        !mp_hasfn_with_params(T, find, U) &&
        decltype(std::begin(where), true){true} &&
        !std::is_array<T>::value && !std::is_array<U>::value &&
        std::is_same<ContainerElemT<T>, U>::value,
        bool
    >::type
{
    if (empty(where)) {
        return false;
    }
    auto it = std::begin(where);
    std::advance(it, size(where) - 1);
    return *it == what;
}

template<class T>
inline auto ends_with(const T& where, const T& what) ->
    typename std::enable_if<
        decltype(where.find_last_of(what), true){true} &&
        !std::is_same<T, std::string>::value,
        bool
    >::type
{
    return size(where) - 1 - where.find_last_of(what) == 0;
}

inline auto ends_with(const std::string& where, const std::string& what) -> bool
{
    return size(where) - 1 - where.find_last_of(what) == 0;
}

/*******************************************************************************
 * capitalize
 *******************************************************************************/

namespace nocopy {

template<class T>
inline auto capitalize(T& s) ->
    typename std::enable_if<
        mp_hasfn_with_signature(T, at, const char&(std::size_t)) ||
        mp_hasfn_with_signature(T, at, char&(std::size_t)),
        void
    >::type
{
    nocopy::to_lower(s);
    if (not s.empty()) {
        s[0] = ::toupper(s.at(0));
    }
}

} // namespace nocopy

template<class T>
inline auto capitalize(const T& s) ->
    typename std::enable_if<
        mp_hasfn_with_signature(T, at, const char&(std::size_t)) ||
        mp_hasfn_with_signature(T, at, char&(std::size_t)),
        T
    >::type
{
    T result{s};
    nocopy::capitalize(result);
    return result;
}

template<std::size_t N>
inline auto capitalize(const char(&s)[N]) -> std::string
{
    return capitalize(std::string{s});
}

/*******************************************************************************
 * take
 *******************************************************************************/

template<class T>
inline auto take(const T& list, const std::size_t N) -> T
{
    if (N >= size(list)) {
        return list;
    }

    T result;
    reserve(result, N);

    for (std::size_t i = 0; i < N; ++i) {
        nocopy::push_back(result, list[i]);
    }

    return result;
}

template<std::size_t N>
inline auto take(const char(&s)[N], const std::size_t i) -> std::string
{
    return take(std::string{s}, i);
}

/*******************************************************************************
 * take_while
 *******************************************************************************/

template<class T, class Fn>
inline auto take_while(const T& list, Fn fn) -> T
{
    T result;

    for (const auto& elem : list) {
        if (not fn(elem)) {
            break;
        }

        nocopy::push_back(result, elem);
    }

    return result;
}

template<std::size_t N, class Fn>
inline auto take_while(const char(&s)[N], Fn&& fn) -> std::string
{
    return take_while(std::string{s}, std::forward<Fn>(fn));
}

/*******************************************************************************
 * drop
 *******************************************************************************/

template<class T>
inline auto drop(const T& list, const std::size_t N) -> T
{
    if (N >= size(list)) {
        return T{};
    }

    T result;
    reserve(result, size(list) - N);

    for (std::size_t i = N; i < size(list); ++i) {
        nocopy::push_back(result, list[i]);
    }

    return result;
}

template<std::size_t N>
inline auto drop(const char(&s)[N], const std::size_t i) -> std::string
{
    return drop(std::string{s}, i);
}

/*******************************************************************************
 * drop_while
 *******************************************************************************/

template<class T, class Fn>
inline auto drop_while(const T& list, Fn fn) -> T
{
    T result;

    std::size_t i = 0;

    for (; i < size(list); ++i) {
        if (not fn(list[i])) {
            break;
        }
    }

    for (; i < size(list); ++i) {
        nocopy::push_back(result, list[i]);
    }

    return result;
}

template<std::size_t N, class Fn>
inline auto drop_while(const char(&s)[N], Fn&& fn) -> std::string
{
    return drop_while(std::string{s}, std::forward<Fn>(fn));
}

/*******************************************************************************
 * slice
 *******************************************************************************/

template<class T>
inline auto slice(const T& list) -> T
{
    return list;
}

template<class T>
inline auto slice(const T& list, const std::int64_t i) -> T
{
    auto it = std::begin(list);
    std::advance(it, nocopy::slice_inner(list, i));

    return T{it, std::end(list)};
}

template<class T>
inline auto slice(const T& list, const std::int64_t i, const std::int64_t j) -> T
{
    const auto ij = nocopy::slice_inner(list, i, j);

    auto it1 = std::begin(list);
    std::advance(it1, ij.first);

    auto it2 = std::begin(list);
    std::advance(it2, ij.second);

    return T{it1, it2};
}

template<class T, class... Args>
inline auto slice(const T& list, Args&&... args) ->
    typename std::enable_if<
        std::is_array<T>::value,
        std::string
    >::type
{
    return slice(std::string{list}, std::forward<Args>(args)...);
}

/*******************************************************************************
 * front
 *******************************************************************************/

template<class T>
inline auto front(const T& list) -> ContainerElemT<T>&
{
    if (not list.empty()) {
        return const_cast<ContainerElemT<T>&>(*std::begin(list));
    }

    throw std::runtime_error("Container is empty.");
}

template<std::size_t N>
inline auto front(const char(&s)[N]) -> const char&
{
    return s[0];
}

/*******************************************************************************
 * back
 *******************************************************************************/

template<class T>
inline auto back(const T& list) -> ContainerElemT<T>&
{
    if (not list.empty()) {
        return const_cast<ContainerElemT<T>&>(*list.rbegin());
    }

    throw std::runtime_error("Container is empty.");
}

template<std::size_t N>
inline auto back(const char(&s)[N]) -> const char&
{
    return s[N - 2];
}

/*******************************************************************************
 * tail
 *******************************************************************************/

template<class T>
inline auto tail(const T& list) -> T
{
    T result {list};
    nocopy::pop_front(result);
    return result;
}

/*******************************************************************************
 * max
 *******************************************************************************/

template<class T>
inline auto max(const T& param) -> std::size_t
{
    return param;
}

template<class T>
inline auto max(const T& param1, const T& param2) ->
    typename std::enable_if<
        decltype(std::max(param1, param2), true){true},
        std::size_t
    >::type
{
    return std::max(param1, param2);
}

template<class T, class... Args>
inline auto max(const T& param1, const T& param2, Args&&... args) -> std::size_t
{
    return std::max(max(param1, param2), max(std::forward<Args>(args)...));
}

/*******************************************************************************
 * min
 *******************************************************************************/

template<class T>
inline auto min(const T& param) -> T
{
    return param;
}

template<class T>
inline auto min(const T& param1, const T& param2) ->
    typename std::enable_if<
        decltype(std::min(param1, param2), true){true},
        T
    >::type
{
    return std::min(param1, param2);
}

template<class T, class... Args>
inline auto min(const T& param1, const T& param2, Args&&... args) -> T
{
    return std::min(min(param1, param2), min(std::forward<Args>(args)...));
}

/*******************************************************************************
 * is_number
 *******************************************************************************/

inline auto is_number(const std::string& s) -> bool
{
    auto it = std::begin(s);
    while (it != std::end(s) and std::isdigit(*it)) {
        ++it;
    }
    return not empty(s) and it == std::end(s);
}

/*******************************************************************************
 * std::map
 *******************************************************************************/

template<class T, class K>
inline auto get(const T& param, const K& key) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, at, typename T::key_type) &&
        !std::is_array<T>::value,
        typename T::mapped_type&
    >::type
{
    try {
        return const_cast<typename std::decay<typename T::mapped_type>::type&>(param.at(key));
    } catch (const std::out_of_range& e) {
        throw std::runtime_error(
            "Value does not exists in list.");
    }
}

template<class T, class K>
inline auto find(const T& param, const K& key) ->
    typename std::enable_if<
        mp_hasfn_with_params(T, at, typename T::key_type) &&
        !std::is_array<T>::value,
        typename T::mapped_type*
    >::type
{
    auto it = param.find(key);
    if (it == std::end(param)) {
        return nullptr;
    }
    return &param.at(key);
}

template<class T>
inline auto keys(const T& param) ->
    typename std::enable_if<
        decltype(std::declval<typename T::key_type>(), true){true} &&
        !std::is_array<T>::value,
        std::vector<typename std::decay<typename T::key_type>::type>
    >::type
{
    std::vector<typename std::decay<typename T::key_type>::type> result;
    for (auto it = std::begin(param); it != std::end(param); ++it) {
        nocopy::push_back(result, it->first);
    }
    return result;
}

template<class T>
inline auto values(const T& param) ->
    typename std::enable_if<
        decltype(std::declval<typename T::mapped_type>(), true){true} &&
        !std::is_array<T>::value,
        std::vector<typename std::decay<typename T::mapped_type>::type>
    >::type
{
    std::vector<typename std::decay<typename T::mapped_type>::type> result;
    for (auto it = std::begin(param); it != std::end(param); ++it) {
        nocopy::push_back(result, it->second);
    }
    return result;
}

} // namespace utils

#endif // UTILS_HPP


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <title>CPackNSIS — CMake 3.7.1 Documentation</title>

    <link rel="stylesheet" href="../_static/cmake.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />

    <link rel="shortcut icon" href="../_static/cmake-favicon.ico"/>
    <link rel="top" title="CMake 3.7.1 Documentation" href="../index.html" />
    <link rel="up" title="cmake-modules(7)" href="../manual/cmake-modules.7.html" />
    <link rel="next" title="CPackPackageMaker" href="CPackPackageMaker.html" />
    <link rel="prev" title="CPackIFW" href="CPackIFW.html" />

Navigation

          index

          next |

          previous |

    CMake »

    3.7.1 Documentation »

cmake-modules(7) »

CPackNSIS¶

CPack NSIS generator specific options

Variables specific to CPack NSIS generator¶

The following variables are specific to the graphical installers built
on Windows using the Nullsoft Installation System.

CPACK_NSIS_INSTALL_ROOT¶

The default installation directory presented to the end user by the NSIS
installer is under this root dir. The full directory presented to the end
user is: ${CPACK_NSIS_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}

CPACK_NSIS_MUI_ICON¶

An icon filename.  The name of a *.ico file used as the main icon for the
generated install program.

CPACK_NSIS_MUI_UNIICON¶

An icon filename.  The name of a *.ico file used as the main icon for the
generated uninstall program.

CPACK_NSIS_INSTALLER_MUI_ICON_CODE¶

undocumented.

CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP¶

The filename of a bitmap to use as the NSIS MUI_WELCOMEFINISHPAGE_BITMAP.

CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP¶

The filename of a bitmap to use as the NSIS MUI_UNWELCOMEFINISHPAGE_BITMAP.

CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS¶

Extra NSIS commands that will be added to the beginning of the install
Section, before your install tree is available on the target system.

CPACK_NSIS_EXTRA_INSTALL_COMMANDS¶

Extra NSIS commands that will be added to the end of the install Section,
after your install tree is available on the target system.

CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS¶

Extra NSIS commands that will be added to the uninstall Section, before
your install tree is removed from the target system.

CPACK_NSIS_COMPRESSOR¶

The arguments that will be passed to the NSIS SetCompressor command.

CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL¶

Ask about uninstalling previous versions first.  If this is set to “ON”,
then an installer will look for previous installed versions and if one is
found, ask the user whether to uninstall it before proceeding with the
install.

CPACK_NSIS_MODIFY_PATH¶

Modify PATH toggle.  If this is set to “ON”, then an extra page will appear
in the installer that will allow the user to choose whether the program
directory should be added to the system PATH variable.

CPACK_NSIS_DISPLAY_NAME¶

The display name string that appears in the Windows Add/Remove Program
control panel

CPACK_NSIS_PACKAGE_NAME¶

The title displayed at the top of the installer.

CPACK_NSIS_INSTALLED_ICON_NAME¶

A path to the executable that contains the installer icon.

CPACK_NSIS_HELP_LINK¶

URL to a web site providing assistance in installing your application.

CPACK_NSIS_URL_INFO_ABOUT¶

URL to a web site providing more information about your application.

CPACK_NSIS_CONTACT¶

Contact information for questions and comments about the installation
process.

CPACK_NSIS_<compName>_INSTALL_DIRECTORY<a class="headerlink" href="#variable:CPACK_NSIS_<compName>_INSTALL_DIRECTORY" title="Permalink to this definition">¶

Custom install directory for the specified component <compName> instead
of $INSTDIR.

CPACK_NSIS_CREATE_ICONS_EXTRA¶

Additional NSIS commands for creating start menu shortcuts.

CPACK_NSIS_DELETE_ICONS_EXTRA¶

Additional NSIS commands to uninstall start menu shortcuts.

CPACK_NSIS_EXECUTABLES_DIRECTORY¶

Creating NSIS start menu links assumes that they are in ‘bin’ unless this
variable is set.  For example, you would set this to ‘exec’ if your
executables are in an exec directory.

CPACK_NSIS_MUI_FINISHPAGE_RUN¶

Specify an executable to add an option to run on the finish page of the
NSIS installer.

CPACK_NSIS_MENU_LINKS¶

Specify links in [application] menu.  This should contain a list of pair
“link” “link name”. The link may be an URL or a path relative to
installation prefix.  Like:

set(CPACK_NSIS_MENU_LINKS
    "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
    "CMake Help" "https://cmake.org" "CMake Web Site")

Table Of Contents

CPackNSIS

Variables specific to CPack NSIS generator

Previous topic

CPackIFW

Next topic

CPackPackageMaker

This Page

Show Source

Quick search

    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>

    Enter search terms or a module, class or function name.

Navigation

          index

          next |

          previous |

    CMake »

    3.7.1 Documentation »

cmake-modules(7) »

        © Copyright 2000-2016 Kitware, Inc. and Contributors.
      Created using Sphinx 1.4a0+.

redpajama_set_name: RedPajamaGithub


text:
import React, { Component } from 'react'
import {
  View,
  Text,
  StatusBar,
  Image,
  FlatList
} from 'react-native'
import styles from '../uitls/styles'
import ProfileItem from '../components/ProfileItem'
import { images } from '../uitls/assets'

const dataProfile = [
  {key: 1, title: 'Email address', value: 'nguyencse.ninhhoa@example.com'},
  {key: 2, title: 'Telephone', value: '01672345678'},
  {key: 3, title: 'Notifications', value: ''},
  {key: 4, title: 'Settings', value: ''},
  {key: 5, title: 'Feedback', value: ''},
  {key: 6, title: 'Get help', value: ''},
  {key: 7, title: 'Delete account', value: ''},
]

export default class Contacts extends Component {
  constructor(props){
    super(props)
    avatar = images.avatarDefault.uri
  }

  render() {
    return (
      <View style={styles.container}>
        <StatusBar hidden />
        <View style={styles.profileHeader}>
          <View style={styles.profileAvatarContainer}>
            <Image source={avatar} style={styles.profileAvatar}/>
          </View>
          <Text style={styles.profileName}>David James</Text>
          <Text numberOfLines={2} style={styles.profileSummary}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</Text>
        </View>
        <View style={styles.profileMenuContainer}>
          <FlatList
            data={dataProfile}
            renderItem={({ item }) =>  <ProfileItem item={item}/>}
          />
        </View>
      </View>
    )
  }
}


text:
<?php

/**
 * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
 * case of a skipped test.
 *
 * @since Class available since Release 3.0.0
 */
class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
{
}


text:
package sk.tomsik68.mclauncher.impl.login.legacy;

import sk.tomsik68.mclauncher.api.common.MCLauncherAPI;
import sk.tomsik68.mclauncher.api.login.IProfile;
import sk.tomsik68.mclauncher.api.login.IProfileIO;
import sk.tomsik68.mclauncher.util.FileUtils;

import java.io.*;

@Deprecated
public final class LegacyProfileIO implements IProfileIO {
    private final LegacyLoginEncryptionProcessor proc;
    private final File dest;

    public LegacyProfileIO(File mcInstance) {
        proc = new LegacyLoginEncryptionProcessor();
        dest = new File(mcInstance, "lastlogin");
    }

    @Override
    public IProfile[] read() throws Exception {
        String user, pass;
        DataInputStream input = new DataInputStream(proc.decrypt(new FileInputStream(dest)));
        user = input.readUTF();
        pass = input.readUTF();
        input.close();
        return new IProfile[]{new LegacyProfile(user, pass)};
    }

    @Override
    public void write(IProfile[] profile) throws Exception {
        // warn the developer if they want to save more profiles
        if(profile.length > 1){
            MCLauncherAPI.log.warning("Saving multiple profiles using LegacyProfileIO is not possible! MCLauncherAPI will only save the one that is 0th in the array. Other profiles won't be saved!");
        }
        // create the file if it doesn't exist
        if (!dest.exists()) {
            MCLauncherAPI.log.fine("lastlogin file doesn't exist. Creating it...");
            FileUtils.createFileSafely(dest);
            MCLauncherAPI.log.fine("lastlogin file created.");
        }
        // write the profile as 2 UTF strings encrypted with LegacyLoginEncryptionProcessor
        DataOutputStream out = new DataOutputStream(proc.encrypt(new FileOutputStream(dest)));
        out.writeUTF(profile[0].getName());
        out.writeUTF(profile[0].getPassword());
        out.flush();
        out.close();
    }

}


text:
template<typename T> using U = int &;

template<typename T, int Size> void f() {
  T x1;
  T* x2;
  T& x3; // expected-error{{declaration of reference variable 'x3' requires an initializer}}
  T x4[]; // expected-error{{needs an explicit size or an initializer}}
  T x5[Size];
  int x6[Size];
  U<T> x7; // expected-error{{declaration of reference variable 'x7' requires an initializer}}
}


text:
package de.alpharogroup.wicket.behaviors;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.util.resource.IResourceStream;

/**
 * This behavior enables us to initiate the download after the AJAX request has been completed.
 *
 * Inspired from @see https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+
 * download+in+one+blow.
 **/
public abstract class AjaxDownloadBehavior extends AbstractAjaxBehavior
{

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The anti cache. */
	private boolean antiCache;

	/**
	 * Instantiates a new {@link AjaxDownloadBehavior}.
	 */
	public AjaxDownloadBehavior()
	{
		this(true);
	}

	/**
	 * Instantiates a new {@link AjaxDownloadBehavior}.
	 *
	 * @param antiCache
	 *            the anti cache
	 */
	public AjaxDownloadBehavior(final boolean antiCache)
	{
		this.antiCache = antiCache;
	}

	/**
	 * Hook method for a file name which will let the browser prompt with a save/open dialog.
	 *
	 * @return the file name
	 */
	protected abstract String getFileName();

	/**
	 * Hook method providing the actual resource stream.
	 *
	 * @return the resource stream.
	 */
	protected abstract IResourceStream getResourceStream();

	/**
	 * Call this method to initiate the download.
	 *
	 * @param target
	 *            the {@link AjaxRequestTarget}
	 */
	public void initiate(final AjaxRequestTarget target)
	{
		String url = getCallbackUrl().toString();

		if (antiCache)
		{
			url = url + (url.contains("?") ? "&" : "?");
			url = url + "antiCache=" + System.currentTimeMillis();
		}
		// the timeout is needed to let Wicket release the channel
		target.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void onRequest()
	{
		final ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(
			getResourceStream(), getFileName());
		handler.setContentDisposition(ContentDisposition.ATTACHMENT);
		getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
	}
}


text:
package org.apache.geode.internal.sequencelog.model;

import java.io.Serializable;

import org.apache.geode.internal.sequencelog.GraphType;

/**
 *
 */
public class GraphID implements Comparable<GraphID>, Serializable {

  public final GraphType type;
  public final String graphName;

  public GraphID(GraphType type, String graphName) {
    this.type = type;
    this.graphName = graphName;
  }

  public GraphType getType() {
    return type;
  }

  public String getGraphName() {
    return graphName;
  }

  @Override
  public String toString() {
    return graphName;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((graphName == null) ? 0 : graphName.hashCode());
    result = prime * result + ((type == null) ? 0 : type.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (!(obj instanceof GraphID))
      return false;
    GraphID other = (GraphID) obj;
    if (graphName == null) {
      if (other.graphName != null)
        return false;
    } else if (!graphName.equals(other.graphName))
      return false;
    if (type == null) {
      if (other.type != null)
        return false;
    } else if (!type.equals(other.type))
      return false;
    return true;
  }

  public int compareTo(GraphID o) {
    if (o == null) {
      return -1;
    }
    int result = type.compareTo(o.getType());
    if (result != 0) {
      return result;
    }
    return graphName.compareTo(o.getGraphName());
  }

}


text:
import React from 'react';
import { QueryRenderer, graphql } from 'react-relay/compat';
import Relay from 'react-relay/classic';
import PropTypes from 'prop-types';
import SlackConfigDialogComponent from './SlackConfigDialogComponent';

const SlackConfigDialog = ({ teamSlug, onCancel }) => (
  <QueryRenderer
    environment={Relay.Store}
    query={graphql`
      query SlackConfigDialogQuery($teamSlug: String!) {
        team(slug: $teamSlug) {
          ...SlackConfigDialogComponent_team
        }
      }
    `}
    variables={{
      teamSlug,
    }}
    render={({ props }) => {
      if (props) {
        return (<SlackConfigDialogComponent team={props.team} onCancel={onCancel} />);
      }
      return null;
    }}
  />
);

SlackConfigDialog.propTypes = {
  teamSlug: PropTypes.string.isRequired,
  onCancel: PropTypes.func.isRequired,
};

export default SlackConfigDialog;


text:
var assert = require('assert');
var EventStream = require('../lib/event_stream');

describe("Event Stream", function() {
  beforeEach(function() {
    this.assertStreamPairBehavior = function(assert, instance, secondInstance) {
      var exampleState = {
        instanceOne: undefined,
        instanceTwo: undefined,
        instanceThree: undefined,
        secondInstance: undefined
      };

      var exampleListeners = {
        instanceOne: function(x) { exampleState.instanceOne = x },
        instanceTwo: function(x) { exampleState.instanceTwo = x },
        instanceThree: function(x) { exampleState.instanceThree = x; },
        secondInstance: function(x) { exampleState.secondInstance = x; }
      };

      instance.on('foo', exampleListeners.instanceOne);
      instance.publish('foo', 42);

      assert(exampleState.instanceOne === 42);
      assert(exampleState.instanceTwo === undefined);
      assert(exampleState.instanceThree === undefined);
      assert(exampleState.secondInstance === undefined);

      secondInstance.on('foo', exampleListeners.secondInstance);
      secondInstance.publish('foo', 86);

      assert(exampleState.instanceOne === 42);
      assert(exampleState.secondInstance === 86);

      instance.on('foo', exampleListeners.instanceTwo);
      instance.publish('foo', 40);

      assert(exampleState.instanceOne === 40);
      assert(exampleState.instanceTwo === 40);
      assert(exampleState.secondInstance === 86);

      instance.on('bar', exampleListeners.instanceThree);
      instance.publish('bar', 100);
      assert(exampleState.instanceOne === 40);
      assert(exampleState.instanceTwo === 40);
      assert(exampleState.instanceThree === 100);
      assert(exampleState.secondInstance === 86);

      instance.unregisterAllCallbacks();
      instance.publish('foo', 500);
      instance.publish('bar', 86);
      secondInstance.publish('foo', 24);
      assert(exampleState.instanceOne === 40);
      assert(exampleState.instanceTwo === 40);
      assert(exampleState.instanceThree === 100);
      assert(exampleState.secondInstance === 24);

      instance.on('foo', exampleListeners.instanceOne);
      instance.publish('foo', 500);
      assert(exampleState.instanceOne === 500);
      assert(exampleState.instanceTwo === 40);
      assert(exampleState.instanceThree === 100);
      assert(exampleState.secondInstance === 24);
    };

    this.assertFirstInFirstOutBehavior = function(assert, stream) {
      var firstCalled = false,
          secondAfter = false;

      var methodOne = function() {
        firstCalled = true;
      };

      var methodTwo = function() {
        if(firstCalled) secondAfter = true;
      };

      stream.on('test', methodOne);
      stream.on('test', methodTwo);

      stream.publish('test');

      assert(secondAfter);
    };

    this.assertUnregisteringSingleSubscription = function(assert, instance) {
      var subscriberCalled = 0;
      var subscriberCallback = function() {
        subscriberCalled += 1;
      };

      var subscription = instance.on('event', subscriberCallback);
      instance.publish('event');
      assert(subscriberCalled === 1,
        'before unregister the subscription should get called - it is not.');
      subscription();
      instance.publish('event');
      assert(subscriberCalled !== 2,
        'after unregistering the subscription is getting called (wrong)');
    };

    this.assertOnlyOneSubscriptionIsUnsubscribed = function(assert, instance) {
      var firstCounter = 0;
      var secondCounter = 0;

      var firstCallback = function() { firstCounter += 1; };
      var secondCallback = function() { secondCounter += 1; };

      var eventFirstSub = instance.on('event', firstCallback);
      var eventSecondSub = instance.on('event', secondCallback);
      var eventFirstSubAgain = instance.on('event', firstCallback);
      var anotherEventSub = instance.on('event2', firstCallback);

      instance.publish('event');
      assert(firstCounter === 2,
            'Double subscription not incremented the first counter twice');
      assert(secondCounter === 1,
            'Second subscription not incremented the second counter once');

      eventSecondSub();
      instance.publish('event');

      assert(firstCounter === 4 && secondCounter === 1,
            'Unregistering the subscription for secondCounter is affecting' +
            ' the first counter subscriptions');

      eventFirstSubAgain();
      instance.publish('event');
      assert(firstCounter === 5,
        'Unregistering one of the twice defined callbacks affected the rest too');

      instance.publish('event2');
      assert(firstCounter === 6,
        'publishing event2 not invoked the associated subscription');
      anotherEventSub();

      instance.publish('event');
      assert(firstCounter === 7,
        'the subscription associated to an another event somehow affected the' +
        'another subscription');
    };

    this.assertAllSubscriptionsForEventUnsubscribed = function(assert, instance) {
      var firstCounter = 0;
      var secondCounter = 0;

      var firstCallback = function() { firstCounter += 1; };
      var secondCallback = function() { secondCounter += 1; };

      instance.on('event', firstCallback);
      instance.on('event', firstCallback);
      instance.on('event2', secondCallback);

      instance.publish('event');

      assert(firstCounter === 2)
      assert(secondCounter === 0)

      instance.unregisterCallbacksForEvent('event')
      instance.publish('event');
      instance.publish('event2');

      assert(firstCounter === 2)
      assert(secondCounter === 1)
    };
  });

  it("can be used with a factory function approach", function() {
    var instance = EventStream();
    var secondInstance = EventStream();

    assert(instance !== secondInstance);
    this.assertStreamPairBehavior(assert, instance, secondInstance);
  });

  it("can be used with the 'new' keyword approach", function() {
    var instance = new EventStream();
    var secondInstance = new EventStream();

    this.assertStreamPairBehavior(assert, instance, secondInstance);
  });

  it("calls listeners in a first in, first out fashion", function() {
    this.assertFirstInFirstOutBehavior(assert, new EventStream());
  });

  it("allows you to unregister the single subscription",
    function() {
      this.assertUnregisteringSingleSubscription(assert, new EventStream());
      this.assertOnlyOneSubscriptionIsUnsubscribed(assert, new EventStream());
  });

  it("allows you to unregister all subscriptions for given event", function () {
    this.assertAllSubscriptionsForEventUnsubscribed(assert, new EventStream());
  })

  it("allows you to unregister event handler by callback", function () {
    var firstCounter = 0
    var secondCounter = 0
    var instance = new EventStream()
    var firstCallback = function () { firstCounter += 1 }
    var secondCallback = function () { secondCounter += 1 }

    instance.on("event1", firstCallback)
    instance.on("event2", secondCallback)

    instance.unregisterCallback(firstCallback)

    instance.publish('event1')
    instance.publish('event2')

    assert.strictEqual(firstCounter, 0)
    assert.strictEqual(secondCounter, 1)
  })
});


text:
/*
 * 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 org.jdbi.v3.jodatime2;

import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.spi.JdbiPlugin;

/**
 * Register date and time providers to integrate with {@code joda-time}.
 */
public class JodaTimePlugin implements JdbiPlugin {
    @Override
    public void customizeJdbi(Jdbi db) {
        db.registerArgument(new DateTimeArgumentFactory());
        db.registerColumnMapper(new DateTimeMapper());
    }
}


text:
#ifndef CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_
#define CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_

#include <atomic>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "api/network_state_predictor.h"
#include "api/transport/network_control.h"
#include "api/units/data_rate.h"
#include "call/rtp_bitrate_configurator.h"
#include "call/rtp_transport_controller_send_interface.h"
#include "call/rtp_video_sender.h"
#include "modules/congestion_controller/rtp/control_handler.h"
#include "modules/congestion_controller/rtp/transport_feedback_adapter.h"
#include "modules/congestion_controller/rtp/transport_feedback_demuxer.h"
#include "modules/pacing/paced_sender.h"
#include "modules/pacing/packet_router.h"
#include "modules/pacing/rtp_packet_pacer.h"
#include "modules/pacing/task_queue_paced_sender.h"
#include "modules/utility/include/process_thread.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/network_route.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/task_utils/repeating_task.h"

namespace webrtc {
class Clock;
class FrameEncryptorInterface;
class RtcEventLog;

// TODO(nisse): When we get the underlying transports here, we should
// have one object implementing RtpTransportControllerSendInterface
// per transport, sharing the same congestion controller.
class RtpTransportControllerSend final
    : public RtpTransportControllerSendInterface,
      public RtcpBandwidthObserver,
      public TransportFeedbackObserver,
      public NetworkStateEstimateObserver {
 public:
  RtpTransportControllerSend(
      Clock* clock,
      RtcEventLog* event_log,
      NetworkStatePredictorFactoryInterface* predictor_factory,
      NetworkControllerFactoryInterface* controller_factory,
      const BitrateConstraints& bitrate_config,
      std::unique_ptr<ProcessThread> process_thread,
      TaskQueueFactory* task_queue_factory,
      const WebRtcKeyValueConfig* trials);
  ~RtpTransportControllerSend() override;

  RtpVideoSenderInterface* CreateRtpVideoSender(
      std::map<uint32_t, RtpState> suspended_ssrcs,
      const std::map<uint32_t, RtpPayloadState>&
          states,  // move states into RtpTransportControllerSend
      const RtpConfig& rtp_config,
      int rtcp_report_interval_ms,
      Transport* send_transport,
      const RtpSenderObservers& observers,
      RtcEventLog* event_log,
      std::unique_ptr<FecController> fec_controller,
      const RtpSenderFrameEncryptionConfig& frame_encryption_config,
      rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) override;
  void DestroyRtpVideoSender(
      RtpVideoSenderInterface* rtp_video_sender) override;

  // Implements RtpTransportControllerSendInterface
  rtc::TaskQueue* GetWorkerQueue() override;
  PacketRouter* packet_router() override;

  NetworkStateEstimateObserver* network_state_estimate_observer() override;
  TransportFeedbackObserver* transport_feedback_observer() override;
  RtpPacketSender* packet_sender() override;

  void SetAllocatedSendBitrateLimits(BitrateAllocationLimits limits) override;

  void SetPacingFactor(float pacing_factor) override;
  void SetQueueTimeLimit(int limit_ms) override;
  StreamFeedbackProvider* GetStreamFeedbackProvider() override;
  void RegisterTargetTransferRateObserver(
      TargetTransferRateObserver* observer) override;
  void OnNetworkRouteChanged(const std::string& transport_name,
                             const rtc::NetworkRoute& network_route) override;
  void OnNetworkAvailability(bool network_available) override;
  RtcpBandwidthObserver* GetBandwidthObserver() override;
  int64_t GetPacerQueuingDelayMs() const override;
  absl::optional<Timestamp> GetFirstPacketTime() const override;
  void EnablePeriodicAlrProbing(bool enable) override;
  void OnSentPacket(const rtc::SentPacket& sent_packet) override;
  void OnReceivedPacket(const ReceivedPacket& packet_msg) override;

  void SetSdpBitrateParameters(const BitrateConstraints& constraints) override;
  void SetClientBitratePreferences(const BitrateSettings& preferences) override;

  void OnTransportOverheadChanged(
      size_t transport_overhead_bytes_per_packet) override;

  void AccountForAudioPacketsInPacedSender(bool account_for_audio) override;
  void IncludeOverheadInPacedSender() override;

  // Implements RtcpBandwidthObserver interface
  void OnReceivedEstimatedBitrate(uint32_t bitrate) override;
  void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
                                    int64_t rtt,
                                    int64_t now_ms) override;

  // Implements TransportFeedbackObserver interface
  void OnAddPacket(const RtpPacketSendInfo& packet_info) override;
  void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override;

  // Implements NetworkStateEstimateObserver interface
  void OnRemoteNetworkEstimate(NetworkStateEstimate estimate) override;

 private:
  void MaybeCreateControllers() RTC_RUN_ON(task_queue_);
  void UpdateInitialConstraints(TargetRateConstraints new_contraints)
      RTC_RUN_ON(task_queue_);

  void StartProcessPeriodicTasks() RTC_RUN_ON(task_queue_);
  void UpdateControllerWithTimeInterval() RTC_RUN_ON(task_queue_);

  absl::optional<BitrateConstraints> ApplyOrLiftRelayCap(bool is_relayed);
  bool IsRelevantRouteChange(const rtc::NetworkRoute& old_route,
                             const rtc::NetworkRoute& new_route) const;
  void UpdateBitrateConstraints(const BitrateConstraints& updated);
  void UpdateStreamsConfig() RTC_RUN_ON(task_queue_);
  void OnReceivedRtcpReceiverReportBlocks(const ReportBlockList& report_blocks,
                                          int64_t now_ms)
      RTC_RUN_ON(task_queue_);
  void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(task_queue_);
  void UpdateControlState() RTC_RUN_ON(task_queue_);
  RtpPacketPacer* pacer();
  const RtpPacketPacer* pacer() const;

  Clock* const clock_;
  RtcEventLog* const event_log_;
  PacketRouter packet_router_;
  std::vector<std::unique_ptr<RtpVideoSenderInterface>> video_rtp_senders_;
  RtpBitrateConfigurator bitrate_configurator_;
  std::map<std::string, rtc::NetworkRoute> network_routes_;
  const std::unique_ptr<ProcessThread> process_thread_;
  const bool use_task_queue_pacer_;
  std::unique_ptr<PacedSender> process_thread_pacer_;
  std::unique_ptr<TaskQueuePacedSender> task_queue_pacer_;

  TargetTransferRateObserver* observer_ RTC_GUARDED_BY(task_queue_);
  TransportFeedbackDemuxer feedback_demuxer_;

  TransportFeedbackAdapter transport_feedback_adapter_
      RTC_GUARDED_BY(task_queue_);

  NetworkControllerFactoryInterface* const controller_factory_override_
      RTC_PT_GUARDED_BY(task_queue_);
  const std::unique_ptr<NetworkControllerFactoryInterface>
      controller_factory_fallback_ RTC_PT_GUARDED_BY(task_queue_);

  std::unique_ptr<CongestionControlHandler> control_handler_
      RTC_GUARDED_BY(task_queue_) RTC_PT_GUARDED_BY(task_queue_);

  std::unique_ptr<NetworkControllerInterface> controller_
      RTC_GUARDED_BY(task_queue_) RTC_PT_GUARDED_BY(task_queue_);

  TimeDelta process_interval_ RTC_GUARDED_BY(task_queue_);

  std::map<uint32_t, RTCPReportBlock> last_report_blocks_
      RTC_GUARDED_BY(task_queue_);
  Timestamp last_report_block_time_ RTC_GUARDED_BY(task_queue_);

  NetworkControllerConfig initial_config_ RTC_GUARDED_BY(task_queue_);
  StreamsConfig streams_config_ RTC_GUARDED_BY(task_queue_);

  const bool reset_feedback_on_route_change_;
  const bool send_side_bwe_with_overhead_;
  const bool add_pacing_to_cwin_;
  FieldTrialParameter<DataRate> relay_bandwidth_cap_;

  size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(task_queue_);
  bool network_available_ RTC_GUARDED_BY(task_queue_);
  RepeatingTaskHandle pacer_queue_update_task_ RTC_GUARDED_BY(task_queue_);
  RepeatingTaskHandle controller_task_ RTC_GUARDED_BY(task_queue_);

  // Protected by internal locks.
  RateLimiter retransmission_rate_limiter_;

  // TODO(perkj): |task_queue_| is supposed to replace |process_thread_|.
  // |task_queue_| is defined last to ensure all pending tasks are cancelled
  // and deleted before any other members.
  rtc::TaskQueue task_queue_;
  RTC_DISALLOW_COPY_AND_ASSIGN(RtpTransportControllerSend);
};

}  // namespace webrtc

#endif  // CALL_RTP_TRANSPORT_CONTROLLER_SEND_H_