summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/core/macros.nim34
-rw-r--r--lib/deprecated/pure/actors.nim10
-rw-r--r--lib/impure/db_postgres.nim19
-rw-r--r--lib/impure/nre.nim36
-rw-r--r--lib/impure/re.nim13
-rw-r--r--lib/impure/ssl.nim6
-rw-r--r--lib/nimbase.h14
-rw-r--r--lib/posix/linux.nim2
-rw-r--r--lib/posix/posix_other.nim2
-rw-r--r--lib/pure/algorithm.nim123
-rw-r--r--lib/pure/asyncmacro.nim14
-rw-r--r--lib/pure/collections/critbits.nim2
-rw-r--r--lib/pure/collections/deques.nim4
-rw-r--r--lib/pure/collections/lists.nim137
-rw-r--r--lib/pure/collections/queues.nim3
-rw-r--r--lib/pure/collections/sequtils.nim440
-rw-r--r--lib/pure/collections/sharedstrings.nim2
-rw-r--r--lib/pure/collections/tableimpl.nim2
-rw-r--r--lib/pure/concurrency/cpuinfo.nim21
-rw-r--r--lib/pure/concurrency/threadpool.nim18
-rw-r--r--lib/pure/future.nim6
-rw-r--r--lib/pure/httpclient.nim22
-rw-r--r--lib/pure/httpcore.nim3
-rw-r--r--lib/pure/includes/osenv.nim4
-rw-r--r--lib/pure/json.nim51
-rw-r--r--lib/pure/lexbase.nim5
-rw-r--r--lib/pure/marshal.nim2
-rw-r--r--lib/pure/matchers.nim2
-rw-r--r--lib/pure/math.nim2
-rw-r--r--lib/pure/nativesockets.nim14
-rw-r--r--lib/pure/net.nim7
-rw-r--r--lib/pure/options.nim5
-rw-r--r--lib/pure/os.nim5
-rw-r--r--lib/pure/osproc.nim4
-rw-r--r--lib/pure/parsecsv.nim5
-rw-r--r--lib/pure/parseopt2.nim2
-rw-r--r--lib/pure/parseutils.nim2
-rw-r--r--lib/pure/random.nim2
-rw-r--r--lib/pure/rationals.nim82
-rw-r--r--lib/pure/securehash.nim2
-rw-r--r--lib/pure/selectors.nim4
-rw-r--r--lib/pure/streams.nim32
-rw-r--r--lib/pure/strscans.nim32
-rw-r--r--lib/pure/strutils.nim254
-rw-r--r--lib/pure/times.nim19
-rw-r--r--lib/pure/typetraits.nim16
-rw-r--r--lib/pure/unicode.nim2
-rw-r--r--lib/pure/unittest.nim2
-rw-r--r--lib/pure/uri.nim15
-rw-r--r--lib/system.nim237
-rw-r--r--lib/system/alloc.nim15
-rw-r--r--lib/system/ansi_c.nim8
-rw-r--r--lib/system/assign.nim8
-rw-r--r--lib/system/debugger.nim6
-rw-r--r--lib/system/dyncalls.nim5
-rw-r--r--lib/system/endb.nim30
-rw-r--r--lib/system/excpt.nim8
-rw-r--r--lib/system/gc.nim23
-rw-r--r--lib/system/gc2.nim6
-rw-r--r--lib/system/gc_ms.nim4
-rw-r--r--lib/system/nimscript.nim2
-rw-r--r--lib/system/repr.nim21
-rw-r--r--lib/system/reprjs.nim36
-rw-r--r--lib/system/sysio.nim23
-rw-r--r--lib/system/sysspawn.nim2
-rw-r--r--lib/system/sysstr.nim33
-rw-r--r--lib/system/threads.nim2
-rw-r--r--lib/windows/winlean.nim4
-rw-r--r--lib/wrappers/openssl.nim20
-rw-r--r--lib/wrappers/pdcurses.nim1560
-rw-r--r--lib/wrappers/tinyc.nim23
71 files changed, 1270 insertions, 2311 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 8c70d2b47..fc5b5bfb7 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -129,13 +129,6 @@ const
   nnkCallKinds* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
                    nnkCallStrLit}
 
-proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.}
-  ## get `n`'s `i`'th child.
-
-proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild",
-  noSideEffect.}
-  ## set `n`'s `i`'th child to `child`.
-
 proc `!`*(s: string): NimIdent {.magic: "StrToIdent", noSideEffect.}
   ## constructs an identifier from the string `s`
 
@@ -162,6 +155,20 @@ proc sameType*(a, b: NimNode): bool {.magic: "SameNodeType", noSideEffect.} =
 proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.}
   ## returns the number of children of `n`.
 
+proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.}
+  ## get `n`'s `i`'th child.
+
+proc `[]`*(n: NimNode, i: BackwardsIndex): NimNode = n[n.len - i.int]
+  ## get `n`'s `i`'th child.
+
+proc `[]=`*(n: NimNode, i: int, child: NimNode) {.magic: "NSetChild",
+  noSideEffect.}
+  ## set `n`'s `i`'th child to `child`.
+
+proc `[]=`*(n: NimNode, i: BackwardsIndex, child: NimNode) =
+  ## set `n`'s `i`'th child to `child`.
+  n[n.len - i.int] = child
+
 proc add*(father, child: NimNode): NimNode {.magic: "NAdd", discardable,
   noSideEffect, locks: 0.}
   ## Adds the `child` to the `father` node. Returns the
@@ -839,7 +846,7 @@ proc newNilLit*(): NimNode {.compileTime.} =
   ## New nil literal shortcut
   result = newNimNode(nnkNilLit)
 
-proc last*(node: NimNode): NimNode {.compileTime.} = node[<node.len]
+proc last*(node: NimNode): NimNode {.compileTime.} = node[node.len-1]
   ## Return the last item in nodes children. Same as `node[^1]`
 
 
@@ -887,7 +894,7 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]):
 
 proc copyChildrenTo*(src, dest: NimNode) {.compileTime.}=
   ## Copy all children from `src` to `dest`
-  for i in 0 .. < src.len:
+  for i in 0 ..< src.len:
     dest.add src[i].copyNimTree
 
 template expectRoutine(node: NimNode) =
@@ -986,6 +993,11 @@ iterator items*(n: NimNode): NimNode {.inline.} =
   for i in 0 ..< n.len:
     yield n[i]
 
+iterator pairs*(n: NimNode): (int, NimNode) {.inline.} =
+  ## Iterates over the children of the NimNode ``n`` and its indices.
+  for i in 0 ..< n.len:
+    yield (i, n[i])
+
 iterator children*(n: NimNode): NimNode {.inline.} =
   ## Iterates over the children of the NimNode ``n``.
   for i in 0 ..< n.len:
@@ -1099,10 +1111,10 @@ proc eqIdent*(node: NimNode; s: string): bool {.compileTime.} =
   else:
     result = false
 
-proc hasArgOfName* (params: NimNode; name: string): bool {.compiletime.}=
+proc hasArgOfName*(params: NimNode; name: string): bool {.compiletime.}=
   ## Search nnkFormalParams for an argument.
   assert params.kind == nnkFormalParams
-  for i in 1 .. <params.len:
+  for i in 1 ..< params.len:
     template node: untyped = params[i]
     if name.eqIdent( $ node[0]):
       return true
diff --git a/lib/deprecated/pure/actors.nim b/lib/deprecated/pure/actors.nim
index 36bd41e9e..17321cc0e 100644
--- a/lib/deprecated/pure/actors.nim
+++ b/lib/deprecated/pure/actors.nim
@@ -18,7 +18,7 @@
 ##      var
 ##        a: ActorPool[int, void]
 ##      createActorPool(a)
-##      for i in 0 .. < 300:
+##      for i in 0 ..< 300:
 ##        a.spawn(i, proc (x: int) {.thread.} = echo x)
 ##      a.join()
 ##
@@ -133,7 +133,7 @@ proc createActorPool*[In, Out](a: var ActorPool[In, Out], poolSize = 4) =
   newSeq(a.actors, poolSize)
   when Out isnot void:
     open(a.outputs)
-  for i in 0 .. < a.actors.len:
+  for i in 0 ..< a.actors.len:
     a.actors[i] = spawn(poolWorker[In, Out])
 
 proc sync*[In, Out](a: var ActorPool[In, Out], polling=50) =
@@ -164,8 +164,8 @@ proc terminate*[In, Out](a: var ActorPool[In, Out]) =
   ## resources attached to `a`.
   var t: Task[In, Out]
   t.shutdown = true
-  for i in 0.. <a.actors.len: send(a.actors[i].i, t)
-  for i in 0.. <a.actors.len: join(a.actors[i])
+  for i in 0..<a.actors.len: send(a.actors[i].i, t)
+  for i in 0..<a.actors.len: join(a.actors[i])
   when Out isnot void:
     close(a.outputs)
   a.actors = nil
@@ -227,7 +227,7 @@ when not defined(testing) and isMainModule:
   var
     a: ActorPool[int, void]
   createActorPool(a)
-  for i in 0 .. < 300:
+  for i in 0 ..< 300:
     a.spawn(i, proc (x: int) {.thread.} = echo x)
 
   when false:
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index a42950557..b0d3170f8 100644
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -98,15 +98,18 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string =
   var a = 0
   if args.len > 0 and not string(formatstr).contains("?"):
     dbError("""parameter substitution expects "?" """)
-  for c in items(string(formatstr)):
-    if c == '?':
-      if args[a] == nil:
-        add(result, "NULL")
+  if args.len == 0:
+    return string(formatstr)
+  else:
+    for c in items(string(formatstr)):
+      if c == '?':
+        if args[a] == nil:
+          add(result, "NULL")
+        else:
+          add(result, dbQuote(args[a]))
+        inc(a)
       else:
-        add(result, dbQuote(args[a]))
-      inc(a)
-    else:
-      add(result, c)
+        add(result, c)
 
 proc tryExec*(db: DbConn, query: SqlQuery,
               args: varargs[string, `$`]): bool {.tags: [ReadDbEffect, WriteDbEffect].} =
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim
index 4013182af..3d4afc0ae 100644
--- a/lib/impure/nre.nim
+++ b/lib/impure/nre.nim
@@ -155,7 +155,7 @@ type
     ##     -  ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"``
     ##     -  ``"abc".match(re"(\w)\w").captures[-1] == "ab"``
     ##
-    ## ``captureBounds[]: Option[Slice[int]]``
+    ## ``captureBounds[]: Option[HSlice[int, int]]``
     ##     gets the bounds of the given capture according to the same rules as
     ##     the above. If the capture is not filled, then ``None`` is returned.
     ##     The bounds are both inclusive.
@@ -167,7 +167,7 @@ type
     ## ``match: string``
     ##     the full text of the match.
     ##
-    ## ``matchBounds: Slice[int]``
+    ## ``matchBounds: HSlice[int, int]``
     ##     the bounds of the match, as in ``captureBounds[]``
     ##
     ## ``(captureBounds|captures).toTable``
@@ -182,9 +182,9 @@ type
                      ## Not nil.
     str*: string  ## The string that was matched against.
                   ## Not nil.
-    pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match
-                                      ## Other items are the captures
-                                      ## `a` is inclusive start, `b` is exclusive end
+    pcreMatchBounds: seq[HSlice[cint, cint]] ## First item is the bounds of the match
+                                            ## Other items are the captures
+                                            ## `a` is inclusive start, `b` is exclusive end
 
   Captures* = distinct RegexMatch
   CaptureBounds* = distinct RegexMatch
@@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p
 
 proc captures*(pattern: RegexMatch): Captures = return Captures(pattern)
 
-proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int]] =
+proc `[]`*(pattern: CaptureBounds, i: int): Option[HSlice[int, int]] =
   let pattern = RegexMatch(pattern)
   if pattern.pcreMatchBounds[i + 1].a != -1:
     let bounds = pattern.pcreMatchBounds[i + 1]
     return some(int(bounds.a) .. int(bounds.b-1))
   else:
-    return none(Slice[int])
+    return none(HSlice[int, int])
 
 proc `[]`*(pattern: Captures, i: int): string =
   let pattern = RegexMatch(pattern)
@@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string =
 proc match*(pattern: RegexMatch): string =
   return pattern.captures[-1]
 
-proc matchBounds*(pattern: RegexMatch): Slice[int] =
+proc matchBounds*(pattern: RegexMatch): HSlice[int, int] =
   return pattern.captureBounds[-1].get
 
-proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int]] =
+proc `[]`*(pattern: CaptureBounds, name: string): Option[HSlice[int, int]] =
   let pattern = RegexMatch(pattern)
   return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)]
 
@@ -295,13 +295,13 @@ proc toTable*(pattern: Captures, default: string = nil): Table[string, string] =
   result = initTable[string, string]()
   toTableImpl(nextVal == nil)
 
-proc toTable*(pattern: CaptureBounds, default = none(Slice[int])):
-    Table[string, Option[Slice[int]]] =
-  result = initTable[string, Option[Slice[int]]]()
+proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])):
+    Table[string, Option[HSlice[int, int]]] =
+  result = initTable[string, Option[HSlice[int, int]]]()
   toTableImpl(nextVal.isNone)
 
 template itemsImpl(cond: untyped) {.dirty.} =
-  for i in 0 .. <RegexMatch(pattern).pattern.captureCount:
+  for i in 0 ..< RegexMatch(pattern).pattern.captureCount:
     let nextVal = pattern[i]
     # done in this roundabout way to avoid multiple yields (potential code
     # bloat)
@@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} =
     yield nextYieldVal
 
 
-iterator items*(pattern: CaptureBounds, default = none(Slice[int])): Option[Slice[int]] =
+iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] =
   itemsImpl(nextVal.isNone)
 
 iterator items*(pattern: Captures, default: string = nil): string =
   itemsImpl(nextVal == nil)
 
-proc toSeq*(pattern: CaptureBounds, default = none(Slice[int])): seq[Option[Slice[int]]] =
+proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] =
   accumulateResult(pattern.items(default))
 
 proc toSeq*(pattern: Captures, default: string = nil): seq[string] =
@@ -396,8 +396,6 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study:
 
 # }}}
 
-type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T]
-
 proc destroyRegex(pattern: Regex) =
   pcre.free_substring(cast[cstring](pattern.pcreObj))
   pattern.pcreObj = nil
@@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] =
 
   result = initTable[string, int]()
 
-  for i in 0 .. <entryCount:
+  for i in 0 ..< entryCount:
     let pos = i * entrySize
     let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
     var name = ""
@@ -464,7 +462,7 @@ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Opt
   # 1x capture count as slack space for PCRE
   let vecsize = (pattern.captureCount() + 1) * 3
   # div 2 because each element is 2 cints long
-  myResult.pcreMatchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int)
+  myResult.pcreMatchBounds = newSeq[HSlice[cint, cint]](ceil(vecsize / 2).int)
   myResult.pcreMatchBounds.setLen(vecsize div 3)
 
   let strlen = if endpos == int.high: str.len else: endpos+1
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index e00f91de1..24fc83366 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -13,10 +13,6 @@
 ## We had to de-deprecate this module since too much code relies on it
 ## and many people prefer its API over ``nre``'s.
 ##
-## **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 matching whitespace requires ``\s`` or something similar.
-##
 ## 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
@@ -78,7 +74,7 @@ proc finalizeRegEx(x: Regex) =
   if not isNil(x.e):
     pcre.free_substring(cast[cstring](x.e))
 
-proc re*(s: string, flags = {reExtended, reStudy}): Regex =
+proc re*(s: string, flags = {reStudy}): Regex =
   ## Constructor of regular expressions.
   ##
   ## Note that Nim's
@@ -96,6 +92,13 @@ proc re*(s: string, flags = {reExtended, reStudy}): Regex =
     result.e = pcre.study(result.h, options, addr msg)
     if not isNil(msg): raiseInvalidRegex($msg)
 
+proc rex*(s: string, flags = {reStudy, reExtended}): Regex =
+  ## Constructor for extended regular expressions.
+  ##
+  ## The extended means that comments starting with `#` and
+  ## whitespace are ignored.
+  result = re(s, flags)
+
 proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} =
   ## Return a Nim string built from a slice of a cstring buffer.
   ## Don't assume cstring is '\0' terminated
diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim
index e3312d792..5b0e899f6 100644
--- a/lib/impure/ssl.nim
+++ b/lib/impure/ssl.nim
@@ -63,16 +63,16 @@ proc recvLine*(sock: SecureSocket, line: var TaintedString): bool =
   setLen(line.string, 0)
   while true:
     var c: array[0..0, char]
-    var n = BIO_read(sock.bio, c, c.len.cint)
+    var n = BIO_read(sock.bio, addr c, c.len.cint)
     if n <= 0: return false
     if c[0] == '\r':
-      n = BIO_read(sock.bio, c, c.len.cint)
+      n = BIO_read(sock.bio, addr c, c.len.cint)
       if n > 0 and c[0] == '\L':
         return true
       elif n <= 0:
         return false
     elif c[0] == '\L': return true
-    add(line.string, c)
+    add(line.string, c[0])
 
 
 proc send*(sock: SecureSocket, data: string) =
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 34a2e43e7..76192713b 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -396,15 +396,13 @@ typedef struct TStringDesc* string;
 #define GenericSeqSize sizeof(TGenericSeq)
 #define paramCount() cmdCount
 
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__i386__)
-#  ifndef NAN
-static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff};
-#    define NAN (*(double*) nimNaN)
-#  endif
-#endif
-
+// NAN definition copied from math.h included in the Windows SDK version 10.0.14393.0
 #ifndef NAN
-#  define NAN (0.0 / 0.0)
+#ifndef _HUGE_ENUF
+#define _HUGE_ENUF  1e+300  // _HUGE_ENUF*_HUGE_ENUF must overflow
+#endif
+#define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
+#define NAN ((float)(NAN_INFINITY * 0.0F))
 #endif
 
 #ifndef INF
diff --git a/lib/posix/linux.nim b/lib/posix/linux.nim
index 01d5e57de..8786ab535 100644
--- a/lib/posix/linux.nim
+++ b/lib/posix/linux.nim
@@ -26,3 +26,5 @@ const
 proc clone*(fn: pointer; child_stack: pointer; flags: cint;
             arg: pointer; ptid: ptr Pid; tls: pointer;
             ctid: ptr Pid): cint {.importc, header: "<sched.h>".}
+
+proc pipe2*(a: array[0..1, cint], flags: cint): cint {.importc, header: "<unistd.h>".}
\ No newline at end of file
diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim
index 69f6acfb8..7321889a8 100644
--- a/lib/posix/posix_other.nim
+++ b/lib/posix/posix_other.nim
@@ -146,7 +146,7 @@ type
   Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint
   Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int
   Off* {.importc: "off_t", header: "<sys/types.h>".} = int64
-  Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int
+  Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32
   Pthread_attr* {.importc: "pthread_attr_t", header: "<sys/types.h>".} = int
   Pthread_barrier* {.importc: "pthread_barrier_t",
                       header: "<sys/types.h>".} = int
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 9eee04404..fdf2d7cbb 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -371,3 +371,126 @@ when isMainModule:
   for i in 0 .. high(arr1):
     assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)]
     assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i]
+
+
+proc rotateInternal[T](arg: var openarray[T]; first, middle, last: int): int =
+  ## A port of std::rotate from c++. Ported from `this reference <http://www.cplusplus.com/reference/algorithm/rotate/>`_.
+  result = first + last - middle
+
+  if first == middle or middle == last:
+    return
+
+  assert first < middle
+  assert middle < last
+
+  # m prefix for mutable
+  var
+    mFirst = first
+    mMiddle = middle
+    next = middle
+
+  swap(arg[mFirst], arg[next])
+  mFirst += 1
+  next  += 1
+  if mFirst == mMiddle:
+    mMiddle = next
+
+  while next != last:
+    swap(arg[mFirst], arg[next])
+    mFirst += 1
+    next += 1
+    if mFirst == mMiddle:
+      mMiddle = next
+
+  next = mMiddle
+  while next != last:
+    swap(arg[mFirst], arg[next])
+    mFirst += 1
+    next += 1
+    if mFirst == mMiddle:
+      mMiddle = next
+    elif next == last:
+      next = mMiddle
+
+proc rotatedInternal[T](arg: openarray[T]; first, middle, last: int): seq[T] =
+  result = newSeq[T](arg.len)
+  for i in 0 ..< first:
+    result[i] = arg[i]
+  let N = last - middle
+  let M = middle - first
+  for i in 0 ..< N:
+    result[first+i] = arg[middle+i]
+  for i in 0 ..< M:
+    result[first+N+i] = arg[first+i]
+  for i in last ..< arg.len:
+    result[i] = arg[i]
+
+proc rotateLeft*[T](arg: var openarray[T]; slice: HSlice[int, int]; dist: int): int =
+  ## Performs a left rotation on a range of elements. If you want to rotate right, use a negative ``dist``.
+  ## Specifically, ``rotateLeft`` rotates the elements at ``slice`` by ``dist`` positions.
+  ## The element at index ``slice.a + dist`` will be at index ``slice.a``.
+  ## The element at index ``slice.b`` will be at ``slice.a + dist -1``.
+  ## The element at index ``slice.a`` will be at ``slice.b + 1 - dist``.
+  ## The element at index ``slice.a + dist - 1`` will be at ``slice.b``.
+  #
+  ## Elements outsize of ``slice`` will be left unchanged.
+  ## The time complexity is linear to ``slice.b - slice.a + 1``.
+  ##
+  ## ``slice``
+  ##   the indices of the element range that should be rotated.
+  ##
+  ## ``dist``
+  ##   the distance in amount of elements that the data should be rotated. Can be negative, can be any number.
+  ##
+  ## .. code-block:: nim
+  ##     var list     = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ##     list.rotateLeft(1 .. 8, 3)
+  ##     doAssert list == [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10]
+  let sliceLen = slice.b + 1 - slice.a
+  let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen
+  arg.rotateInternal(slice.a, slice.a+distLeft, slice.b + 1)
+
+proc rotateLeft*[T](arg: var openarray[T]; dist: int): int =
+  ## default arguments for slice, so that this procedure operates on the entire
+  ## ``arg``, and not just on a part of it.
+  let arglen = arg.len
+  let distLeft = ((dist mod arglen) + arglen) mod arglen
+  arg.rotateInternal(0, distLeft, arglen)
+
+proc rotatedLeft*[T](arg: openarray[T]; slice: HSlice[int, int], dist: int): seq[T] =
+  ## same as ``rotateLeft``, just with the difference that it does
+  ## not modify the argument. It creates a new ``seq`` instead
+  let sliceLen = slice.b + 1 - slice.a
+  let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen
+  arg.rotatedInternal(slice.a, slice.a+distLeft, slice.b+1)
+
+proc rotatedLeft*[T](arg: openarray[T]; dist: int): seq[T] =
+  ## same as ``rotateLeft``, just with the difference that it does
+  ## not modify the argument. It creates a new ``seq`` instead
+  let arglen = arg.len
+  let distLeft = ((dist mod arglen) + arglen) mod arglen
+  arg.rotatedInternal(0, distLeft, arg.len)
+
+when isMainModule:
+  var list     = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  let list2    = list.rotatedLeft(1 ..< 9, 3)
+  let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10]
+
+  doAssert list.rotateLeft(1 ..< 9, 3) == 6
+  doAssert list  ==  expected
+  doAssert list2 == @expected
+
+  var s0,s1,s2,s3,s4,s5 = "xxxabcdefgxxx"
+
+  doAssert s0.rotateLeft(3 ..< 10, 3) == 7
+  doAssert s0 == "xxxdefgabcxxx"
+  doAssert s1.rotateLeft(3 ..< 10, 2) == 8
+  doAssert s1 == "xxxcdefgabxxx"
+  doAssert s2.rotateLeft(3 ..< 10, 4) == 6
+  doAssert s2 == "xxxefgabcdxxx"
+  doAssert s3.rotateLeft(3 ..< 10, -3) == 6
+  doAssert s3 == "xxxefgabcdxxx"
+  doAssert s4.rotateLeft(3 ..< 10, -10) == 6
+  doAssert s4 == "xxxefgabcdxxx"
+  doAssert s5.rotateLeft(3 ..< 10, 11) == 6
+  doAssert s5 == "xxxefgabcdxxx"
diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim
index 6e7d7993f..981190211 100644
--- a/lib/pure/asyncmacro.nim
+++ b/lib/pure/asyncmacro.nim
@@ -61,14 +61,14 @@ proc generateExceptionCheck(futSym,
   else:
     var exceptionChecks: seq[tuple[cond, body: NimNode]] = @[]
     let errorNode = newDotExpr(futSym, newIdentNode("error"))
-    for i in 1 .. <tryStmt.len:
+    for i in 1 ..< tryStmt.len:
       let exceptBranch = tryStmt[i]
       if exceptBranch[0].kind == nnkStmtList:
         exceptionChecks.add((newIdentNode("true"), exceptBranch[0]))
       else:
         var exceptIdentCount = 0
         var ifCond: NimNode
-        for i in 0 .. <exceptBranch.len:
+        for i in 0 ..< exceptBranch.len:
           let child = exceptBranch[i]
           if child.kind == nnkIdent:
             let cond = infix(errorNode, "of", child)
@@ -270,7 +270,7 @@ proc processBody(node, retFutureSym: NimNode,
     return
   else: discard
 
-  for i in 0 .. <result.len:
+  for i in 0 ..< result.len:
     result[i] = processBody(result[i], retFutureSym, subTypeIsVoid,
                             futureVarIdents, nil)
 
@@ -287,7 +287,7 @@ proc getName(node: NimNode): string {.compileTime.} =
 
 proc getFutureVarIdents(params: NimNode): seq[NimNode] {.compileTime.} =
   result = @[]
-  for i in 1 .. <len(params):
+  for i in 1 ..< len(params):
     expectKind(params[i], nnkIdentDefs)
     if params[i][1].kind == nnkBracketExpr and
        ($params[i][1][0].ident).normalize == "futurevar":
@@ -466,7 +466,7 @@ proc stripAwait(node: NimNode): NimNode =
       node[0][0] = emptyNoopSym
   else: discard
 
-  for i in 0 .. <result.len:
+  for i in 0 ..< result.len:
     result[i] = stripAwait(result[i])
 
 proc splitParamType(paramType: NimNode, async: bool): NimNode =
@@ -512,7 +512,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) =
   # Retrieve the `T` inside `Future[T]`.
   let returnType = stripReturnType(result[0][3][0])
   result[0][3][0] = splitParamType(returnType, async=false)
-  for i in 1 .. <result[0][3].len:
+  for i in 1 ..< result[0][3].len:
     # Sync proc (0) -> FormalParams (3) -> IdentDefs, the parameter (i) ->
     # parameter type (1).
     result[0][3][i][1] = splitParamType(result[0][3][i][1], async=false)
@@ -521,7 +521,7 @@ proc splitProc(prc: NimNode): (NimNode, NimNode) =
   result[1] = prc.copyNimTree()
   if result[1][3][0].kind == nnkBracketExpr:
     result[1][3][0][1] = splitParamType(result[1][3][0][1], async=true)
-  for i in 1 .. <result[1][3].len:
+  for i in 1 ..< result[1][3].len:
     # Async proc (1) -> FormalParams (3) -> IdentDefs, the parameter (i) ->
     # parameter type (1).
     result[1][3][i][1] = splitParamType(result[1][3][i][1], async=true)
diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim
index f70a12843..19f1f2e58 100644
--- a/lib/pure/collections/critbits.nim
+++ b/lib/pure/collections/critbits.nim
@@ -257,7 +257,7 @@ proc allprefixedAux[T](c: CritBitTree[T], key: string; longestMatch: bool): Node
       p = p.child[dir]
       if q.byte < key.len: top = p
     if not longestMatch:
-      for i in 0 .. <key.len:
+      for i in 0 ..< key.len:
         if p.key[i] != key[i]: return
     result = top
 
diff --git a/lib/pure/collections/deques.nim b/lib/pure/collections/deques.nim
index 1bbe9f1ad..1e0cb82d2 100644
--- a/lib/pure/collections/deques.nim
+++ b/lib/pure/collections/deques.nim
@@ -207,9 +207,9 @@ when isMainModule:
   assert($deq == "[4, 56, 6, 789]")
 
   assert deq[0] == deq.peekFirst and deq.peekFirst == 4
-  assert deq[^1] == deq.peekLast and deq.peekLast == 789
+  #assert deq[^1] == deq.peekLast and deq.peekLast == 789
   deq[0] = 42
-  deq[^1] = 7
+  deq[deq.len - 1] = 7
 
   assert 6 in deq and 789 notin deq
   assert deq.find(6) >= 0
diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim
index f847ddd58..560273dfa 100644
--- a/lib/pure/collections/lists.nim
+++ b/lib/pure/collections/lists.nim
@@ -37,6 +37,14 @@ type
   DoublyLinkedRing*[T] = object ## a doubly linked ring
     head*: DoublyLinkedNode[T]
 
+  SomeLinkedList*[T] = SinglyLinkedList[T] | DoublyLinkedList[T]
+
+  SomeLinkedRing*[T] = SinglyLinkedRing[T] | DoublyLinkedRing[T]
+
+  SomeLinkedCollection*[T] = SomeLinkedList[T] | SomeLinkedRing[T]
+
+  SomeLinkedNode*[T] = SinglyLinkedNode[T] | DoublyLinkedNode[T]
+
 {.deprecated: [TDoublyLinkedNode: DoublyLinkedNodeObj,
     PDoublyLinkedNode: DoublyLinkedNode,
     TSinglyLinkedNode: SinglyLinkedNodeObj,
@@ -86,137 +94,57 @@ template itemsRingImpl() {.dirty.} =
       it = it.next
       if it == L.head: break
 
-template nodesListImpl() {.dirty.} =
-  var it = L.head
-  while it != nil:
-    var nxt = it.next
-    yield it
-    it = nxt
-
-template nodesRingImpl() {.dirty.} =
-  var it = L.head
-  if it != nil:
-    while true:
-      var nxt = it.next
-      yield it
-      it = nxt
-      if it == L.head: break
-
-template findImpl() {.dirty.} =
-  for x in nodes(L):
-    if x.value == value: return x
-
-iterator items*[T](L: DoublyLinkedList[T]): T =
+iterator items*[T](L: SomeLinkedList[T]): T =
   ## yields every value of `L`.
   itemsListImpl()
 
-iterator items*[T](L: SinglyLinkedList[T]): T =
-  ## yields every value of `L`.
-  itemsListImpl()
-
-iterator items*[T](L: SinglyLinkedRing[T]): T =
-  ## yields every value of `L`.
-  itemsRingImpl()
-
-iterator items*[T](L: DoublyLinkedRing[T]): T =
+iterator items*[T](L: SomeLinkedRing[T]): T =
   ## yields every value of `L`.
   itemsRingImpl()
 
-iterator mitems*[T](L: var DoublyLinkedList[T]): var T =
+iterator mitems*[T](L: var SomeLinkedList[T]): var T =
   ## yields every value of `L` so that you can modify it.
   itemsListImpl()
 
-iterator mitems*[T](L: var SinglyLinkedList[T]): var T =
-  ## yields every value of `L` so that you can modify it.
-  itemsListImpl()
-
-iterator mitems*[T](L: var SinglyLinkedRing[T]): var T =
+iterator mitems*[T](L: var SomeLinkedRing[T]): var T =
   ## yields every value of `L` so that you can modify it.
   itemsRingImpl()
 
-iterator mitems*[T](L: var DoublyLinkedRing[T]): var T =
-  ## yields every value of `L` so that you can modify it.
-  itemsRingImpl()
-
-iterator nodes*[T](L: SinglyLinkedList[T]): SinglyLinkedNode[T] =
-  ## iterates over every node of `x`. Removing the current node from the
-  ## list during traversal is supported.
-  nodesListImpl()
-
-iterator nodes*[T](L: DoublyLinkedList[T]): DoublyLinkedNode[T] =
-  ## iterates over every node of `x`. Removing the current node from the
-  ## list during traversal is supported.
-  nodesListImpl()
-
-iterator nodes*[T](L: SinglyLinkedRing[T]): SinglyLinkedNode[T] =
+iterator nodes*[T](L: SomeLinkedList[T]): SomeLinkedNode[T] =
   ## iterates over every node of `x`. Removing the current node from the
   ## list during traversal is supported.
-  nodesRingImpl()
+  var it = L.head
+  while it != nil:
+    var nxt = it.next
+    yield it
+    it = nxt
 
-iterator nodes*[T](L: DoublyLinkedRing[T]): DoublyLinkedNode[T] =
+iterator nodes*[T](L: SomeLinkedRing[T]): SomeLinkedNode[T] =
   ## iterates over every node of `x`. Removing the current node from the
   ## list during traversal is supported.
-  nodesRingImpl()
+  var it = L.head
+  if it != nil:
+    while true:
+      var nxt = it.next
+      yield it
+      it = nxt
+      if it == L.head: break
 
-template dollarImpl() {.dirty.} =
+proc `$`*[T](L: SomeLinkedCollection[T]): string =
+  ## turns a list into its string representation.
   result = "["
   for x in nodes(L):
     if result.len > 1: result.add(", ")
     result.add($x.value)
   result.add("]")
 
-proc `$`*[T](L: SinglyLinkedList[T]): string =
-  ## turns a list into its string representation.
-  dollarImpl()
-
-proc `$`*[T](L: DoublyLinkedList[T]): string =
-  ## turns a list into its string representation.
-  dollarImpl()
-
-proc `$`*[T](L: SinglyLinkedRing[T]): string =
-  ## turns a list into its string representation.
-  dollarImpl()
-
-proc `$`*[T](L: DoublyLinkedRing[T]): string =
-  ## turns a list into its string representation.
-  dollarImpl()
-
-proc find*[T](L: SinglyLinkedList[T], value: T): SinglyLinkedNode[T] =
-  ## searches in the list for a value. Returns nil if the value does not
-  ## exist.
-  findImpl()
-
-proc find*[T](L: DoublyLinkedList[T], value: T): DoublyLinkedNode[T] =
+proc find*[T](L: SomeLinkedCollection[T], value: T): SomeLinkedNode[T] =
   ## searches in the list for a value. Returns nil if the value does not
   ## exist.
-  findImpl()
-
-proc find*[T](L: SinglyLinkedRing[T], value: T): SinglyLinkedNode[T] =
-  ## searches in the list for a value. Returns nil if the value does not
-  ## exist.
-  findImpl()
-
-proc find*[T](L: DoublyLinkedRing[T], value: T): DoublyLinkedNode[T] =
-  ## searches in the list for a value. Returns nil if the value does not
-  ## exist.
-  findImpl()
-
-proc contains*[T](L: SinglyLinkedList[T], value: T): bool {.inline.} =
-  ## searches in the list for a value. Returns false if the value does not
-  ## exist, true otherwise.
-  result = find(L, value) != nil
-
-proc contains*[T](L: DoublyLinkedList[T], value: T): bool {.inline.} =
-  ## searches in the list for a value. Returns false if the value does not
-  ## exist, true otherwise.
-  result = find(L, value) != nil
-
-proc contains*[T](L: SinglyLinkedRing[T], value: T): bool {.inline.} =
-  ## searches in the list for a value. Returns false if the value does not
-  ## exist, true otherwise.
-  result = find(L, value) != nil
+  for x in nodes(L):
+    if x.value == value: return x
 
-proc contains*[T](L: DoublyLinkedRing[T], value: T): bool {.inline.} =
+proc contains*[T](L: SomeLinkedCollection[T], value: T): bool {.inline.} =
   ## searches in the list for a value. Returns false if the value does not
   ## exist, true otherwise.
   result = find(L, value) != nil
@@ -266,7 +194,6 @@ proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) =
   if n.next != nil: n.next.prev = n.prev
   if n.prev != nil: n.prev.next = n.next
 
-
 proc append*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) =
   ## appends a node `n` to `L`. Efficiency: O(1).
   if L.head != nil:
diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim
index 401422162..ce792d6da 100644
--- a/lib/pure/collections/queues.nim
+++ b/lib/pure/collections/queues.nim
@@ -198,9 +198,8 @@ when isMainModule:
   assert($q == "[4, 56, 6, 789]")
 
   assert q[0] == q.front and q.front == 4
-  assert q[^1] == q.back and q.back == 789
   q[0] = 42
-  q[^1] = 7
+  q[q.len - 1] = 7
 
   assert 6 in q and 789 notin q
   assert q.find(6) >= 0
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index e8e725aa3..0eb8e6704 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -13,8 +13,9 @@
 ## were inspired by functional programming languages.
 ##
 ## For functional style programming you may want to pass `anonymous procs
-## <manual.html#anonymous-procs>`_ to procs like ``filter`` to reduce typing.
-## Anonymous procs can use `the special do notation <manual.html#do-notation>`_
+## <manual.html#procedures-anonymous-procs>`_ to procs like ``filter`` to
+## reduce typing. Anonymous procs can use `the special do notation
+## <manual.html#procedures-do-notation>`_
 ## which is more convenient in certain situations.
 
 include "system/inclrtl"
@@ -43,8 +44,23 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] =
       result[i] = itm
       inc(i)
 
