summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorSimon Hafner <hafnersimon@gmail.com>2015-03-05 14:44:54 -0600
committerSimon Hafner <hafnersimon@gmail.com>2015-03-05 14:44:54 -0600
commit70eaf92ff0493ed11c6e6c8887bca1b235371aff (patch)
tree530255b69df349728c76621e97bf40a11d63fe79 /lib
parentf592240c545506448e2bea78a2fa3404c7f46e69 (diff)
parent8f43979cf6308c9d7e14a0d87c0faf227e1c4afe (diff)
downloadNim-70eaf92ff0493ed11c6e6c8887bca1b235371aff.tar.gz
Merge branch 'devel' into warning-for-result
Diffstat (limited to 'lib')
-rw-r--r--lib/core/locks.nim2
-rw-r--r--lib/core/macros.nim151
-rw-r--r--lib/core/typeinfo.nim4
-rw-r--r--lib/impure/db_mysql.nim4
-rw-r--r--lib/impure/rdstdin.nim52
-rw-r--r--lib/impure/re.nim6
-rw-r--r--lib/js/dom.nim20
-rw-r--r--lib/nimbase.h11
-rw-r--r--lib/nimrtl.nim.cfg (renamed from lib/nimrtl.nimrod.cfg)0
-rw-r--r--lib/packages/docutils/rstgen.nim2
-rw-r--r--lib/posix/posix.nim39
-rw-r--r--lib/posix/termios.nim264
-rw-r--r--lib/pure/actors.nim2
-rw-r--r--lib/pure/algorithm.nim59
-rw-r--r--lib/pure/asyncdispatch.nim60
-rw-r--r--lib/pure/asyncdispatch.nim.cfg (renamed from lib/pure/asyncdispatch.nimrod.cfg)0
-rw-r--r--lib/pure/asyncfile.nim22
-rw-r--r--lib/pure/asyncftpclient.nim6
-rw-r--r--lib/pure/asyncio.nim6
-rw-r--r--lib/pure/basic2d.nim6
-rw-r--r--lib/pure/basic3d.nim10
-rw-r--r--lib/pure/browsers.nim2
-rw-r--r--lib/pure/collections/LockFreeHash.nim2
-rw-r--r--lib/pure/collections/critbits.nim2
-rw-r--r--lib/pure/collections/intsets.nim5
-rw-r--r--lib/pure/collections/sequtils.nim28
-rw-r--r--lib/pure/collections/sets.nim168
-rw-r--r--lib/pure/collections/tables.nim290
-rw-r--r--lib/pure/colors.nim4
-rw-r--r--lib/pure/complex.nim98
-rw-r--r--lib/pure/encodings.nim2
-rw-r--r--lib/pure/events.nim2
-rw-r--r--lib/pure/fsmonitor.nim34
-rw-r--r--lib/pure/ftpclient.nim82
-rw-r--r--lib/pure/htmlparser.nim4
-rw-r--r--lib/pure/httpclient.nim4
-rw-r--r--lib/pure/httpserver.nim2
-rw-r--r--lib/pure/json.nim79
-rw-r--r--lib/pure/logging.nim4
-rw-r--r--lib/pure/matchers.nim2
-rw-r--r--lib/pure/math.nim39
-rw-r--r--lib/pure/net.nim43
-rw-r--r--lib/pure/nimprof.nim2
-rw-r--r--lib/pure/nimprof.nim.cfg (renamed from lib/pure/nimprof.nimrod.cfg)0
-rw-r--r--lib/pure/os.nim46
-rw-r--r--lib/pure/osproc.nim18
-rw-r--r--lib/pure/parsecfg.nim2
-rw-r--r--lib/pure/parseopt.nim9
-rw-r--r--lib/pure/parseopt2.nim2
-rw-r--r--lib/pure/parseutils.nim4
-rw-r--r--lib/pure/parsexml.nim2
-rw-r--r--lib/pure/rationals.nim275
-rw-r--r--lib/pure/ropes.nim2
-rw-r--r--lib/pure/selectors.nim17
-rw-r--r--lib/pure/smtp.nim.cfg (renamed from lib/pure/smtp.nimrod.cfg)0
-rw-r--r--lib/pure/sockets.nim8
-rw-r--r--lib/pure/streams.nim20
-rw-r--r--lib/pure/strtabs.nim4
-rw-r--r--lib/pure/strutils.nim59
-rw-r--r--lib/pure/subexes.nim4
-rw-r--r--lib/pure/terminal.nim28
-rw-r--r--lib/pure/times.nim431
-rw-r--r--lib/pure/unicode.nim5
-rw-r--r--lib/pure/unittest.nim3
-rw-r--r--lib/pure/uri.nim10
-rw-r--r--lib/pure/xmldom.nim2
-rw-r--r--lib/pure/xmlparser.nim4
-rw-r--r--lib/system.nim86
-rw-r--r--lib/system/arithm.nim2
-rw-r--r--lib/system/assign.nim10
-rw-r--r--lib/system/cgprocs.nim2
-rw-r--r--lib/system/dyncalls.nim17
-rw-r--r--lib/system/excpt.nim14
-rw-r--r--lib/system/gc.nim40
-rw-r--r--lib/system/gc2.nim146
-rw-r--r--lib/system/gc_ms.nim12
-rw-r--r--lib/system/hti.nim8
-rw-r--r--lib/system/jssys.nim2
-rw-r--r--lib/system/repr.nim12
-rw-r--r--lib/system/sysio.nim26
-rw-r--r--lib/system/sysstr.nim18
-rw-r--r--lib/system/threads.nim16
-rw-r--r--lib/system/timers.nim4
-rw-r--r--lib/windows/windows.nim2
-rw-r--r--lib/windows/winlean.nim8
-rw-r--r--lib/wrappers/claro.nim14
-rw-r--r--lib/wrappers/libffi/msvc/win32.c2
-rw-r--r--lib/wrappers/libuv.nim58
-rw-r--r--lib/wrappers/mysql.nim12
-rw-r--r--lib/wrappers/readline/history.nim2
-rw-r--r--lib/wrappers/readline/tweaked/history.h2
-rw-r--r--lib/wrappers/sdl/sdl.nim10
-rw-r--r--lib/wrappers/sdl/sdl_mixer.nim2
-rw-r--r--lib/wrappers/zip/zlib.nim2
94 files changed, 2379 insertions, 729 deletions
diff --git a/lib/core/locks.nim b/lib/core/locks.nim
index 766b7b536..8a809fc84 100644
--- a/lib/core/locks.nim
+++ b/lib/core/locks.nim
@@ -21,7 +21,7 @@ type
     ## is performed. Deprecated, do not use anymore!
   AquireEffect* {.deprecated.} = object of LockEffect  ## \
     ## effect that denotes that some lock is
-    ## aquired. Deprecated, do not use anymore!
+    ## acquired. Deprecated, do not use anymore!
   ReleaseEffect* {.deprecated.} = object of LockEffect ## \
     ## effect that denotes that some lock is
     ## released. Deprecated, do not use anymore!
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 3e0da79be..0888a8767 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2013 Andreas Rumpf
+#        (c) Copyright 2015 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -15,7 +15,7 @@ include "system/inclrtl"
 ## .. include:: ../doc/astspec.txt
 
 type
-  TNimrodNodeKind* = enum
+  NimNodeKind* = enum
     nnkNone, nnkEmpty, nnkIdent, nnkSym,
     nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
     nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
@@ -72,20 +72,26 @@ type
     nnkEnumFieldDef,
     nnkArglist, nnkPattern
     nnkReturnToken
-  TNimNodeKinds* = set[TNimrodNodeKind]
-  TNimrodTypeKind* = enum
+  NimNodeKinds* = set[NimNodeKind]
+  NimTypeKind* = enum
     ntyNone, ntyBool, ntyChar, ntyEmpty,
     ntyArrayConstr, ntyNil, ntyExpr, ntyStmt,
-    ntyTypeDesc, ntyGenericInvokation, ntyGenericBody, ntyGenericInst,
+    ntyTypeDesc, ntyGenericInvocation, ntyGenericBody, ntyGenericInst,
     ntyGenericParam, ntyDistinct, ntyEnum, ntyOrdinal,
     ntyArray, ntyObject, ntyTuple, ntySet,
     ntyRange, ntyPtr, ntyRef, ntyVar,
     ntySequence, ntyProc, ntyPointer, ntyOpenArray,
     ntyString, ntyCString, ntyForward, ntyInt,
     ntyInt8, ntyInt16, ntyInt32, ntyInt64,
-    ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128
-  TNimTypeKinds* = set[TNimrodTypeKind]
-  TNimrodSymKind* = enum
+    ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128,
+    ntyUInt, ntyUInt8, ntyUInt16, ntyUInt32, ntyUInt64,
+    ntyBigNum, 
+    ntyConst, ntyMutable, ntyVarargs, 
+    ntyIter,
+    ntyError
+    
+  TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
+  NimSymKind* = enum
     nskUnknown, nskConditional, nskDynLib, nskParam,
     nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet,
     nskConst, nskResult,
@@ -94,22 +100,28 @@ type
     nskEnumField, nskForVar, nskLabel,
     nskStub
 
-  TNimSymKinds* = set[TNimrodSymKind]
+  TNimSymKinds* {.deprecated.} = set[NimSymKind]
 
 type
-  TNimrodIdent* = object of RootObj
-    ## represents a Nimrod identifier in the AST
+  NimIdent* = object of RootObj
+    ## represents a Nim identifier in the AST
 
-  TNimrodSymbol {.final.} = object # hidden
-  PNimrodSymbol* {.compilerproc.} = ref TNimrodSymbol
-    ## represents a Nimrod *symbol* in the compiler; a *symbol* is a looked-up
+  NimSymObj = object # hidden
+  NimSym* = ref NimSymObj
+    ## represents a Nim *symbol* in the compiler; a *symbol* is a looked-up
     ## *ident*.
 
+{.deprecated: [TNimrodNodeKind: NimNodeKind, TNimNodeKinds: NimNodeKinds,
+    TNimrodTypeKind: NimTypeKind, TNimrodSymKind: NimSymKind,
+    TNimrodIdent: NimIdent, PNimrodSymbol: NimSym].}
+
 const
   nnkLiterals* = {nnkCharLit..nnkNilLit}
   nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
                    nnkCallStrLit}
 
+{.push warning[deprecated]: off.}
+
 proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild", noSideEffect.}
   ## get `n`'s `i`'th child.
 
@@ -117,31 +129,31 @@ proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild",
   noSideEffect.}
   ## set `n`'s `i`'th child to `child`.
 
-proc `!`*(s: string): TNimrodIdent {.magic: "StrToIdent", noSideEffect.}
+proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.}
   ## constructs an identifier from the string `s`
 
-proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr", noSideEffect.}
-  ## converts a Nimrod identifier to a string
+proc `$`*(i: NimIdent): string {.magic: "IdentToStr", noSideEffect.}
+  ## converts a Nim identifier to a string
 
-proc `$`*(s: PNimrodSymbol): string {.magic: "IdentToStr", noSideEffect.}
-  ## converts a Nimrod symbol to a string
+proc `$`*(s: NimSym): string {.magic: "IdentToStr", noSideEffect.}
+  ## converts a Nim symbol to a string
 
-proc `==`*(a, b: TNimrodIdent): bool {.magic: "EqIdent", noSideEffect.}
-  ## compares two Nimrod identifiers
+proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
+  ## compares two Nim identifiers
 
 proc `==`*(a, b: PNimrodNode): bool {.magic: "EqNimrodNode", noSideEffect.}
-  ## compares two Nimrod nodes
+  ## compares two Nim nodes
 
 proc len*(n: PNimrodNode): int {.magic: "NLen", noSideEffect.}
   ## returns the number of children of `n`.
 
 proc add*(father, child: PNimrodNode): PNimrodNode {.magic: "NAdd", discardable,
-  noSideEffect.}
+  noSideEffect, locks: 0.}
   ## Adds the `child` to the `father` node. Returns the
   ## father node so that calls can be nested.
 
 proc add*(father: PNimrodNode, children: varargs[PNimrodNode]): PNimrodNode {.
-  magic: "NAddMultiple", discardable, noSideEffect.}
+  magic: "NAddMultiple", discardable, noSideEffect, locks: 0.}
   ## Adds each child of `children` to the `father` node.
   ## Returns the `father` node so that calls can be nested.
 
@@ -153,15 +165,27 @@ proc kind*(n: PNimrodNode): TNimrodNodeKind {.magic: "NKind", noSideEffect.}
 
 proc intVal*(n: PNimrodNode): BiggestInt {.magic: "NIntVal", noSideEffect.}
 proc floatVal*(n: PNimrodNode): BiggestFloat {.magic: "NFloatVal", noSideEffect.}
-proc symbol*(n: PNimrodNode): PNimrodSymbol {.magic: "NSymbol", noSideEffect.}
-proc ident*(n: PNimrodNode): TNimrodIdent {.magic: "NIdent", noSideEffect.}
-proc typ*(n: PNimrodNode): typedesc {.magic: "NGetType", noSideEffect.}
+proc symbol*(n: PNimrodNode): NimSym {.magic: "NSymbol", noSideEffect.}
+proc ident*(n: PNimrodNode): NimIdent {.magic: "NIdent", noSideEffect.}
+
+proc getType*(n: PNimrodNode): PNimrodNode {.magic: "NGetType", noSideEffect.}
+  ## with 'getType' you can access the node's `type`:idx:. A Nim type is
+  ## mapped to a Nim AST too, so it's slightly confusing but it means the same
+  ## API can be used to traverse types. Recursive types are flattened for you
+  ## so there is no danger of infinite recursions during traversal. To
+  ## resolve recursive types, you have to call 'getType' again. To see what
+  ## kind of type it is, call `typeKind` on getType's result.
+
+proc typeKind*(n: PNimrodNode): NimTypeKind {.magic: "NGetType", noSideEffect.}
+  ## Returns the type kind of the node 'n' that should represent a type, that
+  ## means the node should have been obtained via `getType`.
+
 proc strVal*(n: PNimrodNode): string  {.magic: "NStrVal", noSideEffect.}
 
 proc `intVal=`*(n: PNimrodNode, val: BiggestInt) {.magic: "NSetIntVal", noSideEffect.}
 proc `floatVal=`*(n: PNimrodNode, val: BiggestFloat) {.magic: "NSetFloatVal", noSideEffect.}
-proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol", noSideEffect.}
-proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent", noSideEffect.}
+proc `symbol=`*(n: PNimrodNode, val: NimSym) {.magic: "NSetSymbol", noSideEffect.}
+proc `ident=`*(n: PNimrodNode, val: NimIdent) {.magic: "NSetIdent", noSideEffect.}
 #proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
 # this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
 # can easily do:
@@ -177,13 +201,13 @@ proc newNimNode*(kind: TNimrodNodeKind,
 proc copyNimNode*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimNode", noSideEffect.}
 proc copyNimTree*(n: PNimrodNode): PNimrodNode {.magic: "NCopyNimTree", noSideEffect.}
 
-proc error*(msg: string) {.magic: "NError", gcsafe.}
+proc error*(msg: string) {.magic: "NError", benign.}
   ## writes an error message at compile time
 
-proc warning*(msg: string) {.magic: "NWarning", gcsafe.}
+proc warning*(msg: string) {.magic: "NWarning", benign.}
   ## writes a warning message at compile time
 
-proc hint*(msg: string) {.magic: "NHint", gcsafe.}
+proc hint*(msg: string) {.magic: "NHint", benign.}
   ## writes a hint message at compile time
 
 proc newStrLitNode*(s: string): PNimrodNode {.compileTime, noSideEffect.} =
@@ -201,7 +225,7 @@ proc newFloatLitNode*(f: BiggestFloat): PNimrodNode {.compileTime.} =
   result = newNimNode(nnkFloatLit)
   result.floatVal = f
 
-proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} =
+proc newIdentNode*(i: NimIdent): PNimrodNode {.compileTime.} =
   ## creates an identifier node from `i`
   result = newNimNode(nnkIdent)
   result.ident = i
@@ -212,7 +236,7 @@ proc newIdentNode*(i: string): PNimrodNode {.compileTime.} =
   result.ident = !i
 
 type
-  TBindSymRule* = enum   ## specifies how ``bindSym`` behaves
+  BindSymRule* = enum    ## specifies how ``bindSym`` behaves
     brClosed,            ## only the symbols in current scope are bound
     brOpen,              ## open wrt overloaded symbols, but may be a single
                          ## symbol if not ambiguous (the rules match that of
@@ -221,7 +245,9 @@ type
                          ## if not ambiguous (this cannot be achieved with
                          ## any other means in the language currently)
 
-proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {.
+{.deprecated: [TBindSymRule: BindSymRule].}
+
+proc bindSym*(ident: string, rule: BindSymRule = brClosed): PNimrodNode {.
               magic: "NBindSym", noSideEffect.}
   ## creates a node that binds `ident` to a symbol node. The bound symbol
   ## may be an overloaded symbol.
@@ -232,16 +258,16 @@ proc bindSym*(ident: string, rule: TBindSymRule = brClosed): PNimrodNode {.
   ## If ``rule == brForceOpen`` always an ``nkOpenSymChoice`` tree is
   ## returned even if the symbol is not ambiguous.
 
-proc genSym*(kind: TNimrodSymKind = nskLet; ident = ""): PNimrodNode {.
+proc genSym*(kind: NimSymKind = nskLet; ident = ""): PNimrodNode {.
   magic: "NGenSym", noSideEffect.}
   ## generates a fresh symbol that is guaranteed to be unique. The symbol
   ## needs to occur in a declaration context.
 
-proc callsite*(): PNimrodNode {.magic: "NCallSite", gcsafe.}
-  ## returns the AST if the invokation expression that invoked this macro.
+proc callsite*(): PNimrodNode {.magic: "NCallSite", benign.}
+  ## returns the AST of the invocation expression that invoked this macro.
 
 proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
-  ## converts the AST `n` to the concrete Nimrod code and wraps that
+  ## converts the AST `n` to the concrete Nim code and wraps that
   ## in a string literal node
   return newStrLitNode(repr(n))
 
@@ -317,7 +343,7 @@ proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
   ## checks that `n` is of kind `k`. If this is not the case,
   ## compilation aborts with an error message. This is useful for writing
   ## macros that check the AST that is passed to them.
-  if n.kind != k: error("macro expects a node of kind: " & $k)
+  if n.kind != k: error("Expected a node of kind " & $k & ", got " & $n.kind)
 
 proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
   ## checks that `n` has at least `min` children. If this is not the case,
@@ -339,7 +365,7 @@ proc newCall*(theProc: PNimrodNode,
   result.add(theProc)
   result.add(args)
 
-proc newCall*(theProc: TNimrodIdent,
+proc newCall*(theProc: NimIdent,
               args: varargs[PNimrodNode]): PNimrodNode {.compileTime.} =
   ## produces a new call node. `theProc` is the proc that is called with
   ## the arguments ``args[0..]``.
@@ -375,7 +401,7 @@ proc newLit*(s: string): PNimrodNode {.compileTime.} =
   result = newNimNode(nnkStrLit)
   result.strVal = s
 
-proc nestList*(theProc: TNimrodIdent,
+proc nestList*(theProc: NimIdent,
                x: PNimrodNode): PNimrodNode {.compileTime.} =
   ## nests the list `x` into a tree of call expressions:
   ## ``[a, b, c]`` is transformed into ``theProc(a, theProc(c, d))``.
@@ -387,11 +413,11 @@ proc nestList*(theProc: TNimrodIdent,
     # This could easily user code and so should be fixed in evals.nim somehow.
     result = newCall(theProc, x[i], copyNimTree(result))
 
-proc treeRepr*(n: PNimrodNode): string {.compileTime.} =
+proc treeRepr*(n: PNimrodNode): string {.compileTime, benign.} =
   ## Convert the AST `n` to a human-readable tree-like string.
   ##
   ## See also `repr` and `lispRepr`.
-  proc traverse(res: var string, level: int, n: PNimrodNode) =
+  proc traverse(res: var string, level: int, n: PNimrodNode) {.benign.} =
     for i in 0..level-1: res.add "  "
     res.add(($n.kind).substr(3))
 
@@ -412,7 +438,7 @@ proc treeRepr*(n: PNimrodNode): string {.compileTime.} =
   result = ""
   traverse(result, 0, n)
 
-proc lispRepr*(n: PNimrodNode): string {.compileTime.} =
+proc lispRepr*(n: PNimrodNode): string {.compileTime, benign.} =
   ## Convert the AST `n` to a human-readable lisp-like string,
   ##
   ## See also `repr` and `treeRepr`.
@@ -430,10 +456,11 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} =
   of nnkSym: add(result, $n.symbol)
   of nnkNone: assert false
   else:
-    add(result, lispRepr(n[0]))
-    for j in 1..n.len-1:
-      add(result, ", ")
-      add(result, lispRepr(n[j]))
+    if n.len > 0:
+      add(result, lispRepr(n[0]))
+      for j in 1..n.len-1:
+        add(result, ", ")
+        add(result, lispRepr(n[j]))
 
   add(result, ")")
 
@@ -554,10 +581,8 @@ const
   CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
     nnkCallStrLit, nnkHiddenCallConv}
 
-from strutils import cmpIgnoreStyle, format
-
 proc expectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
-  assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind)
+  assert n.kind in k, "Expected one of " & $k & ", got " & $n.kind
 
 proc newProc*(name = newEmptyNode(); params: openArray[PNimrodNode] = [newEmptyNode()];
     body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
@@ -627,7 +652,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
 
 
 template badNodeKind(k; f): stmt{.immediate.} =
-  assert false, "Invalid node kind $# for macros.`$2`".format(k, f)
+  assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
 
 proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
   case someProc.kind:
@@ -651,7 +676,7 @@ proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
   else:
     badNodeKind someProc.kind, "body="
 
-proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.}
+proc basename*(a: PNimrodNode): PNimrodNode {.compiletime, benign.}
 
 
 proc `$`*(node: PNimrodNode): string {.compileTime.} =
@@ -749,6 +774,22 @@ proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} =
   ## An alias for copyNimTree().
   return node.copyNimTree()
 
+proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
+  proc toLower(c: char): char {.inline.} =
+    if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A')))
+    else: result = c
+  var i = 0
+  var j = 0
+  while true:
+    while a[i] == '_': inc(i)
+    while b[j] == '_': inc(j) # BUGFIX: typo
+    var aa = toLower(a[i])
+    var bb = toLower(b[j])
+    result = ord(aa) - ord(bb)
+    if result != 0 or aa == '\0': break
+    inc(i)
+    inc(j)
+
 proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
   ## Check if two idents are identical.
 
@@ -784,3 +825,5 @@ when not defined(booting):
     macro payload: stmt {.gensym.} =
       result = parseStmt(e)
     payload()
+
+{.pop.}
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index 0046924a1..c3ff66591 100644
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -66,9 +66,9 @@ type
   ppointer = ptr pointer
   pbyteArray = ptr array[0.. 0xffff, int8]
 
-  TGenSeq = object
+  TGenericSeq {.importc.} = object
     len, space: int
-  PGenSeq = ptr TGenSeq
+  PGenSeq = ptr TGenericSeq
 
 const
   GenericSeqSize = (2 * sizeof(int))
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim
index 968a2923a..dab84c2d5 100644
--- a/lib/impure/db_mysql.nim
+++ b/lib/impure/db_mysql.nim
@@ -16,11 +16,11 @@ type
   TDbConn* = PMySQL    ## encapsulates a database connection
   TRow* = seq[string]  ## a row of a dataset. NULL database values will be
                        ## transformed always to the empty string.
-  EDb* = object of EIO ## exception that is raised if a database error occurs
+  EDb* = object of IOError ## exception that is raised if a database error occurs
 
   TSqlQuery* = distinct string ## an SQL query string
 
-  FDb* = object of FIO ## effect that denotes a database operation
+  FDb* = object of IOEffect ## effect that denotes a database operation
   FReadDb* = object of FDb   ## effect that denotes a read operation
   FWriteDb* = object of FDb  ## effect that denotes a write operation
 
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index 07ef13fd9..aaf2ed1ca 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2015 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -13,6 +13,8 @@
 ## is used. This suffices because Windows' console already provides the 
 ## wanted functionality.
 
+{.deadCodeElim: on.}
+
 when defined(Windows):
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} = 
@@ -31,9 +33,31 @@ when defined(Windows):
     stdout.write(prompt)
     result = readLine(stdin, line)
 
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
+                              bool {.tags: [ReadIOEffect, WriteIOEffect].} =
+    ## Reads a `password` from stdin without printing it. `password` must not
+    ## be ``nil``! Returns ``false`` if the end of the file has been reached,
+    ## ``true`` otherwise.
+    proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
+
+    password.setLen(0)
+    var c: char
+    stdout.write(prompt)
+    while true:
+      c = getch().char
+      case c
+      of '\r', chr(0xA):
+        break
+      of '\b':
+        password.setLen(password.len - 1)
+      else:
+        password.add(c)
+    stdout.write "\n"
+    # TODO: How to detect EOF on Windows?
+
 else:
-  import readline, history
-    
+  import readline, history, termios, unsigned
+
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} =
     var buffer = readline.readLine(prompt)
@@ -55,8 +79,26 @@ else:
     result = true
 
   # initialization:
-  # disable auto-complete: 
+  # disable auto-complete:
   proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
-  
+
   discard readline.bind_key('\t'.ord, doNothing)
 
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
+                              bool {.tags: [ReadIOEffect, WriteIOEffect].} =
+    password.setLen(0)
+    let fd = stdin.getFileHandle()
+    var cur, old: Termios
+    discard fd.tcgetattr(cur.addr)
+    old = cur
+    cur.lflag = cur.lflag and not Tcflag(ECHO)
+    discard fd.tcsetattr(TCSADRAIN, cur.addr)
+    stdout.write prompt
+    result = stdin.readLine(password)
+    stdout.write "\n"
+    discard fd.tcsetattr(TCSADRAIN, old.addr)
+
+proc readPasswordFromStdin*(prompt: string): TaintedString =
+  ## Reads a password from stdin without printing it.
+  result = TaintedString("")
+  discard readPasswordFromStdin(prompt, result)
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index a7bebb81c..7d5ff8948 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -9,6 +9,12 @@
 
 ## Regular expression support for Nim. Consider using the pegs module
 ## instead.
+##
+## **Note:** The 're' proc defaults to the **extended regular expression
+## syntax** which lets you use whitespace freely to make your regexes readable.
+## However, this means to match whitespace ``\s`` or something similar has
+## to be used.
+##
 ## This module is implemented by providing a wrapper around the
 ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_
 ## C library. This means that your application will depend on the PRCE
diff --git a/lib/js/dom.nim b/lib/js/dom.nim
index 91b260a64..870213db3 100644
--- a/lib/js/dom.nim
+++ b/lib/js/dom.nim
@@ -55,6 +55,7 @@ type
     status*: cstring
     toolbar*: ref TToolBar
 
+    addEventListener*: proc(ev: cstring, cb: proc(ev: ref TEvent) ) {.nimcall.}
     alert*: proc (msg: cstring) {.nimcall.}
     back*: proc () {.nimcall.}
     blur*: proc () {.nimcall.}
@@ -91,6 +92,7 @@ type
   TFrame* {.importc.} = object of TWindow
 
   TDocument* {.importc.} = object of TEventHandlers
+    addEventListener*: proc(ev: cstring, cb: proc(ev: ref TEvent) ) {.nimcall.}
     alinkColor*: cstring
     bgColor*: cstring
     charset*: cstring
@@ -110,6 +112,7 @@ type
     getElementById*: proc (id: cstring): ref TNode {.nimcall.}
     getElementsByName*: proc (name: cstring): seq[ref TNode] {.nimcall.}
     getElementsByTagName*: proc (name: cstring): seq[ref TNode] {.nimcall.}
+    getElementsByClassName*: proc (name: cstring): seq[ref TNode] {.nimcall.}
     getSelection*: proc (): cstring {.nimcall.}
     handleEvent*: proc (event: ref TEvent) {.nimcall.}
     open*: proc () {.nimcall.}
@@ -196,6 +199,12 @@ type
     width*: int
     handleEvent*: proc (event: ref TEvent) {.nimcall.}
 
+  ClassList* {.importc.} = object of RootObj
+    add*: proc (class: cstring) {.nimcall.}
+    remove*: proc (class: cstring) {.nimcall.}
+    contains*: proc (class: cstring):bool {.nimcall.}
+    toggle*: proc (class: cstring) {.nimcall.}
+
   TNodeType* = enum
     ElementNode = 1,
     AttributeNode,
@@ -212,6 +221,8 @@ type
   TNode* {.importc.} = object of RootObj
     attributes*: seq[ref TNode]
     childNodes*: seq[ref TNode]
+    children*: seq[ref TNode]
+    classList*: ref Classlist
     data*: cstring
     firstChild*: ref TNode
     lastChild*: ref TNode
@@ -223,20 +234,23 @@ type
     previousSibling*: ref TNode
     appendChild*: proc (child: ref TNode) {.nimcall.}
     appendData*: proc (data: cstring) {.nimcall.}
-    cloneNode*: proc (copyContent: bool) {.nimcall.}
+    cloneNode*: proc (copyContent: bool): ref TNode {.nimcall.}
     deleteData*: proc (start, len: int) {.nimcall.}
     getAttribute*: proc (attr: cstring): cstring {.nimcall.}
     getAttributeNode*: proc (attr: cstring): ref TNode {.nimcall.}
-    getElementsByTagName*: proc (): seq[ref TNode] {.nimcall.}
+    getElementsByTagName*: proc (name: cstring): seq[ref TNode] {.nimcall.}
+    getElementsByClassName*: proc (name: cstring): seq[ref TNode] {.nimcall.}
     hasChildNodes*: proc (): bool {.nimcall.}
     innerHTML*: cstring
     insertBefore*: proc (newNode, before: ref TNode) {.nimcall.}
     insertData*: proc (position: int, data: cstring) {.nimcall.}
+    addEventListener*: proc(ev: cstring, cb: proc(ev: ref TEvent)) {.nimcall.}
     removeAttribute*: proc (attr: cstring) {.nimcall.}
     removeAttributeNode*: proc (attr: ref TNode) {.nimcall.}
     removeChild*: proc (child: ref TNode) {.nimcall.}
     replaceChild*: proc (newNode, oldNode: ref TNode) {.nimcall.}
     replaceData*: proc (start, len: int, text: cstring) {.nimcall.}
+    scrollIntoView*: proc () {.nimcall.}
     setAttribute*: proc (name, value: cstring) {.nimcall.}
     setAttributeNode*: proc (attr: ref TNode) {.nimcall.}
     style*: ref TStyle
@@ -336,6 +350,7 @@ type
     setAttribute*: proc (attr, value: cstring, caseSensitive=false) {.nimcall.}
 
   TEvent* {.importc.} = object of RootObj
+    target*: ref TNode
     altKey*, ctrlKey*, shiftKey*: bool
     button*: int
     clientX*, clientY*: int
@@ -450,3 +465,4 @@ proc isFinite*(x: BiggestFloat): bool {.importc, nodecl.}
 proc isNaN*(x: BiggestFloat): bool {.importc, nodecl.}
 proc parseFloat*(s: cstring): BiggestFloat {.importc, nodecl.}
 proc parseInt*(s: cstring): int {.importc, nodecl.}
+proc parseInt*(s: cstring, radix: int):int {.importc, nodecl.}
diff --git a/lib/nimbase.h b/lib/nimbase.h
index b72e60ac2..50c7968ac 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -379,7 +379,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
 #  define GC_GUARD
 #endif
 
-/* Test to see if nimrod and the C compiler agree on the size of a pointer.
+/* Test to see if Nim and the C compiler agree on the size of a pointer.
    On disagreement, your C compiler will say something like: 
    "error: 'assert_numbits' declared as an array with a negative size" */
 typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
@@ -390,3 +390,12 @@ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(
 #else
 #  define NIM_EXTERNC
 #endif
+
+/* ---------------- platform specific includes ----------------------- */
+
+/* VxWorks related includes */
+#if defined(__VXWORKS__)
+#  include <sys/types.h>
+#  include <types/vxWind.h>
+#  include <tool/gnu/toolMacros.h>
+#endif
diff --git a/lib/nimrtl.nimrod.cfg b/lib/nimrtl.nim.cfg
index b60de183a..b60de183a 100644
--- a/lib/nimrtl.nimrod.cfg
+++ b/lib/nimrtl.nim.cfg
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index 14614b2ed..e1e590877 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -1145,7 +1145,7 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string],
 proc defaultConfig*(): StringTableRef =
   ## Returns a default configuration for embedded HTML generation.
   ##
-  ## The returned ``StringTableRef`` contains the paramters used by the HTML
+  ## The returned ``StringTableRef`` contains the parameters used by the HTML
   ## engine to build the final output. For information on what these parameters
   ## are and their purpose, please look up the file ``config/nimdoc.cfg``
   ## bundled with the compiler.
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index fbd07ca25..7d3e3ddba 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -70,17 +70,20 @@ const
   STDIN_FILENO* = 0  ## File number of stdin;
   STDOUT_FILENO* = 1 ## File number of stdout;
 
-when defined(endb):
-  # to not break bootstrapping again ...
-  type
-    TDIR* {.importc: "DIR", header: "<dirent.h>",
-            final, pure, incompleteStruct.} = object
-      ## A type representing a directory stream.
-else:
-  type
-    TDIR* {.importc: "DIR", header: "<dirent.h>",
-            final, pure.} = object
-      ## A type representing a directory stream.
+  DT_UNKNOWN* = 0 ## Unknown file type.
+  DT_FIFO* = 1    ## Named pipe, or FIFO.
+  DT_CHR* = 2     ## Character device.
+  DT_DIR* = 4     ## Directory.
+  DT_BLK* = 6     ## Block device.
+  DT_REG* = 8     ## Regular file.
+  DT_LNK* = 10    ## Symbolic link.
+  DT_SOCK* = 12   ## UNIX domain socket.
+  DT_WHT* = 14
+
+type
+  TDIR* {.importc: "DIR", header: "<dirent.h>",
+          incompleteStruct.} = object
+    ## A type representing a directory stream.
 
 type
   SocketHandle* = distinct cint # The type used to represent socket descriptors
@@ -91,6 +94,10 @@ type
   Tdirent* {.importc: "struct dirent",
              header: "<dirent.h>", final, pure.} = object ## dirent_t struct
     d_ino*: Tino  ## File serial number.
+    d_off*: TOff  ## Not an offset. Value that ``telldir()`` would return.
+    d_reclen*: cshort ## Length of this record. (not POSIX)
+    d_type*: int8 ## Type of file; not supported by all filesystem types.
+                  ## (not POSIX)
     d_name*: array [0..255, char] ## Name of entry.
 
   Tflock* {.importc: "struct flock", final, pure,
@@ -1739,12 +1746,10 @@ when hasSpawnH:
   when defined(linux):
     # better be safe than sorry; Linux has this flag, macosx doesn't, don't
     # know about the other OSes
-    when defined(tcc):
-      # TCC doesn't define __USE_GNU, so we can't get the magic number from
-      # spawn.h
-      const POSIX_SPAWN_USEVFORK* = cint(0x40)
-    else:
-      var POSIX_SPAWN_USEVFORK* {.importc, header: "<spawn.h>".}: cint
+
+    # Non-GNU systems like TCC and musl-libc  don't define __USE_GNU, so we
+    # can't get the magic number from spawn.h
+    const POSIX_SPAWN_USEVFORK* = cint(0x40)
   else:
     # macosx lacks this, so we define the constant to be 0 to not affect
     # OR'ing of flags:
diff --git a/lib/posix/termios.nim b/lib/posix/termios.nim
new file mode 100644
index 000000000..830e8a207
--- /dev/null
+++ b/lib/posix/termios.nim
@@ -0,0 +1,264 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+{.deadCodeElim: on.}
+import posix
+
+type 
+  Speed* = cuint
+  Tcflag* = cuint
+
+const 
+  NCCS* = 32
+
+type 
+  Termios* = object {.importc: "struct termios", header: "<termios.h>", final, pure.}
+    iflag*: Tcflag        # input mode flags 
+    oflag*: Tcflag        # output mode flags 
+    cflag*: Tcflag        # control mode flags 
+    lflag*: Tcflag        # local mode flags 
+    line*: cuchar             # line discipline 
+    cc*: array[NCCS, cuchar]  # control characters 
+    ispeed*: Speed        # input speed 
+    ospeed*: Speed        # output speed 
+  
+
+# cc characters 
+
+const 
+  VINTR* = 0
+  VQUIT* = 1
+  VERASE* = 2
+  VKILL* = 3
+  VEOF* = 4
+  VTIME* = 5
+  VMIN* = 6
+  VSWTC* = 7
+  VSTART* = 8
+  VSTOP* = 9
+  VSUSP* = 10
+  VEOL* = 11
+  VREPRINT* = 12
+  VDISCARD* = 13
+  VWERASE* = 14
+  VLNEXT* = 15
+  VEOL2* = 16
+
+# iflag bits 
+
+const 
+  IGNBRK* = 1
+  BRKINT* = 2
+  IGNPAR* = 4
+  PARMRK* = 10
+  INPCK* = 20
+  ISTRIP* = 40
+  INLCR* = 100
+  IGNCR* = 200
+  ICRNL* = 400
+  IUCLC* = 1000
+  IXON* = 2000
+  IXANY* = 4000
+  IXOFF* = 10000
+  IMAXBEL* = 20000
+  IUTF8* = 40000
+
+# oflag bits 
+
+const 
+  OPOST* = 1
+  OLCUC* = 2
+  ONLCR* = 4
+  OCRNL* = 10
+  ONOCR* = 20
+  ONLRET* = 40
+  OFILL* = 100
+  OFDEL* = 200
+  NLDLY* = 400
+  NL0* = 0
+  NL1* = 400
+  CRDLY* = 3000
+  CR0* = 0
+  CR1* = 1000
+  CR2* = 2000
+  CR3* = 3000
+  TABDLY* = 14000
+  TAB0* = 0
+  TAB1* = 4000
+  TAB2* = 10000
+  TAB3* = 14000
+  BSDLY* = 20000
+  BS0* = 0
+  BS1* = 20000
+  FFDLY* = 0o000000100000
+  FF0* = 0
+  FF1* = 0o000000100000
+  VTDLY* = 40000
+  VT0* = 0
+  VT1* = 40000
+  XTABS* = 14000
+
+# cflag bit meaning 
+
+const 
+  CBAUD* = 10017
+  B0* = 0
+  B50* = 1
+  B75* = 2
+  B110* = 3
+  B134* = 4
+  B150* = 5
+  B200* = 6
+  B300* = 7
+  B600* = 10
+  B1200* = 11
+  B1800* = 12
+  B2400* = 13
+  B4800* = 14
+  B9600* = 15
+  B19200* = 16
+  B38400* = 17
+  EXTA* = B19200
+  EXTB* = B38400
+  CSIZE* = 60
+  CS5* = 0
+  CS6* = 20
+  CS7* = 40
+  CS8* = 60
+  CSTOPB* = 100
+  CREAD* = 200
+  PARENB* = 400
+  PARODD* = 1000
+  HUPCL* = 2000
+  CLOCAL* = 4000
+  CBAUDEX* = 10000
+  B57600* = 10001
+  B115200* = 10002
+  B230400* = 10003
+  B460800* = 10004
+  B500000* = 10005
+  B576000* = 10006
+  B921600* = 10007
+  B1000000* = 10010
+  B1152000* = 10011
+  B1500000* = 10012
+  B2000000* = 10013
+  B2500000* = 10014
+  B3000000* = 10015
+  B3500000* = 10016
+  B4000000* = 10017
+  MAX_BAUD* = B4000000
+  CIBAUD* = 2003600000
+  CMSPAR* = 0o010000000000
+  CRTSCTS* = 0o020000000000
+
+# lflag bits 
+
+const 
+  ISIG* = 1
+  ICANON* = 2
+  XCASE* = 4
+  ECHO* = 10
+  ECHOE* = 20
+  ECHOK* = 40
+  ECHONL* = 100
+  NOFLSH* = 200
+  TOSTOP* = 400
+  ECHOCTL* = 1000
+  ECHOPRT* = 2000
+  ECHOKE* = 4000
+  FLUSHO* = 10000
+  PENDIN* = 40000
+  IEXTEN* = 0o000000100000
+  EXTPROC* = 0o000000200000
+
+# tcflow() and TCXONC use these 
+
+const 
+  TCOOFF* = 0
+  TCOON* = 1
+  TCIOFF* = 2
+  TCION* = 3
+
+# tcflush() and TCFLSH use these 
+
+const 
+  TCIFLUSH* = 0
+  TCOFLUSH* = 1
+  TCIOFLUSH* = 2
+
+# tcsetattr uses these 
+
+const 
+  TCSANOW* = 0
+  TCSADRAIN* = 1
+  TCSAFLUSH* = 2
+
+# Compare a character C to a value VAL from the `cc' array in a
+#   `struct termios'.  If VAL is _POSIX_VDISABLE, no character can match it.  
+
+template cceq*(val, c: expr): expr = 
+  c == val and val != POSIX_VDISABLE
+
+# Return the output baud rate stored in *TERMIOS_P.  
+
+proc cfGetOspeed*(termios: ptr Termios): Speed {.importc: "cfgetospeed", 
+    header: "<termios.h>".}
+# Return the input baud rate stored in *TERMIOS_P.  
+
+proc cfGetIspeed*(termios: ptr Termios): Speed {.importc: "cfgetispeed", 
+    header: "<termios.h>".}
+# Set the output baud rate stored in *TERMIOS_P to SPEED.  
+
+proc cfSetOspeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetospeed", header: "<termios.h>".}
+# Set the input baud rate stored in *TERMIOS_P to SPEED.  
+
+proc cfSetIspeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetispeed", header: "<termios.h>".}
+# Set both the input and output baud rates in *TERMIOS_OP to SPEED.  
+
+proc cfSetSpeed*(termios: ptr Termios; speed: Speed): cint {.
+    importc: "cfsetspeed", header: "<termios.h>".}
+# Put the state of FD into *TERMIOS_P.  
+
+proc tcGetAttr*(fd: cint; termios: ptr Termios): cint {.
+    importc: "tcgetattr", header: "<termios.h>".}
+# Set the state of FD to *TERMIOS_P.
+#   Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.  
+
+proc tcSetAttr*(fd: cint; optional_actions: cint; termios: ptr Termios): cint {.
+    importc: "tcsetattr", header: "<termios.h>".}
+# Set *TERMIOS_P to indicate raw mode.  
+
+proc cfMakeRaw*(termios: ptr Termios) {.importc: "cfmakeraw", 
+    header: "<termios.h>".}
+# Send zero bits on FD.  
+
+proc tcSendBreak*(fd: cint; duration: cint): cint {.importc: "tcsendbreak", 
+    header: "<termios.h>".}
+# Wait for pending output to be written on FD.
+#
+#   This function is a cancellation point and therefore not marked with
+#  .  
+
+proc tcDrain*(fd: cint): cint {.importc: "tcdrain", header: "<termios.h>".}
+# Flush pending data on FD.
+#   Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.  
+
+proc tcFlush*(fd: cint; queue_selector: cint): cint {.importc: "tcflush", 
+    header: "<termios.h>".}
+# Suspend or restart transmission on FD.
+#   Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.  
+
+proc tcFlow*(fd: cint; action: cint): cint {.importc: "tcflow", 
+    header: "<termios.h>".}
+# Get process group ID for session leader for controlling terminal FD.  
+
+proc tcGetSid*(fd: cint): TPid {.importc: "tcgetsid", header: "<termios.h>".}
diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim
index f2c50ce4c..8c61ce7df 100644
--- a/lib/pure/actors.nim
+++ b/lib/pure/actors.nim
@@ -200,7 +200,7 @@ template schedule =
   if minIdx >= 0:
     p.actors[minIdx].i.send(t)
   else:
-    raise newException(EDeadThread, "cannot send message; thread died")
+    raise newException(DeadThreadError, "cannot send message; thread died")
 
 proc spawn*[TIn, TOut](p: var TActorPool[TIn, TOut], input: TIn,
                        action: proc (input: TIn): TOut {.thread.}
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 0358a9a81..20bfc5c7c 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -220,3 +220,62 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
     result.add(res)
     index = 0
     indexes[index] -=1
+
+proc nextPermutation*[T](x: var openarray[T]): bool {.discardable.} =
+  ## Calculates the next lexicographic permutation, directly modifying ``x``.
+  ## The result is whether a permutation happened, otherwise we have reached
+  ## the last-ordered permutation.
+  ##
+  ## .. code-block:: nim
+  ##
+  ##     var v = @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+  ##     v.nextPermutation()
+  ##     echo v
+  if x.len < 2:
+    return false
+
+  var i = x.high
+  while i > 0 and x[i-1] >= x[i]:
+    dec i
+
+  if i == 0:
+    return false
+
+  var j = x.high
+  while j >= i and x[j] <= x[i-1]:
+    dec j
+
+  swap x[j], x[i-1]
+  x.reverse(i, x.high)
+
+  result = true
+
+proc prevPermutation*[T](x: var openarray[T]): bool {.discardable.} =
+  ## Calculates the previous lexicographic permutation, directly modifying
+  ## ``x``.  The result is whether a permutation happened, otherwise we have
+  ## reached the first-ordered permutation.
+  ##
+  ## .. code-block:: nim
+  ##
+  ##     var v = @[0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
+  ##     v.prevPermutation()
+  ##     echo v
+  if x.len < 2:
+    return false
+
+  var i = x.high
+  while i > 0 and x[i-1] <= x[i]:
+    dec i
+
+  if i == 0:
+    return false
+
+  x.reverse(i, x.high)
+
+  var j = x.high
+  while j >= i and x[j-1] < x[i-1]:
+    dec j
+
+  swap x[i-1], x[j]
+
+  result = true
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index bbd8ed895..d6ed66030 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -606,7 +606,7 @@ when defined(windows) or defined(nimdoc):
           retFuture.fail(newException(OSError, osErrorMsg(err)))
     elif ret == 0 and bytesReceived == 0 and dataBuf.buf[0] == '\0':
       # We have to ensure that the buffer is empty because WSARecv will tell
-      # us immediatelly when it was disconnected, even when there is still
+      # us immediately when it was disconnected, even when there is still
       # data in the buffer.
       # We want to give the user as much data as we can. So we only return
       # the empty string (which signals a disconnection) when there is
@@ -1064,6 +1064,17 @@ proc accept*(socket: TAsyncFD,
 
 # -- Await Macro
 
+proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
+  # Skips a nest of StmtList's.
+  result = node
+  if node[0].kind == nnkStmtList:
+    result = skipUntilStmtList(node[0])
+
+proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
+  result = node
+  if node[0].kind == nnkStmtList:
+    result = node[0]
+
 template createCb(retFutureSym, iteratorNameSym,
                    name: expr): stmt {.immediate.} =
   var nameIterVar = iteratorNameSym
@@ -1211,26 +1222,53 @@ proc processBody(node, retFutureSym: PNimrodNode,
   of nnkTryStmt:
     # try: await x; except: ...
     result = newNimNode(nnkStmtList, node)
+    template wrapInTry(n, tryBody: PNimrodNode) =
+      var temp = n
+      n[0] = tryBody
+      tryBody = temp
+
+      # Transform ``except`` body.
+      # TODO: Could we perform some ``await`` transformation here to get it
+      # working in ``except``?
+      tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
+
     proc processForTry(n: PNimrodNode, i: var int,
                        res: PNimrodNode): bool {.compileTime.} =
+      ## Transforms the body of the tryStmt. Does not transform the
+      ## body in ``except``.
+      ## Returns true if the tryStmt node was transformed into an ifStmt.
       result = false
-      while i < n[0].len:
-        var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n)
-        if processed.kind != n[0][i].kind or processed.len != n[0][i].len:
+      var skipped = n.skipStmtList()
+      while i < skipped.len:
+        var processed = processBody(skipped[i], retFutureSym,
+                                    subTypeIsVoid, n)
+
+        # Check if we transformed the node into an exception check.
+        # This suggests skipped[i] contains ``await``.
+        if processed.kind != skipped[i].kind or processed.len != skipped[i].len:
+          processed = processed.skipUntilStmtList()
           expectKind(processed, nnkStmtList)
           expectKind(processed[2][1], nnkElse)
           i.inc
-          discard processForTry(n, i, processed[2][1][0])
+
+          if not processForTry(n, i, processed[2][1][0]):
+            # We need to wrap the nnkElse nodes back into a tryStmt.
+            # As they are executed if an exception does not happen
+            # inside the awaited future.
+            # The following code will wrap the nodes inside the
+            # original tryStmt.
+            wrapInTry(n, processed[2][1][0])
+
           res.add processed
           result = true
         else:
-          res.add n[0][i]
+          res.add skipped[i]
           i.inc
     var i = 0
     if not processForTry(node, i, result):
-      var temp = node
-      temp[0] = result
-      result = temp
+      # If the tryStmt hasn't been transformed we can just put the body
+      # back into it.
+      wrapInTry(node, result)
     return
   else: discard
 
@@ -1329,8 +1367,8 @@ macro async*(prc: stmt): stmt {.immediate.} =
   result[6] = outerProcBody
 
   #echo(treeRepr(result))
-  #if prc[0].getName == "catch":
-  #  echo(toStrLit(result))
+  if prc[0].getName == "test3":
+    echo(toStrLit(result))
 
 proc recvLine*(socket: TAsyncFD): Future[string] {.async.} =
   ## Reads a line of data from ``socket``. Returned future will complete once
diff --git a/lib/pure/asyncdispatch.nimrod.cfg b/lib/pure/asyncdispatch.nim.cfg
index e88f8eec3..e88f8eec3 100644
--- a/lib/pure/asyncdispatch.nimrod.cfg
+++ b/lib/pure/asyncdispatch.nim.cfg
diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim
index f75b6fc43..752c01eac 100644
--- a/lib/pure/asyncfile.nim
+++ b/lib/pure/asyncfile.nim
@@ -35,7 +35,7 @@ type
     offset: int64
 
 when defined(windows):
-  proc getDesiredAccess(mode: TFileMode): int32 =
+  proc getDesiredAccess(mode: FileMode): int32 =
     case mode
     of fmRead:
       result = GENERIC_READ
@@ -44,7 +44,7 @@ when defined(windows):
     of fmReadWrite, fmReadWriteExisting:
       result = GENERIC_READ or GENERIC_WRITE
 
-  proc getCreationDisposition(mode: TFileMode, filename: string): int32 =
+  proc getCreationDisposition(mode: FileMode, filename: string): int32 =
     case mode
     of fmRead, fmReadWriteExisting:
       OPEN_EXISTING
@@ -54,7 +54,7 @@ when defined(windows):
       else:
         CREATE_NEW
 else:
-  proc getPosixFlags(mode: TFileMode): cint =
+  proc getPosixFlags(mode: FileMode): cint =
     case mode
     of fmRead:
       result = O_RDONLY
@@ -74,7 +74,7 @@ proc getFileSize(f: AsyncFile): int64 =
     var high: DWord
     let low = getFileSize(f.fd.THandle, addr high)
     if low == INVALID_FILE_SIZE:
-      raiseOSError()
+      raiseOSError(osLastError())
     return (high shl 32) or low
 
 proc openAsync*(filename: string, mode = fmRead): AsyncFile =
@@ -95,7 +95,7 @@ proc openAsync*(filename: string, mode = fmRead): AsyncFile =
           nil, creationDisposition, flags, 0).TAsyncFd
 
     if result.fd.THandle == INVALID_HANDLE_VALUE:
-      raiseOSError()
+      raiseOSError(osLastError())
 
     register(result.fd)
 
@@ -108,7 +108,7 @@ proc openAsync*(filename: string, mode = fmRead): AsyncFile =
     let perm = S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH
     result.fd = open(filename, flags, perm).TAsyncFD
     if result.fd.cint == -1:
-      raiseOSError()
+      raiseOSError(osLastError())
 
     register(result.fd)
 
@@ -185,7 +185,7 @@ proc read*(f: AsyncFile, size: int): Future[string] =
       if res < 0:
         let lastError = osLastError()
         if lastError.int32 != EAGAIN:
-          retFuture.fail(newException(EOS, osErrorMsg(lastError)))
+          retFuture.fail(newException(OSError, osErrorMsg(lastError)))
         else:
           result = false # We still want this callback to be called.
       elif res == 0:
@@ -227,7 +227,7 @@ proc setFilePos*(f: AsyncFile, pos: int64) =
   when not defined(windows):
     let ret = lseek(f.fd.cint, pos, SEEK_SET)
     if ret == -1:
-      raiseOSError()
+      raiseOSError(osLastError())
 
 proc readAll*(f: AsyncFile): Future[string] {.async.} =
   ## Reads all data from the specified file.
@@ -299,7 +299,7 @@ proc write*(f: AsyncFile, data: string): Future[void] =
       if res < 0:
         let lastError = osLastError()
         if lastError.int32 != EAGAIN:
-          retFuture.fail(newException(EOS, osErrorMsg(lastError)))
+          retFuture.fail(newException(OSError, osErrorMsg(lastError)))
         else:
           result = false # We still want this callback to be called.
       else:
@@ -318,8 +318,8 @@ proc close*(f: AsyncFile) =
   ## Closes the file specified.
   when defined(windows):
     if not closeHandle(f.fd.THandle).bool:
-      raiseOSError()
+      raiseOSError(osLastError())
   else:
     if close(f.fd.cint) == -1:
-      raiseOSError()
+      raiseOSError(osLastError())
 
diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim
index 48a6c59b9..8558ad10d 100644
--- a/lib/pure/asyncftpclient.nim
+++ b/lib/pure/asyncftpclient.nim
@@ -149,7 +149,7 @@ proc createDir*(ftp: AsyncFtpClient, dir: string, recursive = false){.async.} =
     assertReply reply, "257"
 
 proc chmod*(ftp: AsyncFtpClient, path: string,
-            permissions: set[TFilePermission]) {.async.} =
+            permissions: set[FilePermission]) {.async.} =
   ## Changes permission of ``path`` to ``permissions``.
   var userOctal = 0
   var groupOctal = 0
@@ -188,7 +188,7 @@ proc retrText*(ftp: AsyncFtpClient, file: string): Future[string] {.async.} =
 
   result = await ftp.getLines()
 
-proc getFile(ftp: AsyncFtpClient, file: TFile, total: BiggestInt,
+proc getFile(ftp: AsyncFtpClient, file: File, total: BiggestInt,
              onProgressChanged: ProgressChangedProc) {.async.} =
   assert ftp.dsockConnected
   var progress = 0
@@ -240,7 +240,7 @@ proc retrFile*(ftp: AsyncFtpClient, file, dest: string,
 
   await getFile(ftp, destFile, fileSize, onProgressChanged)
 
-proc doUpload(ftp: AsyncFtpClient, file: TFile,
+proc doUpload(ftp: AsyncFtpClient, file: File,
               onProgressChanged: ProgressChangedProc) {.async.} =
   assert ftp.dsockConnected
 
diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim
index d40c3849e..6a7cbe396 100644
--- a/lib/pure/asyncio.nim
+++ b/lib/pure/asyncio.nim
@@ -675,7 +675,7 @@ when isMainModule:
     echo(data)
     echo("Finished reading! " & $no)
 
-  proc testAccept(s: AsyncSocket, disp: PDispatcher, no: int) =
+  proc testAccept(s: AsyncSocket, disp: Dispatcher, no: int) =
     echo("Accepting client! " & $no)
     var client: AsyncSocket
     new(client)
@@ -691,7 +691,7 @@ when isMainModule:
     var d = newDispatcher()
     
     var s = asyncSocket()
-    s.connect("amber.tenthbit.net", TPort(6667))
+    s.connect("amber.tenthbit.net", Port(6667))
     s.handleConnect = 
       proc (s: AsyncSocket) =
         testConnect(s, 1)
@@ -704,7 +704,7 @@ when isMainModule:
     server.handleAccept =
       proc (s: AsyncSocket) = 
         testAccept(s, d, 78)
-    server.bindAddr(TPort(5555))
+    server.bindAddr(Port(5555))
     server.listen()
     d.register(server)
     
diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim
index f2fc1566b..a344cd053 100644
--- a/lib/pure/basic2d.nim
+++ b/lib/pure/basic2d.nim
@@ -18,7 +18,7 @@ import strutils
 ##
 ## Quick start example:
 ##   
-##   # Create a matrix wich first rotates, then scales and at last translates
+##   # Create a matrix which first rotates, then scales and at last translates
 ##   
 ##   var m:TMatrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0)
 ##   
@@ -256,7 +256,7 @@ proc `$`* (t:TMatrix2d):string {.noInit.} =
 
 proc isUniform*(t:TMatrix2d,tol=1.0e-6):bool=
   ## Checks if the transform is uniform, that is 
-  ## perpendicular axes of equal lenght, which means (for example)
+  ## perpendicular axes of equal length, which means (for example)
   ## it cannot transform a circle into an ellipse.
   ## `tol` is used as tolerance for both equal length comparison 
   ## and perp. comparison.
@@ -305,7 +305,7 @@ proc equals*(m1:TMatrix2d,m2:TMatrix2d,tol=1.0e-6):bool=
     abs(m1.ty-m2.ty)<=tol
     
 proc `=~`*(m1,m2:TMatrix2d):bool=
-  ## Checks if `m1`and `m2` is aproximately equal, using a
+  ## Checks if `m1`and `m2` is approximately equal, using a
   ## tolerance of 1e-6.
   equals(m1,m2)
 
diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim
index c00764fc5..18ebed67b 100644
--- a/lib/pure/basic3d.nim
+++ b/lib/pure/basic3d.nim
@@ -23,7 +23,7 @@ import times
 ##
 ## Quick start example:
 ##   
-##   # Create a matrix wich first rotates, then scales and at last translates
+##   # Create a matrix which first rotates, then scales and at last translates
 ##   
 ##   var m:TMatrix3d=rotate(PI,vector3d(1,1,2.5)) & scale(2.0) & move(100.0,200.0,300.0)
 ##   
@@ -320,7 +320,7 @@ proc rotateZ*(angle:float):TMatrix3d {.noInit.}=
     
 proc isUniform*(m:TMatrix3d,tol=1.0e-6):bool=
   ## Checks if the transform is uniform, that is 
-  ## perpendicular axes of equal lenght, which means (for example)
+  ## perpendicular axes of equal length, which means (for example)
   ## it cannot transform a sphere into an ellipsoid.
   ## `tol` is used as tolerance for both equal length comparison 
   ## and perpendicular comparison.
@@ -483,7 +483,7 @@ proc equals*(m1:TMatrix3d,m2:TMatrix3d,tol=1.0e-6):bool=
     abs(m1.tw-m2.tw)<=tol
 
 proc `=~`*(m1,m2:TMatrix3d):bool=
-  ## Checks if `m1` and `m2` is aproximately equal, using a
+  ## Checks if `m1` and `m2` is approximately equal, using a
   ## tolerance of 1e-6.
   equals(m1,m2)
   
@@ -788,7 +788,7 @@ proc angleTo*(v1,v2:TVector3d):float=
 proc arbitraryAxis*(norm:TVector3d):TMatrix3d {.noInit.}=
   ## Computes the rotation matrix that would transform
   ## world z vector into `norm`. The inverse of this matrix
-  ## is useful to tranform a planar 3d object to 2d space.
+  ## is useful to transform a planar 3d object to 2d space.
   ## This is the same algorithm used to interpret DXF and DWG files.
   const lim=1.0/64.0
   var ax,ay,az:TVector3d
@@ -812,7 +812,7 @@ proc bisect*(v1,v2:TVector3d):TVector3d {.noInit.}=
   ## Computes the bisector between v1 and v2 as a normalized vector.
   ## If one of the input vectors has zero length, a normalized version
   ## of the other is returned. If both input vectors has zero length, 
-  ## an arbitrary normalized vector `v1`is returned.
+  ## an arbitrary normalized vector `v1` is returned.
   var
     vmag1=v1.len
     vmag2=v2.len
diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim
index 52035ee48..c6a603318 100644
--- a/lib/pure/browsers.nim
+++ b/lib/pure/browsers.nim
@@ -42,7 +42,7 @@ proc openDefaultBrowser*(url: string) =
     for b in getEnv("BROWSER").string.split(PathSep):
       try:
         # we use ``startProcess`` here because we don't want to block!
-        discard startProcess(command=b, args=[url], options={poUseShell})
+        discard startProcess(command=b, args=[url], options={poUsePath})
         return
       except OSError:
         discard
diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim
index 5640838b1..c3954468a 100644
--- a/lib/pure/collections/LockFreeHash.nim
+++ b/lib/pure/collections/LockFreeHash.nim
@@ -404,7 +404,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
     #echo("tomb old slot then set in new table") 
     nextTable = copySlotAndCheck(table,idx)
     return setVal(nextTable, key, val, expVal, match)
-  # Finaly ready to add new val to table
+  # Finally ready to add new val to table
   while true:
     if match and oldVal != expVal:
       #echo("set failed, no match  oldVal= " & $oldVal & " expVal= " & $expVal)
diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim
index 06babc6bb..3d10e39aa 100644
--- a/lib/pure/collections/critbits.nim
+++ b/lib/pure/collections/critbits.nim
@@ -174,7 +174,7 @@ proc excl*[T](c: var CritBitTree[T], key: string) =
 iterator leaves[T](n: Node[T]): Node[T] =
   if n != nil:
     # XXX actually we could compute the necessary stack size in advance:
-    # it's rougly log2(c.count).
+    # it's roughly log2(c.count).
     var stack = @[n]
     while stack.len > 0: 
       var it = stack.pop
diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim
index b46e040ca..7520e6e46 100644
--- a/lib/pure/collections/intsets.nim
+++ b/lib/pure/collections/intsets.nim
@@ -191,9 +191,10 @@ proc `$`*(s: IntSet): string =
   ## The `$` operator for int sets.
   dollarImpl()
 
-proc empty*(s: IntSet): bool {.inline.} =
+proc empty*(s: IntSet): bool {.inline, deprecated.} =
   ## returns true if `s` is empty. This is safe to call even before
-  ## the set has been initialized with `initIntSet`.
+  ## the set has been initialized with `initIntSet`. Note this never
+  ## worked reliably and so is deprecated.
   result = s.counter == 0
 
 when isMainModule:
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index befc9bacb..e690e8eba 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -320,7 +320,7 @@ template foldl*(sequence, operation: expr): expr =
   ##
   ## The ``operation`` parameter should be an expression which uses the
   ## variables ``a`` and ``b`` for each step of the fold. Since this is a left
-  ## fold, for non associative binary operations like substraction think that
+  ## fold, for non associative binary operations like subtraction think that
   ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) -
   ## 3).  Example:
   ##
@@ -328,12 +328,12 @@ template foldl*(sequence, operation: expr): expr =
   ##   let
   ##     numbers = @[5, 9, 11]
   ##     addition = foldl(numbers, a + b)
-  ##     substraction = foldl(numbers, a - b)
+  ##     subtraction = foldl(numbers, a - b)
   ##     multiplication = foldl(numbers, a * b)
   ##     words = @["nim", "is", "cool"]
   ##     concatenation = foldl(words, a & b)
   ##   assert addition == 25, "Addition is (((5)+9)+11)"
-  ##   assert substraction == -15, "Substraction is (((5)-9)-11)"
+  ##   assert subtraction == -15, "Subtraction is (((5)-9)-11)"
   ##   assert multiplication == 495, "Multiplication is (((5)*9)*11)"
   ##   assert concatenation == "nimiscool"
   assert sequence.len > 0, "Can't fold empty sequences"
@@ -356,7 +356,7 @@ template foldr*(sequence, operation: expr): expr =
   ##
   ## The ``operation`` parameter should be an expression which uses the
   ## variables ``a`` and ``b`` for each step of the fold. Since this is a right
-  ## fold, for non associative binary operations like substraction think that
+  ## fold, for non associative binary operations like subtraction think that
   ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 -
   ## (3))). Example:
   ##
@@ -364,12 +364,12 @@ template foldr*(sequence, operation: expr): expr =
   ##   let
   ##     numbers = @[5, 9, 11]
   ##     addition = foldr(numbers, a + b)
-  ##     substraction = foldr(numbers, a - b)
+  ##     subtraction = foldr(numbers, a - b)
   ##     multiplication = foldr(numbers, a * b)
   ##     words = @["nim", "is", "cool"]
   ##     concatenation = foldr(words, a & b)
   ##   assert addition == 25, "Addition is (5+(9+(11)))"
-  ##   assert substraction == 7, "Substraction is (5-(9-(11)))"
+  ##   assert subtraction == 7, "Subtraction is (5-(9-(11)))"
   ##   assert multiplication == 495, "Multiplication is (5*(9*(11)))"
   ##   assert concatenation == "nimiscool"
   assert sequence.len > 0, "Can't fold empty sequences"
@@ -382,7 +382,7 @@ template foldr*(sequence, operation: expr): expr =
     result = operation
   result
 
-template mapIt*(seq1, typ, pred: expr): expr =
+template mapIt*(seq1, typ, op: expr): expr =
   ## Convenience template around the ``map`` proc to reduce typing.
   ##
   ## The template injects the ``it`` variable which you can use directly in an
@@ -397,10 +397,10 @@ template mapIt*(seq1, typ, pred: expr): expr =
   ##   assert strings == @["4", "8", "12", "16"]
   var result {.gensym.}: seq[typ] = @[]
   for it {.inject.} in items(seq1):
-    result.add(pred)
+    result.add(op)
   result
 
-template mapIt*(varSeq, pred: expr) =
+template mapIt*(varSeq, op: expr) =
   ## Convenience template around the mutable ``map`` proc to reduce typing.
   ##
   ## The template injects the ``it`` variable which you can use directly in an
@@ -413,7 +413,7 @@ template mapIt*(varSeq, pred: expr) =
   ##   assert nums[0] + nums[3] == 15
   for i in 0 .. <len(varSeq):
     let it {.inject.} = varSeq[i]
-    varSeq[i] = pred
+    varSeq[i] = op
 
 template newSeqWith*(len: int, init: expr): expr =
   ## creates a new sequence, calling `init` to initialize each value. Example:
@@ -507,12 +507,12 @@ when isMainModule:
     let
       numbers = @[5, 9, 11]
       addition = foldl(numbers, a + b)
-      substraction = foldl(numbers, a - b)
+      subtraction = foldl(numbers, a - b)
       multiplication = foldl(numbers, a * b)
       words = @["nim", "is", "cool"]
       concatenation = foldl(words, a & b)
     assert addition == 25, "Addition is (((5)+9)+11)"
-    assert substraction == -15, "Substraction is (((5)-9)-11)"
+    assert subtraction == -15, "Subtraction is (((5)-9)-11)"
     assert multiplication == 495, "Multiplication is (((5)*9)*11)"
     assert concatenation == "nimiscool"
 
@@ -520,12 +520,12 @@ when isMainModule:
     let
       numbers = @[5, 9, 11]
       addition = foldr(numbers, a + b)
-      substraction = foldr(numbers, a - b)
+      subtraction = foldr(numbers, a - b)
       multiplication = foldr(numbers, a * b)
       words = @["nim", "is", "cool"]
       concatenation = foldr(words, a & b)
     assert addition == 25, "Addition is (5+(9+(11)))"
-    assert substraction == 7, "Substraction is (5-(9-(11)))"
+    assert subtraction == 7, "Subtraction is (5-(9-(11)))"
     assert multiplication == 495, "Multiplication is (5*(9*(11)))"
     assert concatenation == "nimiscool"
 
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 4cc46149e..4a20d00a4 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -24,9 +24,12 @@ import
 when not defined(nimhygiene):
   {.pragma: dirty.}
 
+# For "integer-like A" that are too big for intsets/bit-vectors to be practical,
+# it would be best to shrink hcode to the same size as the integer.  Larger
+# codes should never be needed, and this can pack more entries per cache-line.
+# Losing hcode entirely is also possible - if some element value is forbidden.
 type
-  SlotEnum = enum seEmpty, seFilled, seDeleted
-  KeyValuePair[A] = tuple[slot: SlotEnum, key: A]
+  KeyValuePair[A] = tuple[hcode: THash, key: A]
   KeyValuePairSeq[A] = seq[KeyValuePair[A]]
   HashSet* {.myShallow.}[A] = object ## \
     ## A generic hash set.
@@ -38,6 +41,14 @@ type
 
 {.deprecated: [TSet: HashSet].}
 
+# hcode for real keys cannot be zero.  hcode==0 signifies an empty slot.  These
+# two procs retain clarity of that encoding without the space cost of an enum.
+proc isEmpty(hcode: THash): bool {.inline.} =
+  result = hcode == 0
+
+proc isFilled(hcode: THash): bool {.inline.} =
+  result = hcode != 0
+
 proc isValid*[A](s: HashSet[A]): bool =
   ## Returns `true` if the set has been initialized with `initSet <#initSet>`_.
   ##
@@ -94,7 +105,7 @@ iterator items*[A](s: HashSet[A]): A =
   ##   # --> {(a: 1, b: 3), (a: 0, b: 4)}
   assert s.isValid, "The set needs to be initialized."
   for h in 0..high(s.data):
-    if s.data[h].slot == seFilled: yield s.data[h].key
+    if isFilled(s.data[h].hcode): yield s.data[h].key
 
 const
   growthFactor = 2
@@ -103,25 +114,44 @@ proc mustRehash(length, counter: int): bool {.inline.} =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
-proc nextTry(h, maxHash: THash): THash {.inline.} =
-  result = ((5 * h) + 1) and maxHash
+proc rightSize*(count: int): int {.inline.} =
+  ## Return the value of `initialSize` to support `count` items.
+  ##
+  ## If more items are expected to be added, simply add that
+  ## expected extra amount to the parameter before calling this.
+  ##
+  ## Internally, we want mustRehash(rightSize(x), x) == false.
+  result = nextPowerOfTwo(count * 3 div 2  +  4)
 
-template rawGetImpl() {.dirty.} =
-  var h: THash = hash(key) and high(s.data) # start with real hash value
-  while s.data[h].slot != seEmpty:
-    if s.data[h].key == key and s.data[h].slot == seFilled:
+proc nextTry(h, maxHash: THash): THash {.inline.} =
+  result = (h + 1) and maxHash
+
+template rawGetKnownHCImpl() {.dirty.} =
+  var h: THash = hc and high(s.data)  # start with real hash value
+  while isFilled(s.data[h].hcode):
+    # Compare hc THEN key with boolean short circuit. This makes the common case
+    # zero ==key's for missing (e.g.inserts) and exactly one ==key for present.
+    # It does slow down succeeding lookups by one extra THash cmp&and..usually
+    # just a few clock cycles, generally worth it for any non-integer-like A.
+    if s.data[h].hcode == hc and s.data[h].key == key:  # compare hc THEN key
       return h
     h = nextTry(h, high(s.data))
-  result = -1
+  result = -1 - h                   # < 0 => MISSING; insert idx = -1 - result
+
+template rawGetImpl() {.dirty.} =
+  hc = hash(key)
+  if hc == 0:       # This almost never taken branch should be very predictable.
+    hc = 314159265  # Value doesn't matter; Any non-zero favorite is fine.
+  rawGetKnownHCImpl()
 
 template rawInsertImpl() {.dirty.} =
-  var h: THash = hash(key) and high(data)
-  while data[h].slot == seFilled:
-    h = nextTry(h, high(data))
   data[h].key = key
-  data[h].slot = seFilled
+  data[h].hcode = hc
+
+proc rawGetKnownHC[A](s: HashSet[A], key: A, hc: THash): int {.inline.} =
+  rawGetKnownHCImpl()
 
-proc rawGet[A](s: HashSet[A], key: A): int =
+proc rawGet[A](s: HashSet[A], key: A, hc: var THash): int {.inline.} =
   rawGetImpl()
 
 proc mget*[A](s: var HashSet[A], key: A): var A =
@@ -130,7 +160,8 @@ proc mget*[A](s: var HashSet[A], key: A): var A =
   ## when one overloaded 'hash' and '==' but still needs reference semantics
   ## for sharing.
   assert s.isValid, "The set needs to be initialized."
-  var index = rawGet(s, key)
+  var hc: THash
+  var index = rawGet(s, key, hc)
   if index >= 0: result = s.data[index].key
   else: raise newException(KeyError, "key not found: " & $key)
 
@@ -147,33 +178,43 @@ proc contains*[A](s: HashSet[A], key: A): bool =
   ##   values.excl(2)
   ##   assert(not values.contains(2))
   assert s.isValid, "The set needs to be initialized."
-  var index = rawGet(s, key)
+  var hc: THash
+  var index = rawGet(s, key, hc)
   result = index >= 0
 
-proc rawInsert[A](s: var HashSet[A], data: var KeyValuePairSeq[A], key: A) =
+proc rawInsert[A](s: var HashSet[A], data: var KeyValuePairSeq[A], key: A,
+                  hc: THash, h: THash) =
   rawInsertImpl()
 
 proc enlarge[A](s: var HashSet[A]) =
   var n: KeyValuePairSeq[A]
   newSeq(n, len(s.data) * growthFactor)
-  for i in countup(0, high(s.data)):
-    if s.data[i].slot == seFilled: rawInsert(s, n, s.data[i].key)
-  swap(s.data, n)
+  swap(s.data, n)                   # n is now old seq
+  for i in countup(0, high(n)):
+    if isFilled(n[i].hcode):
+      var j = -1 - rawGetKnownHC(s, n[i].key, n[i].hcode)
+      rawInsert(s, s.data, n[i].key, n[i].hcode, j)
 
 template inclImpl() {.dirty.} =
-  var index = rawGet(s, key)
+  var hc: THash
+  var index = rawGet(s, key, hc)
   if index < 0:
-    if mustRehash(len(s.data), s.counter): enlarge(s)
-    rawInsert(s, s.data, key)
+    if mustRehash(len(s.data), s.counter):
+      enlarge(s)
+      index = rawGetKnownHC(s, key, hc)
+    rawInsert(s, s.data, key, hc, -1 - index)
     inc(s.counter)
 
 template containsOrInclImpl() {.dirty.} =
-  var index = rawGet(s, key)
+  var hc: THash
+  var index = rawGet(s, key, hc)
   if index >= 0:
     result = true
   else:
-    if mustRehash(len(s.data), s.counter): enlarge(s)
-    rawInsert(s, s.data, key)
+    if mustRehash(len(s.data), s.counter):
+      enlarge(s)
+      index = rawGetKnownHC(s, key, hc)
+    rawInsert(s, s.data, key, hc, -1 - index)
     inc(s.counter)
 
 proc incl*[A](s: var HashSet[A], key: A) =
@@ -204,6 +245,11 @@ proc incl*[A](s: var HashSet[A], other: HashSet[A]) =
   assert other.isValid, "The set `other` needs to be initialized."
   for item in other: incl(s, item)
 
+template doWhile(a: expr, b: stmt): stmt =
+  while true:
+    b
+    if not a: break
+
 proc excl*[A](s: var HashSet[A], key: A) =
   ## Excludes `key` from the set `s`.
   ##
@@ -215,10 +261,22 @@ proc excl*[A](s: var HashSet[A], key: A) =
   ##   s.excl(2)
   ##   assert s.len == 3
   assert s.isValid, "The set needs to be initialized."
-  var index = rawGet(s, key)
-  if index >= 0:
-    s.data[index].slot = seDeleted
+  var hc: THash
+  var i = rawGet(s, key, hc)
+  var msk = high(s.data)
+  if i >= 0:
+    s.data[i].hcode = 0
     dec(s.counter)
+    while true:         # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
+      var j = i         # The correctness of this depends on (h+1) in nextTry,
+      var r = j         # though may be adaptable to other simple sequences.
+      s.data[i].hcode = 0              # mark current EMPTY
+      doWhile ((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)):
+        i = (i + 1) and msk            # increment mod table size
+        if isEmpty(s.data[i].hcode):   # end of collision cluster; So all done
+          return
+        r = s.data[i].hcode and msk    # "home" location of key@i
+      shallowCopy(s.data[j], s.data[i]) # data[j] will be marked EMPTY next loop
 
 proc excl*[A](s: var HashSet[A], other: HashSet[A]) =
   ## Excludes everything in `other` from `s`.
@@ -255,9 +313,9 @@ proc init*[A](s: var HashSet[A], initialSize=64) =
   ## Initializes a hash set.
   ##
   ## The `initialSize` parameter needs to be a power of two. You can use
-  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ to guarantee that at
-  ## runtime. All set variables have to be initialized before you can use them
-  ## with other procs from this module with the exception of `isValid()
+  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ or `rightSize` to
+  ## guarantee that at runtime. All set variables must be initialized before
+  ## use with other procs from this module with the exception of `isValid()
   ## <#isValid,TSet[A]>`_ and `len() <#len,TSet[A]>`_.
   ##
   ## You can call this proc on a previously initialized hash set, which will
@@ -295,7 +353,7 @@ proc toSet*[A](keys: openArray[A]): HashSet[A] =
   ##   var numbers = toSet([1, 2, 3, 4, 5])
   ##   assert numbers.contains(2)
   ##   assert numbers.contains(4)
-  result = initSet[A](nextPowerOfTwo(keys.len+10))
+  result = initSet[A](rightSize(keys.len))
   for key in items(keys): result.incl(key)
 
 template dollarImpl(): stmt {.dirty.} =
@@ -494,7 +552,7 @@ proc map*[A, B](data: HashSet[A], op: proc (x: A): B {.closure.}): HashSet[B] =
 
 type
   OrderedKeyValuePair[A] = tuple[
-    slot: SlotEnum, next: int, key: A]
+    hcode: THash, next: int, key: A]
   OrderedKeyValuePairSeq[A] = seq[OrderedKeyValuePair[A]]
   OrderedSet* {.myShallow.}[A] = object ## \
     ## A generic hash set that remembers insertion order.
@@ -546,7 +604,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
   var h = s.first
   while h >= 0:
     var nxt = s.data[h].next
-    if s.data[h].slot == seFilled: yieldStmt
+    if isFilled(s.data[h].hcode): yieldStmt
     h = nxt
 
 iterator items*[A](s: OrderedSet[A]): A =
@@ -571,7 +629,10 @@ iterator items*[A](s: OrderedSet[A]): A =
   forAllOrderedPairs:
     yield s.data[h].key
 
-proc rawGet[A](s: OrderedSet[A], key: A): int =
+proc rawGetKnownHC[A](s: OrderedSet[A], key: A, hc: THash): int {.inline.} =
+  rawGetKnownHCImpl()
+
+proc rawGet[A](s: OrderedSet[A], key: A, hc: var THash): int {.inline.} =
   rawGetImpl()
 
 proc contains*[A](s: OrderedSet[A], key: A): bool =
@@ -585,11 +646,12 @@ proc contains*[A](s: OrderedSet[A], key: A): bool =
   ##   values.incl(2)
   ##   assert values.contains(2)
   assert s.isValid, "The set needs to be initialized."
-  var index = rawGet(s, key)
+  var hc: THash
+  var index = rawGet(s, key, hc)
   result = index >= 0
 
-proc rawInsert[A](s: var OrderedSet[A], 
-                  data: var OrderedKeyValuePairSeq[A], key: A) =
+proc rawInsert[A](s: var OrderedSet[A], data: var OrderedKeyValuePairSeq[A],
+                  key: A, hc: THash, h: THash) =
   rawInsertImpl()
   data[h].next = -1
   if s.first < 0: s.first = h
@@ -602,12 +664,13 @@ proc enlarge[A](s: var OrderedSet[A]) =
   var h = s.first
   s.first = -1
   s.last = -1
+  swap(s.data, n)
   while h >= 0:
-    var nxt = s.data[h].next
-    if s.data[h].slot == seFilled: 
-      rawInsert(s, n, s.data[h].key)
+    var nxt = n[h].next
+    if isFilled(n[h].hcode):
+      var j = -1 - rawGetKnownHC(s, n[h].key, n[h].hcode)
+      rawInsert(s, s.data, n[h].key, n[h].hcode, j)
     h = nxt
-  swap(s.data, n)
 
 proc incl*[A](s: var OrderedSet[A], key: A) =
   ## Includes an element `key` in `s`.
@@ -655,10 +718,10 @@ proc containsOrIncl*[A](s: var OrderedSet[A], key: A): bool =
 proc init*[A](s: var OrderedSet[A], initialSize=64) =
   ## Initializes an ordered hash set.
   ##
-  ## The `initialSize` parameter needs to be a power of too. You can use
-  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ to guarantee that at
-  ## runtime. All set variables have to be initialized before you can use them
-  ## with other procs from this module with the exception of `isValid()
+  ## The `initialSize` parameter needs to be a power of two. You can use
+  ## `math.nextPowerOfTwo() <math.html#nextPowerOfTwo>`_ or `rightSize` to
+  ## guarantee that at runtime. All set variables must be initialized before
+  ## use with other procs from this module with the exception of `isValid()
   ## <#isValid,TOrderedSet[A]>`_ and `len() <#len,TOrderedSet[A]>`_.
   ##
   ## You can call this proc on a previously initialized ordered hash set to
@@ -698,7 +761,7 @@ proc toOrderedSet*[A](keys: openArray[A]): OrderedSet[A] =
   ##   var numbers = toOrderedSet([1, 2, 3, 4, 5])
   ##   assert numbers.contains(2)
   ##   assert numbers.contains(4)
-  result = initOrderedSet[A](nextPowerOfTwo(keys.len+10))
+  result = initOrderedSet[A](rightSize(keys.len))
   for key in items(keys): result.incl(key)
 
 proc `$`*[A](s: OrderedSet[A]): string =
@@ -726,7 +789,7 @@ proc `==`*[A](s, t: OrderedSet[A]): bool =
   while h >= 0 and g >= 0:
     var nxh = s.data[h].next
     var nxg = t.data[g].next
-    if s.data[h].slot == seFilled and s.data[g].slot == seFilled:
+    if isFilled(s.data[h].hcode) and isFilled(s.data[g].hcode):
       if s.data[h].key == s.data[g].key:
         inc compared
       else:
@@ -901,6 +964,11 @@ proc testModule() =
     b.incl(2)
     assert b.len == 1
 
+  for i in 0 .. 32:
+    var s = rightSize(i)
+    if s <= i or mustRehash(s, i):
+      echo "performance issue: rightSize() will not elide enlarge() at ", i
+
   echo "Micro tests run successfully."
 
 when isMainModule and not defined(release): testModule()
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 9dcc97148..959688d6a 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -11,7 +11,7 @@
 ## (also often named `dictionary`:idx: in other programming languages) that is
 ## a mapping from keys to values. ``Table`` is the usual hash table,
 ## ``OrderedTable`` is like ``Table`` but remembers insertion order
-## and ``CountTable`` is a mapping from a key to its number of occurances.
+## and ``CountTable`` is a mapping from a key to its number of occurrences.
 ## For consistency with every other data type in Nim these have **value**
 ## semantics, this means that ``=`` performs a copy of the hash table.
 ## For **reference** semantics use the ``Ref`` variant: ``TableRef``,
@@ -71,8 +71,7 @@ import
 {.pragma: myShallow.}
 
 type
-  SlotEnum = enum seEmpty, seFilled, seDeleted
-  KeyValuePair[A, B] = tuple[slot: SlotEnum, key: A, val: B]
+  KeyValuePair[A, B] = tuple[hcode: THash, key: A, val: B]
   KeyValuePairSeq[A, B] = seq[KeyValuePair[A, B]]
   Table* {.myShallow.}[A, B] = object ## generic hash table
     data: KeyValuePairSeq[A, B]
@@ -84,6 +83,14 @@ type
 when not defined(nimhygiene):
   {.pragma: dirty.}
 
+# hcode for real keys cannot be zero.  hcode==0 signifies an empty slot.  These
+# two procs retain clarity of that encoding without the space cost of an enum.
+proc isEmpty(hcode: THash): bool {.inline.} =
+  result = hcode == 0
+
+proc isFilled(hcode: THash): bool {.inline.} =
+  result = hcode != 0
+
 proc len*[A, B](t: Table[A, B]): int =
   ## returns the number of keys in `t`.
   result = t.counter
@@ -91,28 +98,28 @@ proc len*[A, B](t: Table[A, B]): int =
 iterator pairs*[A, B](t: Table[A, B]): tuple[key: A, val: B] =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
+    if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
 iterator mpairs*[A, B](t: var Table[A, B]): tuple[key: A, val: var B] =
   ## iterates over any (key, value) pair in the table `t`. The values
   ## can be modified.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
+    if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
 iterator keys*[A, B](t: Table[A, B]): A =
   ## iterates over any key in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].key
+    if isFilled(t.data[h].hcode): yield t.data[h].key
 
 iterator values*[A, B](t: Table[A, B]): B =
   ## iterates over any value in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].val
+    if isFilled(t.data[h].hcode): yield t.data[h].val
 
 iterator mvalues*[A, B](t: var Table[A, B]): var B =
   ## iterates over any value in the table `t`. The values can be modified.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].val
+    if isFilled(t.data[h].hcode): yield t.data[h].val
 
 const
   growthFactor = 2
@@ -121,26 +128,57 @@ proc mustRehash(length, counter: int): bool {.inline.} =
   assert(length > counter)
   result = (length * 2 < counter * 3) or (length - counter < 4)
 
+proc rightSize*(count: int): int {.inline.} =
+  ## Return the value of `initialSize` to support `count` items.
+  ##
+  ## If more items are expected to be added, simply add that
+  ## expected extra amount to the parameter before calling this.
+  ##
+  ## Internally, we want mustRehash(rightSize(x), x) == false.
+  result = nextPowerOfTwo(count * 3 div 2  +  4)
+
 proc nextTry(h, maxHash: THash): THash {.inline.} =
-  result = ((5 * h) + 1) and maxHash
+  result = (h + 1) and maxHash
+
+template rawGetKnownHCImpl() {.dirty.} =
+  var h: THash = hc and high(t.data)   # start with real hash value
+  while isFilled(t.data[h].hcode):
+    # Compare hc THEN key with boolean short circuit. This makes the common case
+    # zero ==key's for missing (e.g.inserts) and exactly one ==key for present.
+    # It does slow down succeeding lookups by one extra THash cmp&and..usually
+    # just a few clock cycles, generally worth it for any non-integer-like A.
+    if t.data[h].hcode == hc and t.data[h].key == key:
+      return h
+    h = nextTry(h, high(t.data))
+  result = -1 - h                   # < 0 => MISSING; insert idx = -1 - result
 
 template rawGetImpl() {.dirty.} =
-  var h: THash = hash(key) and high(t.data) # start with real hash value
-  while t.data[h].slot != seEmpty:
-    if t.data[h].key == key and t.data[h].slot == seFilled:
-      return h
+  hc = hash(key)
+  if hc == 0:       # This almost never taken branch should be very predictable.
+    hc = 314159265  # Value doesn't matter; Any non-zero favorite is fine.
+  rawGetKnownHCImpl()
+
+template rawGetDeepImpl() {.dirty.} =   # Search algo for unconditional add
+  hc = hash(key)
+  if hc == 0:
+    hc = 314159265
+  var h: THash = hc and high(t.data)
+  while isFilled(t.data[h].hcode):
     h = nextTry(h, high(t.data))
-  result = -1
+  result = h
 
 template rawInsertImpl() {.dirty.} =
-  var h: THash = hash(key) and high(data)
-  while data[h].slot == seFilled:
-    h = nextTry(h, high(data))
   data[h].key = key
   data[h].val = val
-  data[h].slot = seFilled
+  data[h].hcode = hc
+
+proc rawGetKnownHC[A, B](t: Table[A, B], key: A, hc: THash): int {.inline.} =
+  rawGetKnownHCImpl()
+
+proc rawGetDeep[A, B](t: Table[A, B], key: A, hc: var THash): int {.inline.} =
+  rawGetDeepImpl()
 
-proc rawGet[A, B](t: Table[A, B], key: A): int =
+proc rawGet[A, B](t: Table[A, B], key: A, hc: var THash): int {.inline.} =
   rawGetImpl()
 
 proc `[]`*[A, B](t: Table[A, B], key: A): B =
@@ -148,63 +186,87 @@ proc `[]`*[A, B](t: Table[A, B], key: A): B =
   ## default empty value for the type `B` is returned
   ## and no exception is raised. One can check with ``hasKey`` whether the key
   ## exists.
-  var index = rawGet(t, key)
+  var hc: THash
+  var index = rawGet(t, key, hc)
   if index >= 0: result = t.data[index].val
 
 proc mget*[A, B](t: var Table[A, B], key: A): var B =
   ## retrieves the value at ``t[key]``. The value can be modified.
   ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
-  var index = rawGet(t, key)
+  var hc: THash
+  var index = rawGet(t, key, hc)
   if index >= 0: result = t.data[index].val
   else: raise newException(KeyError, "key not found: " & $key)
 
 iterator allValues*[A, B](t: Table[A, B]; key: A): B =
   ## iterates over any value in the table `t` that belongs to the given `key`.
   var h: THash = hash(key) and high(t.data)
-  while t.data[h].slot != seEmpty:
-    if t.data[h].key == key and t.data[h].slot == seFilled:
+  while isFilled(t.data[h].hcode):
+    if t.data[h].key == key:
       yield t.data[h].val
     h = nextTry(h, high(t.data))
 
 proc hasKey*[A, B](t: Table[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
-  result = rawGet(t, key) >= 0
+  var hc: THash
+  result = rawGet(t, key, hc) >= 0
 
 proc rawInsert[A, B](t: var Table[A, B], data: var KeyValuePairSeq[A, B],
-                     key: A, val: B) =
+                     key: A, val: B, hc: THash, h: THash) =
   rawInsertImpl()
 
 proc enlarge[A, B](t: var Table[A, B]) =
   var n: KeyValuePairSeq[A, B]
   newSeq(n, len(t.data) * growthFactor)
-  for i in countup(0, high(t.data)):
-    if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val)
   swap(t.data, n)
+  for i in countup(0, high(n)):
+    if isFilled(n[i].hcode):
+      var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode)
+      rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j)
 
 template addImpl() {.dirty.} =
   if mustRehash(len(t.data), t.counter): enlarge(t)
-  rawInsert(t, t.data, key, val)
+  var hc: THash
+  var j = rawGetDeep(t, key, hc)
+  rawInsert(t, t.data, key, val, hc, j)
+  inc(t.counter)
+
+template maybeRehashPutImpl() {.dirty.} =
+  if mustRehash(len(t.data), t.counter):
+    enlarge(t)
+    index = rawGetKnownHC(t, key, hc)
+  index = -1 - index                  # important to transform for mgetOrPutImpl
+  rawInsert(t, t.data, key, val, hc, index)
   inc(t.counter)
 
 template putImpl() {.dirty.} =
-  var index = rawGet(t, key)
-  if index >= 0:
-    t.data[index].val = val
-  else:
-    addImpl()
-
-when false:
-  # not yet used:
-  template hasKeyOrPutImpl() {.dirty.} =
-    var index = rawGet(t, key)
-    if index >= 0:
-      t.data[index].val = val
-      result = true
-    else:
-      if mustRehash(len(t.data), t.counter): enlarge(t)
-      rawInsert(t, t.data, key, val)
-      inc(t.counter)
-      result = false
+  var hc: THash
+  var index = rawGet(t, key, hc)
+  if index >= 0: t.data[index].val = val
+  else: maybeRehashPutImpl()
+
+template mgetOrPutImpl() {.dirty.} =
+  var hc: THash
+  var index = rawGet(t, key, hc)
+  if index < 0: maybeRehashPutImpl()    # not present: insert (flipping index)
+  result = t.data[index].val            # either way return modifiable val
+
+template hasKeyOrPutImpl() {.dirty.} =
+  var hc: THash
+  var index = rawGet(t, key, hc)
+  if index < 0:
+    result = false
+    maybeRehashPutImpl()
+  else: result = true
+
+proc mgetOrPut*[A, B](t: var Table[A, B], key: A, val: B): var B =
+  ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
+  ## returning a value which can be modified.
+  mgetOrPutImpl()
+
+proc hasKeyOrPut*[A, B](t: var Table[A, B], key: A, val: B): bool =
+  ## returns true iff `key` is in the table, otherwise inserts `value`.
+  hasKeyOrPutImpl()
 
 proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
   ## puts a (key, value)-pair into `t`.
@@ -213,20 +275,37 @@ proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
 proc add*[A, B](t: var Table[A, B], key: A, val: B) =
   ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
   addImpl()
-  
+
+template doWhile(a: expr, b: stmt): stmt =
+  while true:
+    b
+    if not a: break
+
 proc del*[A, B](t: var Table[A, B], key: A) =
   ## deletes `key` from hash table `t`.
-  let index = rawGet(t, key)
-  if index >= 0:
-    t.data[index].slot = seDeleted
+  var hc: THash
+  var i = rawGet(t, key, hc)
+  let msk = high(t.data)
+  if i >= 0:
+    t.data[i].hcode = 0
     dec(t.counter)
+    while true:         # KnuthV3 Algo6.4R adapted for i=i+1 instead of i=i-1
+      var j = i         # The correctness of this depends on (h+1) in nextTry,
+      var r = j         # though may be adaptable to other simple sequences.
+      t.data[i].hcode = 0              # mark current EMPTY
+      doWhile ((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)):
+        i = (i + 1) and msk            # increment mod table size
+        if isEmpty(t.data[i].hcode):   # end of collision cluster; So all done
+          return
+        r = t.data[i].hcode and msk    # "home" location of key@i
+      shallowCopy(t.data[j], t.data[i]) # data[j] will be marked EMPTY next loop
 
 proc initTable*[A, B](initialSize=64): Table[A, B] =
   ## creates a new hash table that is empty.
   ##
   ## `initialSize` needs to be a power of two. If you need to accept runtime
   ## values for this you could use the ``nextPowerOfTwo`` proc from the
-  ## `math <math.html>`_ module.
+  ## `math <math.html>`_ module or the ``rightSize`` proc from this module.
   assert isPowerOfTwo(initialSize)
   result.counter = 0
   newSeq(result.data, initialSize)
@@ -234,7 +313,7 @@ proc initTable*[A, B](initialSize=64): Table[A, B] =
 proc toTable*[A, B](pairs: openArray[tuple[key: A, 
                     val: B]]): Table[A, B] =
   ## creates a new hash table that contains the given `pairs`.
-  result = initTable[A, B](nextPowerOfTwo(pairs.len+10))
+  result = initTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
 
 template dollarImpl(): stmt {.dirty.} =
@@ -252,7 +331,7 @@ template dollarImpl(): stmt {.dirty.} =
 proc `$`*[A, B](t: Table[A, B]): string =
   ## The `$` operator for hash tables.
   dollarImpl()
-  
+
 template equalsImpl() =
   if s.counter == t.counter:
     # different insertion orders mean different 'data' seqs, so we have
@@ -262,10 +341,10 @@ template equalsImpl() =
       if not t.hasKey(key): return false
       if t[key] != val: return false
     return true
-  
+
 proc `==`*[A, B](s, t: Table[A, B]): bool =
   equalsImpl()
-  
+
 proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): Table[C, B] =
   ## Index the collection with the proc provided.
   # TODO: As soon as supported, change collection: A to collection: A[B]
