     // MARK: Registration
     
     /**
-     Registers the block `eval` with Guise.
+     Registers the block `resolve` with Guise.
      
      - parameter type: Usually the type of `D`, but can be any string.
      - parameter name: An optional name to disambiguate similar `type`s.
      - parameter container: A named container into which to place the dependency.
      - parameter lifecycle: The lifecyle of the registered dependency.
-     - parameter eval: The block to register with Guise.
+     - parameter resolve: The block to register with Guise.
      
      - returns: The registration key, which can be used with `unregister`.
      
      - warning: It is strongly recommended that the generic parameter `D` is not an optional.
      */
-    public static func register<P, D>(type type: String = String(reflecting: D.self), name: String? = nil, container: String? = nil, lifecycle: Lifecycle = .NotCached, eval: P -> D) -> Key {
+    public static func register<P, D>(type type: String = String(reflecting: D.self), name: String? = nil, container: String? = nil, lifecycle: Lifecycle = .NotCached, resolve: P -> D) -> Key {
         let key = Key(type: type, name: name, container: container)
         withWriteLock {
-            dependencies[key] = Dependency(lifecycle: lifecycle, eval: eval)
+            dependencies[key] = Dependency(lifecycle: lifecycle, resolve: resolve)
         }
         return key
     }

        }
    }
    
    // MARK: Keys
    
    public struct Key: Hashable {
        public let container: String?
        public let type: String
        public let name: String?
        
        private init(type: String, name: String? = nil, container: String? = nil) {
            self.type = type
            self.name = name
            self.container = container
            // djb2 hash algorithm: http://www.cse.yorku.ca/~oz/hash.html
            // &+ operator handles Int overflow
            var hash = 5381
            hash = ((hash << 5) &+ hash) &+ type.hashValue
            if let name = name {
                hash = ((hash << 5) &+ hash) &+ name.hashValue
            }
            if let container = container {
                hash = ((hash << 5) &+ hash) &+ container.hashValue
            }
            hashValue = hash
        }
        
        public let hashValue: Int
    }
    
    public static func key(type type: String, name: String? = nil, container: String? = nil) -> Key {
        return Key(type: type, name: name, container: container)
    }
    
    public static func key<P, D>(type type: String = String(reflecting: D.self), name: String? = nil, container: String? = nil, @noescape eval: P -> D) -> Key {
        return Key(type: type, name: name, container: container)
    }
    
    public static func container(name: String?, lifecycle: Lifecycle = .NotCached) -> Container {
        return Container(name: name, lifecycle: lifecycle)
    }
}

public struct Container {
    
    public let container: String?
    public let lifecycle: Lifecycle
    
    private init(name: String?, lifecycle: Lifecycle) {
        self.container = name
        self.lifecycle = lifecycle
    }
    
    /**
     Registers the block `eval` in the current Guise container.
     
     - parameter type: Usually the type of `D`, but can be any string.
     - parameter name: An optional name to disambiguate similar `type`s.
     - parameter lifecycle: The lifecyle of the registered dependency.
     - parameter eval: The block to register with Guise.
     
     - returns: The registration key, which can be used with `unregister`.
     
     - warning: It is strongly recommended that the generic parameter `D` is not an optional.
     */
    public func register<P, D>(type type: String = String(reflecting: D.self), name: String? = nil, lifecycle: Lifecycle? = nil, eval: P -> D) -> Any {
        return Guise.register(type: type, name: name, container: container, lifecycle: lifecycle ?? self.lifecycle, eval: eval)
    }
    
    /**
     Registers an existing instance in the current Guise container.
     
     - note: This effectively creates a singleton. If you want your singleton created lazily,
     register it with a block and set `lifecycle` to `.Cached`.
     
     - parameter instance: The instance to register.
     - parameter type: Usually the type of `D`, but can be any string.
     - parameter name: An optional name to disambiguate the same `type`.
     
     - returns: The registration key, which can be used with `unregister`.
     
     - warning: It is strongly recommended that the generic parameter `D` is not an optional.
     */
    public func register<D>(instance: D, type: String = String(reflecting: D.self), name: String? = nil) -> Any {
        return register(type: type, name: name, lifecycle: .Cached) { instance }
    }
    