-proc cycle*[T](s: seq[T], n: Natural): seq[T] =
-  ## Returns a new sequence with the items of `s` repeated `n` times.
+proc count*[T](s: openArray[T], x: T): int =
+  ## Returns the number of occurrences of the item `x` in the container `s`.
+  ##
+  ## Example:
+  ##
+  ## .. code-block::
+  ##   let
+  ##     s = @[1, 2, 2, 3, 2, 4, 2]
+  ##     c = count(s, 2)
+  ##   assert c == 4
+  for itm in items(s):
+    if itm == x:
+      inc result
+
+proc cycle*[T](s: openArray[T], n: Natural): seq[T] =
+  ## Returns a new sequence with the items of the container `s` repeated
+  ## `n` times.
   ##
   ## Example:
   ##
@@ -56,7 +72,7 @@ proc cycle*[T](s: seq[T], n: Natural): seq[T] =
   ##   assert total == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
   result = newSeq[T](n * s.len)
   var o = 0
-  for x in 0..<n:
+  for x in 0 ..< n:
     for e in s:
       result[o] = e
       inc o
@@ -72,12 +88,14 @@ proc repeat*[T](x: T, n: Natural): seq[T] =
   ##     total = repeat(5, 3)
   ##   assert total == @[5, 5, 5]
   result = newSeq[T](n)
-  for i in 0..<n:
+  for i in 0 ..< n:
     result[i] = x
 
-proc deduplicate*[T](seq1: seq[T]): seq[T] =
+proc deduplicate*[T](s: openArray[T]): seq[T] =
   ## Returns a new sequence without duplicates.
   ##
+  ## Example:
+  ##
   ## .. code-block::
   ##   let
   ##     dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4]
@@ -87,17 +105,19 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] =
   ##   assert unique1 == @[1, 3, 4, 2, 8]
   ##   assert unique2 == @["a", "c", "d"]
   result = @[]
-  for itm in items(seq1):
+  for itm in items(s):
     if not result.contains(itm): result.add(itm)
 
 {.deprecated: [distnct: deduplicate].}
 
-proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
-  ## Returns a new sequence with a combination of the two input sequences.
+proc zip*[S, T](s1: openArray[S], s2: openArray[T]): seq[tuple[a: S, b: T]] =
+  ## Returns a new sequence with a combination of the two input containers.
   ##
   ## For convenience you can access the returned tuples through the named
-  ## fields `a` and `b`. If one sequence is shorter, the remaining items in the
-  ## longer sequence are discarded. Example:
+  ## fields `a` and `b`. If one container is shorter, the remaining items in
+  ## the longer container are discarded.
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   let
@@ -110,15 +130,16 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
   ##   assert zip2 == @[(1, "one"), (2, "two"), (3, "three")]
   ##   assert zip1[2].b == 4
   ##   assert zip2[2].b == "three"
-  var m = min(seq1.len, seq2.len)
+  var m = min(s1.len, s2.len)
   newSeq(result, m)
-  for i in 0 .. m-1: result[i] = (seq1[i], seq2[i])
+  for i in 0 ..< m:
+    result[i] = (s1[i], s2[i])
 
 proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
   ## Splits and distributes a sequence `s` into `num` sub sequences.
   ##
   ## Returns a sequence of `num` sequences. For some input values this is the
-  ## inverse of the `concat <#concat>`_ proc.  The proc will assert in debug
+  ## inverse of the `concat <#concat>`_ proc. The proc will assert in debug
   ## builds if `s` is nil or `num` is less than one, and will likely crash on
   ## release builds.  The input sequence `s` can be empty, which will produce
   ## `num` empty sequences.
@@ -159,48 +180,52 @@ proc distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
     # Use an algorithm which overcounts the stride and minimizes reading limits.
     if extra > 0: inc(stride)
 
-    for i in 0 .. <num:
+    for i in 0 ..< num:
       result[i] = newSeq[T]()
-      for g in first .. <min(s.len, first + stride):
+      for g in first ..< min(s.len, first + stride):
         result[i].add(s[g])
       first += stride
 
   else:
     # Use an undercounting algorithm which *adds* the remainder each iteration.
-    for i in 0 .. <num:
+    for i in 0 ..< num:
       last = first + stride
       if extra > 0:
         extra -= 1
         inc(last)
 
       result[i] = newSeq[T]()
-      for g in first .. <last:
+      for g in first ..< last:
         result[i].add(s[g])
       first = last
 
-
-proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}):
+proc map*[T, S](s: openArray[T], op: proc (x: T): S {.closure.}):
                                                             seq[S]{.inline.} =
   ## Returns a new sequence with the results of `op` applied to every item in
-  ## `data`.
+  ## the container `s`.
   ##
   ## Since the input is not modified you can use this version of ``map`` to
-  ## transform the type of the elements in the input sequence. Example:
+  ## transform the type of the elements in the input container.
+  ##
+  ## Example:
   ##
   ## .. code-block:: nim
   ##   let
   ##     a = @[1, 2, 3, 4]
   ##     b = map(a, proc(x: int): string = $x)
   ##   assert b == @["1", "2", "3", "4"]
-  newSeq(result, data.len)
-  for i in 0..data.len-1: result[i] = op(data[i])
+  newSeq(result, s.len)
+  for i in 0 ..< s.len:
+    result[i] = op(s[i])
 
-proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.})
+proc map*[T](s: var openArray[T], op: proc (x: var T) {.closure.})
                                                               {.deprecated.} =
-  ## Applies `op` to every item in `data` modifying it directly.
+  ## Applies `op` to every item in `s` modifying it directly.
   ##
   ## Note that this version of ``map`` requires your input and output types to
-  ## be the same, since they are modified in-place. Example:
+  ## be the same, since they are modified in-place.
+  ##
+  ## Example:
   ##
   ## .. code-block:: nim
   ##   var a = @["1", "2", "3", "4"]
@@ -210,15 +235,16 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.})
   ##   echo repr(a)
   ##   # --> ["142", "242", "342", "442"]
   ## **Deprecated since version 0.12.0:** Use the ``apply`` proc instead.
-  for i in 0..data.len-1: op(data[i])
+  for i in 0 ..< s.len: op(s[i])
 
-proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.})
+proc apply*[T](s: var openArray[T], op: proc (x: var T) {.closure.})
                                                               {.inline.} =
-  ## Applies `op` to every item in `data` modifying it directly.
+  ## Applies `op` to every item in `s` modifying it directly.
   ##
   ## Note that this requires your input and output types to
   ## be the same, since they are modified in-place.
   ## The parameter function takes a ``var T`` type parameter.
+  ##
   ## Example:
   ##
   ## .. code-block:: nim
@@ -229,15 +255,16 @@ proc apply*[T](data: var seq[T], op: proc (x: var T) {.closure.})
   ##   echo repr(a)
   ##   # --> ["142", "242", "342", "442"]
   ##
-  for i in 0..data.len-1: op(data[i])
+  for i in 0 ..< s.len: op(s[i])
 
-proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.})
+proc apply*[T](s: var openArray[T], op: proc (x: T): T {.closure.})
                                                               {.inline.} =
-  ## Applies `op` to every item in `data` modifying it directly.
+  ## Applies `op` to every item in `s` modifying it directly.
   ##
   ## Note that this requires your input and output types to
   ## be the same, since they are modified in-place.
   ## The parameter function takes and returns a ``T`` type variable.
+  ##
   ## Example:
   ##
   ## .. code-block:: nim
@@ -248,11 +275,10 @@ proc apply*[T](data: var seq[T], op: proc (x: T): T {.closure.})
   ##   echo repr(a)
   ##   # --> ["142", "242", "342", "442"]
   ##
-  for i in 0..data.len-1: data[i] = op(data[i])
+  for i in 0 ..< s.len: s[i] = op(s[i])
 
-
-iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T =
-  ## Iterates through a sequence and yields every item that fulfills the
+iterator filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): T =
+  ## Iterates through a container and yields every item that fulfills the
   ## predicate.
   ##
   ## Example:
@@ -262,11 +288,11 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T =
   ##   for n in filter(numbers, proc (x: int): bool = x mod 2 == 0):
   ##     echo($n)
   ##   # echoes 4, 8, 4 in separate lines
-  for i in 0..<seq1.len:
-    if pred(seq1[i]):
-      yield seq1[i]
+  for i in 0 ..< s.len:
+    if pred(s[i]):
+      yield s[i]
 
-proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T]
+proc filter*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): seq[T]
                                                                   {.inline.} =
   ## Returns a new sequence with all the items that fulfilled the predicate.
   ##
@@ -280,11 +306,11 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T]
   ##   assert f1 == @["red", "black"]
   ##   assert f2 == @["yellow"]
   result = newSeq[T]()
-  for i in 0..<seq1.len:
-    if pred(seq1[i]):
-      result.add(seq1[i])
+  for i in 0 ..< s.len:
+    if pred(s[i]):
+      result.add(s[i])
 
-proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.})
+proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
                                                                 {.inline.} =
   ## Keeps the items in the passed sequence if they fulfilled the predicate.
   ## Same as the ``filter`` proc, but modifies the sequence directly.
@@ -296,12 +322,12 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.})
   ##   keepIf(floats, proc(x: float): bool = x > 10)
   ##   assert floats == @[13.0, 12.5, 10.1]
   var pos = 0
-  for i in 0 .. <len(seq1):
-    if pred(seq1[i]):
+  for i in 0 ..< len(s):
+    if pred(s[i]):
       if pos != i:
-        shallowCopy(seq1[pos], seq1[i])
+        shallowCopy(s[pos], s[i])
       inc(pos)
-  setLen(seq1, pos)
+  setLen(s, pos)
 
 proc delete*[T](s: var seq[T]; first, last: Natural) =
   ## Deletes in `s` the items at position `first` .. `last`. This modifies
@@ -354,11 +380,12 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) =
     inc(j)
 
 
-template filterIt*(seq1, pred: untyped): untyped =
+template filterIt*(s, pred: untyped): untyped =
   ## Returns a new sequence with all the items that fulfilled the predicate.
   ##
   ## Unlike the `proc` version, the predicate needs to be an expression using
   ## the ``it`` variable for testing, like: ``filterIt("abcxyz", it == 'x')``.
+  ##
   ## Example:
   ##
   ## .. code-block::
@@ -368,8 +395,8 @@ template filterIt*(seq1, pred: untyped): untyped =
   ##      notAcceptable = filterIt(temperatures, it > 50 or it < -10)
   ##    assert acceptable == @[-2.0, 24.5, 44.31]
   ##    assert notAcceptable == @[-272.15, 99.9, -113.44]
-  var result = newSeq[type(seq1[0])]()
-  for it {.inject.} in items(seq1):
+  var result = newSeq[type(s[0])]()
+  for it {.inject.} in items(s):
     if pred: result.add(it)
   result
 
@@ -378,6 +405,7 @@ template keepItIf*(varSeq: seq, pred: untyped) =
   ##
   ## Unlike the `proc` version, the predicate needs to be an expression using
   ## the ``it`` variable for testing, like: ``keepItIf("abcxyz", it == 'x')``.
+  ##
   ## Example:
   ##
   ## .. code-block::
@@ -385,7 +413,7 @@ template keepItIf*(varSeq: seq, pred: untyped) =
   ##   keepItIf(candidates, it.len == 3 and it[0] == 'b')
   ##   assert candidates == @["bar", "baz"]
   var pos = 0
-  for i in 0 .. <len(varSeq):
+  for i in 0 ..< len(varSeq):
     let it {.inject.} = varSeq[i]
     if pred:
       if pos != i:
@@ -393,8 +421,8 @@ template keepItIf*(varSeq: seq, pred: untyped) =
       inc(pos)
   setLen(varSeq, pos)
 
-proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
-  ## Iterates through a sequence and checks if every item fulfills the
+proc all*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool =
+  ## Iterates through a container and checks if every item fulfills the
   ## predicate.
   ##
   ## Example:
@@ -403,12 +431,12 @@ proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
   ##   let numbers = @[1, 4, 5, 8, 9, 7, 4]
   ##   assert all(numbers, proc (x: int): bool = return x < 10) == true
   ##   assert all(numbers, proc (x: int): bool = return x < 9) == false
-  for i in seq1:
+  for i in s:
     if not pred(i):
       return false
   return true
 
-template allIt*(seq1, pred: untyped): bool =
+template allIt*(s, pred: untyped): bool =
   ## Checks if every item fulfills the predicate.
   ##
   ## Example:
@@ -418,14 +446,14 @@ template allIt*(seq1, pred: untyped): bool =
   ##   assert allIt(numbers, it < 10) == true
   ##   assert allIt(numbers, it < 9) == false
   var result = true
-  for it {.inject.} in items(seq1):
+  for it {.inject.} in items(s):
     if not pred:
       result = false
       break
   result
 
-proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
-  ## Iterates through a sequence and checks if some item fulfills the
+proc any*[T](s: openArray[T], pred: proc(x: T): bool {.closure.}): bool =
+  ## Iterates through a container and checks if some item fulfills the
   ## predicate.
   ##
   ## Example:
@@ -434,12 +462,12 @@ proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
   ##   let numbers = @[1, 4, 5, 8, 9, 7, 4]
   ##   assert any(numbers, proc (x: int): bool = return x > 8) == true
   ##   assert any(numbers, proc (x: int): bool = return x > 9) == false
-  for i in seq1:
+  for i in s:
     if pred(i):
       return true
   return false
 
-template anyIt*(seq1, pred: untyped): bool =
+template anyIt*(s, pred: untyped): bool =
   ## Checks if some item fulfills the predicate.
   ##
   ## Example:
@@ -449,7 +477,7 @@ template anyIt*(seq1, pred: untyped): bool =
   ##   assert anyIt(numbers, it > 8) == true
   ##   assert anyIt(numbers, it > 9) == false
   var result = false
-  for it {.inject.} in items(seq1):
+  for it {.inject.} in items(s):
     if pred:
       result = true
       break
@@ -493,7 +521,9 @@ template foldl*(sequence, operation: untyped): untyped =
   ## variables ``a`` and ``b`` for each step of the fold. Since this is a left
   ## 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:
+  ## 3).
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   let
@@ -527,6 +557,7 @@ template foldl*(sequence, operation, first): untyped =
   ## The ``operation`` parameter should be an expression which uses the variables
   ## ``a`` and ``b`` for each step of the fold. The ``first`` parameter is the
   ## start value (the first ``a``) and therefor defines the type of the result.
+  ##
   ## Example:
   ##
   ## .. code-block::
@@ -555,7 +586,9 @@ template foldr*(sequence, operation: untyped): untyped =
   ## variables ``a`` and ``b`` for each step of the fold. Since this is a right
   ## 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:
+  ## (3))).
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   let
@@ -580,13 +613,15 @@ template foldr*(sequence, operation: untyped): untyped =
     result = operation
   result
 
-template mapIt*(seq1, typ, op: untyped): untyped =
+template mapIt*(s, typ, op: untyped): untyped =
   ## Convenience template around the ``map`` proc to reduce typing.
   ##
   ## The template injects the ``it`` variable which you can use directly in an
   ## expression. You also need to pass as `typ` the type of the expression,
   ## since the new returned sequence can have a different type than the
-  ## original.  Example:
+  ## original.
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   let
@@ -596,16 +631,18 @@ template mapIt*(seq1, typ, op: untyped): untyped =
   ## **Deprecated since version 0.12.0:** Use the ``mapIt(seq1, op)``
   ##   template instead.
   var result: seq[typ] = @[]
-  for it {.inject.} in items(seq1):
+  for it {.inject.} in items(s):
     result.add(op)
   result
 
 
-template mapIt*(seq1, op: untyped): untyped =
+template mapIt*(s, op: untyped): untyped =
   ## Convenience template around the ``map`` proc to reduce typing.
   ##
   ## The template injects the ``it`` variable which you can use directly in an
-  ## expression. Example:
+  ## expression.
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   let
@@ -614,19 +651,19 @@ template mapIt*(seq1, op: untyped): untyped =
   ##   assert strings == @["4", "8", "12", "16"]
   type outType = type((
     block:
-      var it{.inject.}: type(items(seq1));
+      var it{.inject.}: type(items(s));
       op))
   var result: seq[outType]
-  when compiles(seq1.len):
-    let s = seq1
+  when compiles(s.len):
+    let t = s
     var i = 0
     result = newSeq[outType](s.len)
-    for it {.inject.} in s:
+    for it {.inject.} in t:
       result[i] = op
       i += 1
   else:
     result = @[]
-    for it {.inject.} in seq1:
+    for it {.inject.} in s:
       result.add(op)
   result
 
@@ -635,20 +672,23 @@ template applyIt*(varSeq, op: untyped) =
   ##
   ## The template injects the ``it`` variable which you can use directly in an
   ## expression. The expression has to return the same type as the sequence you
-  ## are mutating. Example:
+  ## are mutating.
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   var nums = @[1, 2, 3, 4]
   ##   nums.applyIt(it * 3)
   ##   assert nums[0] + nums[3] == 15
-  for i in 0 .. <varSeq.len:
+  for i in 0 ..< varSeq.len:
     let it {.inject.} = varSeq[i]
     varSeq[i] = op
 
 
-
 template newSeqWith*(len: int, init: untyped): untyped =
-  ## creates a new sequence, calling `init` to initialize each value. Example:
+  ## creates a new sequence, calling `init` to initialize each value.
+  ##
+  ## Example:
   ##
   ## .. code-block::
   ##   var seq2D = newSeqWith(20, newSeq[bool](10))
@@ -660,7 +700,7 @@ template newSeqWith*(len: int, init: untyped): untyped =
   ##   var seqRand = newSeqWith(20, random(10))
   ##   echo seqRand
   var result = newSeq[type(init)](len)
-  for i in 0 .. <len:
+  for i in 0 ..< len:
     result[i] = init
   result
 
@@ -674,45 +714,178 @@ when isMainModule:
       total = concat(s1, s2, s3)
     assert total == @[1, 2, 3, 4, 5, 6, 7]
 
-  block: # duplicates test
+  block: # count test
+    let
+      s1 = @[1, 2, 3, 2]
+      s2 = @['a', 'b', 'x', 'a']
+      a1 = [1, 2, 3, 2]
+      a2 = ['a', 'b', 'x', 'a']
+      r0 = count(s1, 0)
+      r1 = count(s1, 1)
+      r2 = count(s1, 2)
+      r3 = count(s2, 'y')
+      r4 = count(s2, 'x')
+      r5 = count(s2, 'a')
+      ar0 = count(a1, 0)
+      ar1 = count(a1, 1)
+      ar2 = count(a1, 2)
+      ar3 = count(a2, 'y')
+      ar4 = count(a2, 'x')
+      ar5 = count(a2, 'a')
+    assert r0 == 0
+    assert r1 == 1
+    assert r2 == 2
+    assert r3 == 0
+    assert r4 == 1
+    assert r5 == 2
+    assert ar0 == 0
+    assert ar1 == 1
+    assert ar2 == 2
+    assert ar3 == 0
+    assert ar4 == 1
+    assert ar5 == 2
+
+  block: # cycle tests
+    let
+      a = @[1, 2, 3]
+      b: seq[int] = @[]
+      c = [1, 2, 3]
+
+    doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
+    doAssert a.cycle(0) == @[]
+    #doAssert a.cycle(-1) == @[] # will not compile!
+    doAssert b.cycle(3) == @[]
+    doAssert c.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
+    doAssert c.cycle(0) == @[]
+
+  block: # repeat tests
+    assert repeat(10, 5) == @[10, 10, 10, 10, 10]
+    assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]]
+    assert repeat([1,2,3], 2) == @[[1,2,3], [1,2,3]]
+
+  block: # deduplicates test
     let
       dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4]
       dup2 = @["a", "a", "c", "d", "d"]
+      dup3 = [1, 1, 3, 4, 2, 2, 8, 1, 4]
+      dup4 = ["a", "a", "c", "d", "d"]
       unique1 = deduplicate(dup1)
       unique2 = deduplicate(dup2)
+      unique3 = deduplicate(dup3)
+      unique4 = deduplicate(dup4)
     assert unique1 == @[1, 3, 4, 2, 8]
     assert unique2 == @["a", "c", "d"]
+    assert unique3 == @[1, 3, 4, 2, 8]
+    assert unique4 == @["a", "c", "d"]
 
   block: # zip test
     let
       short = @[1, 2, 3]
       long = @[6, 5, 4, 3, 2, 1]
       words = @["one", "two", "three"]
+      ashort = [1, 2, 3]
+      along = [6, 5, 4, 3, 2, 1]
+      awords = ["one", "two", "three"]
       zip1 = zip(short, long)
       zip2 = zip(short, words)
+      zip3 = zip(ashort, along)
+      zip4 = zip(ashort, awords)
+      zip5 = zip(ashort, words)
     assert zip1 == @[(1, 6), (2, 5), (3, 4)]
     assert zip2 == @[(1, "one"), (2, "two"), (3, "three")]
+    assert zip3 == @[(1, 6), (2, 5), (3, 4)]
+    assert zip4 == @[(1, "one"), (2, "two"), (3, "three")]
+    assert zip5 == @[(1, "one"), (2, "two"), (3, "three")]
     assert zip1[2].b == 4
     assert zip2[2].b == "three"
+    assert zip3[2].b == 4
+    assert zip4[2].b == "three"
+    assert zip5[2].b == "three"
+
+  block: # distribute tests
+    let numbers = @[1, 2, 3, 4, 5, 6, 7]
+    doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]]
+    doAssert numbers.distribute(6)[0] == @[1, 2]
+    doAssert numbers.distribute(6)[5] == @[7]
+    let a = @[1, 2, 3, 4, 5, 6, 7]
+    doAssert a.distribute(1, true)   == @[@[1, 2, 3, 4, 5, 6, 7]]
+    doAssert a.distribute(1, false)  == @[@[1, 2, 3, 4, 5, 6, 7]]
+    doAssert a.distribute(2, true)   == @[@[1, 2, 3, 4], @[5, 6, 7]]
+    doAssert a.distribute(2, false)  == @[@[1, 2, 3, 4], @[5, 6, 7]]
+    doAssert a.distribute(3, true)   == @[@[1, 2, 3], @[4, 5], @[6, 7]]
+    doAssert a.distribute(3, false)  == @[@[1, 2, 3], @[4, 5, 6], @[7]]
+    doAssert a.distribute(4, true)   == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
+    doAssert a.distribute(4, false)  == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
+    doAssert a.distribute(5, true)   == @[@[1, 2], @[3, 4], @[5], @[6], @[7]]
+    doAssert a.distribute(5, false)  == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]]
+    doAssert a.distribute(6, true)   == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]]
+    doAssert a.distribute(6, false)  == @[
+      @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]]
+    doAssert a.distribute(8, false)  == a.distribute(8, true)
+    doAssert a.distribute(90, false) == a.distribute(90, true)
+    var b = @[0]
+    for f in 1 .. 25: b.add(f)
+    doAssert b.distribute(5, true)[4].len == 5
+    doAssert b.distribute(5, false)[4].len == 2
+
+  block: # map test
+    let
+      numbers = @[1, 4, 5, 8, 9, 7, 4]
+      anumbers = [1, 4, 5, 8, 9, 7, 4]
+      m1 = map(numbers, proc(x: int): int = 2*x)
+      m2 = map(anumbers, proc(x: int): int = 2*x)
+    assert m1 == @[2, 8, 10, 16, 18, 14, 8]
+    assert m2 == @[2, 8, 10, 16, 18, 14, 8]
+
+  block: # apply test
+    var a = @["1", "2", "3", "4"]
+    apply(a, proc(x: var string) = x &= "42")
+    assert a == @["142", "242", "342", "442"]
 
   block: # filter proc test
     let
       colors = @["red", "yellow", "black"]
+      acolors = ["red", "yellow", "black"]
       f1 = filter(colors, proc(x: string): bool = x.len < 6)
       f2 = filter(colors) do (x: string) -> bool : x.len > 5
+      f3 = filter(acolors, proc(x: string): bool = x.len < 6)
+      f4 = filter(acolors) do (x: string) -> bool : x.len > 5
     assert f1 == @["red", "black"]
     assert f2 == @["yellow"]
+    assert f3 == @["red", "black"]
+    assert f4 == @["yellow"]
 
   block: # filter iterator test
     let numbers = @[1, 4, 5, 8, 9, 7, 4]
+    let anumbers = [1, 4, 5, 8, 9, 7, 4]
     assert toSeq(filter(numbers, proc (x: int): bool = x mod 2 == 0)) ==
       @[4, 8, 4]
+    assert toSeq(filter(anumbers, proc (x: int): bool = x mod 2 == 0)) ==
+      @[4, 8, 4]
 
   block: # keepIf test
     var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1]
     keepIf(floats, proc(x: float): bool = x > 10)
     assert floats == @[13.0, 12.5, 10.1]
 
+  block: # delete tests
+    let outcome = @[1,1,1,1,1,1,1,1]
+    var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
+    dest.delete(3, 8)
+    assert outcome == dest, """\
+    Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1]
+    is [1,1,1,1,1,1,1,1]"""
+
+  block: # insert tests
+    var dest = @[1,1,1,1,1,1,1,1]
+    let
+      src = @[2,2,2,2,2,2]
+      outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
+    dest.insert(src, 3)
+    assert dest == outcome, """\
+    Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1]
+    at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]"""
+
   block: # filterIt test
     let
       temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44]
@@ -726,37 +899,49 @@ when isMainModule:
     keepItIf(candidates, it.len == 3 and it[0] == 'b')
     assert candidates == @["bar", "baz"]
 
-  block: # any
-    let
-      numbers = @[1, 4, 5, 8, 9, 7, 4]
-      len0seq : seq[int] = @[]
-    assert any(numbers, proc (x: int): bool = return x > 8) == true
-    assert any(numbers, proc (x: int): bool = return x > 9) == false
-    assert any(len0seq, proc (x: int): bool = return true) == false
-
-  block: # anyIt
-    let
-      numbers = @[1, 4, 5, 8, 9, 7, 4]
-      len0seq : seq[int] = @[]
-    assert anyIt(numbers, it > 8) == true
-    assert anyIt(numbers, it > 9) == false
-    assert anyIt(len0seq, true) == false
-
   block: # all
     let
       numbers = @[1, 4, 5, 8, 9, 7, 4]
+      anumbers = [1, 4, 5, 8, 9, 7, 4]
       len0seq : seq[int] = @[]
     assert all(numbers, proc (x: int): bool = return x < 10) == true
     assert all(numbers, proc (x: int): bool = return x < 9) == false
     assert all(len0seq, proc (x: int): bool = return false) == true
+    assert all(anumbers, proc (x: int): bool = return x < 10) == true
+    assert all(anumbers, proc (x: int): bool = return x < 9) == false
 
   block: # allIt
     let
       numbers = @[1, 4, 5, 8, 9, 7, 4]
+      anumbers = [1, 4, 5, 8, 9, 7, 4]
       len0seq : seq[int] = @[]
     assert allIt(numbers, it < 10) == true
     assert allIt(numbers, it < 9) == false
     assert allIt(len0seq, false) == true
+    assert allIt(anumbers, it < 10) == true
+    assert allIt(anumbers, it < 9) == false
+
+  block: # any
+    let
+      numbers = @[1, 4, 5, 8, 9, 7, 4]
+      anumbers = [1, 4, 5, 8, 9, 7, 4]
+      len0seq : seq[int] = @[]
+    assert any(numbers, proc (x: int): bool = return x > 8) == true
+    assert any(numbers, proc (x: int): bool = return x > 9) == false
+    assert any(len0seq, proc (x: int): bool = return true) == false
+    assert any(anumbers, proc (x: int): bool = return x > 8) == true
+    assert any(anumbers, proc (x: int): bool = return x > 9) == false
+
+  block: # anyIt
+    let
+      numbers = @[1, 4, 5, 8, 9, 7, 4]
+      anumbers = [1, 4, 5, 8, 9, 7, 4]
+      len0seq : seq[int] = @[]
+    assert anyIt(numbers, it > 8) == true
+    assert anyIt(numbers, it > 9) == false
+    assert anyIt(len0seq, true) == false
+    assert anyIt(anumbers, it > 8) == true
+    assert anyIt(anumbers, it > 9) == false
 
   block: # toSeq test
     let
@@ -792,56 +977,13 @@ when isMainModule:
     assert multiplication == 495, "Multiplication is (5*(9*(11)))"
     assert concatenation == "nimiscool"
 
-  block: # delete tests
-    let outcome = @[1,1,1,1,1,1,1,1]
-    var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
-    dest.delete(3, 8)
-    assert outcome == dest, """\
-    Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1]
-    is [1,1,1,1,1,1,1,1]"""
-
-  block: # insert tests
-    var dest = @[1,1,1,1,1,1,1,1]
-    let
-      src = @[2,2,2,2,2,2]
-      outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
-    dest.insert(src, 3)
-    assert dest == outcome, """\
-    Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1]
-    at 3 is [1,1,1,2,2,2,2,2,2,1,1,1,1,1]"""
-
   block: # mapIt tests
     var
       nums = @[1, 2, 3, 4]
       strings = nums.mapIt($(4 * it))
     nums.applyIt(it * 3)
     assert nums[0] + nums[3] == 15
