/*******************************************************************************
 *
 *    Copyright (c) 2025 - 2026 Haixing Hu.
 *
 *    SPDX-License-Identifier: Apache-2.0
 *
 *    Licensed under the Apache License, Version 2.0.
 *
 ******************************************************************************/

// qubit-style: allow explicit-imports
//! Unit tests for StatefulMutator types

use qubit_function::{
    ArcStatefulMutator,
    BoxStatefulMutator,
    FnMutStatefulMutatorOps,
    MutatorOnce,
    RcStatefulMutator,
    StatefulMutator,
};
use std::cell::Cell;

// ============================================================================
// BoxStatefulMutator Tests
// ============================================================================

#[test]
fn test_stateful_mutator_default_conversions_allow_relaxed_generic_types() {
    #[derive(Debug)]
    struct BorrowedRc<'a> {
        value: &'a str,
    }

    #[derive(Debug)]
    struct BorrowedRcStatefulMutator {
        count: Cell<usize>,
    }

    impl Clone for BorrowedRcStatefulMutator {
        fn clone(&self) -> Self {
            Self {
                count: Cell::new(self.count.get()),
            }
        }
    }

    impl<'a> StatefulMutator<BorrowedRc<'a>> for BorrowedRcStatefulMutator {
        fn apply(&mut self, value: &mut BorrowedRc<'a>) {
            self.count.set(self.count.get() + 1);
            assert_eq!(value.value, "left");
        }
    }

    let text = String::from("left");
    let mut value = BorrowedRc {
        value: text.as_str(),
    };
    let mutator = BorrowedRcStatefulMutator {
        count: Cell::new(0),
    };

    mutator.clone().into_box().apply(&mut value);
    mutator.clone().into_rc().apply(&mut value);
    mutator.clone().into_arc().apply(&mut value);
    mutator.clone().into_once().apply(&mut value);
    let mut into_fn = mutator.clone().into_fn();
    into_fn(&mut value);

    mutator.to_box().apply(&mut value);
    mutator.to_rc().apply(&mut value);
    mutator.to_arc().apply(&mut value);
    mutator.to_once().apply(&mut value);
    let mut to_fn = mutator.to_fn();
    to_fn(&mut value);
}

#[cfg(test)]
mod test_box_mutator {
    use super::*;

