         
         XCTAssertThrowsError(try PersonWithShortName(Person(name: "Joseph"))) { error in
             XCTAssertEqual(
-                error as! PersonWithShortName_Spec.Error,
-                .nameIsTooLong(name: "Joseph")
+                error as! PersonWithShortName.Spec.NameIsTooLongError,
+                PersonWithShortName.Spec.NameIsTooLongError.init(name: "Joseph")
             )
         }
     }

    
    enum PersonWithShortName_Spec: SemanticTypeSpec {
        typealias BackingPrimitiveWithValueSemantics = Person
        
        enum Error: Swift.Error, Equatable {
            case nameIsTooLong(name: String)
        }
        
        static func gatewayMap(preMap: Person) -> Result<Person, PersonWithShortName_Spec.Error> {
            guard preMap.name.count < 5
                else { return .failure(.nameIsTooLong(name: preMap.name)) }
            
            return .success(preMap)
        }

        XCTAssertEqual(bill.associatedGreeting, "Hello, my name is Bill.")
    }
    
    func testSuccessfulTryMap() {
        let joe = try! PersonWithShortName(Person(name: "Joe"))
        let lowercaseJoe = try! joe.tryMap { person in
            var person = person
            person.name = person.name.lowercased()
            return person
        }.get()
        XCTAssertEqual(lowercaseJoe.name, "joe")
    }
    
    func testFailingTryMap() {
        let joe = try! PersonWithShortName(Person(name: "Joe"))

        let josephTooLong = joe.tryMap { person in
            var person = person
            person.name.removeLast()
            person.name.append(contentsOf: "seph")
            return person
        }
        
        switch josephTooLong {
        case .success:
            XCTFail()
        case .failure(let error):
            XCTAssertEqual(
                error,
                PersonWithShortName.Spec.NameIsTooLongError(name: "Joseph")
            )
        }
    }
    
    func testSuccessfulMutatingTryMap() {
        var joe = try! PersonWithShortName(Person(name: "Joe"))
        
        XCTAssertEqual(joe.name, "Joe")
        try! joe.mutatingTryMap { person in person.name = person.name.lowercased() }
        XCTAssertEqual(joe.name, "joe")
    }
    
    func testFailingMutatingTryMap() {
        var joe = try! PersonWithShortName(Person(name: "Joe"))
        
        XCTAssertEqual(joe.name, "Joe")
        XCTAssertThrowsError(
            try joe.mutatingTryMap { person in
                  person.name.removeLast()
                  person.name.append(contentsOf: "seph")
            }
        ) { error in
            XCTAssertEqual(
                error as! PersonWithShortName.Spec.NameIsTooLongError,
                PersonWithShortName.Spec.NameIsTooLongError.init(name: "Joseph")
            )
        }
    }

    
    static var allTests = [
        ("testInitialization", testInitialization),
        ("testBackingPrimitiveAccess", testBackingPrimitiveAccess),
        ("testSubscriptAccess", testSubscriptAccess),
        ("testSuccessfulTryMap", testSuccessfulTryMap),
        ("testFailingTryMap", testFailingTryMap),
        ("testSuccessfulMutatingTryMap", testSuccessfulMutatingTryMap),
        ("testFailingMutatingTryMap", testFailingMutatingTryMap),
    ]
}