-
-  block: # distribute tests
-    let numbers = @[1, 2, 3, 4, 5, 6, 7]
-    doAssert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]]
-    doAssert numbers.distribute(6)[0] == @[1, 2]
-    doAssert numbers.distribute(6)[5] == @[7]
-    let a = @[1, 2, 3, 4, 5, 6, 7]
-    doAssert a.distribute(1, true)   == @[@[1, 2, 3, 4, 5, 6, 7]]
-    doAssert a.distribute(1, false)  == @[@[1, 2, 3, 4, 5, 6, 7]]
-    doAssert a.distribute(2, true)   == @[@[1, 2, 3, 4], @[5, 6, 7]]
-    doAssert a.distribute(2, false)  == @[@[1, 2, 3, 4], @[5, 6, 7]]
-    doAssert a.distribute(3, true)   == @[@[1, 2, 3], @[4, 5], @[6, 7]]
-    doAssert a.distribute(3, false)  == @[@[1, 2, 3], @[4, 5, 6], @[7]]
-    doAssert a.distribute(4, true)   == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
-    doAssert a.distribute(4, false)  == @[@[1, 2], @[3, 4], @[5, 6], @[7]]
-    doAssert a.distribute(5, true)   == @[@[1, 2], @[3, 4], @[5], @[6], @[7]]
-    doAssert a.distribute(5, false)  == @[@[1, 2], @[3, 4], @[5, 6], @[7], @[]]
-    doAssert a.distribute(6, true)   == @[@[1, 2], @[3], @[4], @[5], @[6], @[7]]
-    doAssert a.distribute(6, false)  == @[
-      @[1, 2], @[3, 4], @[5, 6], @[7], @[], @[]]
-    doAssert a.distribute(8, false)  == a.distribute(8, true)
-    doAssert a.distribute(90, false) == a.distribute(90, true)
-    var b = @[0]
-    for f in 1 .. 25: b.add(f)
-    doAssert b.distribute(5, true)[4].len == 5
-    doAssert b.distribute(5, false)[4].len == 2
+    assert strings[2] == "12"
 
   block: # newSeqWith tests
     var seq2D = newSeqWith(4, newSeq[bool](2))
@@ -850,19 +992,5 @@ when isMainModule:
     seq2D[0][1] = true
     doAssert seq2D == @[@[true, true], @[true, false], @[false, false], @[false, false]]
 
-  block: # cycle tests
-    let
-      a = @[1, 2, 3]
-      b: seq[int] = @[]
-
-    doAssert a.cycle(3) == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
-    doAssert a.cycle(0) == @[]
-    #doAssert a.cycle(-1) == @[] # will not compile!
-    doAssert b.cycle(3) == @[]
-
-  block: # repeat tests
-    assert repeat(10, 5) == @[10, 10, 10, 10, 10]
-    assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]]
-
   when not defined(testing):
     echo "Finished doc tests"
diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim
index a9e194fb4..83edf8d94 100644
--- a/lib/pure/collections/sharedstrings.nim
+++ b/lib/pure/collections/sharedstrings.nim
@@ -55,7 +55,7 @@ proc `[]=`*(s: var SharedString; i: Natural; value: char) =
   if i < s.len: s.buffer.data[i+s.first] = value
   else: raise newException(IndexError, "index out of bounds")
 
-proc `[]`*(s: SharedString; ab: Slice[int]): SharedString =
+proc `[]`*(s: SharedString; ab: HSlice[int, int]): SharedString =
   #incRef(src.buffer)
   if ab.a < s.len:
     result.buffer = s.buffer
diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim
index eec98fcaf..9a5bffcef 100644
--- a/lib/pure/collections/tableimpl.nim
+++ b/lib/pure/collections/tableimpl.nim
@@ -149,7 +149,7 @@ template delImpl() {.dirty.} =
   delImplIdx(t, i)
 
 template clearImpl() {.dirty.} =
-  for i in 0 .. <t.data.len:
+  for i in 0 ..< t.data.len:
     when compiles(t.data[i].hcode): # CountTable records don't contain a hcode
       t.data[i].hcode = 0
     t.data[i].key = default(type(t.data[i].key))
diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim
index 603fee080..f01488811 100644
--- a/lib/pure/concurrency/cpuinfo.nim
+++ b/lib/pure/concurrency/cpuinfo.nim
@@ -45,8 +45,25 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
   ## returns the numer of the processors/cores the machine has.
   ## Returns 0 if it cannot be detected.
   when defined(windows):
-    var x = getEnv("NUMBER_OF_PROCESSORS")
-    if x.len > 0: result = parseInt(x.string)
+    type
+      SYSTEM_INFO {.final, pure.} = object
+        u1: int32
+        dwPageSize: int32
+        lpMinimumApplicationAddress: pointer
+        lpMaximumApplicationAddress: pointer
+        dwActiveProcessorMask: ptr int32
+        dwNumberOfProcessors: int32
+        dwProcessorType: int32
+        dwAllocationGranularity: int32
+        wProcessorLevel: int16
+        wProcessorRevision: int16
+
+    proc GetSystemInfo(lpSystemInfo: var SYSTEM_INFO) {.stdcall, dynlib: "kernel32", importc: "GetSystemInfo".}
+
+    var
+      si: SYSTEM_INFO
+    GetSystemInfo(si)
+    result = si.dwNumberOfProcessors
   elif defined(macosx) or defined(bsd):
     var
       mib: array[0..3, cint]
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index 2a0dbd2ca..a5eaec86e 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -149,7 +149,7 @@ proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool =
 proc cleanFlowVars(w: ptr Worker) =
   let q = addr(w.q)
   acquire(q.lock)
-  for i in 0 .. <q.len:
+  for i in 0 ..< q.len:
     GC_unref(cast[RootRef](q.data[i]))
     #echo "GC_unref"
   q.len = 0
@@ -401,7 +401,7 @@ proc setup() =
     gCpus = p
   currentPoolSize = min(p, MaxThreadPoolSize)
   readyWorker = addr(workersData[0])
-  for i in 0.. <currentPoolSize: activateWorkerThread(i)
+  for i in 0..<currentPoolSize: activateWorkerThread(i)
 
 proc preferSpawn*(): bool =
   ## Use this proc to determine quickly if a 'spawn' or a direct call is
@@ -446,14 +446,24 @@ proc nimSpawn3(fn: WorkerProc; data: pointer) {.compilerProc.} =
   # implementation of 'spawn' that is used by the code generator.
   while true:
     if selectWorker(readyWorker, fn, data): return
-    for i in 0.. <currentPoolSize:
+    for i in 0..<currentPoolSize:
       if selectWorker(addr(workersData[i]), fn, data): return
+
     # determine what to do, but keep in mind this is expensive too:
     # state.calls < maxPoolSize: warmup phase
     # (state.calls and 127) == 0: periodic check
     if state.calls < maxPoolSize or (state.calls and 127) == 0:
       # ensure the call to 'advice' is atomic:
       if tryAcquire(stateLock):
+        if currentPoolSize < minPoolSize:
+          if not workersData[currentPoolSize].initialized:
+            activateWorkerThread(currentPoolSize)
+          let w = addr(workersData[currentPoolSize])
+          atomicInc currentPoolSize
+          if selectWorker(w, fn, data):
+            release(stateLock)
+            return
+
         case advice(state)
         of doNothing: discard
         of doCreateThread:
@@ -533,7 +543,7 @@ proc sync*() =
   var toRelease = 0
   while true:
     var allReady = true
-    for i in 0 .. <currentPoolSize:
+    for i in 0 ..< currentPoolSize:
       if not allReady: break
       allReady = allReady and workersData[i].ready
     if allReady: break
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index 2a6d29933..f6592df71 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -22,7 +22,7 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
 
   case p.kind
   of nnkPar:
-    for i in 0 .. <p.len:
+    for i in 0 ..< p.len:
       let ident = p[i]
       var identDefs = newNimNode(nnkIdentDefs)
       case ident.kind
@@ -77,7 +77,7 @@ macro `=>`*(p, b: untyped): untyped =
         if c[0].kind == nnkIdent and c[0].ident == !"->":
           var procTy = createProcType(c[1], c[2])
           params[0] = procTy[0][0]
-          for i in 1 .. <procTy[0].len:
+          for i in 1 ..< procTy[0].len:
             params.add(procTy[0][i])
         else:
           error("Expected proc type (->) got (" & $c[0].ident & ").")
@@ -96,7 +96,7 @@ macro `=>`*(p, b: untyped): untyped =
     if p[0].kind == nnkIdent and p[0].ident == !"->":
       var procTy = createProcType(p[1], p[2])
       params[0] = procTy[0][0]
-      for i in 1 .. <procTy[0].len:
+      for i in 1 ..< procTy[0].len:
         params.add(procTy[0][i])
     else:
       error("Expected proc type (->) got (" & $p[0].ident & ").")
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index cb4f4f664..de1d332a3 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -883,7 +883,9 @@ proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int,
       let data = client.socket.recv(sizeToRecv, timeout)
     else:
       let data = await client.socket.recv(sizeToRecv)
-    if data == "": break # We've been disconnected.
+    if data == "":
+      client.close()
+      break # We've been disconnected.
 
     readLen.inc(data.len)
     if keep:
@@ -950,6 +952,7 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
       if length > 0:
         let recvLen = await client.recvFull(length, client.timeout, true)
         if recvLen == 0:
+          client.close()
           httpError("Got disconnected while trying to read body.")
         if recvLen != length:
           httpError("Received length doesn't match expected length. Wanted " &
@@ -962,13 +965,20 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
       if headers.getOrDefault"Connection" == "close" or httpVersion == "1.0":
         while true:
           let recvLen = await client.recvFull(4000, client.timeout, true)
-          if recvLen == 0: break
+          if recvLen == 0:
+            client.close()
+            break
 
   when client is AsyncHttpClient:
     client.bodyStream.complete()
   else:
     client.bodyStream.setPosition(0)
 
+  # If the server will close our connection, then no matter the method of
+  # reading the body, we need to close our socket.
+  if headers.getOrDefault"Connection" == "close":
+    client.close()
+
 proc parseResponse(client: HttpClient | AsyncHttpClient,
                    getBody: bool): Future[Response | AsyncResponse]
                    {.multisync.} =
@@ -984,7 +994,10 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
       line = await client.socket.recvLine(client.timeout)
     else:
       line = await client.socket.recvLine()
-    if line == "": break # We've been disconnected.
+    if line == "":
+      # We've been disconnected.
+      client.close()
+      break
     if line == "\c\L":
       fullyRead = true
       break
@@ -1033,7 +1046,8 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
                    url: Uri) {.multisync.} =
   if client.currentURL.hostname != url.hostname or
       client.currentURL.scheme != url.scheme or
-      client.currentURL.port != url.port:
+      client.currentURL.port != url.port or
+      (not client.connected):
     let isSsl = url.scheme.toLowerAscii() == "https"
 
     if isSsl and not defined(ssl):
diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim
index a5ab40ca4..f150fa1c1 100644
--- a/lib/pure/httpcore.nim
+++ b/lib/pure/httpcore.nim
@@ -113,6 +113,9 @@ proc newHttpHeaders*(keyValuePairs:
   new result
   result.table = newTable[string, seq[string]](pairs)
 
+proc `$`*(headers: HttpHeaders): string =
+  return $headers.table
+
 proc clear*(headers: HttpHeaders) =
   headers.table.clear()
 
diff --git a/lib/pure/includes/osenv.nim b/lib/pure/includes/osenv.nim
index 8d2fc235a..ae62a5c4e 100644
--- a/lib/pure/includes/osenv.nim
+++ b/lib/pure/includes/osenv.nim
@@ -94,7 +94,7 @@ proc findEnvVar(key: string): int =
     if startsWith(environment[i], temp): return i
   return -1
 
-proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} =
+proc getEnv*(key: string, default = ""): TaintedString {.tags: [ReadEnvEffect].} =
   ## Returns the value of the `environment variable`:idx: named `key`.
   ##
   ## If the variable does not exist, "" is returned. To distinguish
@@ -108,7 +108,7 @@ proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} =
       return TaintedString(substr(environment[i], find(environment[i], '=')+1))
     else:
       var env = c_getenv(key)
-      if env == nil: return TaintedString("")
+      if env == nil: return TaintedString(default)
       result = TaintedString($env)
 
 proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} =
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 656114fb1..3d86cc9d7 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -37,15 +37,15 @@
 ## Retrieving the value of a JSON node can then be achieved using one of the
 ## helper procedures, which include:
 ##
-## * ``getNum``
-## * ``getFNum``
+## * ``getInt``
+## * ``getFloat``
 ## * ``getStr``
-## * ``getBVal``
+## * ``getBool``
 ##
 ## To retrieve the value of ``"key"`` you can do the following:
 ##
 ## .. code-block:: Nim
-##   doAssert jsonNode["key"].getFNum() == 3.14
+##   doAssert jsonNode["key"].getFloat() == 3.14
 ##
 ## The ``[]`` operator will raise an exception when the specified field does
 ## not exist. If you wish to avoid this behaviour you can use the ``{}``
@@ -681,14 +681,25 @@ proc getStr*(n: JsonNode, default: string = ""): string =
   if n.isNil or n.kind != JString: return default
   else: return n.str
 
-proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt =
+proc getInt*(n: JsonNode, default: int = 0): int =
   ## Retrieves the int value of a `JInt JsonNode`.
   ##
   ## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil.
   if n.isNil or n.kind != JInt: return default
+  else: return int(n.num)
+
+proc getBiggestInt*(n: JsonNode, default: BiggestInt = 0): BiggestInt =
+  ## Retrieves the BiggestInt value of a `JInt JsonNode`.
+  ##
+  ## Returns ``default`` if ``n`` is not a ``JInt``, or if ``n`` is nil.
+  if n.isNil or n.kind != JInt: return default
   else: return n.num
 
-proc getFNum*(n: JsonNode, default: float = 0.0): float =
+proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt {.deprecated.} =
+  ## Deprecated - use getInt or getBiggestInt instead
+  getBiggestInt(n, default)
+
+proc getFloat*(n: JsonNode, default: float = 0.0): float =
   ## Retrieves the float value of a `JFloat JsonNode`.
   ##
   ## Returns ``default`` if ``n`` is not a ``JFloat`` or ``JInt``, or if ``n`` is nil.
@@ -698,13 +709,21 @@ proc getFNum*(n: JsonNode, default: float = 0.0): float =
   of JInt: return float(n.num)
   else: return default
 
-proc getBVal*(n: JsonNode, default: bool = false): bool =
+proc getFNum*(n: JsonNode, default: float = 0.0): float {.deprecated.} =
+  ## Deprecated - use getFloat instead
+  getFloat(n, default)
+
+proc getBool*(n: JsonNode, default: bool = false): bool =
   ## Retrieves the bool value of a `JBool JsonNode`.
   ##
   ## Returns ``default`` if ``n`` is not a ``JBool``, or if ``n`` is nil.
   if n.isNil or n.kind != JBool: return default
   else: return n.bval
 
+proc getBVal*(n: JsonNode, default: bool = false): bool {.deprecated.} =
+  ## Deprecated - use getBVal instead
+  getBool(n, default)
+
 proc getFields*(n: JsonNode,
     default = initOrderedTable[string, JsonNode](4)):
         OrderedTable[string, JsonNode] =
@@ -804,13 +823,13 @@ proc toJson(x: NimNode): NimNode {.compiletime.} =
   of nnkBracket: # array
     if x.len == 0: return newCall(bindSym"newJArray")
     result = newNimNode(nnkBracket)
-    for i in 0 .. <x.len:
+    for i in 0 ..< x.len:
       result.add(toJson(x[i]))
     result = newCall(bindSym"%", result)
   of nnkTableConstr: # object
     if x.len == 0: return newCall(bindSym"newJObject")
     result = newNimNode(nnkTableConstr)
-    for i in 0 .. <x.len:
+    for i in 0 ..< x.len:
       x[i].expectKind nnkExprColonExpr
       result.add newTree(nnkExprColonExpr, x[i][0], toJson(x[i][1]))
     result = newCall(bindSym"%", result)
@@ -1284,7 +1303,7 @@ else:
     case getVarType(x)
     of JArray:
       result = newJArray()
-      for i in 0 .. <x.len:
+      for i in 0 ..< x.len:
         result.add(x[i].convertObject())
     of JObject:
       result = newJObject()
@@ -1342,7 +1361,7 @@ proc getEnum(node: JsonNode, ast: string, T: typedesc): T =
     # TODO: I shouldn't need this proc.
     proc convert[T](x: BiggestInt): T = T(x)
     verifyJsonKind(node, {JInt}, ast)
-    return convert[T](node.getNum())
+    return convert[T](node.getBiggestInt())
   else:
     verifyJsonKind(node, {JString}, ast)
     return parseEnum[T](node.getStr())