@@ -280,28 +359,28 @@ proc len*[A, B](t: TableRef[A, B]): int =
 iterator pairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: B] =
   ## iterates over any (key, value) pair in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
+    if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
 iterator mpairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: var B] =
   ## iterates over any (key, value) pair in the table `t`. The values
   ## can be modified.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
+    if isFilled(t.data[h].hcode): yield (t.data[h].key, t.data[h].val)
 
 iterator keys*[A, B](t: TableRef[A, B]): A =
   ## iterates over any key in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].key
+    if isFilled(t.data[h].hcode): yield t.data[h].key
 
 iterator values*[A, B](t: TableRef[A, B]): B =
   ## iterates over any value in the table `t`.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].val
+    if isFilled(t.data[h].hcode): yield t.data[h].val
 
 iterator mvalues*[A, B](t: TableRef[A, B]): var B =
   ## iterates over any value in the table `t`. The values can be modified.
   for h in 0..high(t.data):
-    if t.data[h].slot == seFilled: yield t.data[h].val
+    if isFilled(t.data[h].hcode): yield t.data[h].val
 
 proc `[]`*[A, B](t: TableRef[A, B], key: A): B =
   ## retrieves the value at ``t[key]``. If `key` is not in `t`,
@@ -315,6 +394,15 @@ proc mget*[A, B](t: TableRef[A, B], key: A): var B =
   ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
   t[].mget(key)
 
+proc mgetOrPut*[A, B](t: TableRef[A, B], key: A, val: B): var B =
+  ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
+  ## returning a value which can be modified.
+  t[].mgetOrPut(key, val)
+
+proc hasKeyOrPut*[A, B](t: var TableRef[A, B], key: A, val: B): bool =
+  ## returns true iff `key` is in the table, otherwise inserts `value`.
+  t[].hasKeyOrPut(key, val)
+
 proc hasKey*[A, B](t: TableRef[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
   result = t[].hasKey(key)
@@ -326,7 +414,7 @@ proc `[]=`*[A, B](t: TableRef[A, B], key: A, val: B) =
 proc add*[A, B](t: TableRef[A, B], key: A, val: B) =
   ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
   t[].add(key, val)
-  
+
 proc del*[A, B](t: TableRef[A, B], key: A) =
   ## deletes `key` from hash table `t`.
   t[].del(key)
@@ -347,7 +435,7 @@ proc `$`*[A, B](t: TableRef[A, B]): string =
 proc `==`*[A, B](s, t: TableRef[A, B]): bool =
   if isNil(s): result = isNil(t)
   elif isNil(t): result = false
-  else: result = equalsImpl()
+  else: equalsImpl()
 
 proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] =
   ## Index the collection with the proc provided.
@@ -360,7 +448,7 @@ proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B]
 
 type
   OrderedKeyValuePair[A, B] = tuple[
-    slot: SlotEnum, next: int, key: A, val: B]
+    hcode: THash, next: int, key: A, val: B]
   OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]]
   OrderedTable* {.
       myShallow.}[A, B] = object ## table that remembers insertion order
@@ -378,7 +466,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
   var h = t.first
   while h >= 0:
     var nxt = t.data[h].next
-    if t.data[h].slot == seFilled: yieldStmt
+    if isFilled(t.data[h].hcode): yieldStmt
     h = nxt
 
 iterator pairs*[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] =
@@ -409,7 +497,13 @@ iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B =
   forAllOrderedPairs:
     yield t.data[h].val
 
-proc rawGet[A, B](t: OrderedTable[A, B], key: A): int =
+proc rawGetKnownHC[A, B](t: OrderedTable[A, B], key: A, hc: THash): int =
+  rawGetKnownHCImpl()
+
+proc rawGetDeep[A, B](t: OrderedTable[A, B], key: A, hc: var THash): int {.inline.} =
+  rawGetDeepImpl()
+
+proc rawGet[A, B](t: OrderedTable[A, B], key: A, hc: var THash): int =
   rawGetImpl()
 
 proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
@@ -417,23 +511,26 @@ proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
   ## default empty value for the type `B` is returned
   ## and no exception is raised. One can check with ``hasKey`` whether the key
   ## exists.
-  var index = rawGet(t, key)
+  var hc: THash
+  var index = rawGet(t, key, hc)
   if index >= 0: result = t.data[index].val
 
 proc mget*[A, B](t: var OrderedTable[A, B], key: A): var B =
   ## retrieves the value at ``t[key]``. The value can be modified.
   ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
-  var index = rawGet(t, key)
+  var hc: THash
+  var index = rawGet(t, key, hc)
   if index >= 0: result = t.data[index].val
   else: raise newException(KeyError, "key not found: " & $key)
 
 proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
-  result = rawGet(t, key) >= 0
+  var hc: THash
+  result = rawGet(t, key, hc) >= 0
 
 proc rawInsert[A, B](t: var OrderedTable[A, B], 
                      data: var OrderedKeyValuePairSeq[A, B],
-                     key: A, val: B) =
+                     key: A, val: B, hc: THash, h: THash) =
   rawInsertImpl()
   data[h].next = -1
   if t.first < 0: t.first = h
@@ -446,12 +543,13 @@ proc enlarge[A, B](t: var OrderedTable[A, B]) =
   var h = t.first
   t.first = -1
   t.last = -1
+  swap(t.data, n)
   while h >= 0:
-    var nxt = t.data[h].next
-    if t.data[h].slot == seFilled: 
-      rawInsert(t, n, t.data[h].key, t.data[h].val)
+    var nxt = n[h].next
+    if isFilled(n[h].hcode):
+      var j = -1 - rawGetKnownHC(t, n[h].key, n[h].hcode)
+      rawInsert(t, t.data, n[h].key, n[h].val, n[h].hcode, j)
     h = nxt
-  swap(t.data, n)
 
 proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) =
   ## puts a (key, value)-pair into `t`.
@@ -461,12 +559,21 @@ proc add*[A, B](t: var OrderedTable[A, B], key: A, val: B) =
   ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
   addImpl()
 
+proc mgetOrPut*[A, B](t: var OrderedTable[A, B], key: A, val: B): var B =
+  ## retrieves value at ``t[key]`` or puts ``value`` if not present, either way
+  ## returning a value which can be modified.
+  mgetOrPutImpl()
+
+proc hasKeyOrPut*[A, B](t: var OrderedTable[A, B], key: A, val: B): bool =
+  ## returns true iff `key` is in the table, otherwise inserts `value`.
+  hasKeyOrPutImpl()
+
 proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] =
   ## creates a new ordered hash table that is empty.
   ##
   ## `initialSize` needs to be a power of two. If you need to accept runtime
   ## values for this you could use the ``nextPowerOfTwo`` proc from the
-  ## `math <math.html>`_ module.
+  ## `math <math.html>`_ module or the ``rightSize`` proc from this module.
   assert isPowerOfTwo(initialSize)
   result.counter = 0
   result.first = -1
@@ -476,7 +583,7 @@ proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] =
 proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, 
                            val: B]]): OrderedTable[A, B] =
   ## creates a new ordered hash table that contains the given `pairs`.
-  result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10))
+  result = initOrderedTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
 
 proc `$`*[A, B](t: OrderedTable[A, B]): string =
@@ -537,7 +644,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
   var h = t.first
   while h >= 0:
     var nxt = t.data[h].next
-    if t.data[h].slot == seFilled: yieldStmt
+    if isFilled(t.data[h].hcode): yieldStmt
     h = nxt
 
 iterator pairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: B] =
@@ -580,6 +687,15 @@ proc mget*[A, B](t: OrderedTableRef[A, B], key: A): var B =
   ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
   result = t[].mget(key)
 
