summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/astalgo.nim4
-rw-r--r--compiler/canonicalizer.nim4
-rw-r--r--compiler/ccgexprs.nim7
-rw-r--r--compiler/ccgthreadvars.nim2
-rw-r--r--compiler/ccgtrav.nim2
-rw-r--r--compiler/ccgtypes.nim4
-rw-r--r--compiler/idgen.nim2
-rw-r--r--compiler/options.nim4
-rw-r--r--compiler/platform.nim2
-rw-r--r--compiler/renderer.nim6
-rw-r--r--compiler/semcall.nim13
-rw-r--r--compiler/semstmts.nim8
-rw-r--r--doc/manual/exceptions.txt2
-rw-r--r--doc/manual/threads.txt2
-rw-r--r--doc/nimc.txt30
-rw-r--r--examples/cross_calculator/nim_commandline/nimcalculator.nim2
-rw-r--r--examples/cross_todo/nim_backend/backend.nim18
-rw-r--r--examples/cross_todo/nim_backend/testbackend.nim2
-rw-r--r--examples/cross_todo/nim_commandline/nimtodo.nim16
-rw-r--r--examples/talk/dsl.nim2
-rw-r--r--lib/deprecated/pure/actors.nim2
-rw-r--r--lib/deprecated/pure/sockets.nim1
-rw-r--r--lib/impure/nre.nim1
-rw-r--r--lib/packages/docutils/rst.nim14
-rw-r--r--lib/packages/docutils/rstgen.nim28
-rw-r--r--lib/pure/collections/LockFreeHash.nim2
-rw-r--r--lib/pure/collections/sets.nim2
-rw-r--r--lib/pure/colors.nim2
-rw-r--r--lib/pure/concurrency/threadpool.nim6
-rw-r--r--lib/pure/future.nim2
-rw-r--r--lib/pure/json.nim10
-rw-r--r--lib/pure/mersenne.nim2
-rw-r--r--lib/pure/net.nim2
-rw-r--r--lib/pure/os.nim8
-rw-r--r--lib/pure/osproc.nim2
-rw-r--r--lib/pure/selectors.nim10
-rw-r--r--lib/system.nim6
-rw-r--r--lib/system/gc.nim9
-rw-r--r--lib/system/gc_common.nim34
-rw-r--r--lib/system/sysspawn.nim2
-rw-r--r--lib/windows/winlean.nim89
-rw-r--r--tests/ccgbugs/tmissing_ccgtrav_unique_type.nim12
-rw-r--r--tests/ccgbugs/tunsafeaddr.nim9
-rw-r--r--tests/converter/tgenericconverter2.nim49
-rw-r--r--tests/cpp/tthread_createthread.nim2
-rw-r--r--tests/generics/tthread_generic.nim10
-rw-r--r--tests/manyloc/argument_parser/argument_parser.nim2
-rw-r--r--tests/manyloc/keineschweine/server/old_server_utils.nim2
-rw-r--r--tests/manyloc/keineschweine/server/old_sg_server.nim2
-rw-r--r--tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim4
-rw-r--r--tests/misc/tunsigned64mod.nim2
-rw-r--r--tests/misc/tunsignedcmp.nim2
-rw-r--r--tests/misc/tunsignedconv.nim2
-rw-r--r--tests/misc/tunsignedmisc.nim2
-rw-r--r--tests/parallel/tguard1.nim2
-rw-r--r--tests/stdlib/tnet_ll.nim39
-rw-r--r--tests/threads/threadex.nim2
-rw-r--r--tests/threads/tthreadanalysis.nim2
-rw-r--r--tests/threads/tthreadanalysis2.nim2
-rw-r--r--tests/threads/tthreadheapviolation1.nim2
-rw-r--r--tests/threads/ttryrecv.nim2
-rw-r--r--tests/typerel/tnoargopenarray.nim2
-rw-r--r--tests/types/tillegaltyperecursion.nim2
-rw-r--r--tools/website.tmpl10
-rw-r--r--web/assets/style.css10
-rw-r--r--web/learn.txt14
-rw-r--r--web/news.txt30
-rw-r--r--web/ticker.txt5
68 files changed, 423 insertions, 167 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 3ba43b4c5..1a70875d4 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -137,7 +137,7 @@ proc sameValue*(a, b: PNode): bool =
   of nkStrLit..nkTripleStrLit:
     if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal == b.strVal
   else:
-    # don't raise an internal error for 'nimrod check':
+    # don't raise an internal error for 'nim check':
     #InternalError(a.info, "SameValue")
     discard
 
@@ -152,7 +152,7 @@ proc leValue*(a, b: PNode): bool =
   of nkStrLit..nkTripleStrLit:
     if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal
   else:
-    # don't raise an internal error for 'nimrod check':
+    # don't raise an internal error for 'nim check':
     #InternalError(a.info, "leValue")
     discard
 
diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim
index dc6445035..9afe4ab10 100644
--- a/compiler/canonicalizer.nim
+++ b/compiler/canonicalizer.nim
@@ -11,7 +11,7 @@
 
 import strutils, db_sqlite, md5
 
-var db: TDbConn
+var db: DbConn
 
 # We *hash* the relevant information into 128 bit hashes. This should be good
 # enough to prevent any collisions.
@@ -33,7 +33,7 @@ type
 const
   cb64 = [
     "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
-    "O", "P", "Q", "R", "S", "T" "U", "V", "W", "X", "Y", "Z",
+    "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
     "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
     "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 3607f347e..fcc36e4fd 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1056,12 +1056,15 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
   var a, b, dest: TLoc
   initLocExpr(p, e.sons[1], a)
   initLocExpr(p, e.sons[2], b)
+  let bt = skipTypes(e.sons[2].typ, abstractVar)
   lineCg(p, cpsStmts, seqAppendPattern, [
       rdLoc(a),
       getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
-      getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))])
+      getTypeDesc(p.module, bt)])
   keepAlive(p, a)
-  initLoc(dest, locExpr, b.t, OnHeap)
+  #if bt != b.t:
+  #  echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
+  initLoc(dest, locExpr, bt, OnHeap)
   dest.r = rfmt(nil, "$1->data[$1->$2]", rdLoc(a), lenField(p))
   genAssignment(p, dest, b, {needToCopy, afDestIsNil})
   lineCg(p, cpsStmts, "++$1->$2;$n", rdLoc(a), lenField(p))
diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim
index d741c47a9..ab771d240 100644
--- a/compiler/ccgthreadvars.nim
+++ b/compiler/ccgthreadvars.nim
@@ -24,7 +24,7 @@ proc accessThreadLocalVar(p: BProc, s: PSym) =
       ropecg(p.module, "\tNimTV = (NimThreadVars*) #GetThreadLocalVars();$n"))
 
 var
-  nimtv: Rope                 # nimrod thread vars; the struct body
+  nimtv: Rope                 # Nim thread vars; the struct body
   nimtvDeps: seq[PType] = @[]  # type deps: every module needs whole struct
   nimtvDeclared = initIntSet() # so that every var/field exists only once
                                # in the struct
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index 5f59702e5..0da6396ea 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -57,6 +57,8 @@ proc parentObj(accessor: Rope; m: BModule): Rope {.inline.} =
 
 proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) =
   if typ == nil: return
+
+  let typ = getUniqueType(typ)
   var p = c.p
   case typ.kind
   of tyGenericInst, tyGenericBody, tyTypeDesc:
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 1ed9ce113..39f16ff0d 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -47,7 +47,7 @@ proc mangleName(s: PSym): Rope =
       # I need to study where these come from.
       #
       # about sfShadowed:
-      # consider the following nimrod code:
+      # consider the following Nim code:
       #   var x = 10
       #   block:
       #     var x = something(x)
@@ -64,7 +64,7 @@ proc mangleName(s: PSym): Rope =
       # use that in the inner scope.
       #
       # about isCKeyword:
-      # nimrod variable names can be C keywords.
+      # Nim variable names can be C keywords.
       # We need to avoid such names in the generated code.
       # XXX: Study whether mangleName is called just once per variable.
       # Otherwise, there might be better place to do this.
diff --git a/compiler/idgen.nim b/compiler/idgen.nim
index c07782fb2..906c16546 100644
--- a/compiler/idgen.nim
+++ b/compiler/idgen.nim
@@ -44,7 +44,7 @@ proc toGid(f: string): string =
   # we used to use ``f.addFileExt("gid")`` (aka ``$project.gid``), but this
   # will cause strange bugs if multiple projects are in the same folder, so
   # we simply use a project independent name:
-  result = options.completeGeneratedFilePath("nimrod.gid")
+  result = options.completeGeneratedFilePath("nim.gid")
 
 proc saveMaxIds*(project: string) =
   var f = open(project.toGid, fmWrite)
