         }
     }
     
+    // TODO: make this work if cursor position is shifted
+    func setCapsIfNeeded() {
+        if self.shiftState == ShiftState.Disabled {
+            if self.shouldAutoCapitalize() {
+                self.shiftState = ShiftState.Enabled
+            }
+        }
+    }
+    
+    func characterIsPunctuation(character: Character) -> Bool {
+        return (character == ".") || (character == "!") || (character == "?")
+    }
+    
+    func characterIsWhitespace(character: Character) -> Bool {
+        // there are others, but who cares
+        return (character == " ") || (character == "\n") || (character == "\r") || (character == "\t")
+    }
+    
+    func stringIsWhitespace(string: String?) -> Bool {
+        if string != nil {
+            for char in string! {
+                if !characterIsWhitespace(char) {
+                    return false
+                }
+            }
+        }
+        return true
+    }
+    
+    func shouldAutoCapitalize() -> Bool {
+        if let traits = self.textDocumentProxy as? UITextInputTraits {
+            if let autocapitalization = traits.autocapitalizationType {
+                var documentProxy = self.textDocumentProxy as? UITextDocumentProxy
+                var beforeContext = documentProxy?.documentContextBeforeInput
+                
+                switch autocapitalization {
+                case .None:
+                    return false
+                case .Words:
+                    if let beforeContext = documentProxy?.documentContextBeforeInput {
+                        let stringContext = beforeContext as NSString
+                        let previousCharacter = stringContext.characterAtIndex(stringContext.length - 1)
+                        return self.characterIsWhitespace(Character(UnicodeScalar(previousCharacter)))
+                    }
+                    else {
+                        return true
+                    }
+                
+                case .Sentences:
+                    if let beforeContext = documentProxy?.documentContextBeforeInput {
+                        let stringContext = beforeContext as NSString
+                        let offset = min(3, stringContext.length)
+                        
+                        for (var i = 0; i < offset; i += 1) {
+                            let char = stringContext.characterAtIndex(stringContext.length - (i + 1))
+                            let uniChar = Character(UnicodeScalar(char))
+                            
+                            if characterIsPunctuation(uniChar) {
+                                if i == 0 {
+                                    return false //not enough spaces after punctuation
+                                }
+                                else {
+                                    return true
+                                }
+                            }
+                            else {
+                                if !characterIsWhitespace(uniChar) {
+                                    return false
+                                }
+                                else {
+                                    if i == offset - 1 {
+                                        if offset != 3 {
+                                            return false //not enough spaces by themselves
+                                        }
+                                        else {
+                                            return true
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        
+                        return false
+                    }
+                    else {
+                        return true
+                    }
+                case .AllCharacters:
+                    return true
+                }
+            }
+            else {
+                return false
+            }
+        }
+        else {
+            return false
+        }
+    }
+    
     func keyPressed(key: Key) {}
 }
 

            else if model.type == Key.KeyType.Character {
                self.setMode(0)
            }
        }
        
        if self.shiftState == ShiftState.Enabled {
            self.shiftState = ShiftState.Disabled
        }
    }
    

    }
    var backspaceDelayTimer: NSTimer?
    var backspaceRepeatTimer: NSTimer?
    
    enum AutoPeriodState {
        case NoSpace
        case FirstSpace
        case WaitingForCharacter
    }
    
    var autoPeriodState: AutoPeriodState = .WaitingForCharacter
    var lastCharCountInBeforeContext: Int = 0
    
    enum ShiftState {
        case Disabled