+proc mgetOrPut*[A, B](t: OrderedTableRef[A, B], key: A, val: B): var B =
+  ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
+  ## returning a value which can be modified.
+  result = t[].mgetOrPut(key, val)
+
+proc hasKeyOrPut*[A, B](t: var OrderedTableRef[A, B], key: A, val: B): bool =
+  ## returns true iff `key` is in the table, otherwise inserts `val`.
+  result = t[].hasKeyOrPut(key, val)
+
 proc hasKey*[A, B](t: OrderedTableRef[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
   result = t[].hasKey(key)
@@ -597,14 +713,14 @@ proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] =
   ##
   ## `initialSize` needs to be a power of two. If you need to accept runtime
   ## values for this you could use the ``nextPowerOfTwo`` proc from the
-  ## `math <math.html>`_ module.
+  ## `math <math.html>`_ module or the ``rightSize`` proc from this module.
   new(result)
   result[] = initOrderedTable[A, B]()
 
 proc newOrderedTable*[A, B](pairs: openArray[tuple[key: A, 
                            val: B]]): OrderedTableRef[A, B] =
   ## creates a new ordered hash table that contains the given `pairs`.
-  result = newOrderedTable[A, B](nextPowerOfTwo(pairs.len+10))
+  result = newOrderedTable[A, B](rightSize(pairs.len))
   for key, val in items(pairs): result[key] = val
 
 proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
@@ -665,7 +781,7 @@ proc rawGet[A](t: CountTable[A], key: A): int =
   while t.data[h].val != 0:
     if t.data[h].key == key: return h
     h = nextTry(h, high(t.data))
-  result = -1
+  result = -1 - h                   # < 0 => MISSING; insert idx = -1 - result
 
 proc `[]`*[A](t: CountTable[A], key: A): int =
   ## retrieves the value at ``t[key]``. If `key` is not in `t`,
@@ -702,21 +818,27 @@ proc enlarge[A](t: var CountTable[A]) =
 proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
   ## puts a (key, value)-pair into `t`. `val` has to be positive.
   assert val > 0
-  putImpl()
+  var h = rawGet(t, key)
+  if h >= 0:
+    t.data[h].val = val
+  else:
+    h = -1 - h
+    t.data[h].key = key
+    t.data[h].val = val
 
 proc initCountTable*[A](initialSize=64): CountTable[A] =
   ## creates a new count table that is empty.
   ##
   ## `initialSize` needs to be a power of two. If you need to accept runtime
   ## values for this you could use the ``nextPowerOfTwo`` proc from the
-  ## `math <math.html>`_ module.
+  ## `math <math.html>`_ module or the ``rightSize`` proc in this module.
   assert isPowerOfTwo(initialSize)
   result.counter = 0
   newSeq(result.data, initialSize)
 
 proc toCountTable*[A](keys: openArray[A]): CountTable[A] =
   ## creates a new count table with every key in `keys` having a count of 1.
-  result = initCountTable[A](nextPowerOfTwo(keys.len+10))
+  result = initCountTable[A](rightSize(keys.len))
   for key in items(keys): result[key] = 1
 
 proc `$`*[A](t: CountTable[A]): string =
@@ -827,13 +949,13 @@ proc newCountTable*[A](initialSize=64): CountTableRef[A] =
   ##
   ## `initialSize` needs to be a power of two. If you need to accept runtime
   ## values for this you could use the ``nextPowerOfTwo`` proc from the
-  ## `math <math.html>`_ module.
+  ## `math <math.html>`_ module or the ``rightSize`` method in this module.
   new(result)
   result[] = initCountTable[A](initialSize)
 
 proc newCountTable*[A](keys: openArray[A]): CountTableRef[A] =
   ## creates a new count table with every key in `keys` having a count of 1.
-  result = newCountTable[A](nextPowerOfTwo(keys.len+10))
+  result = newCountTable[A](rightSize(keys.len))
   for key in items(keys): result[key] = 1
 
 proc `$`*[A](t: CountTableRef[A]): string =
diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim
index 7942255cb..f24cc0072 100644
--- a/lib/pure/colors.nim
+++ b/lib/pure/colors.nim
@@ -46,7 +46,7 @@ proc `+`*(a, b: Color): Color =
   colorOp(satPlus)
   
 proc `-`*(a, b: Color): Color =
-  ## substracts two colors: This uses saturated artithmetic, so that each color
+  ## subtracts two colors: This uses saturated artithmetic, so that each color
   ## component cannot overflow (255 is used as a maximum).
   colorOp(satMinus)
   
@@ -392,7 +392,7 @@ proc parseColor*(name: string): Color =
     result = Color(parseHexInt(name))
   else:
     var idx = binaryStrSearch(colorNames, name)
-    if idx < 0: raise newException(ValueError, "unkown color: " & name)
+    if idx < 0: raise newException(ValueError, "unknown color: " & name)
     result = colorNames[idx][1]
 
 proc isColor*(name: string): bool =
diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim
index 04cffe4e4..8577bf7a1 100644
--- a/lib/pure/complex.nim
+++ b/lib/pure/complex.nim
@@ -27,6 +27,11 @@ type
 
 {.deprecated: [TComplex: Complex].}
 
+proc toComplex*(x: SomeInteger): Complex =
+  ## Convert some integer ``x`` to a complex number.
+  result.re = x
+  result.im = 0
+
 proc `==` *(x, y: Complex): bool =
   ## Compare two complex numbers `x` and `y` for equality.
   result = x.re == y.re and x.im == y.im
@@ -269,27 +274,101 @@ proc tan*(z: Complex): Complex =
   ## Returns the tangent of `z`.
   result = sin(z)/cos(z)
 
+proc arctan*(z: Complex): Complex =
+  ## Returns the inverse tangent of `z`.
+  var i: Complex = (0.0,1.0)
+  result = 0.5*i*(ln(1-i*z)-ln(1+i*z))
+
 proc cot*(z: Complex): Complex =
   ## Returns the cotangent of `z`.
   result = cos(z)/sin(z)
 
+proc arccot*(z: Complex): Complex =
+  ## Returns the inverse cotangent of `z`.
+  var i: Complex = (0.0,1.0)
+  result = 0.5*i*(ln(1-i/z)-ln(1+i/z))
+
 proc sec*(z: Complex): Complex =
   ## Returns the secant of `z`.
   result = 1.0/cos(z)
 
+proc arcsec*(z: Complex): Complex =
+  ## Returns the inverse secant of `z`.
+  var i: Complex = (0.0,1.0)
+  result = -i*ln(i*sqrt(1-1/(z*z))+1/z)
+
 proc csc*(z: Complex): Complex =
   ## Returns the cosecant of `z`.
   result = 1.0/sin(z)
 
+proc arccsc*(z: Complex): Complex =
+  ## Returns the inverse cosecant of `z`.
+  var i: Complex = (0.0,1.0)
+  result = -i*ln(sqrt(1-1/(z*z))+i/z)
+
 
 proc sinh*(z: Complex): Complex =
   ## Returns the hyperbolic sine of `z`.
   result = 0.5*(exp(z)-exp(-z))
 
+proc arcsinh*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic sine of `z`.
+  result = ln(z+sqrt(z*z+1))
+
 proc cosh*(z: Complex): Complex =
   ## Returns the hyperbolic cosine of `z`.
   result = 0.5*(exp(z)+exp(-z))
 
+proc arccosh*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic cosine of `z`.
+  result = ln(z+sqrt(z*z-1))
+
+proc tanh*(z: Complex): Complex =
+  ## Returns the hyperbolic tangent of `z`.
+  result = sinh(z)/cosh(z)
+
+proc arctanh*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic tangent of `z`.
+  result = 0.5*(ln((1+z)/(1-z)))
+
+proc sech*(z: Complex): Complex =
+  ## Returns the hyperbolic secant of `z`.
+  result = 2/(exp(z)+exp(-z))
+
+proc arcsech*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic secant of `z`.
+  result = ln(1/z+sqrt(1/z+1)*sqrt(1/z-1))
+
+proc csch*(z: Complex): Complex =
+  ## Returns the hyperbolic cosecant of `z`.
+  result = 2/(exp(z)-exp(-z))
+
+proc arccsch*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic cosecant of `z`.
+  result = ln(1/z+sqrt(1/(z*z)+1))
+
+proc coth*(z: Complex): Complex =
+  ## Returns the hyperbolic cotangent of `z`.
+  result = cosh(z)/sinh(z)
+
+proc arccoth*(z: Complex): Complex =
+  ## Returns the inverse hyperbolic cotangent of `z`.
+  result = 0.5*(ln(1+1/z)-ln(1-1/z))
+
+proc phase*(z: Complex): float =
+  ## Returns the phase of `z`.
+  arctan2(z.im, z.re)
+
+proc polar*(z: Complex): tuple[r, phi: float] =
+  ## Returns `z` in polar coordinates.
+  result.r = abs(z)
+  result.phi = phase(z)
+
+proc rect*(r: float, phi: float): Complex =
+  ## Returns the complex number with polar coordinates `r` and `phi`.
+  result.re = r * cos(phi)
+  result.im = r * sin(phi)
+
 
 proc `$`*(z: Complex): string =
   ## Returns `z`'s string representation as ``"(re, im)"``.
@@ -343,7 +422,22 @@ when isMainModule:
   assert( csc(a) =~ 1.0/sin(a) )
   assert( arcsin(a) =~ (0.427078586392476, 1.528570919480998) )
   assert( arccos(a) =~ (1.14371774040242, -1.52857091948100) )
+  assert( arctan(a) =~ (1.338972522294494, 0.402359478108525) )
 
-  assert( cosh(a) =~ (-0.642148124715520, 1.068607421382778) ) 
+  assert( cosh(a) =~ (-0.642148124715520, 1.068607421382778) )
   assert( sinh(a) =~ (-0.489056259041294, 1.403119250622040) )
-  
\ No newline at end of file
+  assert( tanh(a) =~ (1.1667362572409199,-0.243458201185725) )
+  assert( sech(a) =~ 1/cosh(a) )
+  assert( csch(a) =~ 1/sinh(a) )
+  assert( coth(a) =~ 1/tanh(a) )
+  assert( arccosh(a) =~ (1.528570919480998, 1.14371774040242) )
+  assert( arcsinh(a) =~ (1.469351744368185, 1.06344002357775) )
+  assert( arctanh(a) =~ (0.173286795139986, 1.17809724509617) )
+  assert( arcsech(a) =~ arccosh(1/a) )
+  assert( arccsch(a) =~ arcsinh(1/a) )
+  assert( arccoth(a) =~ arctanh(1/a) )
+
+  assert( phase(a) == 1.1071487177940904 )
+  var t = polar(a)
+  assert( rect(t.r, t.phi) =~ a )
+  assert( rect(1.0, 2.0) =~ (-0.4161468365471424, 0.9092974268256817) )
diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim
index 298a6072d..25c7ad9ef 100644
--- a/lib/pure/encodings.nim
+++ b/lib/pure/encodings.nim
@@ -301,7 +301,7 @@ proc getCurrentEncoding*(): string =
   
 proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): EncodingConverter =
   ## opens a converter that can convert from `srcEncoding` to `destEncoding`.
-  ## Raises `EIO` if it cannot fullfill the request.
+  ## Raises `EIO` if it cannot fulfill the request.
   when not defined(windows):
     result = iconvOpen(destEncoding, srcEncoding)
     if result == nil:
diff --git a/lib/pure/events.nim b/lib/pure/events.nim
index 77faa6a66..44e9ed286 100644
--- a/lib/pure/events.nim
+++ b/lib/pure/events.nim
@@ -9,7 +9,7 @@
 
 ## :Author: Alex Mitchell
 ##
-## This module implements an event system that is not dependant on external
+## This module implements an event system that is not dependent on external
 ## graphical toolkits. It was originally called ``NimEE`` because 
 ## it was inspired by Python's PyEE module. There are two ways you can use
 ## events: one is a python-inspired way; the other is more of a C-style way.
diff --git a/lib/pure/fsmonitor.nim b/lib/pure/fsmonitor.nim
index bf4aef61c..e6919b661 100644
--- a/lib/pure/fsmonitor.nim
+++ b/lib/pure/fsmonitor.nim
@@ -29,7 +29,7 @@ type
   FSMonitorObj = object of RootObj
     fd: cint
     handleEvent: proc (m: FSMonitor, ev: MonitorEvent) {.closure.}
-    targets: TTable[cint, string]
+    targets: Table[cint, string]
   
   MonitorEventType* = enum ## Monitor event type
     MonitorAccess,       ## File was accessed.
@@ -64,7 +64,7 @@ type
 const
   MaxEvents = 100
 
-proc newMonitor*(): PFSMonitor =
+proc newMonitor*(): FSMonitor =
   ## Creates a new file system monitor.
   new(result)
   result.targets = initTable[cint, string]()
@@ -72,7 +72,7 @@ proc newMonitor*(): PFSMonitor =
   if result.fd < 0:
     raiseOSError(osLastError())
 
-proc add*(monitor: PFSMonitor, target: string,
+proc add*(monitor: FSMonitor, target: string,
                filters = {MonitorAll}): cint {.discardable.} =
   ## Adds ``target`` which may be a directory or a file to the list of
   ## watched paths of ``monitor``.
@@ -99,14 +99,14 @@ proc add*(monitor: PFSMonitor, target: string,
     raiseOSError(osLastError())
   monitor.targets.add(result, target)
 
-proc del*(monitor: PFSMonitor, wd: cint) =
+proc del*(monitor: FSMonitor, wd: cint) =
   ## Removes watched directory or file as specified by ``wd`` from ``monitor``.
   ##
   ## If ``wd`` is not a part of ``monitor`` an EOS error is raised.
   if inotifyRmWatch(monitor.fd, wd) < 0:
     raiseOSError(osLastError())
 
-proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] =
+proc getEvent(m: FSMonitor, fd: cint): seq[MonitorEvent] =
   result = @[]
   let size = (sizeof(TINotifyEvent)+2000)*MaxEvents
   var buffer = newString(size)
@@ -118,7 +118,7 @@ proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] =
   var i = 0
   while i < le:
     var event = cast[ptr TINotifyEvent](addr(buffer[i]))
-    var mev: TMonitorEvent
+    var mev: MonitorEvent
     mev.wd = event.wd
     if event.len.int != 0:
       let cstr = event.name.addr.cstring
@@ -137,7 +137,7 @@ proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] =
       # Find the MovedFrom event.
       mev.oldPath = movedFrom[event.cookie.cint].old
       mev.newPath = "" # Set later
-      # Delete it from the TTable
+      # Delete it from the Table
       movedFrom.del(event.cookie.cint)
     elif (event.mask.int and IN_ACCESS) != 0: mev.kind = MonitorAccess
     elif (event.mask.int and IN_ATTRIB) != 0: mev.kind = MonitorAttrib
@@ -164,26 +164,26 @@ proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] =
   # If movedFrom events have not been matched with a moveTo. File has
   # been moved to an unwatched location, emit a MonitorDelete.
   for cookie, t in pairs(movedFrom):
-    var mev: TMonitorEvent
+    var mev: MonitorEvent
     mev.kind = MonitorDelete
     mev.wd = t.wd
     mev.name = t.old
     result.add(mev)
 
-proc FSMonitorRead(h: PObject) =
-  var events = PFSMonitor(h).getEvent(PFSMonitor(h).fd)
-  #var newEv: TMonitorEvent
+proc FSMonitorRead(h: RootRef) =
+  var events = FSMonitor(h).getEvent(FSMonitor(h).fd)
+  #var newEv: MonitorEvent
   for ev in events:
-    var target = PFSMonitor(h).targets[ev.wd]
+    var target = FSMonitor(h).targets[ev.wd]
     var newEv = ev
     if newEv.kind == MonitorMoved:
       newEv.oldPath = target / newEv.oldPath
       newEv.newPath = target / newEv.name
     else:
       newEv.fullName = target / newEv.name
-    PFSMonitor(h).handleEvent(PFSMonitor(h), newEv)
+    FSMonitor(h).handleEvent(FSMonitor(h), newEv)
 
-proc toDelegate(m: PFSMonitor): PDelegate =
+proc toDelegate(m: FSMonitor): Delegate =
   result = newDelegate()
   result.deleVal = m
   result.fd = (type(result.fd))(m.fd)
@@ -191,8 +191,8 @@ proc toDelegate(m: PFSMonitor): PDelegate =
   result.handleRead = FSMonitorRead
   result.open = true
 
-proc register*(d: PDispatcher, monitor: PFSMonitor,
-               handleEvent: proc (m: PFSMonitor, ev: TMonitorEvent) {.closure.}) =
+proc register*(d: Dispatcher, monitor: FSMonitor,
+               handleEvent: proc (m: FSMonitor, ev: MonitorEvent) {.closure.}) =
   ## Registers ``monitor`` with dispatcher ``d``.
   monitor.handleEvent = handleEvent
   var deleg = toDelegate(monitor)
@@ -204,7 +204,7 @@ when isMainModule:
     var monitor = newMonitor()
     echo monitor.add("/home/dom/inotifytests/")
     disp.register(monitor,
-      proc (m: PFSMonitor, ev: TMonitorEvent) =
+      proc (m: FSMonitor, ev: MonitorEvent) =
         echo("Got event: ", ev.kind)
         if ev.kind == MonitorMoved:
           echo("From ", ev.oldPath, " to ", ev.newPath)
diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim
index 40ee5951b..46af1d528 100644
--- a/lib/pure/ftpclient.nim
+++ b/lib/pure/ftpclient.nim
@@ -107,7 +107,7 @@ type
   EInvalidReply: ReplyError, EFTP: FTPError
 ].}
 
-proc ftpClient*(address: string, port = TPort(21),
+proc ftpClient*(address: string, port = Port(21),
                 user, pass = ""): FtpClient =
   ## Create a ``FtpClient`` object.
   new(result)
@@ -120,10 +120,10 @@ proc ftpClient*(address: string, port = TPort(21),
   result.csock = socket()
   if result.csock == invalidSocket: raiseOSError(osLastError())
 
-template blockingOperation(sock: TSocket, body: stmt) {.immediate.} =
+template blockingOperation(sock: Socket, body: stmt) {.immediate.} =
   body
 
-template blockingOperation(sock: asyncio.PAsyncSocket, body: stmt) {.immediate.} =
+template blockingOperation(sock: asyncio.AsyncSocket, body: stmt) {.immediate.} =
   sock.setBlocking(true)
   body
   sock.setBlocking(false)
@@ -145,14 +145,14 @@ proc send*[T](ftp: FtpBase[T], m: string): TaintedString =
 
 proc assertReply(received: TaintedString, expected: string) =
   if not received.string.startsWith(expected):
-    raise newException(EInvalidReply,
+    raise newException(ReplyError,
                        "Expected reply '$1' got: $2" % [
                        expected, received.string])
 
 proc assertReply(received: TaintedString, expected: varargs[string]) =
   for i in items(expected):
     if received.string.startsWith(i): return
-  raise newException(EInvalidReply,
+  raise newException(ReplyError,
                      "Expected reply '$1' got: $2" %
                      [expected.join("' or '"), received.string])
 
@@ -161,7 +161,7 @@ proc createJob[T](ftp: FtpBase[T],
                           nimcall,gcsafe.},
                cmd: FTPJobType) =
   if ftp.jobInProgress:
-    raise newException(EFTP, "Unable to do two jobs at once.")
+    raise newException(FTPError, "Unable to do two jobs at once.")
   ftp.jobInProgress = true
   new(ftp.job)
   ftp.job.prc = prc
@@ -182,11 +182,11 @@ proc deleteJob[T](ftp: FtpBase[T]) =
     ftp.job.file.close()
   ftp.dsock.close()
 
-proc handleTask(s: PAsyncSocket, ftp: PAsyncFTPClient) =
+proc handleTask(s: AsyncSocket, ftp: AsyncFTPClient) =
   if ftp.jobInProgress:
     if ftp.job.typ in {JRetr, JStore}:
       if epochTime() - ftp.job.lastProgressReport >= 1.0:
-        var r: TFTPEvent
+        var r: FTPEvent
         ftp.job.lastProgressReport = epochTime()
         r.typ = EvTransferProgress
         r.bytesTotal = ftp.job.total
@@ -195,22 +195,22 @@ proc handleTask(s: PAsyncSocket, ftp: PAsyncFTPClient) =
         r.filename = ftp.job.filename
         r.currentJob = ftp.job.typ
         ftp.job.oneSecond = 0
-        ftp.handleEvent(PAsyncFTPClient(ftp), r)
+        ftp.handleEvent(ftp, r)
 
-proc handleWrite(s: PAsyncSocket, ftp: PAsyncFTPClient) =
+proc handleWrite(s: AsyncSocket, ftp: AsyncFTPClient) =
   if ftp.jobInProgress:
     if ftp.job.typ == JStore:
       assert (not ftp.job.prc(ftp, true))
 
-proc handleConnect(s: PAsyncSocket, ftp: PAsyncFTPClient) =
+proc handleConnect(s: AsyncSocket, ftp: AsyncFTPClient) =
   ftp.dsockConnected = true
   assert(ftp.jobInProgress)
   if ftp.job.typ == JStore:
-    s.setHandleWrite(proc (s: PAsyncSocket) = handleWrite(s, ftp))
+    s.setHandleWrite(proc (s: AsyncSocket) = handleWrite(s, ftp))
   else:
     s.delHandleWrite()
 
-proc handleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) =
+proc handleRead(s: AsyncSocket, ftp: AsyncFTPClient) =
   assert ftp.jobInProgress
   assert ftp.job.typ != JStore
   # This can never return true, because it shouldn't check for code 
@@ -219,19 +219,19 @@ proc handleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) =
 
 proc pasv[T](ftp: FtpBase[T]) =
   ## Negotiate a data connection.
-  when T is TSocket:
+  when T is Socket:
     ftp.dsock = socket()
     if ftp.dsock == invalidSocket: raiseOSError(osLastError())
-  elif T is PAsyncSocket:
+  elif T is AsyncSocket:
     ftp.dsock = asyncSocket()
     ftp.dsock.handleRead =
-      proc (s: PAsyncSocket) =
+      proc (s: AsyncSocket) =
         handleRead(s, ftp)
     ftp.dsock.handleConnect =
-      proc (s: PAsyncSocket) =
+      proc (s: AsyncSocket) =
         handleConnect(s, ftp)
     ftp.dsock.handleTask =
-      proc (s: PAsyncSocket) =
+      proc (s: AsyncSocket) =
         handleTask(s, ftp)
     ftp.disp.register(ftp.dsock)
   else:
@@ -244,8 +244,8 @@ proc pasv[T](ftp: FtpBase[T]) =
   var ip = nums[0.. -3]
   var port = nums[-2.. -1]
   var properPort = port[0].parseInt()*256+port[1].parseInt()
-  ftp.dsock.connect(ip.join("."), TPort(properPort.toU16))
-  when T is PAsyncSocket:
+  ftp.dsock.connect(ip.join("."), Port(properPort.toU16))
+  when T is AsyncSocket:
     ftp.dsockConnected = false
   else:
     ftp.dsockConnected = true
@@ -255,10 +255,10 @@ proc normalizePathSep(path: string): string =
 
 proc connect*[T](ftp: FtpBase[T]) =
   ## Connect to the FTP server specified by ``ftp``.
-  when T is PAsyncSocket:
+  when T is AsyncSocket:
     blockingOperation(ftp.csock):
       ftp.csock.connect(ftp.address, ftp.port)
-  elif T is TSocket:
+  elif T is Socket:
     ftp.csock.connect(ftp.address, ftp.port)
   else:
     {.fatal: "Incorrect socket instantiation".}
@@ -292,13 +292,13 @@ proc getLines[T](ftp: FtpBase[T], async: bool = false): bool =
   ## It doesn't if `async` is true, because it doesn't check for 226 then.
   if ftp.dsockConnected:
     var r = TaintedString""
-    when T is PAsyncSocket:
+    when T is AsyncSocket:
       if ftp.asyncDSock.readLine(r):
         if r.string == "":
           ftp.dsockConnected = false
         else:
           ftp.job.lines.add(r.string & "\n")
-    elif T is TSocket:
+    elif T is Socket:
       assert(not async)
       ftp.dsock.readLine(r)
       if r.string == "":
@@ -309,7 +309,7 @@ proc getLines[T](ftp: FtpBase[T], async: bool = false): bool =
       {.fatal: "Incorrect socket instantiation".}
   
   if not async:
-    var readSocks: seq[TSocket] = @[ftp.csock]
+    var readSocks: seq[Socket] = @[ftp.csock]
     # This is only needed here. Asyncio gets this socket...
     blockingOperation(ftp.csock):
       if readSocks.select(1) != 0 and ftp.csock in readSocks:
@@ -372,7 +372,7 @@ proc createDir*[T](ftp: FtpBase[T], dir: string, recursive: bool = false) =
     assertReply reply, "257"
 
 proc chmod*[T](ftp: FtpBase[T], path: string,
-            permissions: set[TFilePermission]) =
+            permissions: set[FilePermission]) =
   ## Changes permission of ``path`` to ``permissions``.
   var userOctal = 0
   var groupOctal = 0
@@ -431,8 +431,8 @@ proc getFile[T](ftp: FtpBase[T], async = false): bool =
     var bytesRead = 0
     var returned = false
     if async:
-      when T is TSocket:
-        raise newException(EFTP, "FTPClient must be async.")
+      when T is Socket:
+        raise newException(FTPError, "FTPClient must be async.")
       else:
         bytesRead = ftp.dsock.recvAsync(r, BufferSize)
         returned = bytesRead != -1
@@ -447,9 +447,9 @@ proc getFile[T](ftp: FtpBase[T], async = false): bool =
     elif returned and r2 == "":
       ftp.dsockConnected = false
 
-  when T is TSocket:
+  when T is Socket:
     if not async:
-      var readSocks: seq[TSocket] = @[ftp.csock]
+      var readSocks: seq[Socket] = @[ftp.csock]
       blockingOperation(ftp.csock):
         if readSocks.select(1) != 0 and ftp.csock in readSocks:
           assertReply ftp.expectReply(), "226"
@@ -467,10 +467,10 @@ proc retrFile*[T](ftp: FtpBase[T], file, dest: string, async = false) =
   var reply = ftp.send("RETR " & file.normalizePathSep)
   assertReply reply, ["125", "150"]
   if {'(', ')'} notin reply.string:
-    raise newException(EInvalidReply, "Reply has no file size.")
+    raise newException(ReplyError, "Reply has no file size.")
   var fileSize: BiggestInt
   if reply.string.captureBetween('(', ')').parseBiggestInt(fileSize) == 0:
-    raise newException(EInvalidReply, "Reply has no file size.")
+    raise newException(ReplyError, "Reply has no file size.")
     
   ftp.job.total = fileSize
   ftp.job.lastProgressReport = epochTime()
@@ -545,10 +545,10 @@ proc close*[T](ftp: FtpBase[T]) =
   ftp.csock.close()
   ftp.dsock.close()
 
-proc csockHandleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) =
+proc csockHandleRead(s: AsyncSocket, ftp: AsyncFTPClient) =
   if ftp.jobInProgress:
     assertReply ftp.expectReply(), "226" # Make sure the transfer completed.
-    var r: TFTPEvent
+    var r: FTPEvent
     case ftp.job.typ
     of JRetrText:
       r.typ = EvLines
@@ -557,21 +557,21 @@ proc csockHandleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) =
       r.typ = EvRetr
       r.filename = ftp.job.filename
       if ftp.job.progress != ftp.job.total:
-        raise newException(EFTP, "Didn't download full file.")
+        raise newException(FTPError, "Didn't download full file.")
     of JStore:
       r.typ = EvStore
       r.filename = ftp.job.filename
       if ftp.job.progress != ftp.job.total:
-        raise newException(EFTP, "Didn't upload full file.")
+        raise newException(FTPError, "Didn't upload full file.")
     ftp.deleteJob()
     
     ftp.handleEvent(ftp, r)
 
-proc asyncFTPClient*(address: string, port = TPort(21),
+proc asyncFTPClient*(address: string, port = Port(21),
                      user, pass = "",
-    handleEvent: proc (ftp: PAsyncFTPClient, ev: TFTPEvent) {.closure,gcsafe.} = 
-      (proc (ftp: PAsyncFTPClient, ev: TFTPEvent) = discard)): PAsyncFTPClient =
-  ## Create a ``PAsyncFTPClient`` object.
+    handleEvent: proc (ftp: AsyncFTPClient, ev: FTPEvent) {.closure,gcsafe.} = 
+      (proc (ftp: AsyncFTPClient, ev: FTPEvent) = discard)): AsyncFTPClient =
+  ## Create a ``AsyncFTPClient`` object.
   ##
   ## Use this if you want to use asyncio's dispatcher.
   var dres: AsyncFtpClient
@@ -588,7 +588,7 @@ proc asyncFTPClient*(address: string, port = TPort(21),
       csockHandleRead(s, dres)
   result = dres
 
-proc register*(d: PDispatcher, ftp: PAsyncFTPClient): PDelegate {.discardable.} =
+proc register*(d: Dispatcher, ftp: AsyncFTPClient): Delegate {.discardable.} =
   ## Registers ``ftp`` with dispatcher ``d``.
   ftp.disp = d
   return ftp.disp.register(ftp.csock)
diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim
index e2cbb4949..5e4eba4e5 100644
--- a/lib/pure/htmlparser.nim
+++ b/lib/pure/htmlparser.nim
@@ -552,7 +552,7 @@ proc parse(x: var XmlParser, errors: var seq[string]): XmlNode =
 proc parseHtml*(s: Stream, filename: string, 
                 errors: var seq[string]): XmlNode = 
   ## parses the XML from stream `s` and returns a ``PXmlNode``. Every
-  ## occured parsing error is added to the `errors` sequence.
+  ## occurred parsing error is added to the `errors` sequence.
   var x: XmlParser
   open(x, s, filename, {reportComments, reportWhitespace})
   next(x)
@@ -581,7 +581,7 @@ proc parseHtml*(s: Stream): XmlNode =
 
 proc loadHtml*(path: string, errors: var seq[string]): XmlNode = 
   ## Loads and parses HTML from file specified by ``path``, and returns 
-  ## a ``PXmlNode``.  Every occured parsing error is added to
+  ## a ``PXmlNode``.  Every occurred parsing error is added to
   ## the `errors` sequence.
   var s = newFileStream(path, fmRead)
   if s == nil: raise newException(IOError, "Unable to read file: " & path)
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 3c1401887..37af14df3 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -385,7 +385,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "",
               userAgent = defUserAgent, proxy: Proxy = nil): Response =
   ## | Requests ``url`` with the custom method string specified by the
   ## | ``httpMethod`` parameter.
-  ## | Extra headers can be specified and must be seperated by ``\c\L``
+  ## | Extra headers can be specified and must be separated by ``\c\L``
   ## | An optional timeout can be specified in miliseconds, if reading from the
   ## server takes longer than specified an ETimeout exception will be raised.
   var r = if proxy == nil: parseUri(url) else: proxy.url
@@ -436,7 +436,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
               body = "", sslContext = defaultSSLContext, timeout = -1,
               userAgent = defUserAgent, proxy: Proxy = nil): Response =
   ## | Requests ``url`` with the specified ``httpMethod``.
-  ## | Extra headers can be specified and must be seperated by ``\c\L``
+  ## | Extra headers can be specified and must be separated by ``\c\L``
   ## | An optional timeout can be specified in miliseconds, if reading from the
   ## server takes longer than specified an ETimeout exception will be raised.
   result = request(url, $httpMethod, extraHeaders, body, sslContext, timeout, 
diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim
index 38a068ea1..5efdbe297 100644
--- a/lib/pure/httpserver.nim
+++ b/lib/pure/httpserver.nim
@@ -363,7 +363,7 @@ proc run*(handleRequest: proc (client: Socket,
           port = Port(80)) =
   ## encapsulates the server object and main loop
   var s: TServer
-  open(s, port)
+  open(s, port, reuseAddr = true)
   #echo("httpserver running on port ", s.port)
   while true:
     next(s)
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 873e4b78e..2038b246d 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -30,13 +30,32 @@
 ##
 ##   1.3000000000000000e+00
 ##   true
+##
+## This module can also be used to comfortably create JSON using the `%*`
+## operator:
+##
+## .. code-block:: nim
+##
+##   var hisName = "John"
+##   let herAge = 31
+##   var j = %*
+##     [
+##       {
+##         "name": hisName,
+##         "age": 30
+##       },
+##       {
+##         "name": "Susan",
+##         "age": herAge
+##       }
+##     ]
 
 import 
-  hashes, strutils, lexbase, streams, unicode
+  hashes, strutils, lexbase, streams, unicode, macros
 
 type 
   JsonEventKind* = enum  ## enumeration of all events that may occur when parsing
-    jsonError,           ## an error ocurred during parsing
+    jsonError,           ## an error occurred during parsing
     jsonEof,             ## end of file reached
     jsonString,          ## a string literal
     jsonInt,             ## an integer literal
@@ -625,6 +644,29 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
   newSeq(result.elems, elements.len)
   for i, p in pairs(elements): result.elems[i] = p
 
+proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
+  case x.kind
+  of nnkBracket:
+    result = newNimNode(nnkBracket)
+    for i in 0 .. <x.len:
+      result.add(toJson(x[i]))
+
+  of nnkTableConstr:
+    result = newNimNode(nnkTableConstr)
+    for i in 0 .. <x.len:
+      assert x[i].kind == nnkExprColonExpr
+      result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1])))
+
+  else:
+    result = x
+
+  result = prefix(result, "%")
+
+macro `%*`*(x: expr): expr =
+  ## Convert an expression to a JsonNode directly, without having to specify
+  ## `%` for every element.
+  result = toJson(x)
+
 proc `==`* (a,b: JsonNode): bool =
   ## Check two nodes for equality
   if a.isNil:
@@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string =
 proc `$`*(node: JsonNode): string =
   ## Converts `node` to its JSON Representation on one line.
   result = ""
-  toPretty(result, node, 1, false)
+  toPretty(result, node, 0, false)
 
 iterator items*(node: JsonNode): JsonNode =
   ## Iterator for the items of `node`. `node` has to be a JArray.
@@ -1101,6 +1143,37 @@ when isMainModule:
   except:
     assert(false, "EInvalidIndex thrown for valid index")
 