diff --git a/compiler/options.nim b/compiler/options.nim
index 9b587fcdb..c9e5e5b76 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -147,8 +147,8 @@ var
   gDllOverrides = newStringTable(modeCaseInsensitive)
   gPrefixDir* = "" # Overrides the default prefix dir in getPrefixDir proc.
   libpath* = ""
-  gProjectName* = "" # holds a name like 'nimrod'
-  gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/
+  gProjectName* = "" # holds a name like 'nim'
+  gProjectPath* = "" # holds a path like /home/alice/projects/nim/compiler/
   gProjectFull* = "" # projectPath/projectName
   gProjectIsStdin* = false # whether we're compiling from stdin
   gProjectMainIdx*: int32 # the canonical path id of the main module
diff --git a/compiler/platform.nim b/compiler/platform.nim
index 8376c2b32..dc414bfeb 100644
--- a/compiler/platform.nim
+++ b/compiler/platform.nim
@@ -10,7 +10,7 @@
 # This module contains data about the different processors
 # and operating systems.
 # Note: Unfortunately if an OS or CPU is listed here this does not mean that
-# Nimrod has been tested on this platform or that the RTL has been ported.
+# Nim has been tested on this platform or that the RTL has been ported.
 # Feel free to test for your excentric platform!
 
 import
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 8e4aa1831..34688c798 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -438,7 +438,7 @@ proc lsub(n: PNode): int =
         len("if_:_")
   of nkElifExpr: result = lsons(n) + len("_elif_:_")
   of nkElseExpr: result = lsub(n.sons[0]) + len("_else:_") # type descriptions
-  of nkTypeOfExpr: result = (if n.len > 0: lsub(n.sons[0]) else: 0)+len("type_")
+  of nkTypeOfExpr: result = (if n.len > 0: lsub(n.sons[0]) else: 0)+len("type()")
   of nkRefTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + len("ref")
   of nkPtrTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + len("ptr")
   of nkVarTy: result = (if n.len > 0: lsub(n.sons[0])+1 else: 0) + len("var")
@@ -1030,8 +1030,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
     putWithSpace(g, tkColon, ":")
     gsub(g, n.sons[0])
   of nkTypeOfExpr:
-    putWithSpace(g, tkType, "type")
+    put(g, tkType, "type")
+    put(g, tkParLe, "(")
     if n.len > 0: gsub(g, n.sons[0])
+    put(g, tkParRi, ")")
   of nkRefTy:
     if sonsLen(n) > 0:
       putWithSpace(g, tkRef, "ref")
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 8445b24d9..a0d0db3ad 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -255,12 +255,13 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
 
 
 proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
-  if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
-      isGenericRoutine(a.sons[0].sym):
-    let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info)
-    a.sons[0].sym = finalCallee
-    a.sons[0].typ = finalCallee.typ
-    #a.typ = finalCallee.typ.sons[0]
+  if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
+    let s = a.sons[0].sym
+    if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:
+      let finalCallee = generateInstance(c, s, x.bindings, a.info)
+      a.sons[0].sym = finalCallee
+      a.sons[0].typ = finalCallee.typ
+      #a.typ = finalCallee.typ.sons[0]
 
 proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
   assert n.kind in nkCallKinds
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index fdf147a2e..edcf079fa 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1101,6 +1101,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
 
     if n[namePos].kind == nkEmpty:
       s = newSym(kind, idAnon, getCurrOwner(), n.info)
+      incl(s.flags, sfUsed)
       isAnon = true
     else:
       s = semIdentDef(c, n.sons[0], kind)
@@ -1153,9 +1154,10 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     s.typ.flags.incl(tfIterator)
 
   var proto = searchForProc(c, oldScope, s)
-  if proto == nil:
-    if s.kind == skIterator and s.typ.callConv == ccClosure:
-      discard
+  if proto == nil or isAnon:
+    if s.kind == skIterator:
+      if s.typ.callConv != ccClosure:
+        s.typ.callConv = if isAnon: ccClosure else: ccInline
     else:
       s.typ.callConv = lastOptionEntry(c).defaultCC
     # add it here, so that recursive procs are possible:
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt
index d35130600..e7af65386 100644
--- a/doc/manual/exceptions.txt
+++ b/doc/manual/exceptions.txt
@@ -15,7 +15,7 @@ Example:
     try:
       var a = readLine(f)
       var b = readLine(f)
-      echo "sum: " & $(parseInt(a + parseInt(b)))
+      echo "sum: " & $(parseInt(a) + parseInt(b))
     except OverflowError:
       echo "overflow!"
     except ValueError:
diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt
index f2b79a34f..a1895362c 100644
--- a/doc/manual/threads.txt
+++ b/doc/manual/threads.txt
@@ -130,7 +130,7 @@ that ``spawn`` takes is restricted:
   programmer to be careful.
 * ``ref`` parameters are deeply copied which is a subtle semantic change and
   can cause performance problems but ensures memory safety. This deep copy
-  is performed via ``system.deepCopy`` and so can be overriden.
+  is performed via ``system.deepCopy`` and so can be overridden.
 * For *safe* data exchange between ``f`` and the caller a global ``TChannel``
   needs to be used. However, since spawn can return a result, often no further
   communication is required.
diff --git a/doc/nimc.txt b/doc/nimc.txt
index 95449d060..e7cb57037 100644
--- a/doc/nimc.txt
+++ b/doc/nimc.txt
@@ -333,21 +333,21 @@ Nim provides language integration with external IDEs through the
 idetools command. See the documentation of `idetools <idetools.html>`_
 for further information.
 
-
-Nim interactive mode
-====================
-
-The Nim compiler supports an interactive mode. This is also known as
-a `REPL`:idx: (*read eval print loop*). If Nim has been built with the
-``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal
-input management. To start Nim in interactive mode use the command
-``nim i``. To quit use the ``quit()`` command. To determine whether an input
-line is an incomplete statement to be continued these rules are used:
-
-1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
-2. The line starts with a space (indentation).
-3. The line is within a triple quoted string literal. However, the detection
-   does not work if the line contains more than one ``"""``.
+..
+  Nim interactive mode
+  ====================
+
+  The Nim compiler supports an interactive mode. This is also known as
+  a `REPL`:idx: (*read eval print loop*). If Nim has been built with the
+  ``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal
+  input management. To start Nim in interactive mode use the command
+  ``nim secret``. To quit use the ``quit()`` command. To determine whether an input
+  line is an incomplete statement to be continued these rules are used:
+
+  1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
+  2. The line starts with a space (indentation).
+  3. The line is within a triple quoted string literal. However, the detection
+     does not work if the line contains more than one ``"""``.
 
 
 Nim for embedded systems
diff --git a/examples/cross_calculator/nim_commandline/nimcalculator.nim b/examples/cross_calculator/nim_commandline/nimcalculator.nim
index 69d62a90c..3f7674dbb 100644
--- a/examples/cross_calculator/nim_commandline/nimcalculator.nim
+++ b/examples/cross_calculator/nim_commandline/nimcalculator.nim
@@ -3,7 +3,7 @@
 import backend, parseopt, strutils
 
 const
-  USAGE = """nimcalculator - Nimrod cross platform calculator
+  USAGE = """nimcalculator - Nim cross platform calculator
   (beta version, only integer addition is supported!)
 
 Usage:
diff --git a/examples/cross_todo/nim_backend/backend.nim b/examples/cross_todo/nim_backend/backend.nim
index 5b49bc4a9..6869665f8 100644
--- a/examples/cross_todo/nim_backend/backend.nim
+++ b/examples/cross_todo/nim_backend/backend.nim
@@ -1,6 +1,6 @@
 # Backend for a simple todo program with sqlite persistence.
 #
-# Most procs dealing with a TDbConn object may raise an EDb exception.
+# Most procs dealing with a DbConn object may raise an EDb exception.
 
 import db_sqlite, parseutils, strutils, times
 
@@ -42,7 +42,7 @@ proc initDefaults*(params: var TPagedParams) =
   params.showChecked = false
 
 
-proc openDatabase*(path: string): TDbConn =
+proc openDatabase*(path: string): DbConn =
   ## Creates or opens the sqlite3 database.
   ##
   ## Pass the path to the sqlite database, if the database doesn't exist it
@@ -86,7 +86,7 @@ proc getModificationDate*(todo: TTodo): Time =
   return todo.modificationDate
 
 
-proc update*(todo: var TTodo; conn: TDbConn): bool =
+proc update*(todo: var TTodo; conn: DbConn): bool =
   ## Checks the database for the object and refreshes its variables.
   ##
   ## Use this method if you (or another entity) have modified the database and