@@ -1430,7 +1449,7 @@ proc processElseBranch(recCaseNode, elseBranch, jsonNode, kindType,
   # We need to build up a list of conditions from each ``of`` branch so that
   # we can then negate it to get ``else``.
   var cond = newIdentNode("false")
-  for i in 1 .. <len(recCaseNode):
+  for i in 1 ..< len(recCaseNode):
     if recCaseNode[i].kind == nnkElse:
       break
 
@@ -1492,7 +1511,7 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
     exprColonExpr.add(getEnumCall)
 
     # Iterate through each `of` branch.
-    for i in 1 .. <field.len:
+    for i in 1 ..< field.len:
       case field[i].kind
       of nnkOfBranch:
         result.add processOfBranch(field[i], jsonNode, kindType, kindJsonNode)
@@ -1621,7 +1640,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
         (
           var list: `typeSym` = @[];
           verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`));
-          for `forLoopI` in 0 .. <`jsonNode`.len: list.add(`constructorNode`);
+          for `forLoopI` in 0 ..< `jsonNode`.len: list.add(`constructorNode`);
           list
         )
     of "array":
@@ -1635,7 +1654,7 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
         (
           var list: `typeSym`;
           verifyJsonKind(`jsonNode`, {JArray}, astToStr(`jsonNode`));
-          for `forLoopI` in 0 .. <`jsonNode`.len: list[`forLoopI`] =`constructorNode`;
+          for `forLoopI` in 0 ..< `jsonNode`.len: list[`forLoopI`] =`constructorNode`;
           list
         )
 
@@ -1664,7 +1683,7 @@ proc postProcessValue(value: NimNode): NimNode =
     result = postProcess(value)
   else:
     result = value
-    for i in 0 .. <len(result):
+    for i in 0 ..< len(result):
       result[i] = postProcessValue(result[i])
 
 proc postProcessExprColonExpr(exprColonExpr, resIdent: NimNode): NimNode =
diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim
index cf2e8bb89..15a390f0b 100644
--- a/lib/pure/lexbase.nim
+++ b/lib/pure/lexbase.nim
@@ -37,6 +37,7 @@ type
     lineNumber*: int          ## the current line number
     sentinel: int
     lineStart: int            # index of last line start in buffer
+    offsetBase*: int          # use ``offsetBase + bufpos`` to get the offset
     refillChars: set[char]
 
 {.deprecated: [TBaseLexer: BaseLexer].}
@@ -107,7 +108,8 @@ proc fillBaseLexer(L: var BaseLexer, pos: int): int =
     result = pos + 1          # nothing to do
   else:
     fillBuffer(L)
-    L.bufpos = 0              # XXX: is this really correct?
+    L.offsetBase += pos
+    L.bufpos = 0
     result = 0
 
 proc handleCR*(L: var BaseLexer, pos: int): int =
@@ -147,6 +149,7 @@ proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192;
   assert(input != nil)
   L.input = input
   L.bufpos = 0
+  L.offsetBase = 0
   L.bufLen = bufLen
   L.refillChars = refillChars
   when defined(js):
diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim
index c4c731acf..6ee830786 100644
--- a/lib/pure/marshal.nim
+++ b/lib/pure/marshal.nim
@@ -283,7 +283,7 @@ proc to*[T](data: string): T =
   loadAny(newStringStream(data), toAny(result), tab)
 
 when not defined(testing) and isMainModule:
-  template testit(x: expr) = echo($$to[type(x)]($$x))
+  template testit(x: untyped) = echo($$to[type(x)]($$x))
 
   var x: array[0..4, array[0..4, string]] = [
     ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim
index 7022c21d9..6366fee1a 100644
--- a/lib/pure/matchers.nim
+++ b/lib/pure/matchers.nim
@@ -48,7 +48,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect,
      "aero", "jobs", "museum": return true
   else: return false
 
-proc parseInt*(s: string, value: var int, validRange: Slice[int]) {.
+proc parseInt*(s: string, value: var int, validRange: HSlice[int, int]) {.
   noSideEffect, rtl, extern: "nmatchParseInt".} =
   ## parses `s` into an integer in the range `validRange`. If successful,
   ## `value` is modified to contain the result. Otherwise no exception is
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 8037b31b0..7fd8bbcef 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -184,6 +184,8 @@ when not defined(JS):
   proc pow*(x, y: float32): float32 {.importc: "powf", header: "<math.h>".}
   proc pow*(x, y: float64): float64 {.importc: "pow", header: "<math.h>".}
     ## computes x to power raised of y.
+    ##
+    ## To compute power between integers, use `^` e.g. 2 ^ 6
 
   proc erf*(x: float32): float32 {.importc: "erff", header: "<math.h>".}
   proc erf*(x: float64): float64 {.importc: "erf", header: "<math.h>".}
diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim
index 98fc62a3b..6c8701843 100644
--- a/lib/pure/nativesockets.nim
+++ b/lib/pure/nativesockets.nim
@@ -496,11 +496,12 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
                    addr(namelen)) == -1'i32:
       raiseOSError(osLastError())
     # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
-    var buf: array[64, char]
+    result[0] = newString(64)
     if inet_ntop(name.sin6_family.cint,
-                 addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
+                 addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
       raiseOSError(osLastError())
-    result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
+    setLen(result[0], result[0].cstring.len)
+    result[1] = Port(nativesockets.ntohs(name.sin6_port))
   else:
     raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
 
@@ -532,11 +533,12 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
                    addr(namelen)) == -1'i32:
       raiseOSError(osLastError())
     # Cannot use INET6_ADDRSTRLEN here, because it's a C define.
-    var buf: array[64, char]
+    result[0] = newString(64)
     if inet_ntop(name.sin6_family.cint,
-                 addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
+                 addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
       raiseOSError(osLastError())
-    result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
+    setLen(result[0], result[0].cstring.len)
+    result[1] = Port(nativesockets.ntohs(name.sin6_port))
   else:
     raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
 
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 215a301b6..a405ce1bd 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -857,13 +857,16 @@ 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:
           socketError(socket, res)
   finally:
+    when defineSsl:
+      if socket.isSSL and socket.sslHandle != nil:
+        SSLFree(socket.sslHandle)
+        socket.sslHandle = nil
+
     socket.fd.close()
 
 proc toCInt*(opt: SOBool): cint =
diff --git a/lib/pure/options.nim b/lib/pure/options.nim
index ad63bbcb6..6d2869bff 100644
--- a/lib/pure/options.nim
+++ b/lib/pure/options.nim
@@ -153,7 +153,10 @@ proc `==`*(a, b: Option): bool =
   (a.has and b.has and a.val == b.val) or (not a.has and not b.has)
 
 proc `$`*[T](self: Option[T]): string =
-  ## Returns the contents of this option or `otherwise` if the option is none.
+  ## Get the string representation of this option. If the option has a value,
+  ## the result will be `Some(x)` where `x` is the string representation of the contained value.
+  ## If the option does not have a value, the result will be `None[T]` where `T` is the name of 
+  ## the type contained in the option.
   if self.has:
     "Some(" & $self.val & ")"
   else:
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index b85181edf..a1ae4e250 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -790,7 +790,10 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
         while true:
           var x = readdir(d)
           if x == nil: break
-          var y = $x.d_name
+          when defined(nimNoArrayToCstringConversion):
+            var y = $cstring(addr x.d_name)
+          else:
+            var y = $x.d_name.cstring
           if y != "." and y != "..":
             var s: Stat
             if not relative:
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 07429b9a9..71d3d9c72 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -280,7 +280,7 @@ proc execProcesses*(cmds: openArray[string],
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
   ## is returned. Runs `beforeRunEvent` before running each command.
-  when defined(posix):
+  when false:
     # poParentStreams causes problems on Posix, so we simply disable it:
     var options = options - {poParentStreams}
 
@@ -617,6 +617,7 @@ when defined(Windows) and not defined(useNimRtl):
     var res: int32
     discard getExitCodeProcess(p.fProcessHandle, res)
     result = res
+    p.exitStatus = res
     discard closeHandle(p.fProcessHandle)
 
   proc peekExitCode(p: Process): int =
@@ -625,6 +626,7 @@ when defined(Windows) and not defined(useNimRtl):
     else:
       var res: int32
       discard getExitCodeProcess(p.fProcessHandle, res)
+      if res == 0: return p.exitStatus
       return res
 
   proc inputStream(p: Process): Stream =
diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim
index 77b145a73..ca0f3f9e0 100644
--- a/lib/pure/parsecsv.nim
+++ b/lib/pure/parsecsv.nim
@@ -72,7 +72,10 @@ proc raiseEInvalidCsv(filename: string, line, col: int,
                       msg: string) {.noreturn.} =
   var e: ref CsvError
   new(e)
-  e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg
+  if filename.len == 0:
+    e.msg = "Error: " & msg
+  else:
+    e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg
   raise e
 
 proc error(my: CsvParser, pos: int, msg: string) =
diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim
index 2e8dbe140..a2ff9bf0c 100644
--- a/lib/pure/parseopt2.nim
+++ b/lib/pure/parseopt2.nim
@@ -35,7 +35,7 @@ type
     cmd: seq[string]
     pos: int
     remainingShortOptions: string
-    kind*: CmdLineKind        ## the dected command line token
+    kind*: CmdLineKind        ## the detected command line token
     key*, val*: TaintedString ## key and value pair; ``key`` is the option
                               ## or the argument, ``value`` is not "" if
                               ## the option was given a value
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index b78e8d000..3c790512f 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -8,6 +8,8 @@
 #
 
 ## This module contains helpers for parsing tokens, numbers, identifiers, etc.
+##
+## To unpack raw bytes look at the `streams <streams.html>`_ module.
 
 {.deadCodeElim: on.}
 
diff --git a/lib/pure/random.nim b/lib/pure/random.nim
index 27fbfad45..e6a9162c5 100644
--- a/lib/pure/random.nim
+++ b/lib/pure/random.nim
@@ -93,7 +93,7 @@ proc random*(max: float): float {.benign.} =
     let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
     result = (cast[float](u) - 1.0) * max
 
-proc random*[T](x: Slice[T]): T =
+proc random*[T](x: HSlice[T, T]): T =
   ## For a slice `a .. b` returns a value in the range `a .. b-1`.
   result = T(random(x.b - x.a)) + x.a
 
diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim
index c2ba2b1f3..7fb24c26f 100644
--- a/lib/pure/rationals.nim
+++ b/lib/pure/rationals.nim
@@ -39,47 +39,13 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] =
   result.num = x
   result.den = 1
 
-proc toRationalSub(x: float, n: int): Rational[int] =
-  var
-    a = 0'i64
-    b, c, d = 1'i64
-  result = 0 // 1   # rational 0
-  while b <= n and d <= n:
-    let ac = (a+c)
-    let bd = (b+d)
-    # scale by 1000 so not overflow for high precision
-    let mediant = (ac.float/1000) / (bd.float/1000)
-    if x == mediant:
-      if bd <= n:
-        result.num = ac.int
-        result.den = bd.int
-        return result
-      elif d > b:
-        result.num = c.int
-        result.den = d.int
-        return result
-      else:
-        result.num = a.int
-        result.den = b.int
-        return result
-    elif x > mediant:
-      a = ac
-      b = bd
-    else:
-      c = ac
-      d = bd
-  if (b > n):
-    return initRational(c.int, d.int)
-  return initRational(a.int, b.int)
-
-proc toRational*(x: float, n: int = high(int)): Rational[int] =
-  ## Calculate the best rational numerator and denominator
+proc toRational*(x: float, n: int = high(int32)): Rational[int] =
+  ## Calculates the best rational numerator and denominator
   ## that approximates to `x`, where the denominator is
   ## smaller than `n` (default is the largest possible
-  ## int to give maximum resolution)
+  ## int to give maximum resolution).
   ##
-  ## The algorithm is based on the Farey sequence named
-  ## after John Farey
+  ## The algorithm is based on the theory of continued fractions.
   ##
   ## .. code-block:: Nim
   ##  import math, rationals
@@ -88,13 +54,24 @@ proc toRational*(x: float, n: int = high(int)): Rational[int] =
   ##    let x = toRational(PI, t)
   ##    let newPI = x.num / x.den
   ##    echo x, " ", newPI, " error: ", PI - newPI, "  ", t
-  if x > 1:
-    result = toRationalSub(1.0/x, n)
-    swap(result.num, result.den)
-  elif x == 1.0:
-    result = 1 // 1
-  else:
-    result = toRationalSub(x, n)
+
+  # David Eppstein / UC Irvine / 8 Aug 1993
+  # With corrections from Arno Formella, May 2008
+  var
+    m11, m22 = 1
+    m12, m21 = 0
+    ai = int(x)
+    x = x
+  while m21 * ai + m22 <= n:
+    swap m12, m11
+    swap m22, m21
+    m11 = m12 * ai + m11
+    m21 = m22 * ai + m21
+    if x == float(ai): break  # division by zero
+    x = 1/(x - float(ai))
+    if x > float(high(int32)): break  # representation failure
+    ai = int(x)
+  result = m11 // m21
 
 proc toFloat*[T](x: Rational[T]): float =
   ## Convert a rational number `x` to a float.
@@ -346,7 +323,14 @@ when isMainModule:
   assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
   assert toInt(z) == 0
 
-  assert toRational(0.98765432) == 12345679 // 12500000
-  assert toRational(0.1, 1000000) == 1 // 10
-  assert toRational(0.9, 1000000) == 9 // 10
-  #assert toRational(PI) == 80143857 // 25510582
+  assert toRational(0.98765432) == 2111111029 // 2137499919
+  assert toRational(PI) == 817696623 // 260280919
+  assert toRational(0.1) == 1 // 10
+  assert toRational(0.9) == 9 // 10
+
+  assert toRational(0.0) == 0 // 1
+  assert toRational(-0.25) == 1 // -4
+  assert toRational(3.2) == 16 // 5
+  assert toRational(0.33) == 33 // 100
+  assert toRational(0.22) == 11 // 50
+  assert toRational(10.0) == 10 // 1
diff --git a/lib/pure/securehash.nim b/lib/pure/securehash.nim
index c19146669..57c1f3631 100644
--- a/lib/pure/securehash.nim
+++ b/lib/pure/securehash.nim
@@ -181,7 +181,7 @@ proc `$`*(self: SecureHash): string =
     result.add(toHex(int(v), 2))
 
 proc parseSecureHash*(hash: string): SecureHash =
-  for i in 0.. <Sha1DigestSize:
+  for i in 0 ..< Sha1DigestSize:
     Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1]))
 
 proc `==`*(a, b: SecureHash): bool =
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index 506b2cec0..d17b6c253 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -162,7 +162,7 @@ elif defined(linux):
         return @[]
       raiseOSError(err)
     if evNum == 0: return @[]
-    for i in 0 .. <evNum:
+    for i in 0 ..< evNum:
       let fd = s.events[i].data.fd.SocketHandle
 
       var evSet: set[Event] = {}
@@ -253,7 +253,7 @@ elif defined(macosx) or defined(freebsd) or defined(openbsd) or defined(netbsd):
         return @[]
       raiseOSError(err)
     if evNum == 0: return @[]
-    for i in 0 .. <evNum:
+    for i in 0 ..< evNum:
       let fd = s.events[i].ident.SocketHandle
 
       var evSet: set[Event] = {}
diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim
index 69f673990..354e07da3 100644
--- a/lib/pure/streams.nim
+++ b/lib/pure/streams.nim
@@ -224,6 +224,38 @@ proc peekInt64*(s: Stream): int64 =
   ## peeks an int64 from the stream `s`. Raises `EIO` if an error occurred.
   peek(s, result)
 
+proc readUint8*(s: Stream): uint8 =
+  ## reads an uint8 from the stream `s`. Raises `EIO` if an error occurred.
+  read(s, result)
+
+proc peekUint8*(s: Stream): uint8 =
+  ## peeks an uint8 from the stream `s`. Raises `EIO` if an error occurred.
+  peek(s, result)
+
+proc readUint16*(s: Stream): uint16 =
+  ## reads an uint16 from the stream `s`. Raises `EIO` if an error occurred.
+  read(s, result)
+
+proc peekUint16*(s: Stream): uint16 =
+  ## peeks an uint16 from the stream `s`. Raises `EIO` if an error occurred.
+  peek(s, result)
+
+proc readUint32*(s: Stream): uint32 =
+  ## reads an uint32 from the stream `s`. Raises `EIO` if an error occurred.
+  read(s, result)
+
+proc peekUint32*(s: Stream): uint32 =
+  ## peeks an uint32 from the stream `s`. Raises `EIO` if an error occurred.
+  peek(s, result)
+
+proc readUint64*(s: Stream): uint64 =
+  ## reads an uint64 from the stream `s`. Raises `EIO` if an error occurred.
+  read(s, result)
+
+proc peekUint64*(s: Stream): uint64 =
+  ## peeks an uint64 from the stream `s`. Raises `EIO` if an error occurred.
+  peek(s, result)
+
 proc readFloat32*(s: Stream): float32 =
   ## reads a float32 from the stream `s`. Raises `EIO` if an error occurred.
   read(s, result)
diff --git a/lib/pure/strscans.nim b/lib/pure/strscans.nim
index bf26d2e59..a54556915 100644
--- a/lib/pure/strscans.nim
+++ b/lib/pure/strscans.nim
@@ -253,7 +253,7 @@ is performed.
   for r in collectLinks(body):
     echo r
 
-In this example both macros are combined seamlessly in order to maximise 
+In this example both macros are combined seamlessly in order to maximise
 efficiency and perform different checks.
 
 .. code-block:: nim
@@ -308,7 +308,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
   ## See top level documentation of his module of how ``scanf`` works.
   template matchBind(parser) {.dirty.} =
     var resLen = genSym(nskLet, "resLen")
-    conds.add newLetStmt(resLen, newCall(bindSym(parser), input, results[i], idx))
+    conds.add newLetStmt(resLen, newCall(bindSym(parser), inp, results[i], idx))
     conds.add resLen.notZero
     conds.add resLen
 
@@ -316,7 +316,8 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
   var p = 0
   var idx = genSym(nskVar, "idx")
   var res = genSym(nskVar, "res")
-  result = newTree(nnkStmtListExpr, newVarStmt(idx, newLit 0), newVarStmt(res, newLit false))
+  let inp = genSym(nskLet, "inp")
+  result = newTree(nnkStmtListExpr, newLetStmt(inp, input), newVarStmt(idx, newLit 0), newVarStmt(res, newLit false))
   var conds = newTree(nnkStmtList)
   var fullMatch = false
   while p < pattern.len:
@@ -325,7 +326,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
       case pattern[p]
       of '$':
         var resLen = genSym(nskLet, "resLen")
-        conds.add newLetStmt(resLen, newCall(bindSym"skip", input, newLit($pattern[p]), idx))
+        conds.add newLetStmt(resLen, newCall(bindSym"skip", inp, newLit($pattern[p]), idx))
         conds.add resLen.notZero
         conds.add resLen
       of 'w':
@@ -347,7 +348,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
           error("no float var given for $f")
         inc i
       of 's':
-        conds.add newCall(bindSym"inc", idx, newCall(bindSym"skipWhitespace", input, idx))
+        conds.add newCall(bindSym"inc", idx, newCall(bindSym"skipWhitespace", inp, idx))
         conds.add newEmptyNode()
         conds.add newEmptyNode()
       of '.':
@@ -364,7 +365,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
             token.add pattern[q]
             inc q
           var resLen = genSym(nskLet, "resLen")
-          conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", input, results[i], newLit(token), idx))
+          conds.add newLetStmt(resLen, newCall(bindSym"parseUntil", inp, results[i], newLit(token), idx))
           conds.add newCall(bindSym"!=", resLen, newLit min)
           conds.add resLen
         else:
@@ -386,7 +387,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
         let expr = pattern.substr(start, p-1)
         if i < results.len:
           var resLen = genSym(nskLet, "resLen")
-          conds.add newLetStmt(resLen, buildUserCall(expr, input, results[i], idx))
+          conds.add newLetStmt(resLen, buildUserCall(expr, inp, results[i], idx))
           conds.add newCall(bindSym"!=", resLen, newLit 0)
           conds.add resLen
         else:
@@ -406,7 +407,7 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
           else: discard
           inc p
         let expr = pattern.substr(start, p-1)
-        conds.add newCall(bindSym"inc", idx, buildUserCall(expr, input, idx))
+        conds.add newCall(bindSym"inc", idx, buildUserCall(expr, inp, idx))
         conds.add newEmptyNode()
         conds.add newEmptyNode()
       else: error("invalid format string")
@@ -417,13 +418,13 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
         token.add pattern[p]
         inc p
       var resLen = genSym(nskLet, "resLen")
-      conds.add newLetStmt(resLen, newCall(bindSym"skip", input, newLit(token), idx))
+      conds.add newLetStmt(resLen, newCall(bindSym"skip", inp, newLit(token), idx))
       conds.add resLen.notZero
       conds.add resLen
   result.add conditionsToIfChain(conds, idx, res, 0)
   if fullMatch:
     result.add newCall(bindSym"and", res,
-      newCall(bindSym">=", idx, newCall(bindSym"len", input)))
+      newCall(bindSym">=", idx, newCall(bindSym"len", inp)))
   else:
     result.add res
 
@@ -684,3 +685,14 @@ when isMainModule:
           "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613",
           "main c:/users/anwender/projects/nim/lib/system.nim:2620"]
   doAssert parseGDB(gdbOut) == result
+
+  # bug #6487
+  var count = 0
+
+  proc test(): string =
+    inc count
+    result = ",123123"
+
+  var a: int
+  discard scanf(test(), ",$i", a)
+  doAssert count == 1
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 8b4e6bd05..2b87e0d43 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -138,7 +138,8 @@ proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar,
 
   result = true
   for c in s:
-    result = c.isAlphaNumeric() and result
+    if not c.isAlphaNumeric():
+      return false
 
 proc isDigit*(s: string): bool {.noSideEffect, procvar,
   rtl, extern: "nsuIsDigitStr".}=
@@ -153,7 +154,8 @@ proc isDigit*(s: string): bool {.noSideEffect, procvar,
 
   result = true
   for c in s:
-    result = c.isDigit() and result
+    if not c.isDigit():
+      return false
 
 proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar,
   rtl, extern: "nsuIsSpaceAsciiStr".}=
@@ -1062,8 +1064,8 @@ proc align*(s: string, count: Natural, padding = ' '): string {.
   ##
   ## `padding` characters (by default spaces) are added before `s` resulting in
   ## right alignment. If ``s.len >= count``, no spaces are added and `s` is
-  ## returned unchanged. If you need to left align a string use the `repeatChar
-  ## proc <#repeatChar>`_. Example:
+  ## returned unchanged. If you need to left align a string use the `alignLeft
+  ## proc <#alignLeft>`_. Example:
   ##
   ## .. code-block:: nim
   ##   assert align("abc", 4) == " abc"
@@ -1078,6 +1080,28 @@ proc align*(s: string, count: Natural, padding = ' '): string {.
   else:
     result = s
 
+proc alignLeft*(s: string, count: Natural, padding = ' '): string {.noSideEffect.} =
+  ## Left-Aligns a string `s` with `padding`, so that it is of length `count`.
+  ##
+  ## `padding` characters (by default spaces) are added after `s` resulting in
+  ## left alignment. If ``s.len >= count``, no spaces are added and `s` is
+  ## returned unchanged. If you need to right align a string use the `align
+  ## proc <#align>`_. Example:
+  ##
+  ## .. code-block:: nim
+  ##   assert alignLeft("abc", 4) == "abc "
+  ##   assert alignLeft("a", 0) == "a"
+  ##   assert alignLeft("1232", 6) == "1232  "
+  ##   assert alignLeft("1232", 6, '#') == "1232##"
+  if s.len < count:
+    result = newString(count)
+    if s.len > 0:
+      result[0 .. (s.len - 1)] = s
+    for i in s.len ..< count:
+      result[i] = padding
+  else:
+    result = s
+
 iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[
   token: string, isSep: bool] =
   ## Tokenizes the string `s` into substrings.
@@ -1175,7 +1199,7 @@ proc unindent*(s: string, count: Natural, padding: string = " "): string
     var indentCount = 0
     for j in 0..<count.int:
       indentCount.inc
-      if line[j .. j + <padding.len] != padding:
+      if line[j .. j + padding.len-1] != padding:
         indentCount = j
         break
     result.add(line[indentCount*padding.len .. ^1])
@@ -1306,18 +1330,36 @@ proc join*[T: not string](a: openArray[T], sep: string = ""): string {.
     add(result, $x)
 
 type
-  SkipTable = array[char, int]
-
-{.push profiler: off.}
-proc preprocessSub(sub: string, a: var SkipTable) =
-  var m = len(sub)
-  for i in 0..0xff: a[chr(i)] = m+1
-  for i in 0..m-1: a[sub[i]] = m-i
-{.pop.}
+  SkipTable* = array[char, int]
 
-proc findAux(s, sub: string, start, last: int, a: SkipTable): int =
-  # Fast "quick search" algorithm:
-  var
+proc initSkipTable*(a: var SkipTable, sub: string)
+  {.noSideEffect, rtl, extern: "nsuInitSkipTable".} =
+  ## Preprocess table `a` for `sub`.
+  let m = len(sub)
+  let m1 = m + 1
+  var i = 0
+  while i <= 0xff-7:
+    a[chr(i + 0)] = m1
+    a[chr(i + 1)] = m1
+    a[chr(i + 2)] = m1
+    a[chr(i + 3)] = m1
+    a[chr(i + 4)] = m1
+    a[chr(i + 5)] = m1
+    a[chr(i + 6)] = m1
+    a[chr(i + 7)] = m1
+    i += 8
+
+  for i in 0..m-1:
+    a[sub[i]] = m-i
+
+proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int
+  {.noSideEffect, rtl, extern: "nsuFindStrA".} =
+  ## Searches for `sub` in `s` inside range `start`..`last` using preprocessed table `a`.
+  ## If `last` is unspecified, it defaults to `s.high`.
+  ##
+  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
+  let
+    last = if last==0: s.high else: last
     m = len(sub)
     n = last + 1
   # search:
@@ -1337,17 +1379,6 @@ when not (defined(js) or defined(nimdoc) or defined(nimscript)):
 else:
   const hasCStringBuiltin = false
 
-proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect,
-  rtl, extern: "nsuFindStr".} =
-  ## Searches for `sub` in `s` inside range `start`..`last`.
-  ## If `last` is unspecified, it defaults to `s.high`.
-  ##
-  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
-  var a {.noinit.}: SkipTable
-  let last = if last==0: s.high else: last
-  preprocessSub(sub, a)
-  result = findAux(s, sub, start, last, a)
-
 proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.noSideEffect,
   rtl, extern: "nsuFindChar".} =
   ## Searches for `sub` in `s` inside range `start`..`last`.
@@ -1366,9 +1397,24 @@ proc find*(s: string, sub: char, start: Natural = 0, last: Natural = 0): int {.n
     else:
       for i in start..last:
         if sub == s[i]: return i
-
   return -1
 
+proc find*(s, sub: string, start: Natural = 0, last: Natural = 0): int {.noSideEffect,
+  rtl, extern: "nsuFindStr".} =
+  ## Searches for `sub` in `s` inside range `start`..`last`.
+  ## If `last` is unspecified, it defaults to `s.high`.
+  ##
+  ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
+  if sub.len > s.len:
+    return -1
+
+  if sub.len == 1:
+    return find(s, sub[0], start, last)
+
+  var a {.noinit.}: SkipTable
+  initSkipTable(a, sub)
+  result = find(a, s, sub, start, last)
+
 proc find*(s: string, chars: set[char], start: Natural = 0, last: Natural = 0): int {.noSideEffect,
   rtl, extern: "nsuFindCharSet".} =
   ## Searches for `chars` in `s` inside range `start`..`last`.
@@ -1500,11 +1546,11 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect,
   ## Replaces `sub` in `s` by the string `by`.
   var a {.noinit.}: SkipTable
   result = ""
-  preprocessSub(sub, a)
+  initSkipTable(a, sub)
   let last = s.high
   var i = 0
   while true:
-    var j = findAux(s, sub, i, last, a)
+    var j = find(a, s, sub, i, last)
     if j < 0: break
     add result, substr(s, i, j - 1)
     add result, by
@@ -1534,11 +1580,11 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
   const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
   var a {.noinit.}: SkipTable
   result = ""
-  preprocessSub(sub, a)
+  initSkipTable(a, sub)
   var i = 0
   let last = s.high
   while true:
-    var j = findAux(s, sub, i, last, a)
+    var j = find(a, s, sub, i, last)
     if j < 0: break
     # word boundary?
     if (j == 0 or s[j-1] notin wordChars) and
@@ -1890,17 +1936,32 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
       frmtstr[3] = '*'
       frmtstr[4] = floatFormatToChar[format]
       frmtstr[5] = '\0'
-      L = c_sprintf(buf, frmtstr, precision, f)
+      when defined(nimNoArrayToCstringConversion):
+        L = c_sprintf(addr buf, addr frmtstr, precision, f)
+      else:
+        L = c_sprintf(buf, frmtstr, precision, f)
     else:
       frmtstr[1] = floatFormatToChar[format]
       frmtstr[2] = '\0'
-      L = c_sprintf(buf, frmtstr, f)
+      when defined(nimNoArrayToCstringConversion):
+        L = c_sprintf(addr buf, addr frmtstr, f)
+      else:
+        L = c_sprintf(buf, frmtstr, f)
     result = newString(L)
     for i in 0 ..< L:
       # Depending on the locale either dot or comma is produced,
       # but nothing else is possible:
       if buf[i] in {'.', ','}: result[i] = decimalsep
       else: result[i] = buf[i]
+    when defined(vcc):
+      # VS pre 2015 violates the C standard: "The exponent always contains at
+      # least two digits, and only as many more digits as necessary to
+      # represent the exponent." [C11 §7.21.6.1]
+      # The following post-processing fixes this behavior.
+      if result.len > 4 and result[^4] == '+' and result[^3] == '0':
+        result[^3] = result[^2]
+        result[^2] = result[^1]
+        result.setLen(result.len - 1)
 
 proc formatFloat*(f: float, format: FloatFormatMode = ffDefault,
                   precision: range[0..32] = 16; decimalSep = '.'): string {.
@@ -2169,11 +2230,26 @@ proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {.
         if idx >% a.high: invalidFormatString()
         add s, a[idx]
       of '{':
-        var j = i+1
-        while formatstr[j] notin {'\0', '}'}: inc(j)
-        var x = findNormalized(substr(formatstr, i+2, j-1), a)
-        if x >= 0 and x < high(a): add s, a[x+1]
-        else: invalidFormatString()
+        var j = i+2
+        var k = 0
+        var negative = formatstr[j] == '-'
+        if negative: inc j
+        var isNumber = 0
+        while formatstr[j] notin {'\0', '}'}:
+          if formatstr[j] in Digits:
+            k = k * 10 + ord(formatstr[j]) - ord('0')
+            if isNumber == 0: isNumber = 1
+          else:
+            isNumber = -1
+          inc(j)
+        if isNumber == 1:
+          let idx = if not negative: k-1 else: a.len-k
+          if idx >% a.high: invalidFormatString()
+          add s, a[idx]
+        else:
+          var x = findNormalized(substr(formatstr, i+2, j-1), a)
+          if x >= 0 and x < high(a): add s, a[x+1]
+          else: invalidFormatString()
         i = j+1
       of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
         var j = i+1
@@ -2250,60 +2326,104 @@ proc format*(formatstr: string, a: varargs[string, `$`]): string {.noSideEffect,
 
 proc removeSuffix*(s: var string, chars: set[char] = Newlines) {.
   rtl, extern: "nsuRemoveSuffixCharSet".} =
-  ## Removes the first matching character from the string (in-place) given a
-  ## set of characters. If the set of characters is only equal to `Newlines`
-  ## then it will remove both the newline and return feed.
+  ## Removes all characters from `chars` from the end of the string `s`
+  ## (in-place).
+  ##
   ## .. code-block:: nim
-  ##   var
-  ##     userInput = "Hello World!\r\n"
-  ##     otherInput = "Hello!?!"
+  ##   var userInput = "Hello World!*~\r\n"
   ##   userInput.removeSuffix
-  ##   userInput == "Hello World!"
-  ##   userInput.removeSuffix({'!', '?'})
-  ##   userInput == "Hello World"
+  ##   doAssert userInput == "Hello World!*~"
+  ##   userInput.removeSuffix({'~', '*'})
+  ##   doAssert userInput == "Hello World!"
+  ##
+  ##   var otherInput = "Hello!?!"
   ##   otherInput.removeSuffix({'!', '?'})
-  ##   otherInput == "Hello!?"
+  ##   doAssert otherInput == "Hello"
   if s.len == 0: return
-  var last = len(s) - 1
-  if chars == Newlines:
-    if s[last] == '\10':
-      last -= 1
-    if s[last] == '\13':
-      last -= 1
-  else:
-    if s[last] in chars:
-      last -= 1
+  var last = s.high
+  while last > -1 and s[last] in chars: last -= 1
   s.setLen(last + 1)
 
 proc removeSuffix*(s: var string, c: char) {.
   rtl, extern: "nsuRemoveSuffixChar".} =
-  ## Removes a single character (in-place) from a string.
+  ## Removes all occurrences of a single character (in-place) from the end
+  ## of a string.
+  ##
   ## .. code-block:: nim
-  ##   var
-  ##     table = "users"
+  ##   var table = "users"
   ##   table.removeSuffix('s')
-  ##   table == "user"
+  ##   doAssert table == "user"
+  ##
+  ##   var dots = "Trailing dots......."
+  ##   dots.removeSuffix('.')
+  ##   doAssert dots == "Trailing dots"
   removeSuffix(s, chars = {c})
 
 proc removeSuffix*(s: var string, suffix: string) {.
   rtl, extern: "nsuRemoveSuffixString".} =
   ## Remove the first matching suffix (in-place) from a string.
+  ##
   ## .. code-block:: nim
-  ##   var
-  ##     answers = "yeses"
+  ##   var answers = "yeses"
   ##   answers.removeSuffix("es")
-  ##   answers == "yes"
+  ##   doAssert answers == "yes"
   var newLen = s.len
   if s.endsWith(suffix):
     newLen -= len(suffix)
     s.setLen(newLen)
 
+proc removePrefix*(s: var string, chars: set[char] = Newlines) {.
+  rtl, extern: "nsuRemovePrefixCharSet".} =
+  ## Removes all characters from `chars` from the start of the string `s`
+  ## (in-place).
+  ##
+  ## .. code-block:: nim
+  ##   var userInput = "\r\n*~Hello World!"
+  ##   userInput.removePrefix
+  ##   doAssert userInput == "*~Hello World!"
+  ##   userInput.removePrefix({'~', '*'})
+  ##   doAssert userInput == "Hello World!"
+  ##
+  ##   var otherInput = "?!?Hello!?!"
+  ##   otherInput.removePrefix({'!', '?'})
+  ##   doAssert otherInput == "Hello!?!"
+  var start = 0
+  while start < s.len and s[start] in chars: start += 1
+  if start > 0: s.delete(0, start - 1)
+
+proc removePrefix*(s: var string, c: char) {.
+  rtl, extern: "nsuRemovePrefixChar".} =
+  ## Removes all occurrences of a single character (in-place) from the start
+  ## of a string.
+  ##
+  ## .. code-block:: nim
+  ##   var ident = "pControl"
+  ##   ident.removePrefix('p')
+  ##   doAssert ident == "Control"
+  removePrefix(s, chars = {c})
+
+proc removePrefix*(s: var string, prefix: string) {.
+  rtl, extern: "nsuRemovePrefixString".} =
+  ## Remove the first matching prefix (in-place) from a string.
+  ##
+  ## .. code-block:: nim
+  ##   var answers = "yesyes"
+  ##   answers.removePrefix("yes")
+  ##   doAssert answers == "yes"
+  if s.startsWith(prefix):
+    s.delete(0, prefix.len - 1)
+
 when isMainModule:
   doAssert align("abc", 4) == " abc"
   doAssert align("a", 0) == "a"
   doAssert align("1232", 6) == "  1232"
   doAssert align("1232", 6, '#') == "##1232"
 
+  doAssert alignLeft("abc", 4) == "abc "
+  doAssert alignLeft("a", 0) == "a"
+  doAssert alignLeft("1232", 6) == "1232  "
+  doAssert alignLeft("1232", 6, '#') == "1232##"
+
   let
     inp = """ this is a long text --  muchlongerthan10chars and here
                it goes"""
@@ -2313,8 +2433,12 @@ when isMainModule:
   doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
   doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in
                                                    ["1,0e-11", "1,0e-011"]
+  # bug #6589
+  doAssert formatFloat(123.456, ffScientific, precision=0) in
+      ["1.234560e+02", "1.234560e+002"]
 
   doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
+  doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb"
 
   block: # formatSize tests
     doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB"
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 68a457084..7dd428904 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -77,20 +77,17 @@ when defined(posix) and not defined(JS):
 
   when not defined(freebsd) and not defined(netbsd) and not defined(openbsd):
     var timezone {.importc, header: "<time.h>".}: int
+    proc tzset(): void {.importc, header: "<time.h>".}
+    tzset()
 
 elif defined(windows):
   import winlean
 
-  when defined(vcc) or defined(bcc) or defined(icl):
-    # newest version of Visual C++ defines time_t to be of 64 bits
-    type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64
-    # visual c's c runtime exposes these under a different name
-    var
-      timezone {.importc: "_timezone", header: "<time.h>".}: int
-  else:
-    type TimeImpl {.importc: "time_t", header: "<time.h>".} = int
-    var
-      timezone {.importc, header: "<time.h>".}: int
+  # newest version of Visual C++ defines time_t to be of 64 bits
+  type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64
+  # visual c's c runtime exposes these under a different name
+  var
+    timezone {.importc: "_timezone", header: "<time.h>".}: int
 
   type
     Time* = distinct TimeImpl
@@ -1028,7 +1025,7 @@ proc countLeapYears*(yearSpan: int): int =
   ## counts the number of leap years up to January 1st of a given year.
   ## Keep in mind that if specified year is a leap year, the leap day
   ## has not happened before January 1st of that year.
-  (((yearSpan - 1) / 4) - ((yearSpan - 1) / 100) + ((yearSpan - 1) / 400)).int
+  (yearSpan - 1) div 4 - (yearSpan - 1) div 100 + (yearSpan - 1) div 400
 
 proc countDays*(yearSpan: int): int =
   ## Returns the number of days spanned by a given number of years.
diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim
index 55c4bf038..3b6f7de1a 100644
--- a/lib/pure/typetraits.nim
+++ b/lib/pure/typetraits.nim
@@ -31,6 +31,10 @@ proc name*(t: typedesc): string {.magic: "TypeTrait".}
   ##   test(@['A','B'])
   ##   # --> type: seq[char], value: @[A, B]
 
+proc `$`*(t: typedesc): string =
+  ## An alias for `name`.
+  name(t)
+
 proc arity*(t: typedesc): int {.magic: "TypeTrait".}
   ## Returns the arity of the given type
 
@@ -49,3 +53,15 @@ proc stripGenericParams*(t: typedesc): typedesc {.magic: "TypeTrait".}
   ## This trait is similar to `genericHead`, but instead of producing
   ## error for non-generic types, it will just return them unmodified
 
+proc supportsCopyMem*(t: typedesc): bool {.magic: "TypeTrait".}
+  ## This trait returns true iff the type ``t`` is safe to use for
+  ## `copyMem`:idx:. Other languages name a type like these `blob`:idx:.
+
+
+when isMainModule:
+  # echo type(42)
+  import streams
+  var ss = newStringStream()
+  ss.write($type(42)) # needs `$`
+  ss.setPosition(0)
+  doAssert ss.readAll() == "int"
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index 0c4f15c91..7d9c3108b 100644
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -285,7 +285,7 @@ proc runeReverseOffset*(s: string, rev:Positive): (int, int) =
 
 proc runeSubStr*(s: string, pos:int, len:int = int.high): string =
   ## Returns the UTF-8 substring starting at codepoint pos
-  ## with len codepoints. If pos or len is negativ they count from
+  ## with len codepoints. If pos or len is negative they count from
   ## the end of the string. If len is not given it means the longest
   ## possible string.
   ##
diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim
index 3772a213a..7a8d1dad0 100644
--- a/lib/pure/unittest.nim
+++ b/lib/pure/unittest.nim
@@ -312,7 +312,7 @@ proc ensureInitialized() =
 
   if not testsToRun.isValid:
     testsToRun.init()
-    when declared(os):
+    when declared(paramCount):
       # Read tests to run from the command line.
       for i in 1 .. paramCount():
         testsToRun.incl(paramStr(i))
diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim
index d8e4ed52f..c702b054c 100644
--- a/lib/pure/uri.nim
+++ b/lib/pure/uri.nim
@@ -250,7 +250,7 @@ proc combine*(base: Uri, reference: Uri): Uri =
 proc combine*(uris: varargs[Uri]): Uri =
   ## Combines multiple URIs together.
   result = uris[0]
-  for i in 1 .. <uris.len:
+  for i in 1 ..< uris.len:
     result = combine(result, uris[i])
 
 proc isAbsolute*(uri: Uri): bool =
@@ -278,7 +278,9 @@ proc `/`*(x: Uri, path: string): Uri =
   result = x
 
   if result.path.len == 0:
-    result.path = path
+    if path[0] != '/':
+      result.path = "/"
+    result.path.add(path)
     return
 
   if result.path[result.path.len-1] == '/':
@@ -476,6 +478,11 @@ when isMainModule:
     let foo = parseUri("http://example.com") / "/baz"
     doAssert foo.path == "/baz"
 
+  # bug found on stream 13/10/17
+  block:
+    let foo = parseUri("http://localhost:9515") / "status"
+    doAssert $foo == "http://localhost:9515/status"
+
   # isAbsolute tests
   block:
     doAssert "www.google.com".parseUri().isAbsolute() == false
@@ -515,4 +522,6 @@ when isMainModule:
     doAssert "https://example.com/about".parseUri().isAbsolute == true
     doAssert "https://example.com/about/staff.html".parseUri().isAbsolute == true
     doAssert "https://example.com/about/staff.html?".parseUri().isAbsolute == true
-    doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true
\ No newline at end of file
+    doAssert "https://example.com/about/staff.html?parameters".parseUri().isAbsolute == true
+
+  echo("All good!")
\ No newline at end of file
diff --git a/lib/system.nim b/lib/system.nim
index dc3152faf..92c5e009f 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -275,7 +275,7 @@ proc low*[T](x: T): T {.magic: "Low", noSideEffect.}
 proc low*[I, T](x: typeDesc[array[I, T]]): I {.magic: "Low", noSideEffect.}
 proc low*(x: cstring): int {.magic: "Low", noSideEffect.}
 proc low*(x: string): int {.magic: "Low", noSideEffect.}
-## returns the lowest possible index of an array, a sequence, a string or
+  ## returns the lowest possible index of an array, a sequence, a string or
   ## the lowest possible value of an ordinal value `x`. As a special
   ## semantic rule, `x` may also be a type identifier.
   ##
@@ -285,6 +285,13 @@ proc low*(x: string): int {.magic: "Low", noSideEffect.}
   ##  low(2) #=> -9223372036854775808
   ##  low(int) #=> -9223372036854775808
 
+proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
+  ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy
+  ## only changes the semantics for sequences and strings (and types which
+  ## contain those). Be careful with the changed semantics though! There
+  ## is a reason why the default assignment does a deep copy of sequences
+  ## and strings.
+
 when defined(nimArrIdx):
   # :array|openarray|string|seq|cstring|tuple
   proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
@@ -292,15 +299,21 @@ when defined(nimArrIdx):
   proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
     x: S) {.noSideEffect, magic: "ArrPut".}
   proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
+  when defined(nimNewRuntime):
+    proc `=destroy`*[T](x: var T) {.inline, magic: "Asgn".} =
+      ## generic `destructor`:idx: implementation that can be overriden.
+      discard
+    proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} =
+      ## generic `sink`:idx: implementation that can be overriden.
+      shallowCopy(x, y)
 
 type
-  Slice*[T] = object ## builtin slice type
-    a*, b*: T        ## the bounds
+  HSlice*[T, U] = object ## "heterogenous" slice type
+    a*: T        ## the lower bound (inclusive)
+    b*: U        ## the upper bound (inclusive)
+  Slice*[T] = HSlice[T, T] ## an alias for ``HSlice[T, T]``
 
-when defined(nimalias):
-  {.deprecated: [TSlice: Slice].}
-
-proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} =
+proc `..`*[T, U](a: T, b: U): HSlice[T, U] {.noSideEffect, inline, magic: "DotDot".} =
   ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a`
   ## and `b` are inclusive. Slices can also be used in the set constructor
   ## and in ordinal case statements, but then they are special-cased by the
@@ -308,7 +321,7 @@ proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} =
   result.a = a
   result.b = b
 
-proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline, magic: "DotDot".} =
+proc `..`*[T](b: T): HSlice[int, T] {.noSideEffect, inline, magic: "DotDot".} =
   ## `slice`:idx: operator that constructs an interval ``[default(T), b]``
   result.b = b
 
@@ -638,13 +651,17 @@ proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
 when defined(nimtypedescfixed):
   proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.}
 
-proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.}
+proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect, deprecated.}
   ## unary ``<`` that can be used for nice looking excluding ranges:
   ##
   ## .. code-block:: nim
   ##   for i in 0 .. <10: echo i #=> 0 1 2 3 4 5 6 7 8 9
   ##
   ## Semantically this is the same as ``pred``.
+  ##
+  ## **Deprecated since version 0.18.0**. For the common excluding range
+  ## write ``0 ..< 10`` instead of ``0 .. < 10`` (look at the spacing).
+  ## For ``<x`` write ``pred(x)``.
 
 proc succ*[T](x: Ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.}
   ## returns the ``y``-th successor of the value ``x``. ``T`` has to be
@@ -1150,7 +1167,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
   ## is achieved by reversing the parameters for ``contains``; ``in`` then
   ## passes its arguments in reverse order.
 
-proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} =
+proc contains*[U, V, W](s: HSlice[U, V], value: W): bool {.noSideEffect, inline.} =
   ## Checks if `value` is within the range of `s`; returns true iff
   ## `value >= s.a and value <= s.b`
   ##
@@ -1429,7 +1446,8 @@ when defined(nimdoc):
     ## <#GC_fullCollect>`_.
     ##
     ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim
-    ## program finishes without incident. A raised unhandled exception is
+    ## program finishes without incident for platforms where this is the
+    ## expected behavior. A raised unhandled exception is
     ## equivalent to calling ``quit(QuitFailure)``.
     ##
     ## Note that this is a *runtime* call and using ``quit`` inside a macro won't
@@ -1444,7 +1462,7 @@ elif defined(genode):
     header: "<base/sleep.h>".}
 
 elif defined(nodejs):
-  proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", 
+  proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
     importc: "process.exit", noreturn.}
 
 else:
@@ -1480,13 +1498,6 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =
   setLen(x, xl + y.len)
   for i in 0..high(y): x[xl+i] = y[i]
 
-proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
-  ## use this instead of `=` for a `shallow copy`:idx:. The shallow copy
-  ## only changes the semantics for sequences and strings (and types which
-  ## contain those). Be careful with the changed semantics though! There
-  ## is a reason why the default assignment does a deep copy of sequences
-  ## and strings.
-
 proc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} =
   ## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`.
   ## This is an O(1) operation.
@@ -1875,7 +1886,7 @@ proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
 proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.}
   ## The stringify operator for a boolean argument. Returns `x`
   ## converted to the string "false" or "true".
-
+#
 proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.}
   ## The stringify operator for a character argument. Returns `x`
   ## converted to a string.
@@ -2065,6 +2076,9 @@ proc max*[T](x, y: T): T =
   if y <= x: x else: y
 {.pop.}
 
+proc high*(T: typedesc[SomeReal]): T = Inf
+proc low*(T: typedesc[SomeReal]): T = NegInf
+
 proc clamp*[T](x, a, b: T): T =
   ## limits the value ``x`` within the interval [a, b]
   ##
@@ -2075,7 +2089,7 @@ proc clamp*[T](x, a, b: T): T =
   if x > b: return b
   return x
 
-proc len*[T: Ordinal](x: Slice[T]): int {.noSideEffect, inline.} =
+proc len*[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int {.noSideEffect, inline.} =
   ## length of ordinal slice, when x.b < x.a returns zero length
   ##
   ## .. code-block:: Nim
@@ -2143,7 +2157,7 @@ iterator items*(E: typedesc[enum]): E =
   for v in low(E)..high(E):
     yield v
 
-iterator items*[T](s: Slice[T]): T =
+iterator items*[T](s: HSlice[T, T]): T =
   ## iterates over the slice `s`, yielding each value between `s.a` and `s.b`
   ## (inclusively).
   for x in s.a..s.b:
@@ -2437,20 +2451,28 @@ proc `$`*[T: tuple|object](x: T): string =
       result.add("...")
   result.add(")")
 
-proc collectionToString[T: set | seq](x: T, b, e: string): string =
-  when x is seq:
-    if x.isNil: return "nil"
-  result = b
+proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
+  result = prefix
   var firstElement = true
   for value in items(x):
-    if not firstElement: result.add(", ")
+    if firstElement:
+      firstElement = false
+    else:
+      result.add(separator)
+
     when compiles(value.isNil):
-      if value.isNil: result.add "nil"
-      else: result.add($value)
+      # this branch should not be necessary
+      if value.isNil:
+        result.add "nil"
+      else:
+        result.add($value)
+    # prevent temporary string allocation
+    elif compiles(result.add(value)):
+      result.add(value)
     else:
       result.add($value)
-    firstElement = false
-  result.add(e)
+
+  result.add(suffix)
 
 proc `$`*[T](x: set[T]): string =
   ## generic ``$`` operator for sets that is lifted from the components
@@ -2458,7 +2480,7 @@ proc `$`*[T](x: set[T]): string =
   ##
   ## .. code-block:: nim
   ##   ${23, 45} == "{23, 45}"
-  collectionToString(x, "{", "}")
+  collectionToString(x, "{", ", ", "}")
 
 proc `$`*[T](x: seq[T]): string =
   ## generic ``$`` operator for seqs that is lifted from the components
@@ -2466,13 +2488,10 @@ proc `$`*[T](x: seq[T]): string =
   ##
   ## .. code-block:: nim
   ##   $(@[23, 45]) == "@[23, 45]"
-  collectionToString(x, "@[", "]")
-
-when false:
-  # causes bootstrapping to fail as we use array of chars and cstring should
-  # match better ...
-  proc `$`*[T, IDX](x: array[IDX, T]): string =
-    collectionToString(x, "[", "]")
+  if x.isNil:
+    "nil"
+  else:
+    collectionToString(x, "@[", ", ", "]")
 
 # ----------------- GC interface ---------------------------------------------
 
@@ -2816,7 +2835,7 @@ when not defined(JS): #and not defined(nimscript):
       fmRead,                   ## Open the file for read access only.
       fmWrite,                  ## Open the file for write access only.
                                 ## If the file does not exist, it will be
-                                ## created.
+                                ## created. Existing files will be cleared!
       fmReadWrite,              ## Open the file for read and write access.
                                 ## If the file does not exist, it will be
                                 ## created. Existing files will be cleared!
@@ -2872,7 +2891,7 @@ when not defined(JS): #and not defined(nimscript):
         importc: when defined(bcc): "setmode" else: "_setmode",
         header: "<io.h>".}
       var