    /**
     Resolves an instance of `D` in the current Guise container.
     
     - parameter parameter: The parameter to pass to the registered block.
     - parameter type: Usually the type of `D`, can be any string.
     - parameter name: An optional name to disambiguate the same `type`.
     - parameter lifecycle: The desired lifecyle of the registered dependency.
     
     - returns: The result of the registered block, or nil if not registered.
     
     - note: The meaning of `lifecycle` here is a bit complex. If `.Once` is passed, the dependency is returned and
     then immediately unregistered, regardless of how it was originally registered. If `.Cached` (the default) is passed and
     the dependency was originally registered with `.Cached`, a cached a value is returned. If `.NotCached` is passed and the
     dependency was originally registered with `.Cached`, the cached value is ignored and a new value is calculated. In all
     other cases, a new value is calculated by invoking the registered block.
     */
    public func resolve<D>(parameter: Any, type: String = String(reflecting: D.self), name: String? = nil, lifecycle: Lifecycle = .Cached) -> D? {
        return Guise.resolve(parameter, type: type, name: name, container: container, lifecycle: lifecycle)
    }
    
    /**
     Resolves an instance of `D` in the current Guise container.
     
     - parameter parameters: The parameters to pass to the registered block.
     - parameter type: Usually the type of `D`, can be any string.
     - parameter name: An optional name to disambiguate similar `type`s.
     - parameter lifecycle: The desired lifecycle of the registered dependency.
     
     - returns: The result of the registered block, or nil if not registered.
     
     - note: The meaning of `lifecycle` here is a bit complex. If `.Once` is passed, the dependency is returned and
     then immediately unregistered, regardless of how it was originally registered. If `.Cached` (the default) is passed and
     the dependency was originally registered with `.Cached`, a cached a value is returned. If `.NotCached` is passed and the
     dependency was originally registered with `.Cached`, the cached value is ignored and a new value is calculated. In all
     other cases, a new value is calculated by invoking the registered block.
     */
    public func resolve<D>(type type: String = String(reflecting: D.self), name: String? = nil, lifecycle: Lifecycle = .Cached) -> D? {
        return resolve((), type: type, name: name, lifecycle: lifecycle)
    }
    
    /**
     Unregisters the dependency with the given type and name from the current Guise container.
     
     - parameter type: The type of the dependency to unregister.
     - parameter name: The name of the dependency to unregister (optional).
     */
    public func unregister(type type: String, name: String? = nil) -> Bool {
        return Guise.unregister(type: type, name: name, container: container)
    }
    
    /**
     Unregisters the dependency with the given name and type, as determined by the `eval` block,
     from the current Guise container.
     
     - parameter name: The optional name under which the dependency was registered.
     - parameter eval: A block (not called) used to determine the type that was registered.
     
     - returns: Whether or not the key was present and could be unregistered.
     
     - note: The block is never called. It is only used to determine the type used to
     originally register the block. The block can take a parameter just like the registration
     block, but it is ignored.
     */
    public func unregister<P, D>(name name: String? = nil, @noescape eval: P -> D) -> Bool {
        return Guise.unregister(name: name, container: container, eval: eval)
    }
    
    /**
     Clears all dependencies in this container from Guise.
     */
    public func reset() {
        Guise.reset(container)
    }

    public func key(type type: String, name: String? = nil) -> Guise.Key {
        return Guise.key(type: type, name: name, container: container)
    }
    
    public func key<P, D>(type type: String = String(reflecting: D.self), name: String? = nil, @noescape eval: P -> D) -> Guise.Key {
        return Guise.key(type: type, name: name, container: container)
    }
    
}

public func ==(lhs: Guise.Key, rhs: Guise.Key) -> Bool {
    if lhs.hashValue != rhs.hashValue { return false }
    if lhs.type != rhs.type { return false }
    if lhs.name != rhs.name { return false }
    if lhs.container != rhs.container { return false }
    return true
}

    private static var dependencies = [Key: Dependency]()
    
    // MARK: Locking
    // Inspired by some of John Gallagher's locking code in the excellent Deferred library at https://github.com/bignerdranch/Deferred
    
    private static var lock: UnsafeMutablePointer<pthread_rwlock_t> = {
        var lock = UnsafeMutablePointer<pthread_rwlock_t>.alloc(1)
