 let snowy = Cat(name: "Snowy")
 let snuffles = Cat(name: "Snuffles")
 
-matt.addPet(fido)
-matt.addPet(spot)
-matt.addPet(snowy)
-matt.addPet(snuffles)
-
-iterator(matt.pets) { (item) in
+matt.addItem(fido)
+matt.addItem(spot)
+matt.addItem(snowy)
+matt.addItem(snuffles)
+
+iterator(matt.items) { (item) in
     
     print("Matt's has a pet named \(item.name)")
 }
+
+// sam, the owner of Ints
+
+let sam = Owner<Int>()
+
+sam.addItem(1)
+sam.addItem(2)
+sam.addItem(3)
+
+iterator(sam.items) { (item) in
+
+    print("Sam owns \(item)")
+}
+/*:
+ - experiment: Create another instance of the `Owner` generic type but use the `String` type as the parameter type name.
+ */
+
 /*:
  ## Extending Generic Types
- 
+ Generic types can be extended just like you extend a concrete type, by using the `extension` keyword then the name of the generic.
+ - example: Below we have extended the `Owner` generic type by adding a `typealias` `Pet` to refer to parameter type name `Something`. `Pet` is a more descriptive thing for the instances of the `Owner` type. With extension, we can add computed properties, function and subscripts.
  */
 extension Owner {
     
+    typealias Pet = Something
+    
     var firstPet: Pet? {
         
-        return pets.isEmpty ? nil : pets.first
+        return items.isEmpty ? nil : items.first
     }
     
     var lastPet: Pet? {
         
-        return pets.isEmpty ? nil : pets.last
+        return items.isEmpty ? nil : items.last
+    }
+    
+    
+    func addPet(item: Pet) {
+        
+        items.append(item)
     }
     
     var dogs: [Dog] {

let dogIsYappy = matt.isYappy(fido)
let catIsNotYappy = matt.isYappy(snowy)
/*:
 ## Associated Types
 
 */
func ==(lhs: Animal, rhs: Animal) -> Bool {
    
    return lhs.name == rhs.name
}

protocol Kennel {

    associatedtype Pet

    func add(pet: Pet)
    
    func remove(pet: Pet) -> Pet?
    
    var count: Int { get }

    subscript(i: Int) -> Pet { get }
}

class BackYard: Kennel {

    var animals = [Animal]()


        closure(cat: cats[index])
    }
}
/*:
 - example: Calling the interator functions for dog and cat.
 */
iteratorDogs(dogs) { (dog) in
    
    print("\(dog.name) makes a \(dog.makeSound()) sound.")