-        O_BINARY {.importc: "O_BINARY", nodecl.}: cint
+        O_BINARY {.importc: "_O_BINARY", header:"<fcntl.h>".}: cint
 
       # we use binary mode on Windows:
       c_setmode(c_fileno(stdin), O_BINARY)
@@ -3329,6 +3348,10 @@ elif defined(JS):
     include "system/sysio"
 
 
+proc `$`*[T, IDX](x: array[IDX, T]): string =
+  ## generic ``$`` operator for arrays that is lifted from the components
+  collectionToString(x, "[", ", ", "]")
+
 proc quit*(errormsg: string, errorcode = QuitFailure) {.noReturn.} =
   ## a shorthand for ``echo(errormsg); quit(errorcode)``.
   echo(errormsg)
@@ -3393,6 +3416,29 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} =
   ## integer division that results in a float.
   result = toFloat(x) / toFloat(y)
 
+type
+  BackwardsIndex* = distinct int ## type that is constructed by ``^`` for
+                                 ## reversed array accesses.
+
+template `^`*(x: int): BackwardsIndex = BackwardsIndex(x)
+  ## builtin `roof`:idx: operator that can be used for convenient array access.
+  ## ``a[^x]`` is a shortcut for ``a[a.len-x]``.
+
+template `..^`*(a, b: untyped): untyped =
+  ## a shortcut for '.. ^' to avoid the common gotcha that a space between
+  ## '..' and '^' is required.
+  a .. ^b
+
+template `..<`*(a, b: untyped): untyped =
+  ## a shortcut for 'a..pred(b)'.
+  a .. pred(b)
+
+iterator `..<`*[S,T](a: S, b: T): T =
+  var i = T(a)
+  while i < b:
+    yield i
+    inc i
+
 template spliceImpl(s, a, L, b: untyped): untyped =
   # make room for additional elements or cut:
   var shift = b.len - max(0,L)  # ignore negative slice size
@@ -3406,19 +3452,22 @@ template spliceImpl(s, a, L, b: untyped): untyped =
     # cut down:
     setLen(s, newLen)
   # fill the hole:
-  for i in 0 .. <b.len: s[a+i] = b[i]
+  for i in 0 ..< b.len: s[a+i] = b[i]
+
+template `^^`(s, i: untyped): untyped =
+  (when i is BackwardsIndex: s.len - int(i) else: int(i))
 
 when hasAlloc or defined(nimscript):
-  proc `[]`*(s: string, x: Slice[int]): string {.inline.} =
+  proc `[]`*[T, U](s: string, x: HSlice[T, U]): string {.inline.} =
     ## slice operation for strings.
     ## returns the inclusive range [s[x.a], s[x.b]]:
     ##
     ## .. code-block:: nim
     ##    var s = "abcdef"
     ##    assert s[1..3] == "bcd"
-    result = s.substr(x.a, x.b)
+    result = s.substr(s ^^ x.a, s ^^ x.b)
 
-  proc `[]=`*(s: var string, x: Slice[int], b: string) =
+  proc `[]=`*[T, U](s: var string, x: HSlice[T, U], b: string) =
     ## slice assignment for strings. If
     ## ``b.len`` is not exactly the number of elements that are referred to
     ## by `x`, a `splice`:idx: is performed:
@@ -3427,75 +3476,74 @@ when hasAlloc or defined(nimscript):
     ##   var s = "abcdef"
     ##   s[1 .. ^2] = "xyz"
     ##   assert s == "axyzf"
-    var a = x.a
-    var L = x.b - a + 1
+    var a = s ^^ x.a
+    var L = (s ^^ x.b) - a + 1
     if L == b.len:
-      for i in 0 .. <L: s[i+a] = b[i]
+      for i in 0..<L: s[i+a] = b[i]
     else:
       spliceImpl(s, a, L, b)
 
-proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[int]): seq[T] =
+proc `[]`*[Idx, T, U, V](a: array[Idx, T], x: HSlice[U, V]): seq[T] =
   ## slice operation for arrays.
   ## returns the inclusive range [a[x.a], a[x.b]]:
   ##
   ## .. code-block:: nim
   ##    var a = [1,2,3,4]
   ##    assert a[0..2] == @[1,2,3]
-  when low(a) < 0:
-    {.error: "Slicing for arrays with negative indices is unsupported.".}
-  var L = x.b - x.a + 1
+  let xa = a ^^ x.a
+  let L = (a ^^ x.b) - xa + 1
   result = newSeq[T](L)
-  for i in 0.. <L: result[i] = a[i + x.a]
-
-proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[int], b: openArray[T]) =
-  ## slice assignment for arrays.
-  when low(a) < 0:
-    {.error: "Slicing for arrays with negative indices is unsupported.".}
-  var L = x.b - x.a + 1
-  if L == b.len:
-    for i in 0 .. <L: a[i+x.a] = b[i]
-  else:
-    sysFatal(RangeError, "different lengths for slice assignment")
-
-proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] =
-  ## slice operation for arrays.
-  var L = ord(x.b) - ord(x.a) + 1
-  newSeq(result, L)
-  for i in 0.. <L:
-    result[i] = a[Idx(ord(x.a) + i)]
+  for i in 0..<L: result[i] = a[Idx(i + xa + int low(a))]
 
-proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) =
+proc `[]=`*[Idx, T, U, V](a: var array[Idx, T], x: HSlice[U, V], b: openArray[T]) =
   ## slice assignment for arrays.
-  var L = ord(x.b) - ord(x.a) + 1
+  let xa = a ^^ x.a
+  let L = (a ^^ x.b) - xa + 1
   if L == b.len:
-    for i in 0 .. <L:
-      a[Idx(ord(x.a) + i)] = b[i]
+    for i in 0..<L: a[Idx(i + xa + int low(a))] = b[i]
   else:
     sysFatal(RangeError, "different lengths for slice assignment")
 
-proc `[]`*[T](s: seq[T], x: Slice[int]): seq[T] =
+proc `[]`*[T, U, V](s: openArray[T], x: HSlice[U, V]): seq[T] =
   ## slice operation for sequences.
   ## returns the inclusive range [s[x.a], s[x.b]]:
   ##
   ## .. code-block:: nim
   ##    var s = @[1,2,3,4]
   ##    assert s[0..2] == @[1,2,3]
-  var a = x.a
-  var L = x.b - a + 1
+  let a = s ^^ x.a
+  let L = (s ^^ x.b) - a + 1
   newSeq(result, L)
-  for i in 0.. <L: result[i] = s[i + a]
+  for i in 0 ..< L: result[i] = s[i + a]
 
-proc `[]=`*[T](s: var seq[T], x: Slice[int], b: openArray[T]) =
+proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) =
   ## slice assignment for sequences. If
   ## ``b.len`` is not exactly the number of elements that are referred to
   ## by `x`, a `splice`:idx: is performed.
-  var a = x.a
-  var L = x.b - a + 1
+  let a = s ^^ x.a
+  let L = (s ^^ x.b) - a + 1
   if L == b.len:
-    for i in 0 .. <L: s[i+a] = b[i]
+    for i in 0 ..< L: s[i+a] = b[i]
   else:
     spliceImpl(s, a, L, b)
 
+proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = s[s.len - int(i)]
+proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} =
+  a[Idx(a.len - int(i) + int low(a))]
+proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)]
+
+proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} =
+  s[s.len - int(i)]
+proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} =
+  a[Idx(a.len - int(i) + int low(a))]
+
+proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} =
+  s[s.len - int(i)] = x
+proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} =
+  a[Idx(a.len - int(i) + int low(a))] = x
+proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} =
+  s[s.len - int(i)] = x
+
 proc slurp*(filename: string): string {.magic: "Slurp".}
   ## This is an alias for `staticRead <#staticRead>`_.
 
@@ -3836,31 +3884,6 @@ proc procCall*(x: untyped) {.magic: "ProcCall", compileTime.} =
   ##   procCall someMethod(a, b)
   discard
 
-proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".}
-proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
-  ## builtin `roof`:idx: operator that can be used for convenient array access.
-  ## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``
-  ## expression must not have side effects for this to compile. Note that since
-  ## this is a builtin, it automatically works for all kinds of
-  ## overloaded ``[]`` or ``[]=`` accessors.
-  discard
-
-template `..^`*(a, b: untyped): untyped =
-  ## a shortcut for '.. ^' to avoid the common gotcha that a space between
-  ## '..' and '^' is required.
-  a .. ^b
-
-template `..<`*(a, b: untyped): untyped {.dirty.} =
-  ## a shortcut for '.. <' to avoid the common gotcha that a space between
-  ## '..' and '<' is required.
-  a .. <b
-
-iterator `..<`*[S,T](a: S, b: T): T =
-  var i = T(a)
-  while i < b:
-    yield i
-    inc i
-
 proc xlen*(x: string): int {.magic: "XLenStr", noSideEffect.} = discard
 proc xlen*[T](x: seq[T]): int {.magic: "XLenSeq", noSideEffect.} =
   ## returns the length of a sequence or a string without testing for 'nil'.
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 78db96e77..19d27e7d2 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -301,13 +301,14 @@ proc pageAddr(p: pointer): PChunk {.inline.} =
   result = cast[PChunk](cast[ByteAddress](p) and not PageMask)
   #sysAssert(Contains(allocator.chunkStarts, pageIndex(result)))
 