    #[test]
    fn test_new() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 1);
        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_with_different_types() {
        // String
        let mut string_mutator = BoxStatefulMutator::new(|s: &mut String| s.push('!'));
        let mut text = String::from("hello");
        string_mutator.apply(&mut text);
        assert_eq!(text, "hello!");

        // Vec
        let mut vec_mutator = BoxStatefulMutator::new(|v: &mut Vec<i32>| v.push(42));
        let mut numbers = vec![1, 2, 3];
        vec_mutator.apply(&mut numbers);
        assert_eq!(numbers, vec![1, 2, 3, 42]);

        // bool
        let mut bool_mutator = BoxStatefulMutator::new(|b: &mut bool| *b = !*b);
        let mut flag = true;
        bool_mutator.apply(&mut flag);
        assert!(!flag);
    }

    #[test]
    fn test_and_then() {
        let mut mutator =
            BoxStatefulMutator::new(|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 20); // (5 * 2) + 10
    }

    #[test]
    fn test_and_then_multiple_chains() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 1)
            .and_then(|x: &mut i32| *x *= 2)
            .and_then(|x: &mut i32| *x -= 5);

        let mut value = 10;
        mutator.apply(&mut value);
        assert_eq!(value, 17); // ((10 + 1) * 2) - 5
    }

    #[test]
    fn test_and_then_with_box_consumer() {
        let c1 = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let c2 = BoxStatefulMutator::new(|x: &mut i32| *x += 10);
        let mut combined = c1.and_then(c2);

        let mut value = 5;
        combined.apply(&mut value);
        assert_eq!(value, 20);
    }

    #[test]
    fn test_noop() {
        let mut noop = BoxStatefulMutator::<i32>::noop();
        let mut value = 42;
        noop.apply(&mut value);
        assert_eq!(value, 42);
    }

    #[test]
    fn test_noop_with_different_types() {
        // Test with String
        let mut noop = BoxStatefulMutator::<String>::noop();
        let mut text = String::from("hello");
        noop.apply(&mut text);
        assert_eq!(text, "hello");

        // Test with Vec
        let mut noop = BoxStatefulMutator::<Vec<i32>>::noop();
        let mut numbers = vec![1, 2, 3];
        noop.apply(&mut numbers);
        assert_eq!(numbers, vec![1, 2, 3]);
    }

    #[test]
    fn test_noop_chaining() {
        let mut chained = BoxStatefulMutator::<i32>::noop()
            .and_then(|x: &mut i32| *x *= 2)
            .and_then(BoxStatefulMutator::<i32>::noop());

        let mut value = 5;
        chained.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_if_then_true() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 10).when(|x: &i32| *x > 0);

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_if_then_false() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 10).when(|x: &i32| *x > 0);

        let mut value = -5;
        mutator.apply(&mut value);
        assert_eq!(value, -5); // unchanged
    }

    #[test]
    fn test_if_then_else() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x = -*x);

        let mut positive = 10;
        mutator.apply(&mut positive);
        assert_eq!(positive, 20);

        let mut negative = -10;
        mutator.apply(&mut negative);
        assert_eq!(negative, 10);
    }

    #[test]
    fn test_into_box() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.into_box();
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_into_rc() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut rc = mutator.into_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_new_with_name() {
        let mut mutator =
            BoxStatefulMutator::new_with_name("box_stateful_test", |x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), Some("box_stateful_test"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_some() {
        let mut mutator = BoxStatefulMutator::new_with_optional_name(
            |x: &mut i32| *x += 1,
            Some("box_optional".to_string()),
        );
        assert_eq!(mutator.name(), Some("box_optional"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_none() {
        let mut mutator = BoxStatefulMutator::new_with_optional_name(|x: &mut i32| *x += 1, None);
        assert_eq!(mutator.name(), None);

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_name_and_set_name() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), None);

        mutator.set_name("box_set_name");
        assert_eq!(mutator.name(), Some("box_set_name"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    // Note: BoxStatefulMutator cannot be safely converted to ArcStatefulMutator because the
    // inner function may not be Send. This test has been removed.
}

// ============================================================================
// ArcStatefulMutator Tests
// ============================================================================

#[cfg(test)]
mod test_arc_mutator {
    use super::*;
    use std::thread;

    #[test]
    fn test_new() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x += 1);
        let mut value = 5;
        let mut c = mutator;
        c.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_clone() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let clone1 = mutator.clone();
        let clone2 = mutator.clone();

        let mut value1 = 5;
        let mut c1 = clone1;
        c1.apply(&mut value1);
        assert_eq!(value1, 10);

        let mut value2 = 3;
        let mut c2 = clone2;
        c2.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_and_then() {
        let first = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let second = ArcStatefulMutator::new(|x: &mut i32| *x += 10);

        let chained = first.and_then(second);

        let mut value = 5;
        let mut c = chained;
        c.apply(&mut value);
        assert_eq!(value, 20); // (5 * 2) + 10

        // first and second are still usable
        let mut value2 = 3;
        let mut f = first;
        f.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_thread_safety() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let clone = mutator.clone();

        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut c = clone;
            c.apply(&mut value);
            value
        });

        let mut value = 3;
        let mut c = mutator;
        c.apply(&mut value);
        assert_eq!(value, 6);

        assert_eq!(handle.join().unwrap(), 10);
    }

    #[test]
    fn test_into_box() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.into_box();
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_into_rc() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut rc = mutator.into_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_into_arc() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut arc = mutator.into_arc();
        let mut value = 5;
        arc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_noop() {
        let noop = ArcStatefulMutator::<i32>::noop();
        let mut value = 42;
        let mut m = noop;
        m.apply(&mut value);
        assert_eq!(value, 42);
    }

    #[test]
    fn test_noop_clone() {
        let noop = ArcStatefulMutator::<i32>::noop();
        let clone1 = noop.clone();
        let clone2 = noop.clone();

        let mut value1 = 42;
        let mut m1 = clone1;
        m1.apply(&mut value1);
        assert_eq!(value1, 42);

        let mut value2 = 100;
        let mut m2 = clone2;
        m2.apply(&mut value2);
        assert_eq!(value2, 100);
    }

    #[test]
    fn test_noop_chaining() {
        let noop = ArcStatefulMutator::<i32>::noop();
        let double = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);

        let chained = noop.and_then(double);

        let mut value = 5;
        let mut c = chained;
        c.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_box() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.to_box();
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_rc() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut rc = mutator.to_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_arc() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let arc = mutator.to_arc();
        let mut value = 5;
        let mut m = arc;
        m.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_fn() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x += 10);
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(mutator.to_fn());
        assert_eq!(values, vec![11, 12, 13]);
    }

    #[test]
    fn test_to_box_preserves_original() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.to_box();

        // Original still usable
        let mut value1 = 5;
        let mut m = mutator;
        m.apply(&mut value1);
        assert_eq!(value1, 10);

        // Boxed version also works
        let mut value2 = 3;
        boxed.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_to_rc_preserves_original() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut rc = mutator.to_rc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = mutator;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_rc version also works
        let mut value2 = 3;
        rc.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_to_arc_preserves_original() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let arc = mutator.to_arc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = mutator;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_arc version also works
        let mut value2 = 3;
        let mut m2 = arc;
        m2.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_to_fn_preserves_original() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x += 10);

        // to_fn version works
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(mutator.to_fn());
        assert_eq!(values, vec![11, 12, 13]);

        // Original still usable after to_fn (because ArcStatefulMutator is Clone)
        let mut value1 = 5;
        let mut m = mutator;
        m.apply(&mut value1);
        assert_eq!(value1, 15);
    }

    #[test]
    fn test_to_arc_thread_safe() {
        use std::thread;

        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let arc = mutator.to_arc();
        let clone = arc.clone();

        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = 3;
        let mut m = arc;
        m.apply(&mut value);
        assert_eq!(value, 6);

        assert_eq!(handle.join().unwrap(), 10);
    }

    #[test]
    fn test_new_with_name() {
        let mut mutator =
            ArcStatefulMutator::new_with_name("arc_stateful_test", |x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), Some("arc_stateful_test"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_some() {
        let mut mutator = ArcStatefulMutator::new_with_optional_name(
            |x: &mut i32| *x += 1,
            Some("arc_stateful_optional".to_string()),
        );
        assert_eq!(mutator.name(), Some("arc_stateful_optional"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_none() {
        let mut mutator = ArcStatefulMutator::new_with_optional_name(|x: &mut i32| *x += 1, None);
        assert_eq!(mutator.name(), None);

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_name_and_set_name() {
        let mut mutator = ArcStatefulMutator::new(|x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), None);

        mutator.set_name("arc_stateful_set_name");
        assert_eq!(mutator.name(), Some("arc_stateful_set_name"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }
}

// ============================================================================
// RcStatefulMutator Tests
// ============================================================================

#[cfg(test)]
mod test_rc_mutator {
    use super::*;

    #[test]
    fn test_new() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x += 1);
        let mut value = 5;
        let mut c = mutator;
        c.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_clone() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let clone1 = mutator.clone();
        let clone2 = mutator.clone();

        let mut value1 = 5;
        let mut c1 = clone1;
        c1.apply(&mut value1);
        assert_eq!(value1, 10);

        let mut value2 = 3;
        let mut c2 = clone2;
        c2.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_and_then() {
        let first = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let second = RcStatefulMutator::new(|x: &mut i32| *x += 10);

        let chained = first.and_then(second.clone());

        let mut value = 5;
        let mut c = chained;
        c.apply(&mut value);
        assert_eq!(value, 20); // (5 * 2) + 10

        // first and second are still usable
        let mut value2 = 3;
        let mut f = first;
        f.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_into_box() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.into_box();
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_into_rc() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut rc = mutator.into_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_noop() {
        let noop = RcStatefulMutator::<i32>::noop();
        let mut value = 42;
        let mut m = noop;
        m.apply(&mut value);
        assert_eq!(value, 42);
    }

    #[test]
    fn test_noop_clone() {
        let noop = RcStatefulMutator::<i32>::noop();
        let clone1 = noop.clone();
        let clone2 = noop.clone();

        let mut value1 = 42;
        let mut m1 = clone1;
        m1.apply(&mut value1);
        assert_eq!(value1, 42);

        let mut value2 = 100;
        let mut m2 = clone2;
        m2.apply(&mut value2);
        assert_eq!(value2, 100);
    }

    #[test]
    fn test_noop_chaining() {
        let noop = RcStatefulMutator::<i32>::noop();
        let double = RcStatefulMutator::new(|x: &mut i32| *x *= 2);

        let chained = noop.and_then(double.clone());

        let mut value = 5;
        let mut c = chained;
        c.apply(&mut value);
        assert_eq!(value, 10);
    }

    // Note: RcStatefulMutator cannot be converted to ArcStatefulMutator because Rc is not
    // Send. This test has been removed.

    #[test]
    fn test_to_box() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.to_box();
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_rc() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let rc = mutator.to_rc();
        let mut value = 5;
        let mut m = rc;
        m.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_to_fn() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x += 10);
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(mutator.to_fn());
        assert_eq!(values, vec![11, 12, 13]);
    }

    #[test]
    fn test_to_box_preserves_original() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut boxed = mutator.to_box();

        // Original still usable
        let mut value1 = 5;
        let mut m = mutator;
        m.apply(&mut value1);
        assert_eq!(value1, 10);

        // Boxed version also works
        let mut value2 = 3;
        boxed.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_to_rc_preserves_original() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let rc = mutator.to_rc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = mutator;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_rc version also works
        let mut value2 = 3;
        let mut m2 = rc;
        m2.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_to_fn_preserves_original() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x += 10);

        // to_fn version works
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(mutator.to_fn());
        assert_eq!(values, vec![11, 12, 13]);

        // Original still usable after to_fn (because RcStatefulMutator is Clone)
        let mut value1 = 5;
        let mut m = mutator;
        m.apply(&mut value1);
        assert_eq!(value1, 15);
    }

    #[test]
    fn test_new_with_name() {
        let mut mutator =
            RcStatefulMutator::new_with_name("rc_stateful_test", |x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), Some("rc_stateful_test"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_some() {
        let mut mutator = RcStatefulMutator::new_with_optional_name(
            |x: &mut i32| *x += 1,
            Some("rc_stateful_optional".to_string()),
        );
        assert_eq!(mutator.name(), Some("rc_stateful_optional"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_new_with_optional_name_none() {
        let mut mutator = RcStatefulMutator::new_with_optional_name(|x: &mut i32| *x += 1, None);
        assert_eq!(mutator.name(), None);

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }

    #[test]
    fn test_name_and_set_name() {
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x += 1);
        assert_eq!(mutator.name(), None);

        mutator.set_name("rc_stateful_set_name");
        assert_eq!(mutator.name(), Some("rc_stateful_set_name"));

        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 6);
    }
}

// ============================================================================
// Closure Extension Methods Tests
// ============================================================================

#[cfg(test)]
mod test_fn_mutator_ops {
    use super::*;

    #[test]
    fn test_closure_accept() {
        let closure = |x: &mut i32| *x *= 2;
        let mut value = 5;
        closure.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_and_then() {
        let mut chained = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);

        let mut value = 5;
        chained.apply(&mut value);
        assert_eq!(value, 20); // (5 * 2) + 10
    }

    #[test]
    fn test_closure_into_box() {
        let closure = |x: &mut i32| *x *= 2;
        let mut boxed = StatefulMutator::into_box(closure);
        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_to_box_panics_or_supports() {
        // closure.to_box() by default panics because &closure cannot be cloned.
        // but into_box() should work. We test into_box above; here we ensure
        // to_box() either panics (expected) or returns a BoxStatefulMutator if changed.
        let closure = |x: &mut i32| *x *= 2;
        let res = std::panic::catch_unwind(|| {
            let _ = StatefulMutator::to_box(&closure);
        });
        // Accept either panic (current behavior) or Ok (if implementation changed)
        assert!(res.is_ok() || res.is_err());
    }

    #[test]
    fn test_cloneable_closure_to_box_apply() {
        // Test to_box with a cloneable closure that doesn't capture mutable references
        let closure = |x: &mut i32| *x *= 2;

        // Test that to_box works with cloneable closure
        let mut boxed = StatefulMutator::to_box(&closure);
        let mut value = 5;
        boxed.apply(&mut value);

        // Verify the boxed mutator works correctly
        assert_eq!(value, 10);

        // Test that original closure is still usable
        let mut original_value = 3;
        let original = closure;
        original.apply(&mut original_value);
        assert_eq!(original_value, 6);
    }

    #[test]
    fn test_closure_into_rc() {
        let closure = |x: &mut i32| *x *= 2;
        let mut rc = closure.into_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_into_arc() {
        let closure = |x: &mut i32| *x *= 2;
        let mut arc = closure.into_arc();
        let mut value = 5;
        arc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_to_rc() {
        // Test non-consuming conversion to RcStatefulMutator
        // Note: Only works with cloneable closures (no mutable captures)
        let closure = |x: &mut i32| *x *= 2;
        let mut rc = closure.to_rc();
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_to_arc() {
        // Test non-consuming conversion to ArcStatefulMutator
        // Note: Only works with cloneable closures (no mutable captures)
        let closure = |x: &mut i32| *x *= 2;
        let mut arc = closure.to_arc();
        let mut value = 5;
        arc.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_closure_to_fn() {
        // Test non-consuming conversion to FnMut
        // Note: Only works with cloneable closures (no mutable captures)
        let closure = |x: &mut i32| *x += 10;
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(StatefulMutator::to_fn(&closure));
        assert_eq!(values, vec![11, 12, 13]);
    }

    #[test]
    fn test_closure_to_rc_preserves_original() {
        let closure = |x: &mut i32| *x *= 2;
        let mut rc = closure.to_rc();

        // to_rc version works
        let mut value = 5;
        rc.apply(&mut value);
        assert_eq!(value, 10);

        // Original closure is still usable (was copied, not moved)
        let mut value2 = 3;
        let closure_copy = closure;
        closure_copy.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_closure_to_arc_preserves_original() {
        let closure = |x: &mut i32| *x *= 2;
        let mut arc = closure.to_arc();

        // to_arc version works
        let mut value = 5;
        arc.apply(&mut value);
        assert_eq!(value, 10);

        // Original closure is still usable (was copied, not moved)
        let mut value2 = 3;
        let closure_copy = closure;
        closure_copy.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_closure_to_fn_preserves_original() {
        let closure = |x: &mut i32| *x += 10;
        let fn_mutator = StatefulMutator::to_fn(&closure);

        // to_fn version works
        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(fn_mutator);
        assert_eq!(values, vec![11, 12, 13]);

        // Original closure is still usable (was copied, not moved)
        let mut value = 5;
        let closure_copy = closure;
        closure_copy.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_closure_to_arc_thread_safe() {
        use std::thread;

        let closure = |x: &mut i32| *x *= 2;
        let arc = closure.to_arc();
        let clone = arc.clone();

        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = 3;
        let mut m = arc;
        m.apply(&mut value);
        assert_eq!(value, 6);

        assert_eq!(handle.join().unwrap(), 10);
    }
}

// ============================================================================
// Unified Interface Tests
// ============================================================================

#[cfg(test)]
mod test_unified_interface {
    use super::*;

    fn apply_mutator<C: StatefulMutator<i32>>(mutator: &mut C, value: i32) -> i32 {
        let mut val = value;
        mutator.apply(&mut val);
        val
    }

    #[test]
    fn test_with_box_consumer() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        assert_eq!(apply_mutator(&mut mutator, 5), 10);
    }

    #[test]
    fn test_with_arc_consumer() {
        let mut mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        assert_eq!(apply_mutator(&mut mutator, 5), 10);
    }

    #[test]
    fn test_with_rc_consumer() {
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        assert_eq!(apply_mutator(&mut mutator, 5), 10);
    }

    #[test]
    fn test_with_closure() {
        let mut closure = |x: &mut i32| *x *= 2;
        assert_eq!(apply_mutator(&mut closure, 5), 10);
    }
}

// ============================================================================
// Complex Scenarios Tests
// ============================================================================

#[cfg(test)]
mod test_complex_scenarios {
    use super::*;

    #[test]
    fn test_data_processing_pipeline() {
        let mut pipeline = BoxStatefulMutator::new(|x: &mut i32| {
            *x = (*x).clamp(0, 100);
        })
        .and_then(|x: &mut i32| *x /= 10)
        .and_then(|x: &mut i32| *x = *x * *x);

        let mut value1 = -50;
        pipeline.apply(&mut value1);
        assert_eq!(value1, 0);

        let mut value2 = 200;
        pipeline.apply(&mut value2);
        assert_eq!(value2, 100);

        let mut value3 = 30;
        pipeline.apply(&mut value3);
        assert_eq!(value3, 9);
    }

    #[test]
    fn test_string_processing() {
        let mut processor =
            BoxStatefulMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
                .and_then(|s: &mut String| *s = s.to_lowercase())
                .and_then(|s: &mut String| s.push_str("!!!"));

        let mut text = String::from("Hello World");
        processor.apply(&mut text);
        assert_eq!(text, "helloworld!!!");
    }

    #[test]
    fn test_conditional_processing() {
        let cond1 = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let cond2 = BoxStatefulMutator::new(|x: &mut i32| *x = 100).when(|x: &i32| *x > 100);
        let mut processor = cond1.and_then(cond2);

        let mut small = 5;
        processor.apply(&mut small);
        assert_eq!(small, 10);

        let mut large = 60;
        processor.apply(&mut large);
        assert_eq!(large, 100);
    }

    #[test]
    fn test_mixed_operations() {
        let cond = BoxStatefulMutator::new(|x: &mut i32| *x -= 20).when(|x: &i32| *x > 50);
        let mut processor = BoxStatefulMutator::new(|x: &mut i32| *x += 10)
            .and_then(|x: &mut i32| *x *= 2)
            .and_then(cond);

        let mut value1 = 5;
        processor.apply(&mut value1);
        assert_eq!(value1, 30); // (5 + 10) * 2 = 30

        let mut value2 = 20;
        processor.apply(&mut value2);
        assert_eq!(value2, 40); // (20 + 10) * 2 = 60, 60 > 50 so 60 - 20 = 40
    }

    #[test]
    fn test_arc_mutator_reuse() {
        let double = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let add_ten = ArcStatefulMutator::new(|x: &mut i32| *x += 10);

        let pipeline1 = double.and_then(add_ten.clone());
        let pipeline2 = add_ten.and_then(double.clone());

        let mut value1 = 5;
        let mut p1 = pipeline1;
        p1.apply(&mut value1);
        assert_eq!(value1, 20); // (5 * 2) + 10

        let mut value2 = 5;
        let mut p2 = pipeline2;
        p2.apply(&mut value2);
        assert_eq!(value2, 30); // (5 + 10) * 2
    }

    #[test]
    fn test_rc_mutator_reuse() {
        let double = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let add_ten = RcStatefulMutator::new(|x: &mut i32| *x += 10);

        let pipeline1 = double.and_then(add_ten.clone());
        let pipeline2 = add_ten.and_then(double.clone());

        let mut value1 = 5;
        let mut p1 = pipeline1;
        p1.apply(&mut value1);
        assert_eq!(value1, 20); // (5 * 2) + 10

        let mut value2 = 5;
        let mut p2 = pipeline2;
        p2.apply(&mut value2);
        assert_eq!(value2, 30); // (5 + 10) * 2
    }
}

// ============================================================================
// Custom Types Tests
// ============================================================================

#[cfg(test)]
mod test_custom_types {
    use super::*;

    #[derive(Debug, Clone, PartialEq)]
    struct Point {
        x: i32,
        y: i32,
    }

    #[test]
    fn test_with_custom_struct() {
        let mut mutator = BoxStatefulMutator::new(|p: &mut Point| {
            p.x += 10;
            p.y += 10;
        });

        let mut point = Point { x: 5, y: 15 };
        mutator.apply(&mut point);
        assert_eq!(point, Point { x: 15, y: 25 });
    }

    #[test]
    fn test_chaining_with_custom_struct() {
        let mut processor = BoxStatefulMutator::new(|p: &mut Point| p.x *= 2)
            .and_then(|p: &mut Point| p.y *= 2)
            .and_then(|p: &mut Point| p.x += p.y);

        let mut point = Point { x: 3, y: 4 };
        processor.apply(&mut point);
        assert_eq!(point, Point { x: 14, y: 8 });
    }

    #[test]
    fn test_conditional_with_custom_struct() {
        let mut normalizer = BoxStatefulMutator::new(|p: &mut Point| {
            if p.x < 0 {
                p.x = 0;
            }
            if p.y < 0 {
                p.y = 0;
            }
        })
        .when(|p: &Point| p.x < 0 || p.y < 0);

        let mut point1 = Point { x: -5, y: 10 };
        normalizer.apply(&mut point1);
        assert_eq!(point1, Point { x: 0, y: 10 });

        let mut point2 = Point { x: 5, y: -10 };
        normalizer.apply(&mut point2);
        assert_eq!(point2, Point { x: 5, y: 0 });

        let mut point3 = Point { x: 5, y: 10 };
        normalizer.apply(&mut point3);
        assert_eq!(point3, Point { x: 5, y: 10 });
    }
}

// ============================================================================
// Edge Cases Tests
// ============================================================================

#[cfg(test)]
mod test_edge_cases {
    use super::*;

    #[test]
    fn test_with_zero() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x += 1);
        let mut value = 0;
        mutator.apply(&mut value);
        assert_eq!(value, 1);
    }

    #[test]
    fn test_with_negative() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x = x.abs());
        let mut value = -42;
        mutator.apply(&mut value);
        assert_eq!(value, 42);
    }

    #[test]
    fn test_with_max_value() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x = x.saturating_add(1));
        let mut value = i32::MAX;
        mutator.apply(&mut value);
        assert_eq!(value, i32::MAX);
    }

    #[test]
    fn test_with_min_value() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x = x.saturating_sub(1));
        let mut value = i32::MIN;
        mutator.apply(&mut value);
        assert_eq!(value, i32::MIN);
    }

    #[test]
    fn test_with_empty_string() {
        let mut mutator = BoxStatefulMutator::new(|s: &mut String| s.push_str("added"));
        let mut text = String::new();
        mutator.apply(&mut text);
        assert_eq!(text, "added");
    }

    #[test]
    fn test_with_empty_vec() {
        let mut mutator = BoxStatefulMutator::new(|v: &mut Vec<i32>| v.push(1));
        let mut numbers = Vec::new();
        mutator.apply(&mut numbers);
        assert_eq!(numbers, vec![1]);
    }

    #[test]
    fn test_unicode() {
        let mut mutator = BoxStatefulMutator::new(|s: &mut String| *s = s.to_uppercase());
        let mut text = String::from("héllo world");
        mutator.apply(&mut text);
        assert_eq!(text, "HÉLLO WORLD");
    }
}

// ============================================================================
// Custom StatefulMutator with Default into_xxx() Implementation Tests
// ============================================================================

#[cfg(test)]
mod test_custom_mutator_default_impl {
    use super::*;

    /// Custom mutator for testing default implementations
    ///
    /// This mutator demonstrates using the default trait method implementations
    /// for `into_box()`, `into_rc()`, `into_arc()`, and `into_fn()`.
    #[derive(Clone)]
    struct DoubleStatefulMutator {
        multiplier: i32,
    }

    impl DoubleStatefulMutator {
        fn new(multiplier: i32) -> Self {
            Self { multiplier }
        }
    }

    impl StatefulMutator<i32> for DoubleStatefulMutator {
        fn apply(&mut self, value: &mut i32) {
            *value *= self.multiplier;
        }

        // Note: All into_xxx() methods use the default implementations from the trait
        // We don't need to implement them here
    }

    #[test]
    fn test_custom_mutator_basic() {
        let mut mutator = DoubleStatefulMutator::new(3);
        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_custom_mutator_into_box() {
        let mutator = DoubleStatefulMutator::new(3);
        let mut boxed = mutator.into_box();

        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_custom_mutator_into_rc() {
        let mutator = DoubleStatefulMutator::new(3);
        let rc = mutator.into_rc();

        let clone1 = rc.clone();
        let clone2 = rc.clone();

        let mut value1 = 5;
        let mut m1 = clone1;
        m1.apply(&mut value1);
        assert_eq!(value1, 15);

        let mut value2 = 10;
        let mut m2 = clone2;
        m2.apply(&mut value2);
        assert_eq!(value2, 30);
    }

    #[test]
    fn test_custom_mutator_into_arc() {
        let mutator = DoubleStatefulMutator::new(3);
        let arc = mutator.into_arc();

        let clone1 = arc.clone();
        let clone2 = arc.clone();

        let mut value1 = 5;
        let mut m1 = clone1;
        m1.apply(&mut value1);
        assert_eq!(value1, 15);

        let mut value2 = 10;
        let mut m2 = clone2;
        m2.apply(&mut value2);
        assert_eq!(value2, 30);
    }

    #[test]
    fn test_custom_mutator_into_fn() {
        let mutator = DoubleStatefulMutator::new(3);
        let mut values = vec![1, 2, 3, 4, 5];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![3, 6, 9, 12, 15]);
    }

    #[test]
    fn test_custom_mutator_into_once() {
        let mutator = DoubleStatefulMutator::new(2);
        let once_mutator = mutator.into_once();

        let mut value = 5;
        once_mutator.apply(&mut value);
        assert_eq!(value, 10);
    }

    #[test]
    fn test_custom_mutator_to_once() {
        let mut mutator = DoubleStatefulMutator::new(2);
        let once_mutator = mutator.to_once();

        let mut value = 5;
        once_mutator.apply(&mut value);
        assert_eq!(value, 10);

        // Ensure original mutator is still usable
        let mut value2 = 3;
        mutator.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_custom_mutator_to_box_rc_arc_to_fn() {
        // Test non-consuming conversions provided by default impls (to_box/to_rc/to_arc/to_fn)
        let mutator = DoubleStatefulMutator::new(2);

        // to_box - this exercises cloned.apply(t) in the default to_box implementation
        let mut b = mutator.to_box();
        let mut v = 5;
        b.apply(&mut v);
        assert_eq!(v, 10);

        // to_rc (from custom mutator, not from BoxStatefulMutator) - exercises cloned.apply(t) in to_rc
        let mutator2 = DoubleStatefulMutator::new(2);
        let r = mutator2.to_rc();
        let mut r1 = r.clone();
        r1.apply(&mut v);
        assert_eq!(v, 20);

        // to_arc (from custom mutator, not from RcStatefulMutator) - exercises cloned.apply(t) in to_arc
        let mutator3 = DoubleStatefulMutator::new(2);
        let a = mutator3.to_arc();
        let mut a1 = a.clone();
        a1.apply(&mut v);
        assert_eq!(v, 40);

        // to_fn - exercises cloned.apply(t) in the default to_fn implementation
        let mutator4 = DoubleStatefulMutator::new(2);
        let mut values = vec![1, 1];
        values.iter_mut().for_each(mutator4.to_fn());
        // after two calls multiplier=2: 1*2 = 2, then again 2*2 = 4? We just ensure it runs
        assert_eq!(values, vec![2, 2]);
    }

    #[test]
    fn test_custom_mutator_chaining() {
        // Test chaining with BoxStatefulMutator
        let custom = DoubleStatefulMutator::new(2);
        let boxed = custom.into_box();
        let mut chained = boxed.and_then(|x: &mut i32| *x += 10);

        let mut value = 5;
        chained.apply(&mut value);
        assert_eq!(value, 20); // (5 * 2) + 10
    }

    #[test]
    fn test_custom_mutator_with_condition() {
        let custom = DoubleStatefulMutator::new(2);
        let boxed = custom.into_box();
        let mut conditional = boxed.when(|x: &i32| *x > 0);

        let mut positive = 5;
        conditional.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        conditional.apply(&mut negative);
        assert_eq!(negative, -5); // Unchanged
    }

    /// Custom mutator with state to test stateful operations
    struct CountingStatefulMutator {
        count: i32,
    }

    impl CountingStatefulMutator {
        fn new() -> Self {
            Self { count: 0 }
        }
    }

    impl StatefulMutator<i32> for CountingStatefulMutator {
        fn apply(&mut self, value: &mut i32) {
            self.count += 1;
            *value += self.count;
        }
    }

    #[test]
    fn test_stateful_mutator() {
        let mut mutator = CountingStatefulMutator::new();

        let mut value1 = 10;
        mutator.apply(&mut value1);
        assert_eq!(value1, 11); // 10 + 1

        let mut value2 = 10;
        mutator.apply(&mut value2);
        assert_eq!(value2, 12); // 10 + 2

        let mut value3 = 10;
        mutator.apply(&mut value3);
        assert_eq!(value3, 13); // 10 + 3
    }

    #[test]
    fn test_stateful_mutator_into_box() {
        let mutator = CountingStatefulMutator::new();
        let mut boxed = mutator.into_box();

        let mut value1 = 10;
        boxed.apply(&mut value1);
        assert_eq!(value1, 11); // 10 + 1

        let mut value2 = 10;
        boxed.apply(&mut value2);
        assert_eq!(value2, 12); // 10 + 2

        let mut value3 = 10;
        boxed.apply(&mut value3);
        assert_eq!(value3, 13); // 10 + 3
    }

    #[test]
    fn test_stateful_mutator_into_fn() {
        let mutator = CountingStatefulMutator::new();
        let mut values = vec![10, 10, 10];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![11, 12, 13]); // 10+1, 10+2, 10+3
    }

    /// Custom mutator with complex type
    #[derive(Debug, Clone, PartialEq)]
    struct Point {
        x: i32,
        y: i32,
    }

    struct OffsetStatefulMutator {
        dx: i32,
        dy: i32,
    }

    impl OffsetStatefulMutator {
        fn new(dx: i32, dy: i32) -> Self {
            Self { dx, dy }
        }
    }

    impl StatefulMutator<Point> for OffsetStatefulMutator {
        fn apply(&mut self, point: &mut Point) {
            point.x += self.dx;
            point.y += self.dy;
        }
    }

    #[test]
    fn test_custom_mutator_with_complex_type() {
        let mut mutator = OffsetStatefulMutator::new(10, 20);
        let mut point = Point { x: 5, y: 15 };

        mutator.apply(&mut point);
        assert_eq!(point, Point { x: 15, y: 35 });
    }

    #[test]
    fn test_custom_mutator_complex_type_into_box() {
        let mutator = OffsetStatefulMutator::new(10, 20);
        let mut boxed = mutator.into_box();

        let mut point = Point { x: 5, y: 15 };
        boxed.apply(&mut point);
        assert_eq!(point, Point { x: 15, y: 35 });
    }

    #[test]
    fn test_custom_mutator_complex_type_into_fn() {
        let mutator = OffsetStatefulMutator::new(10, 20);
        let mut points = vec![
            Point { x: 0, y: 0 },
            Point { x: 5, y: 10 },
            Point { x: -5, y: -10 },
        ];

        points.iter_mut().for_each(mutator.into_fn());

        assert_eq!(
            points,
            vec![
                Point { x: 10, y: 20 },
                Point { x: 15, y: 30 },
                Point { x: 5, y: 10 },
            ]
        );
    }

    #[test]
    fn test_custom_mutator_thread_safety() {
        use std::thread;

        let mutator = DoubleStatefulMutator::new(2);
        let arc = mutator.into_arc();

        let clone = arc.clone();
        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = 10;
        let mut m = arc;
        m.apply(&mut value);
        assert_eq!(value, 20);

        assert_eq!(handle.join().unwrap(), 10);
    }

    /// Generic custom mutator
    struct GenericStatefulMutator<F>
    where
        F: FnMut(&mut i32),
    {
        func: F,
    }

    impl<F> GenericStatefulMutator<F>
    where
        F: FnMut(&mut i32),
    {
        fn new(func: F) -> Self {
            Self { func }
        }
    }

    impl<F> StatefulMutator<i32> for GenericStatefulMutator<F>
    where
        F: FnMut(&mut i32),
    {
        fn apply(&mut self, value: &mut i32) {
            (self.func)(value);
        }
    }

    #[test]
    fn test_generic_custom_mutator() {
        let mut mutator = GenericStatefulMutator::new(|x: &mut i32| *x *= 3);
        let mut value = 5;
        mutator.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_generic_custom_mutator_into_box() {
        let mutator = GenericStatefulMutator::new(|x: &mut i32| *x *= 3);
        let mut boxed = mutator.into_box();

        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 15);
    }

    #[test]
    fn test_generic_custom_mutator_with_capture() {
        let multiplier = 4;
        let mutator = GenericStatefulMutator::new(move |x: &mut i32| *x *= multiplier);
        let mut boxed = mutator.into_box();

        let mut value = 5;
        boxed.apply(&mut value);
        assert_eq!(value, 20);
    }
}

// ============================================================================
// into_fn Tests
// ============================================================================

#[cfg(test)]
mod test_into_fn {
    use super::*;

    #[test]
    fn test_box_mutator_into_fn() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut values = vec![1, 2, 3, 4, 5];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![2, 4, 6, 8, 10]);
    }

    #[test]
    fn test_box_mutator_into_fn_complex() {
        let processor =
            BoxStatefulMutator::new(|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);

        let mut values = vec![1, 2, 3];
        values.iter_mut().for_each(processor.into_fn());

        assert_eq!(values, vec![12, 14, 16]); // (1*2)+10, (2*2)+10, (3*2)+10
    }

    #[test]
    fn test_arc_mutator_into_fn() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut values = vec![1, 2, 3];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![2, 4, 6]);
    }

    #[test]
    fn test_arc_mutator_into_fn_composition() {
        let is_positive = ArcStatefulMutator::new(|x: &mut i32| {
            if *x < 0 {
                *x = 0;
            }
        });
        let double = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let combined = is_positive.and_then(double);

        let mut values = vec![-5, 1, 3, -2, 4];
        values.iter_mut().for_each(combined.into_fn());

        assert_eq!(values, vec![0, 2, 6, 0, 8]);
    }

    #[test]
    fn test_rc_mutator_into_fn() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x += 10);
        let mut values = vec![1, 2, 3];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![11, 12, 13]);
    }

    #[test]
    fn test_rc_mutator_into_fn_chained() {
        let first = RcStatefulMutator::new(|x: &mut i32| *x *= 3);
        let second = RcStatefulMutator::new(|x: &mut i32| *x -= 1);
        let chained = first.and_then(second.clone());

        let mut values = vec![2, 4, 6];
        values.iter_mut().for_each(chained.into_fn());

        assert_eq!(values, vec![5, 11, 17]); // (2*3)-1, (4*3)-1, (6*3)-1
    }

    #[test]
    fn test_closure_into_fn() {
        let closure = |x: &mut i32| *x *= 2;
        let mut values = vec![1, 2, 3, 4];

        values
            .iter_mut()
            .for_each(StatefulMutator::into_fn(closure));

        assert_eq!(values, vec![2, 4, 6, 8]);
    }

    #[test]
    fn test_closure_into_fn_direct() {
        // Test that closure.into_fn() returns the closure itself
        let closure = |x: &mut i32| *x *= 2;
        let mut fn_result = StatefulMutator::into_fn(closure);

        let mut value = 5;
        fn_result(&mut value);
        assert_eq!(value, 10);

        // Can be called multiple times
        let mut value2 = 3;
        fn_result(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_closure_into_fn_with_state() {
        // Test closure with captured state
        let mut count = 0;
        let closure = move |x: &mut i32| {
            count += 1;
            *x += count;
        };

        let mut fn_result = StatefulMutator::into_fn(closure);

        let mut value1 = 10;
        fn_result(&mut value1);
        assert_eq!(value1, 11); // 10 + 1

        let mut value2 = 10;
        fn_result(&mut value2);
        assert_eq!(value2, 12); // 10 + 2
    }

    #[test]
    fn test_into_fn_with_strings() {
        let mutator = BoxStatefulMutator::new(|s: &mut String| s.push('!'));
        let mut strings = vec![
            String::from("hello"),
            String::from("world"),
            String::from("rust"),
        ];

        strings.iter_mut().for_each(mutator.into_fn());

        assert_eq!(
            strings,
            vec![
                String::from("hello!"),
                String::from("world!"),
                String::from("rust!")
            ]
        );
    }

    #[test]
    fn test_into_fn_with_vec() {
        let mutator = BoxStatefulMutator::new(|v: &mut Vec<i32>| v.push(0));
        let mut vecs = vec![vec![1], vec![2, 3], vec![4, 5, 6]];

        vecs.iter_mut().for_each(mutator.into_fn());

        assert_eq!(vecs, vec![vec![1, 0], vec![2, 3, 0], vec![4, 5, 6, 0]]);
    }

    #[test]
    fn test_into_fn_with_empty_iterator() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut values: Vec<i32> = vec![];

        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, Vec::<i32>::new());
    }

    #[test]
    fn test_into_fn_with_conditional() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);

        let mut values = vec![-2, -1, 0, 1, 2, 3];
        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    #[test]
    fn test_into_fn_with_transform() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x = *x * *x);

        let mut values = vec![1, 2, 3, 4, 5];
        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![1, 4, 9, 16, 25]);
    }

    #[test]
    fn test_into_fn_pipeline() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| {
            if *x < 0 {
                *x = 0;
            }
        })
        .and_then(|x: &mut i32| *x += 5)
        .and_then(|x: &mut i32| *x *= 2);

        let mut values = vec![-10, -5, 0, 5, 10];
        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![10, 10, 10, 20, 30]);
        // -10 -> 0 -> 5 -> 10
        // -5 -> 0 -> 5 -> 10
        // 0 -> 0 -> 5 -> 10
        // 5 -> 5 -> 10 -> 20
        // 10 -> 10 -> 15 -> 30
    }

    #[test]
    fn test_arc_mutator_into_fn_thread_safe() {
        use std::thread;

        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let clone = mutator.clone();

        let handle = thread::spawn(move || {
            let mut values = vec![1, 2, 3];
            values.iter_mut().for_each(clone.into_fn());
            values
        });

        let result = handle.join().unwrap();
        assert_eq!(result, vec![2, 4, 6]);
    }

    #[test]
    fn test_into_fn_with_filter_map() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let mut values = vec![1, 2, 3, 4, 5];

        // Use with iter_mut
        values.iter_mut().for_each(mutator.into_fn());

        assert_eq!(values, vec![2, 4, 6, 8, 10]);
    }

    #[test]
    fn test_into_fn_with_complex_types() {
        #[derive(Debug, Clone, PartialEq)]
        struct Point {
            x: i32,
            y: i32,
        }

        let mutator = BoxStatefulMutator::new(|p: &mut Point| {
            p.x *= 2;
            p.y *= 2;
        });

        let mut points = vec![Point { x: 1, y: 2 }, Point { x: 3, y: 4 }];

        points.iter_mut().for_each(mutator.into_fn());

        assert_eq!(points, vec![Point { x: 2, y: 4 }, Point { x: 6, y: 8 }]);
    }
}