@@ -112,7 +112,7 @@ proc update*(todo: var TTodo; conn: TDbConn): bool =
     echo("Something went wrong selecting for id " & $todo.id)
 
 
-proc save*(todo: var TTodo; conn: TDbConn): bool =
+proc save*(todo: var TTodo; conn: DbConn): bool =
   ## Saves the current state of text, priority and isDone to the database.
   ##
   ## Returns true if the database object was updated (in which case the
@@ -135,7 +135,7 @@ proc save*(todo: var TTodo; conn: TDbConn): bool =
 
 # - Procs dealing directly with the database
 #
-proc addTodo*(conn: TDbConn; priority: int; text: string): TTodo =
+proc addTodo*(conn: DbConn; priority: int; text: string): TTodo =
   ## Inserts a new todo into the database.
   ##
   ## Returns the generated todo object. If there is an error EDb will be raised.
@@ -149,7 +149,7 @@ proc addTodo*(conn: TDbConn; priority: int; text: string): TTodo =
   result = initFromDB(todoId, text, priority, false, currentDate)
 
 
-proc deleteTodo*(conn: TDbConn; todoId: int64): int64 {.discardable.} =
+proc deleteTodo*(conn: DbConn; todoId: int64): int64 {.discardable.} =
   ## Deletes the specified todo identifier.
   ##
   ## Returns the number of rows which were affected (1 or 0)
@@ -157,7 +157,7 @@ proc deleteTodo*(conn: TDbConn; todoId: int64): int64 {.discardable.} =
   result = conn.execAffectedRows(query, $todoId)
 
 
-proc getNumEntries*(conn: TDbConn): int =
+proc getNumEntries*(conn: DbConn): int =
   ## Returns the number of entries in the Todos table.
   ##
   ## If the function succeeds, returns the zero or positive value, if something
@@ -171,7 +171,7 @@ proc getNumEntries*(conn: TDbConn): int =
     result = -1
 
 
-proc getPagedTodos*(conn: TDbConn; params: TPagedParams;
+proc getPagedTodos*(conn: DbConn; params: TPagedParams;
                     page = 0'i64): seq[TTodo] =
   ## Returns the todo entries for a specific page.
   ##
@@ -210,7 +210,7 @@ proc getPagedTodos*(conn: TDbConn; params: TPagedParams;
         row[3].parseBool, Time(row[4].parseInt)))
 
 
-proc getTodo*(conn: TDbConn; todoId: int64): ref TTodo =
+proc getTodo*(conn: DbConn; todoId: int64): ref TTodo =
   ## Returns a reference to a TTodo or nil if the todo could not be found.
   var tempTodo: TTodo
   tempTodo.id = todoId
diff --git a/examples/cross_todo/nim_backend/testbackend.nim b/examples/cross_todo/nim_backend/testbackend.nim
index 131dda1cf..6754f013a 100644
--- a/examples/cross_todo/nim_backend/testbackend.nim
+++ b/examples/cross_todo/nim_backend/testbackend.nim
@@ -3,7 +3,7 @@
 import backend, db_sqlite, strutils, times
 
 
-proc showPagedResults(conn: TDbConn; params: TPagedParams) =
+proc showPagedResults(conn: DbConn; params: TPagedParams) =
   ## Shows the contents of the database in pages of specified size.
   ##
   ## Hmm... I guess this is more of a debug proc which should be moved outside,
diff --git a/examples/cross_todo/nim_commandline/nimtodo.nim b/examples/cross_todo/nim_commandline/nimtodo.nim
index 4ab17e7a2..c8993b2c8 100644
--- a/examples/cross_todo/nim_commandline/nimtodo.nim
+++ b/examples/cross_todo/nim_commandline/nimtodo.nim
@@ -3,7 +3,7 @@
 import backend, db_sqlite, os, parseopt, parseutils, strutils, times
 
 const
-  USAGE = """nimtodo - Nimrod cross platform todo manager
+  USAGE = """nimtodo - Nim cross platform todo manager
 
 Usage:
   nimtodo [command] [list options]
@@ -191,11 +191,11 @@ proc parseCmdLine(): TParamConfig =
     abort("Used list options, but didn't specify the list command.", 10)
 
 
-proc generateDatabaseRows(conn: TDbConn) =
+proc generateDatabaseRows(conn: DbConn) =
   ## Adds some rows to the database ignoring errors.
   discard conn.addTodo(1, "Watch another random youtube video")
   discard conn.addTodo(2, "Train some starcraft moves for the league")
-  discard conn.addTodo(3, "Spread the word about Nimrod")
+  discard conn.addTodo(3, "Spread the word about Nim")
   discard conn.addTodo(4, "Give fruit superavit to neighbours")
   var todo = conn.addTodo(4, "Send tax form through snail mail")
   todo.isDone = true
@@ -209,7 +209,7 @@ proc generateDatabaseRows(conn: TDbConn) =
   echo("Generated some entries, they were added to your database.")
 
 
-proc listDatabaseContents(conn: TDbConn; listParams: TPagedParams) =
+proc listDatabaseContents(conn: DbConn; listParams: TPagedParams) =
   ## Dumps the database contents formatted to the standard output.
   ##
   ## Pass the list/filter parameters parsed from the commandline.
@@ -239,7 +239,7 @@ proc listDatabaseContents(conn: TDbConn; listParams: TPagedParams) =
       todo.text])
 
 
-proc deleteOneTodo(conn: TDbConn; todoId: int64) =
+proc deleteOneTodo(conn: DbConn; todoId: int64) =
   ## Deletes a single todo entry from the database.
   let numDeleted = conn.deleteTodo(todoId)
   if numDeleted > 0:
@@ -248,7 +248,7 @@ proc deleteOneTodo(conn: TDbConn; todoId: int64) =
     quit("Couldn't delete todo id " & $todoId, 11)
 
 
-proc deleteAllTodos(conn: TDbConn) =
+proc deleteAllTodos(conn: DbConn) =
   ## Deletes all the contents from the database.
   ##
   ## Note that it would be more optimal to issue a direct DELETE sql statement
@@ -273,7 +273,7 @@ proc deleteAllTodos(conn: TDbConn) =
   echo("Deleted $1 todo entries from database." % $counter)
 
 
-proc setTodoCheck(conn: TDbConn; todoId: int64; value: bool) =
+proc setTodoCheck(conn: DbConn; todoId: int64; value: bool) =
   ## Changes the check state of a todo entry to the specified value.
   let
     newState = if value: "checked" else: "unchecked"
@@ -293,7 +293,7 @@ proc setTodoCheck(conn: TDbConn; todoId: int64; value: bool) =
     quit("Error updating todo id $1 to $2." % [$todoId, newState])
 
 
-proc addTodo(conn: TDbConn; priority: int; tokens: seq[string]) =
+proc addTodo(conn: DbConn; priority: int; tokens: seq[string]) =
   ## Adds to the database a todo with the specified priority.
   ##
   ## The tokens are joined as a single string using the space character. The
diff --git a/examples/talk/dsl.nim b/examples/talk/dsl.nim
index 4dfab5cd7..1034c99d4 100644
--- a/examples/talk/dsl.nim
+++ b/examples/talk/dsl.nim
@@ -28,6 +28,6 @@ html mainPage:
     title "now look at this"
   body:
     ul:
-      li "Nimrod is quite capable"
+      li "Nim is quite capable"
 
 echo mainPage()
diff --git a/lib/deprecated/pure/actors.nim b/lib/deprecated/pure/actors.nim
index f0791f954..36bd41e9e 100644
--- a/lib/deprecated/pure/actors.nim
+++ b/lib/deprecated/pure/actors.nim
@@ -40,7 +40,7 @@ type
 
   Actor[In, Out] = object{.pure, final.}
     i: Channel[Task[In, Out]]
-    t: TThread[ptr Actor[In, Out]]
+    t: Thread[ptr Actor[In, Out]]
 
   PActor*[In, Out] = ptr Actor[In, Out] ## an actor
 {.deprecated: [TTask: Task, TActor: Actor].}
diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim
index 5d6fa0078..f7d0950d8 100644
--- a/lib/deprecated/pure/sockets.nim
+++ b/lib/deprecated/pure/sockets.nim
@@ -39,7 +39,6 @@ when hostOS == "solaris":
 
 import os, parseutils
 from times import epochTime
-import unsigned
 
 when defined(ssl):
   import openssl
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim
index 973f1f2ee..10700b59b 100644
--- a/lib/impure/nre.nim
+++ b/lib/impure/nre.nim
@@ -10,7 +10,6 @@
 from pcre import nil
 import nre.private.util
 import tables
