     }
 
     func trim() -> String {
-        return trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
+        // trimmingCharacters() in the stdlib is not very efficiently
+        // implemented, perhaps because it always creates a new string.
+        // Avoid actually calling it if it's not needed.
+        guard count > 0 else { return self }
+        let (firstChar, lastChar) = (first!, last!)
+        if firstChar.isWhitespace || lastChar.isWhitespace || firstChar.isNewline || lastChar.isNewline {
+            return trimmingCharacters(in: .whitespacesAndNewlines)
+        }
+        return self
     }
 
     func equalsIgnoreCase(string: String?) -> Bool {
-		if(string == nil) {return false}
-        return string!.lowercased() == lowercased()
+        if let string = string {
+            return caseInsensitiveCompare(string) == .orderedSame
+        }
+        return false
     }
 
     static func toHexString(n: Int) -> String {

	func startsWith(_ string: String) -> Bool {
        return self.hasPrefix(string)
    }

	func indexOf(_ substring: String, _ offset: Int ) -> Int {
        if(offset > count) {return -1}


    }

	func unicodeScalar(_ i: Int) -> UnicodeScalar {
        let ix = unicodeScalars.index(unicodeScalars.startIndex, offsetBy: i)
		return unicodeScalars[ix]
    }

	func string(_ offset: Int, _ count: Int) -> String {
		let truncStart = self.unicodeScalars.count-offset