// ============================================================================
// Conditional Execution Tests (when/or_else with various parameter types)
// ============================================================================

#[cfg(test)]
mod test_conditional_execution {
    use super::*;
    use qubit_function::predicates::{
        ArcPredicate,
        BoxPredicate,
        RcPredicate,
    };

    // Helper function pointer for testing
    fn is_positive(x: &i32) -> bool {
        *x > 0
    }

    fn negate(x: &mut i32) {
        *x = -*x;
    }

    // ========================================================================
    // BoxStatefulMutator::when() tests
    // ========================================================================

    #[test]
    fn test_box_when_with_closure() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_box_when_with_function_pointer() {
        let mut mutator =
            BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(is_positive as fn(&i32) -> bool);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_box_when_with_box_predicate() {
        let pred = BoxPredicate::new(|x: &i32| *x > 0);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_box_when_with_rc_predicate() {
        let pred = RcPredicate::new(|x: &i32| *x > 0);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_box_when_with_arc_predicate() {
        let pred = ArcPredicate::new(|x: &i32| *x > 0);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    // ========================================================================
    // BoxConditionalStatefulMutator::or_else() tests
    // ========================================================================

    #[test]
    fn test_box_or_else_with_closure() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x -= 1);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -6);
    }

    #[test]
    fn test_box_or_else_with_function_pointer() {
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(negate as fn(&mut i32));

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 5);
    }