-import unsigned
 from strutils import toLower, `%`
 from math import ceil
 import options
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index 2fbde632e..e1d5f902e 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -1518,7 +1518,7 @@ proc dirInclude(p: var RstParser): PRstNode =
       #  InternalError("Too many binary zeros in include file")
       result = parseDoc(q)
 
-proc dirCodeBlock(p: var RstParser, nimrodExtension = false): PRstNode =
+proc dirCodeBlock(p: var RstParser, nimExtension = false): PRstNode =
   ## Parses a code block.
   ##
   ## Code blocks are rnDirective trees with a `kind` of rnCodeBlock. See the
@@ -1526,8 +1526,8 @@ proc dirCodeBlock(p: var RstParser, nimrodExtension = false): PRstNode =
   ##
   ## Code blocks can come in two forms, the standard `code directive
   ## <http://docutils.sourceforge.net/docs/ref/rst/directives.html#code>`_ and
-  ## the nimrod extension ``.. code-block::``. If the block is an extension, we
-  ## want the default language syntax highlighting to be Nimrod, so we create a
+  ## the nim extension ``.. code-block::``. If the block is an extension, we
+  ## want the default language syntax highlighting to be Nim, so we create a
   ## fake internal field to comminicate with the generator. The field is named
   ## ``default-language``, which is unlikely to collide with a field specified
   ## by any random rst input file.
@@ -1545,16 +1545,16 @@ proc dirCodeBlock(p: var RstParser, nimrodExtension = false): PRstNode =
     result.sons[2] = n
 
   # Extend the field block if we are using our custom extension.
-  if nimrodExtension:
+  if nimExtension:
     # Create a field block if the input block didn't have any.
     if result.sons[1].isNil: result.sons[1] = newRstNode(rnFieldList)
     assert result.sons[1].kind == rnFieldList
-    # Hook the extra field and specify the Nimrod language as value.
+    # Hook the extra field and specify the Nim language as value.
     var extraNode = newRstNode(rnField)
     extraNode.add(newRstNode(rnFieldName))
     extraNode.add(newRstNode(rnFieldBody))
     extraNode.sons[0].add(newRstNode(rnLeaf, "default-language"))
-    extraNode.sons[1].add(newRstNode(rnLeaf, "Nimrod"))
+    extraNode.sons[1].add(newRstNode(rnLeaf, "Nim"))
     result.sons[1].add(extraNode)
 
   result.kind = rnCodeBlock
@@ -1641,7 +1641,7 @@ proc parseDotDot(p: var RstParser): PRstNode =
       else:
         rstMessage(p, meInvalidDirective, d)
     of dkCode: result = dirCodeBlock(p)
-    of dkCodeBlock: result = dirCodeBlock(p, nimrodExtension = true)
+    of dkCodeBlock: result = dirCodeBlock(p, nimExtension = true)
     of dkIndex: result = dirIndex(p)
     else: rstMessage(p, meInvalidDirective, d)
     popInd(p)
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index 22d944597..8b5bb0e8f 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -757,10 +757,15 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) =
   template valid(s): expr =
     s.len > 0 and allCharsInSet(s, {'.','/',':','%','_','\\','\128'..'\xFF'} +
                                    Digits + Letters + WhiteSpace)
-
-  var options = ""
+  let
+    arg = getArgument(n)
+    isObject = arg.toLower().endsWith(".svg")
+  var
+    options = ""
+    content = ""
   var s = getFieldValue(n, "scale")
-  if s.valid: dispA(d.target, options, " scale=\"$1\"", " scale=$1", [strip(s)])
+  if s.valid: dispA(d.target, options, if isObject: "" else: " scale=\"$1\"",
+                    " scale=$1", [strip(s)])
 
   s = getFieldValue(n, "height")
   if s.valid: dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)])
@@ -769,16 +774,21 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) =
   if s.valid: dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)])
 
   s = getFieldValue(n, "alt")
-  if s.valid: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)])
+  if s.valid:
+    # <object> displays its content if it cannot render the image
+    if isObject: dispA(d.target, content, "$1", "", [strip(s)])
+    else: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)])
 
   s = getFieldValue(n, "align")
   if s.valid: dispA(d.target, options, " align=\"$1\"", "", [strip(s)])
 
   if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options])
-
-  let arg = getArgument(n)
+  
   if arg.valid:
-    dispA(d.target, result, "<img src=\"$1\"$2 />", "\\includegraphics$2{$1}",
+    let htmlOut = if isObject:
+        "<object data=\"$1\" type=\"image/svg+xml\"$2 >" & content & "</object>"
+        else: "<img src=\"$1\"$2 />"
+    dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}",
           [arg, options])
   if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
 
@@ -802,7 +812,7 @@ proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) =
     if parseInt(n.getFieldValue, number) > 0:
       params.startLine = number
   of "file":
-    # The ``file`` option is a Nimrod extension to the official spec, it acts
+    # The ``file`` option is a Nim extension to the official spec, it acts
     # like it would for other directives like ``raw`` or ``cvs-table``. This
     # field is dealt with in ``rst.nim`` which replaces the existing block with
     # the referenced file, so we only need to ignore it here to avoid incorrect
@@ -871,7 +881,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
   ## second the code block itself. The code block can use syntax highlighting,
   ## which depends on the directive argument specified by the rst input, and
   ## may also come from the parser through the internal ``default-language``
-  ## option to differentiate between a plain code block and nimrod's code block
+  ## option to differentiate between a plain code block and Nim's code block
   ## extension.
   assert n.kind == rnCodeBlock
   if n.sons[2] == nil: return
diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim
index 1d4471b21..a3ead81e3 100644
--- a/lib/pure/collections/LockFreeHash.nim
+++ b/lib/pure/collections/LockFreeHash.nim
@@ -1,6 +1,6 @@
 #nim c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim
 
-import unsigned, math, hashes
+import math, hashes
 
 #------------------------------------------------------------------------------
 ## Memory Utility Functions
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index abe9cf85e..9a42a21ee 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -951,7 +951,7 @@ when isMainModule and not defined(release):
       var b = initOrderedSet[int]()
       for x in [2, 4, 5]: b.incl(x)
       assert($a == $b)
-      assert(a == b) # https://github.com/Araq/Nimrod/issues/1413
+      assert(a == b) # https://github.com/Araq/Nim/issues/1413
 
     block initBlocks:
       var a: OrderedSet[int]
diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim
index 7328f7c24..f4c027576 100644
--- a/lib/pure/colors.nim
+++ b/lib/pure/colors.nim
@@ -6,7 +6,7 @@
 #    distribution, for details about the copyright.
 #
 
-## This module implements color handling for Nimrod. It is used by
+## This module implements color handling for Nim. It is used by
 ## the ``graphics`` module.
 
 import strutils
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index 2603835dd..a30d49889 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -328,10 +328,10 @@ proc distinguishedSlave(w: ptr Worker) {.thread.} =
     if w.q.len != 0: w.cleanFlowVars
 
 var
-  workers: array[MaxThreadPoolSize, TThread[ptr Worker]]
+  workers: array[MaxThreadPoolSize, Thread[ptr Worker]]
   workersData: array[MaxThreadPoolSize, Worker]
 
-  distinguished: array[MaxDistinguishedThread, TThread[ptr Worker]]
+  distinguished: array[MaxDistinguishedThread, Thread[ptr Worker]]
   distinguishedData: array[MaxDistinguishedThread, Worker]
 
 when defined(nimPinToCpu):
@@ -468,7 +468,7 @@ proc nimSpawn3(fn: WorkerProc; data: pointer) {.compilerProc.} =
       await(gSomeReady)
 
 var
-  distinguishedLock: TLock
+  distinguishedLock: Lock
 
 initLock distinguishedLock
 
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index 4767266e5..3793edc8b 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -134,7 +134,7 @@ macro `[]`*(lc: ListComprehension, comp, typ: expr): expr =
   ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
   ## the type that will be stored inside the result seq.
   ##
-  ## .. code-block:: nimrod
+  ## .. code-block:: nim
   ##
   ##   echo lc[x | (x <- 1..10, x mod 2 == 0), int]
   ##
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index ab7d18bd8..f672a0c1b 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -712,17 +712,21 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
 
 proc toJson(x: NimNode): NimNode {.compiletime.} =
   case x.kind
-  of nnkBracket:
+  of nnkBracket: # array
     result = newNimNode(nnkBracket)
     for i in 0 .. <x.len:
       result.add(toJson(x[i]))
 
-  of nnkTableConstr:
+  of nnkTableConstr: # object
     result = newNimNode(nnkTableConstr)
     for i in 0 .. <x.len:
