     }
     
     init(_ buckets : Int) { // convenience init
-        self.init(_: buckets, hashFunction: { return $0.hashValue })
-    }
-    
-    init(_ buckets : Int, hashFunction: Element -> Int) {
-        table = [[Element]](count: buckets, repeatedValue: [])
+        self.init(_: buckets, hashFunction: { $0.hashValue })
+    }
+    
+    init(_ buckets : Int, hashFunction: K -> Int) {
+        table = [[(key: K, value: V)]](count: buckets, repeatedValue: [])
         self.hashFunction = hashFunction
     }
     
     //P.ERFORMANCE maybe in parallel or hashing all first in parallel, then appending all?
-    mutating func insert(elements: Element...) throws {
+    mutating func insert(elements: (key: K, value: V)...) throws {
         try insert(elements)
     }
     
     //P.ERFORMANCE maybe in parallel or hashing all first in parallel, then appending all?
-    mutating func insert(elements: [Element]) throws {
+    mutating func insert(elements: [(key: K, value: V)]) throws {
         for v in elements {
             try insertNoCorrection(element: v)
         }
+        // print("tries to correct in \(#function)")
         try correctBucketCount()
     }
     
+    subscript(key: K) -> V? {
+        get {
+            do {
+                return try self.get(key: key).value
+            } catch _ {
+                return nil
+            }
+        }
+        set {
+            do {
+                if newValue != nil {
+                    try overwriteOrAdd(element: (key, newValue!))
+                }
+            } catch let e {
+                print(e)
+            }
+        }
+    }
+    
     //I.DEA private?
-    mutating func insertNoCorrection(element new: Element) throws {
-        try executeForKey(new) {
+    mutating func insertNoCorrection(element new: (key: K, value: V)) throws {
+        // print("inserting " + new)
+        try executeForKey(new.key) {
             b,i in
                 if i != nil { throw HashTableError.InList }
                 else        { self.table[b].append(new) }
         }
     }
     
-    mutating func overwriteOrAdd(element: Element) throws {
-        try executeForKey(element) {
-            b, i in
-                if i != nil { self.table[b][i!] = element   }
-                else        { self.table[b].append(element) }
-        }
-    }
-    
-    mutating func executeForKey<T>(key: Element, f: (Int,Int?) throws -> T) throws -> T {
+    mutating func overwriteOrAdd(element new: (key: K, value: V)) throws {
+        try executeForKey(new.key) {
+            b, i in
+                if i != nil { self.table[b][i!] = new   }
+                else        { self.table[b].append(new) }
+        }
+    }
+    
+    func executeForKey<T>(key: K, f: (Int,Int?) throws -> T) throws -> T {
         let h = try hash(key)
-        let i = table[h].find { key == $0 }
+        let i = table[h].find { key == $0.key }
         return try f(h,i)
     }
     
-    mutating func executeForUniqueKey<T>(key: Element, f: (Int,Int?) throws -> T) throws -> T {
+    func executeForUniqueKey<T>(key: K, f: (Int,Int?) throws -> T) throws -> T {
         let h = try hash(key)
-        let i = try table[h].findUnique { key == $0 }
+        let i = try table[h].findUnique { key == $0.key }
         return try f(h,i)
     }
     
-    mutating func overwrite(element: Element) throws {
-        try executeForKey(element) {
-            b, i in
-                if i != nil { self.table[b][i!] = element    }
+    mutating func overwrite(element new: (key: K, value: V)) throws {
+        try executeForKey(new.key) {
+            b, i in
+                if i != nil { self.table[b][i!] = new    }
                 else        { throw HashTableError.NotInList }
         }
     }
     
-    mutating func insert(element new: Element) throws {
+    mutating func insert(element new: (key: K, value: V)) throws {
         try insertNoCorrection(element: new)
         //P.ERFORMANCE useful? maybe saving counter and only testing after 10 insertions...
         try correctBucketCount()
     }
     
-    mutating func get(key key: Element) throws -> Element {
+    func get(key key: K) throws -> (key: K, value: V) {
         return try executeForKey(key) {
             b, i in
                 if i != nil { return self.table[b][i!] }

    
    //T.ODO removeSavely - using findUnique
    
    mutating func remove(key key: Element) throws -> Element {
        return try executeForKey(key) {
            b, i in
                if i != nil { return self.table[b].removeAtIndex(i!) }

    }

    
    mutating func hash(newHash: K -> Int) throws {
        let oldHash = self.hashFunction
        let oldTable = self.table
        do {
            print("setting new hash")
            self.hashFunction = newHash
            self.table = [[(key: K, value: V)]](count: oldTable.count, repeatedValue: [])
            for bucket in oldTable {
                for element in bucket {
                    try insertNoCorrection(element: element)
                }
            }
            try correctBucketCount()
        } catch _ {
            self.hashFunction = oldHash
            self.table = oldTable