-proc writeFreeList(a: MemRegion) =
-  var it = a.freeChunksList
-  c_fprintf(stdout, "freeChunksList: %p\n", it)
-  while it != nil:
-    c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n",
-              it, it.next, it.prev, it.size)
-    it = it.next
+when false:
+  proc writeFreeList(a: MemRegion) =
+    var it = a.freeChunksList
+    c_fprintf(stdout, "freeChunksList: %p\n", it)
+    while it != nil:
+      c_fprintf(stdout, "it: %p, next: %p, prev: %p, size: %ld\n",
+                it, it.next, it.prev, it.size)
+      it = it.next
 
 const nimMaxHeap {.intdefine.} = 0
 
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index b2f6d314f..0bac979e7 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -103,8 +103,12 @@ proc c_sprintf(buf, frmt: cstring): cint {.
   importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
   # we use it only in a way that cannot lead to security issues
 
-proc c_fileno(f: File): cint {.
-  importc: "fileno", header: "<fcntl.h>".}
+when defined(windows):
+  proc c_fileno(f: File): cint {.
+      importc: "_fileno", header: "<stdio.h>".}
+else:
+  proc c_fileno(f: File): cint {.
+      importc: "fileno", header: "<fcntl.h>".}
 
 proc c_malloc(size: csize): pointer {.
   importc: "malloc", header: "<stdlib.h>".}
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 115df61a7..f061c89cf 100644
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -61,13 +61,17 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
       unsureAsgnRef(x, s2)
       return
     sysAssert(dest != nil, "genericAssignAux 3")
-    unsureAsgnRef(x, newSeq(mt, seq.len))
-    var dst = cast[ByteAddress](cast[PPointer](dest)[])
     if ntfNoRefs in mt.base.flags:
+      var ss = nimNewSeqOfCap(mt, seq.len)
+      cast[PGenericSeq](ss).len = seq.len
+      unsureAsgnRef(x, ss)
+      var dst = cast[ByteAddress](cast[PPointer](dest)[])
       copyMem(cast[pointer](dst +% GenericSeqSize),
               cast[pointer](cast[ByteAddress](s2) +% GenericSeqSize),
               seq.len * mt.base.size)
     else:
+      unsureAsgnRef(x, newSeq(mt, seq.len))
+      var dst = cast[ByteAddress](cast[PPointer](dest)[])
       for i in 0..seq.len-1:
         genericAssignAux(
           cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim
index cc6919d36..937c0d6f0 100644
--- a/lib/system/debugger.nim
+++ b/lib/system/debugger.nim
@@ -127,7 +127,7 @@ proc fileMatches(c, bp: cstring): bool =
 
 proc canonFilename*(filename: cstring): cstring =
   ## returns 'nil' if the filename cannot be found.
-  for i in 0 .. <dbgFilenameLen:
+  for i in 0 .. dbgFilenameLen-1:
     result = dbgFilenames[i]
     if fileMatches(result, filename): return result
   result = nil
@@ -261,7 +261,7 @@ proc genericHash(dest: pointer, mt: PNimType): int =
 proc dbgRegisterWatchpoint(address: pointer, name: cstring,
                            typ: PNimType) {.compilerproc.} =
   let L = watchPointsLen
-  for i in 0.. <L:
+  for i in 0 .. pred(L):
     if watchPoints[i].name == name:
       # address may have changed:
       watchPoints[i].address = address
@@ -288,7 +288,7 @@ var
 
 proc checkWatchpoints =
   let L = watchPointsLen
-  for i in 0.. <L:
+  for i in 0 .. pred(L):
     let newHash = genericHash(watchPoints[i].address, watchPoints[i].typ)
     if newHash != watchPoints[i].oldValue:
       dbgWatchpointHook(watchPoints[i].name)
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 2b86ddf25..c8e251d1e 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -142,7 +142,10 @@ elif defined(windows) or defined(dos):
         dec(m)
         k = k div 10
         if k == 0: break
-      result = getProcAddress(cast[THINSTANCE](lib), decorated)
+      when defined(nimNoArrayToCstringConversion):
+        result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
+      else:
+        result = getProcAddress(cast[THINSTANCE](lib), decorated)
       if result != nil: return
     procAddrError(name)
 
diff --git a/lib/system/endb.nim b/lib/system/endb.nim
index d4d10a52c..35d8f25c4 100644
--- a/lib/system/endb.nim
+++ b/lib/system/endb.nim
@@ -76,10 +76,10 @@ proc `==`(a, b: StaticStr): bool =
     return true
 
 proc `==`(a: StaticStr, b: cstring): bool =
-  result = c_strcmp(a.data, b) == 0
+  result = c_strcmp(unsafeAddr a.data, b) == 0
 
 proc write(f: File, s: StaticStr) =
-  write(f, cstring(s.data))
+  write(f, cstring(unsafeAddr s.data))
 
 proc listBreakPoints() =
   write(stdout, EndbBeg)
@@ -260,8 +260,8 @@ proc parseBreakpoint(s: cstring, start: int): Breakpoint =
   if result.high == 0: result.high = result.low
   i = scanFilename(s, dbgTemp, i)
   if dbgTemp.len != 0:
-    if not hasExt(dbgTemp.data): add(dbgTemp, ".nim")
-    result.filename = canonFilename(dbgTemp.data.cstring)
+    if not hasExt(addr dbgTemp.data): add(dbgTemp, ".nim")
+    result.filename = canonFilename(addr dbgTemp.data)
     if result.filename.isNil:
       debugOut("[Warning] no breakpoint could be set; unknown filename ")
       return
@@ -292,12 +292,12 @@ proc dbgEvaluate(stream: File, s: cstring, start: int, f: PFrame) =
     i = scanAndAppendWord(s, dbgTemp, i)
     for i in 0 .. getGlobalLen()-1:
       let v = getGlobal(i)
-      if c_strcmp(v.name, dbgTemp.data) == 0:
+      if c_strcmp(v.name, addr dbgTemp.data) == 0:
         writeVariable(stream, v)
   else:
     for i in 0 .. f.len-1:
       let v = getLocal(f, i)
-      if c_strcmp(v.name, dbgTemp.data) == 0:
+      if c_strcmp(v.name, addr dbgTemp.data) == 0:
         writeVariable(stream, v)
 
 proc dbgOut(s: cstring, start: int, currFrame: PFrame) =
@@ -306,7 +306,7 @@ proc dbgOut(s: cstring, start: int, currFrame: PFrame) =
   if dbgTemp.len == 0:
     invalidCommand()
     return
-  var stream = openAppend(dbgTemp.data)
+  var stream = openAppend(addr dbgTemp.data)
   if stream == nil:
     debugOut("[Warning] could not open or create file ")
     return
@@ -320,7 +320,7 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
     # just write it to stdout:
     listFrame(stdout, currFrame)
   else:
-    var stream = openAppend(dbgTemp.data)
+    var stream = openAppend(addr dbgTemp.data)
     if stream == nil:
       debugOut("[Warning] could not open or create file ")
       return
@@ -369,7 +369,7 @@ proc commandPrompt() =
     if not readLine(stdin, dbgUser): break
     if dbgUser.len == 0: dbgUser.len = oldLen
     # now look what we have to do:
-    var i = scanWord(dbgUser.data, dbgTemp, 0)
+    var i = scanWord(addr dbgUser.data, dbgTemp, 0)
     template `?`(x: expr): expr = dbgTemp == cstring(x)
     if ?"s" or ?"step":
       dbgState = dbStepInto
@@ -400,13 +400,13 @@ proc commandPrompt() =
         prevState = dbgState
         prevSkipFrame = dbgSkipToFrame
       dbgState = dbSkipCurrent
-      dbgEvaluate(stdout, dbgUser.data, i, dbgFramePtr)
+      dbgEvaluate(stdout, addr dbgUser.data, i, dbgFramePtr)
       dbgState = prevState
       dbgSkipToFrame = prevSkipFrame
     elif ?"o" or ?"out":
-      dbgOut(dbgUser.data, i, dbgFramePtr)
+      dbgOut(addr dbgUser.data, i, dbgFramePtr)
     elif ?"stackframe":
-      dbgStackFrame(dbgUser.data, i, dbgFramePtr)
+      dbgStackFrame(addr dbgUser.data, i, dbgFramePtr)
     elif ?"w" or ?"where":
       dbgShowExecutionPoint()
     elif ?"l" or ?"locals":
@@ -444,16 +444,16 @@ proc commandPrompt() =
     elif ?"bt" or ?"backtrace":
       dbgWriteStackTrace(framePtr)
     elif ?"b" or ?"break":
-      createBreakPoint(dbgUser.data, i)
+      createBreakPoint(addr dbgUser.data, i)
     elif ?"breakpoints":
       listBreakPoints()
     elif ?"toggle":
-      breakpointToggle(dbgUser.data, i)
+      breakpointToggle(addr dbgUser.data, i)
     elif ?"filenames":
       listFilenames()
     elif ?"maxdisplay":
       var parsed: int
-      i = scanNumber(dbgUser.data, parsed, i)
+      i = scanNumber(addr dbgUser.data, parsed, i)
       if dbgUser.data[i-1] in {'0'..'9'}:
         if parsed == 0: maxDisplayRecDepth = -1
         else: maxDisplayRecDepth = parsed
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index db4d70613..f2b5997cc 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -306,8 +306,12 @@ proc raiseExceptionAux(e: ref Exception) =
         add(buf, " [")
         xadd(buf, e.name, e.name.len)
         add(buf, "]\n")
-        unhandled(buf):
-          showErrorMessage(buf)
+        when defined(nimNoArrayToCstringConversion):
+          template tbuf(): untyped = addr buf
+        else:
+          template tbuf(): untyped = buf
+        unhandled(tbuf()):
+          showErrorMessage(tbuf())
           quitOrDebug()
 
 proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index a2ff72a30..68bf5f6c2 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -155,14 +155,15 @@ template setColor(c, col) =
   else:
     c.refcount = c.refcount and not colorMask or col
 
-proc writeCell(msg: cstring, c: PCell) =
-  var kind = -1
-  var typName: cstring = "nil"
-  if c.typ != nil:
-    kind = ord(c.typ.kind)
-    when defined(nimTypeNames):
-      if not c.typ.name.isNil:
-        typName = c.typ.name
+when defined(logGC):
+  proc writeCell(msg: cstring, c: PCell) =
+    var kind = -1
+    var typName: cstring = "nil"
+    if c.typ != nil:
+      kind = ord(c.typ.kind)
+      when defined(nimTypeNames):
+        if not c.typ.name.isNil:
+          typName = c.typ.name
 
   when leakDetector:
     c_fprintf(stdout, "[GC] %s: %p %d %s rc=%ld from %s(%ld)\n",
@@ -642,9 +643,9 @@ when useMarkForDebug or useBackupGc:
         forAllChildren(d, waMarkPrecise)
 
   proc markGlobals(gch: var GcHeap) =
-    for i in 0 .. < globalMarkersLen: globalMarkers[i]()
+    for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
     let d = gch.additionalRoots.d
-    for i in 0 .. < gch.additionalRoots.len: markS(gch, d[i])
+    for i in 0 .. gch.additionalRoots.len-1: markS(gch, d[i])
 
 when logGC:
   var
@@ -652,7 +653,7 @@ when logGC:
     cycleCheckALen = 0
 
   proc alreadySeen(c: PCell): bool =
-    for i in 0 .. <cycleCheckALen:
+    for i in 0 .. cycleCheckALen-1:
       if cycleCheckA[i] == c: return true
     if cycleCheckALen == len(cycleCheckA):
       gcAssert(false, "cycle detection overflow")
diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim
index 6dffc323e..70bed8740 100644
--- a/lib/system/gc2.nim
+++ b/lib/system/gc2.nim
@@ -487,12 +487,12 @@ proc GC_dumpHeap*(file: File) =
   var spaceIter: ObjectSpaceIter
   when false:
     var d = gch.decStack.d
-    for i in 0 .. < gch.decStack.len:
+    for i in 0 .. gch.decStack.len-1:
       if isAllocatedPtr(gch.region, d[i]):
         c_fprintf(file, "onstack %p\n", d[i])
       else:
         c_fprintf(file, "onstack_invalid %p\n", d[i])
-  for i in 0 .. < globalMarkersLen: globalMarkers[i]()
+  for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
   while true:
     let x = allObjectsAsProc(gch.region, addr spaceIter)
     if spaceIter.state < 0: break
@@ -579,7 +579,7 @@ proc markIncremental(gch: var GcHeap): bool =
   result = true
 
 proc markGlobals(gch: var GcHeap) =
-  for i in 0 .. < globalMarkersLen: globalMarkers[i]()
+  for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
 
 proc doOperation(p: pointer, op: WalkOp) =
   if p == nil: return
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index cfc0dfa8a..272047bb7 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -450,9 +450,9 @@ when false:
           quit 1
 
 proc markGlobals(gch: var GcHeap) =
-  for i in 0 .. < globalMarkersLen: globalMarkers[i]()
+  for i in 0 .. globalMarkersLen-1: globalMarkers[i]()
   let d = gch.additionalRoots.d
-  for i in 0 .. < gch.additionalRoots.len: mark(gch, d[i])
+  for i in 0 .. gch.additionalRoots.len-1: mark(gch, d[i])
 
 proc gcMark(gch: var GcHeap, p: pointer) {.inline.} =
   # the addresses are not as cells on the stack, so turn them to cells:
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index f5b9cf3ed..f91dae41e 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -106,7 +106,7 @@ proc cmpic*(a, b: string): int =
   ## Compares `a` and `b` ignoring case.
   cmpIgnoreCase(a, b)
 
-proc getEnv*(key: string): string {.tags: [ReadIOEffect].} =
+proc getEnv*(key: string; default = ""): string {.tags: [ReadIOEffect].} =
   ## Retrieves the environment variable of name `key`.
   builtin
 
diff --git a/lib/system/repr.nim b/lib/system/repr.nim
index ab02c58a2..982b07467 100644
--- a/lib/system/repr.nim
+++ b/lib/system/repr.nim
@@ -16,34 +16,39 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
 proc reprFloat(x: float): string {.compilerproc.} = return $x
 
 proc reprPointer(x: pointer): string {.compilerproc.} =
-  var buf: array[0..59, char]
-  discard c_sprintf(buf, "%p", x)
-  return $buf
+  when defined(nimNoArrayToCstringConversion):
+    result = newString(60)
+    let n = c_sprintf(addr result[0], "%p", x)
+    setLen(result, n)
+  else:
+    var buf: array[0..59, char]
+    discard c_sprintf(buf, "%p", x)
+    return $buf
 
 proc `$`(x: uint64): string =
   if x == 0:
     result = "0"
   else:
-    var buf: array[60, char]
+    result = newString(60)
     var i = 0
     var n = x
     while n != 0:
       let nn = n div 10'u64
-      buf[i] = char(n - 10'u64 * nn + ord('0'))
+      result[i] = char(n - 10'u64 * nn + ord('0'))
       inc i
       n = nn
+    result.setLen i
 
     let half = i div 2
     # Reverse
-    for t in 0 .. < half: swap(buf[t], buf[i-t-1])
-    result = $buf
+    for t in 0 .. half-1: swap(result[t], result[i-t-1])
 
 proc reprStrAux(result: var string, s: cstring; len: int) =
   if cast[pointer](s) == nil:
     add result, "nil"
     return
   add result, reprPointer(cast[pointer](s)) & "\""
-  for i in 0.. <len:
+  for i in 0 .. pred(len):
     let c = s[i]
     case c
     of '"': add result, "\\\""
diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim
index 5c265a891..658220c11 100644
--- a/lib/system/reprjs.nim
+++ b/lib/system/reprjs.nim
@@ -9,13 +9,13 @@
 # The generic ``repr`` procedure for the javascript backend.
 
 proc reprInt(x: int64): string {.compilerproc.} = return $x
-proc reprFloat(x: float): string {.compilerproc.} = 
+proc reprFloat(x: float): string {.compilerproc.} =
   # Js toString doesn't differentiate between 1.0 and 1,
   # but we do.
   if $x == $(x.int): $x & ".0"
   else: $x
 
-proc reprPointer(p: pointer): string {.compilerproc.} = 
+proc reprPointer(p: pointer): string {.compilerproc.} =
   # Do we need to generate the full 8bytes ? In js a pointer is an int anyway
   var tmp: int
   {. emit: """
@@ -38,7 +38,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
     result = $typ.node.sons[e].name
   else:
     result = $e & " (invalid data!)"
-  
+
 proc reprChar(x: char): string {.compilerRtl.} =
   result = "\'"
   case x
@@ -50,7 +50,7 @@ proc reprChar(x: char): string {.compilerRtl.} =
 
 proc reprStrAux(result: var string, s: cstring, len: int) =
   add(result, "\"")
-  for i in 0 .. <len:
+  for i in 0 .. len-1:
     let c = s[i]
     case c
     of '"': add(result, "\\\"")
@@ -67,7 +67,7 @@ proc reprStr(s: string): string {.compilerRtl.} =
   if cast[pointer](s).isNil:
     # Handle nil strings here because they don't have a length field in js
     # TODO: check for null/undefined before generating call to length in js?
-    # Also: c backend repr of a nil string is <pointer>"", but repr of an 
+    # Also: c backend repr of a nil string is <pointer>"", but repr of an
     # array of string that is not initialized is [nil, nil, ...] ??
     add(result, "nil")
   else:
@@ -86,7 +86,7 @@ proc addSetElem(result: var string, elem: int, typ: PNimType) =
 
 iterator setKeys(s: int): int {.inline.} =
   # The type of s is a lie, but it's expected to be a set.
-  # Iterate over the JS object representing a set 
+  # Iterate over the JS object representing a set
   # and returns the keys as int.
   var len: int
   var yieldRes: int
@@ -124,16 +124,16 @@ proc initReprClosure(cl: var ReprClosure) =
   cl.recDepth = -1 # default is to display everything!
   cl.indent = 0
 
-proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) 
+proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure)
 
-proc reprArray(a: pointer, typ: PNimType, 
+proc reprArray(a: pointer, typ: PNimType,
               cl: var ReprClosure): string {.compilerRtl.} =
   var isNilArrayOrSeq: bool
   # isnil is not enough here as it would try to deref `a` without knowing what's inside
   {. emit: """
-    if (`a` == null) { 
+    if (`a` == null) {
       `isNilArrayOrSeq` = true;
-    } else if (`a`[0] == null) { 
+    } else if (`a`[0] == null) {
       `isNilArrayOrSeq` = true;
     } else {
       `isNilArrayOrSeq` = false;
@@ -146,19 +146,19 @@ proc reprArray(a: pointer, typ: PNimType,
   result = if typ.kind == tySequence: "@[" else: "["
   var len: int = 0
   var i: int = 0
-    
+
   {. emit: "`len` = `a`.length;\n" .}
   var dereffed: pointer = a
-  for i in 0 .. < len:
+  for i in 0 .. len-1:
     if i > 0 :
       add(result, ", ")
     # advance pointer and point to element at index
     {. emit: """
-    `dereffed`_Idx = `i`; 
+    `dereffed`_Idx = `i`;
     `dereffed` = `a`[`dereffed`_Idx];
     """ .}
     reprAux(result, dereffed, typ.base, cl)
-  
+
   add(result, "]")
 
 proc isPointedToNil(p: pointer): bool {.inline.}=
@@ -181,7 +181,7 @@ proc reprRef(result: var string, p: pointer, typ: PNimType,
 
 proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprClosure) =
   add(result, "[")
-  
+
   var first: bool = true
   var val: pointer = o
   if typ.node.len == 0:
@@ -192,7 +192,7 @@ proc reprRecordAux(result: var string, o: pointer, typ: PNimType, cl: var ReprCl
     reprAux(result, val, typ.node.typ, cl)
   else:
     # if the object has more than one field, sons is not nil and contains the fields.
-    for i in 0 .. <typ.node.len:
+    for i in 0 .. typ.node.len-1:
       if first: first = false
       else: add(result, ",\n")
 
@@ -214,11 +214,11 @@ proc reprJSONStringify(p: int): string {.compilerRtl.} =
   {. emit: "`tmp` = JSON.stringify(`p`);\n" .}
   result = $tmp
 
-proc reprAux(result: var string, p: pointer, typ: PNimType, 
+proc reprAux(result: var string, p: pointer, typ: PNimType,
             cl: var ReprClosure) =
   if cl.recDepth == 0:
     add(result, "...")
-    return 
+    return
   dec(cl.recDepth)
   case typ.kind
   of tyInt..tyInt64, tyUInt..tyUInt64:
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 7b6d93fe0..a40fcc67d 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -15,9 +15,12 @@
 {.push debugger:off .} # the user does not want to trace a part
                        # of the standard library!
 
-
-proc c_fdopen(filehandle: cint, mode: cstring): File {.
-  importc: "fdopen", header: "<stdio.h>".}
+when defined(windows):
+  proc c_fdopen(filehandle: cint, mode: cstring): File {.
+    importc: "_fdopen", header: "<stdio.h>".}
+else:
+  proc c_fdopen(filehandle: cint, mode: cstring): File {.
+    importc: "fdopen", header: "<stdio.h>".}
 proc c_fputs(c: cstring, f: File): cint {.
   importc: "fputs", header: "<stdio.h>", tags: [WriteIOEffect].}
 proc c_fgets(c: cstring, n: cint, f: File): cstring {.
@@ -401,4 +404,18 @@ proc setStdIoUnbuffered() =
   when declared(stdin):
     discard c_setvbuf(stdin, nil, IONBF, 0)
 
+when declared(stdout):
+  proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
+    when not defined(windows):
+      proc flockfile(f: File) {.importc, noDecl.}
+      proc funlockfile(f: File) {.importc, noDecl.}
+      flockfile(stdout)
+    for s in args:
+      discard c_fwrite(s.cstring, s.len, 1, stdout)
+    const linefeed = "\n" # can be 1 or more chars
+    discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
+    discard c_fflush(stdout)
+    when not defined(windows):
+      funlockfile(stdout)
+
 {.pop.}
diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim
index 7da45b4dd..a0d10c446 100644
--- a/lib/system/sysspawn.nim
+++ b/lib/system/sysspawn.nim
@@ -142,7 +142,7 @@ var
   workersData: array[NumThreads, Worker]
 
 proc setup() =
-  for i in 0.. <NumThreads:
+  for i in 0 ..< NumThreads:
     workersData[i].taskArrived = createCondVar()
     workersData[i].taskStarted = createFastCondVar()
     createThread(workers[i], slave, addr(workersData[i]))
diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim
index 90201202c..0627ef2fb 100644
--- a/lib/system/sysstr.nim
+++ b/lib/system/sysstr.nim
@@ -24,7 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
   if a == b: return 0
   if a == nil: return -1
   if b == nil: return 1
-  return c_strcmp(a.data, b.data)
+  when defined(nimNoArrayToCstringConversion):
+    return c_strcmp(addr a.data, addr b.data)
+  else:
+    return c_strcmp(a.data, b.data)
 
 proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
   if a == b: return true
@@ -275,7 +278,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
                             GenericSeqSize +% (i*%elemSize)),
                             extGetCellType(result).base, waPush)
           let len1 = gch.tempStack.len
-          for i in len0 .. <len1:
+          for i in len0 ..< len1:
             doDecRef(gch.tempStack.d[i], LocalHeap, MaybeCyclic)
           gch.tempStack.len = len0
       else:
@@ -320,7 +323,10 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
 
 proc add*(result: var string; x: float) =
   var buf: array[0..64, char]
-  var n: int = c_sprintf(buf, "%.16g", x)
+  when defined(nimNoArrayToCstringConversion):
+    var n: int = c_sprintf(addr buf, "%.16g", x)
+  else:
+    var n: int = c_sprintf(buf, "%.16g", x)
   var hasDot = false
   for i in 0..n-1:
     if buf[i] == ',':
@@ -332,9 +338,10 @@ proc add*(result: var string; x: float) =
     buf[n] = '.'
     buf[n+1] = '0'
     buf[n+2] = '\0'
-  # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN' are produced.
+  # On Windows nice numbers like '1.#INF', '-1.#INF' or '1.#NAN'
+  # of '-1.#IND' are produced.
   # We want to get rid of these here:
-  if buf[n-1] in {'n', 'N'}:
+  if buf[n-1] in {'n', 'N', 'D', 'd'}:
     result.add "nan"
   elif buf[n-1] == 'F':
     if buf[0] == '-':
@@ -342,7 +349,10 @@ proc add*(result: var string; x: float) =
     else:
       result.add "inf"
   else:
-    result.add buf
+    var i = 0
+    while buf[i] != '\0':
+      result.add buf[i]
+      inc i
 
 proc nimFloatToStr(f: float): string {.compilerproc.} =
   result = newStringOfCap(8)
@@ -353,9 +363,9 @@ proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {.
 
 const
   IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
-  powtens =   [ 1e0,   1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,
-                1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
-                1e20, 1e21, 1e22]
+  powtens =  [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+              1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+              1e20, 1e21, 1e22]
 
 proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
                           start = 0): int {.compilerProc.} =
@@ -507,7 +517,10 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
   t[ti-2] = ('0'.ord + abs_exponent mod 10).char; abs_exponent = abs_exponent div 10
   t[ti-3] = ('0'.ord + abs_exponent mod 10).char
 
-  number = c_strtod(t, nil)
+  when defined(nimNoArrayToCstringConversion):
+    number = c_strtod(addr t, nil)
+  else:
+    number = c_strtod(t, nil)
 
 proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
   result = newStringOfCap(sizeof(x)*4)
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 96c045e6b..016bf5822 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -398,7 +398,7 @@ template afterThreadRuns() =
     threadDestructionHandlers[i]()
 
 when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions):
-  proc deallocOsPages()
+  proc deallocOsPages() {.rtl.}
 
 when defined(boehmgc):
   type GCStackBaseProc = proc(sb: pointer, t: pointer) {.noconv.}
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 7a221ceb1..c3229cc7b 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -14,8 +14,8 @@
 
 import dynlib
 
-when defined(vcc):
-  {.passC: "-DWIN32_LEAN_AND_MEAN".}
+
+{.passC: "-DWIN32_LEAN_AND_MEAN".}
 
 const
   useWinUnicode* = not defined(useWinAnsi)
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index 40b54b08d..431ea5912 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -590,13 +590,13 @@ proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.importc: "MD5_Transform".}
 
 from strutils import toHex, toLowerAscii
 
-proc hexStr (buf:cstring): string =
+proc hexStr(buf: cstring): string =
   # turn md5s output into a nice hex str
   result = newStringOfCap(32)
-  for i in 0 .. <16:
+  for i in 0 ..< 16:
     result.add toHex(buf[i].ord, 2).toLowerAscii
 
-proc md5_File* (file: string): string {.raises: [IOError,Exception].} =
+proc md5_File*(file: string): string {.raises: [IOError,Exception].} =
   ## Generate MD5 hash for a file. Result is a 32 character
   # hex string with lowercase characters (like the output
   # of `md5sum`
@@ -611,14 +611,14 @@ proc md5_File* (file: string): string {.raises: [IOError,Exception].} =
   while(let bytes = f.readChars(buf, 0, sz); bytes > 0):
     discard md5_update(ctx, buf[0].addr, bytes)
 
-  discard md5_final( buf[0].addr, ctx )
+  discard md5_final(buf[0].addr, ctx)
   f.close
 
-  result = hexStr(buf)
+  result = hexStr(addr buf)
 
-proc md5_Str*(str:string): string =
-  ##Generate MD5 hash for a string. Result is a 32 character
-  #hex string with lowercase characters
+proc md5_Str*(str: string): string =
+  ## Generate MD5 hash for a string. Result is a 32 character
+  ## hex string with lowercase characters
   var
     ctx: MD5_CTX
     res: array[MD5_DIGEST_LENGTH,char]
@@ -631,5 +631,5 @@ proc md5_Str*(str:string): string =
     discard md5_update(ctx, input[i].addr, L)
     i += L
 
-  discard md5_final(res,ctx)
-  result = hexStr(res)
+  discard md5_final(addr res, ctx)
+  result = hexStr(addr res)
diff --git a/lib/wrappers/pdcurses.nim b/lib/wrappers/pdcurses.nim
deleted file mode 100644
index 2d64ac97a..000000000
--- a/lib/wrappers/pdcurses.nim
+++ /dev/null
@@ -1,1560 +0,0 @@
-#
-#
-#            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.}
-
-discard """
-
-curses.h:
-#ifdef C2NIM
-#dynlib pdcursesdll
-#skipinclude
-#prefix PDC_
-#def FALSE
-#def TRUE
-#def NULL
-#def bool unsigned char
-#def chtype unsigned long
-#def cchar_t unsigned long
-#def attr_t unsigned long
-#def mmask_t unsigned long
-#def wchar_t char
-#def PDCEX
-#cdecl
-#endif
-
-pdcwin.h:
-#ifdef C2NIM
-#dynlib pdcursesdll
-#skipinclude
-#prefix pdc_
-#prefix PDC_
-#stdcall
-#endif
-"""
-
-when defined(windows):
-  import windows
-
-  when defined(nimOldDlls):
-    const pdcursesdll = "pdcurses.dll"
-  elif defined(cpu64):
-    const pdcursesdll = "pdcurses64.dll"
-  else:
-    const pdcursesdll = "pdcurses32.dll"
-
-  const
-    unixOS = false
-  {.pragma: extdecl, stdcall.}
-
-when not defined(windows):
-  const
-    unixOS = true
-  {.pragma: extdecl, cdecl.}
-
-type
-  cunsignedchar = char
-  cunsignedlong = uint32
-
-const
-  BUILD* = 3401
-  PDCURSES* = 1               # PDCurses-only routines
-  XOPEN* = 1                  # X/Open Curses routines
-  SYSVcurses* = 1             # System V Curses routines
-  BSDcurses* = 1              # BSD Curses routines
-  CHTYPE_LONG* = 1            # size of chtype; long
-  ERR* = (- 1)
-  OK* = 0
-  BUTTON_RELEASED* = 0x00000000
-  BUTTON_PRESSED* = 0x00000001
-  BUTTON_CLICKED* = 0x00000002
-  BUTTON_DOUBLE_CLICKED* = 0x00000003
-  BUTTON_TRIPLE_CLICKED* = 0x00000004
-  BUTTON_MOVED* = 0x00000005  # PDCurses
-  WHEEL_SCROLLED* = 0x00000006 # PDCurses
-  BUTTON_ACTION_MASK* = 0x00000007 # PDCurses
-  BUTTON_MODIFIER_MASK* = 0x00000038 # PDCurses
-  MOUSE_MOVED* = 0x00000008
-  MOUSE_POSITION* = 0x00000010
-  MOUSE_WHEEL_UP* = 0x00000020
-  MOUSE_WHEEL_DOWN* = 0x00000040
-  BUTTON1_RELEASED* = 0x00000001
-  BUTTON1_PRESSED* = 0x00000002
-  BUTTON1_CLICKED* = 0x00000004
-  BUTTON1_DOUBLE_CLICKED* = 0x00000008
-  BUTTON1_TRIPLE_CLICKED* = 0x00000010
-  BUTTON1_MOVED* = 0x00000010 # PDCurses
-  BUTTON2_RELEASED* = 0x00000020
-  BUTTON2_PRESSED* = 0x00000040
-  BUTTON2_CLICKED* = 0x00000080
-  BUTTON2_DOUBLE_CLICKED* = 0x00000100
-  BUTTON2_TRIPLE_CLICKED* = 0x00000200
-  BUTTON2_MOVED* = 0x00000200 # PDCurses
-  BUTTON3_RELEASED* = 0x00000400
-  BUTTON3_PRESSED* = 0x00000800
-  BUTTON3_CLICKED* = 0x00001000
-  BUTTON3_DOUBLE_CLICKED* = 0x00002000
-  BUTTON3_TRIPLE_CLICKED* = 0x00004000
-  BUTTON3_MOVED* = 0x00004000 # PDCurses
-  BUTTON4_RELEASED* = 0x00008000
-  BUTTON4_PRESSED* = 0x00010000
-  BUTTON4_CLICKED* = 0x00020000
-  BUTTON4_DOUBLE_CLICKED* = 0x00040000
-  BUTTON4_TRIPLE_CLICKED* = 0x00080000
-  BUTTON5_RELEASED* = 0x00100000
-  BUTTON5_PRESSED* = 0x00200000
-  BUTTON5_CLICKED* = 0x00400000
-  BUTTON5_DOUBLE_CLICKED* = 0x00800000
-  BUTTON5_TRIPLE_CLICKED* = 0x01000000
-  MOUSE_WHEEL_SCROLL* = 0x02000000 # PDCurses
-  BUTTON_MODIFIER_SHIFT* = 0x04000000 # PDCurses
-  BUTTON_MODIFIER_CONTROL* = 0x08000000 # PDCurses
-  BUTTON_MODIFIER_ALT* = 0x10000000 # PDCurses
-  ALL_MOUSE_EVENTS* = 0x1FFFFFFF
-  REPORT_MOUSE_POSITION* = 0x20000000
-  A_NORMAL* = 0
-  A_ALTCHARSET* = 0x00010000
-  A_RIGHTLINE* = 0x00020000
-  A_LEFTLINE* = 0x00040000
-  A_INVIS* = 0x00080000
-  A_UNDERLINE* = 0x00100000
-  A_REVERSE* = 0x00200000
-  A_BLINK* = 0x00400000
-  A_BOLD* = 0x00800000
-  A_ATTRIBUTES* = 0xFFFF0000
-  A_CHARTEXT* = 0x0000FFFF
-  A_COLOR* = 0xFF000000
-  A_ITALIC* = A_INVIS
-  A_PROTECT* = (A_UNDERLINE or A_LEFTLINE or A_RIGHTLINE)
-  ATTR_SHIFT* = 19
-  COLOR_SHIFT* = 24
-  A_STANDOUT* = (A_REVERSE or A_BOLD) # X/Open
-  A_DIM* = A_NORMAL
-  CHR_MSK* = A_CHARTEXT       # Obsolete
-  ATR_MSK* = A_ATTRIBUTES     # Obsolete
-  ATR_NRM* = A_NORMAL         # Obsolete
-  WA_ALTCHARSET* = A_ALTCHARSET
-  WA_BLINK* = A_BLINK
-  WA_BOLD* = A_BOLD
-  WA_DIM* = A_DIM
-  WA_INVIS* = A_INVIS
-  WA_LEFT* = A_LEFTLINE
-  WA_PROTECT* = A_PROTECT
-  WA_REVERSE* = A_REVERSE
-  WA_RIGHT* = A_RIGHTLINE
-  WA_STANDOUT* = A_STANDOUT
-  WA_UNDERLINE* = A_UNDERLINE
-  WA_HORIZONTAL* = A_NORMAL
-  WA_LOW* = A_NORMAL
-  WA_TOP* = A_NORMAL
-  WA_VERTICAL* = A_NORMAL
-  COLOR_BLACK* = 0
-  COLOR_RED* = 1
-  COLOR_GREEN* = 2
-  COLOR_BLUE* = 4
-  COLOR_CYAN* = (COLOR_BLUE or COLOR_GREEN)
-  COLOR_MAGENTA* = (COLOR_RED or COLOR_BLUE)
-  COLOR_YELLOW* = (COLOR_RED or COLOR_GREEN)
-  COLOR_WHITE* = 7
-  KEY_CODE_YES* = 0x00000100  # If get_wch() gives a key code
-  KEY_BREAK* = 0x00000101     # Not on PC KBD
-  KEY_DOWN* = 0x00000102      # Down arrow key
-  KEY_UP* = 0x00000103        # Up arrow key
-  KEY_LEFT* = 0x00000104      # Left arrow key
-  KEY_RIGHT* = 0x00000105     # Right arrow key
-  KEY_HOME* = 0x00000106      # home key
-  KEY_BACKSPACE* = 0x00000107 # not on pc
-  KEY_F0* = 0x00000108        # function keys; 64 reserved
-  KEY_DL* = 0x00000148        # delete line
-  KEY_IL* = 0x00000149        # insert line
-  KEY_DC* = 0x0000014A        # delete character
-  KEY_IC* = 0x0000014B        # insert char or enter ins mode
-  KEY_EIC* = 0x0000014C       # exit insert char mode
-  KEY_CLEAR* = 0x0000014D     # clear screen
-  KEY_EOS* = 0x0000014E       # clear to end of screen
-  KEY_EOL* = 0x0000014F       # clear to end of line
-  KEY_SF* = 0x00000150        # scroll 1 line forward
-  KEY_SR* = 0x00000151        # scroll 1 line back (reverse)
-  KEY_NPAGE* = 0x00000152     # next page
-  KEY_PPAGE* = 0x00000153     # previous page
-  KEY_STAB* = 0x00000154      # set tab
-  KEY_CTAB* = 0x00000155      # clear tab
-  KEY_CATAB* = 0x00000156     # clear all tabs
-  KEY_ENTER* = 0x00000157     # enter or send (unreliable)
-  KEY_SRESET* = 0x00000158    # soft/reset (partial/unreliable)
-  KEY_RESET* = 0x00000159     # reset/hard reset (unreliable)
-  KEY_PRINT* = 0x0000015A     # print/copy
-  KEY_LL* = 0x0000015B        # home down/bottom (lower left)
-  KEY_ABORT* = 0x0000015C     # abort/terminate key (any)
-  KEY_SHELP* = 0x0000015D     # short help
-  KEY_LHELP* = 0x0000015E     # long help
-  KEY_BTAB* = 0x0000015F      # Back tab key
-  KEY_BEG* = 0x00000160       # beg(inning) key
-  KEY_CANCEL* = 0x00000161    # cancel key
-  KEY_CLOSE* = 0x00000162     # close key
-  KEY_COMMAND* = 0x00000163   # cmd (command) key
-  KEY_COPY* = 0x00000164      # copy key
-  KEY_CREATE* = 0x00000165    # create key
-  KEY_END* = 0x00000166       # end key
-  KEY_EXIT* = 0x00000167      # exit key
-  KEY_FIND* = 0x00000168      # find key
-  KEY_HELP* = 0x00000169      # help key
-  KEY_MARK* = 0x0000016A      # mark key
-  KEY_MESSAGE* = 0x0000016B   # message key
-  KEY_MOVE* = 0x0000016C      # move key
-  KEY_NEXT* = 0x0000016D      # next object key
-  KEY_OPEN* = 0x0000016E      # open key
-  KEY_OPTIONS* = 0x0000016F   # options key
-  KEY_PREVIOUS* = 0x00000170  # previous object key
-  KEY_REDO* = 0x00000171      # redo key
-  KEY_REFERENCE* = 0x00000172 # ref(erence) key
-  KEY_REFRESH* = 0x00000173   # refresh key
-  KEY_REPLACE* = 0x00000174   # replace key
-  KEY_RESTART* = 0x00000175   # restart key
-  KEY_RESUME* = 0x00000176    # resume key
-  KEY_SAVE* = 0x00000177      # save key
-  KEY_SBEG* = 0x00000178      # shifted beginning key
-  KEY_SCANCEL* = 0x00000179   # shifted cancel key
-  KEY_SCOMMAND* = 0x0000017A  # shifted command key
-  KEY_SCOPY* = 0x0000017B     # shifted copy key
-  KEY_SCREATE* = 0x0000017C   # shifted create key
-  KEY_SDC* = 0x0000017D       # shifted delete char key
-  KEY_SDL* = 0x0000017E       # shifted delete line key
-  KEY_SELECT* = 0x0000017F    # select key
-  KEY_SEND* = 0x00000180      # shifted end key
-  KEY_SEOL* = 0x00000181      # shifted clear line key
-  KEY_SEXIT* = 0x00000182     # shifted exit key
-  KEY_SFIND* = 0x00000183     # shifted find key
-  KEY_SHOME* = 0x00000184     # shifted home key
-  KEY_SIC* = 0x00000185       # shifted input key
-  KEY_SLEFT* = 0x00000187     # shifted left arrow key
-  KEY_SMESSAGE* = 0x00000188  # shifted message key
-  KEY_SMOVE* = 0x00000189     # shifted move key
-  KEY_SNEXT* = 0x0000018A     # shifted next key
-  KEY_SOPTIONS* = 0x0000018B  # shifted options key
-  KEY_SPREVIOUS* = 0x0000018C # shifted prev key
-  KEY_SPRINT* = 0x0000018D    # shifted print key
-  KEY_SREDO* = 0x0000018E     # shifted redo key
-  KEY_SREPLACE* = 0x0000018F  # shifted replace key
-  KEY_SRIGHT* = 0x00000190    # shifted right arrow
-  KEY_SRSUME* = 0x00000191    # shifted resume key
-  KEY_SSAVE* = 0x00000192     # shifted save key
-  KEY_SSUSPEND* = 0x00000193  # shifted suspend key
-  KEY_SUNDO* = 0x00000194     # shifted undo key
-  KEY_SUSPEND* = 0x00000195   # suspend key
-  KEY_UNDO* = 0x00000196      # undo key
-  ALT_0* = 0x00000197
-  ALT_1* = 0x00000198
-  ALT_2* = 0x00000199
-  ALT_3* = 0x0000019A
-  ALT_4* = 0x0000019B
-  ALT_5* = 0x0000019C
-  ALT_6* = 0x0000019D
-  ALT_7* = 0x0000019E
-  ALT_8* = 0x0000019F
-  ALT_9* = 0x000001A0
-  ALT_A* = 0x000001A1
-  ALT_B* = 0x000001A2
-  ALT_C* = 0x000001A3
-  ALT_D* = 0x000001A4
-  ALT_E* = 0x000001A5
-  ALT_F* = 0x000001A6
-  ALT_G* = 0x000001A7
-  ALT_H* = 0x000001A8
-  ALT_I* = 0x000001A9
-  ALT_J* = 0x000001AA
-  ALT_K* = 0x000001AB
-  ALT_L* = 0x000001AC
-  ALT_M* = 0x000001AD
-  ALT_N* = 0x000001AE
-  ALT_O* = 0x000001AF
-  ALT_P* = 0x000001B0
-  ALT_Q* = 0x000001B1
-  ALT_R* = 0x000001B2
-  ALT_S* = 0x000001B3
-  ALT_T* = 0x000001B4
-  ALT_U* = 0x000001B5
-  ALT_V* = 0x000001B6
-  ALT_W* = 0x000001B7
-  ALT_X* = 0x000001B8
-  ALT_Y* = 0x000001B9
-  ALT_Z* = 0x000001BA
-  CTL_LEFT* = 0x000001BB      # Control-Left-Arrow
-  CTL_RIGHT* = 0x000001BC
-  CTL_PGUP* = 0x000001BD
-  CTL_PGDN* = 0x000001BE
-  CTL_HOME* = 0x000001BF
-  CTL_END* = 0x000001C0
-  KEY_A1* = 0x000001C1        # upper left on Virtual keypad
-  KEY_A2* = 0x000001C2        # upper middle on Virt. keypad
-  KEY_A3* = 0x000001C3        # upper right on Vir. keypad
-  KEY_B1* = 0x000001C4        # middle left on Virt. keypad
-  KEY_B2* = 0x000001C5        # center on Virt. keypad
-  KEY_B3* = 0x000001C6        # middle right on Vir. keypad
-  KEY_C1* = 0x000001C7        # lower left on Virt. keypad
-  KEY_C2* = 0x000001C8        # lower middle on Virt. keypad
-  KEY_C3* = 0x000001C9        # lower right on Vir. keypad
-  PADSLASH* = 0x000001CA      # slash on keypad
-  PADENTER* = 0x000001CB      # enter on keypad
-  CTL_PADENTER* = 0x000001CC  # ctl-enter on keypad
-  ALT_PADENTER* = 0x000001CD  # alt-enter on keypad
-  PADSTOP* = 0x000001CE       # stop on keypad
-  PADSTAR* = 0x000001CF       # star on keypad
-  PADMINUS* = 0x000001D0      # minus on keypad
-  PADPLUS* = 0x000001D1       # plus on keypad
-  CTL_PADSTOP* = 0x000001D2   # ctl-stop on keypad
-  CTL_PADCENTER* = 0x000001D3 # ctl-enter on keypad
-  CTL_PADPLUS* = 0x000001D4   # ctl-plus on keypad
-  CTL_PADMINUS* = 0x000001D5  # ctl-minus on keypad
-  CTL_PADSLASH* = 0x000001D6  # ctl-slash on keypad
-  CTL_PADSTAR* = 0x000001D7   # ctl-star on keypad
-  ALT_PADPLUS* = 0x000001D8   # alt-plus on keypad
-  ALT_PADMINUS* = 0x000001D9  # alt-minus on keypad
-  ALT_PADSLASH* = 0x000001DA  # alt-slash on keypad
-  ALT_PADSTAR* = 0x000001DB   # alt-star on keypad
-  ALT_PADSTOP* = 0x000001DC   # alt-stop on keypad
-  CTL_INS* = 0x000001DD       # ctl-insert
-  ALT_DEL* = 0x000001DE       # alt-delete
-  ALT_INS* = 0x000001DF       # alt-insert
-  CTL_UP* = 0x000001E0        # ctl-up arrow
-  CTL_DOWN* = 0x000001E1      # ctl-down arrow
-  CTL_TAB* = 0x000001E2       # ctl-tab
-  ALT_TAB* = 0x000001E3
-  ALT_MINUS* = 0x000001E4
-  ALT_EQUAL* = 0x000001E5
-  ALT_HOME* = 0x000001E6
-  ALT_PGUP* = 0x000001E7
-  ALT_PGDN* = 0x000001E8
-  ALT_END* = 0x000001E9
-  ALT_UP* = 0x000001EA        # alt-up arrow
-  ALT_DOWN* = 0x000001EB      # alt-down arrow
-  ALT_RIGHT* = 0x000001EC     # alt-right arrow
-  ALT_LEFT* = 0x000001ED      # alt-left arrow
-  ALT_ENTER* = 0x000001EE     # alt-enter
-  ALT_ESC* = 0x000001EF       # alt-escape
-  ALT_BQUOTE* = 0x000001F0    # alt-back quote
-  ALT_LBRACKET* = 0x000001F1  # alt-left bracket
-  ALT_RBRACKET* = 0x000001F2  # alt-right bracket
-  ALT_SEMICOLON* = 0x000001F3 # alt-semi-colon
-  ALT_FQUOTE* = 0x000001F4    # alt-forward quote
-  ALT_COMMA* = 0x000001F5     # alt-comma
-  ALT_STOP* = 0x000001F6      # alt-stop
-  ALT_FSLASH* = 0x000001F7    # alt-forward slash
-  ALT_BKSP* = 0x000001F8      # alt-backspace
-  CTL_BKSP* = 0x000001F9      # ctl-backspace
-  PAD0* = 0x000001FA          # keypad 0
-  CTL_PAD0* = 0x000001FB      # ctl-keypad 0
-  CTL_PAD1* = 0x000001FC
-  CTL_PAD2* = 0x000001FD
-  CTL_PAD3* = 0x000001FE
-  CTL_PAD4* = 0x000001FF
-  CTL_PAD5* = 0x00000200
-  CTL_PAD6* = 0x00000201
-  CTL_PAD7* = 0x00000202
-  CTL_PAD8* = 0x00000203
-  CTL_PAD9* = 0x00000204
-  ALT_PAD0* = 0x00000205      # alt-keypad 0
-  ALT_PAD1* = 0x00000206
-  ALT_PAD2* = 0x00000207
-  ALT_PAD3* = 0x00000208
-  ALT_PAD4* = 0x00000209
-  ALT_PAD5* = 0x0000020A
-  ALT_PAD6* = 0x0000020B
-  ALT_PAD7* = 0x0000020C
-  ALT_PAD8* = 0x0000020D
-  ALT_PAD9* = 0x0000020E
-  CTL_DEL* = 0x0000020F       # clt-delete
-  ALT_BSLASH* = 0x00000210    # alt-back slash
-  CTL_ENTER* = 0x00000211     # ctl-enter
-  SHF_PADENTER* = 0x00000212  # shift-enter on keypad
-  SHF_PADSLASH* = 0x00000213  # shift-slash on keypad
-  SHF_PADSTAR* = 0x00000214   # shift-star  on keypad
-  SHF_PADPLUS* = 0x00000215   # shift-plus  on keypad
-  SHF_PADMINUS* = 0x00000216  # shift-minus on keypad
-  SHF_UP* = 0x00000217        # shift-up on keypad
-  SHF_DOWN* = 0x00000218      # shift-down on keypad
-  SHF_IC* = 0x00000219        # shift-insert on keypad
-  SHF_DC* = 0x0000021A        # shift-delete on keypad
-  KEY_MOUSE* = 0x0000021B     # "mouse" key
-  KEY_SHIFT_L* = 0x0000021C   # Left-shift
-  KEY_SHIFT_R* = 0x0000021D   # Right-shift
-  KEY_CONTROL_L* = 0x0000021E # Left-control
-  KEY_CONTROL_R* = 0x0000021F # Right-control
-  KEY_ALT_L* = 0x00000220     # Left-alt
-  KEY_ALT_R* = 0x00000221     # Right-alt
-  KEY_RESIZE* = 0x00000222    # Window resize
-  KEY_SUP* = 0x00000223       # Shifted up arrow
-  KEY_SDOWN* = 0x00000224     # Shifted down arrow
-  KEY_MIN* = KEY_BREAK        # Minimum curses key value
-  KEY_MAX* = KEY_SDOWN        # Maximum curses key
-  CLIP_SUCCESS* = 0
-  CLIP_ACCESS_ERROR* = 1
-  CLIP_EMPTY* = 2
-  CLIP_MEMORY_ERROR* = 3
-  KEY_MODIFIER_SHIFT* = 1
-  KEY_MODIFIER_CONTROL* = 2
-  KEY_MODIFIER_ALT* = 4
-  KEY_MODIFIER_NUMLOCK* = 8
-
-when appType == "gui":
-  const
-    BUTTON_SHIFT* = BUTTON_MODIFIER_SHIFT
-    BUTTON_CONTROL* = BUTTON_MODIFIER_CONTROL
-    BUTTON_CTRL* = BUTTON_MODIFIER_CONTROL
-    BUTTON_ALT* = BUTTON_MODIFIER_ALT
-else:
-  const
-    BUTTON_SHIFT* = 0x00000008
-    BUTTON_CONTROL* = 0x00000010
-    BUTTON_ALT* = 0x00000020
-
-type
-  TMOUSE_STATUS*{.pure, final.} = object
-    x*: cint                  # absolute column, 0 based, measured in characters
-    y*: cint                  # absolute row, 0 based, measured in characters
-    button*: array[0..3 - 1, cshort] # state of each button
-    changes*: cint            # flags indicating what has changed with the mouse
-
-  MEVENT*{.pure, final.} = object
-    id*: cshort               # unused, always 0
-    x*: cint
-    y*: cint
-    z*: cint                  # x, y same as TMOUSE_STATUS; z unused
-    bstate*: cunsignedlong    # equivalent to changes + button[], but
-                              # in the same format as used for mousemask()
-
-  WINDOW*{.pure, final.} = object
-    cury*: cint              # current pseudo-cursor
-    curx*: cint
-    maxy*: cint              # max window coordinates
-    maxx*: cint
-    begy*: cint              # origin on screen
-    begx*: cint
-    flags*: cint             # window properties
-    attrs*: cunsignedlong    # standard attributes and colors
-    bkgd*: cunsignedlong     # background, normally blank
-    clear*: cunsignedchar    # causes clear at next refresh
-    leaveit*: cunsignedchar  # leaves cursor where it is
-    scroll*: cunsignedchar   # allows window scrolling
-    nodelay*: cunsignedchar  # input character wait flag
-    immed*: cunsignedchar    # immediate update flag
-    sync*: cunsignedchar     # synchronise window ancestors
-    use_keypad*: cunsignedchar # flags keypad key mode active
-    y*: ptr ptr cunsignedlong # pointer to line pointer array
-    firstch*: ptr cint       # first changed character in line
-    lastch*: ptr cint        # last changed character in line
-    tmarg*: cint             # top of scrolling region
-    bmarg*: cint             # bottom of scrolling region
-    delayms*: cint           # milliseconds of delay for getch()
-    parx*: cint
-    pary*: cint              # coords relative to parent (0,0)
-    parent*: ptr WINDOW        # subwin's pointer to parent win
-
-  PANELOBS*{.pure, final.} = object
-    above*: ptr PANELOBS
-    pan*: ptr PANEL
-
-  PANEL*{.pure, final.} = object
-    win*: ptr WINDOW
-    wstarty*: cint
-    wendy*: cint
-    wstartx*: cint
-    wendx*: cint
-    below*: ptr PANEL
-    above*: ptr PANEL
-    user*: pointer
-    obscure*: ptr PANELOBS
-{.deprecated: [
-              #TMOUSE_STATUS: MOUSE_STATUS, # Name conflict when we drop the `T`
-              TMEVENT: MEVENT, TWINDOW: WINDOW,
-              TPANELOBS: PANELOBS, TPANEL:PANEL].}
-
-when unixOS:
-  type
-    SCREEN*{.pure, final.} = object
-      alive*: cunsignedchar     # if initscr() called, and not endwin()
-      autocr*: cunsignedchar    # if cr -> lf
-      cbreak*: cunsignedchar    # if terminal unbuffered
-      echo*: cunsignedchar      # if terminal echo
-      raw_inp*: cunsignedchar   # raw input mode (v. cooked input)
-      raw_out*: cunsignedchar   # raw output mode (7 v. 8 bits)
-      audible*: cunsignedchar   # FALSE if the bell is visual
-      mono*: cunsignedchar      # TRUE if current screen is mono
-      resized*: cunsignedchar   # TRUE if TERM has been resized
-      orig_attr*: cunsignedchar # TRUE if we have the original colors
-      orig_fore*: cshort        # original screen foreground color
-      orig_back*: cshort        # original screen foreground color
-      cursrow*: cint            # position of physical cursor
-      curscol*: cint            # position of physical cursor
-      visibility*: cint         # visibility of cursor
-      orig_cursor*: cint        # original cursor size
-      lines*: cint              # new value for LINES
-      cols*: cint               # new value for COLS
-      trap_mbe*: cunsignedlong # trap these mouse button events
-      map_mbe_to_key*: cunsignedlong # map mouse buttons to slk
-      mouse_wait*: cint # time to wait (in ms) for a button release after a press
-      slklines*: cint           # lines in use by slk_init()
-      slk_winptr*: ptr WINDOW   # window for slk
-      linesrippedoff*: cint     # lines ripped off via ripoffline()
-      linesrippedoffontop*: cint # lines ripped off on top via ripoffline()
-      delaytenths*: cint        # 1/10ths second to wait block getch() for
-      preserve*: cunsignedchar # TRUE if screen background to be preserved
-      restore*: cint           # specifies if screen background to be restored, and how
-      save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press
-      return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys
-      key_code*: cunsignedchar # TRUE if last key is a special key;
-      XcurscrSize*: cint        # size of Xcurscr shared memory block
-      sb_on*: cunsignedchar
-      sb_viewport_y*: cint
-      sb_viewport_x*: cint
-      sb_total_y*: cint
-      sb_total_x*: cint
-      sb_cur_y*: cint
-      sb_cur_x*: cint
-      line_color*: cshort       # color of line attributes - default -1
-  {.deprecated: [TSCREEN: SCREEN].}
-else:
-  type
-    SCREEN*{.pure, final.} = object
-      alive*: cunsignedchar     # if initscr() called, and not endwin()
-      autocr*: cunsignedchar    # if cr -> lf
-      cbreak*: cunsignedchar    # if terminal unbuffered
-      echo*: cunsignedchar      # if terminal echo
-      raw_inp*: cunsignedchar   # raw input mode (v. cooked input)
-      raw_out*: cunsignedchar   # raw output mode (7 v. 8 bits)
-      audible*: cunsignedchar   # FALSE if the bell is visual
-      mono*: cunsignedchar      # TRUE if current screen is mono
-      resized*: cunsignedchar   # TRUE if TERM has been resized
-      orig_attr*: cunsignedchar # TRUE if we have the original colors
-      orig_fore*: cshort        # original screen foreground color
-      orig_back*: cshort        # original screen foreground color
-      cursrow*: cint            # position of physical cursor
-      curscol*: cint            # position of physical cursor
-      visibility*: cint         # visibility of cursor
-      orig_cursor*: cint        # original cursor size
-      lines*: cint              # new value for LINES
-      cols*: cint               # new value for COLS
-      trap_mbe*: cunsignedlong # trap these mouse button events
-      map_mbe_to_key*: cunsignedlong # map mouse buttons to slk
-      mouse_wait*: cint # time to wait (in ms) for a button release after a press
-      slklines*: cint           # lines in use by slk_init()
-      slk_winptr*: ptr WINDOW   # window for slk
-      linesrippedoff*: cint     # lines ripped off via ripoffline()
-      linesrippedoffontop*: cint # lines ripped off on top via ripoffline()
-      delaytenths*: cint        # 1/10ths second to wait block getch() for
-      preserve*: cunsignedchar # TRUE if screen background to be preserved
-      restore*: cint           # specifies if screen background to be restored, and how
-      save_key_modifiers*: cunsignedchar # TRUE if each key modifiers saved with each key press
-      return_key_modifiers*: cunsignedchar # TRUE if modifier keys are returned as "real" keys
-      key_code*: cunsignedchar # TRUE if last key is a special key;
-      line_color*: cshort       # color of line attributes - default -1
-  {.deprecated: [TSCREEN: SCREEN].}
-
-var
-  LINES*{.importc: "LINES", dynlib: pdcursesdll.}: cint
-  COLS*{.importc: "COLS", dynlib: pdcursesdll.}: cint
-  stdscr*{.importc: "stdscr", dynlib: pdcursesdll.}: ptr WINDOW
-  curscr*{.importc: "curscr", dynlib: pdcursesdll.}: ptr WINDOW
-  SP*{.importc: "SP", dynlib: pdcursesdll.}: ptr SCREEN
-  Mouse_status*{.importc: "Mouse_status", dynlib: pdcursesdll.}: MOUSE_STATUS
-  COLORS*{.importc: "COLORS", dynlib: pdcursesdll.}: cint
-  COLOR_PAIRS*{.importc: "COLOR_PAIRS", dynlib: pdcursesdll.}: cint
-  TABSIZE*{.importc: "TABSIZE", dynlib: pdcursesdll.}: cint
-  acs_map*{.importc: "acs_map", dynlib: pdcursesdll.}: ptr cunsignedlong
-  ttytype*{.importc: "ttytype", dynlib: pdcursesdll.}: cstring
-
-template BUTTON_CHANGED*(x: expr): expr =
-  (Mouse_status.changes and (1 shl ((x) - 1)))
-
-template BUTTON_STATUS*(x: expr): expr =
-  (Mouse_status.button[(x) - 1])
-
-template ACS_PICK*(w, n: expr): expr = int32(w) or A_ALTCHARSET
-
-template KEY_F*(n: expr): expr = KEY_F0 + n
-
-template COLOR_PAIR*(n: expr): expr =
-  ((cunsignedlong(n) shl COLOR_SHIFT) and A_COLOR)
-
-template PAIR_NUMBER*(n: expr): expr =
-  (((n) and A_COLOR) shr COLOR_SHIFT)
-
-const
-  #MOUSE_X_POS* = (Mouse_status.x)
-  #MOUSE_Y_POS* = (Mouse_status.y)
-  #A_BUTTON_CHANGED* = (Mouse_status.changes and 7)
-  #MOUSE_MOVED* = (Mouse_status.changes and MOUSE_MOVED)
-  #MOUSE_POS_REPORT* = (Mouse_status.changes and MOUSE_POSITION)
-  #MOUSE_WHEEL_UP* = (Mouse_status.changes and MOUSE_WHEEL_UP)
-  #MOUSE_WHEEL_DOWN* = (Mouse_status.changes and MOUSE_WHEEL_DOWN)
-  ACS_ULCORNER* = ACS_PICK('l', '+')
-  ACS_LLCORNER* = ACS_PICK('m', '+')
-  ACS_URCORNER* = ACS_PICK('k', '+')
-  ACS_LRCORNER* = ACS_PICK('j', '+')
-  ACS_RTEE* = ACS_PICK('u', '+')
-  ACS_LTEE* = ACS_PICK('t', '+')
-  ACS_BTEE* = ACS_PICK('v', '+')
-  ACS_TTEE* = ACS_PICK('w', '+')
-  ACS_HLINE* = ACS_PICK('q', '-')
-  ACS_VLINE* = ACS_PICK('x', '|')
-  ACS_PLUS* = ACS_PICK('n', '+')
-  ACS_S1* = ACS_PICK('o', '-')
-  ACS_S9* = ACS_PICK('s', '_')
-  ACS_DIAMOND* = ACS_PICK('`', '+')
-  ACS_CKBOARD* = ACS_PICK('a', ':')
-  ACS_DEGREE* = ACS_PICK('f', '\'')
-  ACS_PLMINUS* = ACS_PICK('g', '#')
-  ACS_BULLET* = ACS_PICK('~', 'o')
-  ACS_LARROW* = ACS_PICK(',', '<')
-  ACS_RARROW* = ACS_PICK('+', '>')
-  ACS_DARROW* = ACS_PICK('.', 'v')
-  ACS_UARROW* = ACS_PICK('-', '^')
-  ACS_BOARD* = ACS_PICK('h', '#')
-  ACS_LANTERN* = ACS_PICK('i', '*')
-  ACS_BLOCK* = ACS_PICK('0', '#')
-  ACS_S3* = ACS_PICK('p', '-')
-  ACS_S7* = ACS_PICK('r', '-')
-  ACS_LEQUAL* = ACS_PICK('y', '<')
-  ACS_GEQUAL* = ACS_PICK('z', '>')
-  ACS_PI* = ACS_PICK('{', 'n')
-  ACS_NEQUAL* = ACS_PICK('|', '+')
-  ACS_STERLING* = ACS_PICK('}', 'L')
-  ACS_BSSB* = ACS_ULCORNER
-  ACS_SSBB* = ACS_LLCORNER
-  ACS_BBSS* = ACS_URCORNER
-  ACS_SBBS* = ACS_LRCORNER
-  ACS_SBSS* = ACS_RTEE
-  ACS_SSSB* = ACS_LTEE
-  ACS_SSBS* = ACS_BTEE
-  ACS_BSSS* = ACS_TTEE
-  ACS_BSBS* = ACS_HLINE
-  ACS_SBSB* = ACS_VLINE
-  ACS_SSSS* = ACS_PLUS
-discard """WACS_ULCORNER* = (addr((acs_map['l'])))
-  WACS_LLCORNER* = (addr((acs_map['m'])))
-  WACS_URCORNER* = (addr((acs_map['k'])))
-  WACS_LRCORNER* = (addr((acs_map['j'])))
-  WACS_RTEE* = (addr((acs_map['u'])))
-  WACS_LTEE* = (addr((acs_map['t'])))
-  WACS_BTEE* = (addr((acs_map['v'])))
-  WACS_TTEE* = (addr((acs_map['w'])))
-  WACS_HLINE* = (addr((acs_map['q'])))
-  WACS_VLINE* = (addr((acs_map['x'])))
-  WACS_PLUS* = (addr((acs_map['n'])))
-  WACS_S1* = (addr((acs_map['o'])))
-  WACS_S9* = (addr((acs_map['s'])))
-  WACS_DIAMOND* = (addr((acs_map['`'])))
-  WACS_CKBOARD* = (addr((acs_map['a'])))
-  WACS_DEGREE* = (addr((acs_map['f'])))
-  WACS_PLMINUS* = (addr((acs_map['g'])))
-  WACS_BULLET* = (addr((acs_map['~'])))
-  WACS_LARROW* = (addr((acs_map[','])))
-  WACS_RARROW* = (addr((acs_map['+'])))
-  WACS_DARROW* = (addr((acs_map['.'])))
-  WACS_UARROW* = (addr((acs_map['-'])))
-  WACS_BOARD* = (addr((acs_map['h'])))
-  WACS_LANTERN* = (addr((acs_map['i'])))
-  WACS_BLOCK* = (addr((acs_map['0'])))
-  WACS_S3* = (addr((acs_map['p'])))
-  WACS_S7* = (addr((acs_map['r'])))
-  WACS_LEQUAL* = (addr((acs_map['y'])))
-  WACS_GEQUAL* = (addr((acs_map['z'])))
-  WACS_PI* = (addr((acs_map['{'])))
-  WACS_NEQUAL* = (addr((acs_map['|'])))
-  WACS_STERLING* = (addr((acs_map['}'])))
-  WACS_BSSB* = WACS_ULCORNER
-  WACS_SSBB* = WACS_LLCORNER
-  WACS_BBSS* = WACS_URCORNER
-  WACS_SBBS* = WACS_LRCORNER
-  WACS_SBSS* = WACS_RTEE
-  WACS_SSSB* = WACS_LTEE
-  WACS_SSBS* = WACS_BTEE
-  WACS_BSSS* = WACS_TTEE
-  WACS_BSBS* = WACS_HLINE
-  WACS_SBSB* = WACS_VLINE
-  WACS_SSSS* = WACS_PLUS"""
-
-proc addch*(a2: cunsignedlong): cint{.extdecl, importc: "addch",
-                                      dynlib: pdcursesdll.}
-proc addchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "addchnstr", dynlib: pdcursesdll.}
-proc addchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "addchstr",
-    dynlib: pdcursesdll.}
-proc addnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnstr",
-    dynlib: pdcursesdll.}
-proc addstr*(a2: cstring): cint{.extdecl, importc: "addstr", dynlib: pdcursesdll.}
-proc attroff*(a2: cunsignedlong): cint{.extdecl, importc: "attroff",
-                                        dynlib: pdcursesdll.}
-proc attron*(a2: cunsignedlong): cint{.extdecl, importc: "attron",
-                                       dynlib: pdcursesdll.}
-proc attrset*(a2: cunsignedlong): cint{.extdecl, importc: "attrset",
-                                        dynlib: pdcursesdll.}
-proc attr_get*(a2: ptr cunsignedlong; a3: ptr cshort; a4: pointer): cint{.extdecl,
-    importc: "attr_get", dynlib: pdcursesdll.}
-proc attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl,
-    importc: "attr_off", dynlib: pdcursesdll.}
-proc attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl, importc: "attr_on",
-    dynlib: pdcursesdll.}
-proc attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl,
-    importc: "attr_set", dynlib: pdcursesdll.}
-proc baudrate*(): cint{.extdecl, importc: "baudrate", dynlib: pdcursesdll.}
-proc beep*(): cint{.extdecl, importc: "beep", dynlib: pdcursesdll.}
-proc bkgd*(a2: cunsignedlong): cint{.extdecl, importc: "bkgd", dynlib: pdcursesdll.}
-proc bkgdset*(a2: cunsignedlong){.extdecl, importc: "bkgdset", dynlib: pdcursesdll.}
-proc border*(a2: cunsignedlong; a3: cunsignedlong; a4: cunsignedlong;
-             a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong;
-             a8: cunsignedlong; a9: cunsignedlong): cint{.extdecl,
-    importc: "border", dynlib: pdcursesdll.}
-proc box*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong): cint{.extdecl,
-    importc: "box", dynlib: pdcursesdll.}
-proc can_change_color*(): cunsignedchar{.extdecl, importc: "can_change_color",
-    dynlib: pdcursesdll.}
-proc cbreak*(): cint{.extdecl, importc: "cbreak", dynlib: pdcursesdll.}
-proc chgat*(a2: cint; a3: cunsignedlong; a4: cshort; a5: pointer): cint{.extdecl,
-    importc: "chgat", dynlib: pdcursesdll.}
-proc clearok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "clearok", dynlib: pdcursesdll.}
-proc clear*(): cint{.extdecl, importc: "clear", dynlib: pdcursesdll.}
-proc clrtobot*(): cint{.extdecl, importc: "clrtobot", dynlib: pdcursesdll.}
-proc clrtoeol*(): cint{.extdecl, importc: "clrtoeol", dynlib: pdcursesdll.}
-proc color_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort; a5: ptr cshort): cint{.
-    extdecl, importc: "color_content", dynlib: pdcursesdll.}
-proc color_set*(a2: cshort; a3: pointer): cint{.extdecl, importc: "color_set",
-    dynlib: pdcursesdll.}
-proc copywin*(a2: ptr WINDOW; a3: ptr WINDOW; a4: cint; a5: cint; a6: cint;
-              a7: cint; a8: cint; a9: cint; a10: cint): cint{.extdecl,
-    importc: "copywin", dynlib: pdcursesdll.}
-proc curs_set*(a2: cint): cint{.extdecl, importc: "curs_set", dynlib: pdcursesdll.}
-proc def_prog_mode*(): cint{.extdecl, importc: "def_prog_mode",
-                             dynlib: pdcursesdll.}
-proc def_shell_mode*(): cint{.extdecl, importc: "def_shell_mode",
-                              dynlib: pdcursesdll.}
-proc delay_output*(a2: cint): cint{.extdecl, importc: "delay_output",
-                                    dynlib: pdcursesdll.}
-proc delch*(): cint{.extdecl, importc: "delch", dynlib: pdcursesdll.}
-proc deleteln*(): cint{.extdecl, importc: "deleteln", dynlib: pdcursesdll.}
-proc delscreen*(a2: ptr SCREEN){.extdecl, importc: "delscreen",
-                                 dynlib: pdcursesdll.}
-proc delwin*(a2: ptr WINDOW): cint{.extdecl, importc: "delwin",
-                                    dynlib: pdcursesdll.}
-proc derwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{.
-    extdecl, importc: "derwin", dynlib: pdcursesdll.}
-proc doupdate*(): cint{.extdecl, importc: "doupdate", dynlib: pdcursesdll.}
-proc dupwin*(a2: ptr WINDOW): ptr WINDOW{.extdecl, importc: "dupwin",
-    dynlib: pdcursesdll.}
-proc echochar*(a2: cunsignedlong): cint{.extdecl, importc: "echochar",
-    dynlib: pdcursesdll.}
-proc echo*(): cint{.extdecl, importc: "echo", dynlib: pdcursesdll.}
-proc endwin*(): cint{.extdecl, importc: "endwin", dynlib: pdcursesdll.}
-proc erasechar*(): char{.extdecl, importc: "erasechar", dynlib: pdcursesdll.}
-proc erase*(): cint{.extdecl, importc: "erase", dynlib: pdcursesdll.}
-proc filter*(){.extdecl, importc: "filter", dynlib: pdcursesdll.}
-proc flash*(): cint{.extdecl, importc: "flash", dynlib: pdcursesdll.}
-proc flushinp*(): cint{.extdecl, importc: "flushinp", dynlib: pdcursesdll.}
-proc getbkgd*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getbkgd",
-    dynlib: pdcursesdll.}
-proc getnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "getnstr",
-    dynlib: pdcursesdll.}
-proc getstr*(a2: cstring): cint{.extdecl, importc: "getstr", dynlib: pdcursesdll.}
-proc getwin*(a2: File): ptr WINDOW{.extdecl, importc: "getwin",
-                                        dynlib: pdcursesdll.}
-proc halfdelay*(a2: cint): cint{.extdecl, importc: "halfdelay",
-                                 dynlib: pdcursesdll.}
-proc has_colors*(): cunsignedchar{.extdecl, importc: "has_colors",
-                                   dynlib: pdcursesdll.}
-proc has_ic*(): cunsignedchar{.extdecl, importc: "has_ic", dynlib: pdcursesdll.}
-proc has_il*(): cunsignedchar{.extdecl, importc: "has_il", dynlib: pdcursesdll.}
-proc hline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "hline",
-    dynlib: pdcursesdll.}
-proc idcok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "idcok",
-    dynlib: pdcursesdll.}
-proc idlok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "idlok",
-    dynlib: pdcursesdll.}
-proc immedok*(a2: ptr WINDOW; a3: cunsignedchar){.extdecl, importc: "immedok",
-    dynlib: pdcursesdll.}
-proc inchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "inchnstr", dynlib: pdcursesdll.}
-proc inchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "inchstr",
-    dynlib: pdcursesdll.}
-proc inch*(): cunsignedlong{.extdecl, importc: "inch", dynlib: pdcursesdll.}
-proc init_color*(a2: cshort; a3: cshort; a4: cshort; a5: cshort): cint{.extdecl,
-    importc: "init_color", dynlib: pdcursesdll.}
-proc init_pair*(a2: cshort; a3: cshort; a4: cshort): cint{.extdecl,
-    importc: "init_pair", dynlib: pdcursesdll.}
-proc initscr*(): ptr WINDOW{.extdecl, importc: "initscr", dynlib: pdcursesdll.}
-proc innstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innstr",
-    dynlib: pdcursesdll.}
-proc insch*(a2: cunsignedlong): cint{.extdecl, importc: "insch",
-                                      dynlib: pdcursesdll.}
-proc insdelln*(a2: cint): cint{.extdecl, importc: "insdelln", dynlib: pdcursesdll.}
-proc insertln*(): cint{.extdecl, importc: "insertln", dynlib: pdcursesdll.}
-proc insnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "insnstr",
-    dynlib: pdcursesdll.}
-proc insstr*(a2: cstring): cint{.extdecl, importc: "insstr", dynlib: pdcursesdll.}
-proc instr*(a2: cstring): cint{.extdecl, importc: "instr", dynlib: pdcursesdll.}
-proc intrflush*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "intrflush", dynlib: pdcursesdll.}
-proc isendwin*(): cunsignedchar{.extdecl, importc: "isendwin", dynlib: pdcursesdll.}
-proc is_linetouched*(a2: ptr WINDOW; a3: cint): cunsignedchar{.extdecl,
-    importc: "is_linetouched", dynlib: pdcursesdll.}
-proc is_wintouched*(a2: ptr WINDOW): cunsignedchar{.extdecl,
-    importc: "is_wintouched", dynlib: pdcursesdll.}
-proc keyname*(a2: cint): cstring{.extdecl, importc: "keyname", dynlib: pdcursesdll.}
-proc keypad*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "keypad",
-    dynlib: pdcursesdll.}
-proc killchar*(): char{.extdecl, importc: "killchar", dynlib: pdcursesdll.}
-proc leaveok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "leaveok", dynlib: pdcursesdll.}
-proc longname*(): cstring{.extdecl, importc: "longname", dynlib: pdcursesdll.}
-proc meta*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "meta",
-    dynlib: pdcursesdll.}
-proc move*(a2: cint; a3: cint): cint{.extdecl, importc: "move",
-                                      dynlib: pdcursesdll.}
-proc mvaddch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl,
-    importc: "mvaddch", dynlib: pdcursesdll.}
-proc mvaddchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvaddchnstr", dynlib: pdcursesdll.}
-proc mvaddchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvaddchstr", dynlib: pdcursesdll.}
-proc mvaddnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvaddnstr", dynlib: pdcursesdll.}
-proc mvaddstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvaddstr", dynlib: pdcursesdll.}
-proc mvchgat*(a2: cint; a3: cint; a4: cint; a5: cunsignedlong; a6: cshort;
-              a7: pointer): cint{.extdecl, importc: "mvchgat", dynlib: pdcursesdll.}
-proc mvcur*(a2: cint; a3: cint; a4: cint; a5: cint): cint{.extdecl,
-    importc: "mvcur", dynlib: pdcursesdll.}
-proc mvdelch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdelch",
-    dynlib: pdcursesdll.}
-proc mvderwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "mvderwin", dynlib: pdcursesdll.}
-proc mvgetch*(a2: cint; a3: cint): cint{.extdecl, importc: "mvgetch",
-    dynlib: pdcursesdll.}
-proc mvgetnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvgetnstr", dynlib: pdcursesdll.}
-proc mvgetstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvgetstr", dynlib: pdcursesdll.}
-proc mvhline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl,
-    importc: "mvhline", dynlib: pdcursesdll.}
-proc mvinch*(a2: cint; a3: cint): cunsignedlong{.extdecl, importc: "mvinch",
-    dynlib: pdcursesdll.}
-proc mvinchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvinchnstr", dynlib: pdcursesdll.}
-proc mvinchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvinchstr", dynlib: pdcursesdll.}
-proc mvinnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvinnstr", dynlib: pdcursesdll.}
-proc mvinsch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl,
-    importc: "mvinsch", dynlib: pdcursesdll.}
-proc mvinsnstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvinsnstr", dynlib: pdcursesdll.}
-proc mvinsstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvinsstr", dynlib: pdcursesdll.}
-proc mvinstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl, importc: "mvinstr",
-    dynlib: pdcursesdll.}
-proc mvprintw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl,
-    importc: "mvprintw", dynlib: pdcursesdll.}
-proc mvscanw*(a2: cint; a3: cint; a4: cstring): cint{.varargs, extdecl,
-    importc: "mvscanw", dynlib: pdcursesdll.}
-proc mvvline*(a2: cint; a3: cint; a4: cunsignedlong; a5: cint): cint{.extdecl,
-    importc: "mvvline", dynlib: pdcursesdll.}
-proc mvwaddchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                   a6: cint): cint{.extdecl, importc: "mvwaddchnstr",
-                                    dynlib: pdcursesdll.}
-proc mvwaddchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwaddchstr", dynlib: pdcursesdll.}
-proc mvwaddch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{.
-    extdecl, importc: "mvwaddch", dynlib: pdcursesdll.}
-proc mvwaddnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwaddnstr", dynlib: pdcursesdll.}
-proc mvwaddstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl,
-    importc: "mvwaddstr", dynlib: pdcursesdll.}
-proc mvwchgat*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cunsignedlong;
-               a7: cshort; a8: pointer): cint{.extdecl, importc: "mvwchgat",
-    dynlib: pdcursesdll.}
-proc mvwdelch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "mvwdelch", dynlib: pdcursesdll.}
-proc mvwgetch*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "mvwgetch", dynlib: pdcursesdll.}
-proc mvwgetnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwgetnstr", dynlib: pdcursesdll.}
-proc mvwgetstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl,
-    importc: "mvwgetstr", dynlib: pdcursesdll.}
-proc mvwhline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{.
-    extdecl, importc: "mvwhline", dynlib: pdcursesdll.}
-proc mvwinchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                  a6: cint): cint{.extdecl, importc: "mvwinchnstr",
-                                   dynlib: pdcursesdll.}
-proc mvwinchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwinchstr", dynlib: pdcursesdll.}
-proc mvwinch*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedlong{.extdecl,
-    importc: "mvwinch", dynlib: pdcursesdll.}
-proc mvwinnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwinnstr", dynlib: pdcursesdll.}
-proc mvwinsch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{.
-    extdecl, importc: "mvwinsch", dynlib: pdcursesdll.}
-proc mvwinsnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwinsnstr", dynlib: pdcursesdll.}
-proc mvwinsstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl,
-    importc: "mvwinsstr", dynlib: pdcursesdll.}
-proc mvwinstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.extdecl,
-    importc: "mvwinstr", dynlib: pdcursesdll.}
-proc mvwin*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "mvwin",
-    dynlib: pdcursesdll.}
-proc mvwprintw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs,
-    extdecl, importc: "mvwprintw", dynlib: pdcursesdll.}
-proc mvwscanw*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.varargs,
-    extdecl, importc: "mvwscanw", dynlib: pdcursesdll.}
-proc mvwvline*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint): cint{.
-    extdecl, importc: "mvwvline", dynlib: pdcursesdll.}
-proc napms*(a2: cint): cint{.extdecl, importc: "napms", dynlib: pdcursesdll.}
-proc newpad*(a2: cint; a3: cint): ptr WINDOW{.extdecl, importc: "newpad",
-    dynlib: pdcursesdll.}
-proc newterm*(a2: cstring; a3: File; a4: File): ptr SCREEN{.extdecl,
-    importc: "newterm", dynlib: pdcursesdll.}
-proc newwin*(a2: cint; a3: cint; a4: cint; a5: cint): ptr WINDOW{.extdecl,
-    importc: "newwin", dynlib: pdcursesdll.}
-proc nl*(): cint{.extdecl, importc: "nl", dynlib: pdcursesdll.}
-proc nocbreak*(): cint{.extdecl, importc: "nocbreak", dynlib: pdcursesdll.}
-proc nodelay*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "nodelay", dynlib: pdcursesdll.}
-proc noecho*(): cint{.extdecl, importc: "noecho", dynlib: pdcursesdll.}
-proc nonl*(): cint{.extdecl, importc: "nonl", dynlib: pdcursesdll.}
-proc noqiflush*(){.extdecl, importc: "noqiflush", dynlib: pdcursesdll.}
-proc noraw*(): cint{.extdecl, importc: "noraw", dynlib: pdcursesdll.}
-proc notimeout*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "notimeout", dynlib: pdcursesdll.}
-proc overlay*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl, importc: "overlay",
-    dynlib: pdcursesdll.}
-proc overwrite*(a2: ptr WINDOW; a3: ptr WINDOW): cint{.extdecl,
-    importc: "overwrite", dynlib: pdcursesdll.}
-proc pair_content*(a2: cshort; a3: ptr cshort; a4: ptr cshort): cint{.extdecl,
-    importc: "pair_content", dynlib: pdcursesdll.}
-proc pechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "pechochar", dynlib: pdcursesdll.}
-proc pnoutrefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint;
-                   a7: cint; a8: cint): cint{.extdecl, importc: "pnoutrefresh",
-    dynlib: pdcursesdll.}
-proc prefresh*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint; a7: cint;
-               a8: cint): cint{.extdecl, importc: "prefresh", dynlib: pdcursesdll.}
-proc printw*(a2: cstring): cint{.varargs, extdecl, importc: "printw",
-                                 dynlib: pdcursesdll.}
-proc putwin*(a2: ptr WINDOW; a3: File): cint{.extdecl, importc: "putwin",
-    dynlib: pdcursesdll.}
-proc qiflush*(){.extdecl, importc: "qiflush", dynlib: pdcursesdll.}
-proc raw*(): cint{.extdecl, importc: "raw", dynlib: pdcursesdll.}
-proc redrawwin*(a2: ptr WINDOW): cint{.extdecl, importc: "redrawwin",
-                                       dynlib: pdcursesdll.}
-proc refresh*(): cint{.extdecl, importc: "refresh", dynlib: pdcursesdll.}
-proc reset_prog_mode*(): cint{.extdecl, importc: "reset_prog_mode",
-                               dynlib: pdcursesdll.}
-proc reset_shell_mode*(): cint{.extdecl, importc: "reset_shell_mode",
-                                dynlib: pdcursesdll.}
-proc resetty*(): cint{.extdecl, importc: "resetty", dynlib: pdcursesdll.}
-#int     ripoffline(int, int (*)(WINDOW *, int));
-proc savetty*(): cint{.extdecl, importc: "savetty", dynlib: pdcursesdll.}
-proc scanw*(a2: cstring): cint{.varargs, extdecl, importc: "scanw",
-                                dynlib: pdcursesdll.}
-proc scr_dump*(a2: cstring): cint{.extdecl, importc: "scr_dump",
-                                   dynlib: pdcursesdll.}
-proc scr_init*(a2: cstring): cint{.extdecl, importc: "scr_init",
-                                   dynlib: pdcursesdll.}
-proc scr_restore*(a2: cstring): cint{.extdecl, importc: "scr_restore",
-                                      dynlib: pdcursesdll.}
-proc scr_set*(a2: cstring): cint{.extdecl, importc: "scr_set", dynlib: pdcursesdll.}
-proc scrl*(a2: cint): cint{.extdecl, importc: "scrl", dynlib: pdcursesdll.}
-proc scroll*(a2: ptr WINDOW): cint{.extdecl, importc: "scroll",
-                                    dynlib: pdcursesdll.}
-proc scrollok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl,
-    importc: "scrollok", dynlib: pdcursesdll.}
-proc set_term*(a2: ptr SCREEN): ptr SCREEN{.extdecl, importc: "set_term",
-    dynlib: pdcursesdll.}
-proc setscrreg*(a2: cint; a3: cint): cint{.extdecl, importc: "setscrreg",
-    dynlib: pdcursesdll.}
-proc slk_attroff*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attroff",
-    dynlib: pdcursesdll.}
-proc slk_attr_off*(a2: cunsignedlong; a3: pointer): cint{.extdecl,
-    importc: "slk_attr_off", dynlib: pdcursesdll.}
-proc slk_attron*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attron",
-    dynlib: pdcursesdll.}
-proc slk_attr_on*(a2: cunsignedlong; a3: pointer): cint{.extdecl,
-    importc: "slk_attr_on", dynlib: pdcursesdll.}
-proc slk_attrset*(a2: cunsignedlong): cint{.extdecl, importc: "slk_attrset",
-    dynlib: pdcursesdll.}
-proc slk_attr_set*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl,
-    importc: "slk_attr_set", dynlib: pdcursesdll.}
-proc slk_clear*(): cint{.extdecl, importc: "slk_clear", dynlib: pdcursesdll.}
-proc slk_color*(a2: cshort): cint{.extdecl, importc: "slk_color",
-                                   dynlib: pdcursesdll.}
-proc slk_init*(a2: cint): cint{.extdecl, importc: "slk_init", dynlib: pdcursesdll.}
-proc slk_label*(a2: cint): cstring{.extdecl, importc: "slk_label",
-                                    dynlib: pdcursesdll.}
-proc slk_noutrefresh*(): cint{.extdecl, importc: "slk_noutrefresh",
-                               dynlib: pdcursesdll.}
-proc slk_refresh*(): cint{.extdecl, importc: "slk_refresh", dynlib: pdcursesdll.}
-proc slk_restore*(): cint{.extdecl, importc: "slk_restore", dynlib: pdcursesdll.}
-proc slk_set*(a2: cint; a3: cstring; a4: cint): cint{.extdecl, importc: "slk_set",
-    dynlib: pdcursesdll.}
-proc slk_touch*(): cint{.extdecl, importc: "slk_touch", dynlib: pdcursesdll.}
-proc standend*(): cint{.extdecl, importc: "standend", dynlib: pdcursesdll.}
-proc standout*(): cint{.extdecl, importc: "standout", dynlib: pdcursesdll.}
-proc start_color*(): cint{.extdecl, importc: "start_color", dynlib: pdcursesdll.}
-proc subpad*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{.
-    extdecl, importc: "subpad", dynlib: pdcursesdll.}
-proc subwin*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint; a6: cint): ptr WINDOW{.
-    extdecl, importc: "subwin", dynlib: pdcursesdll.}
-proc syncok*(a2: ptr WINDOW; a3: cunsignedchar): cint{.extdecl, importc: "syncok",
-    dynlib: pdcursesdll.}
-proc termattrs*(): cunsignedlong{.extdecl, importc: "termattrs",
-                                  dynlib: pdcursesdll.}
-proc termattrs2*(): cunsignedlong{.extdecl, importc: "term_attrs",
-                                   dynlib: pdcursesdll.}
-proc termname*(): cstring{.extdecl, importc: "termname", dynlib: pdcursesdll.}
-proc timeout*(a2: cint){.extdecl, importc: "timeout", dynlib: pdcursesdll.}
-proc touchline*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "touchline", dynlib: pdcursesdll.}
-proc touchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "touchwin",
-                                      dynlib: pdcursesdll.}
-proc typeahead*(a2: cint): cint{.extdecl, importc: "typeahead",
-                                 dynlib: pdcursesdll.}
-proc untouchwin*(a2: ptr WINDOW): cint{.extdecl, importc: "untouchwin",
-                                        dynlib: pdcursesdll.}
-proc use_env*(a2: cunsignedchar){.extdecl, importc: "use_env", dynlib: pdcursesdll.}
-proc vidattr*(a2: cunsignedlong): cint{.extdecl, importc: "vidattr",
-                                        dynlib: pdcursesdll.}
-proc vid_attr*(a2: cunsignedlong; a3: cshort; a4: pointer): cint{.extdecl,
-    importc: "vid_attr", dynlib: pdcursesdll.}
-#int     vidputs(chtype, int (*)(int));
-#int     vid_puts(attr_t, short, void *, int (*)(int));
-proc vline*(a2: cunsignedlong; a3: cint): cint{.extdecl, importc: "vline",
-    dynlib: pdcursesdll.}
-proc vwprintw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs,
-    importc: "vw_printw", dynlib: pdcursesdll.}
-proc vwprintw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs,
-    importc: "vwprintw", dynlib: pdcursesdll.}
-proc vwscanw*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs,
-    importc: "vw_scanw", dynlib: pdcursesdll.}
-proc vwscanw2*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, varargs,
-    importc: "vwscanw", dynlib: pdcursesdll.}
-proc waddchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "waddchnstr", dynlib: pdcursesdll.}
-proc waddchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "waddchstr", dynlib: pdcursesdll.}
-proc waddch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "waddch",
-    dynlib: pdcursesdll.}
-proc waddnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "waddnstr", dynlib: pdcursesdll.}
-proc waddstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "waddstr",
-    dynlib: pdcursesdll.}
-proc wattroff*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "wattroff", dynlib: pdcursesdll.}
-proc wattron*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "wattron", dynlib: pdcursesdll.}
-proc wattrset*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "wattrset", dynlib: pdcursesdll.}
-proc wattr_get*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cshort;
-                a5: pointer): cint{.extdecl, importc: "wattr_get",
-                                    dynlib: pdcursesdll.}
-proc wattr_off*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl,
-    importc: "wattr_off", dynlib: pdcursesdll.}
-proc wattr_on*(a2: ptr WINDOW; a3: cunsignedlong; a4: pointer): cint{.extdecl,
-    importc: "wattr_on", dynlib: pdcursesdll.}
-proc wattr_set*(a2: ptr WINDOW; a3: cunsignedlong; a4: cshort; a5: pointer): cint{.
-    extdecl, importc: "wattr_set", dynlib: pdcursesdll.}
-proc wbkgdset*(a2: ptr WINDOW; a3: cunsignedlong){.extdecl, importc: "wbkgdset",
-    dynlib: pdcursesdll.}
-proc wbkgd*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "wbkgd",
-    dynlib: pdcursesdll.}
-proc wborder*(a2: ptr WINDOW; a3: cunsignedlong; a4: cunsignedlong;
-              a5: cunsignedlong; a6: cunsignedlong; a7: cunsignedlong;
-              a8: cunsignedlong; a9: cunsignedlong; a10: cunsignedlong): cint{.
-    extdecl, importc: "wborder", dynlib: pdcursesdll.}
-proc wchgat*(a2: ptr WINDOW; a3: cint; a4: cunsignedlong; a5: cshort;
-             a6: pointer): cint{.extdecl, importc: "wchgat", dynlib: pdcursesdll.}
-proc wclear*(a2: ptr WINDOW): cint{.extdecl, importc: "wclear",
-                                    dynlib: pdcursesdll.}
-proc wclrtobot*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtobot",
-                                       dynlib: pdcursesdll.}
-proc wclrtoeol*(a2: ptr WINDOW): cint{.extdecl, importc: "wclrtoeol",
-                                       dynlib: pdcursesdll.}
-proc wcolor_set*(a2: ptr WINDOW; a3: cshort; a4: pointer): cint{.extdecl,
-    importc: "wcolor_set", dynlib: pdcursesdll.}
-proc wcursyncup*(a2: ptr WINDOW){.extdecl, importc: "wcursyncup",
-                                  dynlib: pdcursesdll.}
-proc wdelch*(a2: ptr WINDOW): cint{.extdecl, importc: "wdelch",
-                                    dynlib: pdcursesdll.}
-proc wdeleteln*(a2: ptr WINDOW): cint{.extdecl, importc: "wdeleteln",
-                                       dynlib: pdcursesdll.}
-proc wechochar*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "wechochar", dynlib: pdcursesdll.}
-proc werase*(a2: ptr WINDOW): cint{.extdecl, importc: "werase",
-                                    dynlib: pdcursesdll.}
-proc wgetch*(a2: ptr WINDOW): cint{.extdecl, importc: "wgetch",
-                                    dynlib: pdcursesdll.}
-proc wgetnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "wgetnstr", dynlib: pdcursesdll.}
-proc wgetstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "wgetstr",
-    dynlib: pdcursesdll.}
-proc whline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "whline", dynlib: pdcursesdll.}
-proc winchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "winchnstr", dynlib: pdcursesdll.}
-proc winchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "winchstr", dynlib: pdcursesdll.}
-proc winch*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "winch",
-    dynlib: pdcursesdll.}
-proc winnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "winnstr", dynlib: pdcursesdll.}
-proc winsch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl, importc: "winsch",
-    dynlib: pdcursesdll.}
-proc winsdelln*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "winsdelln",
-    dynlib: pdcursesdll.}
-proc winsertln*(a2: ptr WINDOW): cint{.extdecl, importc: "winsertln",
-                                       dynlib: pdcursesdll.}
-proc winsnstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "winsnstr", dynlib: pdcursesdll.}
-proc winsstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winsstr",
-    dynlib: pdcursesdll.}
-proc winstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winstr",
-    dynlib: pdcursesdll.}
-proc wmove*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl, importc: "wmove",
-    dynlib: pdcursesdll.}
-proc wnoutrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wnoutrefresh",
-    dynlib: pdcursesdll.}
-proc wprintw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl,
-    importc: "wprintw", dynlib: pdcursesdll.}
-proc wredrawln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "wredrawln", dynlib: pdcursesdll.}
-proc wrefresh*(a2: ptr WINDOW): cint{.extdecl, importc: "wrefresh",
-                                      dynlib: pdcursesdll.}
-proc wscanw*(a2: ptr WINDOW; a3: cstring): cint{.varargs, extdecl,
-    importc: "wscanw", dynlib: pdcursesdll.}
-proc wscrl*(a2: ptr WINDOW; a3: cint): cint{.extdecl, importc: "wscrl",
-    dynlib: pdcursesdll.}
-proc wsetscrreg*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "wsetscrreg", dynlib: pdcursesdll.}
-proc wstandend*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandend",
-                                       dynlib: pdcursesdll.}
-proc wstandout*(a2: ptr WINDOW): cint{.extdecl, importc: "wstandout",
-                                       dynlib: pdcursesdll.}
-proc wsyncdown*(a2: ptr WINDOW){.extdecl, importc: "wsyncdown",
-                                 dynlib: pdcursesdll.}
-proc wsyncup*(a2: ptr WINDOW){.extdecl, importc: "wsyncup", dynlib: pdcursesdll.}
-proc wtimeout*(a2: ptr WINDOW; a3: cint){.extdecl, importc: "wtimeout",
-    dynlib: pdcursesdll.}
-proc wtouchln*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cint): cint{.extdecl,
-    importc: "wtouchln", dynlib: pdcursesdll.}
-proc wvline*(a2: ptr WINDOW; a3: cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "wvline", dynlib: pdcursesdll.}
-proc addnwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "addnwstr",
-    dynlib: pdcursesdll.}
-proc addwstr*(a2: cstring): cint{.extdecl, importc: "addwstr",
-                                      dynlib: pdcursesdll.}
-proc add_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wch",
-    dynlib: pdcursesdll.}
-proc add_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "add_wchnstr", dynlib: pdcursesdll.}
-proc add_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "add_wchstr",
-    dynlib: pdcursesdll.}
-proc border_set*(a2: ptr cunsignedlong; a3: ptr cunsignedlong;
-                 a4: ptr cunsignedlong; a5: ptr cunsignedlong;
-                 a6: ptr cunsignedlong; a7: ptr cunsignedlong;
-                 a8: ptr cunsignedlong; a9: ptr cunsignedlong): cint{.extdecl,
-    importc: "border_set", dynlib: pdcursesdll.}
-proc box_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong): cint{.
-    extdecl, importc: "box_set", dynlib: pdcursesdll.}
-proc echo_wchar*(a2: ptr cunsignedlong): cint{.extdecl, importc: "echo_wchar",
-    dynlib: pdcursesdll.}
-proc erasewchar*(a2: cstring): cint{.extdecl, importc: "erasewchar",
-    dynlib: pdcursesdll.}
-proc getbkgrnd*(a2: ptr cunsignedlong): cint{.extdecl, importc: "getbkgrnd",
-    dynlib: pdcursesdll.}
-proc getcchar*(a2: ptr cunsignedlong; a3: cstring; a4: ptr cunsignedlong;
-               a5: ptr cshort; a6: pointer): cint{.extdecl, importc: "getcchar",
-    dynlib: pdcursesdll.}
-proc getn_wstr*(a2: ptr cint; a3: cint): cint{.extdecl, importc: "getn_wstr",
-    dynlib: pdcursesdll.}
-proc get_wch*(a2: ptr cint): cint{.extdecl, importc: "get_wch",
-                                     dynlib: pdcursesdll.}
-proc get_wstr*(a2: ptr cint): cint{.extdecl, importc: "get_wstr",
-                                      dynlib: pdcursesdll.}
-proc hline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "hline_set", dynlib: pdcursesdll.}
-proc innwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "innwstr",
-    dynlib: pdcursesdll.}
-proc ins_nwstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "ins_nwstr",
-    dynlib: pdcursesdll.}
-proc ins_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "ins_wch",
-    dynlib: pdcursesdll.}
-proc ins_wstr*(a2: cstring): cint{.extdecl, importc: "ins_wstr",
-                                       dynlib: pdcursesdll.}
-proc inwstr*(a2: cstring): cint{.extdecl, importc: "inwstr",
-                                     dynlib: pdcursesdll.}
-proc in_wch*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wch",
-    dynlib: pdcursesdll.}
-proc in_wchnstr*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "in_wchnstr", dynlib: pdcursesdll.}
-proc in_wchstr*(a2: ptr cunsignedlong): cint{.extdecl, importc: "in_wchstr",
-    dynlib: pdcursesdll.}
-proc key_name*(a2: char): cstring{.extdecl, importc: "key_name",
-                                      dynlib: pdcursesdll.}
-proc killwchar*(a2: cstring): cint{.extdecl, importc: "killwchar",
-                                        dynlib: pdcursesdll.}
-proc mvaddnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvaddnwstr", dynlib: pdcursesdll.}
-proc mvaddwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvaddwstr", dynlib: pdcursesdll.}
-proc mvadd_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvadd_wch", dynlib: pdcursesdll.}
-proc mvadd_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvadd_wchnstr", dynlib: pdcursesdll.}
-proc mvadd_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvadd_wchstr", dynlib: pdcursesdll.}
-proc mvgetn_wstr*(a2: cint; a3: cint; a4: ptr cint; a5: cint): cint{.extdecl,
-    importc: "mvgetn_wstr", dynlib: pdcursesdll.}
-proc mvget_wch*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl,
-    importc: "mvget_wch", dynlib: pdcursesdll.}
-proc mvget_wstr*(a2: cint; a3: cint; a4: ptr cint): cint{.extdecl,
-    importc: "mvget_wstr", dynlib: pdcursesdll.}
-proc mvhline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvhline_set", dynlib: pdcursesdll.}
-proc mvinnwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvinnwstr", dynlib: pdcursesdll.}
-proc mvins_nwstr*(a2: cint; a3: cint; a4: cstring; a5: cint): cint{.extdecl,
-    importc: "mvins_nwstr", dynlib: pdcursesdll.}
-proc mvins_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvins_wch", dynlib: pdcursesdll.}
-proc mvins_wstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvins_wstr", dynlib: pdcursesdll.}
-proc mvinwstr*(a2: cint; a3: cint; a4: cstring): cint{.extdecl,
-    importc: "mvinwstr", dynlib: pdcursesdll.}
-proc mvin_wch*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvin_wch", dynlib: pdcursesdll.}
-proc mvin_wchnstr*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvin_wchnstr", dynlib: pdcursesdll.}
-proc mvin_wchstr*(a2: cint; a3: cint; a4: ptr cunsignedlong): cint{.extdecl,
-    importc: "mvin_wchstr", dynlib: pdcursesdll.}
-proc mvvline_set*(a2: cint; a3: cint; a4: ptr cunsignedlong; a5: cint): cint{.
-    extdecl, importc: "mvvline_set", dynlib: pdcursesdll.}
-proc mvwaddnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwaddnwstr", dynlib: pdcursesdll.}
-proc mvwaddwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.
-    extdecl, importc: "mvwaddwstr", dynlib: pdcursesdll.}
-proc mvwadd_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwadd_wch", dynlib: pdcursesdll.}
-proc mvwadd_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                     a6: cint): cint{.extdecl, importc: "mvwadd_wchnstr",
-                                      dynlib: pdcursesdll.}
-proc mvwadd_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwadd_wchstr", dynlib: pdcursesdll.}
-proc mvwgetn_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint; a6: cint): cint{.
-    extdecl, importc: "mvwgetn_wstr", dynlib: pdcursesdll.}
-proc mvwget_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{.
-    extdecl, importc: "mvwget_wch", dynlib: pdcursesdll.}
-proc mvwget_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cint): cint{.
-    extdecl, importc: "mvwget_wstr", dynlib: pdcursesdll.}
-proc mvwhline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                   a6: cint): cint{.extdecl, importc: "mvwhline_set",
-                                    dynlib: pdcursesdll.}
-proc mvwinnwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwinnwstr", dynlib: pdcursesdll.}
-proc mvwins_nwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring; a6: cint): cint{.
-    extdecl, importc: "mvwins_nwstr", dynlib: pdcursesdll.}
-proc mvwins_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwins_wch", dynlib: pdcursesdll.}
-proc mvwins_wstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.
-    extdecl, importc: "mvwins_wstr", dynlib: pdcursesdll.}
-proc mvwin_wch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwin_wch", dynlib: pdcursesdll.}
-proc mvwin_wchnstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                    a6: cint): cint{.extdecl, importc: "mvwin_wchnstr",
-                                     dynlib: pdcursesdll.}
-proc mvwin_wchstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong): cint{.
-    extdecl, importc: "mvwin_wchstr", dynlib: pdcursesdll.}
-proc mvwinwstr*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cstring): cint{.
-    extdecl, importc: "mvwinwstr", dynlib: pdcursesdll.}
-proc mvwvline_set*(a2: ptr WINDOW; a3: cint; a4: cint; a5: ptr cunsignedlong;
-                   a6: cint): cint{.extdecl, importc: "mvwvline_set",
-                                    dynlib: pdcursesdll.}
-proc pecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "pecho_wchar", dynlib: pdcursesdll.}
-proc setcchar*(a2: ptr cunsignedlong; a3: cstring; a4: cunsignedlong;
-               a5: cshort; a6: pointer): cint{.extdecl, importc: "setcchar",
-    dynlib: pdcursesdll.}
-proc slk_wset*(a2: cint; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "slk_wset", dynlib: pdcursesdll.}
-proc unget_wch*(a2: char): cint{.extdecl, importc: "unget_wch",
-                                    dynlib: pdcursesdll.}
-proc vline_set*(a2: ptr cunsignedlong; a3: cint): cint{.extdecl,
-    importc: "vline_set", dynlib: pdcursesdll.}
-proc waddnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "waddnwstr", dynlib: pdcursesdll.}
-proc waddwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl,
-    importc: "waddwstr", dynlib: pdcursesdll.}
-proc wadd_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wadd_wch", dynlib: pdcursesdll.}
-proc wadd_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.
-    extdecl, importc: "wadd_wchnstr", dynlib: pdcursesdll.}
-proc wadd_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wadd_wchstr", dynlib: pdcursesdll.}
-proc wbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wbkgrnd", dynlib: pdcursesdll.}
-proc wbkgrndset*(a2: ptr WINDOW; a3: ptr cunsignedlong){.extdecl,
-    importc: "wbkgrndset", dynlib: pdcursesdll.}
-proc wborder_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: ptr cunsignedlong;
-                  a5: ptr cunsignedlong; a6: ptr cunsignedlong;
-                  a7: ptr cunsignedlong; a8: ptr cunsignedlong;
-                  a9: ptr cunsignedlong; a10: ptr cunsignedlong): cint{.extdecl,
-    importc: "wborder_set", dynlib: pdcursesdll.}
-proc wecho_wchar*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wecho_wchar", dynlib: pdcursesdll.}
-proc wgetbkgrnd*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wgetbkgrnd", dynlib: pdcursesdll.}
-proc wgetn_wstr*(a2: ptr WINDOW; a3: ptr cint; a4: cint): cint{.extdecl,
-    importc: "wgetn_wstr", dynlib: pdcursesdll.}
-proc wget_wch*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl,
-    importc: "wget_wch", dynlib: pdcursesdll.}
-proc wget_wstr*(a2: ptr WINDOW; a3: ptr cint): cint{.extdecl,
-    importc: "wget_wstr", dynlib: pdcursesdll.}
-proc whline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "whline_set", dynlib: pdcursesdll.}
-proc winnwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "winnwstr", dynlib: pdcursesdll.}
-proc wins_nwstr*(a2: ptr WINDOW; a3: cstring; a4: cint): cint{.extdecl,
-    importc: "wins_nwstr", dynlib: pdcursesdll.}
-proc wins_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "wins_wch", dynlib: pdcursesdll.}
-proc wins_wstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl,
-    importc: "wins_wstr", dynlib: pdcursesdll.}
-proc winwstr*(a2: ptr WINDOW; a3: cstring): cint{.extdecl, importc: "winwstr",
-    dynlib: pdcursesdll.}
-proc win_wch*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "win_wch", dynlib: pdcursesdll.}
-proc win_wchnstr*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "win_wchnstr", dynlib: pdcursesdll.}
-proc win_wchstr*(a2: ptr WINDOW; a3: ptr cunsignedlong): cint{.extdecl,
-    importc: "win_wchstr", dynlib: pdcursesdll.}
-proc wunctrl*(a2: ptr cunsignedlong): cstring{.extdecl, importc: "wunctrl",
-    dynlib: pdcursesdll.}
-proc wvline_set*(a2: ptr WINDOW; a3: ptr cunsignedlong; a4: cint): cint{.extdecl,
-    importc: "wvline_set", dynlib: pdcursesdll.}
-proc getattrs*(a2: ptr WINDOW): cunsignedlong{.extdecl, importc: "getattrs",
-    dynlib: pdcursesdll.}
-proc getbegx*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegx",
-                                     dynlib: pdcursesdll.}
-proc getbegy*(a2: ptr WINDOW): cint{.extdecl, importc: "getbegy",
-                                     dynlib: pdcursesdll.}
-proc getmaxx*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxx",
-                                     dynlib: pdcursesdll.}
-proc getmaxy*(a2: ptr WINDOW): cint{.extdecl, importc: "getmaxy",
-                                     dynlib: pdcursesdll.}
-proc getparx*(a2: ptr WINDOW): cint{.extdecl, importc: "getparx",
-                                     dynlib: pdcursesdll.}
-proc getpary*(a2: ptr WINDOW): cint{.extdecl, importc: "getpary",
-                                     dynlib: pdcursesdll.}
-proc getcurx*(a2: ptr WINDOW): cint{.extdecl, importc: "getcurx",
-                                     dynlib: pdcursesdll.}
-proc getcury*(a2: ptr WINDOW): cint{.extdecl, importc: "getcury",
-                                     dynlib: pdcursesdll.}
-proc traceoff*(){.extdecl, importc: "traceoff", dynlib: pdcursesdll.}
-proc traceon*(){.extdecl, importc: "traceon", dynlib: pdcursesdll.}
-proc unctrl*(a2: cunsignedlong): cstring{.extdecl, importc: "unctrl",
-    dynlib: pdcursesdll.}
-proc crmode*(): cint{.extdecl, importc: "crmode", dynlib: pdcursesdll.}
-proc nocrmode*(): cint{.extdecl, importc: "nocrmode", dynlib: pdcursesdll.}
-proc draino*(a2: cint): cint{.extdecl, importc: "draino", dynlib: pdcursesdll.}
-proc resetterm*(): cint{.extdecl, importc: "resetterm", dynlib: pdcursesdll.}
-proc fixterm*(): cint{.extdecl, importc: "fixterm", dynlib: pdcursesdll.}
-proc saveterm*(): cint{.extdecl, importc: "saveterm", dynlib: pdcursesdll.}
-proc setsyx*(a2: cint; a3: cint): cint{.extdecl, importc: "setsyx",
-                                        dynlib: pdcursesdll.}
-proc mouse_set*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_set",
-    dynlib: pdcursesdll.}
-proc mouse_on*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_on",
-    dynlib: pdcursesdll.}
-proc mouse_off*(a2: cunsignedlong): cint{.extdecl, importc: "mouse_off",
-    dynlib: pdcursesdll.}
-proc request_mouse_pos*(): cint{.extdecl, importc: "request_mouse_pos",
-                                 dynlib: pdcursesdll.}
-proc map_button*(a2: cunsignedlong): cint{.extdecl, importc: "map_button",
-    dynlib: pdcursesdll.}
-proc wmouse_position*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint){.extdecl,
-    importc: "wmouse_position", dynlib: pdcursesdll.}
-proc getmouse*(): cunsignedlong{.extdecl, importc: "getmouse", dynlib: pdcursesdll.}
-proc getbmap*(): cunsignedlong{.extdecl, importc: "getbmap", dynlib: pdcursesdll.}
-proc assume_default_colors*(a2: cint; a3: cint): cint{.extdecl,
-    importc: "assume_default_colors", dynlib: pdcursesdll.}
-proc curses_version*(): cstring{.extdecl, importc: "curses_version",
-                                 dynlib: pdcursesdll.}
-proc has_key*(a2: cint): cunsignedchar{.extdecl, importc: "has_key",
-                                        dynlib: pdcursesdll.}
-proc use_default_colors*(): cint{.extdecl, importc: "use_default_colors",
-                                  dynlib: pdcursesdll.}
-proc wresize*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "wresize", dynlib: pdcursesdll.}
-proc mouseinterval*(a2: cint): cint{.extdecl, importc: "mouseinterval",
-                                     dynlib: pdcursesdll.}
-proc mousemask*(a2: cunsignedlong; a3: ptr cunsignedlong): cunsignedlong{.extdecl,
-    importc: "mousemask", dynlib: pdcursesdll.}
-proc mouse_trafo*(a2: ptr cint; a3: ptr cint; a4: cunsignedchar): cunsignedchar{.
-    extdecl, importc: "mouse_trafo", dynlib: pdcursesdll.}
-proc nc_getmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "nc_getmouse",
-    dynlib: pdcursesdll.}
-proc ungetmouse*(a2: ptr MEVENT): cint{.extdecl, importc: "ungetmouse",
-                                        dynlib: pdcursesdll.}
-proc wenclose*(a2: ptr WINDOW; a3: cint; a4: cint): cunsignedchar{.extdecl,
-    importc: "wenclose", dynlib: pdcursesdll.}
-proc wmouse_trafo*(a2: ptr WINDOW; a3: ptr cint; a4: ptr cint; a5: cunsignedchar): cunsignedchar{.
-    extdecl, importc: "wmouse_trafo", dynlib: pdcursesdll.}
-proc addrawch*(a2: cunsignedlong): cint{.extdecl, importc: "addrawch",
-    dynlib: pdcursesdll.}
-proc insrawch*(a2: cunsignedlong): cint{.extdecl, importc: "insrawch",
-    dynlib: pdcursesdll.}
-proc is_termresized*(): cunsignedchar{.extdecl, importc: "is_termresized",
-                                       dynlib: pdcursesdll.}
-proc mvaddrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl,
-    importc: "mvaddrawch", dynlib: pdcursesdll.}
-proc mvdeleteln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvdeleteln",
-    dynlib: pdcursesdll.}
-proc mvinsertln*(a2: cint; a3: cint): cint{.extdecl, importc: "mvinsertln",
-    dynlib: pdcursesdll.}
-proc mvinsrawch*(a2: cint; a3: cint; a4: cunsignedlong): cint{.extdecl,
-    importc: "mvinsrawch", dynlib: pdcursesdll.}
-proc mvwaddrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{.
-    extdecl, importc: "mvwaddrawch", dynlib: pdcursesdll.}
-proc mvwdeleteln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "mvwdeleteln", dynlib: pdcursesdll.}
-proc mvwinsertln*(a2: ptr WINDOW; a3: cint; a4: cint): cint{.extdecl,
-    importc: "mvwinsertln", dynlib: pdcursesdll.}
-proc mvwinsrawch*(a2: ptr WINDOW; a3: cint; a4: cint; a5: cunsignedlong): cint{.
-    extdecl, importc: "mvwinsrawch", dynlib: pdcursesdll.}
-proc raw_output*(a2: cunsignedchar): cint{.extdecl, importc: "raw_output",
-    dynlib: pdcursesdll.}
-proc resize_term*(a2: cint; a3: cint): cint{.extdecl, importc: "resize_term",
-    dynlib: pdcursesdll.}
-proc resize_window*(a2: ptr WINDOW; a3: cint; a4: cint): ptr WINDOW{.extdecl,
-    importc: "resize_window", dynlib: pdcursesdll.}
-proc waddrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "waddrawch", dynlib: pdcursesdll.}
-proc winsrawch*(a2: ptr WINDOW; a3: cunsignedlong): cint{.extdecl,
-    importc: "winsrawch", dynlib: pdcursesdll.}
-proc wordchar*(): char{.extdecl, importc: "wordchar", dynlib: pdcursesdll.}
-proc slk_wlabel*(a2: cint): cstring{.extdecl, importc: "slk_wlabel",
-    dynlib: pdcursesdll.}
-proc debug*(a2: cstring){.varargs, extdecl, importc: "PDC_debug",
-                          dynlib: pdcursesdll.}
-proc ungetch*(a2: cint): cint{.extdecl, importc: "PDC_ungetch",
-                               dynlib: pdcursesdll.}
-proc set_blink*(a2: cunsignedchar): cint{.extdecl, importc: "PDC_set_blink",
-    dynlib: pdcursesdll.}
-proc set_line_color*(a2: cshort): cint{.extdecl, importc: "PDC_set_line_color",
-                                        dynlib: pdcursesdll.}
-proc set_title*(a2: cstring){.extdecl, importc: "PDC_set_title",
-                              dynlib: pdcursesdll.}
-proc clearclipboard*(): cint{.extdecl, importc: "PDC_clearclipboard",
-                              dynlib: pdcursesdll.}
-proc freeclipboard*(a2: cstring): cint{.extdecl, importc: "PDC_freeclipboard",
-                                        dynlib: pdcursesdll.}
-proc getclipboard*(a2: cstringArray; a3: ptr clong): cint{.extdecl,
-    importc: "PDC_getclipboard", dynlib: pdcursesdll.}
-proc setclipboard*(a2: cstring; a3: clong): cint{.extdecl,
-    importc: "PDC_setclipboard", dynlib: pdcursesdll.}
-proc get_input_fd*(): cunsignedlong{.extdecl, importc: "PDC_get_input_fd",
-                                     dynlib: pdcursesdll.}
-proc get_key_modifiers*(): cunsignedlong{.extdecl,
-    importc: "PDC_get_key_modifiers", dynlib: pdcursesdll.}
-proc return_key_modifiers*(a2: cunsignedchar): cint{.extdecl,
-    importc: "PDC_return_key_modifiers", dynlib: pdcursesdll.}
-proc save_key_modifiers*(a2: cunsignedchar): cint{.extdecl,
-    importc: "PDC_save_key_modifiers", dynlib: pdcursesdll.}
-proc bottom_panel*(pan: ptr PANEL): cint{.extdecl, importc: "bottom_panel",
-    dynlib: pdcursesdll.}
-proc del_panel*(pan: ptr PANEL): cint{.extdecl, importc: "del_panel",
-                                       dynlib: pdcursesdll.}
-proc hide_panel*(pan: ptr PANEL): cint{.extdecl, importc: "hide_panel",
-                                        dynlib: pdcursesdll.}
-proc move_panel*(pan: ptr PANEL; starty: cint; startx: cint): cint{.extdecl,
-    importc: "move_panel", dynlib: pdcursesdll.}
-proc new_panel*(win: ptr WINDOW): ptr PANEL{.extdecl, importc: "new_panel",
-    dynlib: pdcursesdll.}
-proc panel_above*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_above",
-    dynlib: pdcursesdll.}
-proc panel_below*(pan: ptr PANEL): ptr PANEL{.extdecl, importc: "panel_below",
-    dynlib: pdcursesdll.}
-proc panel_hidden*(pan: ptr PANEL): cint{.extdecl, importc: "panel_hidden",
-    dynlib: pdcursesdll.}
-proc panel_userptr*(pan: ptr PANEL): pointer{.extdecl, importc: "panel_userptr",
-    dynlib: pdcursesdll.}
-proc panel_window*(pan: ptr PANEL): ptr WINDOW{.extdecl, importc: "panel_window",
-    dynlib: pdcursesdll.}
-proc replace_panel*(pan: ptr PANEL; win: ptr WINDOW): cint{.extdecl,
-    importc: "replace_panel", dynlib: pdcursesdll.}
-proc set_panel_userptr*(pan: ptr PANEL; uptr: pointer): cint{.extdecl,
-    importc: "set_panel_userptr", dynlib: pdcursesdll.}
-proc show_panel*(pan: ptr PANEL): cint{.extdecl, importc: "show_panel",
-                                        dynlib: pdcursesdll.}
-proc top_panel*(pan: ptr PANEL): cint{.extdecl, importc: "top_panel",
-                                       dynlib: pdcursesdll.}
-proc update_panels*(){.extdecl, importc: "update_panels", dynlib: pdcursesdll.}
-
-when unixOS:
-  proc Xinitscr*(a2: cint; a3: cstringArray): ptr WINDOW{.extdecl,
-    importc: "Xinitscr", dynlib: pdcursesdll.}
-  proc XCursesExit*(){.extdecl, importc: "XCursesExit", dynlib: pdcursesdll.}
-  proc sb_init*(): cint{.extdecl, importc: "sb_init", dynlib: pdcursesdll.}
-  proc sb_set_horz*(a2: cint; a3: cint; a4: cint): cint{.extdecl,
-    importc: "sb_set_horz", dynlib: pdcursesdll.}
-  proc sb_set_vert*(a2: cint; a3: cint; a4: cint): cint{.extdecl,
-    importc: "sb_set_vert", dynlib: pdcursesdll.}
-  proc sb_get_horz*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl,
-    importc: "sb_get_horz", dynlib: pdcursesdll.}
-  proc sb_get_vert*(a2: ptr cint; a3: ptr cint; a4: ptr cint): cint{.extdecl,
-    importc: "sb_get_vert", dynlib: pdcursesdll.}
-  proc sb_refresh*(): cint{.extdecl, importc: "sb_refresh", dynlib: pdcursesdll.}
-
-template getch*(): expr =
-  wgetch(stdscr)
-
-template ungetch*(ch: expr): expr =
-  ungetch(ch)
-
-template getbegyx*(w, y, x: expr): expr =
-  y = getbegy(w)
-  x = getbegx(w)
-
-template getmaxyx*(w, y, x: expr): expr =
-  y = getmaxy(w)
-  x = getmaxx(w)
-
-template getparyx*(w, y, x: expr): expr =
-  y = getpary(w)
-  x = getparx(w)
-
-template getyx*(w, y, x: expr): expr =
-  y = getcury(w)
-  x = getcurx(w)
-
-template getsyx*(y, x: expr): stmt =
-  if curscr.leaveit:
-    (x) = - 1
-    (y) = (x)
-  else: getyx(curscr, (y), (x))
-
-template getmouse*(x: expr): expr =
-  nc_getmouse(x)
-
-when defined(windows):
-  var
-    atrtab*{.importc: "pdc_atrtab", dynlib: pdcursesdll.}: cstring
-    con_out*{.importc: "pdc_con_out", dynlib: pdcursesdll.}: HANDLE
-    con_in*{.importc: "pdc_con_in", dynlib: pdcursesdll.}: HANDLE
-    quick_edit*{.importc: "pdc_quick_edit", dynlib: pdcursesdll.}: DWORD
-
-  proc get_buffer_rows*(): cint{.extdecl, importc: "PDC_get_buffer_rows",
-                               dynlib: pdcursesdll.}
diff --git a/lib/wrappers/tinyc.nim b/lib/wrappers/tinyc.nim
index 47b505abc..f2ce92d36 100644
--- a/lib/wrappers/tinyc.nim
+++ b/lib/wrappers/tinyc.nim
@@ -20,16 +20,12 @@ proc openCCState*(): PccState {.importc: "tcc_new", cdecl.}
 proc closeCCState*(s: PccState) {.importc: "tcc_delete", cdecl.}
   ## free a TCC compilation context
 
-proc enableDebug*(s: PccState) {.importc: "tcc_enable_debug", cdecl.}
-  ## add debug information in the generated code
-
 proc setErrorFunc*(s: PccState, errorOpaque: pointer, errorFun: ErrorFunc) {.
   cdecl, importc: "tcc_set_error_func".}
   ## set error/warning display callback
 
-proc setWarning*(s: PccState, warningName: cstring, value: int) {.cdecl,
-  importc: "tcc_set_warning".}
-  ## set/reset a warning
+proc setOptions*(s: PccState, options: cstring) {.cdecl, importc: "tcc_set_options".}
+  ## set a options
 
 # preprocessor
 
@@ -41,7 +37,6 @@ proc addSysincludePath*(s: PccState, pathname: cstring) {.cdecl,
   importc: "tcc_add_sysinclude_path".}
   ## add in system include path
 
-
 proc defineSymbol*(s: PccState, sym, value: cstring) {.cdecl,
   importc: "tcc_define_symbol".}
   ## define preprocessor symbol 'sym'. Can put optional value
@@ -65,16 +60,12 @@ proc compileString*(s: PccState, buf: cstring): cint {.cdecl,
 
 
 const
-  OutputMemory*: cint = 0 ## output will be ran in memory (no
+  OutputMemory*: cint = 1 ## output will be ran in memory (no
                           ## output file) (default)
-  OutputExe*: cint = 1 ## executable file
-  OutputDll*: cint = 2 ## dynamic library
-  OutputObj*: cint = 3 ## object file
-  OutputPreprocess*: cint = 4 ## preprocessed file (used internally)
-
-  OutputFormatElf*: cint = 0 ## default output format: ELF
-  OutputFormatBinary*: cint = 1 ## binary image output
-  OutputFormatCoff*: cint = 2 ## COFF
+  OutputExe*: cint = 2 ## executable file
+  OutputDll*: cint = 3 ## dynamic library
+  OutputObj*: cint = 4 ## object file
+  OutputPreprocess*: cint = 5 ## preprocessed file (used internally)
 
 proc setOutputType*(s: PCCState, outputType: cint): cint {.cdecl,
   importc: "tcc_set_output_type".}