-      assert x[i].kind == nnkExprColonExpr
+      x[i].expectKind nnkExprColonExpr
       result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1])))
 
+  of nnkCurly: # empty object
+    result = newNimNode(nnkTableConstr)
+    x.expectLen(0)
+
   else:
     result = x
 
diff --git a/lib/pure/mersenne.nim b/lib/pure/mersenne.nim
index c8090dc6a..ae0845714 100644
--- a/lib/pure/mersenne.nim
+++ b/lib/pure/mersenne.nim
@@ -1,5 +1,3 @@
-import unsigned
-
 type
   MersenneTwister* = object
     mt: array[0..623, uint32]
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 947399646..346b656a0 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -794,7 +794,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
 
   template addNLIfEmpty(): stmt =
     if line.len == 0:
-      line.add("\c\L")
+      line.string.add("\c\L")
 
   template raiseSockError(): stmt {.dirty, immediate.} =
     let lastError = getSocketError(socket)
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 1e00f92b1..a92b74484 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -774,6 +774,7 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
       res: int
     res = findFirstFile(pattern, f)
     if res != -1:
+      defer: findClose(res)
       while true:
         if not skipFindData(f) and
             (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) == 0'i32:
@@ -786,7 +787,6 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
               pattern[dotPos+1] == '*':
             yield splitFile(pattern).dir / extractFilename(ff)
         if findNextFile(res, f) == 0'i32: break
-      findClose(res)
   else: # here we use glob
     var
       f: Glob
@@ -795,11 +795,11 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
     f.gl_pathc = 0
     f.gl_pathv = nil
     res = glob(pattern, 0, nil, addr(f))
+    defer: globfree(addr(f))
     if res == 0:
       for i in 0.. f.gl_pathc - 1:
         assert(f.gl_pathv[i] != nil)
         yield $f.gl_pathv[i]
-    globfree(addr(f))
 
 type
   PathComponent* = enum   ## Enumeration specifying a path component.
@@ -845,6 +845,7 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
       var f: WIN32_FIND_DATA
       var h = findFirstFile(dir / "*", f)
       if h != -1:
+        defer: findClose(h)
         while true:
           var k = pcFile
           if not skipFindData(f):
@@ -856,10 +857,10 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
                      else: dir / extractFilename(getFilename(f))
             yield (k, xx)
           if findNextFile(h, f) == 0'i32: break
-        findClose(h)
     else:
       var d = opendir(dir)
       if d != nil:
+        defer: discard closedir(d)
         while true:
           var x = readdir(d)
           if x == nil: break
@@ -883,7 +884,6 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
             if S_ISDIR(s.st_mode): k = pcDir
             if S_ISLNK(s.st_mode): k = succ(k)
             yield (k, y)
-        discard closedir(d)
 
 iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {.
   tags: [ReadDirEffect].} =
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 34fb81520..38b0ed4a3 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -876,7 +876,7 @@ elif not defined(useNimRtl):
       let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error))
       if sizeRead == sizeof(error):
         raiseOSError("Could not find command: '$1'. OS error: $2" %
-            [$data.sysCommand, $strerror(error)])
+          [$data.sysCommand, $strerror(error)])
 
       return pid
 
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index 832f5f4f9..89e92c133 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -9,7 +9,7 @@
 
 # TODO: Docs.
 
-import os, unsigned, hashes
+import os, hashes
 
 when defined(linux):
   import posix, epoll
@@ -118,7 +118,7 @@ elif defined(linux):
         # are therefore constantly ready. (leading to 100% CPU usage).
         if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0:
           raiseOSError(osLastError())
-        s.fds.mget(fd).events = events
+        s.fds[fd].events = events
       else:
         var event = createEventStruct(events, fd)
         if s.fds[fd].events == {}:
@@ -129,7 +129,7 @@ elif defined(linux):
         else:
           if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0:
             raiseOSError(osLastError())
-        s.fds.mget(fd).events = events
+        s.fds[fd].events = events
 
   proc unregister*(s: var Selector, fd: SocketHandle) =
     if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0:
@@ -229,7 +229,7 @@ elif defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd):
         modifyKQueue(s.kqFD, fd, event, EV_ADD)
       for event in previousEvents-events:
         modifyKQueue(s.kqFD, fd, event, EV_DELETE)
-      s.fds.mget(fd).events = events
+      s.fds[fd].events = events
 
   proc unregister*(s: var Selector, fd: SocketHandle) =
     for event in s.fds[fd].events:
@@ -298,7 +298,7 @@ elif not defined(nimdoc):
   proc update*(s: var Selector, fd: SocketHandle, events: set[Event]) =
     #if not s.fds.hasKey(fd):
     #  raise newException(ValueError, "File descriptor not found.")
-    s.fds.mget(fd).events = events
+    s.fds[fd].events = events
 
   proc unregister*(s: var Selector, fd: SocketHandle) =
     s.fds.del(fd)
diff --git a/lib/system.nim b/lib/system.nim
index e884e784c..1a0a11ff0 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -151,7 +151,7 @@ proc `addr`*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} =
   ##  echo cast[ptr char](p)[]    # b
   discard
 
-proc unsafeAddr*[T](x: var T): ptr T {.magic: "Addr", noSideEffect.} =
+proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
   ## Builtin 'addr' operator for taking the address of a memory location.
   ## This works even for ``let`` variables or parameters for better interop
   ## with C and so it is considered even more unsafe than the ordinary ``addr``.
@@ -1811,7 +1811,7 @@ const
   NimMinor*: int = 13
     ## is the minor number of Nim's version.
 
-  NimPatch*: int = 0
+  NimPatch*: int = 1
     ## is the patch number of Nim's version.
 
   NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
@@ -2960,9 +2960,9 @@ when not defined(JS): #and not defined(nimscript):
       ##       buffer.add(line.replace("a", "0") & '\x0A')
       ##     writeFile(filename, buffer)
       var f = open(filename, bufSize=8000)
+      defer: close(f)
       var res = TaintedString(newStringOfCap(80))
       while f.readLine(res): yield res
-      close(f)
 
     iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} =
       ## Iterate over any line in the file `f`.
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 727b039d7..d8390ca14 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -325,6 +325,8 @@ proc cellsetReset(s: var CellSet) =
   deinit(s)
   init(s)
 
+{.push stacktrace:off.}
+
 proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
   var d = cast[ByteAddress](dest)
   case n.kind
@@ -459,7 +461,8 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
   result = cellToUsr(res)
   sysAssert(allocInv(gch.region), "rawNewObj end")
 
-{.pop.}
+{.pop.} # .stackTrace off
+{.pop.} # .profiler off
 
 proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} =
   result = rawNewObj(typ, size, gch)
@@ -576,7 +579,7 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
 proc growObj(old: pointer, newsize: int): pointer {.rtl.} =
   result = growObj(old, newsize, gch)
 
-{.push profiler:off.}
+{.push profiler:off, stackTrace:off.}
 
 # ---------------- cycle collector -------------------------------------------
 
@@ -1018,4 +1021,4 @@ when not defined(useNimRtl):
       result = result & "[GC] max stack size: " & $gch.stat.maxStackSize & "\n"
     GC_enable()
 
-{.pop.}
+{.pop.} # profiler: off, stackTrace: off
diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim
index fdedcaf18..013dc55f8 100644
--- a/lib/system/gc_common.nim
+++ b/lib/system/gc_common.nim
@@ -78,19 +78,29 @@ iterator items(stack: ptr GcStack): ptr GcStack =
     yield s
     s = s.next
 
-var
-  localGcInitialized {.rtlThreadVar.}: bool
+# There will be problems with GC in foreign threads if `threads` option is off or TLS emulation is enabled
+const allowForeignThreadGc = compileOption("threads") and not compileOption("tlsEmulation")
 
-proc setupForeignThreadGc*() =
-  ## call this if you registered a callback that will be run from a thread not
-  ## under your control. This has a cheap thread-local guard, so the GC for
-  ## this thread will only be initialized once per thread, no matter how often
-  ## it is called.
-  if not localGcInitialized:
-    localGcInitialized = true
-    var stackTop {.volatile.}: pointer
-    setStackBottom(addr(stackTop))
-    initGC()
+when allowForeignThreadGc:
+  var
+    localGcInitialized {.rtlThreadVar.}: bool
+
+  proc setupForeignThreadGc*() =
+    ## Call this if you registered a callback that will be run from a thread not
+    ## under your control. This has a cheap thread-local guard, so the GC for
+    ## this thread will only be initialized once per thread, no matter how often
+    ## it is called.
+    ##
+    ## This function is availble only when ``--threads:on`` and ``--tlsEmulation:off``
+    ## switches are used
+    if not localGcInitialized:
+      localGcInitialized = true
+      var stackTop {.volatile.}: pointer
+      setStackBottom(addr(stackTop))
+      initGC()
+else:
+  template setupForeignThreadGc*(): stmt =
+    {.error: "setupForeignThreadGc is availble only when ``--threads:on`` and ``--tlsEmulation:off`` are used".}
 
 # ----------------- stack management --------------------------------------
 #  inspired from Smart Eiffel
diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim
index 7aef86df9..7da45b4dd 100644
--- a/lib/system/sysspawn.nim
+++ b/lib/system/sysspawn.nim
@@ -138,7 +138,7 @@ proc slave(w: ptr Worker) {.thread.} =
 const NumThreads = 4
 
 var
-  workers: array[NumThreads, TThread[ptr Worker]]
+  workers: array[NumThreads, Thread[ptr Worker]]
   workersData: array[NumThreads, Worker]
 
 proc setup() =
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 4962186fb..d12c661d6 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -12,9 +12,18 @@
 
 {.deadCodeElim:on.}
 
+import dynlib
+
 const
   useWinUnicode* = not defined(useWinAnsi)
 
+when useWinUnicode:
+  type WinChar* = Utf16Char
+  {.deprecated: [TWinChar: WinChar].}
+else:
+  type WinChar* = char
+  {.deprecated: [TWinChar: WinChar].}
+
 type
   Handle* = int
   LONG* = int32
@@ -74,17 +83,18 @@ type
     nFileIndexHigh*: DWORD
     nFileIndexLow*: DWORD
 
+  OSVERSIONINFO* {.final, pure.} = object
+    dwOSVersionInfoSize*: DWORD
+    dwMajorVersion*: DWORD
+    dwMinorVersion*: DWORD
+    dwBuildNumber*: DWORD
+    dwPlatformId*: DWORD
+    szCSDVersion*: array[0..127, WinChar];
+
 {.deprecated: [THandle: Handle, TSECURITY_ATTRIBUTES: SECURITY_ATTRIBUTES,
     TSTARTUPINFO: STARTUPINFO, TPROCESS_INFORMATION: PROCESS_INFORMATION,
     TFILETIME: FILETIME, TBY_HANDLE_FILE_INFORMATION: BY_HANDLE_FILE_INFORMATION].}
 
-when useWinUnicode:
-  type WinChar* = Utf16Char
-  {.deprecated: [TWinChar: WinChar].}
-else:
-  type WinChar* = char
-  {.deprecated: [TWinChar: WinChar].}
-
 const
   STARTF_USESHOWWINDOW* = 1'i32
   STARTF_USESTDHANDLES* = 256'i32
@@ -117,6 +127,13 @@ const
 
   CREATE_NO_WINDOW* = 0x08000000'i32
 
+when useWinUnicode:
+  proc getVersionExW*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExW".}
+else:
+  proc getVersionExA*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExA".}
+
+proc getVersion*(): DWORD {.stdcall, dynlib: "kernel32", importc: "GetVersion".}
+
 proc closeHandle*(hObject: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
     importc: "CloseHandle".}
 