+  # Generator:
+  var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
+  assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
+  var j2 = %*
+    [
+      {
+        "name": "John",
+        "age": 30
+      },
+      {
+        "name": "Susan",
+        "age": 31
+      }
+    ]
+  assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
+  var name = "John"
+  let herAge = 30
+  const hisAge = 31
+
+  var j3 = %*
+    [ { "name": "John"
+      , "age": herAge
+      }
+    , { "name": "Susan"
+      , "age": hisAge
+      }
+    ]
+  assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
+
   discard """
   while true:
     var json = stdin.readLine()
diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim
index bb1835ed7..b64437c89 100644
--- a/lib/pure/logging.nim
+++ b/lib/pure/logging.nim
@@ -8,7 +8,7 @@
 #
 
 ## This module implements a simple logger. It has been designed to be as simple
-## as possible to avoid bloat, if this library does not fullfill your needs,
+## as possible to avoid bloat, if this library does not fulfill your needs,
 ## write your own.
 ## 
 ## Format strings support the following variables which must be prefixed with
@@ -186,7 +186,7 @@ proc newRollingFileLogger*(filename = defaultFilename(),
   ## a new log file will be started and the old will be renamed.
   new(result)
   result.levelThreshold = levelThreshold
-  result.fmtStr = defaultFmtStr
+  result.fmtStr = fmtStr
   result.maxLines = maxLines
   result.f = open(filename, mode)
   result.curLine = 0
diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim
index 1188be4ca..d55963c15 100644
--- a/lib/pure/matchers.nim
+++ b/lib/pure/matchers.nim
@@ -42,7 +42,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect,
   case toLower(x)
   of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name",
      "aero", "jobs", "museum": return true
-  return false
+  else: return false
 
 proc parseInt*(s: string, value: var int, validRange: Slice[int]) {.
   noSideEffect, rtl, extern: "nmatchParseInt".} =
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index b9e057e78..c902af381 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -93,9 +93,9 @@ proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
   result = x - 1 
   when defined(cpu64):
     result = result or (result shr 32)
-  when sizeof(int) > 16:
+  when sizeof(int) > 2:
     result = result or (result shr 16)
-  when sizeof(int) > 8:
+  when sizeof(int) > 1:
     result = result or (result shr 8)
   result = result or (result shr 4)
   result = result or (result shr 2)
@@ -129,25 +129,25 @@ proc variance*(x: openArray[float]): float {.noSideEffect.} =
     result = result + diff*diff
   result = result / toFloat(len(x))
 
-proc random*(max: int): int {.gcsafe.}
+proc random*(max: int): int {.benign.}
   ## returns a random number in the range 0..max-1. The sequence of
   ## random number is always the same, unless `randomize` is called
   ## which initializes the random number generator with a "random"
   ## number, i.e. a tickcount.
 
-proc random*(max: float): float {.gcsafe.}
+proc random*(max: float): float {.benign.}
   ## returns a random number in the range 0..<max. The sequence of
   ## random number is always the same, unless `randomize` is called
   ## which initializes the random number generator with a "random"
   ## number, i.e. a tickcount. This has a 16-bit resolution on windows
   ## and a 48-bit resolution on other platforms.
 
-proc randomize*() {.gcsafe.}
+proc randomize*() {.benign.}
   ## initializes the random number generator with a "random"
   ## number, i.e. a tickcount. Note: Does nothing for the JavaScript target,
   ## as JavaScript does not support this.
   
-proc randomize*(seed: int) {.gcsafe.}
+proc randomize*(seed: int) {.benign.}
   ## initializes the random number generator with a specific seed.
   ## Note: Does nothing for the JavaScript target,
   ## as JavaScript does not support this.
@@ -280,7 +280,7 @@ proc random*[T](x: Slice[T]): T =
   ## For a slice `a .. b` returns a value in the range `a .. b-1`.
   result = random(x.b - x.a) + x.a
 
-proc random[T](a: openArray[T]): T =
+proc random*[T](a: openArray[T]): T =
   ## returns a random element from the openarray `a`.
   result = a[random(a.low..a.len)]
 
@@ -329,6 +329,31 @@ proc standardDeviation*(s: RunningStat): float =
 {.pop.}
 {.pop.}
 
+proc `^`*[T](x, y: T): T =
+  ## Computes ``x`` to the power ``y`. ``x`` must be non-negative, use
+  ## `pow <#pow,float,float>` for negative exponents.
+  assert y >= 0
+  var (x, y) = (x, y)
+  result = 1
+
+  while y != 0:
+    if (y and 1) != 0:
+      result *= x
+    y = y shr 1
+    x *= x
+
+proc gcd*[T](x, y: T): T =
+  ## Computes the greatest common divisor of ``x`` and ``y``.
+  var (x,y) = (x,y)
+  while y != 0:
+    x = x mod y
+    swap x, y
+  abs x
+
+proc lcm*[T](x, y: T): T =
+  ## Computes the least common multiple of ``x`` and ``y``.
+  x div gcd(x, y) * y
+
 when isMainModule and not defined(JS):
   proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
 
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 4eacfea78..bed751542 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -60,7 +60,8 @@ type
         sslHasPeekChar: bool
         sslPeekChar: char
       of false: nil
-  
+    lastError: OSErrorCode ## stores the last error on this socket
+
   Socket* = ref SocketImpl
 
   SOBool* = enum ## Boolean socket options.
@@ -231,6 +232,15 @@ when defined(ssl):
     if SSLSetFd(socket.sslHandle, socket.fd) != 1:
       raiseSSLError()
 
+proc getSocketError*(socket: Socket): OSErrorCode =
+  ## Checks ``osLastError`` for a valid error. If it has been reset it uses
+  ## the last error stored in the socket object.
+  result = osLastError()
+  if result == 0.OSErrorCode:
+    result = socket.lastError
+  if result == 0.OSErrorCode:
+    raise newException(OSError, "No valid socket error code available")
+
 proc socketError*(socket: Socket, err: int = -1, async = false,
                   lastError = (-1).OSErrorCode) =
   ## Raises an OSError based on the error code returned by ``SSLGetError``
@@ -258,7 +268,7 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
         of SSL_ERROR_WANT_X509_LOOKUP:
           raiseSSLError("Function for x509 lookup has been called.")
         of SSL_ERROR_SYSCALL:
-          var errStr = "IO error has occured "
+          var errStr = "IO error has occurred "
           let sslErr = ErrPeekLastError()
           if sslErr == 0 and err == 0:
             errStr.add "because an EOF was observed that violates the protocol"
@@ -276,7 +286,7 @@ proc socketError*(socket: Socket, err: int = -1, async = false,
         else: raiseSSLError("Unknown Error")
   
   if err == -1 and not (when defined(ssl): socket.isSSL else: false):
-    let lastE = if lastError.int == -1: osLastError() else: lastError
+    var lastE = if lastError.int == -1: getSocketError(socket) else: lastError
     if async:
       when useWinVersion:
         if lastE.int32 == WSAEWOULDBLOCK:
@@ -294,7 +304,8 @@ proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
   ## queue of pending connections.
   ##
   ## Raises an EOS error upon failure.
-  if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError())
+  if rawsockets.listen(socket.fd, backlog) < 0'i32:
+    raiseOSError(osLastError())
 
 proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
   tags: [ReadIOEffect].} =
@@ -321,7 +332,8 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
     dealloc(aiList)
 
 proc acceptAddr*(server: Socket, client: var Socket, address: var string,
-                 flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} =
+                 flags = {SocketFlag.SafeDisconn}) {.
+                 tags: [ReadIOEffect], gcsafe, locks: 0.} =
   ## Blocks until a connection is being made from a client. When a connection
   ## is made sets ``client`` to the client socket and ``address`` to the address
   ## of the connecting client.
@@ -442,6 +454,8 @@ proc close*(socket: Socket) =
         # shutdown i.e not wait for the peers "close notify" alert with a second
         # call to SSLShutdown
         let res = SSLShutdown(socket.sslHandle)
+        SSLFree(socket.sslHandle)
+        socket.sslHandle = nil
         if res == 0:
           discard
         elif res != 1:
@@ -568,6 +582,10 @@ proc readIntoBuf(socket: Socket, flags: int32): int =
       result = recv(socket.fd, addr(socket.buffer), cint(socket.buffer.high), flags)
   else:
     result = recv(socket.fd, addr(socket.buffer), cint(socket.buffer.high), flags)
+  if result < 0:
+    # Save it in case it gets reset (the Nim codegen occassionally may call
+    # Win API functions which reset it).
+    socket.lastError = osLastError()
   if result <= 0:
     socket.bufLen = 0
     socket.currPos = 0
@@ -623,6 +641,9 @@ proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect]
         result = recv(socket.fd, data, size.cint, 0'i32)
     else:
       result = recv(socket.fd, data, size.cint, 0'i32)
+    if result < 0:
+      # Save the error in case it gets reset.
+      socket.lastError = osLastError()
 
 proc waitFor(socket: Socket, waited: var float, timeout, size: int,
              funcName: string): int {.tags: [TimeEffect].} =
@@ -695,7 +716,7 @@ proc recv*(socket: Socket, data: var string, size: int, timeout = -1,
   result = recv(socket, cstring(data), size, timeout)
   if result < 0:
     data.setLen(0)
-    let lastError = osLastError()
+    let lastError = getSocketError(socket)
     if flags.isDisconnectionError(lastError): return
     socket.socketError(result, lastError = lastError)
   data.setLen(result)
@@ -743,7 +764,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
       line.add("\c\L")
 
   template raiseSockError(): stmt {.dirty, immediate.} =
-    let lastError = osLastError()
+    let lastError = getSocketError(socket)
     if flags.isDisconnectionError(lastError): setLen(line.string, 0); return
     socket.socketError(n, lastError = lastError)
 
@@ -886,7 +907,7 @@ proc connectAsync(socket: Socket, name: string, port = Port(0),
                   af: Domain = AF_INET) {.tags: [ReadIOEffect].} =
   ## A variant of ``connect`` for non-blocking sockets.
   ##
-  ## This procedure will immediatelly return, it will not block until a connection
+  ## This procedure will immediately return, it will not block until a connection
   ## is made. It is up to the caller to make sure the connection has been established
   ## by checking (using ``select``) whether the socket is writeable.
   ##
@@ -938,8 +959,12 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int,
         doAssert socket.handshake()
   socket.fd.setBlocking(true)
 
-proc isSsl*(socket: Socket): bool = return socket.isSSL
+proc isSsl*(socket: Socket): bool = 
   ## Determines whether ``socket`` is a SSL socket.
+  when defined(ssl):
+    result = socket.isSSL
+  else:
+    result = false
 
 proc getFd*(socket: Socket): SocketHandle = return socket.fd
   ## Returns the socket's file descriptor
diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim
index 3598cdd3a..cce2a20ae 100644
--- a/lib/pure/nimprof.nim
+++ b/lib/pure/nimprof.nim
@@ -132,7 +132,7 @@ else:
   proc hook(st: TStackTrace) {.nimcall.} =
     if interval == 0:
       hookAux(st, 1)
-    elif getTicks() - t0 > interval:
+    elif int64(t0) == 0 or getTicks() - t0 > interval:
       hookAux(st, 1)
       t0 = getTicks()
 
diff --git a/lib/pure/nimprof.nimrod.cfg b/lib/pure/nimprof.nim.cfg
index 1589e7394..1589e7394 100644
--- a/lib/pure/nimprof.nimrod.cfg
+++ b/lib/pure/nimprof.nim.cfg
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 147614d3d..bf581667b 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -185,7 +185,7 @@ const
 proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
   ## Retrieves the operating system's error flag, ``errno``.
   ## On Windows ``GetLastError`` is checked before ``errno``.
-  ## Returns "" if no error occured.
+  ## Returns "" if no error occurred.
   ##
   ## **Deprecated since version 0.9.4**: use the other ``osErrorMsg`` proc.
 
@@ -1010,8 +1010,16 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
 proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
   tags: [ReadIOEffect, WriteIOEffect].} =
   ## Moves a file from `source` to `dest`. If this fails, `OSError` is raised.
-  if c_rename(source, dest) != 0'i32:
-    raise newException(OSError, $strerror(errno))
+  when defined(Windows):
+    when useWinUnicode:
+      let s = newWideCString(source)
+      let d = newWideCString(dest)
+      if moveFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError())
+    else:
+      if moveFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError())
+  else:
+    if c_rename(source, dest) != 0'i32:
+      raise newException(OSError, $strerror(errno))
 
 when not declared(ENOENT) and not defined(Windows):
   when NoFakeVars:
@@ -1074,8 +1082,12 @@ when defined(windows):
   # because we support Windows GUI applications, things get really
   # messy here...
   when useWinUnicode:
-    proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
-      importc: "wcschr", header: "<string.h>".}
+    when defined(cpp):
+      proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
+        importcpp: "(NI16*)wcschr((const wchar_t *)#, #)", header: "<string.h>".}
+    else:
+      proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
+        importc: "wcschr", header: "<string.h>".}
   else:
     proc strEnd(cstr: cstring, c = 0'i32): cstring {.
       importc: "strchr", header: "<string.h>".}
@@ -1087,7 +1099,7 @@ when defined(windows):
         var
           env = getEnvironmentStringsW()
           e = env
-        if e == nil: return # an error occured
+        if e == nil: return # an error occurred
         while true:
           var eend = strEnd(e)
           add(environment, $e)
@@ -1098,7 +1110,7 @@ when defined(windows):
         var
           env = getEnvironmentStringsA()
           e = env
-        if e == nil: return # an error occured
+        if e == nil: return # an error occurred
         while true:
           var eend = strEnd(e)
           add(environment, $e)
@@ -1170,7 +1182,7 @@ proc putEnv*(key, val: string) {.tags: [WriteEnvEffect].} =
   ## If an error occurs, `EInvalidEnvVar` is raised.
 
   # Note: by storing the string in the environment sequence,
-  # we gurantee that we don't free the memory before the program
+  # we guarantee that we don't free the memory before the program
   # ends (this is needed for POSIX compliance). It is also needed so that
   # the process itself may access its modified environment variables!
   var indx = findEnvVar(key)
@@ -1287,8 +1299,16 @@ iterator walkDir*(dir: string): tuple[kind: PathComponent, path: string] {.
         if y != "." and y != "..":
           var s: TStat
           y = dir / y
-          if lstat(y, s) < 0'i32: break
           var k = pcFile
+
+          when defined(linux) or defined(macosx) or defined(bsd):
+            if x.d_type != DT_UNKNOWN:
+              if x.d_type == DT_DIR: k = pcDir
+              if x.d_type == DT_LNK: k = succ(k)
+              yield (k, y)
+              continue
+
+          if lstat(y, s) < 0'i32: break
           if S_ISDIR(s.st_mode): k = pcDir
           if S_ISLNK(s.st_mode): k = succ(k)
           yield (k, y)
@@ -1335,7 +1355,7 @@ proc rawRemoveDir(dir: string) =
     if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError())
 
 proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
-  WriteDirEffect, ReadDirEffect].} =
+  WriteDirEffect, ReadDirEffect], benign.} =
   ## Removes the directory `dir` including all subdirectories and files
   ## in `dir` (recursively).
   ##
@@ -1381,7 +1401,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} =
   rawCreateDir(dir)
 
 proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
-  tags: [WriteIOEffect, ReadIOEffect].} =
+  tags: [WriteIOEffect, ReadIOEffect], benign.} =
   ## Copies a directory from `source` to `dest`.
   ##
   ## If this fails, `OSError` is raised. On the Windows platform this proc will
@@ -1442,7 +1462,7 @@ proc createHardlink*(src, dest: string) =
 proc parseCmdLine*(c: string): seq[string] {.
   noSideEffect, rtl, extern: "nos$1".} =
   ## Splits a command line into several components;
-  ## This proc is only occassionally useful, better use the `parseopt` module.
+  ## This proc is only occasionally useful, better use the `parseopt` module.
   ##
   ## On Windows, it uses the following parsing rules
   ## (see http://msdn.microsoft.com/en-us/library/17w5ykft.aspx ):
@@ -1554,7 +1574,7 @@ proc copyFileWithPermissions*(source, dest: string,
 
 proc copyDirWithPermissions*(source, dest: string,
     ignorePermissionErrors = true) {.rtl, extern: "nos$1",
-    tags: [WriteIOEffect, ReadIOEffect].} =
+    tags: [WriteIOEffect, ReadIOEffect], benign.} =
   ## Copies a directory from `source` to `dest` preserving file permissions.
   ##
   ## If this fails, `OSError` is raised. This is a wrapper proc around `copyDir()
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 6361dfb09..cd3700019 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -146,7 +146,7 @@ proc startProcess*(command: string,
   ## of `args` to `command` carefully escaping/quoting any special characters,
   ## since it will be passed *as is* to the system shell. Each system/shell may
   ## feature different escaping rules, so try to avoid this kind of shell
-  ## invokation if possible as it leads to non portable software.
+  ## invocation if possible as it leads to non portable software.
   ##
   ## Return value: The newly created process object. Nil is never returned,
   ## but ``EOS`` is raised in case of an error.
@@ -260,7 +260,7 @@ proc execProcesses*(cmds: openArray[string],
     for i in 0..m-1:
       if beforeRunEvent != nil:
         beforeRunEvent(i)
-      q[i] = startCmd(cmds[i], options=options)
+      q[i] = startProcess(cmds[i], options=options + {poEvalCommand})
     when defined(noBusyWaiting):
       var r = 0
       for i in m..high(cmds):
@@ -275,7 +275,7 @@ proc execProcesses*(cmds: openArray[string],
         if q[r] != nil: close(q[r])
         if beforeRunEvent != nil:
           beforeRunEvent(i)
-        q[r] = startCmd(cmds[i], options=options)
+        q[r] = startProcess(cmds[i], options=options + {poEvalCommand})
         r = (r + 1) mod n
     else:
       var i = m
@@ -288,7 +288,7 @@ proc execProcesses*(cmds: openArray[string],
             if q[r] != nil: close(q[r])
             if beforeRunEvent != nil:
               beforeRunEvent(i)
-            q[r] = startCmd(cmds[i], options=options)
+            q[r] = startProcess(cmds[i], options=options + {poEvalCommand})
             inc(i)
             if i > high(cmds): break
     for j in 0..m-1:
@@ -298,7 +298,7 @@ proc execProcesses*(cmds: openArray[string],
     for i in 0..high(cmds):
       if beforeRunEvent != nil:
         beforeRunEvent(i)
-      var p = startCmd(cmds[i], options=options)
+      var p = startProcess(cmds[i], options=options + {poEvalCommand})
       result = max(waitForExit(p), result)
       close(p)
 
@@ -644,14 +644,14 @@ elif not defined(useNimRtl):
     var pid: TPid
 
     var sysArgs = allocCStringArray(sysArgsRaw)
-    finally: deallocCStringArray(sysArgs)
+    defer: deallocCStringArray(sysArgs)
 
     var sysEnv = if env == nil:
         envToCStringArray()
       else:
         envToCStringArray(env)
 
-    finally: deallocCStringArray(sysEnv)
+    defer: deallocCStringArray(sysEnv)
 
     var data: TStartProcessData
     data.sysCommand = sysCommand
@@ -748,7 +748,7 @@ elif not defined(useNimRtl):
     if pipe(data.pErrorPipe) != 0:
       raiseOSError(osLastError())
 
-    finally:
+    defer:
       discard close(data.pErrorPipe[readIdx])
 
     var pid: TPid
@@ -956,7 +956,7 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
                 exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect], gcsafe.} =
   ## a convenience proc that runs the `command`, grabs all its output and
   ## exit code and returns both.
-  var p = startCmd(command, options)
+  var p = startProcess(command, options=options + {poEvalCommand})
   var outp = outputStream(p)
   result = (TaintedString"", -1)
   var line = newStringOfCap(120).TaintedString
diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim
index bb9d2aed2..bb64c8134 100644
--- a/lib/pure/parsecfg.nim
+++ b/lib/pure/parsecfg.nim
@@ -35,7 +35,7 @@ type
     cfgSectionStart,    ## a ``[section]`` has been parsed
     cfgKeyValuePair,    ## a ``key=value`` pair has been detected
     cfgOption,          ## a ``--key=value`` command line option
-    cfgError            ## an error ocurred during parsing
+    cfgError            ## an error occurred during parsing
     
   CfgEvent* = object of RootObj ## describes a parsing event
     case kind*: CfgEventKind    ## the kind of the event
diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim
index b1e2444c3..4c92a7cdf 100644
--- a/lib/pure/parseopt.nim
+++ b/lib/pure/parseopt.nim
@@ -11,9 +11,12 @@
 ## It supports one convenience iterator over all command line options and some
 ## lower-level features.
 ##
-## **Deprecated since version 0.9.3:** Use the `parseopt2 <parseopt2.html>`_
-## module instead as this version has issues with spaces in arguments.
-{.deprecated.}
+## Supported syntax:
+##
+## 1. short options - ``-abcd``, where a, b, c, d are names
+## 2. long option - ``--foo:bar``, ``--foo=bar`` or ``--foo``
+## 3. argument - everything else
+
 {.push debugger: off.}
 
 include "system/inclrtl"
diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim
index 8ed519fa4..73b498fe0 100644
--- a/lib/pure/parseopt2.nim
+++ b/lib/pure/parseopt2.nim
@@ -60,7 +60,7 @@ proc initOptParser*(cmdline: string): OptParser {.rtl, deprecated.} =
   ## Initalizes option parses with cmdline. Splits cmdline in on spaces
   ## and calls initOptParser(openarray[string])
   ## Do not use.
-  if cmdline == "": # backward compatibilty
+  if cmdline == "": # backward compatibility
     return initOptParser(seq[string](nil))
   else:
     return initOptParser(cmdline.split)
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 2c677fdc2..eb649a878 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -181,7 +181,7 @@ proc parseWhile*(s: string, token: var string, validChars: set[char],
   token = substr(s, start, i-1)
 
 proc captureBetween*(s: string, first: char, second = '\0', start = 0): string =
-  ## Finds the first occurence of ``first``, then returns everything from there
+  ## Finds the first occurrence of ``first``, then returns everything from there
   ## up to ``second``(if ``second`` is '\0', then ``first`` is used).
   var i = skipUntil(s, first, start)+1+start
   result = ""
@@ -240,7 +240,7 @@ proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
 proc parseFloat*(s: string, number: var float, start = 0): int {.
   rtl, extern: "npuParseFloat", noSideEffect.} =
   ## parses a float starting at `start` and stores the value into `number`.
-  ## Result is the number of processed chars or 0 if there occured a parsing
+  ## Result is the number of processed chars or 0 if there occurred a parsing
   ## error.
   var bf: BiggestFloat
   result = parseBiggestFloat(s, bf, start)
diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim
index 39dead3c0..b957c0cf7 100644
--- a/lib/pure/parsexml.nim
+++ b/lib/pure/parsexml.nim
@@ -57,7 +57,7 @@ import
 
 type 
   XmlEventKind* = enum ## enumation of all events that may occur when parsing
-    xmlError,           ## an error ocurred during parsing
+    xmlError,           ## an error occurred during parsing
     xmlEof,             ## end of file reached
     xmlCharData,        ## character data
     xmlWhitespace,      ## whitespace has been parsed
diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim
new file mode 100644
index 000000000..04aa8316a
--- /dev/null
+++ b/lib/pure/rationals.nim
@@ -0,0 +1,275 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Dennis Felsing
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+
+## This module implements rational numbers, consisting of a numerator `num` and
+## a denominator `den`, both of type int. The denominator can not be 0.
+
+import math
+
+type Rational*[T] = object
+  ## a rational number, consisting of a numerator and denominator
+  num*, den*: T
+
+proc initRational*[T](num, den: T): Rational[T] =
+  ## Create a new rational number.
+  result.num = num
+  result.den = den
+
+proc `//`*[T](num, den: T): Rational[T] = initRational[T](num, den)
+  ## A friendlier version of `initRational`. Example usage:
+  ##
+  ## .. code-block:: nim
+  ##   var x = 1//3 + 1//5
+
+proc `$`*[T](x: Rational[T]): string =
+  ## Turn a rational number into a string.
+  result = $x.num & "/" & $x.den
+
+proc toRational*[T](x: SomeInteger): Rational[T] =
+  ## Convert some integer `x` to a rational number.
+  result.num = x
+  result.den = 1
+
+proc toFloat*[T](x: Rational[T]): float =
+  ## Convert a rational number `x` to a float.
+  x.num / x.den
+
+proc toInt*[T](x: Rational[T]): int =
+  ## Convert a rational number `x` to an int. Conversion rounds towards 0 if
+  ## `x` does not contain an integer value.
+  x.num div x.den
+
+proc reduce*[T](x: var Rational[T]) =
+  ## Reduce rational `x`.
+  let common = gcd(x.num, x.den)
+  if x.den > 0:
+    x.num = x.num div common
+    x.den = x.den div common
+  elif x.den < 0:
+    x.num = -x.num div common
+    x.den = -x.den div common
+  else:
+    raise newException(DivByZeroError, "division by zero")
+
+proc `+` *[T](x, y: Rational[T]): Rational[T] =
+  ## Add two rational numbers.
+  let common = lcm(x.den, y.den)
+  result.num = common div x.den * x.num + common div y.den * y.num
+  result.den = common
+  reduce(result)
+
+proc `+` *[T](x: Rational[T], y: T): Rational[T] =
+  ## Add rational `x` to int `y`.
+  result.num = x.num + y * x.den
+  result.den = x.den
+
+proc `+` *[T](x: T, y: Rational[T]): Rational[T] =
+  ## Add int `x` to rational `y`.
+  result.num = x * y.den + y.num
+  result.den = y.den
+
+proc `+=` *[T](x: var Rational[T], y: Rational[T]) =
+  ## Add rational `y` to rational `x`.
+  let common = lcm(x.den, y.den)
+  x.num = common div x.den * x.num + common div y.den * y.num
+  x.den = common
+  reduce(x)
+
+proc `+=` *[T](x: var Rational[T], y: T) =
+  ## Add int `y` to rational `x`.
+  x.num += y * x.den
+
+proc `-` *[T](x: Rational[T]): Rational[T] =
+  ## Unary minus for rational numbers.
+  result.num = -x.num
+  result.den = x.den
+
+proc `-` *[T](x, y: Rational[T]): Rational[T] =
+  ## Subtract two rational numbers.
+  let common = lcm(x.den, y.den)
+  result.num = common div x.den * x.num - common div y.den * y.num
+  result.den = common
+  reduce(result)
+
+proc `-` *[T](x: Rational[T], y: T): Rational[T] =
+  ## Subtract int `y` from rational `x`.
+  result.num = x.num - y * x.den
+  result.den = x.den
+
+proc `-` *[T](x: T, y: Rational[T]): Rational[T] =
+  ## Subtract rational `y` from int `x`.
+  result.num = - x * y.den + y.num
+  result.den = y.den
+
+proc `-=` *[T](x: var Rational[T], y: Rational[T]) =
+  ## Subtract rational `y` from rational `x`.
+  let common = lcm(x.den, y.den)
+  x.num = common div x.den * x.num - common div y.den * y.num
+  x.den = common
+  reduce(x)
+
+proc `-=` *[T](x: var Rational[T], y: T) =
+  ## Subtract int `y` from rational `x`.
+  x.num -= y * x.den
+
+proc `*` *[T](x, y: Rational[T]): Rational[T] =
+  ## Multiply two rational numbers.
+  result.num = x.num * y.num
+  result.den = x.den * y.den
+  reduce(result)
+
+proc `*` *[T](x: Rational[T], y: T): Rational[T] =
+  ## Multiply rational `x` with int `y`.
+  result.num = x.num * y
+  result.den = x.den
+  reduce(result)
+
+proc `*` *[T](x: T, y: Rational[T]): Rational[T] =
+  ## Multiply int `x` with rational `y`.
+  result.num = x * y.num
+  result.den = y.den
+  reduce(result)
+
+proc `*=` *[T](x: var Rational[T], y: Rational[T]) =
+  ## Multiply rationals `y` to `x`.
+  x.num *= y.num
+  x.den *= y.den
+  reduce(x)
+
+proc `*=` *[T](x: var Rational[T], y: T) =
+  ## Multiply int `y` to rational `x`.
+  x.num *= y
+  reduce(x)
+
+proc reciprocal*[T](x: Rational[T]): Rational[T] =
+  ## Calculate the reciprocal of `x`. (1/x)
+  if x.num > 0:
+    result.num = x.den
+    result.den = x.num
+  elif x.num < 0:
+    result.num = -x.den
+    result.den = -x.num
+  else:
+    raise newException(DivByZeroError, "division by zero")
+
+proc `/`*[T](x, y: Rational[T]): Rational[T] =
+  ## Divide rationals `x` by `y`.
+  result.num = x.num * y.den
+  result.den = x.den * y.num
+  reduce(result)
+
+proc `/`*[T](x: Rational[T], y: T): Rational[T] =
+  ## Divide rational `x` by int `y`.
+  result.num = x.num
+  result.den = x.den * y
+  reduce(result)
+
+proc `/`*[T](x: T, y: Rational[T]): Rational[T] =
+  ## Divide int `x` by Rational `y`.
+  result.num = x * y.den
+  result.den = y.num
+  reduce(result)
+
+proc `/=`*[T](x: var Rational[T], y: Rational[T]) =
+  ## Divide rationals `x` by `y` in place.
+  x.num *= y.den
+  x.den *= y.num
+  reduce(x)
+
+proc `/=`*[T](x: var Rational[T], y: T) =
+  ## Divide rational `x` by int `y` in place.
+  x.den *= y
+  reduce(x)
+
+proc cmp*(x, y: Rational): int =
+  ## Compares two rationals.
+  (x - y).num
+
+proc `<` *(x, y: Rational): bool =
+  (x - y).num < 0
+
+proc `<=` *(x, y: Rational): bool =
+  (x - y).num <= 0
+
+proc `==` *(x, y: Rational): bool =
+  (x - y).num == 0
+
+proc abs*[T](x: Rational[T]): Rational[T] =
+  result.num = abs x.num
+  result.den = abs x.den
+
+when isMainModule:
+  var
+    z = Rational[int](num: 0, den: 1)
+    o = initRational(num=1, den=1)
+    a = initRational(1, 2)
+    b = -1 // -2
+    m1 = -1 // 1
+    tt = 10 // 2
+
+  assert( a     == a )
+  assert( (a-a) == z )
+  assert( (a+b) == o )
+  assert( (a/b) == o )
+  assert( (a*b) == 1 // 4 )
+  assert( (3/a) == 6 // 1 )
+  assert( (a/3) == 1 // 6 )
+  assert( a*b   == 1 // 4 )
+  assert( tt*z  == z )
+  assert( 10*a  == tt )
+  assert( a*10  == tt )
+  assert( tt/10 == a  )
+  assert( a-m1  == 3 // 2 )
+  assert( a+m1  == -1 // 2 )
+  assert( m1+tt == 16 // 4 )
+  assert( m1-tt == 6 // -1 )
+
+  assert( z < o )
+  assert( z <= o )
+  assert( z == z )
+  assert( cmp(z, o) < 0 )
+  assert( cmp(o, z) > 0 )
+
+  assert( o == o )
+  assert( o >= o )
+  assert( not(o > o) )
+  assert( cmp(o, o) == 0 )
+  assert( cmp(z, z) == 0 )
+
+  assert( a == b )
+  assert( a >= b )
+  assert( not(b > a) )
+  assert( cmp(a, b) == 0 )
+
+  var x = 1//3
+
+  x *= 5//1
+  assert( x == 5//3 )
+  x += 2 // 9
+  assert( x == 17//9 )
+  x -= 9//18
+  assert( x == 25//18 )
+  x /= 1//2
+  assert( x == 50//18 )
+
+  var y = 1//3
+
+  y *= 4
+  assert( y == 4//3 )
+  y += 5
+  assert( y == 19//3 )
+  y -= 2
+  assert( y == 13//3 )
+  y /= 9
+  assert( y == 13//27 )
+
+  assert toRational[int, int](5) == 5//1
+  assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
+  assert toInt(z) == 0
diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim
index 995dff2aa..4cc64a154 100644
--- a/lib/pure/ropes.nim
+++ b/lib/pure/ropes.nim
@@ -43,7 +43,7 @@ proc isConc(r: Rope): bool {.inline.} = return isNil(r.data)
 # Note that the left and right pointers are not needed for leafs.
 # Leaves have relatively high memory overhead (~30 bytes on a 32
 # bit machine) and we produce many of them. This is why we cache and
-# share leafs accross different rope trees.
+# share leafs across different rope trees.
 # To cache them they are inserted in another tree, a splay tree for best
 # performance. But for the caching tree we use the leaf's left and right
 # pointers.
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index bd2564937..b6bc9dd3a 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -35,7 +35,7 @@ type
 when defined(nimdoc):
   type
     Selector* = ref object
-      ## An object which holds file descripters to be checked for read/write
+      ## An object which holds file descriptors to be checked for read/write
       ## status.
       fds: Table[SocketHandle, SelectorKey]
 
@@ -48,12 +48,21 @@ when defined(nimdoc):
                events: set[Event]): SelectorKey {.discardable.} =
     ## Updates the events which ``fd`` wants notifications for.
 
+  proc unregister*(s: Selector, fd: SocketHandle): SelectorKey {.discardable.} =
+    ## Unregisters file descriptor ``fd`` from selector ``s``.
+
+  proc close*(s: Selector) =
+    ## Closes the selector
+
   proc select*(s: Selector, timeout: int): seq[ReadyInfo] =
     ## The ``events`` field of the returned ``key`` contains the original events
     ## for which the ``fd`` was bound. This is contrary to the ``events`` field
     ## of the ``TReadyInfo`` tuple which determines which events are ready
     ## on the ``fd``.
 
+  proc newSelector*(): Selector =
+    ## Creates a new selector
+
   proc contains*(s: Selector, fd: SocketHandle): bool =
     ## Determines whether selector contains a file descriptor.
 
@@ -78,8 +87,6 @@ elif defined(linux):
   
   proc register*(s: Selector, fd: SocketHandle, events: set[Event],
       data: RootRef): SelectorKey {.discardable.} =
-    ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent
-    ## ``events``.
     var event = createEventStruct(events, fd)
     if events != {}:
       if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
@@ -92,7 +99,6 @@ elif defined(linux):
   
   proc update*(s: Selector, fd: SocketHandle,
       events: set[Event]): SelectorKey {.discardable.} =
-    ## Updates the events which ``fd`` wants notifications for.
     if s.fds[fd].events != events:
       if events == {}:
         # This fd is idle -- it should not be registered to epoll.
@@ -204,7 +210,6 @@ elif not defined(nimdoc):
 
   proc update*(s: Selector, fd: SocketHandle,
       events: set[Event]): SelectorKey {.discardable.} =
-    ## Updates the events which ``fd`` wants notifications for.
     if not s.fds.hasKey(fd):
       raise newException(ValueError, "File descriptor not found.")
 
@@ -299,7 +304,7 @@ when isMainModule and not defined(nimdoc):
       sock: Socket
   
   var sock = socket()
-  if sock == sockets.InvalidSocket: raiseOSError(osLastError())
+  if sock == sockets.invalidSocket: raiseOSError(osLastError())
   #sock.setBlocking(false)
   sock.connect("irc.freenode.net", Port(6667))
   
diff --git a/lib/pure/smtp.nimrod.cfg b/lib/pure/smtp.nim.cfg
index 521e21de4..521e21de4 100644
--- a/lib/pure/smtp.nimrod.cfg
+++ b/lib/pure/smtp.nim.cfg
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index 11eeefcb9..3afb545c8 100644
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -657,6 +657,8 @@ proc close*(socket: Socket) =
   when defined(ssl):
     if socket.isSSL:
       discard SSLShutdown(socket.sslHandle)
+      SSLFree(socket.sslHandle)
+      socket.sslHandle = nil
 
 proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
   ## Searches the database from the beginning and finds the first entry for 
@@ -851,7 +853,7 @@ proc connectAsync*(socket: Socket, name: string, port = Port(0),
                      af: Domain = AF_INET) {.tags: [ReadIOEffect].} =
   ## A variant of ``connect`` for non-blocking sockets.
   ##
-  ## This procedure will immediatelly return, it will not block until a connection
+  ## This procedure will immediately return, it will not block until a connection
   ## is made. It is up to the caller to make sure the connection has been established
   ## by checking (using ``select``) whether the socket is writeable.
   ##
@@ -1467,7 +1469,7 @@ proc recvAsync*(socket: Socket, s: var TaintedString): bool {.
           of SSL_ERROR_ZERO_RETURN:
             raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.")
           of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
-            raiseSslError("Unexpected error occured.") # This should just not happen.
+            raiseSslError("Unexpected error occurred.") # This should just not happen.
           of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
             return false
           of SSL_ERROR_WANT_X509_LOOKUP:
@@ -1610,7 +1612,7 @@ proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} =
           of SSL_ERROR_ZERO_RETURN:
             raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.")
           of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT:
-            raiseSslError("Unexpected error occured.") # This should just not happen.
+            raiseSslError("Unexpected error occurred.") # This should just not happen.
           of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ:
             return 0
           of SSL_ERROR_WANT_X509_LOOKUP:
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index 55351ffd4..67c80e592 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -122,41 +122,41 @@ proc read[T](s: Stream, result: var T) =
     raise newEIO("cannot read from stream")
 
 proc readChar*(s: Stream): char =
-  ## reads a char from the stream `s`. Raises `EIO` if an error occured.
+  ## reads a char from the stream `s`. Raises `EIO` if an error occurred.
   ## Returns '\0' as an EOF marker.
   if readData(s, addr(result), sizeof(result)) != 1: result = '\0'
 
 proc readBool*(s: Stream): bool = 
-  ## reads a bool from the stream `s`. Raises `EIO` if an error occured.
+  ## reads a bool from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readInt8*(s: Stream): int8 = 
-  ## reads an int8 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads an int8 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readInt16*(s: Stream): int16 = 
-  ## reads an int16 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads an int16 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readInt32*(s: Stream): int32 = 
-  ## reads an int32 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads an int32 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readInt64*(s: Stream): int64 = 
-  ## reads an int64 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads an int64 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readFloat32*(s: Stream): float32 = 
-  ## reads a float32 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readFloat64*(s: Stream): float64 = 
-  ## reads a float64 from the stream `s`. Raises `EIO` if an error occured.
+  ## reads a float64 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
 
 proc readStr*(s: Stream, length: int): TaintedString = 
   ## reads a string of length `length` from the stream `s`. Raises `EIO` if 
-  ## an error occured.
+  ## an error occurred.
   result = newString(length).TaintedString
   var L = readData(s, addr(string(result)[0]), length)
   if L != length: setLen(result.string, L)
@@ -183,7 +183,7 @@ proc readLine*(s: Stream, line: var TaintedString): bool =
 
 proc readLine*(s: Stream): TaintedString =
   ## Reads a line from a stream `s`. Note: This is not very efficient. Raises 
-  ## `EIO` if an error occured.
+  ## `EIO` if an error occurred.
   result = TaintedString""
   while true:
     var c = readChar(s)
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 5b7149d8e..727d5a386 100644
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -112,7 +112,7 @@ proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} =
 proc mget*(t: StringTableRef, key: string): var string {.
              rtl, extern: "nstTake".} =
   ## retrieves the location at ``t[key]``. If `key` is not in `t`, the
-  ## ``EInvalidKey`` exception is raised.
+  ## ``KeyError`` exception is raised.
   var index = rawGet(t, key)
   if index >= 0: result = t.data[index].val
   else: raise newException(KeyError, "key does not exist: " & key)
@@ -158,7 +158,7 @@ proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string =
   else: result = ""
   if result.len == 0:
     if useKey in flags: result = '$' & key
-    elif not (useEmpty in flags): raiseFormatException(key)
+    elif useEmpty notin flags: raiseFormatException(key)
 
 proc newStringTable*(mode: StringTableMode): StringTableRef {.
   rtl, extern: "nst$1".} =
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index e17d99dc2..655203cda 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -395,11 +395,13 @@ proc toHex*(x: BiggestInt, len: int): string {.noSideEffect,
   const
     HexChars = "0123456789ABCDEF"
   var
-    shift: BiggestInt
+    n = x
   result = newString(len)
   for j in countdown(len-1, 0):
-    result[j] = HexChars[toU32(x shr shift) and 0xF'i32]
-    shift = shift + 4
+    result[j] = HexChars[n and 0xF]
+    n = n shr 4
+    # handle negative overflow
+    if n == 0 and x < 0: n = -1
 
 proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect,
   rtl, extern: "nsuIntToStr".} =
@@ -497,26 +499,47 @@ proc parseEnum*[T: enum](s: string, default: T): T =
       return e
   result = default
 
-proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect,
+proc repeat*(c: char, count: int): string {.noSideEffect,
   rtl, extern: "nsuRepeatChar".} =
   ## Returns a string of length `count` consisting only of
   ## the character `c`. You can use this proc to left align strings. Example:
   ##
   ## .. code-block:: nim
+  ##   proc tabexpand(indent: int, text: string, tabsize: int = 4) =
+  ##     echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize), text
+  ##
+  ##   tabexpand(4, "At four")
+  ##   tabexpand(5, "At five")
+  ##   tabexpand(6, "At six")
+  result = newString(count)
+  for i in 0..count-1: result[i] = c
+
+proc repeat*(s: string, n: int): string {.noSideEffect,
+  rtl, extern: "nsuRepeatStr".} =
+  ## Returns String `s` concatenated `n` times.  Example:
+  ##
+  ## .. code-block:: nim
+  ##   echo "+++ STOP ".repeat(4), "+++"
+  result = newStringOfCap(n * s.len)
+  for i in 1..n: result.add(s)
+
+template spaces*(n: int): string =  repeat(' ',n)
+  ## Returns a String with `n` space characters. You can use this proc
+  ## to left align strings. Example:
+  ##
+  ## .. code-block:: nim
   ##   let
   ##     width = 15
   ##     text1 = "Hello user!"
   ##     text2 = "This is a very long string"
-  ##   echo text1 & repeatChar(max(0, width - text1.len)) & "|"
-  ##   echo text2 & repeatChar(max(0, width - text2.len)) & "|"
-  result = newString(count)
-  for i in 0..count-1: result[i] = c
+  ##   echo text1 & spaces(max(0, width - text1.len)) & "|"
+  ##   echo text2 & spaces(max(0, width - text2.len)) & "|"
 
-proc repeatStr*(count: int, s: string): string {.noSideEffect,
-  rtl, extern: "nsuRepeatStr".} =
-  ## Returns `s` concatenated `count` times.
-  result = newStringOfCap(count*s.len)
-  for i in 0..count-1: result.add(s)
+proc repeatChar*(count: int, c: char = ' '): string {.deprecated.} = repeat(c, count)
+  ## deprecated: use repeat() or spaces()
+
+proc repeatStr*(count: int, s: string): string {.deprecated.} = repeat(s, count)
+  ## deprecated: use repeat(string, count) or string.repeat(count)
 
 proc align*(s: string, count: int, padding = ' '): string {.
   noSideEffect, rtl, extern: "nsuAlignString".} =
@@ -815,8 +838,8 @@ proc rfind*(s: string, sub: char, start: int = -1): int {.noSideEffect,
 
 proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect,
   rtl, extern: "nsuCountString".} =
-  ## Count the occurences of a substring `sub` in the string `s`.
-  ## Overlapping occurences of `sub` only count when `overlapping`
+  ## Count the occurrences of a substring `sub` in the string `s`.
+  ## Overlapping occurrences of `sub` only count when `overlapping`
   ## is set to true.
   var i = 0
   while true:
@@ -831,14 +854,14 @@ proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffe
 
 proc count*(s: string, sub: char): int {.noSideEffect,
   rtl, extern: "nsuCountChar".} =
-  ## Count the occurences of the character `sub` in the string `s`.
+  ## Count the occurrences of the character `sub` in the string `s`.
   for c in s:
     if c == sub:
       inc result
 
 proc count*(s: string, subs: set[char]): int {.noSideEffect,
   rtl, extern: "nsuCountCharSet".} =
-  ## Count the occurences of the group of character `subs` in the string `s`.
+  ## Count the occurrences of the group of character `subs` in the string `s`.
   for c in s:
     if c in subs:
       inc result
@@ -898,7 +921,7 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
   rtl, extern: "nsuReplaceWord".} =
   ## Replaces `sub` in `s` by the string `by`.
   ##
-  ## Each occurance of `sub` has to be surrounded by word boundaries
+  ## Each occurrence of `sub` has to be surrounded by word boundaries
   ## (comparable to ``\\w`` in regular expressions), otherwise it is not
   ## replaced.
   const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim
index adcfdd288..d701b85b1 100644
--- a/lib/pure/subexes.nim
+++ b/lib/pure/subexes.nim
@@ -353,11 +353,11 @@ when isMainModule:
 
   proc `%`(formatstr: string, a: openarray[string]): string =
     result = newStringOfCap(formatstr.len + a.len shl 4)
-    addf(result, formatstr.TSubex, a)
+    addf(result, formatstr.Subex, a)
 
   proc `%`(formatstr: string, a: string): string =
     result = newStringOfCap(formatstr.len + a.len)
-    addf(result, formatstr.TSubex, [a])
+    addf(result, formatstr.Subex, [a])
 
 
   doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index 8607066f3..e0e2aa247 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -45,6 +45,21 @@ when defined(windows):
   var
     oldAttr = getAttributes()
 
+  proc winGetch(): cint {.header: "<conio.h>", importc: "_getch".}
+else:
+  import termios, unsigned
+
+  proc setRaw(fd: FileHandle, time: cint = TCSAFLUSH) =
+    var mode: Termios
+    discard fd.tcgetattr(addr mode)
+    mode.iflag = mode.iflag and not Tcflag(BRKINT or ICRNL or INPCK or ISTRIP or IXON)
+    mode.oflag = mode.oflag and not Tcflag(OPOST)
+    mode.cflag = (mode.cflag and not Tcflag(CSIZE or PARENB)) or CS8
+    mode.lflag = mode.lflag and not Tcflag(ECHO or ICANON or IEXTEN or ISIG)
+    mode.cc[VMIN] = 1.cuchar
+    mode.cc[VTIME] = 0.cuchar
+    discard fd.tcsetattr(time, addr mode)
+
 proc setCursorPos*(x, y: int) =
   ## sets the terminal's cursor to the (x,y) position. (0,0) is the
   ## upper left of the screen.
@@ -349,6 +364,19 @@ macro styledEcho*(m: varargs[expr]): stmt =
   result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
   result.add(newCall(bindSym"resetAttributes"))
 
+proc getch*(): char =
+  ## Read a single character from the terminal, blocking until it is entered.
+  ## The character is not printed to the terminal.
+  when defined(windows):
+    result = winGetch().char
+  else:
+    let fd = getFileHandle(stdin)
+    var oldMode: Termios
+    discard fd.tcgetattr(addr oldMode)
+    fd.setRaw()
+    result = stdin.readChar()
+    discard fd.tcsetattr(TCSADRAIN, addr oldMode)
+
 when isMainModule:
   system.addQuitProc(resetAttributes)
   write(stdout, "never mind")
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 1cabd381b..e32ea786a 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -16,7 +16,7 @@
                       # of the standard library!
 
 import
-  strutils
+  strutils, parseutils
 
 include "system/inclrtl"
 
@@ -63,44 +63,44 @@ elif defined(windows):
 elif defined(JS):
   type
     Time* {.importc.} = object
-      getDay: proc (): int {.tags: [], raises: [], gcsafe.}
-      getFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      getHours: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
-      getMonth: proc (): int {.tags: [], raises: [], gcsafe.}
-      getSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getTime: proc (): int {.tags: [], raises: [], gcsafe.}
-      getTimezoneOffset: proc (): int {.tags: [], raises: [], gcsafe.}
-      getDate: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCDate: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCFullYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCHours: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMilliseconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMinutes: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCMonth: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.}
-      getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.}
-      getYear: proc (): int {.tags: [], raises: [], gcsafe.}
-      parse: proc (s: cstring): Time {.tags: [], raises: [], gcsafe.}
-      setDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setTime: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCDate: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCHours: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMinutes: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCMonth: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setUTCSeconds: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      setYear: proc (x: int) {.tags: [], raises: [], gcsafe.}
-      toGMTString: proc (): cstring {.tags: [], raises: [], gcsafe.}
-      toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.}
+      getDay: proc (): int {.tags: [], raises: [], benign.}
+      getFullYear: proc (): int {.tags: [], raises: [], benign.}
+      getHours: proc (): int {.tags: [], raises: [], benign.}
+      getMilliseconds: proc (): int {.tags: [], raises: [], benign.}
+      getMinutes: proc (): int {.tags: [], raises: [], benign.}
+      getMonth: proc (): int {.tags: [], raises: [], benign.}
+      getSeconds: proc (): int {.tags: [], raises: [], benign.}
+      getTime: proc (): int {.tags: [], raises: [], benign.}
+      getTimezoneOffset: proc (): int {.tags: [], raises: [], benign.}
+      getDate: proc (): int {.tags: [], raises: [], benign.}
+      getUTCDate: proc (): int {.tags: [], raises: [], benign.}
+      getUTCFullYear: proc (): int {.tags: [], raises: [], benign.}
+      getUTCHours: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMilliseconds: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMinutes: proc (): int {.tags: [], raises: [], benign.}
+      getUTCMonth: proc (): int {.tags: [], raises: [], benign.}
+      getUTCSeconds: proc (): int {.tags: [], raises: [], benign.}
+      getUTCDay: proc (): int {.tags: [], raises: [], benign.}
+      getYear: proc (): int {.tags: [], raises: [], benign.}
+      parse: proc (s: cstring): Time {.tags: [], raises: [], benign.}
+      setDate: proc (x: int) {.tags: [], raises: [], benign.}
+      setFullYear: proc (x: int) {.tags: [], raises: [], benign.}
+      setHours: proc (x: int) {.tags: [], raises: [], benign.}
+      setMilliseconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setMinutes: proc (x: int) {.tags: [], raises: [], benign.}
+      setMonth: proc (x: int) {.tags: [], raises: [], benign.}
+      setSeconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setTime: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCDate: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCFullYear: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCHours: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMilliseconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMinutes: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCMonth: proc (x: int) {.tags: [], raises: [], benign.}
+      setUTCSeconds: proc (x: int) {.tags: [], raises: [], benign.}
+      setYear: proc (x: int) {.tags: [], raises: [], benign.}
+      toGMTString: proc (): cstring {.tags: [], raises: [], benign.}
+      toLocaleString: proc (): cstring {.tags: [], raises: [], benign.}
 
 type
   TimeInfo* = object of RootObj ## represents a time in different parts
@@ -139,42 +139,42 @@ type
 {.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time,
     TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].}
 
-proc getTime*(): Time {.tags: [TimeEffect], gcsafe.}
+proc getTime*(): Time {.tags: [TimeEffect], benign.}
   ## gets the current calendar time as a UNIX epoch value (number of seconds
   ## elapsed since 1970) with integer precission. Use epochTime for higher
   ## resolution.
-proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.}
   ## converts the calendar time `t` to broken-time representation,
   ## expressed relative to the user's specified time zone.
-proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], benign.}
   ## converts the calendar time `t` to broken-down time representation,
   ## expressed in Coordinated Universal Time (UTC).
 
-proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], gcsafe.}
+proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], benign.}
   ## converts a broken-down time structure to
   ## calendar time representation. The function ignores the specified
   ## contents of the structure members `weekday` and `yearday` and recomputes
   ## them from the other information in the broken-down time structure.
 
-proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], gcsafe.}
+proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], benign.}
   ## Takes a float which contains the number of seconds since the unix epoch and
   ## returns a time object.
 
-proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], gcsafe.} = 
+proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], benign.} = 
   ## Takes an int which contains the number of seconds since the unix epoch and
   ## returns a time object.
   fromSeconds(float(since1970))
 
-proc toSeconds*(time: Time): float {.tags: [], raises: [], gcsafe.}
+proc toSeconds*(time: Time): float {.tags: [], raises: [], benign.}
   ## Returns the time in seconds since the unix epoch.
 
-proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], gcsafe.}
+proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], benign.}
   ## converts a `TimeInfo` object to a string representation.
-proc `$` *(time: Time): string {.tags: [], raises: [], gcsafe.}
+proc `$` *(time: Time): string {.tags: [], raises: [], benign.}
   ## converts a calendar time to a string representation.
 
 proc `-`*(a, b: Time): int64 {.
-  rtl, extern: "ntDiffTime", tags: [], raises: [].}
+  rtl, extern: "ntDiffTime", tags: [], raises: [], benign.}
   ## computes the difference of two calendar times. Result is in seconds.
 
 proc `<`*(a, b: Time): bool {.
@@ -194,14 +194,14 @@ proc `==`*(a, b: Time): bool {.
 
 when not defined(JS):
   proc getTzname*(): tuple[nonDST, DST: string] {.tags: [TimeEffect], raises: [],
-    gcsafe.}
+    benign.}
     ## returns the local timezone; ``nonDST`` is the name of the local non-DST
     ## timezone, ``DST`` is the name of the local DST timezone.
 
-proc getTimezone*(): int {.tags: [TimeEffect], raises: [], gcsafe.}
+proc getTimezone*(): int {.tags: [TimeEffect], raises: [], benign.}
   ## returns the offset of the local (non-DST) timezone in seconds west of UTC.
 
-proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.}
+proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], benign.}
   ## get the miliseconds from the start of the program. **Deprecated since
   ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead.
 
@@ -744,6 +744,285 @@ proc format*(info: TimeInfo, f: string): string =
 
 {.pop.}
 
+proc parseToken(info: var TimeInfo; token, value: string; j: var int) =
+  ## Helper of the parse proc to parse individual tokens.
+  var sv: int
+  case token
+  of "d":
+    var pd = parseInt(value[j..j+1], sv)
+    info.monthday = sv
+    j += pd
+  of "dd":
+    info.monthday = value[j..j+1].parseInt()
+    j += 2
+  of "ddd":
+    case value[j..j+2].toLower():
+    of "sun":
+      info.weekday = dSun
+    of "mon":
+      info.weekday = dMon
+    of "tue":
+      info.weekday = dTue
+    of "wed":
+      info.weekday = dWed
+    of "thu":
+      info.weekday = dThu
+    of "fri":
+      info.weekday = dFri
+    of "sat":
+      info.weekday = dSat
+    else:
+      raise newException(ValueError, "invalid day of week ")
+    j += 3
+  of "dddd":
+    if value.len >= j+6 and value[j..j+5].cmpIgnoreCase("sunday") == 0:
+      info.weekday = dSun
+      j += 6
+    elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("monday") == 0:
+      info.weekday = dMon
+      j += 6
+    elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("tuesday") == 0:
+      info.weekday = dTue
+      j += 7
+    elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("wednesday") == 0:
+      info.weekday = dWed
+      j += 9
+    elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("thursday") == 0:
+      info.weekday = dThu
+      j += 8
+    elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("friday") == 0:
+      info.weekday = dFri
+      j += 6
+    elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("saturday") == 0:
+      info.weekday = dSat
+      j += 8
+    else:
+      raise newException(ValueError, "invalid day of week ")    
+  of "h", "H":
+    var pd = parseInt(value[j..j+1], sv)
+    info.hour = sv
+    j += pd
+  of "hh", "HH":
+    info.hour = value[j..j+1].parseInt()
+    j += 2
+  of "m":
+    var pd = parseInt(value[j..j+1], sv)
+    info.minute = sv
+    j += pd
+  of "mm":
+    info.minute = value[j..j+1].parseInt()
+    j += 2
+  of "M":
+    var pd = parseInt(value[j..j+1], sv)
+    info.month = Month(sv-1)
+    info.monthday = sv
+    j += pd
+  of "MM":
+    var month = value[j..j+1].parseInt()
+    j += 2
+    info.month = Month(month-1)
+  of "MMM":
+    case value[j..j+2].toLower():
+    of "jan":
+      info.month =  mJan
+    of "feb":
+      info.month =  mFeb
+    of "mar":
+      info.month =  mMar
+    of "apr":
+      info.month =  mApr
+    of "may":
+      info.month =  mMay
+    of "jun":
+      info.month =  mJun
+    of "jul":
+      info.month =  mJul
+    of "aug":
+      info.month =  mAug
+    of "sep":
+      info.month =  mSep
+    of "oct":
+      info.month =  mOct
+    of "nov":
+      info.month =  mNov
+    of "dec":
+      info.month =  mDec
+    else:
+      raise newException(ValueError, "invalid month") 
+    j += 3
+  of "MMMM":
+    if value.len >= j+7 and value[j..j+6].cmpIgnoreCase("january") == 0:
+      info.month =  mJan
+      j += 7
+    elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("february") == 0:
+      info.month =  mFeb
+      j += 8
+    elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("march") == 0:
+      info.month =  mMar
+      j += 5
+    elif value.len >= j+5 and value[j..j+4].cmpIgnoreCase("april") == 0:
+      info.month =  mApr
+      j += 5
+    elif value.len >= j+3 and value[j..j+2].cmpIgnoreCase("may") == 0:
+      info.month =  mMay
+      j += 3
+    elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("june") == 0:
+      info.month =  mJun
+      j += 4
+    elif value.len >= j+4 and value[j..j+3].cmpIgnoreCase("july") == 0:
+      info.month =  mJul
+      j += 4
+    elif value.len >= j+6 and value[j..j+5].cmpIgnoreCase("august") == 0:
+      info.month =  mAug
+      j += 6
+    elif value.len >= j+9 and value[j..j+8].cmpIgnoreCase("september") == 0:
+      info.month =  mSep
+      j += 9
+    elif value.len >= j+7 and value[j..j+6].cmpIgnoreCase("october") == 0:
+      info.month =  mOct
+      j += 7
+    elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("november") == 0:
+      info.month =  mNov
+      j += 8
+    elif value.len >= j+8 and value[j..j+7].cmpIgnoreCase("december") == 0:
+      info.month =  mDec
+      j += 8
+    else:
+      raise newException(ValueError, "invalid month") 
+  of "s":
+    var pd = parseInt(value[j..j+1], sv)
+    info.second = sv
+    j += pd
+  of "ss":
+    info.second = value[j..j+1].parseInt()
+    j += 2
+  of "t":
+    if value[j] == 'P' and info.hour > 0 and info.hour < 12:
+      info.hour += 12
+    j += 1
+  of "tt":
+    if value[j..j+1] == "PM" and info.hour > 0 and info.hour < 12:
+      info.hour += 12
+    j += 2
+  of "yy":
+    # Assumes current century
+    var year = value[j..j+1].parseInt()
+    var thisCen = getLocalTime(getTime()).year div 100
+    info.year = thisCen*100 + year
+    j += 2
+  of "yyyy":
+    info.year = value[j..j+3].parseInt()
+    j += 4
+  of "z":
+    if value[j] == '+':
+      info.timezone = parseInt($value[j+1])
+    elif value[j] == '-':
+      info.timezone = 0-parseInt($value[j+1])
+    else:
+      raise newException(ValueError, "Sign for timezone " & value[j])
+    j += 2
+  of "zz":
+    if value[j] == '+':
+      info.timezone = value[j+1..j+2].parseInt()
+    elif value[j] == '-':
+      info.timezone = 0-value[j+1..j+2].parseInt()
+    else:
+      raise newException(ValueError, "Sign for timezone " & value[j])
+    j += 3
+  of "zzz":
+    if value[j] == '+':
+      info.timezone = value[j+1..j+2].parseInt()
+    elif value[j] == '-':
+      info.timezone = 0-value[j+1..j+2].parseInt()
+    else:
+      raise newException(ValueError, "Sign for timezone " & value[j])
+    j += 6
+  of "ZZZ":
+    info.tzname = value[j..j+2].toUpper()
+    j += 3
+  else:
+    # Ignore the token and move forward in the value string by the same length
+    j += token.len
+    
+proc parse*(value, layout: string): TimeInfo =
+  ## This function parses a date/time string using the standard format identifiers (below)
+  ## The function defaults information not provided in the format string from the running program (timezone, month, year, etc)
+  ##
+  ## ==========  =================================================================================  ================================================
+  ## Specifier   Description                                                                        Example
+  ## ==========  =================================================================================  ================================================
+  ##    d        Numeric value of the day of the month, it will be one or two digits long.          ``1/04/2012 -> 1``, ``21/04/2012 -> 21``
+  ##    dd       Same as above, but always two digits.                                              ``1/04/2012 -> 01``, ``21/04/2012 -> 21``
+  ##    ddd      Three letter string which indicates the day of the week.                           ``Saturday -> Sat``, ``Monday -> Mon``
+  ##    dddd     Full string for the day of the week.                                               ``Saturday -> Saturday``, ``Monday -> Monday``
+  ##    h        The hours in one digit if possible. Ranging from 0-12.                             ``5pm -> 5``, ``2am -> 2``
+  ##    hh       The hours in two digits always. If the hour is one digit 0 is prepended.           ``5pm -> 05``, ``11am -> 11``
+  ##    H        The hours in one digit if possible, randing from 0-24.                             ``5pm -> 17``, ``2am -> 2``
+  ##    HH       The hours in two digits always. 0 is prepended if the hour is one digit.           ``5pm -> 17``, ``2am -> 02``
+  ##    m        The minutes in 1 digit if possible.                                                ``5:30 -> 30``, ``2:01 -> 1``
+  ##    mm       Same as above but always 2 digits, 0 is prepended if the minute is one digit.      ``5:30 -> 30``, ``2:01 -> 01``
+  ##    M        The month in one digit if possible.                                                ``September -> 9``, ``December -> 12``
+  ##    MM       The month in two digits always. 0 is prepended.                                    ``September -> 09``, ``December -> 12``
+  ##    MMM      Abbreviated three-letter form of the month.                                        ``September -> Sep``, ``December -> Dec``
+  ##    MMMM     Full month string, properly capitalized.                                           ``September -> September``
+  ##    s        Seconds as one digit if possible.                                                  ``00:00:06 -> 6``
+  ##    ss       Same as above but always two digits. 0 is prepended.                               ``00:00:06 -> 06``
+  ##    t        ``A`` when time is in the AM. ``P`` when time is in the PM.
+  ##    tt       Same as above, but ``AM`` and ``PM`` instead of ``A`` and ``P`` respectively.
+  ##    yy       Displays the year to two digits.                                                   ``2012 -> 12``
+  ##    yyyy     Displays the year to four digits.                                                  ``2012 -> 2012``
+  ##    z        Displays the timezone offset from UTC.                                             ``GMT+7 -> +7``, ``GMT-5 -> -5``
+  ##    zz       Same as above but with leading 0.                                                  ``GMT+7 -> +07``, ``GMT-5 -> -05``
+  ##    zzz      Same as above but with ``:00``.                                                    ``GMT+7 -> +07:00``, ``GMT-5 -> -05:00``
+  ##    ZZZ      Displays the name of the timezone.                                                 ``GMT -> GMT``, ``EST -> EST``
+  ## ==========  =================================================================================  ================================================
+  ##
+  ## Other strings can be inserted by putting them in ``''``. For example
+  ## ``hh'->'mm`` will give ``01->56``.  The following characters can be
+  ## inserted without quoting them: ``:`` ``-`` ``(`` ``)`` ``/`` ``[`` ``]``
+  ## ``,``. However you don't need to necessarily separate format specifiers, a
+  ## unambiguous format string like ``yyyyMMddhhmmss`` is valid too.    
+  var i = 0 # pointer for format string
+  var j = 0 # pointer for value string
+  var token = ""
+  # Assumes current day of month, month and year, but time is reset to 00:00:00. Weekday will be reset after parsing.
+  var info = getLocalTime(getTime())
+  info.hour = 0
+  info.minute = 0
+  info.second = 0
+  while true:
+    case layout[i]
+    of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',':
+      if token.len > 0:
+        parseToken(info, token, value, j)
+      # Reset token
+      token = ""
+      # Break if at end of line
+      if layout[i] == '\0': break
+      # Skip separator and everything between single quotes
+      # These are literals in both the layout and the value string
+      if layout[i] == '\'':
+        inc(i)
+        inc(j)
+        while layout[i] != '\'' and layout.len-1 > i:
+          inc(i)
+          inc(j)
+      else:
+        inc(i)
+        inc(j)
+    else:
+      # Check if the letter being added matches previous accumulated buffer.
+      if token.len < 1 or token[high(token)] == layout[i]:
+        token.add(layout[i])
+        inc(i)
+      else:
+        parseToken(info, token, value, j)
+        token = ""
+  # Reset weekday as it might not have been provided and the default may be wrong
+  info.weekday = getLocalTime(timeInfoToTime(info)).weekday
+  return info
+
+
 when isMainModule:
   # $ date --date='@2147483647'
   # Tue 19 Jan 03:14:07 GMT 2038
@@ -778,3 +1057,51 @@ when isMainModule:
   # Interval tests
   assert((t4 - initInterval(years = 2)).format("yyyy") == "1995")
   assert((t4 - initInterval(years = 7, minutes = 34, seconds = 24)).format("yyyy mm ss") == "1990 24 10")
+
+  var s = "Tuesday at 09:04am on Dec 15, 2015"
+  var f = "dddd at hh:mmtt on MMM d, yyyy"
+  assert($s.parse(f) == "Tue Dec 15 09:04:00 2015")
+  # ANSIC       = "Mon Jan _2 15:04:05 2006"
+  s = "Mon Jan 2 15:04:05 2006"
+  f = "ddd MMM d HH:mm:ss yyyy"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
+  s = "Mon Jan 2 15:04:05 MST 2006"
+  f = "ddd MMM d HH:mm:ss ZZZ yyyy"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
+  s = "Mon Jan 02 15:04:05 -07:00 2006"
+  f = "ddd MMM dd HH:mm:ss zzz yyyy"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RFC822      = "02 Jan 06 15:04 MST"
+  s = "02 Jan 06 15:04 MST"
+  f = "dd MMM yy HH:mm ZZZ"
+  assert($s.parse(f) == "Mon Jan  2 15:04:00 2006")
+  # RFC822Z     = "02 Jan 06 15:04 -0700" # RFC822 with numeric zone
+  s = "02 Jan 06 15:04 -07:00"
+  f = "dd MMM yy HH:mm zzz"
+  assert($s.parse(f) == "Mon Jan  2 15:04:00 2006")
+  # RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
+  s = "Monday, 02-Jan-06 15:04:05 MST"
+  f = "dddd, dd-MMM-yy HH:mm:ss ZZZ"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
+  s = "Mon, 02 Jan 2006 15:04:05 MST"
+  f = "ddd, dd MMM yyyy HH:mm:ss ZZZ"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" # RFC1123 with numeric zone
+  s = "Mon, 02 Jan 2006 15:04:05 -07:00"
+  f = "ddd, dd MMM yyyy HH:mm:ss zzz"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RFC3339     = "2006-01-02T15:04:05Z07:00"
+  s = "2006-01-02T15:04:05Z-07:00"
+  f = "yyyy-MM-ddTHH:mm:ssZzzz"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
+  s = "2006-01-02T15:04:05.999999999Z-07:00"
+  f = "yyyy-MM-ddTHH:mm:ss.999999999Zzzz"
+  assert($s.parse(f) == "Mon Jan  2 15:04:05 2006")
+  # Kitchen     = "3:04PM"
+  s = "3:04PM"
+  f = "h:mmtt"
+  echo "Kitchen: " & $s.parse(f)
\ No newline at end of file
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index b892ec8b4..42e6a3195 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -1235,11 +1235,12 @@ proc reversed*(s: string): string =
   ## returns the reverse of `s`, interpreting it as unicode characters. Unicode
   ## combining characters are correctly interpreted as well:
   ##
-  ## .. code-block:
+  ## .. code-block:: nim
+  ##
   ##   assert reversed("Reverse this!") == "!siht esreveR"
   ##   assert reversed("先秦兩漢") == "漢兩秦先"
   ##   assert reversed("as⃝df̅") == "f̅ds⃝a"
-  ## assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞"
+  ##   assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞"
   var
     i = 0
     lastI = 0
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index 8dc9fe0d4..f4e42ee63 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -39,6 +39,7 @@ when declared(stdout):
 
 when not defined(ECMAScript):
   import terminal
+  system.addQuitProc(resetAttributes)
 
 type
   TestStatus* = enum OK, FAILED
@@ -234,5 +235,3 @@ if envOutLvl.len > 0:
     if $opt == envOutLvl:
       outputLevel = opt
       break
-
-system.addQuitProc(resetAttributes)
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index 1627b6ca3..9a6e273a8 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -20,6 +20,7 @@ type
 
 {.deprecated: [TUrl: Url, TUri: Uri].}
 
+{.push warning[deprecated]: off.}
 proc `$`*(url: Url): string {.deprecated.} =
   ## **Deprecated since 0.9.6**: Use ``Uri`` instead.
   return string(url)
@@ -44,6 +45,7 @@ proc add*(url: var Url, a: Url) {.deprecated.} =
   ##
   ## **Deprecated since 0.9.6**: Use ``Uri`` instead.
   url = url / a
+{.pop.}
 
 proc parseAuthority(authority: string, result: var Uri) =
   var i = 0
@@ -182,10 +184,10 @@ proc combine*(base: Uri, reference: Uri): Uri =
   ##   assert foo.path == "/baz"
   ##
   ##   let bar = combine(parseUri("http://example.com/foo/bar"), parseUri("baz"))
-  ##   assert foo.path == "/foo/baz"
+  ##   assert bar.path == "/foo/baz"
   ##
   ##   let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
-  ##   assert foo.path == "/foo/bar/baz"
+  ##   assert bar.path == "/foo/bar/baz"
   
   template setAuthority(dest, src: expr): stmt =
     dest.hostname = src.hostname
@@ -239,10 +241,10 @@ proc `/`*(x: Uri, path: string): Uri =
   ##   assert foo.path == "/foo/bar/baz"
   ##
   ##   let bar = parseUri("http://example.com/foo/bar") / parseUri("baz")
-  ##   assert foo.path == "/foo/bar/baz"
+  ##   assert bar.path == "/foo/bar/baz"
   ##
   ##   let bar = parseUri("http://example.com/foo/bar/") / parseUri("baz")
-  ##   assert foo.path == "/foo/bar/baz"
+  ##   assert bar.path == "/foo/bar/baz"
   result = x
   if result.path[result.path.len-1] == '/':
     if path[0] == '/':
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 660932d92..2e55ff182 100644
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -642,7 +642,7 @@ proc isEmpty(s: string): bool =
   return true
 
 proc normalize*(n: PNode) =
-  ## Merges all seperated TextNodes together, and removes any empty TextNodes
+  ## Merges all separated TextNodes together, and removes any empty TextNodes
   var curTextNode: PNode = nil
   var i: int = 0
 
diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim
index 8591e894c..755bfcdbc 100644
--- a/lib/pure/xmlparser.nim
+++ b/lib/pure/xmlparser.nim
@@ -103,7 +103,7 @@ proc parse(x: var XmlParser, errors: var seq[string]): XmlNode =
 proc parseXml*(s: Stream, filename: string, 
                errors: var seq[string]): XmlNode = 
   ## parses the XML from stream `s` and returns a ``PXmlNode``. Every
-  ## occured parsing error is added to the `errors` sequence.
+  ## occurred parsing error is added to the `errors` sequence.
   var x: XmlParser
   open(x, s, filename, {reportComments})
   while true:
@@ -129,7 +129,7 @@ proc parseXml*(s: Stream): XmlNode =
 
 proc loadXml*(path: string, errors: var seq[string]): XmlNode =
   ## Loads and parses XML from file specified by ``path``, and returns 
-  ## a ``PXmlNode``. Every occured parsing error is added to the `errors`
+  ## a ``PXmlNode``. Every occurred parsing error is added to the `errors`
   ## sequence.
   var s = newFileStream(path, fmRead)
   if s == nil: raise newException(IOError, "Unable to read file: " & path)
diff --git a/lib/system.nim b/lib/system.nim
index 12c5c6303..abf31c821 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -73,7 +73,7 @@ type
   expr* {.magic: Expr.} ## meta type to denote an expression (for templates)
   stmt* {.magic: Stmt.} ## meta type to denote a statement (for templates)
   typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
-  void* {.magic: "VoidType".}   ## meta type to denote the absense of any type
+  void* {.magic: "VoidType".}   ## meta type to denote the absence of any type
   auto* = expr
   any* = distinct auto
 
@@ -124,7 +124,7 @@ proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.}
   ## feature or not:
   ##
   ## .. code-block:: Nim
-  ##   when not defined(strutils.toUpper):
+  ##   when not declared(strutils.toUpper):
   ##     # provide our own toUpper proc here, because strutils is
   ##     # missing it.
 
@@ -343,10 +343,10 @@ type
     ##
     ## Each exception has to inherit from `Exception`. See the full `exception
     ## hierarchy`_.
-    parent: ref Exception     ## parent exception (can be used as a stack)
-    name: cstring             ## The exception's name is its Nim identifier.
-                              ## This field is filled automatically in the
-                              ## ``raise`` statement.
+    parent*: ref Exception ## parent exception (can be used as a stack)
+    name: cstring ## The exception's name is its Nim identifier.
+                  ## This field is filled automatically in the
+                  ## ``raise`` statement.
     msg* {.exportc: "message".}: string ## the exception's message. Not
                                         ## providing an exception message 
                                         ## is bad style.
@@ -357,7 +357,7 @@ type
     ##
     ## See the full `exception hierarchy`_.
   IOError* = object of SystemError ## \
-    ## Raised if an IO error occured.
+    ## Raised if an IO error occurred.
     ##
     ## See the full `exception hierarchy`_.
   OSError* = object of SystemError ## \
@@ -370,11 +370,11 @@ type
     ##
     ## See the full `exception hierarchy`_.
   ResourceExhaustedError* = object of SystemError ## \
-    ## Raised if a resource request could not be fullfilled.
+    ## Raised if a resource request could not be fulfilled.
     ##
     ## See the full `exception hierarchy`_.
   ArithmeticError* = object of Exception ## \
-    ## Raised if any kind of arithmetic error occured.
+    ## Raised if any kind of arithmetic error occurred.
     ##
     ## See the full `exception hierarchy`_.
   DivByZeroError* = object of ArithmeticError ## \
@@ -578,7 +578,7 @@ proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.}
 proc len*[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.}
 proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}
   ## returns the length of an array, an openarray, a sequence or a string.
-  ## This is rougly the same as ``high(T)-low(T)+1``, but its resulting type is
+  ## This is roughly the same as ``high(T)-low(T)+1``, but its resulting type is
   ## always an int.
 
 # set routines:
@@ -865,7 +865,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
   ## passes its arguments in reverse order.
 
 proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} =
-  ## Checks if `value` is withing the range of `s`; returns true iff
+  ## Checks if `value` is within the range of `s`; returns true iff
   ## `value >= s.a and value <= s.b`
   ##
   ## .. code-block:: Nim
@@ -1455,7 +1455,8 @@ template `>%` *(x, y: expr): expr {.immediate.} = y <% x
 
 proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.}
   ## The stringify operator for an integer argument. Returns `x`
-  ## converted to a decimal string.
+  ## converted to a decimal string. ``$`` is Nim's general way of
+  ## spelling `toString`:idx:.
 
 proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
   ## The stringify operator for an integer argument. Returns `x`
@@ -2098,17 +2099,16 @@ when not defined(nimrodVM) and hostOS != "standalone":
     ## returns an informative string about the GC's activity. This may be useful
     ## for tweaking.
     
-  # XXX mark these as 'locks: 0' once 0.10.0 has been released
-  proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.}
-  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.}
-  proc GC_ref*(x: string) {.magic: "GCref", gcsafe.}
+  proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
+  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
+  proc GC_ref*(x: string) {.magic: "GCref", benign.}
     ## marks the object `x` as referenced, so that it will not be freed until
     ## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
     ## n calls to `GC_unref` are needed to unmark `x`. 
     
-  proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*(x: string) {.magic: "GCunref", gcsafe.}
+  proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
+  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
+  proc GC_unref*(x: string) {.magic: "GCunref", benign.}
     ## see the documentation of `GC_ref`.
 
 template accumulateResult*(iter: expr) =
@@ -2194,7 +2194,8 @@ elif hostOS != "standalone":
       inc(i)
   {.pop.}
 
-proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.}
+proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect],
+  benign, sideEffect.}
   ## Writes and flushes the parameters to the standard output.
   ##
   ## Special built-in that takes a variable number of arguments. Each argument
@@ -2247,14 +2248,9 @@ when not declared(sysFatal):
       e.msg = message & arg
       raise e
 
-when defined(nimlocks):
-  proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe, locks: 0.}
-    ## get type information for `x`. Ordinary code should not use this, but
-    ## the `typeinfo` module instead.
-else:
-  proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.}
-    ## get type information for `x`. Ordinary code should not use this, but
-    ## the `typeinfo` module instead.
+proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
+  ## get type information for `x`. Ordinary code should not use this, but
+  ## the `typeinfo` module instead.
 
 {.push stackTrace: off.}
 proc abs*(x: int): int {.magic: "AbsI", noSideEffect.} =
@@ -2454,19 +2450,15 @@ when not defined(JS): #and not defined(NimrodVM):
       ## Returns ``false`` if the end of the file has been reached, ``true``
       ## otherwise. If ``false`` is returned `line` contains no new data.
 
-    when not defined(booting):
-      proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
-                               tags: [WriteIOEffect], gcsafe, locks: 0.}
-        ## writes the values `x` to `f` and then writes "\n".
-        ## May throw an IO exception.
-    else:
-      proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
-                               tags: [WriteIOEffect].}
+    proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
+                             tags: [WriteIOEffect], benign.}
+      ## writes the values `x` to `f` and then writes "\n".
+      ## May throw an IO exception.
 
     proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.}
       ## retrieves the file size (in bytes) of `f`.
 
-    proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {.
+    proc readBytes*(f: File, a: var openArray[int8|uint8], start, len: int): int {.
       tags: [ReadIOEffect], benign.}
       ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
       ## the actual number of bytes that have been read which may be less than
@@ -2484,7 +2476,7 @@ when not defined(JS): #and not defined(NimrodVM):
       ## the actual number of bytes that have been read which may be less than
       ## `len` (if not as many bytes are remaining), but not greater.
 
-    proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {.
+    proc writeBytes*(f: File, a: openArray[int8|uint8], start, len: int): int {.
       tags: [WriteIOEffect], benign.}
       ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
       ## the number of actual written bytes, which may be less than `len` in case
@@ -2575,7 +2567,7 @@ when not defined(JS): #and not defined(NimrodVM):
     initAllocator()
   when hasThreadSupport:
     include "system/syslocks"
-    include "system/threads"
+    when hostOS != "standalone": include "system/threads"
   elif not defined(nogc) and not defined(NimrodVM) and hostOS != "standalone":
     when not defined(useNimRtl) and not defined(createNimRtl): initStackBottom()
     initGC()
@@ -3134,9 +3126,17 @@ proc shallow*(s: var string) {.noSideEffect, inline.} =
     s.reserved = s.reserved or seqShallowFlag
 
 type
-  TNimrodNode {.final.} = object
-  PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode
-    ## represents a Nim AST node. Macros operate on this type.
+  NimNodeObj = object
+
+when defined(nimnode):
+  type
+    NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
+      ## represents a Nim AST node. Macros operate on this type.
+  {.deprecated: [PNimrodNode: NimNode].}
+else:
+  type
+    PNimrodNode* {.magic: "PNimrodNode".} = ref NimNodeObj
+      ## represents a Nim AST node. Macros operate on this type.
 
 when false:
   template eval*(blk: stmt): stmt =
@@ -3160,7 +3160,7 @@ when hostOS != "standalone":
       x[j+i] = item[j]
       inc(j)
 
-proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} =
+proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
   ## Special compile-time procedure that checks whether `x` can be compiled
   ## without any semantic error.
   ## This can be used to check whether a type supports some operation:
diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim
index c4df287cf..f68e2dcd9 100644
--- a/lib/system/arithm.nim
+++ b/lib/system/arithm.nim
@@ -15,7 +15,7 @@ proc raiseOverflow {.compilerproc, noinline, noreturn.} =
   sysFatal(OverflowError, "over- or underflow")
 
 proc raiseDivByZero {.compilerproc, noinline, noreturn.} =
-  sysFatal(DivByZeroError, "divison by zero")
+  sysFatal(DivByZeroError, "division by zero")
 
 proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
   result = a +% b
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 429a92d34..78995954f 100644
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -27,7 +27,7 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
     var m = selectBranch(src, n)
     # reset if different branches are in use; note different branches also
     # imply that's not self-assignment (``x = x``)!
-    if m != dd and dd != nil: 
+    if m != dd and dd != nil:
       genericResetAux(dest, dd)
     copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
             n.typ.size)
@@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) =
   case mt.kind
   of tyString, tyRef, tySequence:
     unsureAsgnRef(cast[PPointer](dest), nil)
-  of tyObject, tyTuple:
-    # we don't need to reset m_type field for tyObject
+  of tyTuple:
+    genericResetAux(dest, mt.node)
+  of tyObject:
     genericResetAux(dest, mt.node)
+    # also reset the type field for tyObject, for correct branch switching!
+    var pint = cast[ptr PNimType](dest)
+    pint[] = nil
   of tyArray, tyArrayConstr:
     for i in 0..(mt.size div mt.base.size)-1:
       genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim
index 089846578..f3acc81f2 100644
--- a/lib/system/cgprocs.nim
+++ b/lib/system/cgprocs.nim
@@ -13,7 +13,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc, benign.}
 
 type
   TLibHandle = pointer       # private type
-  TProcAddr = pointer        # libary loading and loading of procs:
+  TProcAddr = pointer        # library loading and loading of procs:
 
 proc nimLoadLibrary(path: string): TLibHandle {.compilerproc.}
 proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index e0d99cf88..44f7b67c3 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -8,7 +8,7 @@
 #
 
 # This file implements the ability to call native procs from libraries.
-# It is not possible to do this in a platform independant way, unfortunately.
+# It is not possible to do this in a platform independent way, unfortunately.
 # However, the interface has been designed to take platform differences into
 # account and been ported to all major platforms.
 
@@ -80,15 +80,22 @@ elif defined(windows) or defined(dos):
   # Native Windows Implementation
   # =======================================================================
   #
-  type
-    THINSTANCE {.importc: "HINSTANCE".} = pointer
+  when defined(cpp):
+    type
+      THINSTANCE {.importc: "HINSTANCE".} = object
+        x: pointer
+    proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
+        importcpp: "(void*)GetProcAddress(@)", header: "<windows.h>", stdcall.}
+  else:
+    type
+      THINSTANCE {.importc: "HINSTANCE".} = pointer
+    proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
+        importc: "GetProcAddress", header: "<windows.h>", stdcall.}
 
   proc freeLibrary(lib: THINSTANCE) {.
       importc: "FreeLibrary", header: "<windows.h>", stdcall.}
   proc winLoadLibrary(path: cstring): THINSTANCE {.
       importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
-  proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
-      importc: "GetProcAddress", header: "<windows.h>", stdcall.}
 
   proc nimUnloadLibrary(lib: TLibHandle) =
     freeLibrary(cast[THINSTANCE](lib))
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 417a8634f..1b3471978 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -175,6 +175,8 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
       add(s, tempFrames[j].procname)
     add(s, "\n")
 
+proc stackTraceAvailable*(): bool
+
 when hasSomeStackTrace:
   proc rawWriteStackTrace(s: var string) =
     when NimStackTrace:
@@ -188,6 +190,18 @@ when hasSomeStackTrace:
       auxWriteStackTraceWithBacktrace(s)
     else:
       add(s, "No stack traceback available\n")
+  proc stackTraceAvailable(): bool =
+    when NimStackTrace:
+      if framePtr == nil:
+        result = false
+      else:
+        result = true
+    elif defined(nativeStackTrace) and nativeStackTraceSupported:
+      result = true
+    else:
+      result = false
+else:
+  proc stackTraceAvailable*(): bool = result = false
 
 proc quitOrDebug() {.inline.} =
   when not defined(endb):
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 844f28690..1f4279c8f 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -528,20 +528,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
   zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
           newsize-oldsize)
   sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
-  sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
-  #if res.refcount <% rcIncrement:
-  #  add(gch.zct, res)
-  #else: # XXX: what to do here?
-  #  decRef(ol)
-  if (ol.refcount and ZctFlag) != 0:
-    var j = gch.zct.len-1
-    var d = gch.zct.d
-    while j >= 0: 
-      if d[j] == ol:
-        d[j] = res
-        break
-      dec(j)
-  if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
+  # This can be wrong for intermediate temps that are nevertheless on the
+  # heap because of lambda lifting:
+  #gcAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
   when logGC:
     writeCell("growObj old cell", ol)
     writeCell("growObj new cell", res)
@@ -549,7 +538,26 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
   gcTrace(res, csAllocated)
   when reallyDealloc: 
     sysAssert(allocInv(gch.region), "growObj before dealloc")
-    rawDealloc(gch.region, ol)
+    if ol.refcount shr rcShift <=% 1:
+      # free immediately to save space:
+      if (ol.refcount and ZctFlag) != 0:
+        var j = gch.zct.len-1
+        var d = gch.zct.d
+        while j >= 0:
+          if d[j] == ol:
+            d[j] = res
+            break
+          dec(j)
+      if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
+      rawDealloc(gch.region, ol)
+    else:
+      # we split the old refcount in 2 parts. XXX This is still not entirely
+      # correct if the pointer that receives growObj's result is on the stack.
+      # A better fix would be to emit the location specific write barrier for
+      # 'growObj', but this is lost of more work and who knows what new problems
+      # this would create.
+      res.refcount = rcIncrement
+      decRef(ol)
   else:
     sysAssert(ol.typ != nil, "growObj: 5")
     zeroMem(ol, sizeof(TCell))
@@ -876,7 +884,7 @@ elif stackIncreases:
   var
     jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
       # a little hack to get the size of a TJmpBuf in the generated C code
-      # in a platform independant way
+      # in a platform independent way
 
   template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} =
     var registers: C_JmpBuf
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim
index b0173b78f..ae2d2c85d 100644
--- a/lib/system/gc2.nim
+++ b/lib/system/gc2.nim
@@ -128,7 +128,7 @@ type
                              # cycle roots table that uses a cheap linear scan
                              # to find only possitively dead objects.
                              # One strategy is to perform it only for new objects
-                             # allocated between the invocations of CollectZCT.
+                             # allocated between the invocations of collectZCT.
                              # This index indicates the start of the range of
                              # such new objects within the table.
     when withRealTime:
@@ -140,7 +140,7 @@ var
   gch* {.rtlThreadVar.}: TGcHeap
 
 when not defined(useNimRtl):
-  InstantiateForRegion(gch.region)
+  instantiateForRegion(gch.region)
 
 template acquire(gch: TGcHeap) = 
   when hasThreadSupport and hasSharedHeap:
@@ -233,11 +233,11 @@ template addCycleRoot(cycleRoots: var TCellSeq, c: PCell) =
 
 proc cellToUsr(cell: PCell): pointer {.inline.} =
   # convert object (=pointer to refcount) to pointer to userdata
-  result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
+  result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell)))
 
 proc usrToCell*(usr: pointer): PCell {.inline.} =
   # convert pointer to userdata to object (=pointer to refcount)
-  result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
+  result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell)))
 
 proc canbeCycleRoot(c: PCell): bool {.inline.} =
   result = ntfAcyclic notin c.typ.flags
@@ -255,10 +255,10 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
 
 # forward declarations:
 proc collectCT(gch: var TGcHeap)
-proc IsOnStack*(p: pointer): bool {.noinline.}
+proc isOnStack*(p: pointer): bool {.noinline.}
 proc forAllChildren(cell: PCell, op: TWalkOp)
 proc doOperation(p: pointer, op: TWalkOp)
-proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
+proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp)
 # we need the prototype here for debugging purposes
 
 proc prepareDealloc(cell: PCell) =
@@ -432,7 +432,7 @@ proc nimGCunrefNoCycle(p: pointer) {.compilerProc, inline.} =
     sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 2")
   sysAssert(allocInv(gch.region), "end nimGCunrefNoCycle 5")
 
-template doAsgnRef(dest: ppointer, src: pointer,
+template doAsgnRef(dest: PPointer, src: pointer,
                   heapType = LocalHeap, cycleFlag = MaybeCyclic): stmt =
   sysAssert(not isOnStack(dest), "asgnRef")
   # BUGFIX: first incRef then decRef!
@@ -440,20 +440,20 @@ template doAsgnRef(dest: ppointer, src: pointer,
   if dest[] != nil: doDecRef(usrToCell(dest[]), heapType, cycleFlag)
   dest[] = src
 
-proc asgnRef(dest: ppointer, src: pointer) {.compilerProc, inline.} =
+proc asgnRef(dest: PPointer, src: pointer) {.compilerProc, inline.} =
   # the code generator calls this proc!
   doAsgnRef(dest, src, LocalHeap, MaybeCyclic)
 
-proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerProc, inline.} =
+proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerProc, inline.} =
   # the code generator calls this proc if it is known at compile time that no 
   # cycle is possible.
   doAsgnRef(dest, src, LocalHeap, Acyclic)
 
-proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerProc.} =
+proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerProc.} =
   # unsureAsgnRef updates the reference counters only if dest is not on the
   # stack. It is used by the code generator if it cannot decide wether a
   # reference is in the stack or not (this can happen for var parameters).
-  if not IsOnStack(dest):
+  if not isOnStack(dest):
     if src != nil: doIncRef(usrToCell(src))
     # XXX we must detect a shared heap here
     # better idea may be to just eliminate the need for unsureAsgnRef
@@ -470,16 +470,16 @@ proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerProc.} =
 
 when hasThreadSupport and hasSharedHeap:
   # shared heap version of the above procs
-  proc asgnRefSh(dest: ppointer, src: pointer) {.compilerProc, inline.} =
+  proc asgnRefSh(dest: PPointer, src: pointer) {.compilerProc, inline.} =
     doAsgnRef(dest, src, SharedHeap, MaybeCyclic)
 
-  proc asgnRefNoCycleSh(dest: ppointer, src: pointer) {.compilerProc, inline.} =
+  proc asgnRefNoCycleSh(dest: PPointer, src: pointer) {.compilerProc, inline.} =
     doAsgnRef(dest, src, SharedHeap, Acyclic)
 
 proc initGC() =
   when not defined(useNimRtl):
     when traceGC:
-      for i in low(TCellState)..high(TCellState): Init(states[i])
+      for i in low(TCellState)..high(TCellState): init(states[i])
     gch.cycleThreshold = InitialCycleThreshold
     gch.stat.stackScans = 0
     gch.stat.cycleCollections = 0
@@ -491,11 +491,11 @@ proc initGC() =
     init(gch.zct)
     init(gch.tempStack)
     init(gch.freeStack)
-    Init(gch.cycleRoots)
-    Init(gch.decStack)
+    init(gch.cycleRoots)
+    init(gch.decStack)
 
 proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
-  var d = cast[TAddress](dest)
+  var d = cast[ByteAddress](dest)
   case n.kind
   of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
   of nkList:
@@ -503,7 +503,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
       # inlined for speed
       if n.sons[i].kind == nkSlot:
         if n.sons[i].typ.kind in {tyRef, tyString, tySequence}:
-          doOperation(cast[ppointer](d +% n.sons[i].offset)[], op)
+          doOperation(cast[PPointer](d +% n.sons[i].offset)[], op)
         else:
           forAllChildrenAux(cast[pointer](d +% n.sons[i].offset), 
                             n.sons[i].typ, op)
@@ -514,19 +514,19 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
     if m != nil: forAllSlotsAux(dest, m, op)
   of nkNone: sysAssert(false, "forAllSlotsAux")
 
-proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
-  var d = cast[TAddress](dest)
+proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) =
+  var d = cast[ByteAddress](dest)
   if dest == nil: return # nothing to do
   if ntfNoRefs notin mt.flags:
-    case mt.Kind
+    case mt.kind
     of tyRef, tyString, tySequence: # leaf:
-      doOperation(cast[ppointer](d)[], op)
+      doOperation(cast[PPointer](d)[], op)
     of tyObject, tyTuple:
       forAllSlotsAux(dest, mt.node, op)
     of tyArray, tyArrayConstr, tyOpenArray:
       for i in 0..(mt.size div mt.base.size)-1:
         forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
-    else: nil
+    else: discard
 
 proc forAllChildren(cell: PCell, op: TWalkOp) =
   sysAssert(cell != nil, "forAllChildren: 1")
@@ -536,18 +536,18 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
   if marker != nil:
     marker(cellToUsr(cell), op.int)
   else:
-    case cell.typ.Kind
+    case cell.typ.kind
     of tyRef: # common case
       forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
     of tySequence:
-      var d = cast[TAddress](cellToUsr(cell))
+      var d = cast[ByteAddress](cellToUsr(cell))
       var s = cast[PGenericSeq](d)
       if s != nil:
         let baseAddr = d +% GenericSeqSize
         for i in 0..s.len-1:
           forAllChildrenAux(cast[pointer](baseAddr +% i *% cell.typ.base.size),
                             cell.typ.base, op)
-    else: nil
+    else: discard
 
 proc addNewObjToZCT(res: PCell, gch: var TGcHeap) {.inline.} =
   # we check the last 8 entries (cache line) for a slot that could be reused.
@@ -605,7 +605,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap, rc1: bool): pointer =
   var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
   sysAssert(allocInv(gch.region), "rawNewObj after rawAlloc")
 
-  sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
+  sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
   
   res.typ = typ
   
@@ -708,10 +708,10 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
   # call user-defined move code
   # call user-defined default constructor
   copyMem(res, ol, oldsize + sizeof(TCell))
-  zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)),
+  zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
           newsize-oldsize)
 
-  sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
+  sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
   sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
   
   when false:
@@ -786,10 +786,10 @@ type
     FromChildren,
     FromRoot
 
-proc CollectZCT(gch: var TGcHeap): bool
+proc collectZCT(gch: var TGcHeap): bool
 
 template pseudoRecursion(typ: TRecursionType, body: stmt): stmt =
-  #
+  discard
 
 proc trimCycleRoots(gch: var TGcHeap, startIdx = gch.cycleRootsTrimIdx) =
   var i = startIdx
@@ -967,17 +967,17 @@ proc collectCycles(gch: var TGcHeap) =
       maybedeads,
       collected
 
-  Deinit(gch.cycleRoots)
-  Init(gch.cycleRoots)
+  deinit(gch.cycleRoots)
+  init(gch.cycleRoots)
 
-  Deinit(gch.freeStack)
-  Init(gch.freeStack)
+  deinit(gch.freeStack)
+  init(gch.freeStack)
 
   when MarkingSkipsAcyclicObjects:
     # Collect the acyclic objects that became unreachable due to collected
     # cyclic objects. 
-    discard CollectZCT(gch)
-    # CollectZCT may add new cycle candidates and we may decide to loop here
+    discard collectZCT(gch)
+    # collectZCT may add new cycle candidates and we may decide to loop here
     # if gch.cycleRoots.len > 0: repeat
 
 var gcDebugging* = false
@@ -988,7 +988,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
   # the addresses are not as cells on the stack, so turn them to cells:
   sysAssert(allocInv(gch.region), "gcMark begin")
   var cell = usrToCell(p)
-  var c = cast[TAddress](cell)
+  var c = cast[ByteAddress](cell)
   if c >% PageSize:
     # fast check: does it look like a cell?
     var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
@@ -997,6 +997,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
       if objStart.color != rcReallyDead:
         if gcDebugging:
           # writeCell("marking ", objStart)
+          discard
         else:
           inc objStart.refcount, rcIncrement
           gch.decStack.add objStart
@@ -1009,6 +1010,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
         # coincidence due to the conservative stack marking.
         when debugGC:
           # writeCell("marking dead object", objStart)
+          discard
     when false:
       if isAllocatedPtr(gch.region, cell):
         sysAssert false, "allocated pointer but not interior?"
@@ -1024,12 +1026,12 @@ proc markThreadStacks(gch: var TGcHeap) =
     while it != nil:
       # mark registers: 
       for i in 0 .. high(it.registers): gcMark(gch, it.registers[i])
-      var sp = cast[TAddress](it.stackBottom)
-      var max = cast[TAddress](it.stackTop)
+      var sp = cast[ByteAddress](it.stackBottom)
+      var max = cast[ByteAddress](it.stackTop)
       # XXX stack direction?
       # XXX unroll this loop:
       while sp <=% max:
-        gcMark(gch, cast[ppointer](sp)[])
+        gcMark(gch, cast[PPointer](sp)[])
         sp = sp +% sizeof(pointer)
       it = it.next
 
@@ -1051,8 +1053,8 @@ when not defined(useNimRtl):
     # the first init must be the one that defines the stack bottom:
     if gch.stackBottom == nil: gch.stackBottom = theStackBottom
     else:
-      var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2
-      var b = cast[TAddress](gch.stackBottom)
+      var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2
+      var b = cast[ByteAddress](gch.stackBottom)
       #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
       when stackIncreases:
         gch.stackBottom = cast[pointer](min(a, b))
@@ -1067,15 +1069,15 @@ proc stackSize(): int {.noinline.} =
 var
   jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
     # a little hack to get the size of a TJmpBuf in the generated C code
-    # in a platform independant way
+    # in a platform independent way
 
 when defined(sparc): # For SPARC architecture.
   proc isOnStack(p: pointer): bool =
     var stackTop {.volatile.}: pointer
     stackTop = addr(stackTop)
-    var b = cast[TAddress](gch.stackBottom)
-    var a = cast[TAddress](stackTop)
-    var x = cast[TAddress](p)
+    var b = cast[ByteAddress](gch.stackBottom)
+    var a = cast[ByteAddress](stackTop)
+    var x = cast[ByteAddress](p)
     result = a <=% x and x <=% b
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@@ -1092,7 +1094,7 @@ when defined(sparc): # For SPARC architecture.
     # Addresses decrease as the stack grows.
     while sp <= max:
       gcMark(gch, sp[])
-      sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
+      sp = cast[PPointer](cast[ByteAddress](sp) +% sizeof(pointer))
 
 elif defined(ELATE):
   {.error: "stack marking code is to be written for this architecture".}
@@ -1104,20 +1106,20 @@ elif stackIncreases:
   proc isOnStack(p: pointer): bool =
     var stackTop {.volatile.}: pointer
     stackTop = addr(stackTop)
-    var a = cast[TAddress](gch.stackBottom)
-    var b = cast[TAddress](stackTop)
-    var x = cast[TAddress](p)
+    var a = cast[ByteAddress](gch.stackBottom)
+    var b = cast[ByteAddress](stackTop)
+    var x = cast[ByteAddress](p)
     result = a <=% x and x <=% b
   
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
     var registers: C_JmpBuf
     if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
-      var max = cast[TAddress](gch.stackBottom)
-      var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
+      var max = cast[ByteAddress](gch.stackBottom)
+      var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
       # sp will traverse the JMP_BUF as well (jmp_buf size is added,
       # otherwise sp would be below the registers structure).
       while sp >=% max:
-        gcMark(gch, cast[ppointer](sp)[])
+        gcMark(gch, cast[PPointer](sp)[])
         sp = sp -% sizeof(pointer)
 
 else:
@@ -1127,9 +1129,9 @@ else:
   proc isOnStack(p: pointer): bool =
     var stackTop {.volatile.}: pointer
     stackTop = addr(stackTop)
-    var b = cast[TAddress](gch.stackBottom)
-    var a = cast[TAddress](stackTop)
-    var x = cast[TAddress](p)
+    var b = cast[ByteAddress](gch.stackBottom)
+    var a = cast[ByteAddress](stackTop)
+    var x = cast[ByteAddress](p)
     result = a <=% x and x <=% b
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
@@ -1141,18 +1143,18 @@ else:
     if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
       when MinimumStackMarking:
         # mark the registers
-        var jmpbufPtr = cast[TAddress](addr(registers))
+        var jmpbufPtr = cast[ByteAddress](addr(registers))
         var jmpbufEnd = jmpbufPtr +% jmpbufSize
       
         while jmpbufPtr <=% jmpbufEnd:
-          gcMark(gch, cast[ppointer](jmpbufPtr)[])
+          gcMark(gch, cast[PPointer](jmpbufPtr)[])
           jmpbufPtr = jmpbufPtr +% sizeof(pointer)
 
-        var sp = cast[TAddress](gch.stackTop)
+        var sp = cast[ByteAddress](gch.stackTop)
       else:
-        var sp = cast[TAddress](addr(registers))
+        var sp = cast[ByteAddress](addr(registers))
       # mark the user stack
-      var max = cast[TAddress](gch.stackBottom)
+      var max = cast[ByteAddress](gch.stackBottom)
       # loop unrolled:
       while sp <% max - 8*sizeof(pointer):
         gcMark(gch, cast[PStackSlice](sp)[0])
@@ -1166,7 +1168,7 @@ else:
         sp = sp +% sizeof(pointer)*8
       # last few entries:
       while sp <=% max:
-        gcMark(gch, cast[ppointer](sp)[])
+        gcMark(gch, cast[PPointer](sp)[])
         sp = sp +% sizeof(pointer)
 
 # ----------------------------------------------------------------------------
@@ -1202,7 +1204,7 @@ proc releaseCell(gch: var TGcHeap, cell: PCell) =
   #  recursion).
   # We can ignore it now as the ZCT cleaner will reach it soon.
 
-proc CollectZCT(gch: var TGcHeap): bool =
+proc collectZCT(gch: var TGcHeap): bool =
   const workPackage = 100
   var L = addr(gch.zct.len)
   
@@ -1213,8 +1215,8 @@ proc CollectZCT(gch: var TGcHeap): bool =
   
   while L[] > 0:
     var c = gch.zct.d[0]
-    sysAssert c.isBitUp(rcZct), "CollectZCT: rcZct missing!"
-    sysAssert(isAllocatedPtr(gch.region, c), "CollectZCT: isAllocatedPtr")
+    sysAssert c.isBitUp(rcZct), "collectZCT: rcZct missing!"
+    sysAssert(isAllocatedPtr(gch.region, c), "collectZCT: isAllocatedPtr")
     
     # remove from ZCT:    
     c.clearBit(rcZct)
@@ -1263,7 +1265,7 @@ proc unmarkStackAndRegisters(gch: var TGcHeap) =
     # XXX no need for an atomic dec here:
     if c.refcount--(LocalHeap):
       # the object survived only because of a stack reference
-      # it still doesn't have heap refernces
+      # it still doesn't have heap references
       addZCT(gch.zct, c)
     
     if canbeCycleRoot(c):
@@ -1295,7 +1297,7 @@ proc collectCTBody(gch: var TGcHeap) =
         sysAssert gch.zct.len == 0, "zct is not null after collect cycles"
         inc(gch.stat.cycleCollections)
         gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() *
-                                 cycleIncrease)
+                                 CycleIncrease)
         gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold)
   unmarkStackAndRegisters(gch)
   sysAssert(allocInv(gch.region), "collectCT: end")
@@ -1346,10 +1348,10 @@ when not defined(useNimRtl):
 
   proc GC_setStrategy(strategy: GC_Strategy) =
     case strategy
-    of gcThroughput: nil
-    of gcResponsiveness: nil
-    of gcOptimizeSpace: nil
-    of gcOptimizeTime: nil
+    of gcThroughput: discard
+    of gcResponsiveness: discard
+    of gcOptimizeSpace: discard
+    of gcOptimizeTime: discard
 
   proc GC_enableMarkAndSweep() =
     gch.cycleThreshold = InitialCycleThreshold
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index 9c3ee8ce2..6fbe94239 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -297,10 +297,12 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
   zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
           newsize-oldsize)
   sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
-  when withBitvectors: excl(gch.allocated, ol)
-  when reallyDealloc: rawDealloc(gch.region, ol)
-  else:
-    zeroMem(ol, sizeof(TCell))
+  when false:
+    # this is wrong since seqs can be shared via 'shallow':
+    when withBitvectors: excl(gch.allocated, ol)
+    when reallyDealloc: rawDealloc(gch.region, ol)
+    else:
+      zeroMem(ol, sizeof(TCell))
   when withBitvectors: incl(gch.allocated, res)
   when useCellIds:
     inc gch.idGenerator
@@ -474,7 +476,7 @@ elif stackIncreases:
   var
     jmpbufSize {.importc: "sizeof(jmp_buf)", nodecl.}: int
       # a little hack to get the size of a TJmpBuf in the generated C code
-      # in a platform independant way
+      # in a platform independent way
 
   proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
     var registers: C_JmpBuf
diff --git a/lib/system/hti.nim b/lib/system/hti.nim
index e599668a7..aff0c0e6f 100644
--- a/lib/system/hti.nim
+++ b/lib/system/hti.nim
@@ -11,7 +11,7 @@ when declared(NimString):
   # we are in system module:
   {.pragma: codegenType, compilerproc.}
 else:
-  {.pragma: codegenType.}
+  {.pragma: codegenType, importc.}
 
 type 
   # This should be he same as ast.TTypeKind
@@ -26,7 +26,7 @@ type
     tyExpr,
     tyStmt,
     tyTypeDesc,
-    tyGenericInvokation, # ``T[a, b]`` for types to invoke
+    tyGenericInvocation, # ``T[a, b]`` for types to invoke
     tyGenericBody,       # ``T[a, b, body]`` last parameter is the body
     tyGenericInst,       # ``T[a, b, realInstance]`` instantiated generic type
     tyGenericParam,      # ``a`` in the example
@@ -65,7 +65,7 @@ type
     tyBigNum,
 
   TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
-  TNimNode {.codegenType, final.} = object
+  TNimNode {.codegenType.} = object
     kind: TNimNodeKind
     offset: int
     typ: ptr TNimType
@@ -78,7 +78,7 @@ type
     ntfAcyclic = 1,    # type cannot form a cycle
     ntfEnumHole = 2    # enum has holes and thus `$` for them needs the slow
                        # version
-  TNimType {.codegenType, final.} = object
+  TNimType {.codegenType.} = object
     size: int
     kind: TNimKind
     flags: set[TNimTypeFlag]
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index 9b4a7d556..15b00f8f1 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -128,7 +128,7 @@ proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} =
   raise newException(OverflowError, "over- or underflow")
 
 proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} =
-  raise newException(DivByZeroError, "divison by zero")
+  raise newException(DivByZeroError, "division by zero")
 
 proc raiseRangeError() {.compilerproc, noreturn.} =
   raise newException(RangeError, "value out of range")
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index 2de603cea..f1029ff6a 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -30,14 +30,16 @@ proc reprStrAux(result: var string, s: string) =
     add result, "nil"
     return
   add result, reprPointer(cast[pointer](s)) & "\""
-  for c in items(s):
+  for i in 0.. <s.len:
+    let c = s[i]
     case c
     of '"': add result, "\\\""
     of '\\': add result, "\\\\" # BUGFIX: forgotten
     of '\10': add result, "\\10\"\n\"" # " \n " # better readability
     of '\128' .. '\255', '\0'..'\9', '\11'..'\31':
       add result, "\\" & reprInt(ord(c))
-    else: result.add(c)
+    else:
+      result.add(c)
   add result, "\""
 
 proc reprStr(s: string): string {.compilerRtl.} =
@@ -78,7 +80,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
 type
   PByteArray = ptr array[0.. 0xffff, int8]
 
-proc addSetElem(result: var string, elem: int, typ: PNimType) {.gcsafe.} =
+proc addSetElem(result: var string, elem: int, typ: PNimType) {.benign.} =
   case typ.kind
   of tyEnum: add result, reprEnum(elem, typ)
   of tyBool: add result, reprBool(bool(elem))
@@ -147,7 +149,7 @@ when not defined(useNimRtl):
     for i in 0..cl.indent-1: add result, ' '
 
   proc reprAux(result: var string, p: pointer, typ: PNimType,
-               cl: var TReprClosure) {.gcsafe.}
+               cl: var TReprClosure) {.benign.}
 
   proc reprArray(result: var string, p: pointer, typ: PNimType,
                  cl: var TReprClosure) =
@@ -172,7 +174,7 @@ when not defined(useNimRtl):
     add result, "]"
 
   proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
-                     cl: var TReprClosure) {.gcsafe.} =
+                     cl: var TReprClosure) {.benign.} =
     case n.kind
     of nkNone: sysAssert(false, "reprRecordAux")
     of nkSlot:
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 7908fbe4d..48adb895d 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -132,7 +132,7 @@ proc rawFileSize(file: File): int =
   discard fseek(file, clong(oldPos), 0)
 
 proc readAllFile(file: File, len: int): string =
-  # We aquire the filesize beforehand and hope it doesn't change.
+  # We acquire the filesize beforehand and hope it doesn't change.
   # Speeds things up.
   result = newString(int(len))
   if readBuffer(file, addr(result[0]), int(len)) != len:
@@ -145,8 +145,8 @@ proc readAllFile(file: File): string =
 proc readAll(file: File): TaintedString = 
   # Separate handling needed because we need to buffer when we
   # don't know the overall length of the File.
-  var len = rawFileSize(file)
-  if len >= 0:
+  let len = if file != stdin: rawFileSize(file) else: -1
+  if len > 0:
     result = readAllFile(file, len).TaintedString
   else:
     result = readAllBuffer(file).TaintedString
@@ -183,11 +183,17 @@ proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
 when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc):
   include "system/widestrs"
 
-when defined(windows) and not defined(useWinAnsi):  
-  proc wfopen(filename, mode: WideCString): pointer {.
-    importc: "_wfopen", nodecl.}
-  proc wfreopen(filename, mode: WideCString, stream: File): File {.
-    importc: "_wfreopen", nodecl.}
+when defined(windows) and not defined(useWinAnsi):
+  when defined(cpp):
+    proc wfopen(filename, mode: WideCString): pointer {.
+      importcpp: "_wfopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.}
+    proc wfreopen(filename, mode: WideCString, stream: File): File {.
+      importcpp: "_wfreopen((const wchar_t*)#, (const wchar_t*)#, #)", nodecl.}
+  else:
+    proc wfopen(filename, mode: WideCString): pointer {.
+      importc: "_wfopen", nodecl.}
+    proc wfreopen(filename, mode: WideCString, stream: File): File {.
+      importc: "_wfreopen", nodecl.}
 
   proc fopen(filename, mode: cstring): pointer =
     var f = newWideCString(filename)
@@ -240,14 +246,14 @@ proc fwrite(buf: pointer, size, n: int, f: File): int {.
 proc readBuffer(f: File, buffer: pointer, len: int): int =
   result = fread(buffer, 1, len, f)
 
-proc readBytes(f: File, a: var openArray[int8], start, len: int): int =
+proc readBytes(f: File, a: var openArray[int8|uint8], start, len: int): int =
   result = readBuffer(f, addr(a[start]), len)
 
 proc readChars(f: File, a: var openArray[char], start, len: int): int =
   result = readBuffer(f, addr(a[start]), len)
 
 {.push stackTrace:off, profiler:off.}
-proc writeBytes(f: File, a: openArray[int8], start, len: int): int =
+proc writeBytes(f: File, a: openArray[int8|uint8], start, len: int): int =
   var x = cast[ptr array[0..1000_000_000, int8]](a)
   result = writeBuffer(f, addr(x[start]), len)
 proc writeChars(f: File, a: openArray[char], start, len: int): int =
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 440d040a5..cfbc24f0c 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -208,7 +208,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
       when compileOption("gc", "v2"):
         for i in newLen..result.len-1:
           let len0 = gch.tempStack.len
-          forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
+          forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +%
                             GenericSeqSize +% (i*%elemSize)),
                             extGetCellType(result).base, waPush)
           let len1 = gch.tempStack.len
@@ -222,9 +222,9 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
                             extGetCellType(result).base, waZctDecRef)
       
     # XXX: zeroing out the memory can still result in crashes if a wiped-out
-    # cell is aliased by another pointer (ie proc paramter or a let variable).
+    # cell is aliased by another pointer (ie proc parameter or a let variable).
     # This is a tought problem, because even if we don't zeroMem here, in the
-    # presense of user defined destructors, the user will expect the cell to be
+    # presence of user defined destructors, the user will expect the cell to be
     # "destroyed" thus creating the same problem. We can destoy the cell in the
     # finalizer of the sequence, but this makes destruction non-deterministic.
     zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +%
@@ -264,7 +264,17 @@ proc nimFloatToStr(f: float): string {.compilerproc.} =
     buf[n] = '.'
     buf[n+1] = '0'
     buf[n+2] = '\0'
-  result = $buf
+  # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced.
+  # We want to get rid of these here:
+  if buf[n-1] == 'N':
+    result = "nan"
+  elif buf[n-1] == 'F':
+    if buf[0] == '-':
+      result = "-inf"
+    else:
+      result = "inf"
+  else:
+    result = $buf
 
 proc strtod(buf: cstring, endptr: ptr cstring): float64 {.importc,
   header: "<stdlib.h>", noSideEffect.}
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 496c31af1..81d9e5d73 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -84,8 +84,18 @@ when defined(windows):
       importc: "TlsAlloc", stdcall, header: "<windows.h>".}
     proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {.
       importc: "TlsSetValue", stdcall, header: "<windows.h>".}
-    proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {.
+    proc tlsGetValue(dwTlsIndex: TThreadVarSlot): pointer {.
       importc: "TlsGetValue", stdcall, header: "<windows.h>".}
+
+    proc getLastError(): uint32 {.
+      importc: "GetLastError", stdcall, header: "<windows.h>".}
+    proc setLastError(x: uint32) {.
+      importc: "SetLastError", stdcall, header: "<windows.h>".}
+
+    proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer =
+      let realLastError = getLastError()
+      result = tlsGetValue(dwTlsIndex)
+      setLastError(realLastError)
   else:
     proc threadVarAlloc(): TThreadVarSlot {.
       importc: "TlsAlloc", stdcall, dynlib: "kernel32".}
@@ -95,7 +105,9 @@ when defined(windows):
       importc: "TlsGetValue", stdcall, dynlib: "kernel32".}
   
 else:
-  {.passL: "-pthread".}
+  when not defined(macosx):
+    {.passL: "-pthread".}
+
   {.passC: "-pthread".}
 
   type
diff --git a/lib/system/timers.nim b/lib/system/timers.nim
index e58ff7adc..e5de791ac 100644
--- a/lib/system/timers.nim
+++ b/lib/system/timers.nim
@@ -27,9 +27,9 @@ when defined(windows):
   proc `-`(a, b: TTicks): TNanos =
     var frequency: int64
     QueryPerformanceFrequency(frequency)
-    var performanceCounterRate = 1000000000.0 / toFloat(frequency.int)
+    var performanceCounterRate = 1e+9'f64 / float64(frequency)
 
-    result = ((a.int64 - b.int64).int.toFloat * performanceCounterRate).TNanos
+    result = TNanos(float64(a.int64 - b.int64) * performanceCounterRate)
 
 elif defined(macosx):
   type
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index f0895217b..43c595a64 100644
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -11616,7 +11616,7 @@ type
     dwPageSize*: DWORD

     lpMinimumApplicationAddress*: LPVOID

     lpMaximumApplicationAddress*: LPVOID

-    dwActiveProcessorMask*: DWORD

+    dwActiveProcessorMask*: DWORD_PTR

     dwNumberOfProcessors*: DWORD

     dwProcessorType*: DWORD

     dwAllocationGranularity*: DWORD

diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 51a12141b..584f7cf48 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -284,6 +284,10 @@ when useWinUnicode:
                  bFailIfExists: cint): cint {.
     importc: "CopyFileW", stdcall, dynlib: "kernel32".}
 
+  proc moveFileW*(lpExistingFileName, lpNewFileName: WideCString,
+                 bFailIfExists: cint): cint {.
+    importc: "MoveFileW", stdcall, dynlib: "kernel32".}
+
   proc getEnvironmentStringsW*(): WideCString {.
     stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".}
   proc freeEnvironmentStringsW*(para1: WideCString): int32 {.
@@ -308,6 +312,10 @@ else:
                  bFailIfExists: cint): cint {.
     importc: "CopyFileA", stdcall, dynlib: "kernel32".}
 
+  proc moveFileA*(lpExistingFileName, lpNewFileName: cstring,
+                 bFailIfExists: cint): cint {.
+    importc: "MoveFileA", stdcall, dynlib: "kernel32".}
+
   proc getEnvironmentStringsA*(): cstring {.
     stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".}
   proc freeEnvironmentStringsA*(para1: cstring): int32 {.
diff --git a/lib/wrappers/claro.nim b/lib/wrappers/claro.nim
index fb06da818..d36b9f178 100644
--- a/lib/wrappers/claro.nim
+++ b/lib/wrappers/claro.nim
@@ -64,7 +64,7 @@ proc node_move*(n: ptr TNode, oldlist: ptr TList, newlist: ptr TList){.
     cdecl, importc: "node_move", dynlib: clarodll.}

 

 type 

-  TClaroObj*{.pure.} = object 

+  TClaroObj*{.pure, inheritable.} = object 

     typ*: array[0..64 - 1, char]

     destroy_pending*: cint

     event_handlers*: TList

@@ -86,7 +86,7 @@ type
   TEventHandler*{.pure.} = object 

     typ*: array[0..32 - 1, char]

     data*: pointer

-    func*: TEventFunc   # the function that handles this event 

+    fun*: TEventFunc   # the function that handles this event 

   

 

 # #define event_handler(n) void n ( TClaroObj *object, event_t *event )

@@ -121,10 +121,10 @@ proc object_set_parent*(obj: ptr TClaroObj, parent: ptr TClaroObj){.cdecl,
 # event functions 

 

 proc object_addhandler*(obj: ptr TClaroObj, event: cstring, 

-                        func: TEventFunc){.cdecl, 

+                        fun: TEventFunc){.cdecl, 

     importc: "object_addhandler", dynlib: clarodll.}

 proc object_addhandler_interface*(obj: ptr TClaroObj, event: cstring, 

-                                  func: TEventFunc, data: pointer){.cdecl, 

+                                  fun: TEventFunc, data: pointer){.cdecl, 

     importc: "object_addhandler_interface", dynlib: clarodll.}

 proc event_send*(obj: ptr TClaroObj, event: cstring, fmt: cstring): cint{.

     varargs, cdecl, importc: "event_send", dynlib: clarodll.}

@@ -258,7 +258,7 @@ proc image_load_inline_png*(parent: ptr TClaroObj, data: cstring,
   ##  len size of data

 

 when true:

-  nil

+  discard

 else:

   # status icons are not supported on all platforms yet:

   type 

@@ -682,7 +682,7 @@ const
 type 

   TCanvas*{.pure.} = object of TWidget

     surface*: cairo.PSurface

-    cr*: Cairo.PContext

+    cr*: cairo.PContext

     surfdata*: pointer

     fontdata*: pointer

     font_height*: cint

@@ -854,7 +854,7 @@ proc canvas_cairo_buffered_text_display_count*(widget: ptr TCanvas,
     text: cstring, width: cint): cint{.cdecl, 

     importc: "canvas_cairo_buffered_text_display_count", 

     dynlib: clarodll.}

-proc canvas_get_cairo_context*(widget: ptr TCanvas): Cairo.PContext {.cdecl, 

+proc canvas_get_cairo_context*(widget: ptr TCanvas): cairo.PContext {.cdecl, 

     importc: "canvas_get_cairo_context", dynlib: clarodll.}

 

 type 

diff --git a/lib/wrappers/libffi/msvc/win32.c b/lib/wrappers/libffi/msvc/win32.c
index d1149a85e..2754fd35d 100644
--- a/lib/wrappers/libffi/msvc/win32.c
+++ b/lib/wrappers/libffi/msvc/win32.c
@@ -90,7 +90,7 @@ noclean:
 
 // If the return value pointer is NULL, assume no return value.
 /*
-  Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
+  Intel asm is weird. We have to explicitly specify 'DWORD PTR' in the nexr instruction,
   otherwise only one BYTE will be compared (instead of a DWORD)!
  */
 		cmp DWORD PTR [ebp + 24], 0
diff --git a/lib/wrappers/libuv.nim b/lib/wrappers/libuv.nim
index 3189ec408..a52ae0f63 100644
--- a/lib/wrappers/libuv.nim
+++ b/lib/wrappers/libuv.nim
@@ -30,9 +30,9 @@ type
   CheckProc* = proc (handle: PCheck, status: cint) {.cdecl.}
   IdleProc* = proc (handle: PIdle, status: cint) {.cdecl.}
 
-  PSockAddr* = ptr TSockAddr
+  PSockAddr* = ptr SockAddr
 
-  GetAddrInfoProc* = proc (handle: PGetAddrInfo, status: cint, res: ptr TAddrInfo)
+  GetAddrInfoProc* = proc (handle: PGetAddrInfo, status: cint, res: ptr AddrInfo)
 
   ExitProc* = proc (a2: PProcess, exit_status: cint, term_signal: cint)
   FsProc* = proc (req: PFS)
@@ -210,7 +210,7 @@ type
   cunsigned = int
 
   UdpSendProc* = proc (req: PUdpSend, status: cint)
-  UdpRecvProc* = proc (handle: PUdp, nread: cssize, buf: TBuf, adr: ptr TSockAddr, flags: cunsigned)
+  UdpRecvProc* = proc (handle: PUdp, nread: cssize, buf: TBuf, adr: ptr SockAddr, flags: cunsigned)
 
   TUdp* {.pure, final, importc: "uv_udp_t", header: "uv.h".} = object
     loop* {.importc: "loop".}: PLoop
@@ -366,7 +366,7 @@ type
     tcp_port* {.importc: "tcp_port".}: TPort
     socket_send_buffer_size* {.importc: "socket_send_buffer_size".}: int
     socket_recv_buffer_size* {.importc: "socket_receive_buffer_size".}: int
-    servers* {.importc: "servers".}: ptr TInAddr
+    servers* {.importc: "servers".}: ptr InAddr
     nservers* {.importc: "nservers".}: int
     domains* {.importc: "domains".}: ptr cstring
     ndomains* {.importc: "ndomains".}: int
@@ -450,19 +450,19 @@ proc write*(req: PWrite, handle: PStream, bufs: ptr TBuf, bufcnt: cint, send_han
 proc tcp_init*(a2: PLoop, handle: PTcp): cint{.
     importc: "uv_tcp_init", header: "uv.h".}
 
-proc tcp_bind*(handle: PTcp, a3: TSockAddrIn): cint{.
+proc tcp_bind*(handle: PTcp, a3: SockAddrIn): cint{.
     importc: "uv_tcp_bind", header: "uv.h".}
 
 proc tcp_bind6*(handle: PTcp, a3: TSockAddrIn6): cint{.
     importc: "uv_tcp_bind6", header: "uv.h".}
 
-proc tcp_getsockname*(handle: PTcp, name: ptr TSockAddr, namelen: var cint): cint{.
+proc tcp_getsockname*(handle: PTcp, name: ptr SockAddr, namelen: var cint): cint{.
     importc: "uv_tcp_getsockname", header: "uv.h".}
 
-proc tcp_getpeername*(handle: PTcp, name: ptr TSockAddr, namelen: var cint): cint{.
+proc tcp_getpeername*(handle: PTcp, name: ptr SockAddr, namelen: var cint): cint{.
     importc: "uv_tcp_getpeername", header: "uv.h".}
 
-proc tcp_connect*(req: PConnect, handle: PTcp, address: TSockAddrIn, cb: ConnectProc): cint{.
+proc tcp_connect*(req: PConnect, handle: PTcp, address: SockAddrIn, cb: ConnectProc): cint{.
     importc: "uv_tcp_connect", header: "uv.h".}
 
 proc tcp_connect6*(req: PConnect, handle: PTcp, address: TSockAddrIn6, cb: ConnectProc): cint{.
@@ -471,16 +471,16 @@ proc tcp_connect6*(req: PConnect, handle: PTcp, address: TSockAddrIn6, cb: Conne
 proc udp_init*(a2: PLoop, handle: PUdp): cint{.
     importc: "uv_udp_init", header: "uv.h".}
 
-proc udp_bind*(handle: PUdp, adr: TSockAddrIn, flags: cunsigned): cint{.
+proc udp_bind*(handle: PUdp, adr: SockAddrIn, flags: cunsigned): cint{.
     importc: "uv_udp_bind", header: "uv.h".}
 
 proc udp_bind6*(handle: PUdp, adr: TSockAddrIn6, flags: cunsigned): cint{.
     importc: "uv_udp_bind6", header: "uv.h".}
 
-proc udp_getsockname*(handle: PUdp, name: ptr TSockAddr, namelen: var cint): cint{.
+proc udp_getsockname*(handle: PUdp, name: ptr SockAddr, namelen: var cint): cint{.
     importc: "uv_udp_getsockname", header: "uv.h".}
 
-proc udp_send*(req: PUdpSend, handle: PUdp, bufs: ptr TBuf, bufcnt: cint, adr: TSockAddrIn, send_cb: UdpSendProc): cint{.
+proc udp_send*(req: PUdpSend, handle: PUdp, bufs: ptr TBuf, bufcnt: cint, adr: SockAddrIn, send_cb: UdpSendProc): cint{.
     importc: "uv_udp_send", header: "uv.h".}
 
 proc udp_send6*(req: PUdpSend, handle: PUdp, bufs: ptr TBuf, bufcnt: cint, adr: TSockAddrIn6, send_cb: UdpSendProc): cint{.
@@ -492,7 +492,7 @@ proc udp_recv_start*(handle: PUdp, alloc_cb: AllocProc, recv_cb: UdpRecvProc): c
 proc udp_recv_stop*(handle: PUdp): cint{.
     importc: "uv_udp_recv_stop", header: "uv.h".}
 
-proc tty_init*(a2: PLoop, a3: pTTy, fd: TFile): cint{.
+proc tty_init*(a2: PLoop, a3: pTTy, fd: File): cint{.
     importc: "uv_tty_init", header: "uv.h".}
 
 proc tty_set_mode*(a2: pTTy, mode: cint): cint{.
@@ -504,13 +504,13 @@ proc tty_get_winsize*(a2: pTTy, width: var cint, height: var cint): cint{.
 proc tty_reset_mode*() {.
     importc: "uv_tty_reset_mode", header: "uv.h".}
 
-proc guess_handle*(file: TFile): THandleType{.
+proc guess_handle*(file: File): THandleType{.
     importc: "uv_guess_handle", header: "uv.h".}
 
 proc pipe_init*(a2: PLoop, handle: PPipe, ipc: int): cint{.
     importc: "uv_pipe_init", header: "uv.h".}
 
-proc pipe_open*(a2: PPipe, file: TFile){.
+proc pipe_open*(a2: PPipe, file: File){.
     importc: "uv_pipe_open", header: "uv.h".}
 
 proc pipe_bind*(handle: PPipe, name: cstring): cint{.
@@ -576,10 +576,10 @@ proc ares_init_options*(a2: PLoop, channel: PAresChannel, options: PAresOptions,
 proc ares_destroy*(a2: PLoop, channel: PAresChannel){.
     importc: "uv_ares_destroy", header: "uv.h".}
 
-proc getaddrinfo*(a2: PLoop, handle: PGetAddrInfo,getaddrinfo_cb: GetAddrInfoProc, node: cstring, service: cstring, hints: ptr TAddrInfo): cint{.
+proc getaddrinfo*(a2: PLoop, handle: PGetAddrInfo,getaddrinfo_cb: GetAddrInfoProc, node: cstring, service: cstring, hints: ptr AddrInfo): cint{.
     importc: "uv_getaddrinfo", header: "uv.h".}
 
-proc freeaddrinfo*(ai: ptr TAddrInfo){.
+proc freeaddrinfo*(ai: ptr AddrInfo){.
     importc: "uv_freeaddrinfo", header: "uv.h".}
 
 proc spawn*(a2: PLoop, a3: PProcess, options: TProcessOptions): cint{.
@@ -594,19 +594,19 @@ proc queue_work*(loop: PLoop, req: PWork, work_cb: WorkProc, after_work_cb: Afte
 proc req_cleanup*(req: PFS){.
     importc: "uv_fs_req_cleanup", header: "uv.h".}
 
-proc close*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
+proc close*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{.
     importc: "uv_fs_close", header: "uv.h".}
 
 proc open*(loop: PLoop, req: PFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_open", header: "uv.h".}
 
-proc read*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
+proc read*(loop: PLoop, req: PFS, file: File, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_read", header: "uv.h".}
 
 proc unlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_unlink", header: "uv.h".}
 
-proc write*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
+proc write*(loop: PLoop, req: PFS, file: File, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_write", header: "uv.h".}
 
 proc mkdir*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{.
@@ -621,22 +621,22 @@ proc readdir*(loop: PLoop, req: PFS, path: cstring, flags: cint, cb: FsProc): ci
 proc stat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_stat", header: "uv.h".}
 
-proc fstat*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
+proc fstat*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{.
     importc: "uv_fs_fstat", header: "uv.h".}
 
 proc rename*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_rename", header: "uv.h".}
 
-proc fsync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
+proc fsync*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{.
     importc: "uv_fs_fsync", header: "uv.h".}
 
-proc fdatasync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
+proc fdatasync*(loop: PLoop, req: PFS, file: File, cb: FsProc): cint{.
     importc: "uv_fs_fdatasync", header: "uv.h".}
 
-proc ftruncate*(loop: PLoop, req: PFS, file: TFile, offset: coff, cb: FsProc): cint{.
+proc ftruncate*(loop: PLoop, req: PFS, file: File, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_ftruncate", header: "uv.h".}
 
-proc sendfile*(loop: PLoop, req: PFS, out_fd: TFile, in_fd: TFile, in_offset: coff, length: csize, cb: FsProc): cint{.
+proc sendfile*(loop: PLoop, req: PFS, out_fd: File, in_fd: File, in_offset: coff, length: csize, cb: FsProc): cint{.
     importc: "uv_fs_sendfile", header: "uv.h".}
 
 proc chmod*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{.
@@ -645,7 +645,7 @@ proc chmod*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{
 proc utime*(loop: PLoop, req: PFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
     importc: "uv_fs_utime", header: "uv.h".}
 
-proc futime*(loop: PLoop, req: PFS, file: TFile, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
+proc futime*(loop: PLoop, req: PFS, file: File, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
     importc: "uv_fs_futime", header: "uv.h".}
 
 proc lstat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
@@ -660,25 +660,25 @@ proc symlink*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, flags: ci
 proc readlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_readlink", header: "uv.h".}
 
-proc fchmod*(loop: PLoop, req: PFS, file: TFile, mode: cint, cb: FsProc): cint{.
+proc fchmod*(loop: PLoop, req: PFS, file: File, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_fchmod", header: "uv.h".}
 
 proc chown*(loop: PLoop, req: PFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{.
     importc: "uv_fs_chown", header: "uv.h".}
 
-proc fchown*(loop: PLoop, req: PFS, file: TFile, uid: cint, gid: cint, cb: FsProc): cint{.
+proc fchown*(loop: PLoop, req: PFS, file: File, uid: cint, gid: cint, cb: FsProc): cint{.
     importc: "uv_fs_fchown", header: "uv.h".}
 
 proc event_init*(loop: PLoop, handle: PFSEvent, filename: cstring, cb: FsEventProc): cint{.
     importc: "uv_fs_event_init", header: "uv.h".}
 
-proc ip4_addr*(ip: cstring, port: cint): TSockAddrIn{.
+proc ip4_addr*(ip: cstring, port: cint): SockAddrIn{.
     importc: "uv_ip4_addr", header: "uv.h".}
 
 proc ip6_addr*(ip: cstring, port: cint): TSockAddrIn6{.
     importc: "uv_ip6_addr", header: "uv.h".}
 
-proc ip4_name*(src: ptr TSockAddrIn, dst: cstring, size: csize): cint{.
+proc ip4_name*(src: ptr SockAddrIn, dst: cstring, size: csize): cint{.
     importc: "uv_ip4_name", header: "uv.h".}
 
 proc ip6_name*(src: ptr TSockAddrIn6, dst: cstring, size: csize): cint{.
diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim
index 9161f5672..937a8952a 100644
--- a/lib/wrappers/mysql.nim
+++ b/lib/wrappers/mysql.nim
@@ -13,7 +13,7 @@
 when defined(Unix):
   when defined(macosx):
     const
-      lib = "libmysqlclient.(15|16|17[18).dylib"
+      lib = "libmysqlclient.(15|16|17|18).dylib"
   else:
     const
       lib = "libmysqlclient.so.(15|16|17|18)"
@@ -63,9 +63,9 @@ type
 const 
   SCRAMBLE_LENGTH* = 20 # Length of random string sent by server on handshake; 
                         # this is also length of obfuscated password, 
-                        # recieved from client
+                        # received from client
   SCRAMBLE_LENGTH_323* = 8    # length of password stored in the db: 
-                              # new passwords are preceeded with '*'  
+                              # new passwords are preceded with '*'  
   SCRAMBLED_PASSWORD_CHAR_LENGTH* = SCRAMBLE_LENGTH * 2 + 1
   SCRAMBLED_PASSWORD_CHAR_LENGTH_323* = SCRAMBLE_LENGTH_323 * 2
   NOT_NULL_FLAG* = 1          #  Field can't be NULL
@@ -146,7 +146,7 @@ const
   MAX_MEDIUMINT_WIDTH* = 8    # Max width for a INT24 w.o. sign
   MAX_INT_WIDTH* = 10         # Max width for a LONG w.o. sign
   MAX_BIGINT_WIDTH* = 20      # Max width for a LONGLONG
-  MAX_CHAR_WIDTH* = 255       # Max length for a CHAR colum
+  MAX_CHAR_WIDTH* = 255       # Max length for a CHAR column
   MAX_BLOB_WIDTH* = 8192      # Default width for blob
 
 type 
@@ -558,7 +558,7 @@ type
   Tstatus* = enum 
     STATUS_READY, STATUS_GET_RESULT, STATUS_USE_RESULT
   Tprotocol_type* = enum  # There are three types of queries - the ones that have to go to
-                          # the master, the ones that go to a slave, and the adminstrative
+                          # the master, the ones that go to a slave, and the administrative
                           # type which must happen on the pivot connectioin 
     PROTOCOL_DEFAULT, PROTOCOL_TCP, PROTOCOL_SOCKET, PROTOCOL_PIPE, 
     PROTOCOL_MEMORY
@@ -790,7 +790,7 @@ proc server_init*(argc: cint, argv: cstringArray, groups: cstringArray): cint{.
 proc server_end*(){.cdecl, dynlib: lib, importc: "mysql_server_end".}
   # mysql_server_init/end need to be called when using libmysqld or
   #      libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so
-  #      you don't need to call it explicitely; but you need to call
+  #      you don't need to call it explicitly; but you need to call
   #      mysql_server_end() to free memory). The names are a bit misleading
   #      (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general
   #      names which suit well whether you're using libmysqld or libmysqlclient. We
diff --git a/lib/wrappers/readline/history.nim b/lib/wrappers/readline/history.nim
index caa857ceb..495bc15e4 100644
--- a/lib/wrappers/readline/history.nim
+++ b/lib/wrappers/readline/history.nim
@@ -231,7 +231,7 @@ proc history_truncate_file*(a2: cstring, a3: cint): cint{.cdecl,
 #  -1) If there was an error in expansion.
 #   2) If the returned line should just be printed.
 #
-#  If an error ocurred in expansion, then OUTPUT contains a descriptive
+#  If an error occurred in expansion, then OUTPUT contains a descriptive
 #  error message. 
 
 proc history_expand*(a2: cstring, a3: cstringArray): cint{.cdecl, 
diff --git a/lib/wrappers/readline/tweaked/history.h b/lib/wrappers/readline/tweaked/history.h
index 53bd642b1..b79123790 100644
--- a/lib/wrappers/readline/tweaked/history.h
+++ b/lib/wrappers/readline/tweaked/history.h
@@ -217,7 +217,7 @@ extern int history_truncate_file PARAMS((const char *, int));
   -1) If there was an error in expansion.
    2) If the returned line should just be printed.
 
-  If an error ocurred in expansion, then OUTPUT contains a descriptive
+  If an error occurred in expansion, then OUTPUT contains a descriptive
   error message. */
 extern int history_expand PARAMS((char *, char **));
 
diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index 449b651f9..5bb5b7ec2 100644
--- a/lib/wrappers/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
@@ -89,7 +89,7 @@
 #                           As most games will need it.
 #
 #   April    02 2001 - DL : Added SDL_getenv.h definitions and tested version
-#                           1.2.0 compatability.
+#                           1.2.0 compatibility.
 #
 #   March    13 2001 - MT : Added Linux compatibility.
 #
@@ -118,7 +118,7 @@
 #
 #  November  30 2001 - DL : SDL_NOFRAME added as pointed out by Simon Rushton.
 #
-#  December  11 2001 - DL : Added $WEAKPACKAGEUNIT ON to facilitate useage in
+#  December  11 2001 - DL : Added $WEAKPACKAGEUNIT ON to facilitate usage in
 #                           Components
 #
 #  January   05 2002 - DL : Added SDL_Swap32 function as suggested by Matthias
@@ -209,7 +209,7 @@
 #  forgot to apply Michalis Kamburelis' patch to the implementation section. now fixed
 #
 #  Revision 1.14  2004/12/23 23:42:18  savage
-#  Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability.
+#  Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatibility.
 #
 #  Revision 1.13  2004/09/30 22:31:59  savage
 #  Updated with slightly different header comments
@@ -221,7 +221,7 @@
 #  Updated so that Library name defines are correctly defined for MacOS X.
 #
 #  Revision 1.10  2004/07/20 23:57:33  savage
-#  Thanks to Paul Toth for spotting an error in the SDL Audio Convertion structures.
+#  Thanks to Paul Toth for spotting an error in the SDL Audio Conversion structures.
 #  In TSDL_AudioCVT the filters variable should point to and array of pointers and not what I had there previously.
 #
 #  Revision 1.9  2004/07/03 22:07:22  savage
@@ -243,7 +243,7 @@
 #  SDL_GetEnv Fix so that it is not define twice for FPC. Thanks to Rene Hugentobler for pointing out this bug,
 #
 #  Revision 1.3  2004/02/18 22:35:51  savage
-#  Brought sdl.pas up to 1.2.7 compatability
+#  Brought sdl.pas up to 1.2.7 compatibility
 #  Thus...
 #  Added SDL_GL_STEREO,
 #      SDL_GL_MULTISAMPLEBUFFERS,
diff --git a/lib/wrappers/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim
index 33a71508a..2f8664635 100644
--- a/lib/wrappers/sdl/sdl_mixer.nim
+++ b/lib/wrappers/sdl/sdl_mixer.nim
@@ -136,7 +136,7 @@
 #  Windows unit not used in this file, so it was removed to keep the code tidy.
 #
 #  Revision 1.3  2004/03/31 10:05:08  savage
-#  Better defines for Endianess under FreePascal and Borland compilers.
+#  Better defines for Endianness under FreePascal and Borland compilers.
 #
 #  Revision 1.2  2004/03/30 20:23:28  savage
 #  Tidied up use of UNIX compiler directive.
diff --git a/lib/wrappers/zip/zlib.nim b/lib/wrappers/zip/zlib.nim
index e3530d566..8bdb47106 100644
--- a/lib/wrappers/zip/zlib.nim
+++ b/lib/wrappers/zip/zlib.nim
@@ -232,7 +232,7 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string =
     return
 
   # Make sure memory allocated by inflateInit2() is freed eventually.
-  finally: discard inflateEnd(z)
+  defer: discard inflateEnd(z)
 
   # Decompress all of self.
   while true: