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

    }

    
    mutating func hash(newHash: Element -> Int) throws {
        let oldHash = self.hashFunction
        let oldTable = self.table
        do {
            self.hashFunction = newHash
            self.table = [[Element]](count: oldTable.count, repeatedValue: [])
            for bucket in oldTable {
                for element in bucket {
                    try insert(element: element)
                }
            }
        } catch _ {
            self.hashFunction = oldHash
            self.table = oldTable

    }
    
    init(_ buckets : Int) { // convenience init
        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: (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: [(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: (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 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.key }
        return try f(h,i)
    }
    
    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.key }
        return try f(h,i)
    }
    
    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: (key: K, value: V)) throws {
        try insertNoCorrection(element: new)
        //P.ERFORMANCE useful? maybe saving counter and only testing after 10 insertions...
        try correctBucketCount()
    }
    
    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!] }