    #[test]
    fn test_box_or_else_with_box_mutator() {
        let else_mutator = BoxStatefulMutator::new(|x: &mut i32| *x = 0);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 0);
    }

    #[test]
    fn test_box_or_else_with_rc_mutator() {
        let else_mutator = RcStatefulMutator::new(|x: &mut i32| *x = 100);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 100);
    }

    #[test]
    fn test_box_or_else_with_arc_mutator() {
        let else_mutator = ArcStatefulMutator::new(|x: &mut i32| *x = 200);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 200);
    }

    // ========================================================================
    // BoxConditionalStatefulMutator::and_then() tests
    // ========================================================================

    #[test]
    fn test_box_conditional_and_then_with_closure() {
        let cond1 = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut chained = cond1.and_then(|x: &mut i32| *x += 10);

        let mut positive = 5;
        chained.apply(&mut positive);
        assert_eq!(positive, 20); // 5 * 2 + 10

        let mut negative = -5;
        chained.apply(&mut negative);
        assert_eq!(negative, 5); // -5 + 10 (not doubled)
    }

    #[test]
    fn test_box_conditional_and_then_with_box_mutator() {
        let cond1 = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let next = BoxStatefulMutator::new(|x: &mut i32| *x += 100);
        let mut chained = cond1.and_then(next);

        let mut positive = 10;
        chained.apply(&mut positive);
        assert_eq!(positive, 120); // 10 * 2 + 100

        let mut negative = -10;
        chained.apply(&mut negative);
        assert_eq!(negative, 90); // -10 + 100 (not doubled)
    }

    #[test]
    fn test_box_conditional_and_then_conditional() {
        let cond1 = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let cond2 = BoxStatefulMutator::new(|x: &mut i32| *x = 100).when(|x: &i32| *x > 100);
        let mut chained = cond1.and_then(cond2);

        let mut small = 5;
        chained.apply(&mut small);
        assert_eq!(small, 10); // 5 * 2 = 10 (< 100, not capped)

        let mut large = 60;
        chained.apply(&mut large);
        assert_eq!(large, 100); // 60 * 2 = 120 (> 100, capped)
    }

    // ========================================================================
    // RcConditionalStatefulMutator::and_then() tests
    // ========================================================================

    #[test]
    fn test_rc_conditional_and_then_with_closure() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut chained = conditional.and_then(|x: &mut i32| *x += 10);

        let mut positive = 5;
        chained.apply(&mut positive);
        assert_eq!(positive, 20); // 5 * 2 + 10

        let mut negative = -5;
        chained.apply(&mut negative);
        assert_eq!(negative, 5); // -5 + 10 (condition not met)
    }

    #[test]
    fn test_rc_conditional_and_then_with_rc_mutator() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let next = RcStatefulMutator::new(|x: &mut i32| *x += 100);
        let mut chained = conditional.and_then(next);

        let mut positive = 10;
        chained.apply(&mut positive);
        assert_eq!(positive, 120); // 10 * 2 + 100

        let mut negative = -10;
        chained.apply(&mut negative);
        assert_eq!(negative, 90); // -10 + 100 (condition not met)
    }

    // ========================================================================
    // ArcConditionalStatefulMutator::and_then() tests
    // ========================================================================

    #[test]
    fn test_arc_conditional_and_then_with_closure() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut chained = conditional.and_then(|x: &mut i32| *x += 10);

        let mut positive = 5;
        chained.apply(&mut positive);
        assert_eq!(positive, 20); // 5 * 2 + 10

        let mut negative = -5;
        chained.apply(&mut negative);
        assert_eq!(negative, 5); // -5 + 10 (condition not met)
    }

    #[test]
    fn test_arc_conditional_and_then_with_arc_mutator() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let next = ArcStatefulMutator::new(|x: &mut i32| *x += 100);
        let mut chained = conditional.and_then(next);

        let mut positive = 10;
        chained.apply(&mut positive);
        assert_eq!(positive, 120); // 10 * 2 + 100

        let mut negative = -10;
        chained.apply(&mut negative);
        assert_eq!(negative, 90); // -10 + 100 (condition not met)
    }

    // ========================================================================
    // RcStatefulMutator::when() tests
    // ========================================================================

    #[test]
    fn test_rc_when_with_closure() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_when_with_function_pointer() {
        let conditional =
            RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(is_positive as fn(&i32) -> bool);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_when_with_rc_predicate() {
        let pred = RcPredicate::new(|x: &i32| *x > 0);
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_when_with_box_predicate() {
        let pred = BoxPredicate::new(|x: &i32| *x > 0);
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    // ========================================================================
    // RcConditionalStatefulMutator::or_else() tests
    // ========================================================================

    #[test]
    fn test_rc_or_else_with_closure() {
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x -= 1);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -6);
    }

    #[test]
    fn test_rc_or_else_with_function_pointer() {
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(negate as fn(&mut i32));

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 5);
    }

    #[test]
    fn test_rc_or_else_with_rc_mutator() {
        let else_mutator = RcStatefulMutator::new(|x: &mut i32| *x = 100);
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 100);
    }

    #[test]
    fn test_rc_or_else_with_box_mutator() {
        let else_mutator = BoxStatefulMutator::new(|x: &mut i32| *x = 200);
        let mut mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 200);
    }

    // ========================================================================
    // RcConditionalStatefulMutator::clone() tests
    // ========================================================================

    #[test]
    fn test_rc_conditional_clone() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut clone1 = conditional.clone();
        let mut clone2 = conditional.clone();

        let mut value1 = 5;
        clone1.apply(&mut value1);
        assert_eq!(value1, 10);

        let mut value2 = -5;
        clone2.apply(&mut value2);
        assert_eq!(value2, -5);
    }

    // ========================================================================
    // ArcStatefulMutator::when() tests
    // ========================================================================

    #[test]
    fn test_arc_when_with_closure() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_when_with_function_pointer() {
        let conditional =
            ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(is_positive as fn(&i32) -> bool);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_when_with_arc_predicate() {
        let pred = ArcPredicate::new(|x: &i32| *x > 0);
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);
        let mut m = conditional.clone();

        let mut positive = 5;
        m.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        m.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    // ========================================================================
    // ArcConditionalStatefulMutator::or_else() tests
    // ========================================================================

    #[test]
    fn test_arc_or_else_with_closure() {
        let mut mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x -= 1);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -6);
    }

    #[test]
    fn test_arc_or_else_with_function_pointer() {
        let mut mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(negate as fn(&mut i32));

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 5);
    }

    #[test]
    fn test_arc_or_else_with_arc_mutator() {
        let else_mutator = ArcStatefulMutator::new(|x: &mut i32| *x = 100);
        let mut mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(else_mutator);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, 100);
    }

    // Note: BoxStatefulMutator is not Send, so it cannot be used with ArcStatefulMutator::or_else()

    // ========================================================================
    // ArcConditionalStatefulMutator::clone() tests
    // ========================================================================

    #[test]
    fn test_arc_conditional_clone() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut clone1 = conditional.clone();
        let mut clone2 = conditional.clone();

        let mut value1 = 5;
        clone1.apply(&mut value1);
        assert_eq!(value1, 10);

        let mut value2 = -5;
        clone2.apply(&mut value2);
        assert_eq!(value2, -5);
    }

    // ========================================================================
    // Thread safety tests for ArcConditionalStatefulMutator
    // ========================================================================

    #[test]
    fn test_arc_conditional_thread_safety() {
        use std::thread;

        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let clone = conditional.clone();

        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = -5;
        let mut m = conditional;
        m.apply(&mut value);
        assert_eq!(value, -5);

        assert_eq!(handle.join().unwrap(), 10);
    }

    #[test]
    fn test_arc_or_else_thread_safety() {
        use std::thread;

        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x = 0);

        let clone = mutator.clone();

        let handle = thread::spawn(move || {
            let mut value = -5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = 5;
        let mut m = mutator;
        m.apply(&mut value);
        assert_eq!(value, 10);

        assert_eq!(handle.join().unwrap(), 0);
    }

    // ========================================================================
    // Type conversion tests for ConditionalStatefulMutator
    // ========================================================================

    #[test]
    fn test_box_conditional_into_box() {
        let conditional = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.into_box();

        let mut positive = 5;
        boxed.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        boxed.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_box_conditional_into_rc() {
        let conditional = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.into_rc();

        let mut positive = 5;
        rc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        rc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_conditional_into_box() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.into_box();

        let mut positive = 5;
        boxed.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        boxed.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_conditional_into_rc() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.into_rc();

        let mut positive = 5;
        rc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        rc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_into_box() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.into_box();

        let mut positive = 5;
        boxed.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        boxed.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_into_rc() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.into_rc();

        let mut positive = 5;
        rc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        rc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_into_arc() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut arc = conditional.into_arc();

        let mut positive = 5;
        arc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        arc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    // ========================================================================
    // into_fn tests for ConditionalStatefulMutator
    // ========================================================================

    #[test]
    fn test_box_conditional_into_fn() {
        let conditional = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut values = vec![-2, -1, 0, 1, 2, 3];

        values.iter_mut().for_each(conditional.into_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    #[test]
    fn test_rc_conditional_into_fn() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut values = vec![-2, -1, 0, 1, 2, 3];

        values.iter_mut().for_each(conditional.into_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    #[test]
    fn test_arc_conditional_into_fn() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut values = vec![-2, -1, 0, 1, 2, 3];

        values.iter_mut().for_each(conditional.into_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    // ========================================================================
    // to_xxx tests for RcConditionalStatefulMutator
    // ========================================================================

    #[test]
    fn test_rc_conditional_to_box() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.to_box();

        let mut positive = 5;
        boxed.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        boxed.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_conditional_to_rc() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.to_rc();

        let mut positive = 5;
        rc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        rc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_rc_conditional_to_fn() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut values = vec![-2, -1, 0, 1, 2, 3];

        values.iter_mut().for_each(conditional.to_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    #[test]
    fn test_rc_conditional_to_box_preserves_original() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.to_box();

        // Original still usable
        let mut value1 = 5;
        let mut m = conditional;
        m.apply(&mut value1);
        assert_eq!(value1, 10);

        // Boxed version also works
        let mut value2 = 3;
        boxed.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_rc_conditional_to_rc_preserves_original() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.to_rc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = conditional;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_rc version also works
        let mut value2 = 3;
        rc.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_rc_conditional_to_fn_preserves_original() {
        let conditional = RcStatefulMutator::new(|x: &mut i32| *x += 10).when(|x: &i32| *x > 0);

        // to_fn version works
        let mut values = vec![1, 2, -3];
        values.iter_mut().for_each(conditional.to_fn());
        assert_eq!(values, vec![11, 12, -3]);

        // Original still usable after to_fn (because RcConditionalStatefulMutator is Clone)
        let mut value1 = 5;
        let mut m = conditional;
        m.apply(&mut value1);
        assert_eq!(value1, 15);
    }

    // ========================================================================
    // to_xxx tests for ArcConditionalStatefulMutator
    // ========================================================================

    #[test]
    fn test_arc_conditional_to_box() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.to_box();

        let mut positive = 5;
        boxed.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        boxed.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_to_rc() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.to_rc();

        let mut positive = 5;
        rc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        rc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_to_arc() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut arc = conditional.to_arc();

        let mut positive = 5;
        arc.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        arc.apply(&mut negative);
        assert_eq!(negative, -5);
    }

    #[test]
    fn test_arc_conditional_to_fn() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut values = vec![-2, -1, 0, 1, 2, 3];

        values.iter_mut().for_each(conditional.to_fn());

        assert_eq!(values, vec![-2, -1, 0, 2, 4, 6]);
    }

    #[test]
    fn test_arc_conditional_to_box_preserves_original() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut boxed = conditional.to_box();

        // Original still usable
        let mut value1 = 5;
        let mut m = conditional;
        m.apply(&mut value1);
        assert_eq!(value1, 10);

        // Boxed version also works
        let mut value2 = 3;
        boxed.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_arc_conditional_to_rc_preserves_original() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut rc = conditional.to_rc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = conditional;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_rc version also works
        let mut value2 = 3;
        rc.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_arc_conditional_to_arc_preserves_original() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let mut arc = conditional.to_arc();

        // Original still usable
        let mut value1 = 5;
        let mut m1 = conditional;
        m1.apply(&mut value1);
        assert_eq!(value1, 10);

        // to_arc version also works
        let mut value2 = 3;
        arc.apply(&mut value2);
        assert_eq!(value2, 6);
    }

    #[test]
    fn test_arc_conditional_to_fn_preserves_original() {
        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x += 10).when(|x: &i32| *x > 0);

        // to_fn version works
        let mut values = vec![1, 2, -3];
        values.iter_mut().for_each(conditional.to_fn());
        assert_eq!(values, vec![11, 12, -3]);

        // Original still usable after to_fn (because ArcConditionalStatefulMutator is Clone)
        let mut value1 = 5;
        let mut m = conditional;
        m.apply(&mut value1);
        assert_eq!(value1, 15);
    }

    #[test]
    fn test_arc_conditional_to_arc_thread_safe() {
        use std::thread;

        let conditional = ArcStatefulMutator::new(|x: &mut i32| *x *= 2).when(|x: &i32| *x > 0);
        let arc = conditional.to_arc();
        let clone = arc.clone();

        let handle = thread::spawn(move || {
            let mut value = 5;
            let mut m = clone;
            m.apply(&mut value);
            value
        });

        let mut value = -5;
        let mut m = arc;
        m.apply(&mut value);
        assert_eq!(value, -5);

        assert_eq!(handle.join().unwrap(), 10);
    }

    // ========================================================================
    // Complex conditional composition tests
    // ========================================================================

    #[test]
    fn test_nested_conditionals() {
        // When x > 0: multiply by 2, then if result > 10: cap at 10
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .and_then(BoxStatefulMutator::new(|x: &mut i32| *x = 10).when(|x: &i32| *x > 10));

        let mut small = 3;
        mutator.apply(&mut small);
        assert_eq!(small, 6); // 3 * 2 = 6 (not capped)

        let mut medium = 5;
        mutator.apply(&mut medium);
        assert_eq!(medium, 10); // 5 * 2 = 10 (not capped)

        let mut large = 8;
        mutator.apply(&mut large);
        assert_eq!(large, 10); // 8 * 2 = 16 -> capped to 10

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -5); // Not doubled (condition failed)
    }

    #[test]
    fn test_or_else_chaining() {
        // If positive: double, else: triple
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2)
            .when(|x: &i32| *x > 0)
            .or_else(|x: &mut i32| *x *= 3);

        let mut positive = 5;
        mutator.apply(&mut positive);
        assert_eq!(positive, 10);

        let mut negative = -5;
        mutator.apply(&mut negative);
        assert_eq!(negative, -15);

        let mut zero = 0;
        mutator.apply(&mut zero);
        assert_eq!(zero, 0); // 0 * 3
    }

    #[test]
    fn test_combined_predicate_types() {
        use qubit_function::predicates::FnPredicateOps;

        // Combine predicates: x > 0 AND x < 100
        let pred = (|x: &i32| *x > 0).and(|x: &i32| *x < 100);
        let mut mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2).when(pred);

        let mut in_range = 50;
        mutator.apply(&mut in_range);
        assert_eq!(in_range, 100); // Doubled

        let mut too_small = -10;
        mutator.apply(&mut too_small);
        assert_eq!(too_small, -10); // Not doubled

        let mut too_large = 150;
        mutator.apply(&mut too_large);
        assert_eq!(too_large, 150); // Not doubled
    }
}

