// Path: src/main/java/org/paradise/domain/Car.java
// public class Car {
// 
//     private static Optional<Insurance> insurance;
// 
//     public Car(Insurance insurance) {
//         this.insurance = Optional.ofNullable(insurance);
//     }
// 
//     public static <U> Optional<Insurance> getInsurance(U u) {
//         return insurance;
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/domain/Insurance.java
// public class Insurance {
// 
//     private static String name;
//     private static String policy;
// 
//     public Insurance(String name, String policy) {
//         this.name = name;
//         this.policy = policy;
//     }
// 
//     public static <U> String getName(U u) {
//         return name;
//     }
// 
//     public static <U> String getPolicy(U u) {
//         return policy;
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/domain/Person.java
// public class Person {
// 
//     private String name;
//     private int age;
// 
//     private static Optional<Car> car;
// 
//     private static Address address;
// 
// 
//     public Person(Car car) {
//         this.car = Optional.ofNullable(car);
//     }
// 
//     public static <U> Optional<Car> getCar(U u) {
//         return car;
//     }
// 
//     public static <U> Try<Address> getAddress(U u) {
// 
//         return address == null
//                 ? new TryFailure<>(address).failure(u.toString(), new NullValueException("Address is NULL"))
//                 : new TrySuccess(address);
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public int getAge() {
//         return age;
//     }
// 
//     public void setAge(int age) {
//         this.age = age;
//     }
// 
//     @Override
//     public String toString() {
//         return "Person {" +
//                 "name = [" + name + ']' +
//                 ", age = [" + age + ']' +
//                 ", car = [" + car + ']' +
//                 ", address = [" + address + ']' +
//                 '}';
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/exception/NullValueException.java
// public class NullValueException extends Exception {
// 
//     public NullValueException() {
//     }
// 
//     public NullValueException(String message) {
//         super(message);
//     }
// 
//     public NullValueException(Throwable cause) {
//         super(cause);
//     }
// 
//     public NullValueException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public NullValueException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/validator/PersonValidator.java
// @Component
// public class PersonValidator {
// 
//     public static Validation<String, Person> validateAge(Person p) {
//         return (p.getAge() > 0 && p.getAge() < 130) ? new ValidationSuccess(p) : new ValidationFailure("Age must be between 0 and 130", p);
//     }
// 
//     public static Validation<String, Person> validateName(Person p) {
//         return Character.isUpperCase(p.getName().charAt(0)) ? new ValidationSuccess(p) : new ValidationFailure("Name must start with uppercase", p);
//     }
// 
//     public Boolean validate(Person p) {
// 
//         return Boolean.FALSE;
//     }
// 
// }


import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.paradise.domain.Car;
import org.paradise.domain.Insurance;
import org.paradise.domain.Person;
import org.paradise.exception.NullValueException;
import org.paradise.validator.PersonValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

    @Test
    public void testGetCarInsuranceNameAndPolicy() throws Exception {

        person = new Person(new Car(new Insurance(insuranceName, insurancePolicy)));

        assertSame("Incorrect car insurance name", insuranceName, personService.getCarInsuranceName(person));
        assertSame("Incorrect car insurance policy", insurancePolicy, personService.getCarInsurancePolicy(person));
    }

    @Test
    public void testGetCarInsuranceNameUnknown() {

        person = new Person(null);
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));

        person = new Person(new Car(null));
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));

        person = new Person(new Car(new Insurance(null, insurancePolicy)));
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));
    }

    @Test(expected = NullValueException.class)
    public void testGetCarInsurancePolicyExceptionWhenPersonIsNull() throws Exception {

        person = new Person(null);
        personService.getCarInsurancePolicy(person);
    }

// Path: src/main/java/org/paradise/domain/Car.java
// public class Car {
// 
//     private static Optional<Insurance> insurance;
// 
//     public Car(Insurance insurance) {
//         this.insurance = Optional.ofNullable(insurance);
//     }
// 
//     public static <U> Optional<Insurance> getInsurance(U u) {
//         return insurance;
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/domain/Insurance.java
// public class Insurance {
// 
//     private static String name;
//     private static String policy;
// 
//     public Insurance(String name, String policy) {
//         this.name = name;
//         this.policy = policy;
//     }
// 
//     public static <U> String getName(U u) {
//         return name;
//     }
// 
//     public static <U> String getPolicy(U u) {
//         return policy;
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/domain/Person.java
// public class Person {
// 
//     private String name;
//     private int age;
// 
//     private static Optional<Car> car;
// 
//     private static Address address;
// 
// 
//     public Person(Car car) {
//         this.car = Optional.ofNullable(car);
//     }
// 
//     public static <U> Optional<Car> getCar(U u) {
//         return car;
//     }
// 
//     public static <U> Try<Address> getAddress(U u) {
// 
//         return address == null
//                 ? new TryFailure<>(address).failure(u.toString(), new NullValueException("Address is NULL"))
//                 : new TrySuccess(address);
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public int getAge() {
//         return age;
//     }
// 
//     public void setAge(int age) {
//         this.age = age;
//     }
// 
//     @Override
//     public String toString() {
//         return "Person {" +
//                 "name = [" + name + ']' +
//                 ", age = [" + age + ']' +
//                 ", car = [" + car + ']' +
//                 ", address = [" + address + ']' +
//                 '}';
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/exception/NullValueException.java
// public class NullValueException extends Exception {
// 
//     public NullValueException() {
//     }
// 
//     public NullValueException(String message) {
//         super(message);
//     }
// 
//     public NullValueException(Throwable cause) {
//         super(cause);
//     }
// 
//     public NullValueException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public NullValueException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
// }
// 
// Path: src/main/java/org/paradise/validator/PersonValidator.java
// @Component
// public class PersonValidator {
// 
//     public static Validation<String, Person> validateAge(Person p) {
//         return (p.getAge() > 0 && p.getAge() < 130) ? new ValidationSuccess(p) : new ValidationFailure("Age must be between 0 and 130", p);
//     }
// 
//     public static Validation<String, Person> validateName(Person p) {
//         return Character.isUpperCase(p.getName().charAt(0)) ? new ValidationSuccess(p) : new ValidationFailure("Name must start with uppercase", p);
//     }
// 
//     public Boolean validate(Person p) {
// 
//         return Boolean.FALSE;
//     }
// 
// }


// Path: src/test/java/org/paradise/service/PersonServiceTest.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.paradise.domain.Car;
import org.paradise.domain.Insurance;
import org.paradise.domain.Person;
import org.paradise.exception.NullValueException;
import org.paradise.validator.PersonValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;


    @Test
    public void testGetCarInsuranceNameAndPolicy() throws Exception {

        person = new Person(new Car(new Insurance(insuranceName, insurancePolicy)));

        assertSame("Incorrect car insurance name", insuranceName, personService.getCarInsuranceName(person));
        assertSame("Incorrect car insurance policy", insurancePolicy, personService.getCarInsurancePolicy(person));
    }

    @Test
    public void testGetCarInsuranceNameUnknown() {

        person = new Person(null);
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));

        person = new Person(new Car(null));
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));

        person = new Person(new Car(new Insurance(null, insurancePolicy)));
        assertSame("Incorrect car insurance name", "Unknown", personService.getCarInsuranceName(person));
    }

    @Test(expected = NullValueException.class)
    public void testGetCarInsurancePolicyExceptionWhenPersonIsNull() throws Exception {

        person = new Person(null);
        personService.getCarInsurancePolicy(person);
    }

    @Test(expected = NullValueException.class)