@@ -192,6 +209,9 @@ proc flushFileBuffers*(hFile: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
 proc getLastError*(): int32 {.importc: "GetLastError",
     stdcall, dynlib: "kernel32".}
 
+proc setLastError*(error: int32) {.importc: "SetLastError",
+    stdcall, dynlib: "kernel32".}
+
 when useWinUnicode:
   proc formatMessageW*(dwFlags: int32, lpSource: pointer,
                       dwMessageId, dwLanguageId: int32,
@@ -597,9 +617,6 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
 proc inet_ntoa*(i: InAddr): cstring {.
   stdcall, importc, dynlib: ws2dll.}
 
-proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
-            stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
-
 const
   MAXIMUM_WAIT_OBJECTS* = 0x00000040
 
@@ -645,6 +662,7 @@ const
 const
   ERROR_ACCESS_DENIED* = 5
   ERROR_HANDLE_EOF* = 38
+  ERROR_BAD_ARGUMENTS* = 165
 
 proc duplicateHandle*(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
                       hTargetProcessHandle: HANDLE,
@@ -806,3 +824,54 @@ proc getSystemTimes*(lpIdleTime, lpKernelTime,
 proc getProcessTimes*(hProcess: Handle; lpCreationTime, lpExitTime,
   lpKernelTime, lpUserTime: var FILETIME): WINBOOL {.stdcall,
   dynlib: "kernel32", importc: "GetProcessTimes".}
+
+type inet_ntop_proc = proc(family: cint, paddr: pointer, pStringBuffer: cstring,
+                      stringBufSize: int32): cstring {.stdcall.}
+
+var inet_ntop_real: inet_ntop_proc = nil
+
+let l = loadLib(ws2dll)
+if l != nil:
+  inet_ntop_real = cast[inet_ntop_proc](symAddr(l, "inet_ntop"))
+
+proc WSAAddressToStringA(pAddr: ptr SockAddr, addrSize: DWORD, unused: pointer, pBuff: cstring, pBuffSize: ptr DWORD): cint {.stdcall, importc, dynlib: ws2dll.}
+proc inet_ntop_emulated(family: cint, paddr: pointer, pStringBuffer: cstring,
+                  stringBufSize: int32): cstring {.stdcall.} =
+    case family
+    of AF_INET:
+      var sa: Sockaddr_in
+      sa.sin_family = AF_INET
+      sa.sin_addr = cast[ptr InAddr](paddr)[]
+      var bs = stringBufSize.DWORD
+      let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
+      if r != 0:
+        result = nil
+      else:
+        result = pStringBuffer
+    of AF_INET6:
+      var sa: Sockaddr_in6
+      sa.sin6_family = AF_INET6
+      sa.sin6_addr = cast[ptr In6_addr](paddr)[]
+      var bs = stringBufSize.DWORD
+      let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
+      if r != 0:
+        result = nil
+      else:
+        result = pStringBuffer
+    else:
+      setLastError(ERROR_BAD_ARGUMENTS)
+      result = nil
+
+proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
+                  stringBufSize: int32): cstring {.stdcall.} =
+  var ver: OSVERSIONINFO
+  ver.dwOSVersionInfoSize = sizeof(ver).DWORD
+  let res = when useWinUnicode: getVersionExW(ver.addr) else: getVersionExA(ver.addr)
+  if res == 0:
+    result = nil
+  elif ver.dwMajorVersion >= 6:
+    if inet_ntop_real == nil:
+      quit("Can't load inet_ntop proc from " & ws2dll)
+    result = inet_ntop_real(family, paddr, pStringBuffer, stringBufSize)
+  else:
+    result = inet_ntop_emulated(family, paddr, pStringBuffer, stringBufSize)
diff --git a/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim b/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim
new file mode 100644
index 000000000..cb87eabd8
--- /dev/null
+++ b/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim
@@ -0,0 +1,12 @@
+
+# bug #3794
+
+
+import options
+
+proc getRef*(): Option[int] =
+  return none(int)
+
+proc getChild*() =
+  let iter = iterator (): int {.closure.} =
+    let reference = getRef()
diff --git a/tests/ccgbugs/tunsafeaddr.nim b/tests/ccgbugs/tunsafeaddr.nim
index 518e05b25..8d0a9d8cb 100644
--- a/tests/ccgbugs/tunsafeaddr.nim
+++ b/tests/ccgbugs/tunsafeaddr.nim
@@ -16,4 +16,13 @@ proc main =
   let foo = [8, 3, 1]
   echo sum(unsafeAddr foo[0], foo.len)
 
+
+# bug #3736
+
+proc p(x: seq[int]) = discard x[0].unsafeAddr # works
+proc q(x: seq[SomeInteger]) = discard x[0].unsafeAddr # doesn't work
+
+p(@[1])
+q(@[1])
+
 main()
diff --git a/tests/converter/tgenericconverter2.nim b/tests/converter/tgenericconverter2.nim
new file mode 100644
index 000000000..ae064d852
--- /dev/null
+++ b/tests/converter/tgenericconverter2.nim
@@ -0,0 +1,49 @@
+# bug #3799
+
+import macros
+
+const nmax = 500
+
+type
+  Complex*[T] = object
+    re*: T
+    im*: T
+
+converter toComplex*[T](x: tuple[re, im: T]): Complex[T] =
+  result.re = x.re
+  result.im = x.im
+
+
+proc julia*[T](z0, c: Complex[T], er2: T, nmax: int): int =
+  result = 0
+  var z = z0
+  var sre = z0.re * z0.re
+  var sim = z0.im * z0.im
+  while (result < nmax) and (sre + sim < er2):
+    z.im = z.re * z.im
+    z.im = z.im + z.im
+    z.im = z.im + c.im
+    z.re = sre - sim + c.re
+    sre = z.re * z.re
+    sim = z.im * z.im
+    inc result
+
+template dendriteFractal*[T](z0: Complex[T], er2: T, nmax: int): int =
+  julia(z0, (T(0.0), T(1.0)), er2, nmax)
+
+iterator stepIt[T](start, step: T, iterations: int): T =
+  for i in 0 .. iterations:
+    yield start + T(i) * step
+
+
+let c = (0.36237, 0.32)
+for y in stepIt(2.0, -0.0375, 107):
+  var row = ""
+  for x in stepIt(-2.0, 0.025, 160):
+    #let n = julia((x, y), c, 4.0, nmax)         ### this works
+    let n = dendriteFractal((x, y), 4.0, nmax)
+    if n < nmax:
+      row.add($(n mod 10))
+    else:
+      row.add(' ')
+  echo row
diff --git a/tests/cpp/tthread_createthread.nim b/tests/cpp/tthread_createthread.nim
index 2c239005f..363136e9d 100644
--- a/tests/cpp/tthread_createthread.nim
+++ b/tests/cpp/tthread_createthread.nim
@@ -6,7 +6,7 @@ proc threadMain(a: int) {.thread.} =
     discard
 
 proc main() =
-    var thread: TThread[int]
+    var thread: Thread[int]
 
     thread.createThread(threadMain, 0)
     thread.joinThreads()
diff --git a/tests/generics/tthread_generic.nim b/tests/generics/tthread_generic.nim
index e8946caf6..def1acfe1 100644
--- a/tests/generics/tthread_generic.nim
+++ b/tests/generics/tthread_generic.nim
@@ -3,20 +3,20 @@ discard """
 """
 
 type
-  TThreadFuncArgs[T] = object of RootObj
+  ThreadFuncArgs[T] = object of RootObj
     a: proc(): T {.thread.}
     b: proc(val: T) {.thread.}
 
-proc handleThreadFunc(arg: TThreadFuncArgs[int]){.thread.} =
+proc handleThreadFunc(arg: ThreadFuncArgs[int]){.thread.} =
   var fn = arg.a
   var callback = arg.b
   var output = fn()
   callback(output)
 
 proc `@||->`*[T](fn: proc(): T {.thread.},
-                 callback: proc(val: T){.thread.}): TThread[TThreadFuncArgs[T]] =
-  var thr: TThread[TThreadFuncArgs[T]]
-  var args: TThreadFuncArgs[T]
+                 callback: proc(val: T){.thread.}): Thread[ThreadFuncArgs[T]] =
+  var thr: Thread[ThreadFuncArgs[T]]
+  var args: ThreadFuncArgs[T]
   args.a = fn
   args.b = callback
   createThread(thr, handleThreadFunc, args)
diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim
index 060610ae0..97de552e3 100644
--- a/tests/manyloc/argument_parser/argument_parser.nim
+++ b/tests/manyloc/argument_parser/argument_parser.nim
@@ -1,4 +1,4 @@
-## Command line parsing module for Nimrod.
+## Command line parsing module for Nim.
 ##
 ## `Nim <http://nim-lang.org>`_ provides the `parseopt module
 ## <http://nim-lang.org/parseopt.html>`_ to parse options from the
diff --git a/tests/manyloc/keineschweine/server/old_server_utils.nim b/tests/manyloc/keineschweine/server/old_server_utils.nim
index d0fd39ae0..3da6e078c 100644
--- a/tests/manyloc/keineschweine/server/old_server_utils.nim
+++ b/tests/manyloc/keineschweine/server/old_server_utils.nim
@@ -1,5 +1,5 @@
 import
-  streams, md5, sockets, unsigned,
+  streams, md5, sockets,
   sg_packets, zlib_helpers, idgen
 type
   TClientType* = enum
diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim
index c326720fe..bddc74c6d 100644
--- a/tests/manyloc/keineschweine/server/old_sg_server.nim
+++ b/tests/manyloc/keineschweine/server/old_sg_server.nim
@@ -1,5 +1,5 @@
 import
-  sockets, times, streams, streams_enh, tables, json, os, unsigned,
+  sockets, times, streams, streams_enh, tables, json, os,
   sg_packets, sg_assets, md5, server_utils, client_helpers
 var
   dirServer: PServer
diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
index cdd5aaf03..b84be7a4c 100644
--- a/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
+++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim
@@ -8,10 +8,6 @@ from strutils import
   `%`,
   ffDecimal
 
-from unsigned import
-  `shr`,
-  `and`
-
 type
   TColor* = tuple[r, g, b, a: TR]
 
diff --git a/tests/misc/tunsigned64mod.nim b/tests/misc/tunsigned64mod.nim
index 3007405a2..9c9e01c45 100644
--- a/tests/misc/tunsigned64mod.nim
+++ b/tests/misc/tunsigned64mod.nim
@@ -1,8 +1,6 @@
 
 # bug #1638
 
-import unsigned
-
 let v1 = 7
 let v2 = 7'u64
 
diff --git a/tests/misc/tunsignedcmp.nim b/tests/misc/tunsignedcmp.nim
index a66fbaae1..9ffc0d119 100644
--- a/tests/misc/tunsignedcmp.nim
+++ b/tests/misc/tunsignedcmp.nim
@@ -5,8 +5,6 @@ true'''
 """
 
 # bug 1420
-import unsigned
-
 var x = 40'u32
 var y = 30'u32
 echo x > y # works
diff --git a/tests/misc/tunsignedconv.nim b/tests/misc/tunsignedconv.nim
index 3032f8de6..956e014da 100644
--- a/tests/misc/tunsignedconv.nim
+++ b/tests/misc/tunsignedconv.nim
@@ -1,6 +1,4 @@
 
-import unsigned
-
 # Tests unsigned literals and implicit conversion between uints and ints
 # Passes if it compiles
 
diff --git a/tests/misc/tunsignedmisc.nim b/tests/misc/tunsignedmisc.nim
index e6a497a3d..4b8157ddd 100644
--- a/tests/misc/tunsignedmisc.nim
+++ b/tests/misc/tunsignedmisc.nim
@@ -1,5 +1,3 @@
-import unsigned
-
 discard """
   errormsg: "number 0x123'u8 out of valid range"
 """
diff --git a/tests/parallel/tguard1.nim b/tests/parallel/tguard1.nim
index d96e17589..3e0c131c5 100644
--- a/tests/parallel/tguard1.nim
+++ b/tests/parallel/tguard1.nim
@@ -1,6 +1,6 @@
 
 when false:
-  template lock(a, b: ptr TLock; body: stmt) =
+  template lock(a, b: ptr Lock; body: stmt) =
     if cast[ByteAddress](a) < cast[ByteAddress](b):
       pthread_mutex_lock(a)
       pthread_mutex_lock(b)
diff --git a/tests/stdlib/tnet_ll.nim b/tests/stdlib/tnet_ll.nim
new file mode 100644
index 000000000..4d4df7c13
--- /dev/null
+++ b/tests/stdlib/tnet_ll.nim
@@ -0,0 +1,39 @@
+discard """

+  action: run

+"""

+

+when defined(windows):

+  import winlean

+elif defined(posix):

+  import posix

+else:

+  {.error: "Unsupported OS".}

+

+import unittest, strutils

+

+suite "inet_ntop tests":

+

+  setup:

+    when defined(windows):

+      var wsa: WSAData

+      discard wsaStartup(0x101'i16, wsa.addr)

+  

+  test "IP V4":

+    var ip4 = 0x10111213

+    var buff: array[0..255, char]

+    let r = inet_ntop(AF_INET, ip4.addr, buff[0].addr, buff.sizeof.int32)

+    let res = if r == nil: "" else: $r

+    check: res == "19.18.17.16"

+      

+

+  test "IP V6":

+    when defined(windows):

+      let ipv6Support = (getVersion() and 0xff) > 0x5

+    else:

+      let ipv6Support = true

+          

+    var ip6 = [0x1000'u16, 0x1001, 0x2000, 0x2001, 0x3000, 0x3001, 0x4000, 0x4001]

+    var buff: array[0..255, char]

+    let r = inet_ntop(AF_INET6, ip6[0].addr, buff[0].addr, buff.sizeof.int32)

+    let res = if r == nil: "" else: $r

+    check: not ipv6Support or res == "10:110:20:120:30:130:40:140"

diff --git a/tests/threads/threadex.nim b/tests/threads/threadex.nim
index 545d1f0cc..00d0992a5 100644
--- a/tests/threads/threadex.nim
+++ b/tests/threads/threadex.nim
@@ -11,7 +11,7 @@ type
     of mLine: data: string
 
 var
-  producer, consumer: TThread[void]
+  producer, consumer: Thread[void]
   chan: TChannel[TMsg]
   printedLines = 0
 
diff --git a/tests/threads/tthreadanalysis.nim b/tests/threads/tthreadanalysis.nim
index 6ef4de0bf..a6a847a0a 100644
--- a/tests/threads/tthreadanalysis.nim
+++ b/tests/threads/tthreadanalysis.nim
@@ -8,7 +8,7 @@ discard """
 import os
 
 var
-  thr: array [0..5, TThread[tuple[a, b: int]]]
+  thr: array [0..5, Thread[tuple[a, b: int]]]
 
 proc doNothing() = discard
 
diff --git a/tests/threads/tthreadanalysis2.nim b/tests/threads/tthreadanalysis2.nim
index 07d77028b..93d169f0b 100644
--- a/tests/threads/tthreadanalysis2.nim
+++ b/tests/threads/tthreadanalysis2.nim
@@ -8,7 +8,7 @@ discard """
 import os
 
 var
-  thr: array [0..5, TThread[tuple[a, b: int]]]
+  thr: array [0..5, Thread[tuple[a, b: int]]]
 
 proc doNothing() = discard
 
diff --git a/tests/threads/tthreadheapviolation1.nim b/tests/threads/tthreadheapviolation1.nim
index 02ce7878a..59ecb742c 100644
--- a/tests/threads/tthreadheapviolation1.nim
+++ b/tests/threads/tthreadheapviolation1.nim
@@ -6,7 +6,7 @@ discard """
 
 var
   global: string = "test string"
-  t: TThread[void]
+  t: Thread[void]
 
 proc horrible() {.thread.} =
   global = "string in thread local heap!"
diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim
index 28529b5ac..fc1f21321 100644
--- a/tests/threads/ttryrecv.nim
+++ b/tests/threads/ttryrecv.nim
@@ -15,7 +15,7 @@ proc doAction(outC: PComm) {.thread.} =
     send(outC[], i)
 
 var
-  thr: TThread[PComm]
+  thr: Thread[PComm]
   chan: TChannel[int]
 
 open(chan)
diff --git a/tests/typerel/tnoargopenarray.nim b/tests/typerel/tnoargopenarray.nim
index 3e65194ff..20ebe5ecc 100644
--- a/tests/typerel/tnoargopenarray.nim
+++ b/tests/typerel/tnoargopenarray.nim
@@ -1,7 +1,7 @@
 
 import db_sqlite
 
-var db: TDbConn
+var db: DbConn
 exec(db, sql"create table blabla()")
 
 
diff --git a/tests/types/tillegaltyperecursion.nim b/tests/types/tillegaltyperecursion.nim
index 52fbd622f..6ead902b7 100644
--- a/tests/types/tillegaltyperecursion.nim
+++ b/tests/types/tillegaltyperecursion.nim
@@ -52,7 +52,7 @@ proc Connect*(irc: var TIRC, nick: string, host: string, port: int = 6667) =
     connect(irc.Socket, host, TPort(port), TDomain.AF_INET)
     send(irc.Socket,"USER " & nick & " " & nick & " " & nick & " " & nick & "\r\L")
     send(irc.Socket,"NICK " & nick & "\r\L")
-    var thread: TThread[TIRC]
+    var thread: Thread[TIRC]
     createThread(thread, handleData, irc)
     irc.Thread = thread
 
diff --git a/tools/website.tmpl b/tools/website.tmpl
index d2fcb0afd..50152a051 100644
--- a/tools/website.tmpl
+++ b/tools/website.tmpl
@@ -49,7 +49,12 @@
 #  if currentTab == "index":
         <div id="slideshow">
           <!-- slides -->
-          <div id="slide0" class="active codeslide2">
+          <div id="slide0" class="active niaslide">
+            <a href="news.html#Z2016-01-27-nim-in-action-is-now-available">
+              <img src="assets/niminaction/banner.jpg" alt="New in Manning Early Access Program: Nim in Action!"/>
+            </a>
+          </div>
+          <div id="slide1" class="codeslide2">
             <div>
               <h2>Nim is simple..</h2>
 <pre>
@@ -83,7 +88,7 @@ p.greet() <span class="cmt"># or greet(p)</span>
 </pre>
              </div>
           </div>
-          <div id="slide1" class="codeslide3">
+          <div id="slide2" class="codeslide3">
             <div>
               <h2>C FFI is easy in Nim..</h2>
 <pre>
@@ -119,6 +124,7 @@ runForever()
         <div id="slideshow-nav">
           <div id="slideControl0" onclick="slideshow_click(0)" class="active"></div>
           <div id="slideControl1" onclick="slideshow_click(1)"></div>
+          <div id="slideControl2" onclick="slideshow_click(2)"></div>
         </div>
 #  end
         <aside id="sidebar">
diff --git a/web/assets/style.css b/web/assets/style.css
index 15886ae2e..529358ec9 100644
--- a/web/assets/style.css
+++ b/web/assets/style.css
@@ -130,10 +130,12 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; }
 	#slideshow-nav > div:hover { background-image:url("images/slideshow-nav_active.png"); opacity:0.5; }
 	#slideshow-nav > div.active { background-image:url("images/slideshow-nav_active.png"); opacity:1; }
 
-                .zeoslide img {
-                  box-shadow: 1px 2px 16px rgba(28, 180, 236, 0.4);
-                  width: 705px;
-                }
+    .niaslide a img {
+      width: 542px;
+      box-shadow: 1px 2px 16px rgba(28, 180, 236, 0.4);
+      margin-left: 4em;
+      margin-top: -1em;
+    }
 
 		.codeslide1 { float:left; width:680px; font:10pt monospace; }
 		.codeslide1 > div:first-child { margin:0 40px 0 0; }
diff --git a/web/learn.txt b/web/learn.txt
index 987666f8e..c0b583429 100644
--- a/web/learn.txt
+++ b/web/learn.txt
@@ -17,6 +17,20 @@ Learning Nim
 
 .. container:: standout
 
+  Books
+  ---------
+
+  .. container:: books
+
+    - | `Nim in Action <https://manning.com/books/nim-in-action?a_aid=niminaction&a_bid=78a27e81>`_
+      | *Nim in Action* teaches
+        you all you need to know to begin writing powerful, portable
+        and efficient applications in Nim. It includes a handful of practical
+        and fun hands-on examples which teach you Nim.
+
+
+.. container:: standout
+
   Examples
   --------
 
diff --git a/web/news.txt b/web/news.txt
index 61a74127f..ddb8da042 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -2,6 +2,36 @@
 News
 ====
 
+2016-01-27 Nim in Action is now available!
+==========================================
+
+.. raw::html
+
+  <a href="https://manning.com/books/nim-in-action?a_aid=niminaction&a_bid=78a27e81">
+    <img src="assets/niminaction/banner.jpg" alt="New in Manning Early Access Program: Nim in Action!" width="682"/>
+  </a>
+
+
+We are proud to announce that *Nim in Action*, a book about the Nim programming
+language, is now available!
+
+The book is available at this URL:
+`https://www.manning.com/books/nim-in-action <https://manning.com/books/nim-in-action?a_aid=niminaction&a_bid=78a27e81>`_
+
+The first three chapters are available for download
+as an eBook through Manning's Early Access program. You can download a free
+sample of the book containing the first chapter as well!
+
+*Nim in Action* is currently being written and is expected to be completed by
+Summer 2016. If you purchase the eBook you will start receiving new chapters
+as they become available. You can also purchase the printed book together with
+the eBook for a slightly higher price.
+
+If you do read the book, even if it's just the first chapter, then please share
+any comments, suggestions and questions on the
+`Nim forum <http://forum.nim-lang.org/t/1978>`_ or in
+Manning's own `Author Online forum! <https://forums.manning.com/forums/nim-in-action>`_
+
 
 2016-01-18 Version 0.13.0 released
 ==================================
diff --git a/web/ticker.txt b/web/ticker.txt
index 1f9bd3e97..7e917e0f2 100644
--- a/web/ticker.txt
+++ b/web/ticker.txt
@@ -1,3 +1,8 @@
+<a class="news" href="news.html#Z2016-01-27-nim-in-action-is-now-available">
+  <h4>January 27, 2016</h4>
+  <p>Nim in Action is now available!</p>
+</a>
+
 <a class="news" href="news.html#Z2016-01-18-version-0-13-0-released">
   <h4>January 18, 2016</h4>
   <p>Nim version 0.13.0 has been released!</p>