// ============================================================================
// Conditional Stateful Mutator Debug/Display Tests
// ============================================================================

#[cfg(test)]
mod test_conditional_stateful_mutator_debug_display {
    use super::*;

    #[test]
    fn test_box_conditional_stateful_mutator_debug() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let debug_str = format!("{:?}", conditional);
        assert!(debug_str.contains("BoxConditionalStatefulMutator"));
        assert!(debug_str.contains("BoxStatefulMutator"));
        assert!(debug_str.contains("BoxPredicate"));
    }

    #[test]
    fn test_box_conditional_stateful_mutator_display() {
        let mutator = BoxStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let display_str = format!("{}", conditional);
        assert!(display_str.contains("BoxConditionalStatefulMutator"));
    }

    #[test]
    fn test_rc_conditional_stateful_mutator_debug() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let debug_str = format!("{:?}", conditional);
        assert!(debug_str.contains("RcConditionalStatefulMutator"));
        assert!(debug_str.contains("RcStatefulMutator"));
        assert!(debug_str.contains("RcPredicate"));
    }

    #[test]
    fn test_rc_conditional_stateful_mutator_display() {
        let mutator = RcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let display_str = format!("{}", conditional);
        assert!(display_str.contains("RcConditionalStatefulMutator"));
    }

    #[test]
    fn test_arc_conditional_stateful_mutator_debug() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let debug_str = format!("{:?}", conditional);
        assert!(debug_str.contains("ArcConditionalStatefulMutator"));
        assert!(debug_str.contains("ArcStatefulMutator"));
        assert!(debug_str.contains("ArcPredicate"));
    }

    #[test]
    fn test_arc_conditional_stateful_mutator_display() {
        let mutator = ArcStatefulMutator::new(|x: &mut i32| *x *= 2);
        let conditional = mutator.when(|x: &i32| *x > 0);

        let display_str = format!("{}", conditional);
        assert!(display_str.contains("ArcConditionalStatefulMutator"));
    }
}
